@particle-academy/agent-integrations 0.40.0 → 0.42.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 (160) hide show
  1. package/dist/bridges/artboard.d.cts +2 -2
  2. package/dist/bridges/artboard.d.ts +2 -2
  3. package/dist/bridges/catalog.d.cts +2 -2
  4. package/dist/bridges/catalog.d.ts +2 -2
  5. package/dist/bridges/charts.d.cts +2 -2
  6. package/dist/bridges/charts.d.ts +2 -2
  7. package/dist/bridges/cms.d.cts +2 -2
  8. package/dist/bridges/cms.d.ts +2 -2
  9. package/dist/bridges/code.d.cts +2 -2
  10. package/dist/bridges/code.d.ts +2 -2
  11. package/dist/bridges/doc.d.cts +2 -2
  12. package/dist/bridges/doc.d.ts +2 -2
  13. package/dist/bridges/features.d.cts +2 -2
  14. package/dist/bridges/features.d.ts +2 -2
  15. package/dist/bridges/files.d.cts +38 -3
  16. package/dist/bridges/files.d.ts +38 -3
  17. package/dist/bridges/flow.d.cts +2 -2
  18. package/dist/bridges/flow.d.ts +2 -2
  19. package/dist/bridges/forms.d.cts +2 -2
  20. package/dist/bridges/forms.d.ts +2 -2
  21. package/dist/bridges/git.d.cts +2 -2
  22. package/dist/bridges/git.d.ts +2 -2
  23. package/dist/bridges/grid.d.cts +2 -2
  24. package/dist/bridges/grid.d.ts +2 -2
  25. package/dist/bridges/map.d.cts +2 -2
  26. package/dist/bridges/map.d.ts +2 -2
  27. package/dist/bridges/passkeys.d.cts +2 -2
  28. package/dist/bridges/passkeys.d.ts +2 -2
  29. package/dist/bridges/scene.d.cts +2 -2
  30. package/dist/bridges/scene.d.ts +2 -2
  31. package/dist/bridges/screens.d.cts +2 -2
  32. package/dist/bridges/screens.d.ts +2 -2
  33. package/dist/bridges/sheets.d.cts +2 -2
  34. package/dist/bridges/sheets.d.ts +2 -2
  35. package/dist/bridges/slides.d.cts +2 -2
  36. package/dist/bridges/slides.d.ts +2 -2
  37. package/dist/bridges/terminal.d.cts +2 -2
  38. package/dist/bridges/terminal.d.ts +2 -2
  39. package/dist/bridges/tui.d.cts +1 -1
  40. package/dist/bridges/tui.d.ts +1 -1
  41. package/dist/bridges/whiteboard.d.cts +2 -2
  42. package/dist/bridges/whiteboard.d.ts +2 -2
  43. package/dist/bridges-artboard.cjs.map +1 -1
  44. package/dist/bridges-artboard.js +2 -2
  45. package/dist/bridges-catalog.cjs.map +1 -1
  46. package/dist/bridges-catalog.js +3 -3
  47. package/dist/bridges-charts.cjs.map +1 -1
  48. package/dist/bridges-charts.js +3 -3
  49. package/dist/bridges-cms.cjs.map +1 -1
  50. package/dist/bridges-cms.js +4 -4
  51. package/dist/bridges-code.cjs.map +1 -1
  52. package/dist/bridges-code.js +3 -3
  53. package/dist/bridges-doc.cjs.map +1 -1
  54. package/dist/bridges-doc.js +3 -3
  55. package/dist/bridges-features.cjs.map +1 -1
  56. package/dist/bridges-features.js +3 -3
  57. package/dist/bridges-files.cjs +45 -0
  58. package/dist/bridges-files.cjs.map +1 -1
  59. package/dist/bridges-files.js +3 -3
  60. package/dist/bridges-flow.cjs.map +1 -1
  61. package/dist/bridges-flow.js +2 -2
  62. package/dist/bridges-forms.cjs.map +1 -1
  63. package/dist/bridges-forms.js +3 -3
  64. package/dist/bridges-git.cjs.map +1 -1
  65. package/dist/bridges-git.js +3 -3
  66. package/dist/bridges-grid.cjs.map +1 -1
  67. package/dist/bridges-grid.js +3 -3
  68. package/dist/bridges-map.cjs.map +1 -1
  69. package/dist/bridges-map.js +3 -3
  70. package/dist/bridges-passkeys.cjs.map +1 -1
  71. package/dist/bridges-passkeys.js +3 -3
  72. package/dist/bridges-scene.cjs.map +1 -1
  73. package/dist/bridges-scene.js +3 -3
  74. package/dist/bridges-screens.cjs.map +1 -1
  75. package/dist/bridges-screens.js +3 -3
  76. package/dist/bridges-sheets.cjs.map +1 -1
  77. package/dist/bridges-sheets.js +3 -3
  78. package/dist/bridges-slides.cjs.map +1 -1
  79. package/dist/bridges-slides.js +3 -3
  80. package/dist/bridges-terminal.cjs.map +1 -1
  81. package/dist/bridges-terminal.js +3 -3
  82. package/dist/bridges-tui.cjs.map +1 -1
  83. package/dist/bridges-tui.js +2 -2
  84. package/dist/bridges-whiteboard.cjs.map +1 -1
  85. package/dist/bridges-whiteboard.js +3 -3
  86. package/dist/{chunk-2U5JB6ZA.js → chunk-2LSU3NFO.js} +4 -4
  87. package/dist/{chunk-2U5JB6ZA.js.map → chunk-2LSU3NFO.js.map} +1 -1
  88. package/dist/{chunk-PR4SXFZH.js → chunk-2Q4EGZHJ.js} +4 -4
  89. package/dist/{chunk-PR4SXFZH.js.map → chunk-2Q4EGZHJ.js.map} +1 -1
  90. package/dist/{chunk-G5EZNWXJ.js → chunk-5W6YOXLT.js} +4 -4
  91. package/dist/{chunk-G5EZNWXJ.js.map → chunk-5W6YOXLT.js.map} +1 -1
  92. package/dist/{chunk-CA7GIJJC.js → chunk-7LLMILTM.js} +4 -4
  93. package/dist/{chunk-CA7GIJJC.js.map → chunk-7LLMILTM.js.map} +1 -1
  94. package/dist/{chunk-MFMBR6LN.js → chunk-E2I3YVKC.js} +3 -3
  95. package/dist/{chunk-MFMBR6LN.js.map → chunk-E2I3YVKC.js.map} +1 -1
  96. package/dist/{chunk-USQGA672.js → chunk-EIBV76IB.js} +4 -4
  97. package/dist/{chunk-USQGA672.js.map → chunk-EIBV76IB.js.map} +1 -1
  98. package/dist/{chunk-WCKSDFTM.js → chunk-GT63LSPJ.js} +4 -4
  99. package/dist/{chunk-WCKSDFTM.js.map → chunk-GT63LSPJ.js.map} +1 -1
  100. package/dist/{chunk-CT3LRNH7.js → chunk-HVDHT7DM.js} +3 -3
  101. package/dist/{chunk-CT3LRNH7.js.map → chunk-HVDHT7DM.js.map} +1 -1
  102. package/dist/{chunk-7THGQUX3.js → chunk-LOD77NCD.js} +4 -4
  103. package/dist/{chunk-7THGQUX3.js.map → chunk-LOD77NCD.js.map} +1 -1
  104. package/dist/{chunk-BHQJJ2YG.js → chunk-MZ74LLDS.js} +4 -4
  105. package/dist/{chunk-BHQJJ2YG.js.map → chunk-MZ74LLDS.js.map} +1 -1
  106. package/dist/{chunk-A25E22WW.js → chunk-N5VOPV64.js} +49 -5
  107. package/dist/chunk-N5VOPV64.js.map +1 -0
  108. package/dist/{chunk-ZNGTC4CO.js → chunk-NIFPRC7P.js} +4 -4
  109. package/dist/{chunk-ZNGTC4CO.js.map → chunk-NIFPRC7P.js.map} +1 -1
  110. package/dist/{chunk-JJUABMAP.js → chunk-NIXOY473.js} +3 -3
  111. package/dist/{chunk-JJUABMAP.js.map → chunk-NIXOY473.js.map} +1 -1
  112. package/dist/{chunk-OAFJ53X3.js → chunk-NKAH67JK.js} +4 -4
  113. package/dist/{chunk-OAFJ53X3.js.map → chunk-NKAH67JK.js.map} +1 -1
  114. package/dist/{chunk-RIXYCFDO.js → chunk-PCFRBVKS.js} +4 -4
  115. package/dist/{chunk-RIXYCFDO.js.map → chunk-PCFRBVKS.js.map} +1 -1
  116. package/dist/{chunk-4D3II37O.js → chunk-PUMQDV67.js} +4 -4
  117. package/dist/{chunk-4D3II37O.js.map → chunk-PUMQDV67.js.map} +1 -1
  118. package/dist/{chunk-DF3PLL2E.js → chunk-QJYRWEXD.js} +28 -5
  119. package/dist/chunk-QJYRWEXD.js.map +1 -0
  120. package/dist/{chunk-XY2TDE6E.js → chunk-SXVRIIXW.js} +4 -4
  121. package/dist/{chunk-XY2TDE6E.js.map → chunk-SXVRIIXW.js.map} +1 -1
  122. package/dist/{chunk-6YUBWQTS.js → chunk-TEB5U6Y5.js} +4 -4
  123. package/dist/{chunk-6YUBWQTS.js.map → chunk-TEB5U6Y5.js.map} +1 -1
  124. package/dist/{chunk-MJ2S25ON.js → chunk-VJD3Y7E5.js} +4 -4
  125. package/dist/{chunk-MJ2S25ON.js.map → chunk-VJD3Y7E5.js.map} +1 -1
  126. package/dist/{chunk-BT7HM5I6.js → chunk-WEXMZMJH.js} +3 -3
  127. package/dist/{chunk-BT7HM5I6.js.map → chunk-WEXMZMJH.js.map} +1 -1
  128. package/dist/{chunk-UZHNKUER.js → chunk-Z4L2GOAK.js} +4 -4
  129. package/dist/{chunk-UZHNKUER.js.map → chunk-Z4L2GOAK.js.map} +1 -1
  130. package/dist/components-shared-whiteboard.cjs +26 -3
  131. package/dist/components-shared-whiteboard.cjs.map +1 -1
  132. package/dist/components-shared-whiteboard.js +3 -3
  133. package/dist/index.cjs +132 -3
  134. package/dist/index.cjs.map +1 -1
  135. package/dist/index.d.cts +88 -8
  136. package/dist/index.d.ts +88 -8
  137. package/dist/index.js +87 -26
  138. package/dist/index.js.map +1 -1
  139. package/dist/mcp/index.d.cts +3 -3
  140. package/dist/mcp/index.d.ts +3 -3
  141. package/dist/mcp.cjs +26 -3
  142. package/dist/mcp.cjs.map +1 -1
  143. package/dist/mcp.js +1 -1
  144. package/dist/{server-DDD3IZ56.d.cts → server-BJNF7pQe.d.cts} +1 -1
  145. package/dist/{server-CDX643Kz.d.ts → server-Dt97UxuD.d.ts} +1 -1
  146. package/dist/sharing/index.d.cts +2 -2
  147. package/dist/sharing/index.d.ts +2 -2
  148. package/dist/sheets-adapter.d.cts +2 -2
  149. package/dist/sheets-adapter.d.ts +2 -2
  150. package/dist/{tool-host-EuYHYSSH.d.cts → tool-host-BpEBqf5u.d.cts} +17 -0
  151. package/dist/{tool-host-CWTOJEm2.d.ts → tool-host-xY5F-eqG.d.ts} +17 -0
  152. package/dist/{types-NFGP769G.d.cts → types-C4NaIW6B.d.cts} +1 -1
  153. package/dist/{types-BKD6uf86.d.ts → types-DSwsNTBG.d.ts} +1 -1
  154. package/dist/undo/index.d.cts +1 -1
  155. package/dist/undo/index.d.ts +1 -1
  156. package/dist/undo.cjs.map +1 -1
  157. package/dist/undo.js +3 -3
  158. package/package.json +1 -1
  159. package/dist/chunk-A25E22WW.js.map +0 -1
  160. package/dist/chunk-DF3PLL2E.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-tools.ts","../src/bridges/features.ts"],"names":["emitActivity","undoOne","redoOne","readHistory","pushUndoEntry"],"mappings":"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","file":"bridges-features.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, transport);\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, transport: Transport): 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, { transport });\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 /** Send an application notification to every client, or one attached transport. */\n notify(message: JsonRpcMessage, transport?: Transport): void {\n if (transport) transport.send(message);\n else this.broadcast(message);\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 * Build the `meta` broadcast to all relay peers. Defaults to the tool's full\n * `structuredContent`. Override to REDACT sensitive fields before fan-out —\n * e.g. the terminal bridge strips raw command/keystroke bytes so a command\n * line (or its secrets) is never broadcast verbatim to every peer.\n */\n buildMeta?: (result: CallToolResult) => Record<string, unknown> | undefined;\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: options.buildMeta ? options.buildMeta(result) : extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Headless bridge for `@particle-academy/fancy-features` — feature management\n * with NO UI surface. The adapter is the `FeatureManager` (a `FeatureSource`\n * consumer): define features in the registry, check access for a subject,\n * grant/revoke via group assignment, and meter resource usage. Mutations\n * funnel through `wrapToolWithActivity` so presence + undo compose; `grant` /\n * `revoke` are `pendingMode`-gated (they change what a real user can do).\n *\n * The adapter shapes mirror fancy-features' public `FeatureManager` +\n * `FeatureRegistry` + `GroupStore`, defined LOCALLY so the bridge builds with\n * the sibling absent (optional peer). A live `FeatureManager` (plus its\n * `.registry` / `.groupStore`) satisfies this structurally with no import.\n *\n * SUBJECTS over the wire: `Subject` is opaque (`unknown`) in fancy-features.\n * Agents pass a JSON-serializable subject (string id or `{ id, … }` object);\n * the host's stores key on it via their `defaultSubjectKey`.\n */\n\nexport type FeatureGrant = {\n key: string;\n type: \"boolean\" | \"resource\";\n enabled: boolean;\n includedQuantity?: number | null;\n overageLimit?: number | null;\n source?: string;\n config?: Record<string, unknown>;\n};\n\n/** Normalized feature definition (mirror of fancy-features `FeatureDefinition`). */\nexport type FeatureDefinition = {\n key?: string;\n name?: string;\n description?: string;\n type?: \"boolean\" | \"resource\";\n enabled?: boolean;\n limit?: number;\n [k: string]: unknown;\n};\n\n/**\n * Adapter = the `FeatureManager` + its registry + group store. The bridge only\n * needs these members; a real manager exposes them directly.\n */\nexport type FeaturesBridgeAdapter = {\n /** Stable id for this feature manager instance. */\n id?: string;\n title?: string;\n screenId?: string;\n\n // ── Access checks (FeatureManager) ──\n /** Can the subject access the feature now? `manager.canAccess`. */\n canAccess(feature: string, subject?: unknown, context?: unknown): boolean | Promise<boolean>;\n /** Remaining quota for a resource feature (null = unlimited / n-a). `manager.remaining`. */\n remaining(feature: string, subject?: unknown, context?: unknown): number | null | Promise<number | null>;\n /** All enabled feature keys for the subject. `manager.enabled`. */\n enabled(subject?: unknown, context?: unknown): string[] | Promise<string[]>;\n /** Trace a feature's resolution to an AccessResult. `manager.explain`. */\n explain?(feature: string, subject?: unknown, context?: unknown): Promise<unknown> | unknown;\n\n // ── Registry (define) ──\n /** Register a programmatic feature. `manager.registerFeature` / `manager.registry.register`. */\n registerFeature(key: string, definition: FeatureDefinition): void;\n /** Registered feature keys. `manager.registry.keys`. */\n registryKeys(): string[];\n /** Resolve a registered definition (or null). `manager.registry.definition`. */\n definition?(key: string): FeatureDefinition | null | Promise<FeatureDefinition | null>;\n\n // ── Group store (grant / revoke) ──\n /** Assign a subject to a feature group (the grant primitive). `manager.groupStore.assign`. */\n assignGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Detach a subject from a group (the revoke primitive). `manager.groupStore.detach`. */\n detachGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Group keys assigned to a subject. `manager.groupStore.list`. */\n listGroups(subject: unknown): string[] | Promise<string[]>;\n\n // ── Usage / metering (resource features) ──\n /** Current usage for a resource feature. `manager.usageFor`. Optional. */\n usageFor?(feature: string, subject: unknown): number | Promise<number>;\n /** Atomic check-and-increment quota. `manager.tryConsume`. Optional. */\n tryConsume?(feature: string, subject: unknown, amount?: number, context?: unknown): boolean | Promise<boolean>;\n};\n\nexport type FeaturesBridgeOptions = {\n adapter: FeaturesBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n /**\n * Trust-but-verify. When on (default), `features_grant` / `features_revoke`\n * (they change a real subject's entitlements) require `confirm:true` OR a\n * host `confirm` hook. Checks + define + usage are unaffected.\n */\n pendingMode?: boolean;\n confirm?: (req: { action: string; subject: unknown; groupKey: string }) => Promise<boolean> | boolean;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback = 0): number => (typeof v === \"number\" && Number.isFinite(v) ? v : fallback);\n\n/**\n * registerFeaturesBridge — full MCP tool set over a headless feature manager.\n *\n * features_list enabled feature keys for a subject\n * features_check can a subject access a feature? (+ remaining for resources)\n * features_explain trace why a feature is on/off for a subject\n * features_define register a feature definition (boolean / resource)\n * features_grant assign a subject to a group (pendingMode-gated, undoable)\n * features_revoke detach a subject from a group (pendingMode-gated, undoable)\n * features_groups list a subject's assigned groups\n * features_consume meter a resource feature (atomic check-and-increment)\n */\nexport function registerFeaturesBridge(host: ToolHost, options: FeaturesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const featuresId = adapter.id ?? \"features\";\n const disposers: Array<() => void> = [];\n\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target = (elementId?: string, label?: string): AgentTarget => ({\n kind: \"custom\",\n screenId: adapter.screenId,\n elementId,\n label: label ?? featuresId,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<unknown> | unknown,\n resolveTarget: false | ((args: JsonObject) => AgentTarget),\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 as never, {\n toolName: name,\n agent,\n kind: \"custom\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => resolveTarget(args as JsonObject),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as Record<string, never>, required, additionalProperties: false } },\n final as never,\n ),\n );\n };\n\n const guardGrant = async (action: string, subject: unknown, groupKey: string, hasConfirmArg: boolean) => {\n if (!pendingMode) return null;\n if (options.confirm) {\n const ok = await options.confirm({ action, subject, groupKey });\n return ok ? null : errorResult(`Declined: ${action} ${groupKey} (human did not confirm).`);\n }\n if (!hasConfirmArg) {\n return errorResult(`${action} is staged (pendingMode). Re-call with confirm:true to apply, or wire a host confirm hook.`);\n }\n return null;\n };\n\n // ─── Read / check tools ──────────────────────────────────────────────────\n\n reg(\n \"features_list\",\n \"List the feature keys enabled for a subject. Pass `subject` (a string id or object).\",\n { subject: { description: \"Opaque subject — string id or { id, … } object.\" }, context: { description: \"Optional resolution context.\" } },\n [],\n async (args) => {\n const keys = await adapter.enabled(args.subject, args.context);\n return textResult(JSON.stringify(keys, null, 2), { subject: args.subject, enabled: keys });\n },\n false,\n );\n\n reg(\n \"features_check\",\n \"Check whether a subject can access a feature. For resource features also returns the remaining quota.\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n const feature = str(args.feature);\n const allowed = await adapter.canAccess(feature, args.subject, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, allowed, remaining };\n return textResult(JSON.stringify(out), out);\n },\n false,\n );\n\n reg(\n \"features_explain\",\n \"Trace why a feature is on/off for a subject — returns the AccessResult (source, remaining, limit, used).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n if (!adapter.explain) return errorResult(\"Host did not wire explain().\");\n const result = await adapter.explain(str(args.feature), args.subject, args.context);\n return textResult(JSON.stringify(result, null, 2), result as Record<string, unknown>);\n },\n false,\n );\n\n reg(\n \"features_groups\",\n \"List the feature groups a subject is assigned to.\",\n { subject: { description: \"Opaque subject.\" } },\n [\"subject\"],\n async (args) => {\n const groups = await adapter.listGroups(args.subject);\n return textResult(JSON.stringify(groups, null, 2), { subject: args.subject, groups });\n },\n false,\n );\n\n // ─── Define ──────────────────────────────────────────────────────────────\n\n reg(\n \"features_define\",\n \"Register a feature definition. type 'boolean' (on/off) or 'resource' (metered with a `limit`). `enabled` sets the default gate.\",\n {\n key: { type: \"string\" },\n name: { type: \"string\" },\n description: { type: \"string\" },\n type: { type: \"string\", enum: [\"boolean\", \"resource\"] },\n enabled: { type: \"boolean\" },\n limit: { type: \"number\", description: \"Resource quota per period (resource type).\" },\n },\n [\"key\"],\n (args) => {\n const key = str(args.key);\n if (!key) return errorResult(\"key is required.\");\n const existed = adapter.registryKeys().includes(key);\n const definition: FeatureDefinition = {\n ...(args.name !== undefined ? { name: str(args.name) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.type !== undefined ? { type: str(args.type) as \"boolean\" | \"resource\" } : {}),\n ...(args.enabled !== undefined ? { enabled: args.enabled === true } : {}),\n ...(args.limit !== undefined ? { limit: num(args.limit) } : {}),\n };\n adapter.registerFeature(key, definition);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_define\",\n // Registry has no unregister; undo re-registers the prior definition when we had one.\n label: existed ? `Redefined feature ${key}` : `Defined feature ${key}`,\n undo: () => {},\n redo: () => adapter.registerFeature(key, definition),\n });\n return textResult(`${existed ? \"Redefined\" : \"Defined\"} feature ${key} (${definition.type ?? \"boolean\"})`, { key, definition });\n },\n (args) => target(str(args.key), `define ${str(args.key)}`),\n );\n\n // ─── Grant / revoke (pendingMode-gated) ──────────────────────────────────\n\n reg(\n \"features_grant\",\n \"Grant a subject access by assigning it to a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\", description: \"Feature group key.\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_grant\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const already = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.assignGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_grant\",\n label: `Granted group ${groupKey}`,\n // Only reverse if WE added it (idempotent assign — don't revoke a pre-existing grant).\n undo: () => { if (!already) void adapter.detachGroup(args.subject, groupKey); },\n redo: () => void adapter.assignGroup(args.subject, groupKey),\n });\n return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `grant ${str(args.group)}`),\n );\n\n reg(\n \"features_revoke\",\n \"Revoke access by detaching a subject from a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_revoke\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const had = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.detachGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_revoke\",\n label: `Revoked group ${groupKey}`,\n undo: () => { if (had) void adapter.assignGroup(args.subject, groupKey); },\n redo: () => void adapter.detachGroup(args.subject, groupKey),\n });\n return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `revoke ${str(args.group)}`),\n );\n\n // ─── Usage / metering ────────────────────────────────────────────────────\n\n reg(\n \"features_consume\",\n \"Meter a resource feature: atomic check-and-increment. Returns ok:false if the quota would be exceeded (nothing recorded).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, amount: { type: \"number\", description: \"Units to consume. Default 1.\" }, context: { description: \"Optional context.\" } },\n [\"feature\", \"subject\"],\n async (args) => {\n if (!adapter.tryConsume) return errorResult(\"Host did not wire usage metering (tryConsume).\");\n const feature = str(args.feature);\n const amount = num(args.amount, 1);\n const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, ok, amount, remaining };\n return textResult(JSON.stringify(out), out);\n },\n (args) => target(str(args.feature), `consume ${str(args.feature)}`),\n );\n\n return {\n id: `features:${featuresId}`,\n title: adapter.title ?? \"Features\",\n dispose: () => {\n for (const d of disposers.splice(0)) d();\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-tools.ts","../src/bridges/features.ts"],"names":["emitActivity","undoOne","redoOne","readHistory","pushUndoEntry"],"mappings":"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","file":"bridges-features.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, transport);\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, transport: Transport): 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, this.missingToolMessage(name));\n }\n const result = await tool.handler(args, { transport });\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 /** Send an application notification to every client, or one attached transport. */\n notify(message: JsonRpcMessage, transport?: Transport): void {\n if (transport) transport.send(message);\n else this.broadcast(message);\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 * Build the `meta` broadcast to all relay peers. Defaults to the tool's full\n * `structuredContent`. Override to REDACT sensitive fields before fan-out —\n * e.g. the terminal bridge strips raw command/keystroke bytes so a command\n * line (or its secrets) is never broadcast verbatim to every peer.\n */\n buildMeta?: (result: CallToolResult) => Record<string, unknown> | undefined;\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: options.buildMeta ? options.buildMeta(result) : extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Headless bridge for `@particle-academy/fancy-features` — feature management\n * with NO UI surface. The adapter is the `FeatureManager` (a `FeatureSource`\n * consumer): define features in the registry, check access for a subject,\n * grant/revoke via group assignment, and meter resource usage. Mutations\n * funnel through `wrapToolWithActivity` so presence + undo compose; `grant` /\n * `revoke` are `pendingMode`-gated (they change what a real user can do).\n *\n * The adapter shapes mirror fancy-features' public `FeatureManager` +\n * `FeatureRegistry` + `GroupStore`, defined LOCALLY so the bridge builds with\n * the sibling absent (optional peer). A live `FeatureManager` (plus its\n * `.registry` / `.groupStore`) satisfies this structurally with no import.\n *\n * SUBJECTS over the wire: `Subject` is opaque (`unknown`) in fancy-features.\n * Agents pass a JSON-serializable subject (string id or `{ id, … }` object);\n * the host's stores key on it via their `defaultSubjectKey`.\n */\n\nexport type FeatureGrant = {\n key: string;\n type: \"boolean\" | \"resource\";\n enabled: boolean;\n includedQuantity?: number | null;\n overageLimit?: number | null;\n source?: string;\n config?: Record<string, unknown>;\n};\n\n/** Normalized feature definition (mirror of fancy-features `FeatureDefinition`). */\nexport type FeatureDefinition = {\n key?: string;\n name?: string;\n description?: string;\n type?: \"boolean\" | \"resource\";\n enabled?: boolean;\n limit?: number;\n [k: string]: unknown;\n};\n\n/**\n * Adapter = the `FeatureManager` + its registry + group store. The bridge only\n * needs these members; a real manager exposes them directly.\n */\nexport type FeaturesBridgeAdapter = {\n /** Stable id for this feature manager instance. */\n id?: string;\n title?: string;\n screenId?: string;\n\n // ── Access checks (FeatureManager) ──\n /** Can the subject access the feature now? `manager.canAccess`. */\n canAccess(feature: string, subject?: unknown, context?: unknown): boolean | Promise<boolean>;\n /** Remaining quota for a resource feature (null = unlimited / n-a). `manager.remaining`. */\n remaining(feature: string, subject?: unknown, context?: unknown): number | null | Promise<number | null>;\n /** All enabled feature keys for the subject. `manager.enabled`. */\n enabled(subject?: unknown, context?: unknown): string[] | Promise<string[]>;\n /** Trace a feature's resolution to an AccessResult. `manager.explain`. */\n explain?(feature: string, subject?: unknown, context?: unknown): Promise<unknown> | unknown;\n\n // ── Registry (define) ──\n /** Register a programmatic feature. `manager.registerFeature` / `manager.registry.register`. */\n registerFeature(key: string, definition: FeatureDefinition): void;\n /** Registered feature keys. `manager.registry.keys`. */\n registryKeys(): string[];\n /** Resolve a registered definition (or null). `manager.registry.definition`. */\n definition?(key: string): FeatureDefinition | null | Promise<FeatureDefinition | null>;\n\n // ── Group store (grant / revoke) ──\n /** Assign a subject to a feature group (the grant primitive). `manager.groupStore.assign`. */\n assignGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Detach a subject from a group (the revoke primitive). `manager.groupStore.detach`. */\n detachGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Group keys assigned to a subject. `manager.groupStore.list`. */\n listGroups(subject: unknown): string[] | Promise<string[]>;\n\n // ── Usage / metering (resource features) ──\n /** Current usage for a resource feature. `manager.usageFor`. Optional. */\n usageFor?(feature: string, subject: unknown): number | Promise<number>;\n /** Atomic check-and-increment quota. `manager.tryConsume`. Optional. */\n tryConsume?(feature: string, subject: unknown, amount?: number, context?: unknown): boolean | Promise<boolean>;\n};\n\nexport type FeaturesBridgeOptions = {\n adapter: FeaturesBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n /**\n * Trust-but-verify. When on (default), `features_grant` / `features_revoke`\n * (they change a real subject's entitlements) require `confirm:true` OR a\n * host `confirm` hook. Checks + define + usage are unaffected.\n */\n pendingMode?: boolean;\n confirm?: (req: { action: string; subject: unknown; groupKey: string }) => Promise<boolean> | boolean;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback = 0): number => (typeof v === \"number\" && Number.isFinite(v) ? v : fallback);\n\n/**\n * registerFeaturesBridge — full MCP tool set over a headless feature manager.\n *\n * features_list enabled feature keys for a subject\n * features_check can a subject access a feature? (+ remaining for resources)\n * features_explain trace why a feature is on/off for a subject\n * features_define register a feature definition (boolean / resource)\n * features_grant assign a subject to a group (pendingMode-gated, undoable)\n * features_revoke detach a subject from a group (pendingMode-gated, undoable)\n * features_groups list a subject's assigned groups\n * features_consume meter a resource feature (atomic check-and-increment)\n */\nexport function registerFeaturesBridge(host: ToolHost, options: FeaturesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const featuresId = adapter.id ?? \"features\";\n const disposers: Array<() => void> = [];\n\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target = (elementId?: string, label?: string): AgentTarget => ({\n kind: \"custom\",\n screenId: adapter.screenId,\n elementId,\n label: label ?? featuresId,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<unknown> | unknown,\n resolveTarget: false | ((args: JsonObject) => AgentTarget),\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 as never, {\n toolName: name,\n agent,\n kind: \"custom\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => resolveTarget(args as JsonObject),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as Record<string, never>, required, additionalProperties: false } },\n final as never,\n ),\n );\n };\n\n const guardGrant = async (action: string, subject: unknown, groupKey: string, hasConfirmArg: boolean) => {\n if (!pendingMode) return null;\n if (options.confirm) {\n const ok = await options.confirm({ action, subject, groupKey });\n return ok ? null : errorResult(`Declined: ${action} ${groupKey} (human did not confirm).`);\n }\n if (!hasConfirmArg) {\n return errorResult(`${action} is staged (pendingMode). Re-call with confirm:true to apply, or wire a host confirm hook.`);\n }\n return null;\n };\n\n // ─── Read / check tools ──────────────────────────────────────────────────\n\n reg(\n \"features_list\",\n \"List the feature keys enabled for a subject. Pass `subject` (a string id or object).\",\n { subject: { description: \"Opaque subject — string id or { id, … } object.\" }, context: { description: \"Optional resolution context.\" } },\n [],\n async (args) => {\n const keys = await adapter.enabled(args.subject, args.context);\n return textResult(JSON.stringify(keys, null, 2), { subject: args.subject, enabled: keys });\n },\n false,\n );\n\n reg(\n \"features_check\",\n \"Check whether a subject can access a feature. For resource features also returns the remaining quota.\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n const feature = str(args.feature);\n const allowed = await adapter.canAccess(feature, args.subject, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, allowed, remaining };\n return textResult(JSON.stringify(out), out);\n },\n false,\n );\n\n reg(\n \"features_explain\",\n \"Trace why a feature is on/off for a subject — returns the AccessResult (source, remaining, limit, used).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n if (!adapter.explain) return errorResult(\"Host did not wire explain().\");\n const result = await adapter.explain(str(args.feature), args.subject, args.context);\n return textResult(JSON.stringify(result, null, 2), result as Record<string, unknown>);\n },\n false,\n );\n\n reg(\n \"features_groups\",\n \"List the feature groups a subject is assigned to.\",\n { subject: { description: \"Opaque subject.\" } },\n [\"subject\"],\n async (args) => {\n const groups = await adapter.listGroups(args.subject);\n return textResult(JSON.stringify(groups, null, 2), { subject: args.subject, groups });\n },\n false,\n );\n\n // ─── Define ──────────────────────────────────────────────────────────────\n\n reg(\n \"features_define\",\n \"Register a feature definition. type 'boolean' (on/off) or 'resource' (metered with a `limit`). `enabled` sets the default gate.\",\n {\n key: { type: \"string\" },\n name: { type: \"string\" },\n description: { type: \"string\" },\n type: { type: \"string\", enum: [\"boolean\", \"resource\"] },\n enabled: { type: \"boolean\" },\n limit: { type: \"number\", description: \"Resource quota per period (resource type).\" },\n },\n [\"key\"],\n (args) => {\n const key = str(args.key);\n if (!key) return errorResult(\"key is required.\");\n const existed = adapter.registryKeys().includes(key);\n const definition: FeatureDefinition = {\n ...(args.name !== undefined ? { name: str(args.name) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.type !== undefined ? { type: str(args.type) as \"boolean\" | \"resource\" } : {}),\n ...(args.enabled !== undefined ? { enabled: args.enabled === true } : {}),\n ...(args.limit !== undefined ? { limit: num(args.limit) } : {}),\n };\n adapter.registerFeature(key, definition);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_define\",\n // Registry has no unregister; undo re-registers the prior definition when we had one.\n label: existed ? `Redefined feature ${key}` : `Defined feature ${key}`,\n undo: () => {},\n redo: () => adapter.registerFeature(key, definition),\n });\n return textResult(`${existed ? \"Redefined\" : \"Defined\"} feature ${key} (${definition.type ?? \"boolean\"})`, { key, definition });\n },\n (args) => target(str(args.key), `define ${str(args.key)}`),\n );\n\n // ─── Grant / revoke (pendingMode-gated) ──────────────────────────────────\n\n reg(\n \"features_grant\",\n \"Grant a subject access by assigning it to a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\", description: \"Feature group key.\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_grant\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const already = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.assignGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_grant\",\n label: `Granted group ${groupKey}`,\n // Only reverse if WE added it (idempotent assign — don't revoke a pre-existing grant).\n undo: () => { if (!already) void adapter.detachGroup(args.subject, groupKey); },\n redo: () => void adapter.assignGroup(args.subject, groupKey),\n });\n return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `grant ${str(args.group)}`),\n );\n\n reg(\n \"features_revoke\",\n \"Revoke access by detaching a subject from a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_revoke\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const had = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.detachGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_revoke\",\n label: `Revoked group ${groupKey}`,\n undo: () => { if (had) void adapter.assignGroup(args.subject, groupKey); },\n redo: () => void adapter.detachGroup(args.subject, groupKey),\n });\n return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `revoke ${str(args.group)}`),\n );\n\n // ─── Usage / metering ────────────────────────────────────────────────────\n\n reg(\n \"features_consume\",\n \"Meter a resource feature: atomic check-and-increment. Returns ok:false if the quota would be exceeded (nothing recorded).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, amount: { type: \"number\", description: \"Units to consume. Default 1.\" }, context: { description: \"Optional context.\" } },\n [\"feature\", \"subject\"],\n async (args) => {\n if (!adapter.tryConsume) return errorResult(\"Host did not wire usage metering (tryConsume).\");\n const feature = str(args.feature);\n const amount = num(args.amount, 1);\n const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, ok, amount, remaining };\n return textResult(JSON.stringify(out), out);\n },\n (args) => target(str(args.feature), `consume ${str(args.feature)}`),\n );\n\n return {\n id: `features:${featuresId}`,\n title: adapter.title ?? \"Features\",\n dispose: () => {\n for (const d of disposers.splice(0)) d();\n },\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
- export { registerFeaturesBridge } from './chunk-ZNGTC4CO.js';
2
- import './chunk-CT3LRNH7.js';
1
+ export { registerFeaturesBridge } from './chunk-NIFPRC7P.js';
2
+ import './chunk-HVDHT7DM.js';
3
3
  import './chunk-2VENWGLZ.js';
4
4
  import './chunk-C3TYI5TJ.js';
5
- import './chunk-DF3PLL2E.js';
5
+ import './chunk-QJYRWEXD.js';
6
6
  //# sourceMappingURL=bridges-features.js.map
7
7
  //# sourceMappingURL=bridges-features.js.map
@@ -125,6 +125,13 @@ function serialize(entry) {
125
125
  // src/bridges/files.ts
126
126
  var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
127
127
  var MAX_SNAPSHOT_DEPTH = 8;
128
+ function invalidFolderName(name) {
129
+ const trimmed = name.trim();
130
+ if (trimmed === "") return "A folder name is required.";
131
+ if (trimmed.includes("/") || trimmed.includes("\\")) return "A folder name may not contain a path separator.";
132
+ if (trimmed === "." || trimmed === "..") return "That folder name is reserved.";
133
+ return null;
134
+ }
128
135
  function assertPathWithinRoot(root, path) {
129
136
  const segments = path.replace(/[\\/]+/g, "/").split("/");
130
137
  if (segments.includes("..")) {
@@ -154,6 +161,7 @@ var asPaths = (v) => {
154
161
  function registerFilesBridge(host, options) {
155
162
  const { adapter } = options;
156
163
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
164
+ const pendingMode = options.pendingMode ?? true;
157
165
  const disposers = [];
158
166
  const guard = (path) => {
159
167
  if (options.root !== void 0) assertPathWithinRoot(options.root, path);
@@ -320,6 +328,42 @@ function registerFilesBridge(host, options) {
320
328
  },
321
329
  fTarget
322
330
  );
331
+ if (adapter.createFolder) {
332
+ reg(
333
+ "files_create_folder",
334
+ "Create a folder inside `parentPath`. Staged for human confirmation unless the host disabled pendingMode.",
335
+ {
336
+ parentPath: { type: "string", description: "Directory to create in; defaults to the current directory." },
337
+ name: { type: "string", description: "The new folder's name. A leaf name \u2014 no separators." },
338
+ confirm: { type: "boolean", description: "Acknowledge a staged write when the host wired no confirm hook." }
339
+ },
340
+ ["name"],
341
+ async (args) => {
342
+ const parentPath = guard(args.parentPath !== void 0 ? str(args.parentPath) : adapter.getPath());
343
+ const name = str(args.name).trim();
344
+ const invalid = invalidFolderName(name);
345
+ if (invalid) return errorResult(invalid);
346
+ const label = `${parentPath}/${name}`;
347
+ if (pendingMode) {
348
+ if (options.confirm) {
349
+ const ok = await options.confirm({ action: "files_create_folder", path: label, label });
350
+ if (!ok) return errorResult(`Declined: create folder ${label} (human did not confirm).`);
351
+ } else if (args.confirm !== true) {
352
+ return errorResult(
353
+ `Staged: create folder ${label}. Re-call with confirm:true to proceed.`
354
+ );
355
+ }
356
+ }
357
+ try {
358
+ await adapter.createFolder({ parentPath, name });
359
+ } catch (e) {
360
+ return errorResult(e instanceof Error ? e.message : String(e));
361
+ }
362
+ return textResult(`Created folder ${label}.`, { parentPath, name, path: label });
363
+ },
364
+ (args) => ({ kind: "directory", path: `${str(args.parentPath)}/${str(args.name)}`, label: str(args.name) })
365
+ );
366
+ }
323
367
  reg(
324
368
  "files_request_snapshot",
325
369
  "Request a fresh snapshot subtree rooted at `path` (snapshot mode) \u2014 e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.",
@@ -353,6 +397,7 @@ function registerFilesBridge(host, options) {
353
397
  }
354
398
 
355
399
  exports.assertPathWithinRoot = assertPathWithinRoot;
400
+ exports.invalidFolderName = invalidFolderName;
356
401
  exports.registerFilesBridge = registerFilesBridge;
357
402
  //# sourceMappingURL=bridges-files.cjs.map
358
403
  //# sourceMappingURL=bridges-files.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-tools.ts","../src/bridges/files.ts"],"names":["emitActivity","undoOne","redoOne","readHistory","p","pushUndoEntry"],"mappings":"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","file":"bridges-files.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, transport);\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, transport: Transport): 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, { transport });\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 /** Send an application notification to every client, or one attached transport. */\n notify(message: JsonRpcMessage, transport?: Transport): void {\n if (transport) transport.send(message);\n else this.broadcast(message);\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 * Build the `meta` broadcast to all relay peers. Defaults to the tool's full\n * `structuredContent`. Override to REDACT sensitive fields before fan-out —\n * e.g. the terminal bridge strips raw command/keystroke bytes so a command\n * line (or its secrets) is never broadcast verbatim to every peer.\n */\n buildMeta?: (result: CallToolResult) => Record<string, unknown> | undefined;\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: options.buildMeta ? options.buildMeta(result) : extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","// Loose types so this bridge builds standalone without a hard dep on\n// @particle-academy/react-fancy. Hosts using FileBrowser pass its own\n// FileEntry / FileSnapshotNode values straight through — the shapes match.\ntype FileKind = \"file\" | \"dir\";\ntype FileEntry = {\n path: string;\n name: string;\n kind: FileKind;\n size?: number;\n mtime?: string;\n hasChildren?: boolean;\n disabled?: boolean;\n};\ntype FileSnapshotNode = FileEntry & { children?: FileSnapshotNode[] };\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 FilesAgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Adapter the host provides — getters/setters over the SAME controlled props it\n * passes to react-fancy's `<FileBrowser>` (`value`/`path`/`expandedPaths`), plus\n * `listChildren` (wire to your `provider.loadChildren` or the loaded cache) and,\n * for snapshot mode, an optional `requestSnapshot`.\n */\nexport type FilesBridgeAdapter = {\n /** Current directory (the `path` prop). */\n getPath: () => string;\n setPath: (path: string) => void;\n /** Selected path(s) — normalize FileBrowser's `value` (string | string[] | null) to an array. */\n getSelection: () => string[];\n setSelection: (paths: string[]) => void;\n /** Expanded folder paths (the `expandedPaths` prop). */\n getExpanded: () => string[];\n setExpanded: (next: string[] | ((prev: string[]) => string[])) => void;\n /** Direct children of a path — wire to `provider.loadChildren` (async) or the loaded/snapshot cache. */\n listChildren: (path: string) => Promise<FileEntry[]> | FileEntry[];\n /** Optional (snapshot mode): fetch/refresh a snapshot subtree so an agent can pull remote state on demand. */\n requestSnapshot?: (path: string, depth?: number) => Promise<FileSnapshotNode[]> | FileSnapshotNode[];\n};\n\nexport type FilesBridgeOptions = {\n adapter: FilesBridgeAdapter;\n /** Identity tagged onto agent-driven actions. */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Optional containment root. When set, every agent-supplied path is checked\n * with {@link assertPathWithinRoot} before it reaches the adapter: a `..`\n * segment or an absolute path outside `root` is rejected. This is a\n * fail-closed, string-level guard (no filesystem access — the bridge runs in\n * the browser). It is NOT sufficient on its own: a host over a real\n * filesystem MUST additionally resolve symlinks/junctions (realpath) and\n * enforce the root, because a link under `root` can still point outside it.\n * When `root` is unset the bridge does no containment and the adapter is\n * SOLELY responsible for sandboxing what `listChildren`/`requestSnapshot` expose.\n */\n root?: string;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/** Host default cap on snapshot recursion, so an agent can't request an\n * unbounded deep walk. */\nconst MAX_SNAPSHOT_DEPTH = 8;\n\n/**\n * Fail-closed, filesystem-free path containment. Throws when `path` contains a\n * `..` segment, or is absolute and not within `root`. Relative paths without\n * `..` pass (resolved within root by the host). String-level only — see the\n * `root` docs: hosts over a real fs must ALSO realpath to defeat symlinks.\n */\nexport function assertPathWithinRoot(root: string, path: string): void {\n const segments = path.replace(/[\\\\/]+/g, \"/\").split(\"/\");\n if (segments.includes(\"..\")) {\n throw new Error(`Path may not contain '..': ${path}`);\n }\n const isAbsolute = /^([A-Za-z]:)?[\\\\/]/.test(path) || /^[A-Za-z]:/.test(path);\n if (isAbsolute) {\n // Strip a trailing slash with `\\/$`, NOT `\\/+$`. The quantified `\\/+$`\n // is a polynomial-ReDoS on paths with many slashes (CodeQL js/polynomial-\n // redos), and the `+` is redundant here: the preceding\n // `.replace(/[\\\\/]+/g, \"/\")` has already collapsed every slash-run to a\n // single `/`, so at most one trailing slash can remain. Non-quantified\n // `\\/$` matches the same input in linear time.\n const norm = (p: string): string => p.replace(/[\\\\/]+/g, \"/\").replace(/\\/$/, \"\").toLowerCase();\n const r = norm(root);\n const p = norm(path);\n if (p !== r && !p.startsWith(r + \"/\")) {\n throw new Error(`Path escapes the configured root: ${path}`);\n }\n }\n}\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst asPaths = (v: unknown): string[] => {\n if (typeof v === \"string\") {\n return [v];\n }\n if (Array.isArray(v)) {\n return v.filter((x): x is string => typeof x === \"string\");\n }\n return [];\n};\n\n/**\n * registerFilesBridge — an MCP tool set over a react-fancy `<FileBrowser>`'s\n * controlled state, so a human and an agent share one file browser. The agent\n * lists a folder's children, navigates, expands/collapses folders, selects\n * entries, and (in snapshot mode) requests a fresh subtree — driving the same\n * `value`/`path`/`expandedPaths` props, no DOM scraping. Every mutation\n * broadcasts AgentActivity (presence) and pushes an undo entry. Mirrors the\n * map / whiteboard / flow bridges in shape.\n *\n * Read-only browse in v1: no content preview (pair with fancy-code's\n * FileViewer) and no write ops (rename/delete/upload) — those arrive later\n * behind a pendingMode-gated iteration.\n */\nexport function registerFilesBridge(host: ToolHost, options: FilesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Reject traversal / out-of-root paths before they reach the adapter (no-op\n // when no root is configured — the adapter is then responsible for sandboxing).\n const guard = (path: string): string => {\n if (options.root !== undefined) assertPathWithinRoot(options.root, path);\n return path;\n };\n\n // Register agent_undo / agent_redo / agent_history once per host. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const fTarget = (args: any, _result: any): FilesAgentTarget => ({\n kind: \"files\",\n elementId: (args?.path as string | undefined) ?? 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) => FilesAgentTarget | 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: \"files\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read ─────────────\n\n reg(\n \"files_get_state\",\n \"Get the file browser's current directory, selected path(s), and expanded folders.\",\n {},\n [],\n () => {\n const state = {\n path: adapter.getPath(),\n selected: adapter.getSelection(),\n expanded: adapter.getExpanded(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n },\n );\n\n reg(\n \"files_list\",\n \"List the direct children of a folder (files + subfolders). Omit `path` for the current directory. Loads lazily from the host's provider/snapshot — never an eager tree walk.\",\n { path: { type: \"string\", description: \"Folder path to list; defaults to the current directory.\" } },\n [],\n async (args) => {\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n const entries = await adapter.listChildren(path);\n const summary = entries.map((e) => ({\n path: e.path,\n name: e.name,\n kind: e.kind,\n ...(e.size !== undefined ? { size: e.size } : {}),\n ...(e.mtime !== undefined ? { mtime: e.mtime } : {}),\n }));\n const text =\n summary.map((e) => `${e.kind === \"dir\" ? \"📁\" : \"📄\"} ${e.path}`).join(\"\\n\") ||\n `(empty: ${path})`;\n return textResult(text, { path, entries: summary });\n },\n );\n\n // ───────────── Navigation ─────────────\n\n reg(\n \"files_navigate\",\n \"Set the current directory (as if the user clicked a breadcrumb or opened a folder).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n const prev = adapter.getPath();\n adapter.setPath(path);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_navigate\",\n label: `Navigated to ${path}`,\n undo: () => adapter.setPath(prev),\n redo: () => adapter.setPath(path),\n });\n return textResult(`Current directory → ${path}`, { path });\n },\n fTarget,\n );\n\n // ───────────── Expansion ─────────────\n\n reg(\n \"files_expand\",\n \"Expand a folder in the tree (loads its children if needed).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (adapter.getExpanded().includes(path)) {\n return textResult(`${path} already expanded`, { path, expanded: true });\n }\n adapter.setExpanded((prev) => [...prev, path]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_expand\",\n label: `Expanded ${path}`,\n undo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n redo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n });\n return textResult(`Expanded ${path}`, { path, expanded: true });\n },\n fTarget,\n );\n\n reg(\n \"files_collapse\",\n \"Collapse a folder in the tree.\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (!adapter.getExpanded().includes(path)) {\n return textResult(`${path} already collapsed`, { path, expanded: false });\n }\n adapter.setExpanded((prev) => prev.filter((p) => p !== path));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_collapse\",\n label: `Collapsed ${path}`,\n undo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n redo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n });\n return textResult(`Collapsed ${path}`, { path, expanded: false });\n },\n fTarget,\n );\n\n // ───────────── Selection ─────────────\n\n reg(\n \"files_select\",\n \"Set the selection to the given path(s). Pass a single `path`, or `paths` for a multi-select browser; either empty clears the selection.\",\n {\n path: { type: \"string\", description: \"A single path to select.\" },\n paths: { type: \"array\", items: { type: \"string\" }, description: \"Multiple paths (multi-select browsers).\" },\n },\n [],\n (args) => {\n const next = (args.paths !== undefined ? asPaths(args.paths) : asPaths(args.path)).map(guard);\n const prev = adapter.getSelection();\n adapter.setSelection(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_select\",\n label: next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\",\n undo: () => adapter.setSelection(prev),\n redo: () => adapter.setSelection(next),\n });\n return textResult(next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\", {\n selected: next,\n });\n },\n fTarget,\n );\n\n // ───────────── Snapshot (streamed remote trees) ─────────────\n\n reg(\n \"files_request_snapshot\",\n \"Request a fresh snapshot subtree rooted at `path` (snapshot mode) — e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.\",\n {\n path: { type: \"string\", description: \"Root of the subtree; defaults to the current directory.\" },\n depth: { type: \"number\", description: \"How many levels deep to materialize (host-defined default).\" },\n },\n [],\n async (args) => {\n if (!adapter.requestSnapshot) {\n return errorResult(\"Host did not wire requestSnapshot (snapshot mode not enabled).\");\n }\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n // Clamp depth so an agent can't demand an unbounded recursive walk.\n const depth =\n args.depth !== undefined ? Math.max(0, Math.min(MAX_SNAPSHOT_DEPTH, num(args.depth))) : undefined;\n const tree = await adapter.requestSnapshot(path, depth);\n const count = Array.isArray(tree) ? tree.length : 0;\n return textResult(`Snapshot of ${path}: ${count} top-level entr${count === 1 ? \"y\" : \"ies\"}.`, {\n path,\n snapshot: tree,\n });\n },\n fTarget,\n );\n\n return {\n id: \"files\",\n title: \"Files\",\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/undo/undo-tools.ts","../src/bridges/files.ts"],"names":["emitActivity","undoOne","redoOne","readHistory","p","pushUndoEntry"],"mappings":"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","file":"bridges-files.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, transport);\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, transport: Transport): 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, this.missingToolMessage(name));\n }\n const result = await tool.handler(args, { transport });\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 /** Send an application notification to every client, or one attached transport. */\n notify(message: JsonRpcMessage, transport?: Transport): void {\n if (transport) transport.send(message);\n else this.broadcast(message);\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 * Build the `meta` broadcast to all relay peers. Defaults to the tool's full\n * `structuredContent`. Override to REDACT sensitive fields before fan-out —\n * e.g. the terminal bridge strips raw command/keystroke bytes so a command\n * line (or its secrets) is never broadcast verbatim to every peer.\n */\n buildMeta?: (result: CallToolResult) => Record<string, unknown> | undefined;\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: options.buildMeta ? options.buildMeta(result) : extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedHosts = new WeakSet<ToolHost>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(host: ToolHost, options: UndoToolsOptions = {}): void {\n if (installedHosts.has(host)) return;\n installedHosts.add(host);\n registerUndoTools(host, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(host: ToolHost, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n host.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","// Loose types so this bridge builds standalone without a hard dep on\n// @particle-academy/react-fancy. Hosts using FileBrowser pass its own\n// FileEntry / FileSnapshotNode values straight through — the shapes match.\ntype FileKind = \"file\" | \"dir\";\ntype FileEntry = {\n path: string;\n name: string;\n kind: FileKind;\n size?: number;\n mtime?: string;\n hasChildren?: boolean;\n disabled?: boolean;\n};\ntype FileSnapshotNode = FileEntry & { children?: FileSnapshotNode[] };\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 FilesAgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Adapter the host provides — getters/setters over the SAME controlled props it\n * passes to react-fancy's `<FileBrowser>` (`value`/`path`/`expandedPaths`), plus\n * `listChildren` (wire to your `provider.loadChildren` or the loaded cache) and,\n * for snapshot mode, an optional `requestSnapshot`.\n */\nexport type FilesBridgeAdapter = {\n /** Current directory (the `path` prop). */\n getPath: () => string;\n setPath: (path: string) => void;\n /** Selected path(s) — normalize FileBrowser's `value` (string | string[] | null) to an array. */\n getSelection: () => string[];\n setSelection: (paths: string[]) => void;\n /** Expanded folder paths (the `expandedPaths` prop). */\n getExpanded: () => string[];\n setExpanded: (next: string[] | ((prev: string[]) => string[])) => void;\n /** Direct children of a path — wire to `provider.loadChildren` (async) or the loaded/snapshot cache. */\n listChildren: (path: string) => Promise<FileEntry[]> | FileEntry[];\n /** Optional (snapshot mode): fetch/refresh a snapshot subtree so an agent can pull remote state on demand. */\n requestSnapshot?: (path: string, depth?: number) => Promise<FileSnapshotNode[]> | FileSnapshotNode[];\n /**\n * Create a folder. **Supplying this is the opt-in** — `files_create_folder`\n * is registered only when it is present, so an agent cannot be handed a write\n * a host never wired, and the advertised tool list tells the truth about what\n * is possible.\n *\n * Pairs with `FileBrowser`'s `onCreateFolder` (react-fancy 5.18+): the same\n * operation the human has, given to the agent.\n */\n createFolder?: (input: { parentPath: string; name: string }) => Promise<void> | void;\n};\n\nexport type FilesBridgeOptions = {\n adapter: FilesBridgeAdapter;\n /** Identity tagged onto agent-driven actions. */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Optional containment root. When set, every agent-supplied path is checked\n * with {@link assertPathWithinRoot} before it reaches the adapter: a `..`\n * segment or an absolute path outside `root` is rejected. This is a\n * fail-closed, string-level guard (no filesystem access — the bridge runs in\n * the browser). It is NOT sufficient on its own: a host over a real\n * filesystem MUST additionally resolve symlinks/junctions (realpath) and\n * enforce the root, because a link under `root` can still point outside it.\n * When `root` is unset the bridge does no containment and the adapter is\n * SOLELY responsible for sandboxing what `listChildren`/`requestSnapshot` expose.\n */\n root?: string;\n /**\n * Stage writes for human confirmation. Default **true**, matching the\n * catalog bridge's destructive ops.\n *\n * This bridge writes to a filesystem on the strength of a model's output, so\n * the safe mode is the default and turning it off is the deliberate act.\n */\n pendingMode?: boolean;\n /** Host confirm hook for staged writes. Resolves true to proceed. */\n confirm?: (req: { action: string; path: string; label: string }) => Promise<boolean> | boolean;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/** Host default cap on snapshot recursion, so an agent can't request an\n * unbounded deep walk. */\nconst MAX_SNAPSHOT_DEPTH = 8;\n\n/**\n * Fail-closed, filesystem-free path containment. Throws when `path` contains a\n * `..` segment, or is absolute and not within `root`. Relative paths without\n * `..` pass (resolved within root by the host). String-level only — see the\n * `root` docs: hosts over a real fs must ALSO realpath to defeat symlinks.\n */\n/**\n * Why a folder NAME cannot be used, or `null`.\n *\n * `assertPathWithinRoot` inspects the parent path; the name is appended to it\n * afterwards, so `{ parentPath: \"/root\", name: \"../..\" }` clears that check and\n * still escapes. A name containing a separator is not a name.\n */\nexport function invalidFolderName(name: string): string | null {\n const trimmed = name.trim();\n if (trimmed === \"\") return \"A folder name is required.\";\n if (trimmed.includes(\"/\") || trimmed.includes(\"\\\\\")) return \"A folder name may not contain a path separator.\";\n if (trimmed === \".\" || trimmed === \"..\") return \"That folder name is reserved.\";\n return null;\n}\n\nexport function assertPathWithinRoot(root: string, path: string): void {\n const segments = path.replace(/[\\\\/]+/g, \"/\").split(\"/\");\n if (segments.includes(\"..\")) {\n throw new Error(`Path may not contain '..': ${path}`);\n }\n const isAbsolute = /^([A-Za-z]:)?[\\\\/]/.test(path) || /^[A-Za-z]:/.test(path);\n if (isAbsolute) {\n // Strip a trailing slash with `\\/$`, NOT `\\/+$`. The quantified `\\/+$`\n // is a polynomial-ReDoS on paths with many slashes (CodeQL js/polynomial-\n // redos), and the `+` is redundant here: the preceding\n // `.replace(/[\\\\/]+/g, \"/\")` has already collapsed every slash-run to a\n // single `/`, so at most one trailing slash can remain. Non-quantified\n // `\\/$` matches the same input in linear time.\n const norm = (p: string): string => p.replace(/[\\\\/]+/g, \"/\").replace(/\\/$/, \"\").toLowerCase();\n const r = norm(root);\n const p = norm(path);\n if (p !== r && !p.startsWith(r + \"/\")) {\n throw new Error(`Path escapes the configured root: ${path}`);\n }\n }\n}\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst asPaths = (v: unknown): string[] => {\n if (typeof v === \"string\") {\n return [v];\n }\n if (Array.isArray(v)) {\n return v.filter((x): x is string => typeof x === \"string\");\n }\n return [];\n};\n\n/**\n * registerFilesBridge — an MCP tool set over a react-fancy `<FileBrowser>`'s\n * controlled state, so a human and an agent share one file browser. The agent\n * lists a folder's children, navigates, expands/collapses folders, selects\n * entries, and (in snapshot mode) requests a fresh subtree — driving the same\n * `value`/`path`/`expandedPaths` props, no DOM scraping. Every mutation\n * broadcasts AgentActivity (presence) and pushes an undo entry. Mirrors the\n * map / whiteboard / flow bridges in shape.\n *\n * Read-only browse in v1: no content preview (pair with fancy-code's\n * FileViewer) and no write ops (rename/delete/upload) — those arrive later\n * behind a pendingMode-gated iteration.\n */\nexport function registerFilesBridge(host: ToolHost, options: FilesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const disposers: Array<() => void> = [];\n\n // Reject traversal / out-of-root paths before they reach the adapter (no-op\n // when no root is configured — the adapter is then responsible for sandboxing).\n const guard = (path: string): string => {\n if (options.root !== undefined) assertPathWithinRoot(options.root, path);\n return path;\n };\n\n // Register agent_undo / agent_redo / agent_history once per host. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const fTarget = (args: any, _result: any): FilesAgentTarget => ({\n kind: \"files\",\n elementId: (args?.path as string | undefined) ?? 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) => FilesAgentTarget | 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: \"files\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read ─────────────\n\n reg(\n \"files_get_state\",\n \"Get the file browser's current directory, selected path(s), and expanded folders.\",\n {},\n [],\n () => {\n const state = {\n path: adapter.getPath(),\n selected: adapter.getSelection(),\n expanded: adapter.getExpanded(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n },\n );\n\n reg(\n \"files_list\",\n \"List the direct children of a folder (files + subfolders). Omit `path` for the current directory. Loads lazily from the host's provider/snapshot — never an eager tree walk.\",\n { path: { type: \"string\", description: \"Folder path to list; defaults to the current directory.\" } },\n [],\n async (args) => {\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n const entries = await adapter.listChildren(path);\n const summary = entries.map((e) => ({\n path: e.path,\n name: e.name,\n kind: e.kind,\n ...(e.size !== undefined ? { size: e.size } : {}),\n ...(e.mtime !== undefined ? { mtime: e.mtime } : {}),\n }));\n const text =\n summary.map((e) => `${e.kind === \"dir\" ? \"📁\" : \"📄\"} ${e.path}`).join(\"\\n\") ||\n `(empty: ${path})`;\n return textResult(text, { path, entries: summary });\n },\n );\n\n // ───────────── Navigation ─────────────\n\n reg(\n \"files_navigate\",\n \"Set the current directory (as if the user clicked a breadcrumb or opened a folder).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n const prev = adapter.getPath();\n adapter.setPath(path);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_navigate\",\n label: `Navigated to ${path}`,\n undo: () => adapter.setPath(prev),\n redo: () => adapter.setPath(path),\n });\n return textResult(`Current directory → ${path}`, { path });\n },\n fTarget,\n );\n\n // ───────────── Expansion ─────────────\n\n reg(\n \"files_expand\",\n \"Expand a folder in the tree (loads its children if needed).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (adapter.getExpanded().includes(path)) {\n return textResult(`${path} already expanded`, { path, expanded: true });\n }\n adapter.setExpanded((prev) => [...prev, path]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_expand\",\n label: `Expanded ${path}`,\n undo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n redo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n });\n return textResult(`Expanded ${path}`, { path, expanded: true });\n },\n fTarget,\n );\n\n reg(\n \"files_collapse\",\n \"Collapse a folder in the tree.\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (!adapter.getExpanded().includes(path)) {\n return textResult(`${path} already collapsed`, { path, expanded: false });\n }\n adapter.setExpanded((prev) => prev.filter((p) => p !== path));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_collapse\",\n label: `Collapsed ${path}`,\n undo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n redo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n });\n return textResult(`Collapsed ${path}`, { path, expanded: false });\n },\n fTarget,\n );\n\n // ───────────── Selection ─────────────\n\n reg(\n \"files_select\",\n \"Set the selection to the given path(s). Pass a single `path`, or `paths` for a multi-select browser; either empty clears the selection.\",\n {\n path: { type: \"string\", description: \"A single path to select.\" },\n paths: { type: \"array\", items: { type: \"string\" }, description: \"Multiple paths (multi-select browsers).\" },\n },\n [],\n (args) => {\n const next = (args.paths !== undefined ? asPaths(args.paths) : asPaths(args.path)).map(guard);\n const prev = adapter.getSelection();\n adapter.setSelection(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_select\",\n label: next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\",\n undo: () => adapter.setSelection(prev),\n redo: () => adapter.setSelection(next),\n });\n return textResult(next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\", {\n selected: next,\n });\n },\n fTarget,\n );\n\n // ───────────── Write (staged) ─────────────\n\n if (adapter.createFolder) {\n reg(\n \"files_create_folder\",\n \"Create a folder inside `parentPath`. Staged for human confirmation unless the host disabled pendingMode.\",\n {\n parentPath: { type: \"string\", description: \"Directory to create in; defaults to the current directory.\" },\n name: { type: \"string\", description: \"The new folder's name. A leaf name — no separators.\" },\n confirm: { type: \"boolean\", description: \"Acknowledge a staged write when the host wired no confirm hook.\" },\n },\n [\"name\"],\n async (args) => {\n const parentPath = guard(args.parentPath !== undefined ? str(args.parentPath) : adapter.getPath());\n const name = str(args.name).trim();\n\n const invalid = invalidFolderName(name);\n if (invalid) return errorResult(invalid);\n\n const label = `${parentPath}/${name}`;\n\n if (pendingMode) {\n if (options.confirm) {\n const ok = await options.confirm({ action: \"files_create_folder\", path: label, label });\n if (!ok) return errorResult(`Declined: create folder ${label} (human did not confirm).`);\n } else if (args.confirm !== true) {\n return errorResult(\n `Staged: create folder ${label}. Re-call with confirm:true to proceed.`,\n );\n }\n }\n\n try {\n await adapter.createFolder!({ parentPath, name });\n } catch (e) {\n // The host's filesystem is the authority on what is allowed —\n // permissions, name rules, a race with another writer. Reporting its\n // refusal as success would tell the agent a folder exists that does not.\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n\n return textResult(`Created folder ${label}.`, { parentPath, name, path: label });\n },\n (args) => ({ kind: \"directory\", path: `${str(args.parentPath)}/${str(args.name)}`, label: str(args.name) }),\n );\n }\n\n // ───────────── Snapshot (streamed remote trees) ─────────────\n\n reg(\n \"files_request_snapshot\",\n \"Request a fresh snapshot subtree rooted at `path` (snapshot mode) — e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.\",\n {\n path: { type: \"string\", description: \"Root of the subtree; defaults to the current directory.\" },\n depth: { type: \"number\", description: \"How many levels deep to materialize (host-defined default).\" },\n },\n [],\n async (args) => {\n if (!adapter.requestSnapshot) {\n return errorResult(\"Host did not wire requestSnapshot (snapshot mode not enabled).\");\n }\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n // Clamp depth so an agent can't demand an unbounded recursive walk.\n const depth =\n args.depth !== undefined ? Math.max(0, Math.min(MAX_SNAPSHOT_DEPTH, num(args.depth))) : undefined;\n const tree = await adapter.requestSnapshot(path, depth);\n const count = Array.isArray(tree) ? tree.length : 0;\n return textResult(`Snapshot of ${path}: ${count} top-level entr${count === 1 ? \"y\" : \"ies\"}.`, {\n path,\n snapshot: tree,\n });\n },\n fTarget,\n );\n\n return {\n id: \"files\",\n title: \"Files\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
- export { assertPathWithinRoot, registerFilesBridge } from './chunk-A25E22WW.js';
2
- import './chunk-CT3LRNH7.js';
1
+ export { assertPathWithinRoot, invalidFolderName, registerFilesBridge } from './chunk-N5VOPV64.js';
2
+ import './chunk-HVDHT7DM.js';
3
3
  import './chunk-2VENWGLZ.js';
4
4
  import './chunk-C3TYI5TJ.js';
5
- import './chunk-DF3PLL2E.js';
5
+ import './chunk-QJYRWEXD.js';
6
6
  //# sourceMappingURL=bridges-files.js.map
7
7
  //# sourceMappingURL=bridges-files.js.map