@particle-academy/agent-integrations 0.7.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/bridges/artboard.d.cts +3 -3
  2. package/dist/bridges/artboard.d.ts +3 -3
  3. package/dist/bridges/charts.d.cts +3 -3
  4. package/dist/bridges/charts.d.ts +3 -3
  5. package/dist/bridges/code.d.cts +3 -3
  6. package/dist/bridges/code.d.ts +3 -3
  7. package/dist/bridges/flow.d.cts +3 -3
  8. package/dist/bridges/flow.d.ts +3 -3
  9. package/dist/bridges/forms.d.cts +3 -3
  10. package/dist/bridges/forms.d.ts +3 -3
  11. package/dist/bridges/scene.d.cts +3 -3
  12. package/dist/bridges/scene.d.ts +3 -3
  13. package/dist/bridges/screens.d.cts +3 -3
  14. package/dist/bridges/screens.d.ts +3 -3
  15. package/dist/bridges/sheets.d.cts +3 -3
  16. package/dist/bridges/sheets.d.ts +3 -3
  17. package/dist/bridges/slides.d.cts +4 -3
  18. package/dist/bridges/slides.d.ts +4 -3
  19. package/dist/bridges/whiteboard.d.cts +3 -3
  20. package/dist/bridges/whiteboard.d.ts +3 -3
  21. package/dist/bridges-artboard.cjs +15 -54
  22. package/dist/bridges-artboard.cjs.map +1 -1
  23. package/dist/bridges-artboard.js +3 -3
  24. package/dist/bridges-charts.cjs +3 -5
  25. package/dist/bridges-charts.cjs.map +1 -1
  26. package/dist/bridges-charts.js +3 -3
  27. package/dist/bridges-code.cjs +3 -5
  28. package/dist/bridges-code.cjs.map +1 -1
  29. package/dist/bridges-code.js +3 -3
  30. package/dist/bridges-flow.cjs +3 -5
  31. package/dist/bridges-flow.cjs.map +1 -1
  32. package/dist/bridges-flow.js +2 -2
  33. package/dist/bridges-forms.cjs +3 -5
  34. package/dist/bridges-forms.cjs.map +1 -1
  35. package/dist/bridges-forms.js +3 -3
  36. package/dist/bridges-scene.cjs +3 -5
  37. package/dist/bridges-scene.cjs.map +1 -1
  38. package/dist/bridges-scene.js +3 -3
  39. package/dist/bridges-screens.cjs +3 -5
  40. package/dist/bridges-screens.cjs.map +1 -1
  41. package/dist/bridges-screens.js +3 -3
  42. package/dist/bridges-sheets.cjs +3 -5
  43. package/dist/bridges-sheets.cjs.map +1 -1
  44. package/dist/bridges-sheets.js +3 -3
  45. package/dist/bridges-slides.cjs +24 -5
  46. package/dist/bridges-slides.cjs.map +1 -1
  47. package/dist/bridges-slides.js +3 -3
  48. package/dist/bridges-whiteboard.cjs +10 -49
  49. package/dist/bridges-whiteboard.cjs.map +1 -1
  50. package/dist/bridges-whiteboard.js +4 -4
  51. package/dist/{chunk-3KSZNGNW.js → chunk-3QJSOS7G.js} +4 -4
  52. package/dist/{chunk-3KSZNGNW.js.map → chunk-3QJSOS7G.js.map} +1 -1
  53. package/dist/{chunk-4BL5M3U3.js → chunk-5AD35HS5.js} +3 -3
  54. package/dist/{chunk-4BL5M3U3.js.map → chunk-5AD35HS5.js.map} +1 -1
  55. package/dist/chunk-C3TYI5TJ.js +3 -0
  56. package/dist/chunk-C3TYI5TJ.js.map +1 -0
  57. package/dist/{chunk-57ZDHD53.js → chunk-CKK4QKD2.js} +3 -3
  58. package/dist/{chunk-57ZDHD53.js.map → chunk-CKK4QKD2.js.map} +1 -1
  59. package/dist/{chunk-LVQXIUJH.js → chunk-CPNOF4HI.js} +3 -3
  60. package/dist/{chunk-LVQXIUJH.js.map → chunk-CPNOF4HI.js.map} +1 -1
  61. package/dist/{chunk-HSTW7ZNO.js → chunk-FYGMFIY5.js} +3 -3
  62. package/dist/{chunk-HSTW7ZNO.js.map → chunk-FYGMFIY5.js.map} +1 -1
  63. package/dist/{chunk-RGO42EQ6.js → chunk-GHY3PBPN.js} +3 -3
  64. package/dist/{chunk-RGO42EQ6.js.map → chunk-GHY3PBPN.js.map} +1 -1
  65. package/dist/{chunk-IANI25IT.js → chunk-GSVVIT2O.js} +3 -3
  66. package/dist/{chunk-IANI25IT.js.map → chunk-GSVVIT2O.js.map} +1 -1
  67. package/dist/{chunk-ZHAK2DQR.js → chunk-J5KYPEYB.js} +3 -3
  68. package/dist/{chunk-ZHAK2DQR.js.map → chunk-J5KYPEYB.js.map} +1 -1
  69. package/dist/{chunk-5XELJIJR.js → chunk-KHKSQEMC.js} +3 -3
  70. package/dist/{chunk-5XELJIJR.js.map → chunk-KHKSQEMC.js.map} +1 -1
  71. package/dist/{chunk-GQ7XXK7G.js → chunk-KJ5AOOV7.js} +5 -46
  72. package/dist/chunk-KJ5AOOV7.js.map +1 -0
  73. package/dist/{chunk-7X5ZAU4P.js → chunk-R5OA26MJ.js} +26 -4
  74. package/dist/chunk-R5OA26MJ.js.map +1 -0
  75. package/dist/{chunk-NTDZWGYB.js → chunk-SJ7H242B.js} +3 -3
  76. package/dist/{chunk-NTDZWGYB.js.map → chunk-SJ7H242B.js.map} +1 -1
  77. package/dist/{chunk-X66JWQBB.js → chunk-UCKJAUBY.js} +3 -3
  78. package/dist/{chunk-X66JWQBB.js.map → chunk-UCKJAUBY.js.map} +1 -1
  79. package/dist/{chunk-52S7XYZK.js → chunk-ULJL53DL.js} +3 -3
  80. package/dist/{chunk-52S7XYZK.js.map → chunk-ULJL53DL.js.map} +1 -1
  81. package/dist/{chunk-XRAJSOPS.js → chunk-VUMFO2UW.js} +3 -3
  82. package/dist/{chunk-XRAJSOPS.js.map → chunk-VUMFO2UW.js.map} +1 -1
  83. package/dist/components/SharedWhiteboard/index.d.cts +3 -3
  84. package/dist/components/SharedWhiteboard/index.d.ts +3 -3
  85. package/dist/components-shared-whiteboard.cjs +13 -79
  86. package/dist/components-shared-whiteboard.cjs.map +1 -1
  87. package/dist/components-shared-whiteboard.js +6 -6
  88. package/dist/index.cjs +82 -102
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.cts +16 -15
  91. package/dist/index.d.ts +16 -15
  92. package/dist/index.js +17 -17
  93. package/dist/mcp/index.d.cts +5 -5
  94. package/dist/mcp/index.d.ts +5 -5
  95. package/dist/presence/index.d.cts +10 -64
  96. package/dist/presence/index.d.ts +10 -64
  97. package/dist/presence.cjs +21 -37
  98. package/dist/presence.cjs.map +1 -1
  99. package/dist/presence.js +3 -3
  100. package/dist/registry-TFWVXQOU.js +3 -0
  101. package/dist/{registry-2DRURS6U.js.map → registry-TFWVXQOU.js.map} +1 -1
  102. package/dist/{server-C2OpfPEo.d.cts → server-BsSwfemr.d.cts} +3 -3
  103. package/dist/{server-CKAqFTyc.d.ts → server-Du3-IGqM.d.ts} +3 -3
  104. package/dist/sharing/index.d.cts +4 -4
  105. package/dist/sharing/index.d.ts +4 -4
  106. package/dist/sharing.cjs +6 -34
  107. package/dist/sharing.cjs.map +1 -1
  108. package/dist/sharing.js +1 -1
  109. package/dist/sheets-adapter.cjs +2 -9
  110. package/dist/sheets-adapter.cjs.map +1 -1
  111. package/dist/sheets-adapter.d.cts +3 -3
  112. package/dist/sheets-adapter.d.ts +3 -3
  113. package/dist/sheets-adapter.js +2 -2
  114. package/dist/{token-C1O22GxJ.d.ts → token-CrJF76oH.d.cts} +1 -1
  115. package/dist/{token-C1O22GxJ.d.cts → token-CrJF76oH.d.ts} +1 -1
  116. package/dist/{tool-host-CX3WFXgh.d.cts → tool-host-BQuUygLF.d.cts} +1 -1
  117. package/dist/{tool-host-DldwGNqR.d.ts → tool-host-C8JMMGYq.d.ts} +1 -1
  118. package/dist/{types-Cq5u8MJ8.d.cts → types-CCSBGW9T.d.cts} +1 -1
  119. package/dist/{types-DyaHnqNC.d.ts → types-DIVNcIQO.d.ts} +1 -1
  120. package/dist/{types-C2zdUpzn.d.cts → types-aOQLTW0E.d.cts} +1 -1
  121. package/dist/{types-C2zdUpzn.d.ts → types-aOQLTW0E.d.ts} +1 -1
  122. package/dist/undo/index.d.cts +6 -43
  123. package/dist/undo/index.d.ts +6 -43
  124. package/dist/undo.cjs +31 -53
  125. package/dist/undo.cjs.map +1 -1
  126. package/dist/undo.js +2 -2
  127. package/package.json +188 -51
  128. package/dist/chunk-7X5ZAU4P.js.map +0 -1
  129. package/dist/chunk-GQ7XXK7G.js.map +0 -1
  130. package/dist/chunk-JU2N4KK6.js +0 -34
  131. package/dist/chunk-JU2N4KK6.js.map +0 -1
  132. package/dist/registry-2DRURS6U.js +0 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-stack.ts","../src/undo/undo-tools.ts","../src/bridges/artboard.ts"],"names":["history"],"mappings":"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","file":"bridges-artboard.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { ActivityFilter, AgentActivityEvent, AgentActivityListener } from \"./types\";\n\n/**\n * In-process registry of agent activity events. Bridges call `emitActivity`\n * after a tool runs; React hooks + the SSE relay subscribe via\n * `onActivity()`.\n *\n * Holds a short scrollback of recent events (default 200) so newly-mounted\n * subscribers can render the recent past — useful for activity-log UIs\n * that rejoin a session mid-stream.\n */\n\nconst HISTORY_CAP = 200;\n\nconst listeners = new Set<AgentActivityListener>();\nconst history: AgentActivityEvent[] = [];\n\n/** Emit an activity event. All current listeners receive it synchronously. */\nexport function emitActivity(event: AgentActivityEvent): void {\n history.push(event);\n if (history.length > HISTORY_CAP) history.splice(0, history.length - HISTORY_CAP);\n for (const l of listeners) l(event);\n}\n\n/**\n * Subscribe to all events (or a filtered subset). Returns an unsubscribe\n * function. Filter checks all provided keys with strict equality; omit a\n * key to ignore it.\n */\nexport function onActivity(listener: AgentActivityListener, filter?: ActivityFilter): () => void {\n const wrapped: AgentActivityListener = filter\n ? (e) => { if (matches(e, filter)) listener(e); }\n : listener;\n listeners.add(wrapped);\n return () => listeners.delete(wrapped);\n}\n\n/** Read the recent history (newest last). Optional filter. */\nexport function readActivityHistory(filter?: ActivityFilter): AgentActivityEvent[] {\n if (!filter) return history.slice();\n return history.filter((e) => matches(e, filter));\n}\n\n/** Wipe history + clear listeners. Test/teardown helper. */\nexport function resetActivityRegistry(): void {\n listeners.clear();\n history.length = 0;\n}\n\nfunction matches(e: AgentActivityEvent, f: ActivityFilter): boolean {\n if (f.agentId !== undefined && e.agentId !== f.agentId) return false;\n if (f.screenId !== undefined && e.target.screenId !== f.screenId) return false;\n if (f.kind !== undefined && e.target.kind !== f.kind) return false;\n return true;\n}\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","/**\n * Generic undo/redo stack keyed by `agentId`. Each entry holds:\n * - `do` — re-applies the action (for redo)\n * - `undo` — reverses it\n * - `label` — human-readable summary surfaced in agent_history\n *\n * Bridges register entries by calling `pushUndoEntry` after a successful\n * mutation. The corresponding MCP tools (`agent_undo`, `agent_redo`,\n * `agent_history`) are registered once per server via `registerUndoTools`.\n *\n * Stacks are per-agent so multiple agents can rewind independently.\n */\n\nexport type UndoEntry = {\n /** Wall-clock ms. */\n timestamp: number;\n /** Bridge id (e.g. \"whiteboard\", \"form:signup\"). */\n bridgeId: string;\n /** Tool name that produced the entry. */\n action: string;\n /** Short human label, e.g. `Added sticky n_abc`. */\n label: string;\n /** Reverse the action. */\n undo: () => void | Promise<void>;\n /** Re-apply the action (used when redoing after an undo). */\n redo: () => void | Promise<void>;\n};\n\ntype Stack = { past: UndoEntry[]; future: UndoEntry[] };\n\nconst stacks = new Map<string, Stack>();\nconst CAP = 200;\n\nfunction getStack(agentId: string): Stack {\n let s = stacks.get(agentId);\n if (!s) {\n s = { past: [], future: [] };\n stacks.set(agentId, s);\n }\n return s;\n}\n\n/** Push a new undo entry on the agent's stack. Clears the redo (future) stack. */\nexport function pushUndoEntry(agentId: string, entry: UndoEntry): void {\n const s = getStack(agentId);\n s.past.push(entry);\n if (s.past.length > CAP) s.past.splice(0, s.past.length - CAP);\n s.future.length = 0;\n}\n\n/** Pop and undo the most recent entry. Returns the entry that ran, or null. */\nexport async function undoOne(agentId: string): Promise<UndoEntry | null> {\n const s = getStack(agentId);\n const entry = s.past.pop();\n if (!entry) return null;\n await entry.undo();\n s.future.push(entry);\n return entry;\n}\n\n/** Re-apply the most recently undone entry. Returns it, or null if no future. */\nexport async function redoOne(agentId: string): Promise<UndoEntry | null> {\n const s = getStack(agentId);\n const entry = s.future.pop();\n if (!entry) return null;\n await entry.redo();\n s.past.push(entry);\n return entry;\n}\n\n/** Read the past stack (oldest first). */\nexport function readHistory(agentId: string): UndoEntry[] {\n return getStack(agentId).past.slice();\n}\n\n/** Wipe an agent's stacks. */\nexport function clearStack(agentId: string): void {\n stacks.delete(agentId);\n}\n\n/** Test/teardown helper. */\nexport function resetAllUndoStacks(): void {\n stacks.clear();\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Transport-level JSON shapes. These intentionally mirror fancy-artboard's\n * public `ArtBoardValue` but are defined LOCALLY so this bridge builds\n * independently of the sibling package — they are plain JSON crossing the\n * MCP wire, not the live component types. Keep them in sync with\n * @particle-academy/fancy-artboard's public surface.\n */\ntype Viewport = { x: number; y: number; zoom: number };\ntype ArtPieceContent =\n | { kind: \"image\"; src: string; alt?: string }\n | { kind: \"html\"; html: string }\n | { kind: \"node\" };\ntype ArtPieceData = {\n id: string;\n label?: string;\n width?: number;\n height?: number;\n content: ArtPieceContent;\n pending?: boolean;\n};\ntype ArtSectionData = {\n id: string;\n title: string;\n subtitle?: string;\n pieces: ArtPieceData[];\n};\ntype ArtBoardValue = { sections: ArtSectionData[] };\n\n/**\n * State accessors / mutators the bridge needs from the host. The host owns\n * artboard state (controlled props on fancy-artboard components); the bridge\n * calls into these to read or change it.\n */\nexport type ArtboardBridgeAdapter = {\n getValue: () => ArtBoardValue;\n setValue: (next: ArtBoardValue | ((prev: ArtBoardValue) => ArtBoardValue)) => void;\n getViewport: () => Viewport;\n setViewport: (next: Viewport) => void;\n getFocus: () => string | null;\n setFocus: (id: string | null) => void;\n /** Optional: agent presence cursor (for the visualizer). */\n setAgentCursor?: (cursor: { x: number; y: number } | null) => void;\n};\n\nexport type ArtboardBridgeOptions = {\n adapter: ArtboardBridgeAdapter;\n /** Identity used when the agent stamps authorship / cursor. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/** Deep-clone helper for snapshotting pieces/sections for undo closures. */\nconst clone = <T,>(v: T): T => JSON.parse(JSON.stringify(v)) as T;\n\n/** Coerce arbitrary JSON into a valid ArtPieceContent, defaulting to a node. */\nconst coerceContent = (v: unknown): ArtPieceContent => {\n if (v && typeof v === \"object\") {\n const c = v as Record<string, unknown>;\n if (c.kind === \"image\") return { kind: \"image\", src: str(c.src), ...(c.alt !== undefined ? { alt: str(c.alt) } : {}) };\n if (c.kind === \"html\") return { kind: \"html\", html: str(c.html) };\n if (c.kind === \"node\") return { kind: \"node\" };\n }\n return { kind: \"node\" };\n};\n\n/**\n * registerArtboardBridge — wires a full MCP tool set against a fancy-artboard\n * session controlled by the host. Returns a Bridge handle the host can dispose\n * to tear everything down.\n */\nexport function registerArtboardBridge(\n host: ToolHost,\n options: ArtboardBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Register agent_undo / agent_redo / agent_history once per server. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n // Activity-target resolver shared by every mutation tool. Pulls the touched\n // piece/section id from the result (structuredContent) when present, falling\n // back to the args id for rename/remove/focus tools.\n const abTarget = (args: any, result: any): AgentTarget => ({\n kind: \"artboard\",\n id:\n (result?.structuredContent?.id as string | undefined) ??\n (args?.pieceId as string | undefined) ??\n (args?.sectionId as string | undefined),\n } as AgentTarget);\n\n const reg = (\n name: string,\n description: string,\n inputProperties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n /** Optional: resolve the activity target so the presence layer can render\n * a focus indicator on the touched element. Read tools omit this. */\n resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"artboard\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: inputProperties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"artboard_get_state\", \"Get the full board state: viewport, focus, all sections and pieces.\", {}, [], () => {\n const state = {\n viewport: adapter.getViewport(),\n focus: adapter.getFocus(),\n sections: adapter.getValue().sections,\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"artboard_list_pieces\", \"List sections and their pieces with id, label, and content kind.\", {}, [], () => {\n const lines: string[] = [];\n const summary: Array<{ sectionId: string; title: string; pieces: Array<{ id: string; label?: string; kind: string; pending?: boolean }> }> = [];\n for (const s of adapter.getValue().sections) {\n lines.push(`section ${s.id}: \"${s.title}\"`);\n const pieces = s.pieces.map((p) => ({\n id: p.id,\n ...(p.label !== undefined ? { label: p.label } : {}),\n kind: p.content.kind,\n ...(p.pending ? { pending: true } : {}),\n }));\n for (const p of s.pieces) {\n lines.push(` piece ${p.id}: ${p.label ? `\"${p.label}\" ` : \"\"}[${p.content.kind}]${p.pending ? \" (pending)\" : \"\"}`);\n }\n summary.push({ sectionId: s.id, title: s.title, pieces });\n }\n return textResult(lines.join(\"\\n\") || \"(empty board)\", summary);\n });\n\n // ───────────── Piece tools ─────────────\n\n reg(\n \"artboard_add_piece\",\n \"Add a piece to a section. New agent-added pieces default to pending:true (trust-but-verify — a human confirms before it is final).\",\n {\n sectionId: { type: \"string\" },\n piece: {\n type: \"object\",\n description: \"Piece spec: { label?, width?, height?, content }. content is { kind: 'image', src, alt? } | { kind: 'html', html } | { kind: 'node' }.\",\n },\n index: { type: \"number\", description: \"Insertion index within the section. Defaults to the end.\" },\n },\n [\"sectionId\", \"piece\"],\n (args) => {\n const sectionId = str(args.sectionId);\n const section = adapter.getValue().sections.find((s) => s.id === sectionId);\n if (!section) return errorResult(`No section with id ${sectionId}`);\n const spec = (args.piece ?? {}) as Record<string, unknown>;\n const piece: ArtPieceData = {\n id: newId(\"p\"),\n ...(spec.label !== undefined ? { label: str(spec.label) } : {}),\n ...(spec.width !== undefined ? { width: num(spec.width) } : {}),\n ...(spec.height !== undefined ? { height: num(spec.height) } : {}),\n content: coerceContent(spec.content),\n pending: true,\n };\n const insertAt =\n args.index !== undefined ? Math.max(0, Math.min(num(args.index), section.pieces.length)) : section.pieces.length;\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, insertAt), piece, ...s.pieces.slice(insertAt)] },\n ),\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_add_piece\",\n label: `Added piece ${piece.id} to ${sectionId}`,\n undo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== piece.id) },\n ),\n })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, insertAt), piece, ...s.pieces.slice(insertAt)] },\n ),\n })),\n });\n return textResult(`Added piece ${piece.id} to section ${sectionId} (pending)`, piece);\n },\n abTarget,\n );\n\n reg(\n \"artboard_remove_piece\",\n \"Remove a piece by id.\",\n { pieceId: { type: \"string\" } },\n [\"pieceId\"],\n (args) => {\n const pieceId = str(args.pieceId);\n let removed: ArtPieceData | null = null;\n let fromSection: string | null = null;\n let oldIndex = -1;\n for (const s of adapter.getValue().sections) {\n const idx = s.pieces.findIndex((p) => p.id === pieceId);\n if (idx !== -1) {\n removed = clone(s.pieces[idx]);\n fromSection = s.id;\n oldIndex = idx;\n break;\n }\n }\n if (!removed || fromSection === null) return errorResult(`No piece with id ${pieceId}`);\n const sectionId = fromSection;\n const snapshot = removed;\n const at = oldIndex;\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) },\n ),\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_remove_piece\",\n label: `Removed piece ${pieceId}`,\n undo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, at), clone(snapshot), ...s.pieces.slice(at)] },\n ),\n })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) },\n ),\n })),\n });\n return textResult(`Removed piece ${pieceId}`, { id: pieceId });\n },\n abTarget,\n );\n\n reg(\n \"artboard_reorder_piece\",\n \"Move a piece to a new index, optionally into a different section.\",\n {\n pieceId: { type: \"string\" },\n sectionId: { type: \"string\", description: \"Target section id. Defaults to the piece's current section.\" },\n toIndex: { type: \"number\" },\n },\n [\"pieceId\", \"toIndex\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const before = adapter.getValue();\n // Locate the piece.\n let piece: ArtPieceData | null = null;\n let srcSection: string | null = null;\n for (const s of before.sections) {\n const found = s.pieces.find((p) => p.id === pieceId);\n if (found) {\n piece = found;\n srcSection = s.id;\n break;\n }\n }\n if (!piece || srcSection === null) return errorResult(`No piece with id ${pieceId}`);\n const dstSection = args.sectionId !== undefined ? str(args.sectionId) : srcSection;\n if (!before.sections.some((s) => s.id === dstSection)) return errorResult(`No section with id ${dstSection}`);\n const toIndex = Math.max(0, num(args.toIndex));\n const moving = piece;\n const snapshot = clone(before);\n adapter.setValue((prev) => {\n // Remove from wherever it currently is.\n const stripped = prev.sections.map((s) => ({ ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) }));\n return {\n sections: stripped.map((s) => {\n if (s.id !== dstSection) return s;\n const clamped = Math.min(toIndex, s.pieces.length);\n return { ...s, pieces: [...s.pieces.slice(0, clamped), moving, ...s.pieces.slice(clamped)] };\n }),\n };\n });\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_reorder_piece\",\n label: `Reordered piece ${pieceId}`,\n undo: () => adapter.setValue(() => clone(snapshot)),\n redo: () =>\n adapter.setValue((prev) => {\n const stripped = prev.sections.map((s) => ({ ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) }));\n return {\n sections: stripped.map((s) => {\n if (s.id !== dstSection) return s;\n const clamped = Math.min(toIndex, s.pieces.length);\n return { ...s, pieces: [...s.pieces.slice(0, clamped), moving, ...s.pieces.slice(clamped)] };\n }),\n };\n }),\n });\n return textResult(`Reordered piece ${pieceId} → ${dstSection}[${toIndex}]`, { id: pieceId, sectionId: dstSection, toIndex });\n },\n abTarget,\n );\n\n reg(\n \"artboard_rename_piece\",\n \"Set a piece's label.\",\n { pieceId: { type: \"string\" }, label: { type: \"string\" } },\n [\"pieceId\", \"label\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const label = str(args.label);\n const existing = adapter.getValue().sections.flatMap((s) => s.pieces).find((p) => p.id === pieceId);\n if (!existing) return errorResult(`No piece with id ${pieceId}`);\n const prevLabel = existing.label;\n const apply = (l: string | undefined) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) => ({\n ...s,\n pieces: s.pieces.map((p) => (p.id !== pieceId ? p : { ...p, ...(l !== undefined ? { label: l } : {}) })),\n })),\n }));\n apply(label);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_rename_piece\",\n label: `Renamed piece ${pieceId}`,\n undo: () => apply(prevLabel),\n redo: () => apply(label),\n });\n return textResult(`Renamed piece ${pieceId} → \"${label}\"`, { id: pieceId, label });\n },\n abTarget,\n );\n\n reg(\n \"artboard_set_piece_content\",\n \"Replace a piece's content. content is { kind: 'image', src, alt? } | { kind: 'html', html } | { kind: 'node' }.\",\n { pieceId: { type: \"string\" }, content: { type: \"object\" } },\n [\"pieceId\", \"content\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const existing = adapter.getValue().sections.flatMap((s) => s.pieces).find((p) => p.id === pieceId);\n if (!existing) return errorResult(`No piece with id ${pieceId}`);\n const prevContent = clone(existing.content);\n const nextContent = coerceContent(args.content);\n const apply = (c: ArtPieceContent) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) => ({\n ...s,\n pieces: s.pieces.map((p) => (p.id !== pieceId ? p : { ...p, content: clone(c) })),\n })),\n }));\n apply(nextContent);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_set_piece_content\",\n label: `Set content of piece ${pieceId}`,\n undo: () => apply(prevContent),\n redo: () => apply(nextContent),\n });\n return textResult(`Set content of piece ${pieceId} → ${nextContent.kind}`, { id: pieceId, content: nextContent });\n },\n abTarget,\n );\n\n reg(\n \"artboard_focus_piece\",\n \"Focus a piece by id (or pass null to clear focus).\",\n { pieceId: { type: [\"string\", \"null\"] } },\n [],\n (args) => {\n const raw = args.pieceId;\n const pieceId = typeof raw === \"string\" ? raw : null;\n if (pieceId !== null && !adapter.getValue().sections.some((s) => s.pieces.some((p) => p.id === pieceId))) {\n return errorResult(`No piece with id ${pieceId}`);\n }\n adapter.setFocus(pieceId);\n return textResult(pieceId ? `Focused piece ${pieceId}` : \"Cleared focus\", { id: pieceId });\n },\n abTarget,\n );\n\n // ───────────── Section tools ─────────────\n\n reg(\n \"artboard_add_section\",\n \"Add a section. Provide an explicit id or one is generated.\",\n {\n section: { type: \"object\", description: \"Section spec: { id?, title, subtitle? }.\" },\n index: { type: \"number\", description: \"Insertion index. Defaults to the end.\" },\n },\n [\"section\"],\n (args) => {\n const spec = (args.section ?? {}) as Record<string, unknown>;\n const section: ArtSectionData = {\n id: spec.id !== undefined ? str(spec.id) : newId(\"sec\"),\n title: str(spec.title),\n ...(spec.subtitle !== undefined ? { subtitle: str(spec.subtitle) } : {}),\n pieces: [],\n };\n if (adapter.getValue().sections.some((s) => s.id === section.id)) {\n return errorResult(`Section id ${section.id} already exists`);\n }\n const insertAt =\n args.index !== undefined\n ? Math.max(0, Math.min(num(args.index), adapter.getValue().sections.length))\n : adapter.getValue().sections.length;\n adapter.setValue((prev) => ({\n sections: [...prev.sections.slice(0, insertAt), section, ...prev.sections.slice(insertAt)],\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_add_section\",\n label: `Added section ${section.id}`,\n undo: () => adapter.setValue((prev) => ({ sections: prev.sections.filter((s) => s.id !== section.id) })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: [...prev.sections.slice(0, insertAt), section, ...prev.sections.slice(insertAt)],\n })),\n });\n return textResult(`Added section ${section.id}`, section);\n },\n abTarget,\n );\n\n reg(\n \"artboard_rename_section\",\n \"Set a section's title and optionally its subtitle.\",\n { sectionId: { type: \"string\" }, title: { type: \"string\" }, subtitle: { type: \"string\" } },\n [\"sectionId\", \"title\"],\n (args) => {\n const sectionId = str(args.sectionId);\n const existing = adapter.getValue().sections.find((s) => s.id === sectionId);\n if (!existing) return errorResult(`No section with id ${sectionId}`);\n const prevTitle = existing.title;\n const prevSubtitle = existing.subtitle;\n const title = str(args.title);\n const hasSubtitle = args.subtitle !== undefined;\n const subtitle = hasSubtitle ? str(args.subtitle) : prevSubtitle;\n const apply = (t: string, sub: string | undefined) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId\n ? s\n : { ...s, title: t, ...(sub !== undefined ? { subtitle: sub } : {}) },\n ),\n }));\n apply(title, subtitle);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_rename_section\",\n label: `Renamed section ${sectionId}`,\n undo: () => apply(prevTitle, prevSubtitle),\n redo: () => apply(title, subtitle),\n });\n return textResult(`Renamed section ${sectionId} → \"${title}\"`, { id: sectionId, title, subtitle });\n },\n abTarget,\n );\n\n // ───────────── Viewport ─────────────\n\n reg(\n \"artboard_set_viewport\",\n \"Pan / zoom the viewport.\",\n { x: { type: \"number\" }, y: { type: \"number\" }, zoom: { type: \"number\" } },\n [],\n (args) => {\n const v = adapter.getViewport();\n const next: Viewport = {\n x: args.x !== undefined ? num(args.x) : v.x,\n y: args.y !== undefined ? num(args.y) : v.y,\n zoom: args.zoom !== undefined ? num(args.zoom) : v.zoom,\n };\n adapter.setViewport(next);\n return textResult(`Viewport → ${JSON.stringify(next)}`, next);\n },\n abTarget,\n );\n\n return {\n id: \"artboard\",\n title: \"Artboard\",\n dispose: () => {\n for (const d of disposers) d();\n adapter.setAgentCursor?.(null);\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-tools.ts","../src/bridges/artboard.ts"],"names":["emitActivity","undoOne","redoOne","readHistory","pushUndoEntry"],"mappings":"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","file":"bridges-artboard.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Transport-level JSON shapes. These intentionally mirror fancy-artboard's\n * public `ArtBoardValue` but are defined LOCALLY so this bridge builds\n * independently of the sibling package — they are plain JSON crossing the\n * MCP wire, not the live component types. Keep them in sync with\n * @particle-academy/fancy-artboard's public surface.\n */\ntype Viewport = { x: number; y: number; zoom: number };\ntype ArtPieceContent =\n | { kind: \"image\"; src: string; alt?: string }\n | { kind: \"html\"; html: string }\n | { kind: \"node\" };\ntype ArtPieceData = {\n id: string;\n label?: string;\n width?: number;\n height?: number;\n content: ArtPieceContent;\n pending?: boolean;\n};\ntype ArtSectionData = {\n id: string;\n title: string;\n subtitle?: string;\n pieces: ArtPieceData[];\n};\ntype ArtBoardValue = { sections: ArtSectionData[] };\n\n/**\n * State accessors / mutators the bridge needs from the host. The host owns\n * artboard state (controlled props on fancy-artboard components); the bridge\n * calls into these to read or change it.\n */\nexport type ArtboardBridgeAdapter = {\n getValue: () => ArtBoardValue;\n setValue: (next: ArtBoardValue | ((prev: ArtBoardValue) => ArtBoardValue)) => void;\n getViewport: () => Viewport;\n setViewport: (next: Viewport) => void;\n getFocus: () => string | null;\n setFocus: (id: string | null) => void;\n /** Optional: agent presence cursor (for the visualizer). */\n setAgentCursor?: (cursor: { x: number; y: number } | null) => void;\n};\n\nexport type ArtboardBridgeOptions = {\n adapter: ArtboardBridgeAdapter;\n /** Identity used when the agent stamps authorship / cursor. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/** Deep-clone helper for snapshotting pieces/sections for undo closures. */\nconst clone = <T,>(v: T): T => JSON.parse(JSON.stringify(v)) as T;\n\n/** Coerce arbitrary JSON into a valid ArtPieceContent, defaulting to a node. */\nconst coerceContent = (v: unknown): ArtPieceContent => {\n if (v && typeof v === \"object\") {\n const c = v as Record<string, unknown>;\n if (c.kind === \"image\") return { kind: \"image\", src: str(c.src), ...(c.alt !== undefined ? { alt: str(c.alt) } : {}) };\n if (c.kind === \"html\") return { kind: \"html\", html: str(c.html) };\n if (c.kind === \"node\") return { kind: \"node\" };\n }\n return { kind: \"node\" };\n};\n\n/**\n * registerArtboardBridge — wires a full MCP tool set against a fancy-artboard\n * session controlled by the host. Returns a Bridge handle the host can dispose\n * to tear everything down.\n */\nexport function registerArtboardBridge(\n host: ToolHost,\n options: ArtboardBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Register agent_undo / agent_redo / agent_history once per server. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n // Activity-target resolver shared by every mutation tool. Pulls the touched\n // piece/section id from the result (structuredContent) when present, falling\n // back to the args id for rename/remove/focus tools.\n const abTarget = (args: any, result: any): AgentTarget => ({\n kind: \"artboard\",\n id:\n (result?.structuredContent?.id as string | undefined) ??\n (args?.pieceId as string | undefined) ??\n (args?.sectionId as string | undefined),\n } as AgentTarget);\n\n const reg = (\n name: string,\n description: string,\n inputProperties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n /** Optional: resolve the activity target so the presence layer can render\n * a focus indicator on the touched element. Read tools omit this. */\n resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"artboard\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: inputProperties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"artboard_get_state\", \"Get the full board state: viewport, focus, all sections and pieces.\", {}, [], () => {\n const state = {\n viewport: adapter.getViewport(),\n focus: adapter.getFocus(),\n sections: adapter.getValue().sections,\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"artboard_list_pieces\", \"List sections and their pieces with id, label, and content kind.\", {}, [], () => {\n const lines: string[] = [];\n const summary: Array<{ sectionId: string; title: string; pieces: Array<{ id: string; label?: string; kind: string; pending?: boolean }> }> = [];\n for (const s of adapter.getValue().sections) {\n lines.push(`section ${s.id}: \"${s.title}\"`);\n const pieces = s.pieces.map((p) => ({\n id: p.id,\n ...(p.label !== undefined ? { label: p.label } : {}),\n kind: p.content.kind,\n ...(p.pending ? { pending: true } : {}),\n }));\n for (const p of s.pieces) {\n lines.push(` piece ${p.id}: ${p.label ? `\"${p.label}\" ` : \"\"}[${p.content.kind}]${p.pending ? \" (pending)\" : \"\"}`);\n }\n summary.push({ sectionId: s.id, title: s.title, pieces });\n }\n return textResult(lines.join(\"\\n\") || \"(empty board)\", summary);\n });\n\n // ───────────── Piece tools ─────────────\n\n reg(\n \"artboard_add_piece\",\n \"Add a piece to a section. New agent-added pieces default to pending:true (trust-but-verify — a human confirms before it is final).\",\n {\n sectionId: { type: \"string\" },\n piece: {\n type: \"object\",\n description: \"Piece spec: { label?, width?, height?, content }. content is { kind: 'image', src, alt? } | { kind: 'html', html } | { kind: 'node' }.\",\n },\n index: { type: \"number\", description: \"Insertion index within the section. Defaults to the end.\" },\n },\n [\"sectionId\", \"piece\"],\n (args) => {\n const sectionId = str(args.sectionId);\n const section = adapter.getValue().sections.find((s) => s.id === sectionId);\n if (!section) return errorResult(`No section with id ${sectionId}`);\n const spec = (args.piece ?? {}) as Record<string, unknown>;\n const piece: ArtPieceData = {\n id: newId(\"p\"),\n ...(spec.label !== undefined ? { label: str(spec.label) } : {}),\n ...(spec.width !== undefined ? { width: num(spec.width) } : {}),\n ...(spec.height !== undefined ? { height: num(spec.height) } : {}),\n content: coerceContent(spec.content),\n pending: true,\n };\n const insertAt =\n args.index !== undefined ? Math.max(0, Math.min(num(args.index), section.pieces.length)) : section.pieces.length;\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, insertAt), piece, ...s.pieces.slice(insertAt)] },\n ),\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_add_piece\",\n label: `Added piece ${piece.id} to ${sectionId}`,\n undo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== piece.id) },\n ),\n })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, insertAt), piece, ...s.pieces.slice(insertAt)] },\n ),\n })),\n });\n return textResult(`Added piece ${piece.id} to section ${sectionId} (pending)`, piece);\n },\n abTarget,\n );\n\n reg(\n \"artboard_remove_piece\",\n \"Remove a piece by id.\",\n { pieceId: { type: \"string\" } },\n [\"pieceId\"],\n (args) => {\n const pieceId = str(args.pieceId);\n let removed: ArtPieceData | null = null;\n let fromSection: string | null = null;\n let oldIndex = -1;\n for (const s of adapter.getValue().sections) {\n const idx = s.pieces.findIndex((p) => p.id === pieceId);\n if (idx !== -1) {\n removed = clone(s.pieces[idx]);\n fromSection = s.id;\n oldIndex = idx;\n break;\n }\n }\n if (!removed || fromSection === null) return errorResult(`No piece with id ${pieceId}`);\n const sectionId = fromSection;\n const snapshot = removed;\n const at = oldIndex;\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) },\n ),\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_remove_piece\",\n label: `Removed piece ${pieceId}`,\n undo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: [...s.pieces.slice(0, at), clone(snapshot), ...s.pieces.slice(at)] },\n ),\n })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId ? s : { ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) },\n ),\n })),\n });\n return textResult(`Removed piece ${pieceId}`, { id: pieceId });\n },\n abTarget,\n );\n\n reg(\n \"artboard_reorder_piece\",\n \"Move a piece to a new index, optionally into a different section.\",\n {\n pieceId: { type: \"string\" },\n sectionId: { type: \"string\", description: \"Target section id. Defaults to the piece's current section.\" },\n toIndex: { type: \"number\" },\n },\n [\"pieceId\", \"toIndex\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const before = adapter.getValue();\n // Locate the piece.\n let piece: ArtPieceData | null = null;\n let srcSection: string | null = null;\n for (const s of before.sections) {\n const found = s.pieces.find((p) => p.id === pieceId);\n if (found) {\n piece = found;\n srcSection = s.id;\n break;\n }\n }\n if (!piece || srcSection === null) return errorResult(`No piece with id ${pieceId}`);\n const dstSection = args.sectionId !== undefined ? str(args.sectionId) : srcSection;\n if (!before.sections.some((s) => s.id === dstSection)) return errorResult(`No section with id ${dstSection}`);\n const toIndex = Math.max(0, num(args.toIndex));\n const moving = piece;\n const snapshot = clone(before);\n adapter.setValue((prev) => {\n // Remove from wherever it currently is.\n const stripped = prev.sections.map((s) => ({ ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) }));\n return {\n sections: stripped.map((s) => {\n if (s.id !== dstSection) return s;\n const clamped = Math.min(toIndex, s.pieces.length);\n return { ...s, pieces: [...s.pieces.slice(0, clamped), moving, ...s.pieces.slice(clamped)] };\n }),\n };\n });\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_reorder_piece\",\n label: `Reordered piece ${pieceId}`,\n undo: () => adapter.setValue(() => clone(snapshot)),\n redo: () =>\n adapter.setValue((prev) => {\n const stripped = prev.sections.map((s) => ({ ...s, pieces: s.pieces.filter((p) => p.id !== pieceId) }));\n return {\n sections: stripped.map((s) => {\n if (s.id !== dstSection) return s;\n const clamped = Math.min(toIndex, s.pieces.length);\n return { ...s, pieces: [...s.pieces.slice(0, clamped), moving, ...s.pieces.slice(clamped)] };\n }),\n };\n }),\n });\n return textResult(`Reordered piece ${pieceId} → ${dstSection}[${toIndex}]`, { id: pieceId, sectionId: dstSection, toIndex });\n },\n abTarget,\n );\n\n reg(\n \"artboard_rename_piece\",\n \"Set a piece's label.\",\n { pieceId: { type: \"string\" }, label: { type: \"string\" } },\n [\"pieceId\", \"label\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const label = str(args.label);\n const existing = adapter.getValue().sections.flatMap((s) => s.pieces).find((p) => p.id === pieceId);\n if (!existing) return errorResult(`No piece with id ${pieceId}`);\n const prevLabel = existing.label;\n const apply = (l: string | undefined) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) => ({\n ...s,\n pieces: s.pieces.map((p) => (p.id !== pieceId ? p : { ...p, ...(l !== undefined ? { label: l } : {}) })),\n })),\n }));\n apply(label);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_rename_piece\",\n label: `Renamed piece ${pieceId}`,\n undo: () => apply(prevLabel),\n redo: () => apply(label),\n });\n return textResult(`Renamed piece ${pieceId} → \"${label}\"`, { id: pieceId, label });\n },\n abTarget,\n );\n\n reg(\n \"artboard_set_piece_content\",\n \"Replace a piece's content. content is { kind: 'image', src, alt? } | { kind: 'html', html } | { kind: 'node' }.\",\n { pieceId: { type: \"string\" }, content: { type: \"object\" } },\n [\"pieceId\", \"content\"],\n (args) => {\n const pieceId = str(args.pieceId);\n const existing = adapter.getValue().sections.flatMap((s) => s.pieces).find((p) => p.id === pieceId);\n if (!existing) return errorResult(`No piece with id ${pieceId}`);\n const prevContent = clone(existing.content);\n const nextContent = coerceContent(args.content);\n const apply = (c: ArtPieceContent) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) => ({\n ...s,\n pieces: s.pieces.map((p) => (p.id !== pieceId ? p : { ...p, content: clone(c) })),\n })),\n }));\n apply(nextContent);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_set_piece_content\",\n label: `Set content of piece ${pieceId}`,\n undo: () => apply(prevContent),\n redo: () => apply(nextContent),\n });\n return textResult(`Set content of piece ${pieceId} → ${nextContent.kind}`, { id: pieceId, content: nextContent });\n },\n abTarget,\n );\n\n reg(\n \"artboard_focus_piece\",\n \"Focus a piece by id (or pass null to clear focus).\",\n { pieceId: { type: [\"string\", \"null\"] } },\n [],\n (args) => {\n const raw = args.pieceId;\n const pieceId = typeof raw === \"string\" ? raw : null;\n if (pieceId !== null && !adapter.getValue().sections.some((s) => s.pieces.some((p) => p.id === pieceId))) {\n return errorResult(`No piece with id ${pieceId}`);\n }\n adapter.setFocus(pieceId);\n return textResult(pieceId ? `Focused piece ${pieceId}` : \"Cleared focus\", { id: pieceId });\n },\n abTarget,\n );\n\n // ───────────── Section tools ─────────────\n\n reg(\n \"artboard_add_section\",\n \"Add a section. Provide an explicit id or one is generated.\",\n {\n section: { type: \"object\", description: \"Section spec: { id?, title, subtitle? }.\" },\n index: { type: \"number\", description: \"Insertion index. Defaults to the end.\" },\n },\n [\"section\"],\n (args) => {\n const spec = (args.section ?? {}) as Record<string, unknown>;\n const section: ArtSectionData = {\n id: spec.id !== undefined ? str(spec.id) : newId(\"sec\"),\n title: str(spec.title),\n ...(spec.subtitle !== undefined ? { subtitle: str(spec.subtitle) } : {}),\n pieces: [],\n };\n if (adapter.getValue().sections.some((s) => s.id === section.id)) {\n return errorResult(`Section id ${section.id} already exists`);\n }\n const insertAt =\n args.index !== undefined\n ? Math.max(0, Math.min(num(args.index), adapter.getValue().sections.length))\n : adapter.getValue().sections.length;\n adapter.setValue((prev) => ({\n sections: [...prev.sections.slice(0, insertAt), section, ...prev.sections.slice(insertAt)],\n }));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_add_section\",\n label: `Added section ${section.id}`,\n undo: () => adapter.setValue((prev) => ({ sections: prev.sections.filter((s) => s.id !== section.id) })),\n redo: () =>\n adapter.setValue((prev) => ({\n sections: [...prev.sections.slice(0, insertAt), section, ...prev.sections.slice(insertAt)],\n })),\n });\n return textResult(`Added section ${section.id}`, section);\n },\n abTarget,\n );\n\n reg(\n \"artboard_rename_section\",\n \"Set a section's title and optionally its subtitle.\",\n { sectionId: { type: \"string\" }, title: { type: \"string\" }, subtitle: { type: \"string\" } },\n [\"sectionId\", \"title\"],\n (args) => {\n const sectionId = str(args.sectionId);\n const existing = adapter.getValue().sections.find((s) => s.id === sectionId);\n if (!existing) return errorResult(`No section with id ${sectionId}`);\n const prevTitle = existing.title;\n const prevSubtitle = existing.subtitle;\n const title = str(args.title);\n const hasSubtitle = args.subtitle !== undefined;\n const subtitle = hasSubtitle ? str(args.subtitle) : prevSubtitle;\n const apply = (t: string, sub: string | undefined) =>\n adapter.setValue((prev) => ({\n sections: prev.sections.map((s) =>\n s.id !== sectionId\n ? s\n : { ...s, title: t, ...(sub !== undefined ? { subtitle: sub } : {}) },\n ),\n }));\n apply(title, subtitle);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"artboard\",\n action: \"artboard_rename_section\",\n label: `Renamed section ${sectionId}`,\n undo: () => apply(prevTitle, prevSubtitle),\n redo: () => apply(title, subtitle),\n });\n return textResult(`Renamed section ${sectionId} → \"${title}\"`, { id: sectionId, title, subtitle });\n },\n abTarget,\n );\n\n // ───────────── Viewport ─────────────\n\n reg(\n \"artboard_set_viewport\",\n \"Pan / zoom the viewport.\",\n { x: { type: \"number\" }, y: { type: \"number\" }, zoom: { type: \"number\" } },\n [],\n (args) => {\n const v = adapter.getViewport();\n const next: Viewport = {\n x: args.x !== undefined ? num(args.x) : v.x,\n y: args.y !== undefined ? num(args.y) : v.y,\n zoom: args.zoom !== undefined ? num(args.zoom) : v.zoom,\n };\n adapter.setViewport(next);\n return textResult(`Viewport → ${JSON.stringify(next)}`, next);\n },\n abTarget,\n );\n\n return {\n id: \"artboard\",\n title: \"Artboard\",\n dispose: () => {\n for (const d of disposers) d();\n adapter.setAgentCursor?.(null);\n },\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { ensureUndoToolsRegistered, pushUndoEntry } from './chunk-GQ7XXK7G.js';
