@particle-academy/agent-integrations 0.3.4 → 0.4.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 (110) hide show
  1. package/README.md +20 -0
  2. package/dist/bridges/charts.d.cts +4 -4
  3. package/dist/bridges/charts.d.ts +4 -4
  4. package/dist/bridges/code.d.cts +4 -4
  5. package/dist/bridges/code.d.ts +4 -4
  6. package/dist/bridges/flow.d.cts +4 -4
  7. package/dist/bridges/flow.d.ts +4 -4
  8. package/dist/bridges/forms.d.cts +4 -4
  9. package/dist/bridges/forms.d.ts +4 -4
  10. package/dist/bridges/scene.d.cts +4 -4
  11. package/dist/bridges/scene.d.ts +4 -4
  12. package/dist/bridges/screens.d.cts +78 -0
  13. package/dist/bridges/screens.d.ts +78 -0
  14. package/dist/bridges/sheets.d.cts +4 -4
  15. package/dist/bridges/sheets.d.ts +4 -4
  16. package/dist/bridges/whiteboard.d.cts +4 -4
  17. package/dist/bridges/whiteboard.d.ts +4 -4
  18. package/dist/bridges-charts.cjs +2 -2
  19. package/dist/bridges-charts.cjs.map +1 -1
  20. package/dist/bridges-charts.js +2 -2
  21. package/dist/bridges-code.cjs +2 -2
  22. package/dist/bridges-code.cjs.map +1 -1
  23. package/dist/bridges-code.js +2 -2
  24. package/dist/bridges-flow.cjs +2 -2
  25. package/dist/bridges-flow.cjs.map +1 -1
  26. package/dist/bridges-flow.js +2 -2
  27. package/dist/bridges-forms.cjs +2 -2
  28. package/dist/bridges-forms.cjs.map +1 -1
  29. package/dist/bridges-forms.js +2 -2
  30. package/dist/bridges-scene.cjs +2 -2
  31. package/dist/bridges-scene.cjs.map +1 -1
  32. package/dist/bridges-scene.js +2 -2
  33. package/dist/bridges-screens.cjs +227 -0
  34. package/dist/bridges-screens.cjs.map +1 -0
  35. package/dist/bridges-screens.js +6 -0
  36. package/dist/bridges-screens.js.map +1 -0
  37. package/dist/bridges-sheets.cjs +2 -2
  38. package/dist/bridges-sheets.cjs.map +1 -1
  39. package/dist/bridges-sheets.js +2 -2
  40. package/dist/bridges-whiteboard.cjs +12 -12
  41. package/dist/bridges-whiteboard.cjs.map +1 -1
  42. package/dist/bridges-whiteboard.js +3 -3
  43. package/dist/{chunk-TBEITXF4.js → chunk-3KSZNGNW.js} +7 -7
  44. package/dist/chunk-3KSZNGNW.js.map +1 -0
  45. package/dist/{chunk-OEIULP2L.js → chunk-4BL5M3U3.js} +5 -5
  46. package/dist/chunk-4BL5M3U3.js.map +1 -0
  47. package/dist/{chunk-QGCF7YKW.js → chunk-4KAIV6OD.js} +40 -12
  48. package/dist/chunk-4KAIV6OD.js.map +1 -0
  49. package/dist/chunk-57ZDHD53.js +180 -0
  50. package/dist/chunk-57ZDHD53.js.map +1 -0
  51. package/dist/chunk-E4AICMFZ.js +83 -0
  52. package/dist/chunk-E4AICMFZ.js.map +1 -0
  53. package/dist/{chunk-ACBENYYO.js → chunk-GQ7XXK7G.js} +12 -12
  54. package/dist/chunk-GQ7XXK7G.js.map +1 -0
  55. package/dist/{chunk-XYYSTJHW.js → chunk-HSTW7ZNO.js} +5 -5
  56. package/dist/chunk-HSTW7ZNO.js.map +1 -0
  57. package/dist/{chunk-PDBF4W7E.js → chunk-IANI25IT.js} +5 -5
  58. package/dist/chunk-IANI25IT.js.map +1 -0
  59. package/dist/{chunk-4IAVAFUV.js → chunk-N3H4DXY5.js} +5 -5
  60. package/dist/chunk-N3H4DXY5.js.map +1 -0
  61. package/dist/{chunk-PHPXKSWI.js → chunk-NTDZWGYB.js} +5 -5
  62. package/dist/chunk-NTDZWGYB.js.map +1 -0
  63. package/dist/{chunk-DJOWMF6Q.js → chunk-RGO42EQ6.js} +3 -3
  64. package/dist/{chunk-DJOWMF6Q.js.map → chunk-RGO42EQ6.js.map} +1 -1
  65. package/dist/{chunk-QJUTISFC.js → chunk-XRAJSOPS.js} +5 -5
  66. package/dist/chunk-XRAJSOPS.js.map +1 -0
  67. package/dist/index.cjs +320 -35
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.cts +7 -4
  70. package/dist/index.d.ts +7 -4
  71. package/dist/index.js +15 -13
  72. package/dist/index.js.map +1 -1
  73. package/dist/mcp/index.d.cts +5 -4
  74. package/dist/mcp/index.d.ts +5 -4
  75. package/dist/mcp.cjs +37 -9
  76. package/dist/mcp.cjs.map +1 -1
  77. package/dist/mcp.js +1 -1
  78. package/dist/presence/index.d.cts +1 -1
  79. package/dist/presence/index.d.ts +1 -1
  80. package/dist/{server-BJu_AMH3.d.ts → server-BsSwfemr.d.cts} +4 -5
  81. package/dist/{server-si-VvFxI.d.cts → server-Du3-IGqM.d.ts} +4 -5
  82. package/dist/sharing/index.d.cts +3 -2
  83. package/dist/sharing/index.d.ts +3 -2
  84. package/dist/sheets-adapter.cjs +96 -0
  85. package/dist/sheets-adapter.cjs.map +1 -0
  86. package/dist/sheets-adapter.d.cts +115 -0
  87. package/dist/sheets-adapter.d.ts +115 -0
  88. package/dist/sheets-adapter.js +4 -0
  89. package/dist/sheets-adapter.js.map +1 -0
  90. package/dist/tool-host-BQuUygLF.d.cts +60 -0
  91. package/dist/tool-host-C8JMMGYq.d.ts +60 -0
  92. package/dist/{types-DXKpLuia.d.ts → types-CCSBGW9T.d.cts} +2 -2
  93. package/dist/{types-Bf1ZoGmI.d.cts → types-DIVNcIQO.d.ts} +2 -2
  94. package/dist/{types-DksGd5Y7.d.cts → types-aOQLTW0E.d.cts} +1 -1
  95. package/dist/{types-DksGd5Y7.d.ts → types-aOQLTW0E.d.ts} +1 -1
  96. package/dist/undo/index.d.cts +4 -4
  97. package/dist/undo/index.d.ts +4 -4
  98. package/dist/undo.cjs +9 -9
  99. package/dist/undo.cjs.map +1 -1
  100. package/dist/undo.js +3 -3
  101. package/package.json +1 -1
  102. package/dist/chunk-4IAVAFUV.js.map +0 -1
  103. package/dist/chunk-ACBENYYO.js.map +0 -1
  104. package/dist/chunk-OEIULP2L.js.map +0 -1
  105. package/dist/chunk-PDBF4W7E.js.map +0 -1
  106. package/dist/chunk-PHPXKSWI.js.map +0 -1
  107. package/dist/chunk-QGCF7YKW.js.map +0 -1
  108. package/dist/chunk-QJUTISFC.js.map +0 -1
  109. package/dist/chunk-TBEITXF4.js.map +0 -1
  110. package/dist/chunk-XYYSTJHW.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/scene.ts"],"names":[],"mappings":"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","file":"bridges-scene.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\";\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 {\n private tools = new Map<string, RegisteredTool>();\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 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 registerTool(definition: ToolDefinition, handler: ToolHandler): () => void {\n this.tools.set(definition.name, { definition, handler });\n this.scheduleListChangedNotification();\n return () => this.unregisterTool(definition.name);\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n listTools(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((t) => t.definition);\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 { MicroMcpServer } from \"../mcp/server\";\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 * Loose Scene types — mirror the public surface of fancy-3d's Scene\n * descriptor (engine-agnostic JSON the package's adapters consume).\n */\nexport type SceneObjectKind = \"box\" | \"sphere\" | \"cylinder\" | \"plane\" | \"screen\" | \"group\" | \"custom\";\n\nexport type SceneObject = {\n id: string;\n kind: SceneObjectKind | string;\n position?: [number, number, number];\n rotation?: [number, number, number];\n scale?: [number, number, number];\n color?: string;\n /** Free-form per-kind config (e.g. text content for screens). */\n props?: Record<string, unknown>;\n children?: SceneObject[];\n};\n\nexport type SceneCamera = {\n position?: [number, number, number];\n target?: [number, number, number];\n fov?: number;\n};\n\nexport type SceneState = {\n objects: SceneObject[];\n camera?: SceneCamera;\n background?: string;\n};\n\nexport type SceneBridgeAdapter = {\n id: string;\n title?: string;\n screenId?: string;\n getScene: () => SceneState;\n setScene: (next: SceneState) => void;\n /** Convenience: set just the camera without touching objects. */\n setCamera?: (next: SceneCamera) => void;\n};\n\nexport type SceneBridgeOptions = {\n adapter: SceneBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerSceneBridge — schema-aware MCP access to a fancy-3d Scene.\n * Tools cover read, add/update/delete object, set camera, set background.\n */\nexport function registerSceneBridge(\n server: MicroMcpServer,\n options: SceneBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target = (objectId?: string): AgentTarget => ({\n kind: \"scene\",\n screenId: adapter.screenId,\n elementId: objectId ? `${adapter.id}:${objectId}` : adapter.id,\n label: objectId ? `${adapter.title ?? adapter.id} → ${objectId}` : 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 objectIdFromArgs?: (args: JsonObject) => string | undefined,\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: \"scene\", screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(objectIdFromArgs?.(args)),\n })\n : wrapped;\n disposers.push(\n server.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n const newId = (kind: string) => `${kind}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n\n // ───────────── Read ─────────────\n\n reg(\n \"scene_describe\",\n \"Describe the scene — object count, kinds, camera position.\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n const summary = {\n id: adapter.id,\n objectCount: scene.objects.length,\n kinds: scene.objects.map((o) => o.kind),\n camera: scene.camera,\n background: scene.background,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n },\n false,\n );\n\n reg(\n \"scene_get_state\",\n \"Read the full SceneState (objects + camera + background).\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n return textResult(JSON.stringify(scene, null, 2), scene);\n },\n false,\n );\n\n // ───────────── Mutations ─────────────\n\n reg(\n \"scene_add_object\",\n \"Add an object to the scene root. Returns the new object's id.\",\n {\n kind: { type: \"string\", description: \"box | sphere | cylinder | plane | screen | group | custom kind\" },\n position: { type: \"array\", description: \"[x, y, z]\" },\n rotation: { type: \"array\", description: \"[x, y, z] euler\" },\n scale: { type: \"array\", description: \"[x, y, z]\" },\n color: { type: \"string\" },\n props: { type: \"object\", description: \"Per-kind config.\" },\n },\n [\"kind\"],\n (args) => {\n const obj: SceneObject = {\n id: newId(String(args.kind)),\n kind: String(args.kind),\n position: parseTriple(args.position),\n rotation: parseTriple(args.rotation),\n scale: parseTriple(args.scale),\n color: typeof args.color === \"string\" ? args.color : undefined,\n props: (args.props && typeof args.props === \"object\") ? args.props as Record<string, unknown> : undefined,\n };\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, objects: [...scene.objects, obj] });\n return textResult(`Added ${obj.kind} ${obj.id}`, obj);\n },\n true,\n (args) => undefined, // id resolved from result.structuredContent.id\n );\n\n reg(\n \"scene_update_object\",\n \"Update fields on an object. Only provided fields change.\",\n {\n id: { type: \"string\" },\n position: { type: \"array\" },\n rotation: { type: \"array\" },\n scale: { type: \"array\" },\n color: { type: \"string\" },\n props: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const idx = scene.objects.findIndex((o) => o.id === id);\n if (idx === -1) return errorResult(`No object ${id}`);\n const orig = scene.objects[idx];\n const next: SceneObject = {\n ...orig,\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.rotation !== undefined ? { rotation: parseTriple(args.rotation) } : {}),\n ...(args.scale !== undefined ? { scale: parseTriple(args.scale) } : {}),\n ...(args.color !== undefined ? { color: String(args.color) } : {}),\n ...(args.props && typeof args.props === \"object\" ? { props: { ...(orig.props ?? {}), ...(args.props as Record<string, unknown>) } } : {}),\n };\n const objects = [...scene.objects];\n objects[idx] = next;\n adapter.setScene({ ...scene, objects });\n return textResult(`Updated ${id}`, next);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_delete_object\",\n \"Remove an object from the scene root.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const next = scene.objects.filter((o) => o.id !== id);\n if (next.length === scene.objects.length) return errorResult(`No object ${id}`);\n adapter.setScene({ ...scene, objects: next });\n return textResult(`Deleted ${id}`);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_set_camera\",\n \"Move the camera. Pass any subset of position/target/fov.\",\n {\n position: { type: \"array\", description: \"[x, y, z]\" },\n target: { type: \"array\", description: \"[x, y, z] look-at point\" },\n fov: { type: \"number\" },\n },\n [],\n (args) => {\n const scene = adapter.getScene();\n const next: SceneCamera = {\n ...(scene.camera ?? {}),\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.target !== undefined ? { target: parseTriple(args.target) } : {}),\n ...(args.fov !== undefined ? { fov: Number(args.fov) } : {}),\n };\n if (adapter.setCamera) {\n adapter.setCamera(next);\n } else {\n adapter.setScene({ ...scene, camera: next });\n }\n return textResult(`Camera updated`, next);\n },\n true,\n );\n\n reg(\n \"scene_set_background\",\n \"Change the scene background color (CSS color).\",\n { color: { type: \"string\" } },\n [\"color\"],\n (args) => {\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, background: String(args.color) });\n return textResult(`Background → ${args.color}`, { background: args.color });\n },\n true,\n );\n\n return {\n id: `scene:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n\nfunction parseTriple(v: unknown): [number, number, number] | undefined {\n if (!Array.isArray(v) || v.length !== 3) return undefined;\n const out = v.map((x) => Number(x));\n if (out.some((x) => !Number.isFinite(x))) return undefined;\n return out as [number, number, number];\n}\n"]}
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/scene.ts"],"names":[],"mappings":";;;AAgLO,SAAS,UAAA,CAAW,MAAc,UAAA,EAAkC;AACzE,EAAA,OAAO;AAAA,IACL,SAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAA;AAAA,IAChC,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,iBAAA,EAAmB,UAAA,KAAe;AAAC,GACtE;AACF;AAEO,SAAS,YAAY,IAAA,EAA8B;AACxD,EAAA,OAAO,EAAE,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK;AAC5D;AC3KA,IAAM,SAAA,uBAAgB,GAAA,EAA2B;AAI1C,SAAS,aAAa,KAAA,EAAiC;AAG5D,EAAA,KAAA,MAAW,CAAA,IAAK,SAAA,EAAW,CAAA,CAAE,KAAK,CAAA;AACpC;;;ACyBO,SAAS,oBAAA,CACd,SACA,OAAA,EAYoB;AACpB,EAAA,OAAO,OAAO,IAAA,KAAS;AACrB,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AACjC,IAAA,IAAI,MAAA,CAAO,SAAS,OAAO,MAAA;AAE3B,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,QAAQ,aAAA,EAAe;AACzB,MAAA,MAAA,GAAS,OAAA,CAAQ,cAAc,EAAE,QAAA,EAAU,QAAQ,QAAA,EAAU,IAAA,EAAM,QAAQ,CAAA;AAAA,IAC7E,CAAA,MAAO;AACL,MAAA,MAAA,GAAS,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAM,QAAA,EAAU,QAAQ,QAAA,EAAS;AAAA,IAC5D;AACA,IAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AAEpB,IAAA,YAAA,CAAa;AAAA,MACX,OAAA,EAAS,QAAQ,KAAA,CAAM,EAAA;AAAA,MACvB,SAAA,EAAW,QAAQ,KAAA,CAAM,IAAA;AAAA,MACzB,UAAA,EAAY,QAAQ,KAAA,CAAM,KAAA;AAAA,MAC1B,MAAA,EAAQ,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAM,MAAA,CAAO,IAAA,IAAQ,OAAA,CAAQ,IAAA,EAAM,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,QAAQ,QAAA,EAAS;AAAA,MACtG,QAAQ,OAAA,CAAQ,QAAA;AAAA,MAChB,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,IAAA,EAAM,YAAY,MAAM,CAAA;AAAA,MACxB,OAAO,OAAA,CAAQ;AAAA,KAChB,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;AAEA,SAAS,YAAY,MAAA,EAA6D;AAChF,EAAA,MAAM,KAAK,MAAA,CAAO,iBAAA;AAClB,EAAA,IAAI,EAAA,IAAM,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,EAAG;AACtD,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA;AACT;;;AC1CA,IAAM,gBAAgB,EAAE,EAAA,EAAI,SAAS,IAAA,EAAM,OAAA,EAAS,OAAO,SAAA,EAAU;AAM9D,SAAS,mBAAA,CACd,MACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,aAAA,EAAe,GAAI,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG;AAC3D,EAAA,MAAM,YAA+B,EAAC;AAEtC,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,MAAoC;AAAA,IAClD,IAAA,EAAM,OAAA;AAAA,IACN,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,SAAA,EAAW,WAAW,CAAA,EAAG,OAAA,CAAQ,EAAE,CAAA,CAAA,EAAI,QAAQ,KAAK,OAAA,CAAQ,EAAA;AAAA,IAC5D,KAAA,EAAO,QAAA,GAAW,CAAA,EAAG,OAAA,CAAQ,KAAA,IAAS,OAAA,CAAQ,EAAE,CAAA,QAAA,EAAM,QAAQ,CAAA,CAAA,GAAK,OAAA,CAAQ,KAAA,IAAS,OAAA,CAAQ;AAAA,GAC9F,CAAA;AAEA,EAAA,MAAM,GAAA,GAAM,CACV,IAAA,EACA,WAAA,EACA,YACA,QAAA,EACA,OAAA,EACA,YACA,gBAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,KAAqB;AAC1C,MAAA,IAAI;AAAE,QAAA,OAAO,MAAM,QAAQ,IAAI,CAAA;AAAA,MAAG,SAC3B,CAAA,EAAG;AAAE,QAAA,OAAO,YAAY,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MAAG;AAAA,IAC9E,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,UAAA,GACV,oBAAA,CAAqB,OAAA,EAAS;AAAA,MAC5B,QAAA,EAAU,IAAA;AAAA,MAAM,KAAA;AAAA,MAAO,IAAA,EAAM,OAAA;AAAA,MAAS,UAAU,OAAA,CAAQ,QAAA;AAAA,MACxD,aAAA,EAAe,CAAC,EAAE,IAAA,OAAW,MAAA,CAAO,gBAAA,GAAmB,IAAI,CAAC;AAAA,KAC7D,CAAA,GACD,OAAA;AACJ,IAAA,SAAA,CAAU,IAAA;AAAA,MACR,IAAA,CAAK,YAAA;AAAA,QACH,EAAE,IAAA,EAAM,WAAA,EAAa,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAU,UAAA,EAA+B,QAAA,EAAU,oBAAA,EAAsB,KAAA,EAAM,EAAE;AAAA,QAC3H;AAAA;AACF,KACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAiB,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAI5G,EAAA,GAAA;AAAA,IACE,gBAAA;AAAA,IACA,iEAAA;AAAA,IACA,EAAC;AAAA,IACD,EAAC;AAAA,IACD,MAAM;AACJ,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,MAAM,OAAA,GAAU;AAAA,QACd,IAAI,OAAA,CAAQ,EAAA;AAAA,QACZ,WAAA,EAAa,MAAM,OAAA,CAAQ,MAAA;AAAA,QAC3B,OAAO,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,QACtC,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,YAAY,KAAA,CAAM;AAAA,OACpB;AACA,MAAA,OAAO,WAAW,IAAA,CAAK,SAAA,CAAU,SAAS,IAAA,EAAM,CAAC,GAAG,OAAO,CAAA;AAAA,IAC7D,CAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,GAAA;AAAA,IACE,iBAAA;AAAA,IACA,2DAAA;AAAA,IACA,EAAC;AAAA,IACD,EAAC;AAAA,IACD,MAAM;AACJ,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,OAAO,WAAW,IAAA,CAAK,SAAA,CAAU,OAAO,IAAA,EAAM,CAAC,GAAG,KAAK,CAAA;AAAA,IACzD,CAAA;AAAA,IACA;AAAA,GACF;AAIA,EAAA,GAAA;AAAA,IACE,kBAAA;AAAA,IACA,+DAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,gEAAA,EAAiE;AAAA,MACtG,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAS,aAAa,WAAA,EAAY;AAAA,MACpD,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAS,aAAa,iBAAA,EAAkB;AAAA,MAC1D,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,EAAS,aAAa,WAAA,EAAY;AAAA,MACjD,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,MACxB,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,kBAAA;AAAmB,KAC3D;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,IACP,CAAC,IAAA,KAAS;AACR,MAAA,MAAM,GAAA,GAAmB;AAAA,QACvB,EAAA,EAAI,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,QAC3B,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AAAA,QACtB,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,QACnC,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,QACnC,KAAA,EAAO,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA;AAAA,QAC7B,OAAO,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GAAW,KAAK,KAAA,GAAQ,MAAA;AAAA,QACrD,KAAA,EAAQ,KAAK,KAAA,IAAS,OAAO,KAAK,KAAA,KAAU,QAAA,GAAY,KAAK,KAAA,GAAmC;AAAA,OAClG;AACA,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,OAAA,CAAQ,QAAA,CAAS,EAAE,GAAG,KAAA,EAAO,OAAA,EAAS,CAAC,GAAG,KAAA,CAAM,OAAA,EAAS,GAAG,CAAA,EAAG,CAAA;AAC/D,MAAA,OAAO,UAAA,CAAW,SAAS,GAAA,CAAI,IAAI,IAAI,GAAA,CAAI,EAAE,IAAI,GAAG,CAAA;AAAA,IACtD,CAAA;AAAA,IACA,IAAA;AAAA,IACA,CAAC,IAAA,KAAS;AAAA;AAAA,GACZ;AAEA,EAAA,GAAA;AAAA,IACE,qBAAA;AAAA,IACA,0DAAA;AAAA,IACA;AAAA,MACE,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,MACrB,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAQ;AAAA,MAC1B,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAQ;AAAA,MAC1B,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,EAAQ;AAAA,MACvB,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,MACxB,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA;AAAS,KAC1B;AAAA,IACA,CAAC,IAAI,CAAA;AAAA,IACL,CAAC,IAAA,KAAS;AACR,MAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACtD,MAAA,IAAI,QAAQ,EAAA,EAAI,OAAO,WAAA,CAAY,CAAA,UAAA,EAAa,EAAE,CAAA,CAAE,CAAA;AACpD,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAC9B,MAAA,MAAM,IAAA,GAAoB;AAAA,QACxB,GAAG,IAAA;AAAA,QACH,GAAI,IAAA,CAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA,EAAE,GAAI,EAAC;AAAA,QAC9E,GAAI,IAAA,CAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA,EAAE,GAAI,EAAC;AAAA,QAC9E,GAAI,IAAA,CAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA,EAAE,GAAI,EAAC;AAAA,QACrE,GAAI,IAAA,CAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAE,GAAI,EAAC;AAAA,QAChE,GAAI,KAAK,KAAA,IAAS,OAAO,KAAK,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,EAAE,GAAI,IAAA,CAAK,KAAA,IAAS,EAAC,EAAI,GAAI,KAAK,KAAA,EAAkC,KAAM;AAAC,OACzI;AACA,MAAA,MAAM,OAAA,GAAU,CAAC,GAAG,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,IAAA;AACf,MAAA,OAAA,CAAQ,QAAA,CAAS,EAAE,GAAG,KAAA,EAAO,SAAS,CAAA;AACtC,MAAA,OAAO,UAAA,CAAW,CAAA,QAAA,EAAW,EAAE,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,IAAA;AAAA,IACA,CAAC,IAAA,KAAS,MAAA,CAAO,IAAA,CAAK,MAAM,EAAE;AAAA,GAChC;AAEA,EAAA,GAAA;AAAA,IACE,qBAAA;AAAA,IACA,uCAAA;AAAA,IACA,EAAE,EAAA,EAAI,EAAE,IAAA,EAAM,UAAS,EAAE;AAAA,IACzB,CAAC,IAAI,CAAA;AAAA,IACL,CAAC,IAAA,KAAS;AACR,MAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACpD,MAAA,IAAI,IAAA,CAAK,WAAW,KAAA,CAAM,OAAA,CAAQ,QAAQ,OAAO,WAAA,CAAY,CAAA,UAAA,EAAa,EAAE,CAAA,CAAE,CAAA;AAC9E,MAAA,OAAA,CAAQ,SAAS,EAAE,GAAG,KAAA,EAAO,OAAA,EAAS,MAAM,CAAA;AAC5C,MAAA,OAAO,UAAA,CAAW,CAAA,QAAA,EAAW,EAAE,CAAA,CAAE,CAAA;AAAA,IACnC,CAAA;AAAA,IACA,IAAA;AAAA,IACA,CAAC,IAAA,KAAS,MAAA,CAAO,IAAA,CAAK,MAAM,EAAE;AAAA,GAChC;AAEA,EAAA,GAAA;AAAA,IACE,kBAAA;AAAA,IACA,0DAAA;AAAA,IACA;AAAA,MACE,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAS,aAAa,WAAA,EAAY;AAAA,MACpD,MAAA,EAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,aAAa,yBAAA,EAA0B;AAAA,MAChE,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA;AAAS,KACxB;AAAA,IACA,EAAC;AAAA,IACD,CAAC,IAAA,KAAS;AACR,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,MAAM,IAAA,GAAoB;AAAA,QACxB,GAAI,KAAA,CAAM,MAAA,IAAU,EAAC;AAAA,QACrB,GAAI,IAAA,CAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA,EAAE,GAAI,EAAC;AAAA,QAC9E,GAAI,IAAA,CAAK,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA,EAAE,GAAI,EAAC;AAAA,QACxE,GAAI,IAAA,CAAK,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAE,GAAI;AAAC,OAC5D;AACA,MAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,QAAA,OAAA,CAAQ,UAAU,IAAI,CAAA;AAAA,MACxB,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,SAAS,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC7C;AACA,MAAA,OAAO,UAAA,CAAW,kBAAkB,IAAI,CAAA;AAAA,IAC1C,CAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,GAAA;AAAA,IACE,sBAAA;AAAA,IACA,gDAAA;AAAA,IACA,EAAE,KAAA,EAAO,EAAE,IAAA,EAAM,UAAS,EAAE;AAAA,IAC5B,CAAC,OAAO,CAAA;AAAA,IACR,CAAC,IAAA,KAAS;AACR,MAAA,MAAM,KAAA,GAAQ,QAAQ,QAAA,EAAS;AAC/B,MAAA,OAAA,CAAQ,QAAA,CAAS,EAAE,GAAG,KAAA,EAAO,YAAY,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG,CAAA;AAC7D,MAAA,OAAO,UAAA,CAAW,qBAAgB,IAAA,CAAK,KAAK,IAAI,EAAE,UAAA,EAAY,IAAA,CAAK,KAAA,EAAO,CAAA;AAAA,IAC5E,CAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA,MAAA,EAAS,OAAA,CAAQ,EAAE,CAAA,CAAA;AAAA,IACvB,KAAA,EAAO,OAAA,CAAQ,KAAA,IAAS,OAAA,CAAQ,EAAA;AAAA,IAChC,SAAS,MAAM;AAAE,MAAA,KAAA,MAAW,CAAA,IAAK,WAAW,CAAA,EAAE;AAAA,IAAG;AAAA,GACnD;AACF;AAEA,SAAS,YAAY,CAAA,EAAkD;AACrE,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,CAAC,KAAK,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,MAAA;AAChD,EAAA,MAAM,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,MAAA,CAAO,CAAC,CAAC,CAAA;AAClC,EAAA,IAAI,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,CAAC,OAAO,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG,OAAO,MAAA;AACjD,EAAA,OAAO,GAAA;AACT","file":"bridges-scene.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 * Loose Scene types — mirror the public surface of fancy-3d's Scene\n * descriptor (engine-agnostic JSON the package's adapters consume).\n */\nexport type SceneObjectKind = \"box\" | \"sphere\" | \"cylinder\" | \"plane\" | \"screen\" | \"group\" | \"custom\";\n\nexport type SceneObject = {\n id: string;\n kind: SceneObjectKind | string;\n position?: [number, number, number];\n rotation?: [number, number, number];\n scale?: [number, number, number];\n color?: string;\n /** Free-form per-kind config (e.g. text content for screens). */\n props?: Record<string, unknown>;\n children?: SceneObject[];\n};\n\nexport type SceneCamera = {\n position?: [number, number, number];\n target?: [number, number, number];\n fov?: number;\n};\n\nexport type SceneState = {\n objects: SceneObject[];\n camera?: SceneCamera;\n background?: string;\n};\n\nexport type SceneBridgeAdapter = {\n id: string;\n title?: string;\n screenId?: string;\n getScene: () => SceneState;\n setScene: (next: SceneState) => void;\n /** Convenience: set just the camera without touching objects. */\n setCamera?: (next: SceneCamera) => void;\n};\n\nexport type SceneBridgeOptions = {\n adapter: SceneBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerSceneBridge — schema-aware MCP access to a fancy-3d Scene.\n * Tools cover read, add/update/delete object, set camera, set background.\n */\nexport function registerSceneBridge(\n host: ToolHost,\n options: SceneBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target = (objectId?: string): AgentTarget => ({\n kind: \"scene\",\n screenId: adapter.screenId,\n elementId: objectId ? `${adapter.id}:${objectId}` : adapter.id,\n label: objectId ? `${adapter.title ?? adapter.id} → ${objectId}` : 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 objectIdFromArgs?: (args: JsonObject) => string | undefined,\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: \"scene\", screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(objectIdFromArgs?.(args)),\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 const newId = (kind: string) => `${kind}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n\n // ───────────── Read ─────────────\n\n reg(\n \"scene_describe\",\n \"Describe the scene — object count, kinds, camera position.\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n const summary = {\n id: adapter.id,\n objectCount: scene.objects.length,\n kinds: scene.objects.map((o) => o.kind),\n camera: scene.camera,\n background: scene.background,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n },\n false,\n );\n\n reg(\n \"scene_get_state\",\n \"Read the full SceneState (objects + camera + background).\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n return textResult(JSON.stringify(scene, null, 2), scene);\n },\n false,\n );\n\n // ───────────── Mutations ─────────────\n\n reg(\n \"scene_add_object\",\n \"Add an object to the scene root. Returns the new object's id.\",\n {\n kind: { type: \"string\", description: \"box | sphere | cylinder | plane | screen | group | custom kind\" },\n position: { type: \"array\", description: \"[x, y, z]\" },\n rotation: { type: \"array\", description: \"[x, y, z] euler\" },\n scale: { type: \"array\", description: \"[x, y, z]\" },\n color: { type: \"string\" },\n props: { type: \"object\", description: \"Per-kind config.\" },\n },\n [\"kind\"],\n (args) => {\n const obj: SceneObject = {\n id: newId(String(args.kind)),\n kind: String(args.kind),\n position: parseTriple(args.position),\n rotation: parseTriple(args.rotation),\n scale: parseTriple(args.scale),\n color: typeof args.color === \"string\" ? args.color : undefined,\n props: (args.props && typeof args.props === \"object\") ? args.props as Record<string, unknown> : undefined,\n };\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, objects: [...scene.objects, obj] });\n return textResult(`Added ${obj.kind} ${obj.id}`, obj);\n },\n true,\n (args) => undefined, // id resolved from result.structuredContent.id\n );\n\n reg(\n \"scene_update_object\",\n \"Update fields on an object. Only provided fields change.\",\n {\n id: { type: \"string\" },\n position: { type: \"array\" },\n rotation: { type: \"array\" },\n scale: { type: \"array\" },\n color: { type: \"string\" },\n props: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const idx = scene.objects.findIndex((o) => o.id === id);\n if (idx === -1) return errorResult(`No object ${id}`);\n const orig = scene.objects[idx];\n const next: SceneObject = {\n ...orig,\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.rotation !== undefined ? { rotation: parseTriple(args.rotation) } : {}),\n ...(args.scale !== undefined ? { scale: parseTriple(args.scale) } : {}),\n ...(args.color !== undefined ? { color: String(args.color) } : {}),\n ...(args.props && typeof args.props === \"object\" ? { props: { ...(orig.props ?? {}), ...(args.props as Record<string, unknown>) } } : {}),\n };\n const objects = [...scene.objects];\n objects[idx] = next;\n adapter.setScene({ ...scene, objects });\n return textResult(`Updated ${id}`, next);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_delete_object\",\n \"Remove an object from the scene root.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const next = scene.objects.filter((o) => o.id !== id);\n if (next.length === scene.objects.length) return errorResult(`No object ${id}`);\n adapter.setScene({ ...scene, objects: next });\n return textResult(`Deleted ${id}`);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_set_camera\",\n \"Move the camera. Pass any subset of position/target/fov.\",\n {\n position: { type: \"array\", description: \"[x, y, z]\" },\n target: { type: \"array\", description: \"[x, y, z] look-at point\" },\n fov: { type: \"number\" },\n },\n [],\n (args) => {\n const scene = adapter.getScene();\n const next: SceneCamera = {\n ...(scene.camera ?? {}),\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.target !== undefined ? { target: parseTriple(args.target) } : {}),\n ...(args.fov !== undefined ? { fov: Number(args.fov) } : {}),\n };\n if (adapter.setCamera) {\n adapter.setCamera(next);\n } else {\n adapter.setScene({ ...scene, camera: next });\n }\n return textResult(`Camera updated`, next);\n },\n true,\n );\n\n reg(\n \"scene_set_background\",\n \"Change the scene background color (CSS color).\",\n { color: { type: \"string\" } },\n [\"color\"],\n (args) => {\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, background: String(args.color) });\n return textResult(`Background → ${args.color}`, { background: args.color });\n },\n true,\n );\n\n return {\n id: `scene:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n\nfunction parseTriple(v: unknown): [number, number, number] | undefined {\n if (!Array.isArray(v) || v.length !== 3) return undefined;\n const out = v.map((x) => Number(x));\n if (out.some((x) => !Number.isFinite(x))) return undefined;\n return out as [number, number, number];\n}\n"]}
@@ -1,6 +1,6 @@
1
- export { registerSceneBridge } from './chunk-QJUTISFC.js';
1
+ export { registerSceneBridge } from './chunk-XRAJSOPS.js';
2
2
  import './chunk-52S7XYZK.js';
