Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.0 kB · 89 lines
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990import { z } from "zod";
// Project only the fields displayed below. Never stringify the arbitrary script// return value or workspace content from a persisted tool message.const display = z.object({ kind: z.literal("skill-script"), skill: z.object({ source: z.enum(["bundled", "installed"]), name: z.string().min(1).max(64), version: z.string().min(1).max(64), fingerprint: z.string().regex(/^[a-f0-9]{64}$/), }), path: z.string().min(1).max(240), result: z.object({ ok: z.boolean(), stdout: z.string().max(8192), stderr: z.string().max(8192), exitCode: z.union([z.literal(0), z.literal(1)]), truncated: z.boolean(), error: z.object({ message: z.string().max(240) }).optional(), }), workspace: z.object({ files: z.array(z.object({ path: z.string().min(1).max(240) })).max(8), truncated: z.boolean(), }),});export function skillScriptOutput(value: unknown) { const parsed = display.safeParse(value); if (!parsed.success) return; const { stdout, stderr } = parsed.data.result; if ( [stdout, stderr].some( (text) => new TextEncoder().encode(JSON.stringify(text)).byteLength > 8192, ) ) return; return parsed.data;}type Output = z.infer<typeof display>;
export function SkillScriptOutput({ output }: { output: Output }) { return ( <details className="mt-2 text-sm"> <summary className="cursor-pointer text-kumo-default"> Script output · Exit status {output.result.exitCode} {output.result.truncated ? " · Output truncated" : ""} </summary> <div className="mt-2 grid min-w-0 gap-3" role="region" aria-label="Skill script output" > <p> {output.skill.name} · {output.skill.version} · {output.path} </p> {!output.result.ok && output.result.error ? ( <p>{output.result.error.message}</p> ) : null} {(["stdout", "stderr"] as const).map((stream) => ( <div key={stream} className="grid min-w-0 gap-1"> <span className="font-medium">{stream}</span> <pre className="skill-script-stream rounded-md bg-kumo-base px-3 py-2 text-sm"> {output.result[stream] || "No output"} </pre> </div> ))} {output.workspace.files.length ? ( <div className="grid gap-1"> <span className="font-medium"> Changed files in this invocation </span> <ul> {output.workspace.files.map((file) => ( <li key={file.path}> <code className="skill-script-file">{file.path}</code> </li> ))} </ul> <p>Changes belong to the files supplied for this invocation.</p> </div> ) : null} {output.workspace.truncated ? ( <p>Changed file output was truncated.</p> ) : null} </div> </details> );}