@particle-academy/agent-integrations 0.2.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +20 -0
  2. package/dist/bridges/charts.d.cts +39 -0
  3. package/dist/bridges/charts.d.ts +39 -0
  4. package/dist/bridges/code.d.cts +47 -0
  5. package/dist/bridges/code.d.ts +47 -0
  6. package/dist/bridges/flow.d.cts +4 -3
  7. package/dist/bridges/flow.d.ts +4 -3
  8. package/dist/bridges/forms.d.cts +76 -0
  9. package/dist/bridges/forms.d.ts +76 -0
  10. package/dist/bridges/scene.d.cts +54 -0
  11. package/dist/bridges/scene.d.ts +54 -0
  12. package/dist/bridges/screens.d.cts +78 -0
  13. package/dist/bridges/screens.d.ts +78 -0
  14. package/dist/bridges/sheets.d.cts +62 -0
  15. package/dist/bridges/sheets.d.ts +62 -0
  16. package/dist/bridges/whiteboard.d.cts +4 -3
  17. package/dist/bridges/whiteboard.d.ts +4 -3
  18. package/dist/bridges-charts.cjs +167 -0
  19. package/dist/bridges-charts.cjs.map +1 -0
  20. package/dist/bridges-charts.js +6 -0
  21. package/dist/bridges-charts.js.map +1 -0
  22. package/dist/bridges-code.cjs +219 -0
  23. package/dist/bridges-code.cjs.map +1 -0
  24. package/dist/bridges-code.js +6 -0
  25. package/dist/bridges-code.js.map +1 -0
  26. package/dist/bridges-flow.cjs +78 -19
  27. package/dist/bridges-flow.cjs.map +1 -1
  28. package/dist/bridges-flow.js +4 -2
  29. package/dist/bridges-forms.cjs +205 -0
  30. package/dist/bridges-forms.cjs.map +1 -0
  31. package/dist/bridges-forms.js +6 -0
  32. package/dist/bridges-forms.js.map +1 -0
  33. package/dist/bridges-scene.cjs +250 -0
  34. package/dist/bridges-scene.cjs.map +1 -0
  35. package/dist/bridges-scene.js +6 -0
  36. package/dist/bridges-scene.js.map +1 -0
  37. package/dist/bridges-screens.cjs +227 -0
  38. package/dist/bridges-screens.cjs.map +1 -0
  39. package/dist/bridges-screens.js +6 -0
  40. package/dist/bridges-screens.js.map +1 -0
  41. package/dist/bridges-sheets.cjs +327 -0
  42. package/dist/bridges-sheets.cjs.map +1 -0
  43. package/dist/bridges-sheets.js +6 -0
  44. package/dist/bridges-sheets.js.map +1 -0
  45. package/dist/bridges-whiteboard.cjs +226 -40
  46. package/dist/bridges-whiteboard.cjs.map +1 -1
  47. package/dist/bridges-whiteboard.js +5 -2
  48. package/dist/{chunk-5ZUHNNLR.js → chunk-3KSZNGNW.js} +81 -43
  49. package/dist/chunk-3KSZNGNW.js.map +1 -0
  50. package/dist/chunk-4BL5M3U3.js +158 -0
  51. package/dist/chunk-4BL5M3U3.js.map +1 -0
  52. package/dist/{chunk-QGCF7YKW.js → chunk-4KAIV6OD.js} +40 -12
  53. package/dist/chunk-4KAIV6OD.js.map +1 -0
  54. package/dist/chunk-52S7XYZK.js +38 -0
  55. package/dist/chunk-52S7XYZK.js.map +1 -0
  56. package/dist/chunk-57ZDHD53.js +180 -0
  57. package/dist/chunk-57ZDHD53.js.map +1 -0
  58. package/dist/chunk-E4AICMFZ.js +83 -0
  59. package/dist/chunk-E4AICMFZ.js.map +1 -0
  60. package/dist/chunk-GQ7XXK7G.js +124 -0
  61. package/dist/chunk-GQ7XXK7G.js.map +1 -0
  62. package/dist/chunk-HSTW7ZNO.js +172 -0
  63. package/dist/chunk-HSTW7ZNO.js.map +1 -0
  64. package/dist/chunk-IANI25IT.js +280 -0
  65. package/dist/chunk-IANI25IT.js.map +1 -0
  66. package/dist/{chunk-FLEOQUKF.js → chunk-JMYPUAFH.js} +17 -2
  67. package/dist/chunk-JMYPUAFH.js.map +1 -0
  68. package/dist/chunk-JU2N4KK6.js +34 -0
  69. package/dist/chunk-JU2N4KK6.js.map +1 -0
  70. package/dist/{chunk-2VOQJKSU.js → chunk-N3H4DXY5.js} +44 -22
  71. package/dist/chunk-N3H4DXY5.js.map +1 -0
  72. package/dist/chunk-NTDZWGYB.js +120 -0
  73. package/dist/chunk-NTDZWGYB.js.map +1 -0
  74. package/dist/chunk-RGO42EQ6.js +25 -0
  75. package/dist/chunk-RGO42EQ6.js.map +1 -0
  76. package/dist/chunk-X66JWQBB.js +37 -0
  77. package/dist/chunk-X66JWQBB.js.map +1 -0
  78. package/dist/chunk-XRAJSOPS.js +203 -0
  79. package/dist/chunk-XRAJSOPS.js.map +1 -0
  80. package/dist/index.cjs +1766 -127
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.cts +99 -3
  83. package/dist/index.d.ts +99 -3
  84. package/dist/index.js +115 -9
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcp/index.d.cts +5 -2
  87. package/dist/mcp/index.d.ts +5 -2
  88. package/dist/mcp.cjs +37 -9
  89. package/dist/mcp.cjs.map +1 -1
  90. package/dist/mcp.js +1 -1
  91. package/dist/presence/index.d.cts +136 -0
  92. package/dist/presence/index.d.ts +136 -0
  93. package/dist/presence.cjs +107 -0
  94. package/dist/presence.cjs.map +1 -0
  95. package/dist/presence.js +5 -0
  96. package/dist/presence.js.map +1 -0
  97. package/dist/registry-2DRURS6U.js +3 -0
  98. package/dist/registry-2DRURS6U.js.map +1 -0
  99. package/dist/server-BsSwfemr.d.cts +63 -0
  100. package/dist/server-Du3-IGqM.d.ts +63 -0
  101. package/dist/sharing/index.d.cts +3 -1
  102. package/dist/sharing/index.d.ts +3 -1
  103. package/dist/sharing.cjs +68 -0
  104. package/dist/sharing.cjs.map +1 -1
  105. package/dist/sharing.js +1 -1
  106. package/dist/sheets-adapter.cjs +96 -0
  107. package/dist/sheets-adapter.cjs.map +1 -0
  108. package/dist/sheets-adapter.d.cts +115 -0
  109. package/dist/sheets-adapter.d.ts +115 -0
  110. package/dist/sheets-adapter.js +4 -0
  111. package/dist/sheets-adapter.js.map +1 -0
  112. package/dist/styles.css +57 -0
  113. package/dist/styles.css.map +1 -1
  114. package/dist/tool-host-BQuUygLF.d.cts +60 -0
  115. package/dist/tool-host-C8JMMGYq.d.ts +60 -0
  116. package/dist/{types-CRPA_D0z.d.ts → types-CCSBGW9T.d.cts} +2 -2
  117. package/dist/{types-DR5AS6Rd.d.cts → types-DIVNcIQO.d.ts} +2 -2
  118. package/dist/types-aOQLTW0E.d.cts +112 -0
  119. package/dist/types-aOQLTW0E.d.ts +112 -0
  120. package/dist/undo/index.d.cts +69 -0
  121. package/dist/undo/index.d.ts +69 -0
  122. package/dist/undo.cjs +163 -0
  123. package/dist/undo.cjs.map +1 -0
  124. package/dist/undo.js +5 -0
  125. package/dist/undo.js.map +1 -0
  126. package/package.json +1 -1
  127. package/dist/chunk-2VOQJKSU.js.map +0 -1
  128. package/dist/chunk-5ZUHNNLR.js.map +0 -1
  129. package/dist/chunk-FLEOQUKF.js.map +0 -1
  130. package/dist/chunk-QGCF7YKW.js.map +0 -1
  131. package/dist/server-Bv985us3.d.cts +0 -173
  132. package/dist/server-Bv985us3.d.ts +0 -173
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/bridges/sheets.ts"],"names":[],"mappings":"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","file":"bridges-sheets.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { ActivityFilter, AgentActivityEvent, AgentActivityListener } from \"./types\";\n\n/**\n * In-process registry of agent activity events. Bridges call `emitActivity`\n * after a tool runs; React hooks + the SSE relay subscribe via\n * `onActivity()`.\n *\n * Holds a short scrollback of recent events (default 200) so newly-mounted\n * subscribers can render the recent past — useful for activity-log UIs\n * that rejoin a session mid-stream.\n */\n\nconst HISTORY_CAP = 200;\n\nconst listeners = new Set<AgentActivityListener>();\nconst history: AgentActivityEvent[] = [];\n\n/** Emit an activity event. All current listeners receive it synchronously. */\nexport function emitActivity(event: AgentActivityEvent): void {\n history.push(event);\n if (history.length > HISTORY_CAP) history.splice(0, history.length - HISTORY_CAP);\n for (const l of listeners) l(event);\n}\n\n/**\n * Subscribe to all events (or a filtered subset). Returns an unsubscribe\n * function. Filter checks all provided keys with strict equality; omit a\n * key to ignore it.\n */\nexport function onActivity(listener: AgentActivityListener, filter?: ActivityFilter): () => void {\n const wrapped: AgentActivityListener = filter\n ? (e) => { if (matches(e, filter)) listener(e); }\n : listener;\n listeners.add(wrapped);\n return () => listeners.delete(wrapped);\n}\n\n/** Read the recent history (newest last). Optional filter. */\nexport function readActivityHistory(filter?: ActivityFilter): AgentActivityEvent[] {\n if (!filter) return history.slice();\n return history.filter((e) => matches(e, filter));\n}\n\n/** Wipe history + clear listeners. Test/teardown helper. */\nexport function resetActivityRegistry(): void {\n listeners.clear();\n history.length = 0;\n}\n\nfunction matches(e: AgentActivityEvent, f: ActivityFilter): boolean {\n if (f.agentId !== undefined && e.agentId !== f.agentId) return false;\n if (f.screenId !== undefined && e.target.screenId !== f.screenId) return false;\n if (f.kind !== undefined && e.target.kind !== f.kind) return false;\n return true;\n}\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Loose types — kept here so the bridge builds without a hard dep on\n * @particle-academy/fancy-sheets. They mirror the public surface of\n * `WorkbookData` / `SheetData` / `CellData` from that package.\n */\ntype CellValue = string | number | boolean | null;\ntype CellData = { address: string; value: CellValue; format?: unknown; comment?: unknown; computedValue?: CellValue };\ntype SheetData = {\n id: string;\n name: string;\n cells: Record<string, CellData>;\n columnWidths: Record<number, number>;\n mergedRegions: Array<{ start: string; end: string }>;\n columnFilters: Record<number, string>;\n sortColumn?: number;\n sortDirection?: \"asc\" | \"desc\";\n frozenRows: number;\n frozenCols: number;\n};\ntype WorkbookData = { sheets: SheetData[]; activeSheetId: string };\n\nexport type SheetsBridgeAdapter = {\n /** fancy-screens screen id (optional) so activity events know which screen the sheet lives in. */\n screenId?: string;\n /** Read the current workbook. */\n getWorkbook: () => WorkbookData;\n /** Replace the workbook. Host wires this to its onChange. */\n setWorkbook: (next: WorkbookData) => void;\n /** Optional: programmatically change the active cell. */\n setActiveCell?: (sheetId: string, address: string) => void;\n};\n\nexport type SheetsBridgeOptions = {\n adapter: SheetsBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerSheetsBridge — schema-aware MCP access to a fancy-sheets workbook.\n * Tools are sheet-aware (every mutator takes an explicit `sheet` id, defaulting\n * to the active sheet when omitted) so an agent can author multi-sheet docs.\n */\nexport function registerSheetsBridge(\n host: ToolHost,\n options: SheetsBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n const target = (sheetId: string, address?: string): AgentTarget => ({\n kind: \"sheet\",\n screenId: adapter.screenId,\n elementId: address ? `${sheetId}!${address}` : sheetId,\n label: address ? `${sheetId}!${address}` : sheetId,\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 resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"sheet\",\n screenId: adapter.screenId,\n resolveTarget: ({ args, result }) =>\n resolveTarget?.(args, result) ?? target(getSheetId(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 function activeSheetId(): string {\n return adapter.getWorkbook().activeSheetId;\n }\n function getSheetId(args: JsonObject): string {\n return typeof args.sheet === \"string\" ? args.sheet : activeSheetId();\n }\n function getSheet(workbook: WorkbookData, sheetId: string): SheetData | undefined {\n return workbook.sheets.find((s) => s.id === sheetId);\n }\n\n // ───────────── Read tools ─────────────\n\n reg(\n \"sheet_describe\",\n \"Describe the workbook: every sheet's id, name, dimensions, cell count, active sheet. Call before reading or writing.\",\n {},\n [],\n () => {\n const wb = adapter.getWorkbook();\n const summary = {\n activeSheetId: wb.activeSheetId,\n sheets: wb.sheets.map((s) => ({\n id: s.id,\n name: s.name,\n cellCount: Object.keys(s.cells).length,\n columnCount: Object.keys(s.columnWidths).length,\n frozenRows: s.frozenRows,\n frozenCols: s.frozenCols,\n })),\n };\n const text = `Active: ${summary.activeSheetId}\\n` + summary.sheets\n .map((s) => `${s.id} \"${s.name}\" — ${s.cellCount} cells`)\n .join(\"\\n\");\n return textResult(text, summary);\n },\n false,\n );\n\n reg(\n \"sheet_get_cell\",\n \"Read a single cell's raw + computed value.\",\n {\n sheet: { type: \"string\", description: \"Sheet id (defaults to active).\" },\n address: { type: \"string\", description: \"A1-style address, e.g. \\\"B12\\\".\" },\n },\n [\"address\"],\n (args) => {\n const sheetId = getSheetId(args);\n const address = String(args.address);\n const sheet = getSheet(adapter.getWorkbook(), sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const cell = sheet.cells[address];\n if (!cell) {\n return textResult(`(empty)`, { sheet: sheetId, address, value: null });\n }\n return textResult(`${address} = ${JSON.stringify(cell.computedValue ?? cell.value)}`, { ...cell, sheet: sheetId, address });\n },\n false,\n );\n\n reg(\n \"sheet_get_range\",\n \"Read a rectangular range as a 2D array of values.\",\n {\n sheet: { type: \"string\" },\n start: { type: \"string\", description: \"Top-left A1 address.\" },\n end: { type: \"string\", description: \"Bottom-right A1 address.\" },\n },\n [\"start\", \"end\"],\n (args) => {\n const sheetId = getSheetId(args);\n const sheet = getSheet(adapter.getWorkbook(), sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const grid = readRange(sheet, String(args.start), String(args.end));\n return textResult(JSON.stringify(grid), { sheet: sheetId, start: args.start, end: args.end, values: grid });\n },\n false,\n );\n\n // ───────────── Mutation tools ─────────────\n\n reg(\n \"sheet_set_cell\",\n \"Set a single cell's value. To set a formula, pass a string starting with '='.\",\n {\n sheet: { type: \"string\" },\n address: { type: \"string\" },\n value: { description: \"string | number | boolean | null. Strings starting with '=' are stored as formulas.\" },\n },\n [\"address\", \"value\"],\n (args) => {\n const sheetId = getSheetId(args);\n const address = String(args.address);\n const value = args.value as CellValue;\n const wb = adapter.getWorkbook();\n const sheet = getSheet(wb, sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const next = mergeCells(wb, sheetId, { [address]: cellOf(address, value) });\n adapter.setWorkbook(next);\n return textResult(`${sheetId}!${address} ← ${JSON.stringify(value)}`, { sheet: sheetId, address, value });\n },\n true,\n (args) => target(getSheetId(args), String(args.address ?? \"\")),\n );\n\n reg(\n \"sheet_set_range\",\n \"Set many cells atomically. `cells` is an object map of { \\\"A1\\\": value, \\\"B2\\\": value, ... }.\",\n {\n sheet: { type: \"string\" },\n cells: { type: \"object\" },\n },\n [\"cells\"],\n (args) => {\n const sheetId = getSheetId(args);\n const wb = adapter.getWorkbook();\n const sheet = getSheet(wb, sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const cells = (args.cells && typeof args.cells === \"object\") ? args.cells as Record<string, CellValue> : {};\n const updates: Record<string, CellData> = {};\n for (const [addr, v] of Object.entries(cells)) updates[addr] = cellOf(addr, v);\n const next = mergeCells(wb, sheetId, updates);\n adapter.setWorkbook(next);\n return textResult(`Set ${Object.keys(cells).length} cells in ${sheetId}`, { sheet: sheetId, count: Object.keys(cells).length });\n },\n true,\n );\n\n reg(\n \"sheet_add_sheet\",\n \"Add a new sheet (tab) to the workbook.\",\n { id: { type: \"string\" }, name: { type: \"string\" } },\n [\"id\", \"name\"],\n (args) => {\n const wb = adapter.getWorkbook();\n const id = String(args.id);\n const name = String(args.name);\n if (wb.sheets.find((s) => s.id === id)) return errorResult(`Sheet ${id} already exists`);\n const next: WorkbookData = {\n ...wb,\n sheets: [\n ...wb.sheets,\n {\n id, name, cells: {}, columnWidths: {}, mergedRegions: [],\n columnFilters: {}, frozenRows: 0, frozenCols: 0,\n },\n ],\n };\n adapter.setWorkbook(next);\n return textResult(`Added sheet ${id} (\"${name}\")`, { id, name });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"sheet_set_active\",\n \"Switch to a different sheet tab.\",\n { sheet: { type: \"string\" } },\n [\"sheet\"],\n (args) => {\n const sheetId = String(args.sheet);\n const wb = adapter.getWorkbook();\n if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);\n adapter.setWorkbook({ ...wb, activeSheetId: sheetId });\n return textResult(`Active sheet → ${sheetId}`, { sheet: sheetId });\n },\n true,\n );\n\n reg(\n \"sheet_set_active_cell\",\n \"Move the active cell selection (host implements DOM focus + scroll).\",\n { sheet: { type: \"string\" }, address: { type: \"string\" } },\n [\"address\"],\n (args) => {\n if (!adapter.setActiveCell) return errorResult(\"Host did not provide setActiveCell.\");\n const sheetId = getSheetId(args);\n adapter.setActiveCell(sheetId, String(args.address));\n return textResult(`Active cell → ${sheetId}!${args.address}`, { sheet: sheetId, address: args.address });\n },\n true,\n (args) => target(getSheetId(args), String(args.address ?? \"\")),\n );\n\n return {\n id: \"sheets\",\n title: \"Sheets\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n\n// ───────────── helpers ─────────────\n\nfunction cellOf(address: string, value: CellValue): CellData {\n return { address, value };\n}\n\nfunction mergeCells(wb: WorkbookData, sheetId: string, updates: Record<string, CellData>): WorkbookData {\n return {\n ...wb,\n sheets: wb.sheets.map((s) =>\n s.id !== sheetId ? s : { ...s, cells: { ...s.cells, ...updates } },\n ),\n };\n}\n\n/** Parse \"B12\" → { col: 1, row: 11 }. Letters are 1-based, rows 1-based. */\nfunction parseAddress(addr: string): { col: number; row: number } {\n const m = /^([A-Za-z]+)(\\d+)$/.exec(addr.trim());\n if (!m) throw new Error(`Bad address: ${addr}`);\n const letters = m[1].toUpperCase();\n let col = 0;\n for (let i = 0; i < letters.length; i++) {\n col = col * 26 + (letters.charCodeAt(i) - 64);\n }\n return { col: col - 1, row: parseInt(m[2], 10) - 1 };\n}\n\nfunction colToLetter(col: number): string {\n let s = \"\";\n let n = col + 1;\n while (n > 0) {\n const r = (n - 1) % 26;\n s = String.fromCharCode(65 + r) + s;\n n = Math.floor((n - 1) / 26);\n }\n return s;\n}\n\nfunction readRange(sheet: SheetData, startAddr: string, endAddr: string): CellValue[][] {\n const start = parseAddress(startAddr);\n const end = parseAddress(endAddr);\n const r0 = Math.min(start.row, end.row);\n const r1 = Math.max(start.row, end.row);\n const c0 = Math.min(start.col, end.col);\n const c1 = Math.max(start.col, end.col);\n const grid: CellValue[][] = [];\n for (let r = r0; r <= r1; r++) {\n const row: CellValue[] = [];\n for (let c = c0; c <= c1; c++) {\n const addr = `${colToLetter(c)}${r + 1}`;\n const cell = sheet.cells[addr];\n row.push(cell?.computedValue ?? cell?.value ?? null);\n }\n grid.push(row);\n }\n return grid;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { registerSheetsBridge } from './chunk-IANI25IT.js';
2
+ import './chunk-52S7XYZK.js';
3
+ import './chunk-JU2N4KK6.js';
4
+ import './chunk-4KAIV6OD.js';
5
+ //# sourceMappingURL=bridges-sheets.js.map
6
+ //# sourceMappingURL=bridges-sheets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"bridges-sheets.js"}
@@ -10,6 +10,156 @@ function textResult(text, structured) {
10
10
  function errorResult(text) {
11
11
  return { content: [{ type: "text", text }], isError: true };
12
12
  }
13
+ var listeners = /* @__PURE__ */ new Set();
14
+ function emitActivity(event) {
15
+ for (const l of listeners) l(event);
16
+ }
17
+
18
+ // src/presence/wrap-tool-with-activity.ts
19
+ function wrapToolWithActivity(handler, options) {
20
+ return async (args) => {
21
+ const result = await handler(args);
22
+ if (result.isError) return result;
23
+ let target;
24
+ if (options.resolveTarget) {
25
+ target = options.resolveTarget({ toolName: options.toolName, args, result });
26
+ } else {
27
+ target = { kind: options.kind, screenId: options.screenId };
28
+ }
29
+ if (!target) return result;
30
+ emitActivity({
31
+ agentId: options.agent.id,
32
+ agentName: options.agent.name,
33
+ agentColor: options.agent.color,
34
+ target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },
35
+ action: options.toolName,
36
+ timestamp: Date.now(),
37
+ meta: extractMeta(result),
38
+ ttlMs: options.ttlMs
39
+ });
40
+ return result;
41
+ };
42
+ }
43
+ function extractMeta(result) {
44
+ const sc = result.structuredContent;
45
+ if (sc && typeof sc === "object" && !Array.isArray(sc)) {
46
+ return sc;
47
+ }
48
+ return void 0;
49
+ }
50
+
51
+ // src/undo/undo-stack.ts
52
+ var stacks = /* @__PURE__ */ new Map();
53
+ var CAP = 200;
54
+ function getStack(agentId) {
55
+ let s = stacks.get(agentId);
56
+ if (!s) {
57
+ s = { past: [], future: [] };
58
+ stacks.set(agentId, s);
59
+ }
60
+ return s;
61
+ }
62
+ function pushUndoEntry(agentId, entry) {
63
+ const s = getStack(agentId);
64
+ s.past.push(entry);
65
+ if (s.past.length > CAP) s.past.splice(0, s.past.length - CAP);
66
+ s.future.length = 0;
67
+ }
68
+ async function undoOne(agentId) {
69
+ const s = getStack(agentId);
70
+ const entry = s.past.pop();
71
+ if (!entry) return null;
72
+ await entry.undo();
73
+ s.future.push(entry);
74
+ return entry;
75
+ }
76
+ async function redoOne(agentId) {
77
+ const s = getStack(agentId);
78
+ const entry = s.future.pop();
79
+ if (!entry) return null;
80
+ await entry.redo();
81
+ s.past.push(entry);
82
+ return entry;
83
+ }
84
+ function readHistory(agentId) {
85
+ return getStack(agentId).past.slice();
86
+ }
87
+
88
+ // src/undo/undo-tools.ts
89
+ var installedHosts = /* @__PURE__ */ new WeakSet();
90
+ function ensureUndoToolsRegistered(host, options = {}) {
91
+ if (installedHosts.has(host)) return;
92
+ installedHosts.add(host);
93
+ registerUndoTools(host, options);
94
+ }
95
+ function registerUndoTools(host, options = {}) {
96
+ const defaultAgent = options.defaultAgentId ?? "agent";
97
+ const disposers = [];
98
+ const agentOf = (args) => typeof args?.agentId === "string" ? args.agentId : defaultAgent;
99
+ disposers.push(
100
+ host.registerTool(
101
+ {
102
+ name: "agent_undo",
103
+ description: "Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.",
104
+ inputSchema: {
105
+ type: "object",
106
+ properties: { agentId: { type: "string" } },
107
+ additionalProperties: false
108
+ }
109
+ },
110
+ async (args) => {
111
+ const entry = await undoOne(agentOf(args));
112
+ if (!entry) return errorResult("Nothing to undo.");
113
+ return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });
114
+ }
115
+ )
116
+ );
117
+ disposers.push(
118
+ host.registerTool(
119
+ {
120
+ name: "agent_redo",
121
+ description: "Redo the most recently undone action.",
122
+ inputSchema: {
123
+ type: "object",
124
+ properties: { agentId: { type: "string" } },
125
+ additionalProperties: false
126
+ }
127
+ },
128
+ async (args) => {
129
+ const entry = await redoOne(agentOf(args));
130
+ if (!entry) return errorResult("Nothing to redo.");
131
+ return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });
132
+ }
133
+ )
134
+ );
135
+ disposers.push(
136
+ host.registerTool(
137
+ {
138
+ name: "agent_history",
139
+ description: "List the agent's undo stack (oldest first). Useful for understanding what's reversible.",
140
+ inputSchema: {
141
+ type: "object",
142
+ properties: { agentId: { type: "string" } },
143
+ additionalProperties: false
144
+ }
145
+ },
146
+ async (args) => {
147
+ const history2 = readHistory(agentOf(args)).map(serialize);
148
+ const text = history2.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join("\n");
149
+ return textResult(text || "(empty)", history2);
150
+ }
151
+ )
152
+ );
153
+ return () => disposers.forEach((d) => d());
154
+ }
155
+ function serialize(entry) {
156
+ return {
157
+ timestamp: entry.timestamp,
158
+ bridgeId: entry.bridgeId,
159
+ action: entry.action,
160
+ label: entry.label
161
+ };
162
+ }
13
163
 
