@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,6 +1,6 @@
1
- export { registerCodeBridge } from './chunk-HSTW7ZNO.js';
2
- import './chunk-52S7XYZK.js';
3
- import './chunk-JU2N4KK6.js';
1
+ export { registerCodeBridge } from './chunk-FYGMFIY5.js';
2
+ import './chunk-ULJL53DL.js';
3
+ import './chunk-C3TYI5TJ.js';
4
4
  import './chunk-4KAIV6OD.js';
5
5
  //# sourceMappingURL=bridges-code.js.map
6
6
  //# sourceMappingURL=bridges-code.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/flow.ts"],"names":[],"mappings":"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","file":"bridges-flow.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","// Loose types so this bridge builds standalone without a hard dep on\n// fancy-flow. Hosts that have fancy-flow installed get full editor\n// integration via the runtime dynamic imports below.\ntype FlowNode = {\n id: string;\n type?: string;\n position: { x: number; y: number };\n data: { kind?: string; label?: string; description?: string; status?: string; statusText?: string; config?: Record<string, unknown>; [k: string]: unknown };\n};\ntype FlowEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n [k: string]: unknown;\n};\ntype FlowGraph = { nodes: FlowNode[]; edges: FlowEdge[] };\ntype NodeRunStatus = \"idle\" | \"queued\" | \"running\" | \"done\" | \"error\";\ntype ExecutorRegistry = Record<string, unknown>;\ntype RunResult = { ok: boolean; outputs: Record<string, unknown>; error?: string };\n\nimport { 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 as FlAgentTarget } from \"../presence/types\";\n\n/**\n * Adapter the host provides — same shape as the editor's local state plus\n * an optional `run`/`cancel` pair so agents can trigger executions.\n */\nexport type FlowBridgeAdapter = {\n getNodes: () => FlowNode[];\n setNodes: (next: FlowNode[] | ((prev: FlowNode[]) => FlowNode[])) => void;\n getEdges: () => FlowEdge[];\n setEdges: (next: FlowEdge[] | ((prev: FlowEdge[]) => FlowEdge[])) => void;\n /** Optional: invoke runFlow with the host's executor registry. */\n run?: (executors?: ExecutorRegistry) => Promise<RunResult>;\n /** Optional: cancel the in-flight run. */\n cancel?: () => void;\n /** Optional: set per-node status text without going through the runner\n * (useful for agents narrating). */\n setNodeStatus?: (id: string, status: NodeRunStatus, text?: string) => void;\n};\n\nexport type FlowBridgeOptions = {\n adapter: FlowBridgeAdapter;\n /** Identity tagged onto agent-authored nodes. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst KINDS: string[] = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"];\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/**\n * registerFlowBridge — wires an MCP tool set against a fancy-flow editor's\n * controlled state. Mirrors the whiteboard bridge in shape: read tools,\n * mutation tools (add / update / delete nodes + edges), and optional\n * run/cancel if the host provides those callbacks.\n */\nexport function registerFlowBridge(\n host: ToolHost,\n options: FlowBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Activity-target resolver shared by every mutation tool. Pulls element id\n // from the freshly-added node/edge (structuredContent), falling back to args.\n const flTarget = (args: any, result: any): FlAgentTarget => ({\n kind: \"flow\",\n elementId: (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\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 resolveTarget?: (args: JsonObject, result: any) => FlAgentTarget | 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: \"flow\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\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 // ───────────── Read tools ─────────────\n\n reg(\"flow_get_state\", \"Get the full graph: nodes + edges.\", {}, [], () => {\n const state: FlowGraph = { nodes: adapter.getNodes(), edges: adapter.getEdges() };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"flow_list_nodes\", \"Summarise every node: id, kind, label, position, status.\", {}, [], () => {\n const items = adapter.getNodes().map((n) => ({\n id: n.id,\n kind: n.type,\n label: n.data?.label,\n x: Math.round(n.position.x),\n y: Math.round(n.position.y),\n status: n.data?.status ?? \"idle\",\n }));\n const text = items.map((i) => `${i.kind} ${i.id}: \"${i.label}\" @(${i.x},${i.y}) [${i.status}]`).join(\"\\n\") || \"(empty graph)\";\n return textResult(text, items);\n });\n\n reg(\n \"flow_get_node\",\n \"Get a single node's full record by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const node = adapter.getNodes().find((n) => n.id === id);\n if (!node) return errorResult(`No node with id ${id}`);\n return textResult(JSON.stringify(node, null, 2), node);\n },\n );\n\n reg(\n \"flow_list_node_kinds\",\n \"List every node kind registered in fancy-flow's registry. Use this to discover what's authorable before adding nodes.\",\n { category: { type: \"string\", description: \"Optional category filter: trigger | logic | data | ai | io | human | output | custom.\" } },\n [],\n async () => {\n // Dynamic import keeps the bridge usable even when fancy-flow isn't loaded.\n try {\n // @ts-ignore — optional peer dep, may not be installed\n const { listNodeKinds } = await import(\"@particle-academy/fancy-flow\" as any);\n const cat = adapter ? undefined : undefined; // placeholder\n const all = (cat ? listNodeKinds(cat) : listNodeKinds()).map((k: any) => ({\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n icon: k.icon,\n accent: k.accent,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configFields: (k.configSchema ?? []).map((f: any) => ({ key: f.key, type: f.type, label: f.label, required: !!f.required })),\n }));\n const text = all.map((k: any) => `${k.category}/${k.name}: ${k.label}${k.description ? \" — \" + k.description : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", all);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\n \"flow_get_node_schema\",\n \"Get the full configSchema + ports for a node kind. Use to know exactly what fields a kind accepts before calling flow_add_node.\",\n { name: { type: \"string\" } },\n [\"name\"],\n async (args) => {\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind } = await import(\"@particle-academy/fancy-flow\" as any);\n const k: any = getNodeKind(str(args.name));\n if (!k) return errorResult(`No kind registered: ${args.name}`);\n const summary = {\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configSchema: k.configSchema ?? [],\n defaultConfig: k.defaultConfig ?? null,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\"flow_list_edges\", \"Summarise every edge.\", {}, [], () => {\n const items = adapter.getEdges().map((e) => ({\n id: e.id,\n from: `${e.source}${e.sourceHandle ? `:${e.sourceHandle}` : \"\"}`,\n to: `${e.target}${e.targetHandle ? `:${e.targetHandle}` : \"\"}`,\n }));\n return textResult(items.map((i) => `${i.id}: ${i.from} → ${i.to}`).join(\"\\n\") || \"(no edges)\", items);\n });\n\n // ───────────── Node CRUD ─────────────\n\n reg(\n \"flow_add_node\",\n \"Add a node of any kind registered in fancy-flow's registry. Call flow_list_node_kinds first to discover what's available.\",\n {\n kind: { type: \"string\", description: \"Registry kind name (e.g. memory_store, llm_call, branch).\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\", description: \"Config fields per the kind's configSchema.\" },\n body: { type: \"string\", description: \"Note kinds only — body text.\" },\n },\n [\"kind\", \"label\", \"x\", \"y\"],\n async (args) => {\n const kindName = str(args.kind);\n // Resolve the kind dynamically from the registry. Falls back to the\n // legacy 6-pack so old graphs keep working.\n let kindDef: any = null;\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind, defaultConfigFor } = await import(\"@particle-academy/fancy-flow\" as any);\n kindDef = getNodeKind(kindName);\n var defaults: Record<string, unknown> = kindDef ? defaultConfigFor(kindDef) : {};\n } catch {\n var defaults: Record<string, unknown> = {};\n }\n const isLegacy = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"].includes(kindName);\n if (!kindDef && !isLegacy) {\n return errorResult(`Unknown kind: ${kindName} — call flow_list_node_kinds for the registry.`);\n }\n const id = newId(\"n\");\n const config = { ...defaults, ...((args.config && typeof args.config === \"object\") ? (args.config as Record<string, unknown>) : {}) };\n const node: FlowNode = {\n id,\n type: kindName,\n position: { x: num(args.x), y: num(args.y) },\n data: {\n kind: kindName,\n label: str(args.label),\n ...(args.description ? { description: str(args.description) } : {}),\n config,\n ...(kindName === \"note\" && args.body ? { body: str(args.body) } : {}),\n } as any,\n };\n adapter.setNodes((all) => [...all, node]);\n return textResult(`Added ${kindName} ${id} (\"${str(args.label)}\")`, node);\n },\n flTarget,\n );\n\n reg(\n \"flow_update_node\",\n \"Update fields on a node. Only provided fields change.\",\n {\n id: { type: \"string\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n let updated: FlowNode | null = null;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n position: {\n x: args.x !== undefined ? num(args.x) : n.position.x,\n y: args.y !== undefined ? num(args.y) : n.position.y,\n },\n data: {\n ...n.data,\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.config && typeof args.config === \"object\"\n ? { config: { ...(n.data.config ?? {}), ...(args.config as Record<string, unknown>) } }\n : {}),\n },\n };\n return updated;\n }),\n );\n if (!updated) return errorResult(`No node with id ${id}`);\n return textResult(`Updated node ${id}`, updated);\n },\n flTarget,\n );\n\n reg(\n \"flow_delete_node\",\n \"Remove a node by id (also removes any connected edges).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n // Validate existence BEFORE scheduling the state update — React's\n // functional updaters may run async in strict mode, so checking a\n // flag set inside the updater would race the response.\n if (!adapter.getNodes().some((n) => n.id === id)) {\n return errorResult(`No node with id ${id}`);\n }\n adapter.setNodes((all) => all.filter((n) => n.id !== id));\n adapter.setEdges((all) => all.filter((e) => e.source !== id && e.target !== id));\n return textResult(`Deleted node ${id}`);\n },\n flTarget,\n );\n\n // ───────────── Edges ─────────────\n\n reg(\n \"flow_connect\",\n \"Create an edge between two nodes (optionally specifying handle ids).\",\n {\n source: { type: \"string\" },\n target: { type: \"string\" },\n sourceHandle: { type: \"string\" },\n targetHandle: { type: \"string\" },\n label: { type: \"string\" },\n },\n [\"source\", \"target\"],\n (args) => {\n const source = str(args.source);\n const target = str(args.target);\n const all = adapter.getNodes();\n if (!all.find((n) => n.id === source)) return errorResult(`No source node ${source}`);\n if (!all.find((n) => n.id === target)) return errorResult(`No target node ${target}`);\n const edge: FlowEdge = {\n id: newId(\"e\"),\n source,\n target,\n ...(args.sourceHandle ? { sourceHandle: str(args.sourceHandle) } : {}),\n ...(args.targetHandle ? { targetHandle: str(args.targetHandle) } : {}),\n ...(args.label ? { label: str(args.label) } : {}),\n };\n adapter.setEdges((existing) => [...existing, edge]);\n return textResult(`Connected ${source}${edge.sourceHandle ? `:${edge.sourceHandle}` : \"\"} → ${target}${edge.targetHandle ? `:${edge.targetHandle}` : \"\"}`, edge);\n },\n flTarget,\n );\n\n reg(\n \"flow_disconnect\",\n \"Remove an edge by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n if (!adapter.getEdges().some((e) => e.id === id)) {\n return errorResult(`No edge ${id}`);\n }\n adapter.setEdges((all) => all.filter((e) => e.id !== id));\n return textResult(`Disconnected ${id}`);\n },\n flTarget,\n );\n\n // ───────────── Status / run ─────────────\n\n reg(\n \"flow_set_node_status\",\n \"Manually set a node's status badge (idle | queued | running | done | error) and optional text. Useful for narration outside a run.\",\n {\n id: { type: \"string\" },\n status: { type: \"string\", enum: [\"idle\", \"queued\", \"running\", \"done\", \"error\"] },\n text: { type: \"string\" },\n },\n [\"id\", \"status\"],\n (args) => {\n const id = str(args.id);\n const status = str(args.status) as NodeRunStatus;\n const text = args.text !== undefined ? str(args.text) : undefined;\n if (adapter.setNodeStatus) {\n adapter.setNodeStatus(id, status, text);\n } else {\n // Fall back to mutating the node data directly.\n let found = false;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n found = true;\n return { ...n, data: { ...n.data, status, statusText: text } };\n }),\n );\n if (!found) return errorResult(`No node with id ${id}`);\n }\n return textResult(`${id} → ${status}${text ? ` (${text})` : \"\"}`);\n },\n flTarget,\n );\n\n reg(\n \"flow_run\",\n \"Trigger a run of the current graph. Returns the topological result. Requires the host to have wired `run` into the adapter.\",\n {},\n [],\n async () => {\n if (!adapter.run) return errorResult(\"Host did not provide a run handler.\");\n const result = await adapter.run();\n return textResult(result.ok ? \"Run complete\" : `Run failed: ${result.error ?? \"unknown\"}`, result);\n },\n flTarget,\n );\n\n reg(\n \"flow_cancel\",\n \"Cancel an in-flight run.\",\n {},\n [],\n () => {\n if (!adapter.cancel) return errorResult(\"Host did not provide a cancel handler.\");\n adapter.cancel();\n return textResult(\"Run cancelled\");\n },\n flTarget,\n );\n\n return {\n id: \"flow\",\n title: \"Flow\",\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/flow.ts"],"names":["emitActivity"],"mappings":"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","file":"bridges-flow.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","// Loose types so this bridge builds standalone without a hard dep on\n// fancy-flow. Hosts that have fancy-flow installed get full editor\n// integration via the runtime dynamic imports below.\ntype FlowNode = {\n id: string;\n type?: string;\n position: { x: number; y: number };\n data: { kind?: string; label?: string; description?: string; status?: string; statusText?: string; config?: Record<string, unknown>; [k: string]: unknown };\n};\ntype FlowEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n [k: string]: unknown;\n};\ntype FlowGraph = { nodes: FlowNode[]; edges: FlowEdge[] };\ntype NodeRunStatus = \"idle\" | \"queued\" | \"running\" | \"done\" | \"error\";\ntype ExecutorRegistry = Record<string, unknown>;\ntype RunResult = { ok: boolean; outputs: Record<string, unknown>; error?: string };\n\nimport { 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 as FlAgentTarget } from \"../presence/types\";\n\n/**\n * Adapter the host provides — same shape as the editor's local state plus\n * an optional `run`/`cancel` pair so agents can trigger executions.\n */\nexport type FlowBridgeAdapter = {\n getNodes: () => FlowNode[];\n setNodes: (next: FlowNode[] | ((prev: FlowNode[]) => FlowNode[])) => void;\n getEdges: () => FlowEdge[];\n setEdges: (next: FlowEdge[] | ((prev: FlowEdge[]) => FlowEdge[])) => void;\n /** Optional: invoke runFlow with the host's executor registry. */\n run?: (executors?: ExecutorRegistry) => Promise<RunResult>;\n /** Optional: cancel the in-flight run. */\n cancel?: () => void;\n /** Optional: set per-node status text without going through the runner\n * (useful for agents narrating). */\n setNodeStatus?: (id: string, status: NodeRunStatus, text?: string) => void;\n};\n\nexport type FlowBridgeOptions = {\n adapter: FlowBridgeAdapter;\n /** Identity tagged onto agent-authored nodes. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst KINDS: string[] = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"];\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/**\n * registerFlowBridge — wires an MCP tool set against a fancy-flow editor's\n * controlled state. Mirrors the whiteboard bridge in shape: read tools,\n * mutation tools (add / update / delete nodes + edges), and optional\n * run/cancel if the host provides those callbacks.\n */\nexport function registerFlowBridge(\n host: ToolHost,\n options: FlowBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Activity-target resolver shared by every mutation tool. Pulls element id\n // from the freshly-added node/edge (structuredContent), falling back to args.\n const flTarget = (args: any, result: any): FlAgentTarget => ({\n kind: \"flow\",\n elementId: (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\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 resolveTarget?: (args: JsonObject, result: any) => FlAgentTarget | 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: \"flow\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\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 // ───────────── Read tools ─────────────\n\n reg(\"flow_get_state\", \"Get the full graph: nodes + edges.\", {}, [], () => {\n const state: FlowGraph = { nodes: adapter.getNodes(), edges: adapter.getEdges() };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"flow_list_nodes\", \"Summarise every node: id, kind, label, position, status.\", {}, [], () => {\n const items = adapter.getNodes().map((n) => ({\n id: n.id,\n kind: n.type,\n label: n.data?.label,\n x: Math.round(n.position.x),\n y: Math.round(n.position.y),\n status: n.data?.status ?? \"idle\",\n }));\n const text = items.map((i) => `${i.kind} ${i.id}: \"${i.label}\" @(${i.x},${i.y}) [${i.status}]`).join(\"\\n\") || \"(empty graph)\";\n return textResult(text, items);\n });\n\n reg(\n \"flow_get_node\",\n \"Get a single node's full record by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const node = adapter.getNodes().find((n) => n.id === id);\n if (!node) return errorResult(`No node with id ${id}`);\n return textResult(JSON.stringify(node, null, 2), node);\n },\n );\n\n reg(\n \"flow_list_node_kinds\",\n \"List every node kind registered in fancy-flow's registry. Use this to discover what's authorable before adding nodes.\",\n { category: { type: \"string\", description: \"Optional category filter: trigger | logic | data | ai | io | human | output | custom.\" } },\n [],\n async () => {\n // Dynamic import keeps the bridge usable even when fancy-flow isn't loaded.\n try {\n // @ts-ignore — optional peer dep, may not be installed\n const { listNodeKinds } = await import(\"@particle-academy/fancy-flow\" as any);\n const cat = adapter ? undefined : undefined; // placeholder\n const all = (cat ? listNodeKinds(cat) : listNodeKinds()).map((k: any) => ({\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n icon: k.icon,\n accent: k.accent,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configFields: (k.configSchema ?? []).map((f: any) => ({ key: f.key, type: f.type, label: f.label, required: !!f.required })),\n }));\n const text = all.map((k: any) => `${k.category}/${k.name}: ${k.label}${k.description ? \" — \" + k.description : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", all);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\n \"flow_get_node_schema\",\n \"Get the full configSchema + ports for a node kind. Use to know exactly what fields a kind accepts before calling flow_add_node.\",\n { name: { type: \"string\" } },\n [\"name\"],\n async (args) => {\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind } = await import(\"@particle-academy/fancy-flow\" as any);\n const k: any = getNodeKind(str(args.name));\n if (!k) return errorResult(`No kind registered: ${args.name}`);\n const summary = {\n name: k.name,\n category: k.category,\n label: k.label,\n description: k.description,\n inputs: k.inputs ?? [],\n outputs: k.outputs ?? [],\n configSchema: k.configSchema ?? [],\n defaultConfig: k.defaultConfig ?? null,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n } catch (e) {\n return errorResult(`fancy-flow registry not available: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n );\n\n reg(\"flow_list_edges\", \"Summarise every edge.\", {}, [], () => {\n const items = adapter.getEdges().map((e) => ({\n id: e.id,\n from: `${e.source}${e.sourceHandle ? `:${e.sourceHandle}` : \"\"}`,\n to: `${e.target}${e.targetHandle ? `:${e.targetHandle}` : \"\"}`,\n }));\n return textResult(items.map((i) => `${i.id}: ${i.from} → ${i.to}`).join(\"\\n\") || \"(no edges)\", items);\n });\n\n // ───────────── Node CRUD ─────────────\n\n reg(\n \"flow_add_node\",\n \"Add a node of any kind registered in fancy-flow's registry. Call flow_list_node_kinds first to discover what's available.\",\n {\n kind: { type: \"string\", description: \"Registry kind name (e.g. memory_store, llm_call, branch).\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\", description: \"Config fields per the kind's configSchema.\" },\n body: { type: \"string\", description: \"Note kinds only — body text.\" },\n },\n [\"kind\", \"label\", \"x\", \"y\"],\n async (args) => {\n const kindName = str(args.kind);\n // Resolve the kind dynamically from the registry. Falls back to the\n // legacy 6-pack so old graphs keep working.\n let kindDef: any = null;\n try {\n // @ts-ignore — optional peer dep\n const { getNodeKind, defaultConfigFor } = await import(\"@particle-academy/fancy-flow\" as any);\n kindDef = getNodeKind(kindName);\n var defaults: Record<string, unknown> = kindDef ? defaultConfigFor(kindDef) : {};\n } catch {\n var defaults: Record<string, unknown> = {};\n }\n const isLegacy = [\"trigger\", \"action\", \"decision\", \"output\", \"note\", \"subgraph\"].includes(kindName);\n if (!kindDef && !isLegacy) {\n return errorResult(`Unknown kind: ${kindName} — call flow_list_node_kinds for the registry.`);\n }\n const id = newId(\"n\");\n const config = { ...defaults, ...((args.config && typeof args.config === \"object\") ? (args.config as Record<string, unknown>) : {}) };\n const node: FlowNode = {\n id,\n type: kindName,\n position: { x: num(args.x), y: num(args.y) },\n data: {\n kind: kindName,\n label: str(args.label),\n ...(args.description ? { description: str(args.description) } : {}),\n config,\n ...(kindName === \"note\" && args.body ? { body: str(args.body) } : {}),\n } as any,\n };\n adapter.setNodes((all) => [...all, node]);\n return textResult(`Added ${kindName} ${id} (\"${str(args.label)}\")`, node);\n },\n flTarget,\n );\n\n reg(\n \"flow_update_node\",\n \"Update fields on a node. Only provided fields change.\",\n {\n id: { type: \"string\" },\n label: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n description: { type: \"string\" },\n config: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n let updated: FlowNode | null = null;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n position: {\n x: args.x !== undefined ? num(args.x) : n.position.x,\n y: args.y !== undefined ? num(args.y) : n.position.y,\n },\n data: {\n ...n.data,\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.config && typeof args.config === \"object\"\n ? { config: { ...(n.data.config ?? {}), ...(args.config as Record<string, unknown>) } }\n : {}),\n },\n };\n return updated;\n }),\n );\n if (!updated) return errorResult(`No node with id ${id}`);\n return textResult(`Updated node ${id}`, updated);\n },\n flTarget,\n );\n\n reg(\n \"flow_delete_node\",\n \"Remove a node by id (also removes any connected edges).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n // Validate existence BEFORE scheduling the state update — React's\n // functional updaters may run async in strict mode, so checking a\n // flag set inside the updater would race the response.\n if (!adapter.getNodes().some((n) => n.id === id)) {\n return errorResult(`No node with id ${id}`);\n }\n adapter.setNodes((all) => all.filter((n) => n.id !== id));\n adapter.setEdges((all) => all.filter((e) => e.source !== id && e.target !== id));\n return textResult(`Deleted node ${id}`);\n },\n flTarget,\n );\n\n // ───────────── Edges ─────────────\n\n reg(\n \"flow_connect\",\n \"Create an edge between two nodes (optionally specifying handle ids).\",\n {\n source: { type: \"string\" },\n target: { type: \"string\" },\n sourceHandle: { type: \"string\" },\n targetHandle: { type: \"string\" },\n label: { type: \"string\" },\n },\n [\"source\", \"target\"],\n (args) => {\n const source = str(args.source);\n const target = str(args.target);\n const all = adapter.getNodes();\n if (!all.find((n) => n.id === source)) return errorResult(`No source node ${source}`);\n if (!all.find((n) => n.id === target)) return errorResult(`No target node ${target}`);\n const edge: FlowEdge = {\n id: newId(\"e\"),\n source,\n target,\n ...(args.sourceHandle ? { sourceHandle: str(args.sourceHandle) } : {}),\n ...(args.targetHandle ? { targetHandle: str(args.targetHandle) } : {}),\n ...(args.label ? { label: str(args.label) } : {}),\n };\n adapter.setEdges((existing) => [...existing, edge]);\n return textResult(`Connected ${source}${edge.sourceHandle ? `:${edge.sourceHandle}` : \"\"} → ${target}${edge.targetHandle ? `:${edge.targetHandle}` : \"\"}`, edge);\n },\n flTarget,\n );\n\n reg(\n \"flow_disconnect\",\n \"Remove an edge by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n if (!adapter.getEdges().some((e) => e.id === id)) {\n return errorResult(`No edge ${id}`);\n }\n adapter.setEdges((all) => all.filter((e) => e.id !== id));\n return textResult(`Disconnected ${id}`);\n },\n flTarget,\n );\n\n // ───────────── Status / run ─────────────\n\n reg(\n \"flow_set_node_status\",\n \"Manually set a node's status badge (idle | queued | running | done | error) and optional text. Useful for narration outside a run.\",\n {\n id: { type: \"string\" },\n status: { type: \"string\", enum: [\"idle\", \"queued\", \"running\", \"done\", \"error\"] },\n text: { type: \"string\" },\n },\n [\"id\", \"status\"],\n (args) => {\n const id = str(args.id);\n const status = str(args.status) as NodeRunStatus;\n const text = args.text !== undefined ? str(args.text) : undefined;\n if (adapter.setNodeStatus) {\n adapter.setNodeStatus(id, status, text);\n } else {\n // Fall back to mutating the node data directly.\n let found = false;\n adapter.setNodes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n found = true;\n return { ...n, data: { ...n.data, status, statusText: text } };\n }),\n );\n if (!found) return errorResult(`No node with id ${id}`);\n }\n return textResult(`${id} → ${status}${text ? ` (${text})` : \"\"}`);\n },\n flTarget,\n );\n\n reg(\n \"flow_run\",\n \"Trigger a run of the current graph. Returns the topological result. Requires the host to have wired `run` into the adapter.\",\n {},\n [],\n async () => {\n if (!adapter.run) return errorResult(\"Host did not provide a run handler.\");\n const result = await adapter.run();\n return textResult(result.ok ? \"Run complete\" : `Run failed: ${result.error ?? \"unknown\"}`, result);\n },\n flTarget,\n );\n\n reg(\n \"flow_cancel\",\n \"Cancel an in-flight run.\",\n {},\n [],\n () => {\n if (!adapter.cancel) return errorResult(\"Host did not provide a cancel handler.\");\n adapter.cancel();\n return textResult(\"Run cancelled\");\n },\n flTarget,\n );\n\n return {\n id: \"flow\",\n title: \"Flow\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { wrapToolWithActivity } from './chunk-52S7XYZK.js';
