{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/core/canvas/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Canvas wire protocol — the entire GitHub-facing surface.\n *\n * Design: `docs/canvas-extensions-design.md` §2. The short version: GitHub's own\n * types (`@github/copilot-sdk` `dist/canvas.d.ts`) state that the Node\n * `createCanvas`/`joinSession` API is one of five language wrappers over the same\n * JSON-RPC wire protocol, and that \"the divergence is API ergonomics only\". So\n * hoocode binds to the wire protocol, not to the Node sugar, and the drift\n * surface is the three provider methods below plus one version integer.\n *\n * Everything a third-party canvas can observe lives in this file. If GitHub\n * moves the protocol, this file and `sdk-shim/` move; nothing else does.\n *\n * Two layers are deliberately separated here:\n *\n *   1. **Provider contract** (`CanvasProvider*`, `CANVAS_METHOD_*`) — GitHub's.\n *      These payload shapes reach extension code as the `ctx` argument of\n *      `open`, `onClose`, and action handlers, so they must stay structurally\n *      identical to the SDK's. `test/canvas-protocol-conformance.test.ts` fails\n *      the build if they drift.\n *   2. **Host envelope** (`Canvas*Message`) — ours. It carries provider calls\n *      between hoocode's runner and the child-side shim. In the Copilot case the\n *      equivalent layer sits between their CLI and their SDK and an extension\n *      never sees it, so we are free to keep it simple: newline-delimited JSON.\n */\n\n/** JSON value, mirroring the SDK's `JsonValue`. */\nexport type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };\n\n/** JSON Schema carried as data, mirroring the SDK's `CanvasJsonSchema`. */\nexport type CanvasJsonSchema = JsonValue;\n\n/** Result of an action invocation, mirroring the SDK's `CanvasActionInvokeResult`. */\nexport type CanvasActionInvokeResult = JsonValue;\n\n/**\n * SDK protocol version this implementation targets, mirroring the SDK's\n * `SDK_PROTOCOL_VERSION`. The conformance test asserts the two are equal, so a\n * protocol bump surfaces as a failing test rather than a runtime mismatch.\n */\nexport const CANVAS_SDK_PROTOCOL_VERSION = 3;\n\n/** Provider callback: open a canvas instance. */\nexport const CANVAS_METHOD_OPEN = \"canvas.open\";\n/** Provider callback: a canvas instance was closed. */\nexport const CANVAS_METHOD_CLOSE = \"canvas.close\";\n/** Provider callback: invoke an agent-callable action. */\nexport const CANVAS_METHOD_INVOKE_ACTION = \"canvas.action.invoke\";\n\n/** The three provider callbacks, in the order the design doc lists them. */\nexport const CANVAS_PROVIDER_METHODS = [CANVAS_METHOD_OPEN, CANVAS_METHOD_CLOSE, CANVAS_METHOD_INVOKE_ACTION] as const;\n\n/** One of the three provider callback names. */\nexport type CanvasProviderMethod = (typeof CANVAS_PROVIDER_METHODS)[number];\n\n/** Host capabilities advertised to the provider. */\nexport interface CanvasHostContextCapabilities {\n\t/** Whether canvas rendering is supported. */\n\tcanvases?: boolean;\n}\n\n/** Host context supplied by the runtime. */\nexport interface CanvasHostContext {\n\tcapabilities?: CanvasHostContextCapabilities;\n}\n\n/** Session context supplied by the runtime. */\nexport interface CanvasSessionContext {\n\t/** Active session working directory, when known. */\n\tworkingDirectory?: string;\n}\n\n/** Fields shared by every provider callback payload. */\ninterface CanvasProviderRequestBase {\n\t/** Target session identifier. */\n\tsessionId: string;\n\t/** Owning provider identifier. */\n\textensionId: string;\n\t/** Provider-local canvas identifier. */\n\tcanvasId: string;\n\t/** Canvas instance identifier. */\n\tinstanceId: string;\n\thost?: CanvasHostContext;\n\tsession?: CanvasSessionContext;\n}\n\n/** `canvas.open` payload. */\nexport interface CanvasProviderOpenRequest extends CanvasProviderRequestBase {\n\t/** Canvas open input. */\n\tinput?: JsonValue;\n}\n\n/** `canvas.open` result. A web-rendered canvas returns the URL the host loads. */\nexport interface CanvasProviderOpenResult {\n\t/** URL for web-rendered canvases. */\n\turl?: string;\n\t/** Provider-supplied title. */\n\ttitle?: string;\n\t/** Provider-supplied status text. */\n\tstatus?: string;\n}\n\n/** `canvas.close` payload. */\nexport interface CanvasProviderCloseRequest extends CanvasProviderRequestBase {}\n\n/** `canvas.action.invoke` payload. */\nexport interface CanvasProviderInvokeActionRequest extends CanvasProviderRequestBase {\n\t/** Action name to invoke. */\n\tactionName: string;\n\t/** Action input. */\n\tinput?: JsonValue;\n}\n\n/**\n * Action metadata as it crosses the wire. The SDK strips each action's `handler`\n * closure before sending the declaration, so this is `CanvasAction` minus the\n * handler.\n */\nexport interface CanvasActionDeclaration {\n\t/** Action identifier, unique within the canvas. */\n\tname: string;\n\t/** Description shown to the model when picking an action. */\n\tdescription?: string;\n\t/** Optional JSON Schema for the action's `input` payload. */\n\tinputSchema?: CanvasJsonSchema;\n}\n\n/** Declarative metadata for a single canvas. */\nexport interface CanvasDeclaration {\n\t/** Canvas id, unique within the declaring connection. */\n\tid: string;\n\t/** Human-readable label shown in discovery and host UI chrome. */\n\tdisplayName: string;\n\t/** Short, single-sentence description shown to the agent in canvas catalogs. */\n\tdescription: string;\n\t/** Optional JSON Schema for the `input` payload accepted by `canvas.open`. */\n\tinputSchema?: CanvasJsonSchema;\n\t/** Agent-invocable actions. */\n\tactions?: CanvasActionDeclaration[];\n}\n\n/**\n * Reserved action-name prefix. The SDK is explicit: \"Names MUST NOT start with\n * `canvas.` — that prefix is reserved for lifecycle verbs.\"\n */\nexport const CANVAS_RESERVED_ACTION_PREFIX = \"canvas.\";\n\n/** Log levels accepted by `session.log`. */\nexport type CanvasLogLevel = \"info\" | \"warning\" | \"error\";\n\n/**\n * Host envelope version. Ours, not GitHub's — bumped only when the\n * runner↔shim framing changes.\n */\nexport const CANVAS_ENVELOPE_VERSION = 1;\n\n/** Child announces itself and its canvases. Always the first message. */\nexport interface CanvasReadyMessage {\n\tenvelope: typeof CANVAS_ENVELOPE_VERSION;\n\ttype: \"ready\";\n\t/** The `CANVAS_SDK_PROTOCOL_VERSION` the child was built against. */\n\tprotocolVersion: number;\n\t/** Provider identifier, derived by the runner from the extension directory. */\n\textensionId: string;\n\tcanvases: CanvasDeclaration[];\n\t/**\n\t * Surfaces declared by the extension that this shim does not implement, so the\n\t * runner can warn once instead of letting the extension half-work\n\t * (design doc §6.2).\n\t */\n\tunsupported?: string[];\n}\n\n/** Child forwards a `session.log` call. */\nexport interface CanvasLogMessage {\n\tenvelope: typeof CANVAS_ENVELOPE_VERSION;\n\ttype: \"log\";\n\tmessage: string;\n\tlevel?: CanvasLogLevel;\n\tephemeral?: boolean;\n}\n\n/** Host asks the child to run one provider callback. */\nexport interface CanvasRequestMessage {\n\tenvelope: typeof CANVAS_ENVELOPE_VERSION;\n\ttype: \"request\";\n\tid: number;\n\tmethod: CanvasProviderMethod;\n\tparams: JsonValue;\n}\n\n/** Child returns a provider callback result. */\nexport interface CanvasResponseMessage {\n\tenvelope: typeof CANVAS_ENVELOPE_VERSION;\n\ttype: \"response\";\n\tid: number;\n\tresult: JsonValue;\n}\n\n/**\n * Child returns a failure. `code` carries `CanvasError.code` when the handler threw\n * one, so the agent gets a machine-readable code rather than a string to parse.\n */\nexport interface CanvasErrorMessage {\n\tenvelope: typeof CANVAS_ENVELOPE_VERSION;\n\ttype: \"error\";\n\tid: number;\n\tcode: string;\n\tmessage: string;\n}\n\n/** Anything the host may send to a child. */\nexport type CanvasHostToChildMessage = CanvasRequestMessage;\n\n/** Anything a child may send to the host. */\nexport type CanvasChildToHostMessage =\n\t| CanvasReadyMessage\n\t| CanvasLogMessage\n\t| CanvasResponseMessage\n\t| CanvasErrorMessage;\n\n/** Error code used when a handler throws something that is not a `CanvasError`. */\nexport const CANVAS_ERROR_CODE_INTERNAL = \"internal_error\";\n/** Error code used when the host asks for a canvas or action the child does not declare. */\nexport const CANVAS_ERROR_CODE_UNKNOWN_TARGET = \"unknown_target\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasCurrentEnvelope(value: Record<string, unknown>): boolean {\n\treturn value.envelope === CANVAS_ENVELOPE_VERSION;\n}\n\n/** Whether `value` is a provider callback name. */\nexport function isCanvasProviderMethod(value: unknown): value is CanvasProviderMethod {\n\treturn typeof value === \"string\" && (CANVAS_PROVIDER_METHODS as readonly string[]).includes(value);\n}\n\n/** Narrow a decoded value to a host→child message. */\nexport function isCanvasHostToChildMessage(value: unknown): value is CanvasHostToChildMessage {\n\tif (!isRecord(value) || !hasCurrentEnvelope(value)) return false;\n\treturn value.type === \"request\" && typeof value.id === \"number\" && isCanvasProviderMethod(value.method);\n}\n\n/** Narrow a decoded value to a child→host message. */\nexport function isCanvasChildToHostMessage(value: unknown): value is CanvasChildToHostMessage {\n\tif (!isRecord(value) || !hasCurrentEnvelope(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"ready\":\n\t\t\treturn typeof value.extensionId === \"string\" && Array.isArray(value.canvases);\n\t\tcase \"log\":\n\t\t\treturn typeof value.message === \"string\";\n\t\tcase \"response\":\n\t\t\treturn typeof value.id === \"number\";\n\t\tcase \"error\":\n\t\t\treturn typeof value.id === \"number\" && typeof value.code === \"string\" && typeof value.message === \"string\";\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/** Serialize one message as a single NDJSON line, newline included. */\nexport function encodeCanvasMessage(message: CanvasHostToChildMessage | CanvasChildToHostMessage): string {\n\treturn `${JSON.stringify(message)}\\n`;\n}\n\n/** One decode pass: parsed JSON values plus any lines that were not JSON at all. */\nexport interface CanvasDecodeResult {\n\tvalues: unknown[];\n\t/**\n\t * Lines that failed to parse. In the Copilot CLI stdout is the JSON-RPC channel,\n\t * so a stray `console.log` corrupts it; we keep the same discipline but report\n\t * the stray text so the runner can tell the author to use `session.log`\n\t * instead of leaving them with a silent protocol error.\n\t */\n\tstrays: string[];\n}\n\n/**\n * Incremental NDJSON decoder. Chunk boundaries do not respect line boundaries, so\n * a partial trailing line is held until the rest arrives.\n */\nexport class CanvasMessageDecoder {\n\tprivate buffer = \"\";\n\n\t/** Decode everything complete in `chunk`, buffering any partial trailing line. */\n\tpush(chunk: string): CanvasDecodeResult {\n\t\tthis.buffer += chunk;\n\t\tconst result: CanvasDecodeResult = { values: [], strays: [] };\n\t\tlet newline = this.buffer.indexOf(\"\\n\");\n\t\twhile (newline !== -1) {\n\t\t\tthis.take(this.buffer.slice(0, newline), result);\n\t\t\tthis.buffer = this.buffer.slice(newline + 1);\n\t\t\tnewline = this.buffer.indexOf(\"\\n\");\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Decode whatever is left, for use when the stream ends without a trailing newline. */\n\tflush(): CanvasDecodeResult {\n\t\tconst result: CanvasDecodeResult = { values: [], strays: [] };\n\t\tconst rest = this.buffer;\n\t\tthis.buffer = \"\";\n\t\tthis.take(rest, result);\n\t\treturn result;\n\t}\n\n\tprivate take(line: string, result: CanvasDecodeResult): void {\n\t\tconst trimmed = line.trim();\n\t\tif (trimmed.length === 0) return;\n\t\ttry {\n\t\t\tresult.values.push(JSON.parse(trimmed));\n\t\t} catch {\n\t\t\tresult.strays.push(trimmed);\n\t\t}\n\t}\n}\n"]}