14
164
  // src/bridges/whiteboard.ts
15
165
  var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
@@ -18,13 +168,31 @@ var num = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : fal
18
168
  var str = (v, fallback = "") => typeof v === "string" ? v : fallback;
19
169
  var bool = (v, fallback = false) => typeof v === "boolean" ? v : fallback;
20
170
  var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
21
- function registerWhiteboardBridge(server, options) {
171
+ function registerWhiteboardBridge(host, options) {
22
172
  const { adapter } = options;
23
173
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
24
174
  const disposers = [];
25
- const reg = (name, description, inputProperties, required, handler) => {
175
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
176
+ const wbTarget = (args, result) => ({
177
+ kind: "whiteboard",
178
+ elementId: result?.structuredContent?.id ?? args?.id
179
+ });
180
+ const reg = (name, description, inputProperties, required, handler, resolveTarget) => {
181
+ const wrapped = async (args) => {
182
+ try {
183
+ return await handler(args);
184
+ } catch (e) {
185
+ return errorResult(e instanceof Error ? e.message : String(e));
186
+ }
187
+ };
188
+ const final = resolveTarget ? wrapToolWithActivity(wrapped, {
189
+ toolName: name,
190
+ agent: { id: agent.id, name: agent.name, color: agent.color },
191
+ kind: "whiteboard",
192
+ resolveTarget: ({ args, result }) => resolveTarget(args, result)
193
+ }) : wrapped;
26
194
  disposers.push(
27
- server.registerTool(
195
+ host.registerTool(
28
196
  {
29
197
  name,
30
198
  description,
@@ -35,13 +203,7 @@ function registerWhiteboardBridge(server, options) {
35
203
  additionalProperties: false
36
204
  }
37
205
  },
38
- async (args) => {
39
- try {
40
- return await handler(args);
41
- } catch (e) {
42
- return errorResult(e instanceof Error ? e.message : String(e));
43
- }
44
- }
206
+ final
45
207
  )
46
208
  );
47
209
  };
@@ -118,8 +280,17 @@ function registerWhiteboardBridge(server, options) {
118
280
  authorId: agent.id
119
281
  };
120
282
  adapter.setNotes((all) => [...all, note]);
283
+ pushUndoEntry(agent.id, {
284
+ timestamp: Date.now(),
285
+ bridgeId: "whiteboard",
286
+ action: "whiteboard_add_sticky",
287
+ label: `Added sticky ${note.id}`,
288
+ undo: () => adapter.setNotes((all) => all.filter((n) => n.id !== note.id)),
289
+ redo: () => adapter.setNotes((all) => [...all, note])
290
+ });
121
291
  return textResult(`Added sticky ${note.id}`, note);
122
- }
292
+ },
293
+ wbTarget
123
294
  );
124
295
  reg(
125
296
  "whiteboard_stream_text",
@@ -186,7 +357,8 @@ function registerWhiteboardBridge(server, options) {
186
357
  })
187
358
  );