3
3
  import './chunk-JU2N4KK6.js';
4
- import './chunk-QGCF7YKW.js';
4
+ import './chunk-4KAIV6OD.js';
5
5
  //# sourceMappingURL=bridges-scene.js.map
6
6
  //# sourceMappingURL=bridges-scene.js.map
@@ -0,0 +1,227 @@
1
+ 'use strict';
2
+
3
+ // src/mcp/server.ts
4
+ function textResult(text, structured) {
5
+ return {
6
+ content: [{ type: "text", text }],
7
+ ...structured !== void 0 ? { structuredContent: structured } : {}
8
+ };
9
+ }
10
+ function errorResult(text) {
11
+ return { content: [{ type: "text", text }], isError: true };
12
+ }
13
+ var listeners = /* @__PURE__ */ new Set();
14
+ function emitActivity(event) {
15
+ for (const l of listeners) l(event);
16
+ }
17
+
18
+ // src/presence/wrap-tool-with-activity.ts
19
+ function wrapToolWithActivity(handler, options) {
20
+ return async (args) => {
21
+ const result = await handler(args);
22
+ if (result.isError) return result;
23
+ let target;
24
+ if (options.resolveTarget) {
25
+ target = options.resolveTarget({ toolName: options.toolName, args, result });
26
+ } else {
27
+ target = { kind: options.kind, screenId: options.screenId };
28
+ }
29
+ if (!target) return result;
30
+ emitActivity({
31
+ agentId: options.agent.id,
32
+ agentName: options.agent.name,
33
+ agentColor: options.agent.color,
34
+ target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },
35
+ action: options.toolName,
36
+ timestamp: Date.now(),
37
+ meta: extractMeta(result),
38
+ ttlMs: options.ttlMs
39
+ });
40
+ return result;
41
+ };
42
+ }
43
+ function extractMeta(result) {
44
+ const sc = result.structuredContent;
45
+ if (sc && typeof sc === "object" && !Array.isArray(sc)) {
46
+ return sc;
47
+ }
48
+ return void 0;
49
+ }
50
+
51
+ // src/bridges/screens.ts
52
+ var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
53
+ function registerScreensBridge(host, options) {
54
+ const { adapter } = options;
55
+ const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
56
+ const disposers = [];
57
+ const target = (screenId) => ({
58
+ kind: "screens",
59
+ screenId,
60
+ label: `Screen ${screenId}`
61
+ });
62
+ const reg = (name, description, properties, required, handler, isMutation, targetFromArgs) => {
63
+ const wrapped = async (args) => {
64
+ try {
65
+ return await handler(args);
66
+ } catch (e) {
67
+ return errorResult(e instanceof Error ? e.message : String(e));
68
+ }
69
+ };
70
+ const final = isMutation ? wrapToolWithActivity(wrapped, {
71
+ toolName: name,
72
+ agent,
73
+ kind: "screens",
74
+ resolveTarget: ({ args }) => targetFromArgs?.(args) ?? null
75
+ }) : wrapped;
76
+ disposers.push(
77
+ host.registerTool(
78
+ { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
79
+ final
80
+ )
81
+ );
82
+ };
83
+ reg(
84
+ "screens_list",
85
+ "List every screen the host has registered. Returns id, title, active flag, and optional kind.",
86
+ {},
87
+ [],
88
+ () => {
89
+ const screens = adapter.listScreens();
90
+ const text = screens.map((s) => `${s.active ? "\u25B8" : " "} ${s.id}${s.title ? ` \u2014 ${s.title}` : ""}${s.kind ? ` [${s.kind}]` : ""}`).join("\n");
91
+ return textResult(text || "(no screens)", { screens, active: adapter.getActive() });
92
+ },
93
+ false
94
+ );
95
+ reg(
96
+ "screens_describe_active",
97
+ "Get the currently-active screen id (or null).",
98
+ {},
99
+ [],
100
+ () => {
101
+ const active = adapter.getActive();
102
+ return textResult(active ?? "(none)", { active });
103
+ },
104
+ false
105
+ );
106
+ reg(
107
+ "screens_list_kinds",
108
+ "List the screen kinds (templates) the host knows how to instantiate. Use this before screens_create to know what's available.",
109
+ {},
110
+ [],
111
+ () => {
112
+ if (!adapter.listKinds) return errorResult("Host did not register a kind catalog. Cannot create screens dynamically.");
113
+ const kinds = adapter.listKinds();
114
+ const text = kinds.map((k) => `${k.kind}${k.label ? ` \u2014 ${k.label}` : ""}${k.description ? ` (${k.description})` : ""}`).join("\n");
115
+ return textResult(text || "(no kinds registered)", kinds);
116
+ },
117
+ false
118
+ );
119
+ reg(
120
+ "screens_create",
121
+ "Instantiate a new screen from a template kind + config. Switches the active view to the new screen.",
122
+ {
123
+ id: { type: "string", description: "Stable screen id. Must be unique." },
124
+ title: { type: "string" },
125
+ kind: { type: "string", description: "Template kind \u2014 call screens_list_kinds for the catalog." },
126
+ config: { type: "object", description: "Template-specific config (e.g. { fields: [...] } for a form)." }
127
+ },
128
+ ["id", "kind"],
129
+ (args) => {
130
+ if (!adapter.createScreen) return errorResult("Host did not provide createScreen.");
131
+ const id = String(args.id);
132
+ const kind = String(args.kind);
133
+ if (adapter.listScreens().find((s) => s.id === id)) {
134
+ return errorResult(`Screen ${id} already exists. Use screens_destroy first or pick a fresh id.`);
135
+ }
136
+ adapter.createScreen({
137
+ id,
138
+ title: typeof args.title === "string" ? args.title : void 0,
139
+ kind,
140
+ config: args.config && typeof args.config === "object" ? args.config : void 0
141
+ });
142
+ adapter.setActive(id);
143
+ return textResult(`Created ${kind} screen "${id}"`, { id, kind });
144
+ },
145
+ true,
146
+ (args) => target(String(args.id ?? ""))
147
+ );
148
+ reg(
149
+ "screens_destroy",
150
+ "Remove a previously-created screen. Active screen falls back to the first remaining one (or null).",
151
+ { id: { type: "string" } },
152
+ ["id"],
153
+ (args) => {
154
+ if (!adapter.destroyScreen) return errorResult("Host did not provide destroyScreen.");
155
+ const id = String(args.id);
156
+ if (!adapter.listScreens().find((s) => s.id === id)) {
157
+ return errorResult(`No screen with id ${id}`);
158
+ }
159
+ adapter.destroyScreen(id);
160
+ return textResult(`Destroyed screen ${id}`, { id });
161
+ },
162
+ true,
163
+ (args) => target(String(args.id ?? ""))
164
+ );
165
+ reg(
166
+ "screens_set_layout",
167
+ "Change the layout of an existing composite screen. Layouts: 'single', 'split-h' (left/right), 'split-v' (top/bottom), 'grid-2x2', 'stack' (tabs).",
168
+ {
169
+ id: { type: "string" },
170
+ layout: { type: "string", enum: ["single", "split-h", "split-v", "grid-2x2", "stack"] }
171
+ },
172
+ ["id", "layout"],
173
+ (args) => {
174
+ if (!adapter.updateScreenContent) return errorResult("Host did not provide updateScreenContent.");
175
+ adapter.updateScreenContent(String(args.id), { layout: String(args.layout) });
176
+ return textResult(`Layout of ${args.id} \u2192 ${args.layout}`, { id: args.id, layout: args.layout });
177
+ },
178
+ true,
179
+ (args) => target(String(args.id ?? ""))
180
+ );
181
+ reg(
182
+ "screens_update_content",
183
+ "Merge new config into an existing screen (e.g. add a field to a form, append a sheet column, change chart series).",
184
+ {
185
+ id: { type: "string" },
186
+ partial: { type: "object", description: "Shallow-merged into the screen's config." }
187
+ },
188
+ ["id", "partial"],
189
+ (args) => {
190
+ if (!adapter.updateScreenContent) return errorResult("Host did not provide updateScreenContent.");
191
+ const id = String(args.id);
192
+ const partial = args.partial && typeof args.partial === "object" ? args.partial : {};
193
+ adapter.updateScreenContent(id, partial);
194
+ return textResult(`Updated content of ${id}`, { id });
195
+ },
196
+ true,
197
+ (args) => target(String(args.id ?? ""))
198
+ );
199
+ reg(
200
+ "screens_navigate",
201
+ "Switch the human's view to a different screen. The host updates its router / tab state and re-renders.",
202
+ { screen: { type: "string", description: "Screen id to activate." } },
203
+ ["screen"],
204
+ (args) => {
205
+ const screenId = String(args.screen ?? "");
206
+ const screens = adapter.listScreens();
207
+ if (!screens.find((s) => s.id === screenId)) {
208
+ return errorResult(`No screen registered with id "${screenId}". Call screens_list first.`);
209
+ }
210
+ adapter.setActive(screenId);
211
+ return textResult(`Navigated to ${screenId}`, { screen: screenId });
212
+ },
213
+ true,
214
+ (args) => target(String(args.screen ?? ""))
215
+ );
216
+ return {
217
+ id: "screens",
218
+ title: "Screens",
219
+ dispose: () => {
220
+ for (const d of disposers) d();
221
+ }
222
+ };
223
+ }
224
+
225
+ exports.registerScreensBridge = registerScreensBridge;
226
+ //# sourceMappingURL=bridges-screens.cjs.map
227
+ //# sourceMappingURL=bridges-screens.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/screens.ts"],"names":[],"mappings":"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","file":"bridges-screens.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 * Loose snapshot of a screen — what's in fancy-screens' ScreenMeta plus\n * the host's optional activity status. Kept here so this bridge has no\n * hard dep on fancy-screens.\n */\nexport type ScreenSnapshot = {\n id: string;\n title?: string;\n /** Whether this screen is the one the human / agent is looking at. */\n active: boolean;\n /** Optional category / kind (e.g. \"form\", \"whiteboard\"). */\n kind?: string;\n};\n\n/**\n * Spec for a dynamically-created screen. The host's `createScreen`\n * implementation looks up `kind` in its template registry and instantiates\n * the matching surface (form / whiteboard / sheet / chart / markdown / etc.).\n */\nexport type ScreenCreateSpec = {\n id: string;\n title?: string;\n /** Template kind. Hosts decide the catalog. */\n kind: string;\n /** Template-specific config. Form: { fields }. Sheet: { headers }. etc. */\n config?: Record<string, unknown>;\n};\n\n/**\n * Adapter exposes the host's screen-navigation surface to the bridge.\n * Hosts wire this up against react-router, a custom tab state, or the\n * fancy-screens registry — wherever \"current screen\" lives.\n *\n * The optional create / destroy / update hooks let agents author screens\n * dynamically against a host-defined template catalog.\n */\nexport type ScreensBridgeAdapter = {\n /** List every available screen. */\n listScreens: () => ScreenSnapshot[];\n /** Read which screen is currently active. */\n getActive: () => string | null;\n /** Navigate to a screen by id. Host updates router / tab state. */\n setActive: (screenId: string) => void;\n /** Optional: instantiate a new screen from a template + config. */\n createScreen?: (spec: ScreenCreateSpec) => void;\n /** Optional: remove a previously-created screen. */\n destroyScreen?: (screenId: string) => void;\n /** Optional: shallow-merge new config into an existing screen. */\n updateScreenContent?: (screenId: string, partial: Record<string, unknown>) => void;\n /** Optional: enumerate the kinds the host knows how to instantiate. */\n listKinds?: () => Array<{ kind: string; label?: string; description?: string; configSchema?: unknown }>;\n};\n\nexport type ScreensBridgeOptions = {\n adapter: ScreensBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerScreensBridge — top-level navigation bridge so agents can\n * switch between screens (`screens_navigate`) and discover what surfaces\n * exist (`screens_list`, `screens_describe_active`).\n *\n * Pair with the per-surface bridges (whiteboard, form, sheet, etc.) so\n * the agent has both navigation and per-screen control.\n */\nexport function registerScreensBridge(\n host: ToolHost,\n options: ScreensBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target = (screenId: string): AgentTarget => ({\n kind: \"screens\",\n screenId,\n label: `Screen ${screenId}`,\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 targetFromArgs?: (args: JsonObject) => AgentTarget,\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: \"screens\",\n resolveTarget: ({ args }) => targetFromArgs?.(args) ?? null,\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 \"screens_list\",\n \"List every screen the host has registered. Returns id, title, active flag, and optional kind.\",\n {},\n [],\n () => {\n const screens = adapter.listScreens();\n const text = screens\n .map((s) => `${s.active ? \"▸\" : \" \"} ${s.id}${s.title ? ` — ${s.title}` : \"\"}${s.kind ? ` [${s.kind}]` : \"\"}`)\n .join(\"\\n\");\n return textResult(text || \"(no screens)\", { screens, active: adapter.getActive() });\n },\n false,\n );\n\n reg(\n \"screens_describe_active\",\n \"Get the currently-active screen id (or null).\",\n {},\n [],\n () => {\n const active = adapter.getActive();\n return textResult(active ?? \"(none)\", { active });\n },\n false,\n );\n\n reg(\n \"screens_list_kinds\",\n \"List the screen kinds (templates) the host knows how to instantiate. Use this before screens_create to know what's available.\",\n {},\n [],\n () => {\n if (!adapter.listKinds) return errorResult(\"Host did not register a kind catalog. Cannot create screens dynamically.\");\n const kinds = adapter.listKinds();\n const text = kinds.map((k) => `${k.kind}${k.label ? ` — ${k.label}` : \"\"}${k.description ? ` (${k.description})` : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", kinds);\n },\n false,\n );\n\n reg(\n \"screens_create\",\n \"Instantiate a new screen from a template kind + config. Switches the active view to the new screen.\",\n {\n id: { type: \"string\", description: \"Stable screen id. Must be unique.\" },\n title: { type: \"string\" },\n kind: { type: \"string\", description: \"Template kind — call screens_list_kinds for the catalog.\" },\n config: { type: \"object\", description: \"Template-specific config (e.g. { fields: [...] } for a form).\" },\n },\n [\"id\", \"kind\"],\n (args) => {\n if (!adapter.createScreen) return errorResult(\"Host did not provide createScreen.\");\n const id = String(args.id);\n const kind = String(args.kind);\n if (adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`Screen ${id} already exists. Use screens_destroy first or pick a fresh id.`);\n }\n adapter.createScreen({\n id,\n title: typeof args.title === \"string\" ? args.title : undefined,\n kind,\n config: (args.config && typeof args.config === \"object\") ? args.config as Record<string, unknown> : undefined,\n });\n adapter.setActive(id);\n return textResult(`Created ${kind} screen \"${id}\"`, { id, kind });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_destroy\",\n \"Remove a previously-created screen. Active screen falls back to the first remaining one (or null).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n if (!adapter.destroyScreen) return errorResult(\"Host did not provide destroyScreen.\");\n const id = String(args.id);\n if (!adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`No screen with id ${id}`);\n }\n adapter.destroyScreen(id);\n return textResult(`Destroyed screen ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_set_layout\",\n \"Change the layout of an existing composite screen. Layouts: 'single', 'split-h' (left/right), 'split-v' (top/bottom), 'grid-2x2', 'stack' (tabs).\",\n {\n id: { type: \"string\" },\n layout: { type: \"string\", enum: [\"single\", \"split-h\", \"split-v\", \"grid-2x2\", \"stack\"] },\n },\n [\"id\", \"layout\"],\n (args) => {\n if (!adapter.updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n adapter.updateScreenContent(String(args.id), { layout: String(args.layout) });\n return textResult(`Layout of ${args.id} → ${args.layout}`, { id: args.id, layout: args.layout });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_update_content\",\n \"Merge new config into an existing screen (e.g. add a field to a form, append a sheet column, change chart series).\",\n {\n id: { type: \"string\" },\n partial: { type: \"object\", description: \"Shallow-merged into the screen's config.\" },\n },\n [\"id\", \"partial\"],\n (args) => {\n if (!adapter.updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n const id = String(args.id);\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n adapter.updateScreenContent(id, partial);\n return textResult(`Updated content of ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_navigate\",\n \"Switch the human's view to a different screen. The host updates its router / tab state and re-renders.\",\n { screen: { type: \"string\", description: \"Screen id to activate.\" } },\n [\"screen\"],\n (args) => {\n const screenId = String(args.screen ?? \"\");\n const screens = adapter.listScreens();\n if (!screens.find((s) => s.id === screenId)) {\n return errorResult(`No screen registered with id \"${screenId}\". Call screens_list first.`);\n }\n adapter.setActive(screenId);\n return textResult(`Navigated to ${screenId}`, { screen: screenId });\n },\n true,\n (args) => target(String(args.screen ?? \"\")),\n );\n\n return {\n id: \"screens\",\n title: \"Screens\",\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { registerScreensBridge } from './chunk-57ZDHD53.js';
2
+ import './chunk-52S7XYZK.js';
3
+ import './chunk-JU2N4KK6.js';
4
+ import './chunk-4KAIV6OD.js';
5
+ //# sourceMappingURL=bridges-screens.js.map
6
+ //# sourceMappingURL=bridges-screens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"bridges-screens.js"}
@@ -50,7 +50,7 @@ function extractMeta(result) {
50
50
 
51
51
  // src/bridges/sheets.ts
52
52
  var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
53
- function registerSheetsBridge(server, options) {
53
+ function registerSheetsBridge(host, options) {
54
54
  const { adapter } = options;
55
55
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
56
56
  const disposers = [];
@@ -76,7 +76,7 @@ function registerSheetsBridge(server, options) {
76
76
  resolveTarget: ({ args, result }) => resolveTarget?.(args, result) ?? target(getSheetId(args))
77
77
  }) : wrapped;
78
78
  disposers.push(
79
- server.registerTool(
79
+ host.registerTool(
80
80
  {
81
81
  name,
82
82
  description,