2
- import { wrapToolWithActivity } from './chunk-52S7XYZK.js';
3
- import './chunk-JU2N4KK6.js';
1
+ import { ensureUndoToolsRegistered, pushUndoEntry } from './chunk-KJ5AOOV7.js';
2
+ import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
3
+ import './chunk-C3TYI5TJ.js';
4
4
  import { errorResult, textResult } from './chunk-4KAIV6OD.js';
5
5
 
6
6
  // src/bridges/artboard.ts
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var fancyAutoCommon = require('@particle-academy/fancy-auto-common');
4
+
3
5
  // src/mcp/server.ts
4
6
  function textResult(text, structured) {
5
7
  return {
@@ -10,10 +12,6 @@ function textResult(text, structured) {
10
12
  function errorResult(text) {
11
13
  return { content: [{ type: "text", text }], isError: true };
12
14
  }
13
- var listeners = /* @__PURE__ */ new Set();
14
- function emitActivity(event) {
15
- for (const l of listeners) l(event);
16
- }
17
15
 
18
16
  // src/presence/wrap-tool-with-activity.ts
19
17
  function wrapToolWithActivity(handler, options) {
@@ -27,7 +25,7 @@ function wrapToolWithActivity(handler, options) {
27
25
  target = { kind: options.kind, screenId: options.screenId };
28
26
  }
29
27
  if (!target) return result;
30
- emitActivity({
28
+ fancyAutoCommon.emitActivity({
31
29
  agentId: options.agent.id,
32
30
  agentName: options.agent.name,
33
31
  agentColor: options.agent.color,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/charts.ts"],"names":[],"mappings":"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","file":"bridges-charts.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { ActivityFilter, AgentActivityEvent, AgentActivityListener } from \"./types\";\n\n/**\n * In-process registry of agent activity events. Bridges call `emitActivity`\n * after a tool runs; React hooks + the SSE relay subscribe via\n * `onActivity()`.\n *\n * Holds a short scrollback of recent events (default 200) so newly-mounted\n * subscribers can render the recent past — useful for activity-log UIs\n * that rejoin a session mid-stream.\n */\n\nconst HISTORY_CAP = 200;\n\nconst listeners = new Set<AgentActivityListener>();\nconst history: AgentActivityEvent[] = [];\n\n/** Emit an activity event. All current listeners receive it synchronously. */\nexport function emitActivity(event: AgentActivityEvent): void {\n history.push(event);\n if (history.length > HISTORY_CAP) history.splice(0, history.length - HISTORY_CAP);\n for (const l of listeners) l(event);\n}\n\n/**\n * Subscribe to all events (or a filtered subset). Returns an unsubscribe\n * function. Filter checks all provided keys with strict equality; omit a\n * key to ignore it.\n */\nexport function onActivity(listener: AgentActivityListener, filter?: ActivityFilter): () => void {\n const wrapped: AgentActivityListener = filter\n ? (e) => { if (matches(e, filter)) listener(e); }\n : listener;\n listeners.add(wrapped);\n return () => listeners.delete(wrapped);\n}\n\n/** Read the recent history (newest last). Optional filter. */\nexport function readActivityHistory(filter?: ActivityFilter): AgentActivityEvent[] {\n if (!filter) return history.slice();\n return history.filter((e) => matches(e, filter));\n}\n\n/** Wipe history + clear listeners. Test/teardown helper. */\nexport function resetActivityRegistry(): void {\n listeners.clear();\n history.length = 0;\n}\n\nfunction matches(e: AgentActivityEvent, f: ActivityFilter): boolean {\n if (f.agentId !== undefined && e.agentId !== f.agentId) return false;\n if (f.screenId !== undefined && e.target.screenId !== f.screenId) return false;\n if (f.kind !== undefined && e.target.kind !== f.kind) return false;\n return true;\n}\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Adapter wires a single fancy-echarts chart to the bridge. Charts are\n * already prop-driven, so the adapter just exposes the data + option\n * setters and a way to read what's currently rendered.\n */\nexport type ChartsBridgeAdapter = {\n /** Stable id for this chart instance. */\n id: string;\n title?: string;\n screenId?: string;\n /** Read the current ECharts option object the chart is rendering. */\n getOption: () => Record<string, unknown>;\n /** Replace the entire option. */\n setOption: (option: Record<string, unknown>) => void;\n /** Convenience: shallow-merge a partial option update. */\n updateOption?: (partial: Record<string, unknown>) => void;\n /** Read just the data series (subset of option for quick agent reads). */\n getData?: () => unknown;\n /** Update only the data, leaving axes/colors/etc. alone. */\n updateData?: (data: unknown) => void;\n};\n\nexport type ChartsBridgeOptions = {\n adapter: ChartsBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerChartsBridge — schema-aware MCP access to a single chart.\n */\nexport function registerChartsBridge(\n host: ToolHost,\n options: ChartsBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target: AgentTarget = {\n kind: \"chart\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try { return await handler(args); }\n catch (e) { return errorResult(e instanceof Error ? e.message : String(e)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"chart\", screenId: adapter.screenId,\n resolveTarget: () => target,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n reg(\n \"chart_describe\",\n `Describe the chart \"${adapter.id}\" — series count, type guesses, axis info.`,\n {},\n [],\n () => {\n const opt = adapter.getOption();\n const series = Array.isArray(opt.series) ? opt.series : [];\n const summary = {\n id: adapter.id,\n title: adapter.title,\n seriesCount: series.length,\n seriesTypes: series.map((s: any) => s?.type ?? \"unknown\"),\n hasXAxis: !!opt.xAxis,\n hasYAxis: !!opt.yAxis,\n };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"chart_get_option\",\n \"Read the full ECharts option object the chart is rendering.\",\n {},\n [],\n () => {\n const opt = adapter.getOption();\n return textResult(JSON.stringify(opt, null, 2), opt);\n },\n false,\n );\n\n reg(\n \"chart_set_option\",\n \"Replace the entire ECharts option. Use chart_update_option for partial updates.\",\n { option: { type: \"object\" } },\n [\"option\"],\n (args) => {\n const opt = (args.option && typeof args.option === \"object\") ? args.option as Record<string, unknown> : {};\n adapter.setOption(opt);\n return textResult(\"Replaced chart option\", { });\n },\n true,\n );\n\n reg(\n \"chart_update_option\",\n \"Shallow-merge a partial option update — only the keys you provide change.\",\n { partial: { type: \"object\" } },\n [\"partial\"],\n (args) => {\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n if (adapter.updateOption) {\n adapter.updateOption(partial);\n } else {\n adapter.setOption({ ...adapter.getOption(), ...partial });\n }\n return textResult(\"Merged chart option\", { keys: Object.keys(partial) });\n },\n true,\n );\n\n reg(\n \"chart_update_data\",\n \"Update only the data (typically the `series` field). Leaves layout / axes / colors alone.\",\n { data: { description: \"New series array (or whatever shape the host's adapter expects).\" } },\n [\"data\"],\n (args) => {\n if (!adapter.updateData) return errorResult(\"Host did not provide updateData.\");\n adapter.updateData(args.data);\n return textResult(\"Updated chart data\", { });\n },\n true,\n );\n\n return {\n id: `chart:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/charts.ts"],"names":["emitActivity"],"mappings":"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","file":"bridges-charts.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Adapter wires a single fancy-echarts chart to the bridge. Charts are\n * already prop-driven, so the adapter just exposes the data + option\n * setters and a way to read what's currently rendered.\n */\nexport type ChartsBridgeAdapter = {\n /** Stable id for this chart instance. */\n id: string;\n title?: string;\n screenId?: string;\n /** Read the current ECharts option object the chart is rendering. */\n getOption: () => Record<string, unknown>;\n /** Replace the entire option. */\n setOption: (option: Record<string, unknown>) => void;\n /** Convenience: shallow-merge a partial option update. */\n updateOption?: (partial: Record<string, unknown>) => void;\n /** Read just the data series (subset of option for quick agent reads). */\n getData?: () => unknown;\n /** Update only the data, leaving axes/colors/etc. alone. */\n updateData?: (data: unknown) => void;\n};\n\nexport type ChartsBridgeOptions = {\n adapter: ChartsBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerChartsBridge — schema-aware MCP access to a single chart.\n */\nexport function registerChartsBridge(\n host: ToolHost,\n options: ChartsBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target: AgentTarget = {\n kind: \"chart\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try { return await handler(args); }\n catch (e) { return errorResult(e instanceof Error ? e.message : String(e)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"chart\", screenId: adapter.screenId,\n resolveTarget: () => target,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n reg(\n \"chart_describe\",\n `Describe the chart \"${adapter.id}\" — series count, type guesses, axis info.`,\n {},\n [],\n () => {\n const opt = adapter.getOption();\n const series = Array.isArray(opt.series) ? opt.series : [];\n const summary = {\n id: adapter.id,\n title: adapter.title,\n seriesCount: series.length,\n seriesTypes: series.map((s: any) => s?.type ?? \"unknown\"),\n hasXAxis: !!opt.xAxis,\n hasYAxis: !!opt.yAxis,\n };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"chart_get_option\",\n \"Read the full ECharts option object the chart is rendering.\",\n {},\n [],\n () => {\n const opt = adapter.getOption();\n return textResult(JSON.stringify(opt, null, 2), opt);\n },\n false,\n );\n\n reg(\n \"chart_set_option\",\n \"Replace the entire ECharts option. Use chart_update_option for partial updates.\",\n { option: { type: \"object\" } },\n [\"option\"],\n (args) => {\n const opt = (args.option && typeof args.option === \"object\") ? args.option as Record<string, unknown> : {};\n adapter.setOption(opt);\n return textResult(\"Replaced chart option\", { });\n },\n true,\n );\n\n reg(\n \"chart_update_option\",\n \"Shallow-merge a partial option update — only the keys you provide change.\",\n { partial: { type: \"object\" } },\n [\"partial\"],\n (args) => {\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n if (adapter.updateOption) {\n adapter.updateOption(partial);\n } else {\n adapter.setOption({ ...adapter.getOption(), ...partial });\n }\n return textResult(\"Merged chart option\", { keys: Object.keys(partial) });\n },\n true,\n );\n\n reg(\n \"chart_update_data\",\n \"Update only the data (typically the `series` field). Leaves layout / axes / colors alone.\",\n { data: { description: \"New series array (or whatever shape the host's adapter expects).\" } },\n [\"data\"],\n (args) => {\n if (!adapter.updateData) return errorResult(\"Host did not provide updateData.\");\n adapter.updateData(args.data);\n return textResult(\"Updated chart data\", { });\n },\n true,\n );\n\n return {\n id: `chart:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- export { registerChartsBridge } from './chunk-NTDZWGYB.js';
2
- import './chunk-52S7XYZK.js';
3
- import './chunk-JU2N4KK6.js';
1
+ export { registerChartsBridge } from './chunk-SJ7H242B.js';
2
+ import './chunk-ULJL53DL.js';
3
+ import './chunk-C3TYI5TJ.js';
4
4
  import './chunk-4KAIV6OD.js';
5
5
  //# sourceMappingURL=bridges-charts.js.map
6
6
  //# sourceMappingURL=bridges-charts.js.map
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var fancyAutoCommon = require('@particle-academy/fancy-auto-common');
4
+
3
5
  // src/mcp/server.ts
4
6
  function textResult(text, structured) {
5
7
  return {
@@ -10,10 +12,6 @@ function textResult(text, structured) {
10
12
  function errorResult(text) {
11
13
  return { content: [{ type: "text", text }], isError: true };
12
14
  }
13
- var listeners = /* @__PURE__ */ new Set();
14
- function emitActivity(event) {
15
- for (const l of listeners) l(event);
16
- }
17
15
 
18
16
  // src/presence/wrap-tool-with-activity.ts
19
17
  function wrapToolWithActivity(handler, options) {
@@ -27,7 +25,7 @@ function wrapToolWithActivity(handler, options) {
27
25
  target = { kind: options.kind, screenId: options.screenId };
28
26
  }
29
27
  if (!target) return result;
30
- emitActivity({
28
+ fancyAutoCommon.emitActivity({
31
29
  agentId: options.agent.id,
32
30
  agentName: options.agent.name,
33
31
  agentColor: options.agent.color,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/code.ts"],"names":[],"mappings":"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","file":"bridges-code.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { ActivityFilter, AgentActivityEvent, AgentActivityListener } from \"./types\";\n\n/**\n * In-process registry of agent activity events. Bridges call `emitActivity`\n * after a tool runs; React hooks + the SSE relay subscribe via\n * `onActivity()`.\n *\n * Holds a short scrollback of recent events (default 200) so newly-mounted\n * subscribers can render the recent past — useful for activity-log UIs\n * that rejoin a session mid-stream.\n */\n\nconst HISTORY_CAP = 200;\n\nconst listeners = new Set<AgentActivityListener>();\nconst history: AgentActivityEvent[] = [];\n\n/** Emit an activity event. All current listeners receive it synchronously. */\nexport function emitActivity(event: AgentActivityEvent): void {\n history.push(event);\n if (history.length > HISTORY_CAP) history.splice(0, history.length - HISTORY_CAP);\n for (const l of listeners) l(event);\n}\n\n/**\n * Subscribe to all events (or a filtered subset). Returns an unsubscribe\n * function. Filter checks all provided keys with strict equality; omit a\n * key to ignore it.\n */\nexport function onActivity(listener: AgentActivityListener, filter?: ActivityFilter): () => void {\n const wrapped: AgentActivityListener = filter\n ? (e) => { if (matches(e, filter)) listener(e); }\n : listener;\n listeners.add(wrapped);\n return () => listeners.delete(wrapped);\n}\n\n/** Read the recent history (newest last). Optional filter. */\nexport function readActivityHistory(filter?: ActivityFilter): AgentActivityEvent[] {\n if (!filter) return history.slice();\n return history.filter((e) => matches(e, filter));\n}\n\n/** Wipe history + clear listeners. Test/teardown helper. */\nexport function resetActivityRegistry(): void {\n listeners.clear();\n history.length = 0;\n}\n\nfunction matches(e: AgentActivityEvent, f: ActivityFilter): boolean {\n if (f.agentId !== undefined && e.agentId !== f.agentId) return false;\n if (f.screenId !== undefined && e.target.screenId !== f.screenId) return false;\n if (f.kind !== undefined && e.target.kind !== f.kind) return false;\n return true;\n}\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Adapter the host wires to a fancy-code CodeEditor (typically via the\n * useCodeEditor hook's context value).\n */\nexport type CodeBridgeAdapter = {\n /** Stable id for this editor instance. */\n id: string;\n /** Display label. */\n title?: string;\n /** Optional fancy-screens screen id. */\n screenId?: string;\n /** Read the current document text. */\n getValue: () => string;\n /** Replace the document. */\n setValue: (value: string) => void;\n /** Read the current selection text (empty string if none). */\n getSelection?: () => string;\n /** Replace the current selection with text. */\n replaceSelection?: (text: string) => void;\n /** Programmatic focus. */\n focus?: () => void;\n /** Read / set the active language. */\n getLanguage?: () => string;\n /** Set the active language. */\n setLanguage?: (lang: string) => void;\n};\n\nexport type CodeBridgeOptions = {\n adapter: CodeBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerCodeBridge — schema-aware MCP access to a single CodeEditor.\n * Tools cover read, full replace, append, selection replace, language\n * switch, and a streaming append helper for \"type characters into the\n * editor over time\" UX.\n */\nexport function registerCodeBridge(\n host: ToolHost,\n options: CodeBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target: AgentTarget = {\n kind: \"code\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"code\",\n screenId: adapter.screenId,\n resolveTarget: () => target,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false },\n },\n final as any,\n ),\n );\n };\n\n reg(\n \"code_describe\",\n `Describe the editor \"${adapter.id}\" — language + length + has-selection.`,\n {},\n [],\n () => {\n const value = adapter.getValue();\n const language = adapter.getLanguage?.() ?? \"unknown\";\n const summary = { id: adapter.id, language, length: value.length, lines: value.split(\"\\n\").length };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"code_get_value\",\n \"Read the full document text.\",\n {},\n [],\n () => {\n const value = adapter.getValue();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_get_selection\",\n \"Read the currently-selected text (empty string if no selection).\",\n {},\n [],\n () => {\n if (!adapter.getSelection) return errorResult(\"Host did not provide getSelection.\");\n const value = adapter.getSelection();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_set_value\",\n \"Replace the entire document.\",\n { value: { type: \"string\" } },\n [\"value\"],\n (args) => {\n const value = String(args.value ?? \"\");\n adapter.setValue(value);\n return textResult(`Replaced document (${value.length} chars)`, { length: value.length });\n },\n true,\n );\n\n reg(\n \"code_append\",\n \"Append text to the end of the document.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n const text = String(args.text ?? \"\");\n const next = adapter.getValue() + text;\n adapter.setValue(next);\n return textResult(`Appended ${text.length} chars`, { length: next.length });\n },\n true,\n );\n\n reg(\n \"code_stream_append\",\n \"Type characters into the document one at a time so the human can read it forming. Returns when streaming finishes.\",\n {\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n },\n [\"text\"],\n async (args) => {\n const text = String(args.text ?? \"\");\n const cps = Math.max(1, Number(args.cps ?? 25));\n const interval = Math.max(8, Math.round(1000 / cps));\n const start = adapter.getValue();\n for (let i = 1; i <= text.length; i++) {\n adapter.setValue(start + text.slice(0, i));\n if (i < text.length) await new Promise((r) => setTimeout(r, interval));\n }\n return textResult(`Streamed ${text.length} chars`, { length: text.length });\n },\n true,\n );\n\n reg(\n \"code_replace_selection\",\n \"Replace the currently-selected text with the supplied text.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n if (!adapter.replaceSelection) return errorResult(\"Host did not provide replaceSelection.\");\n adapter.replaceSelection(String(args.text ?? \"\"));\n return textResult(\"Selection replaced\", { });\n },\n true,\n );\n\n reg(\n \"code_set_language\",\n \"Switch the active syntax highlighting / formatter.\",\n { language: { type: \"string\", description: \"e.g. 'javascript', 'php', 'sql'.\" } },\n [\"language\"],\n (args) => {\n if (!adapter.setLanguage) return errorResult(\"Host did not provide setLanguage.\");\n const lang = String(args.language ?? \"\");\n adapter.setLanguage(lang);\n return textResult(`Language → ${lang}`, { language: lang });\n },\n true,\n );\n\n reg(\n \"code_focus\",\n \"Move browser focus to the editor.\",\n {},\n [],\n () => {\n if (!adapter.focus) return errorResult(\"Host did not provide focus.\");\n adapter.focus();\n return textResult(\"Focused\", { });\n },\n true,\n );\n\n return {\n id: `code:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/code.ts"],"names":["emitActivity"],"mappings":"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","file":"bridges-code.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Adapter the host wires to a fancy-code CodeEditor (typically via the\n * useCodeEditor hook's context value).\n */\nexport type CodeBridgeAdapter = {\n /** Stable id for this editor instance. */\n id: string;\n /** Display label. */\n title?: string;\n /** Optional fancy-screens screen id. */\n screenId?: string;\n /** Read the current document text. */\n getValue: () => string;\n /** Replace the document. */\n setValue: (value: string) => void;\n /** Read the current selection text (empty string if none). */\n getSelection?: () => string;\n /** Replace the current selection with text. */\n replaceSelection?: (text: string) => void;\n /** Programmatic focus. */\n focus?: () => void;\n /** Read / set the active language. */\n getLanguage?: () => string;\n /** Set the active language. */\n setLanguage?: (lang: string) => void;\n};\n\nexport type CodeBridgeOptions = {\n adapter: CodeBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerCodeBridge — schema-aware MCP access to a single CodeEditor.\n * Tools cover read, full replace, append, selection replace, language\n * switch, and a streaming append helper for \"type characters into the\n * editor over time\" UX.\n */\nexport function registerCodeBridge(\n host: ToolHost,\n options: CodeBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target: AgentTarget = {\n kind: \"code\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"code\",\n screenId: adapter.screenId,\n resolveTarget: () => target,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false },\n },\n final as any,\n ),\n );\n };\n\n reg(\n \"code_describe\",\n `Describe the editor \"${adapter.id}\" — language + length + has-selection.`,\n {},\n [],\n () => {\n const value = adapter.getValue();\n const language = adapter.getLanguage?.() ?? \"unknown\";\n const summary = { id: adapter.id, language, length: value.length, lines: value.split(\"\\n\").length };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"code_get_value\",\n \"Read the full document text.\",\n {},\n [],\n () => {\n const value = adapter.getValue();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_get_selection\",\n \"Read the currently-selected text (empty string if no selection).\",\n {},\n [],\n () => {\n if (!adapter.getSelection) return errorResult(\"Host did not provide getSelection.\");\n const value = adapter.getSelection();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_set_value\",\n \"Replace the entire document.\",\n { value: { type: \"string\" } },\n [\"value\"],\n (args) => {\n const value = String(args.value ?? \"\");\n adapter.setValue(value);\n return textResult(`Replaced document (${value.length} chars)`, { length: value.length });\n },\n true,\n );\n\n reg(\n \"code_append\",\n \"Append text to the end of the document.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n const text = String(args.text ?? \"\");\n const next = adapter.getValue() + text;\n adapter.setValue(next);\n return textResult(`Appended ${text.length} chars`, { length: next.length });\n },\n true,\n );\n\n reg(\n \"code_stream_append\",\n \"Type characters into the document one at a time so the human can read it forming. Returns when streaming finishes.\",\n {\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n },\n [\"text\"],\n async (args) => {\n const text = String(args.text ?? \"\");\n const cps = Math.max(1, Number(args.cps ?? 25));\n const interval = Math.max(8, Math.round(1000 / cps));\n const start = adapter.getValue();\n for (let i = 1; i <= text.length; i++) {\n adapter.setValue(start + text.slice(0, i));\n if (i < text.length) await new Promise((r) => setTimeout(r, interval));\n }\n return textResult(`Streamed ${text.length} chars`, { length: text.length });\n },\n true,\n );\n\n reg(\n \"code_replace_selection\",\n \"Replace the currently-selected text with the supplied text.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n if (!adapter.replaceSelection) return errorResult(\"Host did not provide replaceSelection.\");\n adapter.replaceSelection(String(args.text ?? \"\"));\n return textResult(\"Selection replaced\", { });\n },\n true,\n );\n\n reg(\n \"code_set_language\",\n \"Switch the active syntax highlighting / formatter.\",\n { language: { type: \"string\", description: \"e.g. 'javascript', 'php', 'sql'.\" } },\n [\"language\"],\n (args) => {\n if (!adapter.setLanguage) return errorResult(\"Host did not provide setLanguage.\");\n const lang = String(args.language ?? \"\");\n adapter.setLanguage(lang);\n return textResult(`Language → ${lang}`, { language: lang });\n },\n true,\n );\n\n reg(\n \"code_focus\",\n \"Move browser focus to the editor.\",\n {},\n [],\n () => {\n if (!adapter.focus) return errorResult(\"Host did not provide focus.\");\n adapter.focus();\n return textResult(\"Focused\", { });\n },\n true,\n );\n\n return {\n id: `code:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}