188
359
  return textResult(`Updated sticky ${id}`, updated);
189
- }
360
+ },
361
+ wbTarget
190
362
  );
191
363
  reg(
192
364
  "whiteboard_add_shape",
@@ -227,7 +399,8 @@ function registerWhiteboardBridge(server, options) {
227
399
  };
228
400
  adapter.setShapes((all) => [...all, shape]);
229
401
  return textResult(`Added ${kind} ${shape.id}`, shape);
230
- }
402
+ },
403
+ wbTarget
231
404
  );
232
405
  reg(
233
406
  "whiteboard_update_shape",
@@ -269,7 +442,8 @@ function registerWhiteboardBridge(server, options) {
269
442
  })
270
443
  );
271
444
  return textResult(`Updated shape ${id}`, updated);
272
- }
445
+ },
446
+ wbTarget
273
447
  );
274
448
  reg(
275
449
  "whiteboard_add_connector",
@@ -290,7 +464,8 @@ function registerWhiteboardBridge(server, options) {
290
464
  };
291
465
  adapter.setConnectors((all) => [...all, c]);
292
466
  return textResult(`Added connector ${c.id}`, c);
293
- }
467
+ },
468
+ wbTarget
294
469
  );
295
470
  reg(
296
471
  "whiteboard_add_stroke",
@@ -319,7 +494,8 @@ function registerWhiteboardBridge(server, options) {
319
494
  };
320
495
  adapter.setStrokes((all) => [...all, stroke]);
321
496
  return textResult(`Added stroke ${stroke.id} (${points.length} points)`, stroke);
322
- }
497
+ },
498
+ wbTarget
323
499
  );