2
- import './chunk-JU2N4KK6.js';
1
+ import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
2
+ import './chunk-C3TYI5TJ.js';
3
3
  import { errorResult, textResult } from './chunk-4KAIV6OD.js';
4
4
 
5
5
  // src/bridges/flow.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/forms.ts"],"names":[],"mappings":"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","file":"bridges-forms.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 * Field descriptor — what the host says about each form field. Mirrors the\n * subset of HTML / react-fancy input shapes agents care about.\n */\nexport type FormFieldDescriptor = {\n /** Form-local field name. Matches the key the host uses in its values map. */\n name: string;\n /** Display label. */\n label?: string;\n /** Logical type. Drives validation + agent expectations. */\n type:\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"email\"\n | \"password\"\n | \"url\"\n | \"date\"\n | \"select\"\n | \"multi-select\"\n | \"checkbox\"\n | \"switch\"\n | \"radio\"\n | \"file\"\n | \"json\";\n /** Allowed values for select / radio. */\n options?: Array<{ value: string; label: string }>;\n /** Whether the field must be filled before submit. */\n required?: boolean;\n /** Free-text hint surfaced to the agent. */\n description?: string;\n /** Default value (presented in get_value when nothing set). */\n defaultValue?: unknown;\n};\n\n/**\n * Adapter the host wires per form. Matches the controlled-state pattern\n * react-fancy already uses (`value` / `onValueChange`); this adapter just\n * exposes those state slots in a form-shaped way the bridge can call.\n */\nexport type FormBridgeAdapter = {\n /** Stable id for the form (used in form_describe + presence target). */\n id: string;\n /** Display title for human-readable logs. */\n title?: string;\n /** Optional fancy-screens screen id this form belongs to. */\n screenId?: string;\n /** Field descriptors. The bridge uses these for schema introspection\n * (form_describe). Agents call this first to know what to fill. */\n getFields: () => FormFieldDescriptor[];\n /** Read a single field's current value. */\n getValue: (name: string) => unknown;\n /** Read all values as { fieldName: value }. */\n getValues: () => Record<string, unknown>;\n /** Set a single field's value. The host wires this to its setState. */\n setValue: (name: string, value: unknown) => void;\n /** Set many at once. Defaults to calling setValue in a loop. */\n setValues?: (values: Record<string, unknown>) => void;\n /** Programmatically focus a field (host implements DOM focus). Optional. */\n focus?: (name: string) => void;\n /** Submit the form. Returns the values that were submitted (or rejection). */\n submit?: () => Promise<{ ok: boolean; values?: Record<string, unknown>; error?: string }>;\n};\n\nexport type FormBridgeOptions = {\n adapter: FormBridgeAdapter;\n /** Identity tagged into activity events. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerFormBridge — wires schema-driven MCP access to a single form.\n * Hosts can register multiple bridges (one per form on the screen) by\n * giving each adapter a distinct `id`.\n */\nexport function registerFormBridge(\n host: ToolHost,\n options: FormBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n const formId = adapter.id;\n\n const target = (args: any): AgentTarget => ({\n kind: \"form\",\n screenId: adapter.screenId,\n elementId: typeof args?.field === \"string\" ? `${formId}:${args.field}` : formId,\n label: typeof args?.field === \"string\"\n ? `${adapter.title ?? formId} → ${args.field}`\n : adapter.title ?? formId,\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: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"form\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(args),\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 // ───────────── Read tools ─────────────\n\n reg(\n \"form_describe\",\n `Describe the form \"${formId}\" — fields, types, options, required flags. Call this first to know what's fillable.`,\n {},\n [],\n () => {\n const fields = adapter.getFields();\n const text = fields\n .map((f) => `${f.name}${f.required ? \"*\" : \"\"} (${f.type})${f.label ? ` — ${f.label}` : \"\"}`)\n .join(\"\\n\");\n return textResult(text || \"(no fields)\", { id: formId, title: adapter.title, fields });\n },\n false,\n );\n\n reg(\n \"form_get_value\",\n \"Read a single field's current value.\",\n { field: { type: \"string\" } },\n [\"field\"],\n (args) => {\n const name = String(args.field ?? \"\");\n if (!adapter.getFields().find((f) => f.name === name)) {\n return errorResult(`Unknown field: ${name}`);\n }\n const value = adapter.getValue(name);\n return textResult(JSON.stringify(value), { field: name, value });\n },\n false,\n );\n\n reg(\n \"form_get_values\",\n \"Read every field's current value as a JSON object.\",\n {},\n [],\n () => {\n const values = adapter.getValues();\n return textResult(JSON.stringify(values, null, 2), values);\n },\n false,\n );\n\n // ───────────── Mutation tools ─────────────\n\n reg(\n \"form_set_value\",\n \"Set one field's value. The host's controlled state updates and the human sees the field change.\",\n {\n field: { type: \"string\" },\n value: { description: \"Value to set. Type depends on the field's `type`.\" },\n },\n [\"field\", \"value\"],\n (args) => {\n const name = String(args.field ?? \"\");\n const fieldDef = adapter.getFields().find((f) => f.name === name);\n if (!fieldDef) return errorResult(`Unknown field: ${name}`);\n adapter.setValue(name, args.value);\n return textResult(`${name} ← ${JSON.stringify(args.value)}`, { field: name, value: args.value });\n },\n true,\n );\n\n reg(\n \"form_set_values\",\n \"Set multiple fields atomically. Pass a `values` object keyed by field name.\",\n { values: { type: \"object\" } },\n [\"values\"],\n (args) => {\n const values = (args.values && typeof args.values === \"object\") ? args.values as Record<string, unknown> : {};\n const fields = adapter.getFields();\n const known = new Set(fields.map((f) => f.name));\n const unknownKeys = Object.keys(values).filter((k) => !known.has(k));\n if (unknownKeys.length) return errorResult(`Unknown fields: ${unknownKeys.join(\", \")}`);\n if (adapter.setValues) {\n adapter.setValues(values);\n } else {\n for (const [k, v] of Object.entries(values)) adapter.setValue(k, v);\n }\n return textResult(`Set ${Object.keys(values).length} field(s)`, { values });\n },\n true,\n );\n\n reg(\n \"form_focus\",\n \"Move browser focus to a field (host-implemented). Useful before streaming text into it.\",\n { field: { type: \"string\" } },\n [\"field\"],\n (args) => {\n const name = String(args.field ?? \"\");\n if (!adapter.focus) return errorResult(\"Host did not provide a focus implementation.\");\n if (!adapter.getFields().find((f) => f.name === name)) {\n return errorResult(`Unknown field: ${name}`);\n }\n adapter.focus(name);\n return textResult(`Focused ${name}`, { field: name });\n },\n true,\n );\n\n reg(\n \"form_submit\",\n \"Submit the form. Host returns ok + values (or an error).\",\n {},\n [],\n async () => {\n if (!adapter.submit) return errorResult(\"Host did not provide a submit implementation.\");\n const result = await adapter.submit();\n if (!result.ok) return errorResult(result.error ?? \"Submit failed\");\n return textResult(\"Submitted\", { values: result.values });\n },\n true,\n );\n\n return {\n id: `form:${formId}`,\n title: adapter.title ?? formId,\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/forms.ts"],"names":["emitActivity"],"mappings":"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","file":"bridges-forms.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 * Field descriptor — what the host says about each form field. Mirrors the\n * subset of HTML / react-fancy input shapes agents care about.\n */\nexport type FormFieldDescriptor = {\n /** Form-local field name. Matches the key the host uses in its values map. */\n name: string;\n /** Display label. */\n label?: string;\n /** Logical type. Drives validation + agent expectations. */\n type:\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"email\"\n | \"password\"\n | \"url\"\n | \"date\"\n | \"select\"\n | \"multi-select\"\n | \"checkbox\"\n | \"switch\"\n | \"radio\"\n | \"file\"\n | \"json\";\n /** Allowed values for select / radio. */\n options?: Array<{ value: string; label: string }>;\n /** Whether the field must be filled before submit. */\n required?: boolean;\n /** Free-text hint surfaced to the agent. */\n description?: string;\n /** Default value (presented in get_value when nothing set). */\n defaultValue?: unknown;\n};\n\n/**\n * Adapter the host wires per form. Matches the controlled-state pattern\n * react-fancy already uses (`value` / `onValueChange`); this adapter just\n * exposes those state slots in a form-shaped way the bridge can call.\n */\nexport type FormBridgeAdapter = {\n /** Stable id for the form (used in form_describe + presence target). */\n id: string;\n /** Display title for human-readable logs. */\n title?: string;\n /** Optional fancy-screens screen id this form belongs to. */\n screenId?: string;\n /** Field descriptors. The bridge uses these for schema introspection\n * (form_describe). Agents call this first to know what to fill. */\n getFields: () => FormFieldDescriptor[];\n /** Read a single field's current value. */\n getValue: (name: string) => unknown;\n /** Read all values as { fieldName: value }. */\n getValues: () => Record<string, unknown>;\n /** Set a single field's value. The host wires this to its setState. */\n setValue: (name: string, value: unknown) => void;\n /** Set many at once. Defaults to calling setValue in a loop. */\n setValues?: (values: Record<string, unknown>) => void;\n /** Programmatically focus a field (host implements DOM focus). Optional. */\n focus?: (name: string) => void;\n /** Submit the form. Returns the values that were submitted (or rejection). */\n submit?: () => Promise<{ ok: boolean; values?: Record<string, unknown>; error?: string }>;\n};\n\nexport type FormBridgeOptions = {\n adapter: FormBridgeAdapter;\n /** Identity tagged into activity events. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerFormBridge — wires schema-driven MCP access to a single form.\n * Hosts can register multiple bridges (one per form on the screen) by\n * giving each adapter a distinct `id`.\n */\nexport function registerFormBridge(\n host: ToolHost,\n options: FormBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n const formId = adapter.id;\n\n const target = (args: any): AgentTarget => ({\n kind: \"form\",\n screenId: adapter.screenId,\n elementId: typeof args?.field === \"string\" ? `${formId}:${args.field}` : formId,\n label: typeof args?.field === \"string\"\n ? `${adapter.title ?? formId} → ${args.field}`\n : adapter.title ?? formId,\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: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"form\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(args),\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 // ───────────── Read tools ─────────────\n\n reg(\n \"form_describe\",\n `Describe the form \"${formId}\" — fields, types, options, required flags. Call this first to know what's fillable.`,\n {},\n [],\n () => {\n const fields = adapter.getFields();\n const text = fields\n .map((f) => `${f.name}${f.required ? \"*\" : \"\"} (${f.type})${f.label ? ` — ${f.label}` : \"\"}`)\n .join(\"\\n\");\n return textResult(text || \"(no fields)\", { id: formId, title: adapter.title, fields });\n },\n false,\n );\n\n reg(\n \"form_get_value\",\n \"Read a single field's current value.\",\n { field: { type: \"string\" } },\n [\"field\"],\n (args) => {\n const name = String(args.field ?? \"\");\n if (!adapter.getFields().find((f) => f.name === name)) {\n return errorResult(`Unknown field: ${name}`);\n }\n const value = adapter.getValue(name);\n return textResult(JSON.stringify(value), { field: name, value });\n },\n false,\n );\n\n reg(\n \"form_get_values\",\n \"Read every field's current value as a JSON object.\",\n {},\n [],\n () => {\n const values = adapter.getValues();\n return textResult(JSON.stringify(values, null, 2), values);\n },\n false,\n );\n\n // ───────────── Mutation tools ─────────────\n\n reg(\n \"form_set_value\",\n \"Set one field's value. The host's controlled state updates and the human sees the field change.\",\n {\n field: { type: \"string\" },\n value: { description: \"Value to set. Type depends on the field's `type`.\" },\n },\n [\"field\", \"value\"],\n (args) => {\n const name = String(args.field ?? \"\");\n const fieldDef = adapter.getFields().find((f) => f.name === name);\n if (!fieldDef) return errorResult(`Unknown field: ${name}`);\n adapter.setValue(name, args.value);\n return textResult(`${name} ← ${JSON.stringify(args.value)}`, { field: name, value: args.value });\n },\n true,\n );\n\n reg(\n \"form_set_values\",\n \"Set multiple fields atomically. Pass a `values` object keyed by field name.\",\n { values: { type: \"object\" } },\n [\"values\"],\n (args) => {\n const values = (args.values && typeof args.values === \"object\") ? args.values as Record<string, unknown> : {};\n const fields = adapter.getFields();\n const known = new Set(fields.map((f) => f.name));\n const unknownKeys = Object.keys(values).filter((k) => !known.has(k));\n if (unknownKeys.length) return errorResult(`Unknown fields: ${unknownKeys.join(\", \")}`);\n if (adapter.setValues) {\n adapter.setValues(values);\n } else {\n for (const [k, v] of Object.entries(values)) adapter.setValue(k, v);\n }\n return textResult(`Set ${Object.keys(values).length} field(s)`, { values });\n },\n true,\n );\n\n reg(\n \"form_focus\",\n \"Move browser focus to a field (host-implemented). Useful before streaming text into it.\",\n { field: { type: \"string\" } },\n [\"field\"],\n (args) => {\n const name = String(args.field ?? \"\");\n if (!adapter.focus) return errorResult(\"Host did not provide a focus implementation.\");\n if (!adapter.getFields().find((f) => f.name === name)) {\n return errorResult(`Unknown field: ${name}`);\n }\n adapter.focus(name);\n return textResult(`Focused ${name}`, { field: name });\n },\n true,\n );\n\n reg(\n \"form_submit\",\n \"Submit the form. Host returns ok + values (or an error).\",\n {},\n [],\n async () => {\n if (!adapter.submit) return errorResult(\"Host did not provide a submit implementation.\");\n const result = await adapter.submit();\n if (!result.ok) return errorResult(result.error ?? \"Submit failed\");\n return textResult(\"Submitted\", { values: result.values });\n },\n true,\n );\n\n return {\n id: `form:${formId}`,\n title: adapter.title ?? formId,\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- export { registerFormBridge } from './chunk-4BL5M3U3.js';
2
- import './chunk-52S7XYZK.js';
3
- import './chunk-JU2N4KK6.js';
1
+ export { registerFormBridge } from './chunk-5AD35HS5.js';
2
+ import './chunk-ULJL53DL.js';
3
+ import './chunk-C3TYI5TJ.js';
4
4
  import './chunk-4KAIV6OD.js';
5
5
  //# sourceMappingURL=bridges-forms.js.map
6
6
  //# sourceMappingURL=bridges-forms.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,