324
500
  reg(
325
501
  "whiteboard_delete_item",
@@ -328,29 +504,37 @@ function registerWhiteboardBridge(server, options) {
328
504
  ["id"],
329
505
  (args) => {
330
506
  const id = str(args.id);
331
- let removed = false;
332
- adapter.setNotes((all) => {
333
- const next = all.filter((x) => x.id !== id);
334
- if (next.length !== all.length) removed = true;
335
- return next;
336
- });
337
- adapter.setShapes((all) => {
338
- const next = all.filter((x) => x.id !== id);
339
- if (next.length !== all.length) removed = true;
340
- return next;
341
- });
342
- adapter.setConnectors((all) => {
343
- const next = all.filter((x) => x.id !== id);
344
- if (next.length !== all.length) removed = true;
345
- return next;
346
- });
347
- adapter.setStrokes((all) => {
348
- const next = all.filter((x) => x.id !== id);
349
- if (next.length !== all.length) removed = true;
350
- return next;
507
+ const removedNotes = adapter.getNotes().filter((x) => x.id === id);
508
+ const removedShapes = adapter.getShapes().filter((x) => x.id === id);
509
+ const removedConnectors = adapter.getConnectors().filter((x) => x.id === id);
510
+ const removedStrokes = adapter.getStrokes().filter((x) => x.id === id);
511
+ const removed = removedNotes.length + removedShapes.length + removedConnectors.length + removedStrokes.length > 0;
512
+ if (!removed) return errorResult(`No item with id ${id}`);
513
+ adapter.setNotes((all) => all.filter((x) => x.id !== id));
514
+ adapter.setShapes((all) => all.filter((x) => x.id !== id));
515
+ adapter.setConnectors((all) => all.filter((x) => x.id !== id));
516
+ adapter.setStrokes((all) => all.filter((x) => x.id !== id));
517
+ pushUndoEntry(agent.id, {
518
+ timestamp: Date.now(),
519
+ bridgeId: "whiteboard",
520
+ action: "whiteboard_delete_item",
521
+ label: `Deleted ${id}`,
522
+ undo: () => {
523
+ if (removedNotes.length) adapter.setNotes((all) => [...all, ...removedNotes]);
524
+ if (removedShapes.length) adapter.setShapes((all) => [...all, ...removedShapes]);
525
+ if (removedConnectors.length) adapter.setConnectors((all) => [...all, ...removedConnectors]);
526
+ if (removedStrokes.length) adapter.setStrokes((all) => [...all, ...removedStrokes]);
527
+ },
528
+ redo: () => {
529
+ adapter.setNotes((all) => all.filter((x) => x.id !== id));
530
+ adapter.setShapes((all) => all.filter((x) => x.id !== id));
531
+ adapter.setConnectors((all) => all.filter((x) => x.id !== id));
532
+ adapter.setStrokes((all) => all.filter((x) => x.id !== id));
533
+ }
351
534
  });
352
- return removed ? textResult(`Deleted ${id}`) : errorResult(`No item with id ${id}`);
353
- }
535
+ return textResult(`Deleted ${id}`);
536
+ },
537
+ wbTarget
354
538
  );
355
539
  reg(
356
540
  "whiteboard_set_viewport",
@@ -366,7 +550,8 @@ function registerWhiteboardBridge(server, options) {
366
550
  };
367
551
  adapter.setViewport(next);
368
552
  return textResult(`Viewport \u2192 ${JSON.stringify(next)}`, next);
369
- }
553
+ },
554
+ wbTarget
370
555
  );
371
556
  reg(
372
557
  "whiteboard_set_agent_cursor",
@@ -392,7 +577,8 @@ function registerWhiteboardBridge(server, options) {
392
577
  };
393
578
  adapter.setAgentCursor(cursor);
394
579
  return textResult(`Cursor \u2192 (${cursor.x}, ${cursor.y})`, cursor);
395
- }
580
+ },
581
+ wbTarget
396
582
  );
397
583
  return {
398
584
  id: "whiteboard",