@particle-academy/agent-integrations 0.49.0 → 0.51.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 (226) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +11 -0
  3. package/dist/bridges/artboard.d.cts +3 -3
  4. package/dist/bridges/artboard.d.ts +3 -3
  5. package/dist/bridges/catalog.d.cts +3 -3
  6. package/dist/bridges/catalog.d.ts +3 -3
  7. package/dist/bridges/charts.d.cts +3 -3
  8. package/dist/bridges/charts.d.ts +3 -3
  9. package/dist/bridges/cms.d.cts +3 -3
  10. package/dist/bridges/cms.d.ts +3 -3
  11. package/dist/bridges/code.d.cts +3 -3
  12. package/dist/bridges/code.d.ts +3 -3
  13. package/dist/bridges/doc.d.cts +3 -3
  14. package/dist/bridges/doc.d.ts +3 -3
  15. package/dist/bridges/features.d.cts +3 -3
  16. package/dist/bridges/features.d.ts +3 -3
  17. package/dist/bridges/files.d.cts +3 -3
  18. package/dist/bridges/files.d.ts +3 -3
  19. package/dist/bridges/flow.d.cts +3 -3
  20. package/dist/bridges/flow.d.ts +3 -3
  21. package/dist/bridges/forms.d.cts +3 -3
  22. package/dist/bridges/forms.d.ts +3 -3
  23. package/dist/bridges/git.d.cts +3 -3
  24. package/dist/bridges/git.d.ts +3 -3
  25. package/dist/bridges/grid.d.cts +3 -3
  26. package/dist/bridges/grid.d.ts +3 -3
  27. package/dist/bridges/map.d.cts +3 -3
  28. package/dist/bridges/map.d.ts +3 -3
  29. package/dist/bridges/navigation.d.cts +3 -3
  30. package/dist/bridges/navigation.d.ts +3 -3
  31. package/dist/bridges/passkeys.d.cts +3 -3
  32. package/dist/bridges/passkeys.d.ts +3 -3
  33. package/dist/bridges/scene.d.cts +3 -3
  34. package/dist/bridges/scene.d.ts +3 -3
  35. package/dist/bridges/screen-doc.d.cts +3 -3
  36. package/dist/bridges/screen-doc.d.ts +3 -3
  37. package/dist/bridges/screens.d.cts +3 -3
  38. package/dist/bridges/screens.d.ts +3 -3
  39. package/dist/bridges/sheets.d.cts +3 -3
  40. package/dist/bridges/sheets.d.ts +3 -3
  41. package/dist/bridges/slides.d.cts +3 -3
  42. package/dist/bridges/slides.d.ts +3 -3
  43. package/dist/bridges/terminal.d.cts +3 -3
  44. package/dist/bridges/terminal.d.ts +3 -3
  45. package/dist/bridges/tui.d.cts +2 -2
  46. package/dist/bridges/tui.d.ts +2 -2
  47. package/dist/bridges/whiteboard.d.cts +3 -3
  48. package/dist/bridges/whiteboard.d.ts +3 -3
  49. package/dist/bridges-artboard.cjs +11 -5
  50. package/dist/bridges-artboard.cjs.map +1 -1
  51. package/dist/bridges-artboard.js +6 -4
  52. package/dist/bridges-artboard.js.map +1 -1
  53. package/dist/bridges-catalog.cjs +35 -13
  54. package/dist/bridges-catalog.cjs.map +1 -1
  55. package/dist/bridges-catalog.js +3 -3
  56. package/dist/bridges-charts.cjs +11 -5
  57. package/dist/bridges-charts.cjs.map +1 -1
  58. package/dist/bridges-charts.js +3 -3
  59. package/dist/bridges-cms.cjs +11 -5
  60. package/dist/bridges-cms.cjs.map +1 -1
  61. package/dist/bridges-cms.js +4 -4
  62. package/dist/bridges-code.cjs +11 -5
  63. package/dist/bridges-code.cjs.map +1 -1
  64. package/dist/bridges-code.js +3 -3
  65. package/dist/bridges-doc.cjs +11 -5
  66. package/dist/bridges-doc.cjs.map +1 -1
  67. package/dist/bridges-doc.js +3 -3
  68. package/dist/bridges-features.cjs +21 -11
  69. package/dist/bridges-features.cjs.map +1 -1
  70. package/dist/bridges-features.js +3 -3
  71. package/dist/bridges-files.cjs +11 -5
  72. package/dist/bridges-files.cjs.map +1 -1
  73. package/dist/bridges-files.js +3 -3
  74. package/dist/bridges-flow.cjs +11 -5
  75. package/dist/bridges-flow.cjs.map +1 -1
  76. package/dist/bridges-flow.js +6 -4
  77. package/dist/bridges-flow.js.map +1 -1
  78. package/dist/bridges-forms.cjs +11 -5
  79. package/dist/bridges-forms.cjs.map +1 -1
  80. package/dist/bridges-forms.js +3 -3
  81. package/dist/bridges-git.cjs +10 -5
  82. package/dist/bridges-git.cjs.map +1 -1
  83. package/dist/bridges-git.js +3 -3
  84. package/dist/bridges-grid.cjs +11 -5
  85. package/dist/bridges-grid.cjs.map +1 -1
  86. package/dist/bridges-grid.js +3 -3
  87. package/dist/bridges-map.cjs +11 -5
  88. package/dist/bridges-map.cjs.map +1 -1
  89. package/dist/bridges-map.js +3 -3
  90. package/dist/bridges-navigation.cjs +15 -9
  91. package/dist/bridges-navigation.cjs.map +1 -1
  92. package/dist/bridges-navigation.js +3 -3
  93. package/dist/bridges-passkeys.cjs +17 -7
  94. package/dist/bridges-passkeys.cjs.map +1 -1
  95. package/dist/bridges-passkeys.js +3 -3
  96. package/dist/bridges-scene.cjs +11 -5
  97. package/dist/bridges-scene.cjs.map +1 -1
  98. package/dist/bridges-scene.js +3 -3
  99. package/dist/bridges-screen-doc.cjs +14 -6
  100. package/dist/bridges-screen-doc.cjs.map +1 -1
  101. package/dist/bridges-screen-doc.js +4 -4
  102. package/dist/bridges-screens.cjs +11 -5
  103. package/dist/bridges-screens.cjs.map +1 -1
  104. package/dist/bridges-screens.js +3 -3
  105. package/dist/bridges-sheets.cjs +11 -5
  106. package/dist/bridges-sheets.cjs.map +1 -1
  107. package/dist/bridges-sheets.js +3 -3
  108. package/dist/bridges-slides.cjs +11 -5
  109. package/dist/bridges-slides.cjs.map +1 -1
  110. package/dist/bridges-slides.js +3 -3
  111. package/dist/bridges-terminal.cjs +11 -5
  112. package/dist/bridges-terminal.cjs.map +1 -1
  113. package/dist/bridges-terminal.js +3 -3
  114. package/dist/bridges-tui.cjs +1 -1
  115. package/dist/bridges-tui.cjs.map +1 -1
  116. package/dist/bridges-tui.js +2 -2
  117. package/dist/bridges-whiteboard.cjs +11 -5
  118. package/dist/bridges-whiteboard.cjs.map +1 -1
  119. package/dist/bridges-whiteboard.js +3 -3
  120. package/dist/{chunk-CZV3WUW5.js → chunk-3GFKC6OK.js} +20 -7
  121. package/dist/chunk-3GFKC6OK.js.map +1 -0
  122. package/dist/{chunk-JLHVQWOV.js → chunk-6Q3PMT7K.js} +4 -4
  123. package/dist/chunk-6Q3PMT7K.js.map +1 -0
  124. package/dist/{chunk-AXWMWYH5.js → chunk-C4AQ2YBW.js} +7 -6
  125. package/dist/chunk-C4AQ2YBW.js.map +1 -0
  126. package/dist/{chunk-CS3CHGYC.js → chunk-CI5ZVHDY.js} +32 -14
  127. package/dist/chunk-CI5ZVHDY.js.map +1 -0
  128. package/dist/{chunk-5ZWNCHZS.js → chunk-CKJL5C7A.js} +8 -6
  129. package/dist/chunk-CKJL5C7A.js.map +1 -0
  130. package/dist/{chunk-HOZCDDRA.js → chunk-CP3EHLZJ.js} +8 -6
  131. package/dist/chunk-CP3EHLZJ.js.map +1 -0
  132. package/dist/{chunk-VFWFT3OK.js → chunk-DNF3QVTW.js} +8 -6
  133. package/dist/chunk-DNF3QVTW.js.map +1 -0
  134. package/dist/{chunk-OHNGURUJ.js → chunk-HNVHAY4A.js} +12 -10
  135. package/dist/chunk-HNVHAY4A.js.map +1 -0
  136. package/dist/{chunk-GVTBMJU6.js → chunk-KAEPC6N4.js} +18 -12
  137. package/dist/chunk-KAEPC6N4.js.map +1 -0
  138. package/dist/{chunk-3WVXAB3D.js → chunk-M423JOQ3.js} +3 -3
  139. package/dist/{chunk-3WVXAB3D.js.map → chunk-M423JOQ3.js.map} +1 -1
  140. package/dist/{chunk-SWWJUOCY.js → chunk-MKC633WU.js} +3 -3
  141. package/dist/{chunk-SWWJUOCY.js.map → chunk-MKC633WU.js.map} +1 -1
  142. package/dist/{chunk-LQB42OSA.js → chunk-MKJE6V4Z.js} +8 -6
  143. package/dist/chunk-MKJE6V4Z.js.map +1 -0
  144. package/dist/{chunk-MIDZWKIF.js → chunk-NB5AQIR2.js} +8 -6
  145. package/dist/chunk-NB5AQIR2.js.map +1 -0
  146. package/dist/{chunk-VMRUW4B4.js → chunk-OUUHFR4N.js} +8 -6
  147. package/dist/chunk-OUUHFR4N.js.map +1 -0
  148. package/dist/{chunk-FCXSR7I5.js → chunk-P6SJBP5T.js} +8 -6
  149. package/dist/chunk-P6SJBP5T.js.map +1 -0
  150. package/dist/{chunk-5JLTXHX6.js → chunk-PMPBI6I3.js} +7 -5
  151. package/dist/chunk-PMPBI6I3.js.map +1 -0
  152. package/dist/{chunk-G6CRHFWU.js → chunk-PV4FZDYX.js} +14 -8
  153. package/dist/chunk-PV4FZDYX.js.map +1 -0
  154. package/dist/{chunk-3UUF5KKZ.js → chunk-QEVSNDJW.js} +8 -6
  155. package/dist/chunk-QEVSNDJW.js.map +1 -0
  156. package/dist/{chunk-VOCUGTZB.js → chunk-S4DA2UTJ.js} +8 -6
  157. package/dist/chunk-S4DA2UTJ.js.map +1 -0
  158. package/dist/{chunk-RVMM4BHK.js → chunk-V6EHKHSF.js} +8 -6
  159. package/dist/chunk-V6EHKHSF.js.map +1 -0
  160. package/dist/{chunk-36MKPTVD.js → chunk-VE7TRWZR.js} +8 -6
  161. package/dist/chunk-VE7TRWZR.js.map +1 -0
  162. package/dist/{chunk-Z5NL5D4J.js → chunk-VFUKZ6UA.js} +8 -6
  163. package/dist/chunk-VFUKZ6UA.js.map +1 -0
  164. package/dist/{chunk-3HVYUMQF.js → chunk-VHB3VE53.js} +8 -6
  165. package/dist/chunk-VHB3VE53.js.map +1 -0
  166. package/dist/{chunk-R4XXOGQH.js → chunk-ZDKYKJFH.js} +10 -6
  167. package/dist/chunk-ZDKYKJFH.js.map +1 -0
  168. package/dist/components-shared-whiteboard.cjs +29 -10
  169. package/dist/components-shared-whiteboard.cjs.map +1 -1
  170. package/dist/components-shared-whiteboard.js +3 -3
  171. package/dist/dom-navigation/index.d.cts +3 -3
  172. package/dist/dom-navigation/index.d.ts +3 -3
  173. package/dist/index.cjs +140 -64
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.d.cts +5 -5
  176. package/dist/index.d.ts +5 -5
  177. package/dist/index.js +26 -26
  178. package/dist/mcp/index.d.cts +5 -5
  179. package/dist/mcp/index.d.ts +5 -5
  180. package/dist/mcp/stdio.d.cts +3 -3
  181. package/dist/mcp/stdio.d.ts +3 -3
  182. package/dist/mcp.cjs +18 -5
  183. package/dist/mcp.cjs.map +1 -1
  184. package/dist/mcp.js +1 -1
  185. package/dist/presence/index.d.cts +1 -1
  186. package/dist/presence/index.d.ts +1 -1
  187. package/dist/{server-1y0n61R5.d.cts → server-DJJygNo1.d.cts} +2 -2
  188. package/dist/{server-vq6qVl3T.d.ts → server-Dwo9LOxh.d.ts} +2 -2
  189. package/dist/sharing/index.d.cts +3 -3
  190. package/dist/sharing/index.d.ts +3 -3
  191. package/dist/sheets-adapter.d.cts +3 -3
  192. package/dist/sheets-adapter.d.ts +3 -3
  193. package/dist/{tool-host-LYfdPE8u.d.ts → tool-host-BBSaU7IJ.d.cts} +10 -4
  194. package/dist/{tool-host-D67N2a2h.d.cts → tool-host-BqJRPr_T.d.ts} +10 -4
  195. package/dist/{types-DP5yQZQU.d.cts → types-D_H2f-wF.d.cts} +1 -1
  196. package/dist/{types-VX_9je7w.d.ts → types-D_TzdBsK.d.ts} +1 -1
  197. package/dist/{types-gzIpsUDE.d.cts → types-ITRQFAir.d.cts} +26 -1
  198. package/dist/{types-gzIpsUDE.d.ts → types-ITRQFAir.d.ts} +26 -1
  199. package/dist/undo/index.d.cts +2 -2
  200. package/dist/undo/index.d.ts +2 -2
  201. package/dist/undo.cjs +7 -3
  202. package/dist/undo.cjs.map +1 -1
  203. package/dist/undo.js +3 -3
  204. package/package.json +1 -1
  205. package/dist/chunk-36MKPTVD.js.map +0 -1
  206. package/dist/chunk-3HVYUMQF.js.map +0 -1
  207. package/dist/chunk-3UUF5KKZ.js.map +0 -1
  208. package/dist/chunk-5JLTXHX6.js.map +0 -1
  209. package/dist/chunk-5ZWNCHZS.js.map +0 -1
  210. package/dist/chunk-AXWMWYH5.js.map +0 -1
  211. package/dist/chunk-CS3CHGYC.js.map +0 -1
  212. package/dist/chunk-CZV3WUW5.js.map +0 -1
  213. package/dist/chunk-FCXSR7I5.js.map +0 -1
  214. package/dist/chunk-G6CRHFWU.js.map +0 -1
  215. package/dist/chunk-GVTBMJU6.js.map +0 -1
  216. package/dist/chunk-HOZCDDRA.js.map +0 -1
  217. package/dist/chunk-JLHVQWOV.js.map +0 -1
  218. package/dist/chunk-LQB42OSA.js.map +0 -1
  219. package/dist/chunk-MIDZWKIF.js.map +0 -1
  220. package/dist/chunk-OHNGURUJ.js.map +0 -1
  221. package/dist/chunk-R4XXOGQH.js.map +0 -1
  222. package/dist/chunk-RVMM4BHK.js.map +0 -1
  223. package/dist/chunk-VFWFT3OK.js.map +0 -1
  224. package/dist/chunk-VMRUW4B4.js.map +0 -1
  225. package/dist/chunk-VOCUGTZB.js.map +0 -1
  226. package/dist/chunk-Z5NL5D4J.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/catalog.ts"],"names":[],"mappings":"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","file":"chunk-CS3CHGYC.js","sourcesContent":["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-catalog` — a Stripe catalog with\n * NO UI surface. The adapter exposes the catalog's STORES + operations (not UI\n * getters/setters), and the tools are CRUD over products / prices + checkout +\n * Stripe sync. Mutations still funnel through `wrapToolWithActivity` so presence\n * + undo compose, and the destructive delete is `pendingMode`-gated.\n *\n * The adapter shapes below are STRUCTURAL mirrors of fancy-catalog's public\n * `Catalog` + store interfaces, defined LOCALLY so this bridge builds with the\n * sibling package absent (it's an optional peer). A real `Catalog` instance is\n * assignable to `CatalogBridgeAdapter` with no import — TypeScript is structural.\n */\n\n/** Minimal product shape crossing the MCP wire (mirror of fancy-catalog `Product`). */\nexport type CatalogProduct = {\n id: string;\n name: string;\n description?: string | null;\n active?: boolean;\n lookupKey?: string | null;\n externalId?: string | null;\n metadata?: Record<string, unknown> | null;\n [k: string]: unknown;\n};\n\n/** Minimal price shape crossing the MCP wire (mirror of fancy-catalog `Price`). */\nexport type CatalogPrice = {\n id: string;\n productId: string;\n active?: boolean;\n currency: string;\n unitAmount: number;\n type: \"recurring\" | \"one_time\";\n externalId?: string | null;\n [k: string]: unknown;\n};\n\n/** Common checkout args (mirror of fancy-catalog `CheckoutArgs`). */\nexport type CatalogCheckoutArgs = {\n customer?: string;\n successUrl: string;\n cancelUrl: string;\n metadata?: Record<string, string>;\n /** One-time checkouts only. */\n quantity?: number;\n};\n\n/**\n * Adapter = the catalog instance / stores. A live `Catalog` from fancy-catalog\n * satisfies this directly (`catalog.products`, `catalog.createProduct`, …); a\n * host can also hand-roll one over its own persistence.\n */\nexport type CatalogBridgeAdapter = {\n /** Stable id for this catalog instance (multiple catalogs ⇒ distinct ids). */\n id?: string;\n /** Display label for logs / presence. */\n title?: string;\n /** Optional fancy-screens screen id (usually unset — this is headless). */\n screenId?: string;\n\n /** Product store — `catalog.products`. */\n products: {\n find(id: string, opts?: { withTrashed?: boolean }): CatalogProduct | null | Promise<CatalogProduct | null>;\n all(opts?: { withTrashed?: boolean }): CatalogProduct[] | Promise<CatalogProduct[]>;\n remove(id: string): void | Promise<void>;\n };\n /** Price store — `catalog.prices`. */\n prices: {\n find(id: string, opts?: { withTrashed?: boolean }): CatalogPrice | null | Promise<CatalogPrice | null>;\n forProduct(productId: string, opts?: { withTrashed?: boolean }): CatalogPrice[] | Promise<CatalogPrice[]>;\n all(opts?: { withTrashed?: boolean }): CatalogPrice[] | Promise<CatalogPrice[]>;\n remove(id: string): void | Promise<void>;\n };\n\n /** Authoring helpers — `catalog.createProduct` / `catalog.createPrice` (ULIDs auto-assigned). */\n createProduct(input: Partial<CatalogProduct> & { name: string }): Promise<CatalogProduct> | CatalogProduct;\n createPrice(\n input: Partial<CatalogPrice> & { productId: string; currency: string; unitAmount: number; type: \"recurring\" | \"one_time\" },\n ): Promise<CatalogPrice> | CatalogPrice;\n\n /** Stripe sync — `catalog.syncProductAndPrices`. Optional (no-op when absent). */\n syncProductAndPrices?(product: CatalogProduct): Promise<CatalogProduct> | CatalogProduct;\n /** Connection test — `catalog.testConnection`. Optional. */\n testConnection?(): Promise<{ success: boolean; message: string; productCount?: number }> | { success: boolean; message: string; productCount?: number };\n\n /** Hosted Checkout — `catalog.getSubscriptionCheckoutUrl` / `getOneTimeCheckoutUrl`. Optional. */\n getSubscriptionCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;\n getOneTimeCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;\n};\n\nexport type CatalogBridgeOptions = {\n adapter: CatalogBridgeAdapter;\n /** Identity stamped on activity + undo entries. */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Trust-but-verify. When on (default), destructive ops (`catalog_delete_product`,\n * `catalog_delete_price`) route through `adapter`-less staging: they require an\n * explicit `confirm: true` arg OR a host `confirm` callback. Read + create +\n * checkout-url tools are unaffected.\n */\n pendingMode?: boolean;\n /** Host confirm hook for destructive ops (pendingMode). Resolves true to proceed. */\n confirm?: (req: { action: string; id: string; label: 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 * registerCatalogBridge — full MCP tool set over a headless Stripe catalog.\n *\n * catalog_list_products list products ({ id, name, active, priceCount })\n * catalog_get_product full product JSON + its prices\n * catalog_create_product create a product (ULID auto-assigned)\n * catalog_delete_product soft-delete a product (pendingMode-gated, undoable*)\n * catalog_list_prices list a product's prices (or all)\n * catalog_create_price create a price under a product\n * catalog_delete_price soft-delete a price (pendingMode-gated)\n * catalog_sync_product push a product + its prices to Stripe\n * catalog_test_connection verify the Stripe connection\n * catalog_create_checkout build a hosted Checkout URL for a price\n *\n * *delete undo is best-effort: stores expose soft-delete (`remove`) but no\n * un-delete, so the undo closure re-creates from the captured snapshot.\n */\nexport function registerCatalogBridge(host: ToolHost, options: CatalogBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const catalogId = adapter.id ?? \"catalog\";\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 ?? catalogId,\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 /** Stage a destructive op behind the human (pendingMode). Returns null to proceed, or an errorResult to block. */\n const guardDestructive = async (action: string, id: string, label: string, hasConfirmArg: boolean) => {\n if (!pendingMode) return null;\n if (options.confirm) {\n const ok = await options.confirm({ action, id, label });\n return ok ? null : errorResult(`Declined: ${action} ${id} (human did not confirm).`);\n }\n // No host confirm hook → require an explicit confirm:true arg as the staged ack.\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 tools ──────────────────────────────────────────────────────────\n\n reg(\n \"catalog_list_products\",\n \"List products: { id, name, active, lookupKey, priceCount }. Pass withTrashed:true to include soft-deleted.\",\n { withTrashed: { type: \"boolean\" } },\n [],\n async (args) => {\n const products = await adapter.products.all({ withTrashed: args.withTrashed === true });\n const list = await Promise.all(\n products.map(async (p) => ({\n id: p.id,\n name: p.name,\n active: p.active ?? true,\n lookupKey: p.lookupKey ?? null,\n priceCount: (await adapter.prices.forProduct(p.id)).length,\n })),\n );\n return textResult(JSON.stringify(list, null, 2), list);\n },\n false,\n );\n\n reg(\n \"catalog_get_product\",\n \"Read a product's full JSON plus its prices.\",\n { id: { type: \"string\" }, withTrashed: { type: \"boolean\" } },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });\n if (!product) return errorResult(`No product with id ${id}`);\n const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });\n const out = { product, prices };\n return textResult(JSON.stringify(out, null, 2), out);\n },\n false,\n );\n\n reg(\n \"catalog_list_prices\",\n \"List prices for a product (pass productId), or every price (omit it).\",\n { productId: { type: \"string\" }, withTrashed: { type: \"boolean\" } },\n [],\n async (args) => {\n const withTrashed = args.withTrashed === true;\n const prices = args.productId !== undefined\n ? await adapter.prices.forProduct(str(args.productId), { withTrashed })\n : await adapter.prices.all({ withTrashed });\n const list = prices.map((p) => ({\n id: p.id,\n productId: p.productId,\n currency: p.currency,\n unitAmount: p.unitAmount,\n type: p.type,\n active: p.active ?? true,\n externalId: p.externalId ?? null,\n }));\n return textResult(JSON.stringify(list, null, 2), list);\n },\n false,\n );\n\n // ─── Create tools ────────────────────────────────────────────────────────\n\n reg(\n \"catalog_create_product\",\n \"Create a product. `name` is required; id (ULID) is auto-assigned. Returns the created product.\",\n {\n name: { type: \"string\" },\n description: { type: \"string\" },\n active: { type: \"boolean\" },\n lookupKey: { type: \"string\" },\n metadata: { type: \"object\" },\n },\n [\"name\"],\n async (args) => {\n const name = str(args.name);\n if (!name) return errorResult(\"name is required.\");\n const product = await adapter.createProduct({\n name,\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.active !== undefined ? { active: args.active === true } : {}),\n ...(args.lookupKey !== undefined ? { lookupKey: str(args.lookupKey) } : {}),\n ...(args.metadata && typeof args.metadata === \"object\" ? { metadata: args.metadata as Record<string, unknown> } : {}),\n });\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: catalogId,\n action: \"catalog_create_product\",\n label: `Created product ${product.id} (${product.name})`,\n undo: () => void adapter.products.remove(product.id),\n redo: () => void adapter.createProduct({ ...product }),\n });\n return textResult(`Created product ${product.id} (${product.name})`, product);\n },\n (args) => target(undefined, `create product ${str(args.name)}`),\n );\n\n reg(\n \"catalog_create_price\",\n \"Create a price under a product. unitAmount is integer minor units (cents). type is 'recurring' | 'one_time'.\",\n {\n productId: { type: \"string\" },\n currency: { type: \"string\", description: \"ISO-4217, e.g. 'USD'.\" },\n unitAmount: { type: \"number\", description: \"Price in cents.\" },\n type: { type: \"string\", enum: [\"recurring\", \"one_time\"] },\n recurringInterval: { type: \"string\", description: \"'month' | 'year' | … (recurring only).\" },\n nickname: { type: \"string\" },\n lookupKey: { type: \"string\" },\n metadata: { type: \"object\" },\n },\n [\"productId\", \"currency\", \"unitAmount\", \"type\"],\n async (args) => {\n const productId = str(args.productId);\n const product = await adapter.products.find(productId);\n if (!product) return errorResult(`No product with id ${productId}`);\n const type = str(args.type) as \"recurring\" | \"one_time\";\n if (type !== \"recurring\" && type !== \"one_time\") return errorResult(\"type must be 'recurring' or 'one_time'.\");\n const price = await adapter.createPrice({\n productId,\n currency: str(args.currency),\n unitAmount: num(args.unitAmount),\n type,\n ...(args.recurringInterval !== undefined ? { recurringInterval: str(args.recurringInterval) } : {}),\n ...(args.nickname !== undefined ? { nickname: str(args.nickname) } : {}),\n ...(args.lookupKey !== undefined ? { lookupKey: str(args.lookupKey) } : {}),\n ...(args.metadata && typeof args.metadata === \"object\" ? { metadata: args.metadata as Record<string, unknown> } : {}),\n });\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: catalogId,\n action: \"catalog_create_price\",\n label: `Created price ${price.id} on ${productId}`,\n undo: () => void adapter.prices.remove(price.id),\n redo: () => void adapter.createPrice({ ...price }),\n });\n return textResult(`Created ${type} price ${price.id} on ${productId}`, price);\n },\n (args) => target(str(args.productId), `create price on ${str(args.productId)}`),\n );\n\n // ─── Destructive tools (pendingMode-gated) ───────────────────────────────\n\n reg(\n \"catalog_delete_product\",\n \"Soft-delete a product (preserves financial history). Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { id: { type: \"string\" }, confirm: { type: \"boolean\" } },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const product = await adapter.products.find(id, { withTrashed: true });\n if (!product) return errorResult(`No product with id ${id}`);\n const blocked = await guardDestructive(\"catalog_delete_product\", id, product.name, args.confirm === true);\n if (blocked) return blocked;\n const snapshot = { ...product };\n await adapter.products.remove(id);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: catalogId,\n action: \"catalog_delete_product\",\n label: `Deleted product ${id} (${product.name})`,\n undo: () => void adapter.createProduct({ ...snapshot }),\n redo: () => void adapter.products.remove(id),\n });\n return textResult(`Deleted product ${id}`, { id });\n },\n (args) => target(str(args.id), `delete product ${str(args.id)}`),\n );\n\n reg(\n \"catalog_delete_price\",\n \"Soft-delete a price (mirrors Stripe archiving). Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { id: { type: \"string\" }, confirm: { type: \"boolean\" } },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const price = await adapter.prices.find(id, { withTrashed: true });\n if (!price) return errorResult(`No price with id ${id}`);\n const blocked = await guardDestructive(\"catalog_delete_price\", id, id, args.confirm === true);\n if (blocked) return blocked;\n const snapshot = { ...price };\n await adapter.prices.remove(id);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: catalogId,\n action: \"catalog_delete_price\",\n label: `Deleted price ${id}`,\n undo: () => void adapter.createPrice({ ...snapshot }),\n redo: () => void adapter.prices.remove(id),\n });\n return textResult(`Deleted price ${id}`, { id });\n },\n (args) => target(str(args.id), `delete price ${str(args.id)}`),\n );\n\n // ─── Stripe sync ─────────────────────────────────────────────────────────\n\n reg(\n \"catalog_sync_product\",\n \"Push a product + its prices to Stripe (creates/updates the Stripe Product + Prices, stamps external ids).\",\n { id: { type: \"string\" } },\n [\"id\"],\n async (args) => {\n if (!adapter.syncProductAndPrices) return errorResult(\"Host did not wire Stripe sync.\");\n const id = str(args.id);\n const product = await adapter.products.find(id);\n if (!product) return errorResult(`No product with id ${id}`);\n const synced = await adapter.syncProductAndPrices(product);\n return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? \"no external id\"})`, synced);\n },\n (args) => target(str(args.id), `sync product ${str(args.id)}`),\n );\n\n reg(\n \"catalog_test_connection\",\n \"Verify the Stripe connection — returns { success, message, productCount? }.\",\n {},\n [],\n async () => {\n if (!adapter.testConnection) return errorResult(\"Host did not wire a Stripe connection test.\");\n const result = await adapter.testConnection();\n return textResult(JSON.stringify(result, null, 2), result);\n },\n false,\n );\n\n // ─── Checkout ────────────────────────────────────────────────────────────\n\n reg(\n \"catalog_create_checkout\",\n \"Build a hosted Stripe Checkout URL for a price. Recurring prices → subscription; one-time → payment (pass quantity). Requires the price be synced to Stripe first.\",\n {\n priceId: { type: \"string\" },\n successUrl: { type: \"string\" },\n cancelUrl: { type: \"string\" },\n customer: { type: \"string\", description: \"Stripe customer id (optional — Checkout collects one if omitted).\" },\n quantity: { type: \"number\", description: \"One-time checkouts only. Default 1.\" },\n metadata: { type: \"object\" },\n },\n [\"priceId\", \"successUrl\", \"cancelUrl\"],\n async (args) => {\n const priceId = str(args.priceId);\n const price = await adapter.prices.find(priceId);\n if (!price) return errorResult(`No price with id ${priceId}`);\n const checkoutArgs: CatalogCheckoutArgs = {\n successUrl: str(args.successUrl),\n cancelUrl: str(args.cancelUrl),\n ...(args.customer !== undefined ? { customer: str(args.customer) } : {}),\n ...(args.metadata && typeof args.metadata === \"object\" ? { metadata: args.metadata as Record<string, string> } : {}),\n };\n let url: string;\n if (price.type === \"recurring\") {\n if (!adapter.getSubscriptionCheckoutUrl) return errorResult(\"Host did not wire subscription checkout.\");\n url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);\n } else {\n if (!adapter.getOneTimeCheckoutUrl) return errorResult(\"Host did not wire one-time checkout.\");\n url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num(args.quantity, 1) });\n }\n return textResult(url || \"(no url)\", { priceId, type: price.type, url });\n },\n (args) => target(str(args.priceId), `checkout ${str(args.priceId)}`),\n );\n\n return {\n id: `catalog:${catalogId}`,\n title: adapter.title ?? \"Catalog\",\n dispose: () => {\n for (const d of disposers.splice(0)) d();\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/mcp/types.ts","../src/mcp/tool-host.ts","../src/mcp/server.ts"],"names":[],"mappings":"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","file":"chunk-CZV3WUW5.js","sourcesContent":["/**\n * Minimal MCP (Model Context Protocol) types — covers the subset this\n * package implements: initialize, tools/list, tools/call, plus JSON-RPC.\n *\n * Aligned with the public MCP spec but trimmed to v0.1 needs. See\n * https://spec.modelcontextprotocol.io/ for the full surface.\n */\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | { [key: string]: JsonValue }\n | JsonValue[];\n\nexport type JsonObject = { [key: string]: JsonValue };\n\nexport type JsonRpcId = string | number | null;\n\nexport type JsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: JsonObject;\n};\n\nexport type JsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: JsonObject;\n};\n\nexport type JsonRpcSuccess = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result: JsonValue;\n};\n\nexport type JsonRpcError = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n error: { code: number; message: string; data?: JsonValue };\n};\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\nexport const JSONRPC_PARSE_ERROR = -32700;\nexport const JSONRPC_INVALID_REQUEST = -32600;\nexport const JSONRPC_METHOD_NOT_FOUND = -32601;\nexport const JSONRPC_INVALID_PARAMS = -32602;\nexport const JSONRPC_INTERNAL_ERROR = -32603;\n\nexport type ServerCapabilities = {\n tools?: { listChanged?: boolean };\n resources?: { listChanged?: boolean; subscribe?: boolean };\n prompts?: { listChanged?: boolean };\n logging?: Record<string, never>;\n experimental?: Record<string, JsonValue>;\n};\n\nexport type ServerInfo = {\n name: string;\n version: string;\n title?: string;\n};\n\nexport type InitializeResult = {\n protocolVersion: string;\n capabilities: ServerCapabilities;\n serverInfo: ServerInfo;\n instructions?: string;\n};\n\nexport type ToolInputSchema = {\n /** The JSON Schema dialect, when a server states it (e.g. draft-07). */\n $schema?: string;\n type: \"object\";\n properties?: Record<string, JsonValue>;\n required?: string[];\n additionalProperties?: boolean;\n};\n\n/** Behaviour hints a client may use when presenting or gating a tool. */\nexport type ToolAnnotations = {\n title?: string;\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n idempotentHint?: boolean;\n openWorldHint?: boolean;\n};\n\n/**\n * A tool as `tools/list` reports it. Every field is passed to the client\n * verbatim, so the optional ones below are the spec's, not extensions.\n */\nexport type ToolDefinition = {\n name: string;\n title?: string;\n description?: string;\n inputSchema: ToolInputSchema;\n /** JSON Schema for `structuredContent`, when the tool returns it. */\n outputSchema?: ToolInputSchema;\n annotations?: ToolAnnotations;\n /** 2025-11-25: whether the tool may run as a task. */\n execution?: { taskSupport?: \"forbidden\" | \"optional\" | \"required\" };\n _meta?: { [key: string]: JsonValue };\n};\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"image\"; data: string; mimeType: string }\n | { type: \"resource\"; resource: { uri: string; text?: string; mimeType?: string } };\n\nexport type CallToolResult = {\n content: ContentBlock[];\n isError?: boolean;\n /** Structured tool output — non-spec but useful for typed bridges. */\n structuredContent?: JsonValue;\n};\n\n/** Handler signature for a tool registered on the MicroMcpServer. */\nexport type ToolCallContext = { transport?: unknown };\nexport type ToolHandler = (args: JsonObject, context?: ToolCallContext) => Promise<CallToolResult> | CallToolResult;\n\n/** Internal record kept by the server. */\nexport type RegisteredTool = {\n definition: ToolDefinition;\n handler: ToolHandler;\n};\n\nexport const MCP_PROTOCOL_VERSION = \"2025-06-18\";\n","import type {\n CallToolResult,\n JsonObject,\n RegisteredTool,\n ToolDefinition,\n ToolHandler,\n} from \"./types\";\n\n/**\n * ToolHost — the minimal surface a bridge needs to register its tools.\n *\n * Bridges (whiteboard, flow, sheets, code, charts, screens, scene, form)\n * speak only through this interface. The MCP server implements it\n * alongside its transport / JSON-RPC duties, and the standalone\n * {@link ToolRegistry} implements it for in-process agents that don't\n * need any of MCP's wire framing.\n *\n * Net effect: every bridge works equally well behind an MCP server\n * (browser ↔ external agents over SSE) or behind a plain registry\n * (in-process agent calling `host.callTool(\"sheet_set_cell\", { … })`).\n */\nexport interface ToolHost {\n /** Register a tool. Returns a disposer that unregisters it. */\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void;\n\n /** Look up an already-registered tool's definition + handler, or null. */\n getTool(name: string): RegisteredTool | null;\n\n /** Snapshot of all currently-registered tool definitions. */\n listTools(): ToolDefinition[];\n\n /**\n * Invoke a registered tool directly, bypassing any transport layer.\n * Throws if no tool is registered under `name`.\n *\n * This is the single entry point in-process agents use to drive the\n * surface — no JSON-RPC framing, no transport plumbing.\n */\n callTool(name: string, args?: JsonObject): Promise<CallToolResult>;\n}\n\n/**\n * Standalone in-memory ToolHost. Use this when no MCP server is needed —\n * e.g. an in-process agent that just wants to register the same bridges\n * and call them directly.\n *\n * Example:\n *\n * const host = new ToolRegistry();\n * registerSheetsBridge(host, { adapter });\n * const result = await host.callTool(\"sheet_set_cell\", { address: \"B3\", value: 42 });\n *\n * Pair with a MicroMcpServer in the same app to expose the same tools\n * to remote agents over SSE while in-process agents still get\n * zero-overhead direct calls.\n */\nexport class ToolRegistry implements ToolHost {\n protected readonly tools = new Map<string, RegisteredTool>();\n\n /**\n * Tools that existed and were withdrawn, kept so a call that races an unmount\n * can say WHICH thing happened.\n *\n * The tool surface is dynamic by design — \"site tools always, page tools while\n * mounted\" — so an agent deciding to call a tool while the human navigates\n * away is normal traffic, not an edge case. Reporting that as `Unknown tool`\n * is the least useful thing available: it reads as \"the agent is broken\" or\n * \"you asked for something imaginary\", when the truth is \"that surface just\n * closed\".\n *\n * Names only. Nothing about the handler is retained, so this cannot keep a\n * disposed surface alive.\n */\n protected readonly withdrawn = new Set<string>();\n\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void {\n this.tools.set(definition.name, { definition, handler });\n // A remounted surface must stop apologising for a previous unmount.\n this.withdrawn.delete(definition.name);\n this.onToolsChanged();\n return () => {\n if (this.tools.delete(definition.name)) {\n this.withdrawn.add(definition.name);\n this.onToolsChanged();\n }\n };\n }\n\n /** Why `name` is not callable, phrased for whoever has to act on it. */\n protected missingToolMessage(name: string): string {\n return this.withdrawn.has(name)\n ? `Tool \"${name}\" was withdrawn: the surface it targets is no longer mounted. `\n + `Call tools/list for the current surface — the site-wide tools remain available.`\n : `Unknown tool: ${name}`;\n }\n\n getTool(name: string): RegisteredTool | null {\n return this.tools.get(name) ?? null;\n }\n\n listTools(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((t) => t.definition);\n }\n\n async callTool(name: string, args: JsonObject = {}): Promise<CallToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new Error(this.missingToolMessage(name));\n }\n return tool.handler(args);\n }\n\n /**\n * Hook for subclasses (e.g. MicroMcpServer) to notify subscribers\n * when the tool catalog changes. Default no-op.\n */\n protected onToolsChanged(): void {}\n}\n","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 * The protocol revisions this server speaks, NEWEST FIRST.\n *\n * `initialize` echoes the client's requested revision when it is in this\n * list, and answers the first entry otherwise — the spec's rule, which leaves\n * the client to decide whether it can live with the answer.\n *\n * Defaults to `[MCP_PROTOCOL_VERSION]`: one revision, answered whatever the\n * client asks, which is exactly what this server did before the option\n * existed. Only list a revision the tools you register are correct under.\n */\n protocolVersions?: readonly 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 /**\n * Transports owed a `tools/list_changed` at the end of this tick. Empty when\n * none is scheduled. See {@link scheduleListChangedNotification}.\n */\n private listChangedOwed = new Set<Transport>();\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n readonly protocolVersions: readonly 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 if (options.protocolVersions && options.protocolVersions.length === 0) {\n // No answer exists for a client's initialize. Fail here, next to the\n // mistake, rather than in a handshake nobody is watching.\n throw new Error(\"MicroMcpServer: protocolVersions is empty — a server must speak at least one protocol revision.\");\n }\n this.protocolVersions = options.protocolVersions ? [...options.protocolVersions] : [MCP_PROTOCOL_VERSION];\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: this.negotiate(params?.protocolVersion),\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 /** The revision to answer `initialize` with: the one asked for if spoken, else the newest. */\n private negotiate(requested: unknown): string {\n return typeof requested === \"string\" && this.protocolVersions.includes(requested)\n ? requested\n : this.protocolVersions[0];\n }\n\n /**\n * Tell the transports that SAW the old tool list that it changed.\n *\n * Changes in one tick coalesce into one notification. The recipients are the\n * transports attached at the moment of a change, not at the moment the\n * notification goes out: a transport attached afterwards never had the old\n * list, so \"your list is stale\" is noise to it — and on stdio, where a host\n * builds the server and attaches stdin/stdout in the same tick, it was the\n * first frame a client received, before it had even sent `initialize`.\n */\n private scheduleListChangedNotification(): void {\n if (this.transports.size === 0) return;\n const scheduled = this.listChangedOwed.size > 0;\n for (const t of this.transports) this.listChangedOwed.add(t);\n if (scheduled) return;\n queueMicrotask(() => {\n const owed = this.listChangedOwed;\n this.listChangedOwed = new Set();\n for (const t of owed) {\n // Detached since the change: it is not listening any more.\n if (this.transports.has(t)) t.send({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n }\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/code.ts"],"names":[],"mappings":"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","file":"chunk-FCXSR7I5.js","sourcesContent":["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 { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/** Streaming append is a UX nicety; large content must use code_set_value. */\nconst MAX_STREAM_CHARS = 10_000;\n\n/**\n * Adapter the host wires to a fancy-code CodeEditor (typically via the\n * useCodeEditor hook's context value).\n */\nexport type CodeBridgeAdapter = {\n /** Stable id for this editor instance. */\n id: string;\n /** Display label. */\n title?: string;\n /** Optional fancy-screens screen id. */\n screenId?: string;\n /** Read the current document text. */\n getValue: () => string;\n /** Replace the document. */\n setValue: (value: string) => void;\n /** Read the current selection text (empty string if none). */\n getSelection?: () => string;\n /** Replace the current selection with text. */\n replaceSelection?: (text: string) => void;\n /** Programmatic focus. */\n focus?: () => void;\n /** Read / set the active language. */\n getLanguage?: () => string;\n /** Set the active language. */\n setLanguage?: (lang: string) => void;\n};\n\nexport type CodeBridgeOptions = {\n adapter: CodeBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerCodeBridge — schema-aware MCP access to a single CodeEditor.\n * Tools cover read, full replace, append, selection replace, language\n * switch, and a streaming append helper for \"type characters into the\n * editor over time\" UX.\n */\nexport function registerCodeBridge(\n host: ToolHost,\n options: CodeBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // agent_undo / agent_redo / agent_history are registered whenever any bridge\n // mounts, so undo availability doesn't hinge on which bridges are co-present.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target: AgentTarget = {\n kind: \"code\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n // Record a reversible document edit so agent_undo/redo actually work for code\n // (they were registered but the code bridge pushed nothing — false\n // recoverability). Captures the whole-document before/after; restore is a\n // full setValue either way.\n const recordUndo = (action: string, label: string, prevValue: string, nextValue: string): void => {\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"code\",\n action,\n label,\n undo: () => adapter.setValue(prevValue),\n redo: () => adapter.setValue(nextValue),\n });\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"code\",\n screenId: adapter.screenId,\n resolveTarget: () => target,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false },\n },\n final as any,\n ),\n );\n };\n\n reg(\n \"code_describe\",\n `Describe the editor \"${adapter.id}\" — language + length + has-selection.`,\n {},\n [],\n () => {\n const value = adapter.getValue();\n const language = adapter.getLanguage?.() ?? \"unknown\";\n const summary = { id: adapter.id, language, length: value.length, lines: value.split(\"\\n\").length };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"code_get_value\",\n \"Read the full document text.\",\n {},\n [],\n () => {\n const value = adapter.getValue();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_get_selection\",\n \"Read the currently-selected text (empty string if no selection).\",\n {},\n [],\n () => {\n if (!adapter.getSelection) return errorResult(\"Host did not provide getSelection.\");\n const value = adapter.getSelection();\n return textResult(value, { value });\n },\n false,\n );\n\n reg(\n \"code_set_value\",\n \"Replace the entire document.\",\n { value: { type: \"string\" } },\n [\"value\"],\n (args) => {\n const value = String(args.value ?? \"\");\n const prev = adapter.getValue();\n adapter.setValue(value);\n recordUndo(\"code_set_value\", \"Replace document\", prev, value);\n return textResult(`Replaced document (${value.length} chars)`, { length: value.length });\n },\n true,\n );\n\n reg(\n \"code_append\",\n \"Append text to the end of the document.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n const text = String(args.text ?? \"\");\n const prev = adapter.getValue();\n const next = prev + text;\n adapter.setValue(next);\n recordUndo(\"code_append\", `Append ${text.length} chars`, prev, next);\n return textResult(`Appended ${text.length} chars`, { length: next.length });\n },\n true,\n );\n\n reg(\n \"code_stream_append\",\n \"Type characters into the document one at a time so the human can read it forming. Returns when streaming finishes.\",\n {\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n },\n [\"text\"],\n async (args) => {\n const text = String(args.text ?? \"\");\n if (text.length > MAX_STREAM_CHARS) {\n return errorResult(\n `Text too long to stream (${text.length} > ${MAX_STREAM_CHARS}). Use code_set_value / code_append for large content.`,\n );\n }\n const cps = Math.max(1, Number(args.cps ?? 25));\n const interval = Math.max(8, Math.round(1000 / cps));\n const start = adapter.getValue();\n for (let i = 1; i <= text.length; i++) {\n adapter.setValue(start + text.slice(0, i));\n if (i < text.length) await new Promise((r) => setTimeout(r, interval));\n }\n recordUndo(\"code_stream_append\", `Append ${text.length} chars`, start, start + text);\n return textResult(`Streamed ${text.length} chars`, { length: text.length });\n },\n true,\n );\n\n reg(\n \"code_replace_selection\",\n \"Replace the currently-selected text with the supplied text.\",\n { text: { type: \"string\" } },\n [\"text\"],\n (args) => {\n if (!adapter.replaceSelection) return errorResult(\"Host did not provide replaceSelection.\");\n // No selection-range API, so restore is whole-document before/after.\n const prev = adapter.getValue();\n adapter.replaceSelection(String(args.text ?? \"\"));\n recordUndo(\"code_replace_selection\", \"Replace selection\", prev, adapter.getValue());\n return textResult(\"Selection replaced\", { });\n },\n true,\n );\n\n reg(\n \"code_set_language\",\n \"Switch the active syntax highlighting / formatter.\",\n { language: { type: \"string\", description: \"e.g. 'javascript', 'php', 'sql'.\" } },\n [\"language\"],\n (args) => {\n if (!adapter.setLanguage) return errorResult(\"Host did not provide setLanguage.\");\n const lang = String(args.language ?? \"\");\n const prevLang = adapter.getLanguage?.();\n adapter.setLanguage(lang);\n if (prevLang !== undefined) {\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"code\",\n action: \"code_set_language\",\n label: `Language → ${lang}`,\n undo: () => adapter.setLanguage?.(prevLang),\n redo: () => adapter.setLanguage?.(lang),\n });\n }\n return textResult(`Language → ${lang}`, { language: lang });\n },\n true,\n );\n\n reg(\n \"code_focus\",\n \"Move browser focus to the editor.\",\n {},\n [],\n () => {\n if (!adapter.focus) return errorResult(\"Host did not provide focus.\");\n adapter.focus();\n return textResult(\"Focused\", { });\n },\n // Focus is not a document mutation — don't broadcast it as one or log undo.\n false,\n );\n\n return {\n id: `code:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/passkeys.ts"],"names":[],"mappings":"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","file":"chunk-G6CRHFWU.js","sourcesContent":["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 * Bridge for `@particle-academy/fancy-passkeys-ui` — the **management** half of\n * a passkey (WebAuthn) surface, and only that half.\n *\n * ## The absence is the design\n *\n * There is **no tool here that completes an authentication or registration\n * ceremony**, and there must never be one. Not `passkey_authenticate`, not\n * `passkey_sign_in`, not `passkey_complete`, not a \"headless\" variant behind a\n * flag.\n *\n * The reason is construction, not policy. `navigator.credentials.get()` requires\n * a user gesture and a biometric or PIN — both things only the person at the\n * keyboard has. An agent-drivable passkey login would be a bypass of the exact\n * property that makes a passkey worth more than a password: that possession of\n * the credential cannot be delegated, replayed, or phished. A bridge offering\n * one would quietly turn a phishing-resistant factor back into a bearer token.\n *\n * So the boundary sits where the cryptography already puts it, and the tool set\n * is drawn to match: **read the management surface, rename, propose, ask the\n * human to start a ceremony.** `bridges/__tests__/passkeys.test.ts` asserts the\n * registered tool names against a closed list, so \"finishing\" this bridge with a\n * sign-in tool fails CI rather than shipping.\n *\n * ## What it does do\n *\n * passkey_list the user's credentials (whitelisted fields only)\n * passkey_status browser support + what the surface currently shows\n * passkey_rename relabel one credential, by credential ID (undoable)\n * passkey_revoke **STAGES** a revoke for the human to confirm\n * passkey_begin_enrollment opens the enrollment prompt; returns immediately\n *\n * `passkey_revoke` never revokes. Revoking a passkey is destructive and revoking\n * the last one is a lockout, so the confirming click comes from the human at the\n * surface — there is deliberately **no `pendingMode: false`**, no `confirm: true`\n * argument, and no host hook that turns staging off. On this bridge staging is\n * not a mode.\n *\n * The adapter type is declared LOCALLY (like `features` / `catalog`) so the\n * bridge builds and type-checks with the sibling package absent. A host wiring a\n * live `PasskeyManager` satisfies it structurally, with no import.\n */\n\n/**\n * One credential as the bridge is willing to describe it — the `PasskeySummary`\n * shape both passkey backends already serialise.\n *\n * Everything the server stores that is NOT on this list — the COSE public key,\n * the user handle, the signature counter, the attestation statement and trust\n * path — is absent on purpose, and {@link toSummary} re-projects onto exactly\n * these keys rather than trusting the adapter to have withheld them. A host that\n * hands `list()` its raw ORM model (the obvious thing to do) therefore cannot\n * leak credential material through an MCP tool by accident.\n */\nexport type PasskeySummaryLike = {\n /** base64url credential ID — the handle every action here is keyed by. */\n id: string;\n /** Human-chosen label, or null when the user never named it. */\n name: string | null;\n /** ISO-8601. */\n createdAt: string;\n /** ISO-8601, or null when never used to sign in. */\n lastUsedAt: string | null;\n /** Transport hints (\"internal\", \"hybrid\", \"usb\", …). */\n transports: string[];\n /** True for a synced passkey (BE/BS flags); false means this device only. */\n backedUp: boolean;\n /** Authenticator model id. Stored, never a trust decision. */\n aaguid: string;\n /** ISO-8601 when the signature counter regressed — a suspected clone. */\n clonedAt: string | null;\n};\n\n/** What the browser can do, as the three `./client` predicates report it. */\nexport type PasskeySupport = {\n supported: boolean;\n /** Touch ID / Windows Hello present? `null` while unknown. */\n platformAuthenticator?: boolean | null;\n /** Can the browser offer a passkey from a username field? `null` while unknown. */\n conditionalUi?: boolean | null;\n};\n\n/** A read of what the management surface is currently showing. */\nexport type PasskeySurfaceState = {\n status?: \"idle\" | \"busy\" | \"error\";\n /** `{ code, message }` as carried in surface state — never an Error. */\n error?: { code: string; message: string } | null;\n /** The revoke awaiting a human's confirmation, if any. */\n pendingRevoke?: { id: string; isLastPasskey: boolean } | null;\n /** Credential ID currently being renamed, if any. */\n renamingId?: string | null;\n};\n\n/**\n * Host-provided access to the management surface. Mirrors the props a\n * `PasskeyManager` is already wired with, so a host usually passes the same four\n * callbacks it passed the component.\n */\nexport type PasskeyBridgeAdapter = {\n /** Stable id for this surface instance. Surfaces in activity logs. */\n id?: string;\n title?: string;\n screenId?: string;\n\n /** The signed-in user's credentials. */\n list(): PasskeySummaryLike[] | Promise<PasskeySummaryLike[]>;\n\n /** Relabel one credential. Cosmetic, reversible, and undoable here. */\n rename(input: { id: string; name: string }): void | Promise<void>;\n\n /**\n * **Stage** a revoke for human confirmation — the `pendingRevoke` the surface\n * renders a confirm/cancel dialog for. It must NOT revoke; a host that wires\n * this to a delete call has removed the human from the loop the bridge was\n * built around.\n */\n proposeRevoke(input: { id: string }): PasskeyProposal | Promise<PasskeyProposal>;\n\n /**\n * Open the enrollment prompt on the human's screen and return immediately.\n * The ceremony completes on their authenticator or not at all.\n */\n beginEnrollment?(input: { name?: string }): void | Promise<void>;\n\n /** Browser capability flags, if the host tracks them. */\n support?(): PasskeySupport | Promise<PasskeySupport>;\n\n /** What the surface currently shows. */\n state?(): PasskeySurfaceState | Promise<PasskeySurfaceState>;\n};\n\nexport type PasskeyProposal = { staged: true; isLastPasskey: boolean };\n\nexport type PasskeyBridgeOptions = {\n adapter: PasskeyBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n /**\n * Also route `passkey_rename` through {@link confirm}. Off by default: a\n * rename is cosmetic, reversible and pushed onto the undo stack. Worth turning\n * on where the label itself carries trust — a rogue credential relabelled\n * \"Avery's iPhone\" survives a human's audit of the list.\n */\n confirmRename?: boolean;\n /**\n * Host confirmation hook for renames, when {@link confirmRename} is on.\n *\n * Note there is no revoke case: a revoke is staged into the surface and\n * confirmed there, never through a hook the agent's own host supplies.\n */\n confirm?: (req: { action: \"passkey_rename\"; id: string; name: string }) => boolean | Promise<boolean>;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\n\n/**\n * Project an adapter record onto exactly the public summary fields.\n *\n * Deliberately a whitelist and not a `delete` of known-bad keys: a blacklist has\n * to be updated every time a backend grows a column, and the failure mode of\n * forgetting is silently publishing credential material to every agent in the\n * session.\n */\nfunction toSummary(record: PasskeySummaryLike): PasskeySummaryLike {\n return {\n id: str(record?.id),\n name: typeof record?.name === \"string\" ? record.name : null,\n createdAt: str(record?.createdAt),\n lastUsedAt: typeof record?.lastUsedAt === \"string\" ? record.lastUsedAt : null,\n transports: Array.isArray(record?.transports) ? record.transports.map((t) => String(t)) : [],\n backedUp: record?.backedUp === true,\n aaguid: str(record?.aaguid),\n clonedAt: typeof record?.clonedAt === \"string\" ? record.clonedAt : null,\n };\n}\n\n/**\n * The complete set of tools this bridge may ever register.\n *\n * Exported so the test suite — and anyone auditing what an agent can reach —\n * can assert the registered names against it rather than eyeballing the file.\n */\nexport const PASSKEY_BRIDGE_TOOLS = [\n \"passkey_list\",\n \"passkey_status\",\n \"passkey_rename\",\n \"passkey_revoke\",\n \"passkey_begin_enrollment\",\n] as const;\n\n/**\n * registerPasskeyBridge — MCP tools over a passkey **management** surface.\n *\n * Read the credential list, read browser support and surface state, rename a\n * credential, propose a revoke for the human to confirm, and ask for an\n * enrollment prompt. Nothing signs anyone in; see the file header for why that\n * is a property rather than a gap.\n */\nexport function registerPasskeyBridge(host: ToolHost, options: PasskeyBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const surfaceId = adapter.id ?? \"passkeys\";\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 ?? surfaceId,\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 {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as Record<string, never>,\n required,\n additionalProperties: false,\n },\n },\n final as never,\n ),\n );\n };\n\n const findById = async (id: string): Promise<PasskeySummaryLike | null> =>\n (await adapter.list()).map(toSummary).find((p) => p.id === id) ?? null;\n\n // ─── Read ────────────────────────────────────────────────────────────────\n\n reg(\n \"passkey_list\",\n \"List the signed-in user's passkeys: credential id, label, when it was added and last used, transports, whether it is a synced passkey, and whether the server flagged it as a possible clone. Read-only. Public keys, user handles and signature counters are never returned.\",\n {},\n [],\n async () => {\n const passkeys = (await adapter.list()).map(toSummary);\n return textResult(JSON.stringify(passkeys, null, 2), { passkeys, count: passkeys.length });\n },\n false,\n );\n\n reg(\n \"passkey_status\",\n \"Read what this browser can do (passkey support, a built-in authenticator, autofill sign-in) and what the management surface is currently showing (busy/error, a revoke awaiting confirmation, a rename in progress).\",\n {},\n [],\n async () => {\n const support = adapter.support ? await adapter.support() : null;\n const state = adapter.state ? await adapter.state() : null;\n const out = {\n support,\n state,\n // Said in the payload, not only in the docs: an agent reading this to\n // work out \"how do I sign the user in\" should find the answer here.\n canCompleteCeremony: false,\n note: \"A passkey ceremony needs a user gesture and a biometric or PIN. No tool on this bridge can perform one; ask the human to complete it on their device.\",\n };\n return textResult(JSON.stringify(out, null, 2), out);\n },\n false,\n );\n\n // ─── Rename (undoable) ───────────────────────────────────────────────────\n\n reg(\n \"passkey_rename\",\n \"Rename one passkey, by credential id (from passkey_list). Cosmetic and undoable with agent_undo.\",\n {\n id: { type: \"string\", description: \"base64url credential id.\" },\n name: { type: \"string\", description: \"New label, e.g. 'MacBook Touch ID'. Empty string clears it.\" },\n },\n [\"id\", \"name\"],\n async (args) => {\n const id = str(args.id);\n const name = str(args.name);\n if (!id) return errorResult(\"id is required.\");\n\n const existing = await findById(id);\n if (!existing) return errorResult(`No passkey with id ${id}.`);\n\n if (options.confirmRename) {\n if (!options.confirm) {\n return errorResult(\n \"passkey_rename requires confirmation (confirmRename), but the host wired no confirm hook.\",\n );\n }\n const ok = await options.confirm({ action: \"passkey_rename\", id, name });\n if (!ok) return errorResult(`Declined: rename ${id} (human did not confirm).`);\n }\n\n const previous = existing.name ?? \"\";\n await adapter.rename({ id, name });\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: surfaceId,\n action: \"passkey_rename\",\n label: `Renamed passkey to ${name || \"(unnamed)\"}`,\n undo: () => void adapter.rename({ id, name: previous }),\n redo: () => void adapter.rename({ id, name }),\n });\n\n return textResult(`Renamed passkey ${id} to ${name || \"(unnamed)\"}`, { id, name, previous });\n },\n (args) => target(str(args.id), `rename ${str(args.id)}`),\n );\n\n // ─── Revoke — PROPOSAL ONLY ──────────────────────────────────────────────\n\n reg(\n \"passkey_revoke\",\n \"PROPOSE revoking one passkey. This does NOT revoke it: the request is staged on the surface and the human confirms or cancels there. Revoking the last passkey can lock the user out, and the response says when that is the case so you can tell them before they confirm.\",\n { id: { type: \"string\", description: \"base64url credential id.\" } },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n if (!id) return errorResult(\"id is required.\");\n\n const existing = await findById(id);\n if (!existing) return errorResult(`No passkey with id ${id}.`);\n\n const proposal = await adapter.proposeRevoke({ id });\n const isLastPasskey = proposal?.isLastPasskey === true;\n const out = {\n id,\n name: existing.name,\n staged: true as const,\n awaitingHuman: true as const,\n isLastPasskey,\n };\n\n return textResult(\n isLastPasskey\n ? `Staged a revoke of ${existing.name ?? id}. This is the account's LAST passkey — confirming it removes passkey sign-in entirely. Waiting for the human to confirm or cancel.`\n : `Staged a revoke of ${existing.name ?? id}. Waiting for the human to confirm or cancel on the surface.`,\n out,\n );\n },\n (args) => target(str(args.id), `propose revoke ${str(args.id)}`),\n );\n\n // ─── Enrollment — opens the prompt, never completes it ───────────────────\n\n reg(\n \"passkey_begin_enrollment\",\n \"Ask the surface to start enrolling a new passkey. This only opens the prompt: the ceremony completes on the human's authenticator (Touch ID, Windows Hello, phone, security key) or it does not complete at all. Returns immediately.\",\n { name: { type: \"string\", description: \"Optional label to pre-fill for the new passkey.\" } },\n [],\n async (args) => {\n if (!adapter.beginEnrollment) return errorResult(\"Host did not wire beginEnrollment().\");\n const name = args.name === undefined ? undefined : str(args.name);\n await adapter.beginEnrollment(name === undefined ? {} : { name });\n const out = { awaitingHuman: true as const, ...(name === undefined ? {} : { name }) };\n return textResult(\n \"Enrollment prompt opened. The human has to complete it on their authenticator — there is no tool that can finish it for them.\",\n out,\n );\n },\n (args) => target(undefined, `begin enrollment${args.name ? ` (${str(args.name)})` : \"\"}`),\n );\n\n // ── There is deliberately NO tool below that completes a ceremony. ────────\n // No passkey_authenticate, no passkey_sign_in, no passkey_complete, no\n // passkey_assert. Do not \"finish\" this bridge by adding one — see the header,\n // and see the closed-tool-list test that will fail if you do.\n\n return {\n id: `passkeys:${surfaceId}`,\n title: adapter.title ?? \"Passkeys\",\n dispose: () => {\n for (const d of disposers.splice(0)) d();\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/features.ts"],"names":[],"mappings":"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","file":"chunk-GVTBMJU6.js","sourcesContent":["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 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/screens.ts"],"names":[],"mappings":"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","file":"chunk-HOZCDDRA.js","sourcesContent":["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 { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\nimport { emitActivity } from \"../presence/registry\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Loose snapshot of a screen — what's in fancy-screens' ScreenMeta plus\n * the host's optional activity status. Kept here so this bridge has no\n * hard dep on fancy-screens.\n */\nexport type ScreenSnapshot = {\n id: string;\n title?: string;\n /** Whether this screen is the one the human / agent is looking at. */\n active: boolean;\n /** Optional category / kind (e.g. \"form\", \"whiteboard\"). */\n kind?: string;\n};\n\n/**\n * Spec for a dynamically-created screen. The host's `createScreen`\n * implementation looks up `kind` in its template registry and instantiates\n * the matching surface (form / whiteboard / sheet / chart / markdown / etc.).\n */\nexport type ScreenCreateSpec = {\n id: string;\n title?: string;\n /** Template kind. Hosts decide the catalog. */\n kind: string;\n /** Template-specific config. Form: { fields }. Sheet: { headers }. etc. */\n config?: Record<string, unknown>;\n};\n\n/**\n * What a mutating adapter method may resolve to, to acknowledge (or refuse)\n * a commit. `{ ok: false }` is a refusal the agent can act on: `error` is\n * shown to the agent verbatim, so keep it a human-readable sentence, never a\n * stack trace or an internal path. `code` is a machine-readable hint\n * (e.g. `\"conflict\"`) for the host's own use; it is not shown to the agent.\n */\nexport type ScreensAdapterResult = { ok: true } | { ok: false; error: string; code?: string };\n\n/**\n * Return type of every mutating adapter method. A sync `void` return keeps\n * the original behaviour. A Promise makes the bridge WAIT: the tool reports\n * success, and emits its AgentActivity event, only after the promise\n * resolves. A rejection or an `{ ok: false }` result becomes an error result\n * and emits no activity.\n */\nexport type ScreensAdapterCommit = void | Promise<void | ScreensAdapterResult>;\n\n/**\n * Adapter exposes the host's screen-navigation surface to the bridge.\n * Hosts wire this up against react-router, a custom tab state, or the\n * fancy-screens registry — wherever \"current screen\" lives.\n *\n * The optional create / destroy / update hooks let agents author screens\n * dynamically against a host-defined template catalog.\n *\n * Every mutating method may be sync (`void`) or async (`Promise`); see\n * {@link ScreensAdapterCommit}. Return a Promise when the host's commit is\n * authoritative — persisted, or able to refuse or conflict — so the agent is\n * told the truth instead of \"success\" before anything was committed.\n *\n * This bridge pushes NO undo entries: `agent_undo` cannot revert a screens\n * tool. A host that needs undo for navigation or screen authoring must keep\n * its own history.\n */\nexport type ScreensBridgeAdapter = {\n /** List every available screen. */\n listScreens: () => ScreenSnapshot[];\n /** Read which screen is currently active. */\n getActive: () => string | null;\n /** Navigate to a screen by id. Host updates router / tab state. */\n setActive: (screenId: string) => ScreensAdapterCommit;\n /** Optional: instantiate a new screen from a template + config. */\n createScreen?: (spec: ScreenCreateSpec) => ScreensAdapterCommit;\n /** Optional: remove a previously-created screen. */\n destroyScreen?: (screenId: string) => ScreensAdapterCommit;\n /** Optional: shallow-merge new config into an existing screen. */\n updateScreenContent?: (screenId: string, partial: Record<string, unknown>) => ScreensAdapterCommit;\n /** Optional: enumerate the kinds the host knows how to instantiate. */\n listKinds?: () => Array<{ kind: string; label?: string; description?: string; configSchema?: unknown }>;\n};\n\nexport type ScreensBridgeOptions = {\n adapter: ScreensBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * The agent-facing text for a host failure. Only the message is used — never\n * `stack`, which carries file paths — matching the other bridges. A message\n * that itself embeds stack frames is cut at the first frame. A non-Error\n * rejection (a plain object, a response) has no reliable message, so it gets\n * the fallback rather than \"[object Object]\".\n */\nfunction hostErrorMessage(e: unknown, fallback: string): string {\n let msg: string | undefined;\n if (e instanceof Error) msg = e.message;\n else if (typeof e === \"string\") msg = e;\n else if (e && typeof e === \"object\" && typeof (e as { message?: unknown }).message === \"string\") {\n msg = (e as { message: string }).message;\n }\n const firstFrame = msg ? msg.search(/\\n\\s+at\\s/) : -1;\n if (msg && firstFrame >= 0) msg = msg.slice(0, firstFrame);\n msg = msg?.trim();\n return msg ? msg : fallback;\n}\n\ntype CommitOutcome = { ok: true } | { ok: false; error: string };\n\n/** Run one adapter commit, await it, and normalise every way it can fail. */\nasync function commit(run: () => ScreensAdapterCommit, fallback: string): Promise<CommitOutcome> {\n try {\n const r = await run();\n if (r && typeof r === \"object\" && r.ok === false) {\n return { ok: false, error: hostErrorMessage(r.error, fallback) };\n }\n return { ok: true };\n } catch (e) {\n return { ok: false, error: hostErrorMessage(e, fallback) };\n }\n}\n\n/**\n * registerScreensBridge — top-level navigation bridge so agents can\n * switch between screens (`screens_navigate`) and discover what surfaces\n * exist (`screens_list`, `screens_describe_active`).\n *\n * Pair with the per-surface bridges (whiteboard, form, sheet, etc.) so\n * the agent has both navigation and per-screen control.\n */\nexport function registerScreensBridge(\n host: ToolHost,\n options: ScreensBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // agent_undo / agent_redo / agent_history are registered whenever any bridge\n // mounts, so undo availability doesn't hinge on which bridges are co-present.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target = (screenId: string): AgentTarget => ({\n kind: \"screens\",\n screenId,\n label: `Screen ${screenId}`,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n targetFromArgs?: (args: JsonObject) => AgentTarget,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try { return await handler(args); }\n catch (e) { return errorResult(hostErrorMessage(e, `${name} failed.`)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"screens\",\n resolveTarget: ({ args }) => targetFromArgs?.(args) ?? null,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n reg(\n \"screens_list\",\n \"List every screen the host has registered. Returns id, title, active flag, and optional kind.\",\n {},\n [],\n () => {\n const screens = adapter.listScreens();\n const text = screens\n .map((s) => `${s.active ? \"▸\" : \" \"} ${s.id}${s.title ? ` — ${s.title}` : \"\"}${s.kind ? ` [${s.kind}]` : \"\"}`)\n .join(\"\\n\");\n return textResult(text || \"(no screens)\", { screens, active: adapter.getActive() });\n },\n false,\n );\n\n reg(\n \"screens_describe_active\",\n \"Get the currently-active screen id (or null).\",\n {},\n [],\n () => {\n const active = adapter.getActive();\n return textResult(active ?? \"(none)\", { active });\n },\n false,\n );\n\n reg(\n \"screens_list_kinds\",\n \"List the screen kinds (templates) the host knows how to instantiate. Use this before screens_create to know what's available.\",\n {},\n [],\n () => {\n if (!adapter.listKinds) return errorResult(\"Host did not register a kind catalog. Cannot create screens dynamically.\");\n const kinds = adapter.listKinds();\n const text = kinds.map((k) => `${k.kind}${k.label ? ` — ${k.label}` : \"\"}${k.description ? ` (${k.description})` : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", kinds);\n },\n false,\n );\n\n reg(\n \"screens_create\",\n \"Instantiate a new screen from a template kind + config. Switches the active view to the new screen.\",\n {\n id: { type: \"string\", description: \"Stable screen id. Must be unique.\" },\n title: { type: \"string\" },\n kind: { type: \"string\", description: \"Template kind — call screens_list_kinds for the catalog.\" },\n config: { type: \"object\", description: \"Template-specific config (e.g. { fields: [...] } for a form).\" },\n },\n [\"id\", \"kind\"],\n async (args) => {\n const createScreen = adapter.createScreen;\n if (!createScreen) return errorResult(\"Host did not provide createScreen.\");\n const id = String(args.id);\n const kind = String(args.kind);\n if (adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`Screen ${id} already exists. Use screens_destroy first or pick a fresh id.`);\n }\n const created = await commit(() => createScreen({\n id,\n title: typeof args.title === \"string\" ? args.title : undefined,\n kind,\n config: (args.config && typeof args.config === \"object\") ? args.config as Record<string, unknown> : undefined,\n }), `Host failed to create screen \"${id}\".`);\n // Nothing was created, so there is nothing to activate.\n if (!created.ok) return errorResult(created.error);\n\n const activated = await commit(() => adapter.setActive(id), `Host failed to activate screen \"${id}\".`);\n if (!activated.ok) {\n // Partial commit: the screen EXISTS but is not showing. Reported as an\n // error so an agent branching on isError does not go on to tell the\n // human \"look at the new screen\". The create DID commit, though, and\n // every committed mutation must be observable, so its activity is\n // emitted here by hand (wrapToolWithActivity skips error results).\n const state = { id, kind, created: true, activated: false };\n emitActivity({\n agentId: agent.id,\n agentName: agent.name,\n agentColor: agent.color,\n target: target(id),\n action: \"screens_create\",\n timestamp: Date.now(),\n meta: state,\n });\n return {\n ...errorResult(\n `Screen \"${id}\" was created but not activated: ${activated.error} ` +\n \"The screen exists; do not call screens_create again. \" +\n \"Call screens_navigate to show it, or screens_destroy to remove it.\",\n ),\n structuredContent: state,\n };\n }\n return textResult(`Created ${kind} screen \"${id}\"`, { id, kind });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_destroy\",\n \"Remove a previously-created screen. Active screen falls back to the first remaining one (or null).\",\n { id: { type: \"string\" } },\n [\"id\"],\n async (args) => {\n const destroyScreen = adapter.destroyScreen;\n if (!destroyScreen) return errorResult(\"Host did not provide destroyScreen.\");\n const id = String(args.id);\n if (!adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`No screen with id ${id}`);\n }\n const done = await commit(() => destroyScreen(id), `Host failed to destroy screen \"${id}\".`);\n if (!done.ok) return errorResult(done.error);\n return textResult(`Destroyed screen ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_set_layout\",\n \"Change the layout of an existing composite screen. Layouts: 'single', 'split-h' (left/right), 'split-v' (top/bottom), 'grid-2x2', 'stack' (tabs).\",\n {\n id: { type: \"string\" },\n layout: { type: \"string\", enum: [\"single\", \"split-h\", \"split-v\", \"grid-2x2\", \"stack\"] },\n },\n [\"id\", \"layout\"],\n async (args) => {\n const updateScreenContent = adapter.updateScreenContent;\n if (!updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n const id = String(args.id);\n const done = await commit(\n () => updateScreenContent(id, { layout: String(args.layout) }),\n `Host failed to change the layout of screen \"${id}\".`,\n );\n if (!done.ok) return errorResult(done.error);\n return textResult(`Layout of ${args.id} → ${args.layout}`, { id: args.id, layout: args.layout });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_update_content\",\n \"Merge new config into an existing screen (e.g. add a field to a form, append a sheet column, change chart series).\",\n {\n id: { type: \"string\" },\n partial: { type: \"object\", description: \"Shallow-merged into the screen's config.\" },\n },\n [\"id\", \"partial\"],\n async (args) => {\n const updateScreenContent = adapter.updateScreenContent;\n if (!updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n const id = String(args.id);\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n const done = await commit(() => updateScreenContent(id, partial), `Host failed to update screen \"${id}\".`);\n if (!done.ok) return errorResult(done.error);\n return textResult(`Updated content of ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_navigate\",\n \"Switch the human's view to a different screen. The host updates its router / tab state and re-renders.\",\n { screen: { type: \"string\", description: \"Screen id to activate.\" } },\n [\"screen\"],\n async (args) => {\n const screenId = String(args.screen ?? \"\");\n const screens = adapter.listScreens();\n if (!screens.find((s) => s.id === screenId)) {\n return errorResult(`No screen registered with id \"${screenId}\". Call screens_list first.`);\n }\n const done = await commit(() => adapter.setActive(screenId), `Host failed to navigate to screen \"${screenId}\".`);\n if (!done.ok) return errorResult(done.error);\n return textResult(`Navigated to ${screenId}`, { screen: screenId });\n },\n true,\n (args) => target(String(args.screen ?? \"\")),\n );\n\n return {\n id: \"screens\",\n title: \"Screens\",\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/tui.ts"],"names":[],"mappings":"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","file":"chunk-JLHVQWOV.js","sourcesContent":["import { emitActivity } from \"../presence\";\nimport { errorResult, textResult, type MicroMcpServer, type Transport } from \"../mcp/server\";\nimport type { JsonObject, ToolCallContext } from \"../mcp/types\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { HumanPlusActor, HumanPlusEventStore, HumanPlusPriority } from \"../human-plus/events\";\n\nexport type TuiActionPolicy = \"observe\" | \"execute\" | \"propose\" | \"confirm\" | \"human-only\";\nexport interface TuiSurfaceCommandLike { name: string; description?: string; policy?: TuiActionPolicy; inputSchema?: Record<string, unknown>; invoke(input?: Record<string, unknown>): unknown | Promise<unknown>; }\nexport interface TuiSurfaceLike { id: string; kind: string; label?: string; read(): unknown; commands?: TuiSurfaceCommandLike[]; }\nexport interface TuiSurfaceRegistryLike { list(): TuiSurfaceLike[]; get(id: string): TuiSurfaceLike | undefined; }\nexport interface TuiBridgeOptions {\n registry: TuiSurfaceRegistryLike;\n eventStore: HumanPlusEventStore;\n appId: string;\n sessionId?: string;\n actor?: HumanPlusActor;\n}\n\ntype Subscription = { consumerId: string; types?: string[]; surfaces?: string[] };\ntype PendingAction = { id: string; surfaceId: string; command: string; input: Record<string, unknown>; actor: HumanPlusActor };\n\nexport function registerTuiBridge(host: ToolHost, options: TuiBridgeOptions) {\n const disposers: Array<() => void> = []; const subscriptions = new Map<unknown, Subscription>(); const pending = new Map<string, PendingAction>();\n const defaultActor = options.actor ?? { kind: \"agent\" as const, id: \"agent\", name: \"Agent\" };\n const serverCapabilities = (host as ToolHost & { capabilities?: { experimental?: Record<string, unknown> } }).capabilities;\n if (serverCapabilities) serverCapabilities.experimental = { ...serverCapabilities.experimental, \"io.particle-academy/human-plus\": { version: \"1\", push: true, durableCursor: true, stagedActions: true, wakesAgent: false } };\n const register = (name: string, description: string, properties: Record<string, unknown>, required: string[], handler: (args: JsonObject, context?: ToolCallContext) => unknown | Promise<unknown>) => {\n disposers.push(host.registerTool({ name, description, inputSchema: { type: \"object\", properties: properties as never, required } }, async (args, context) => {\n try { const result = await handler(args, context); return textResult(typeof result === \"string\" ? result : JSON.stringify(result), result); }\n catch (error) { return errorResult(error instanceof Error ? error.message : String(error)); }\n }));\n };\n const publish = async (surfaceId: string, type: string, payload: unknown, actor = defaultActor, priority: HumanPlusPriority = \"normal\") => options.eventStore.append({ appId: options.appId, sessionId: options.sessionId, surfaceId, type, payload, actor, priority });\n\n register(\"tui_surfaces_list\", \"List addressable Fancy TUI surfaces and commands.\", {}, [], () => options.registry.list().map((surface) => ({ id: surface.id, kind: surface.kind, label: surface.label, commands: surface.commands?.map((command) => ({ name: command.name, description: command.description, policy: command.policy ?? \"execute\", inputSchema: command.inputSchema })) ?? [] })));\n register(\"tui_surface_read\", \"Read a Fancy TUI surface by stable id.\", { id: { type: \"string\" } }, [\"id\"], (args) => {\n const surface = options.registry.get(String(args.id)); if (!surface) throw new Error(`Unknown TUI surface: ${String(args.id)}`); return { id: surface.id, kind: surface.kind, state: surface.read() };\n });\n register(\"tui_action_invoke\", \"Invoke or propose an action on a Fancy TUI surface.\", { surfaceId: { type: \"string\" }, command: { type: \"string\" }, input: { type: \"object\" } }, [\"surfaceId\", \"command\"], async (args) => {\n const surfaceId = String(args.surfaceId); const commandName = String(args.command); const surface = options.registry.get(surfaceId); if (!surface) throw new Error(`Unknown TUI surface: ${surfaceId}`);\n const command = surface.commands?.find((value) => value.name === commandName); if (!command) throw new Error(`Unknown command '${commandName}' on ${surfaceId}`);\n const policy = command.policy ?? \"execute\"; if (policy === \"observe\" || policy === \"human-only\") throw new Error(`Action ${surfaceId}.${commandName} is ${policy}`);\n const input = (args.input && typeof args.input === \"object\" && !Array.isArray(args.input) ? args.input : {}) as Record<string, unknown>;\n if (policy === \"propose\" || policy === \"confirm\") {\n const id = globalThis.crypto.randomUUID(); pending.set(id, { id, surfaceId, command: commandName, input, actor: defaultActor });\n await publish(surfaceId, \"action.proposed\", { id, command: commandName, input }, defaultActor, \"attention\"); return { pending: true, id };\n }\n const result = await command.invoke(input); await publish(surfaceId, \"action.executed\", { command: commandName, input, result });\n emitActivity({ agentId: defaultActor.id, agentName: defaultActor.name, target: { kind: \"custom\", elementId: surfaceId }, action: `tui_${commandName}`, timestamp: Date.now(), meta: { surfaceId } });\n return { executed: true, result };\n });\n register(\"tui_action_confirm\", \"Confirm and execute a pending TUI action.\", { id: { type: \"string\" } }, [\"id\"], async (args) => {\n const id = String(args.id); const value = pending.get(id); if (!value) throw new Error(`Unknown pending action: ${id}`); const surface = options.registry.get(value.surfaceId); const command = surface?.commands?.find((x) => x.name === value.command); if (!command) throw new Error(\"Pending action target is no longer available\");\n pending.delete(id); const result = await command.invoke(value.input); await publish(value.surfaceId, \"action.confirmed\", { id, command: value.command, result }, { kind: \"human\", id: \"human\" }); return { executed: true, result };\n });\n register(\"tui_action_reject\", \"Reject a pending TUI action.\", { id: { type: \"string\" } }, [\"id\"], async (args) => { const id = String(args.id); const value = pending.get(id); if (!value) throw new Error(`Unknown pending action: ${id}`); pending.delete(id); await publish(value.surfaceId, \"action.rejected\", { id, command: value.command }, { kind: \"human\", id: \"human\" }); return { rejected: true }; });\n register(\"human_plus_events_list\", \"Pull durable Human+ events for a consumer.\", { consumerId: { type: \"string\" }, after: { type: \"number\" }, limit: { type: \"number\" }, unacknowledgedOnly: { type: \"boolean\" } }, [\"consumerId\"], (args) => options.eventStore.list({ consumerId: String(args.consumerId), after: typeof args.after === \"number\" ? args.after : undefined, limit: typeof args.limit === \"number\" ? args.limit : undefined, unacknowledgedOnly: args.unacknowledgedOnly === true }));\n register(\"human_plus_events_ack\", \"Acknowledge durable Human+ events.\", { consumerId: { type: \"string\" }, eventIds: { type: \"array\", items: { type: \"string\" } }, disposition: { type: \"string\" } }, [\"consumerId\", \"eventIds\"], async (args) => { const ids = Array.isArray(args.eventIds) ? args.eventIds.map(String) : []; await options.eventStore.acknowledge(String(args.consumerId), ids, [\"seen\", \"handled\", \"rejected\", \"ignored\"].includes(String(args.disposition)) ? String(args.disposition) as any : \"handled\"); return { acknowledged: ids.length }; });\n register(\"human_plus_events_subscribe\", \"Push matching Human+ events on this MCP transport while retaining them in the inbox.\", { consumerId: { type: \"string\" }, types: { type: \"array\" }, surfaces: { type: \"array\" } }, [\"consumerId\"], (args, context) => { if (!context?.transport) throw new Error(\"Subscriptions require an attached MCP transport\"); subscriptions.set(context.transport, { consumerId: String(args.consumerId), types: Array.isArray(args.types) ? args.types.map(String) : undefined, surfaces: Array.isArray(args.surfaces) ? args.surfaces.map(String) : undefined }); return { subscribed: true, delivery: \"at-least-once\", wakesAgent: false }; });\n\n const unsubscribeStore = options.eventStore.subscribe((event) => {\n const server = host as ToolHost & Pick<MicroMcpServer, \"notify\">;\n if (typeof server.notify !== \"function\") return;\n for (const [transport, subscription] of subscriptions) {\n if (subscription.types?.length && !subscription.types.includes(event.type)) continue;\n if (subscription.surfaces?.length && !subscription.surfaces.includes(event.surfaceId)) continue;\n server.notify({ jsonrpc: \"2.0\", method: \"notifications/human_plus/event\", params: event as never }, transport as Transport);\n }\n });\n return { id: \"tui\", title: \"Fancy TUI\", pending: () => [...pending.values()], dispose: () => { disposers.forEach((dispose) => dispose()); unsubscribeStore(); subscriptions.clear(); pending.clear(); } };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/whiteboard.ts"],"names":[],"mappings":"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","file":"chunk-LQB42OSA.js","sourcesContent":["import type {\n BoardItem,\n ConnectorItem,\n RemoteCursor,\n ShapeItem,\n ShapeKind,\n StickyNoteItem,\n Stroke,\n Viewport,\n} from \"@particle-academy/fancy-whiteboard\";\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 } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * State accessors / mutators the bridge needs from the host. The host owns\n * whiteboard state (controlled props on fancy-whiteboard components); the\n * bridge calls into these to read or change it.\n */\nexport type WhiteboardBridgeAdapter = {\n getNotes: () => StickyNoteItem[];\n setNotes: (next: StickyNoteItem[] | ((prev: StickyNoteItem[]) => StickyNoteItem[])) => void;\n getShapes: () => ShapeItem[];\n setShapes: (next: ShapeItem[] | ((prev: ShapeItem[]) => ShapeItem[])) => void;\n getConnectors: () => ConnectorItem[];\n setConnectors: (next: ConnectorItem[] | ((prev: ConnectorItem[]) => ConnectorItem[])) => void;\n getStrokes: () => Stroke[];\n setStrokes: (next: Stroke[] | ((prev: Stroke[]) => Stroke[])) => void;\n getViewport: () => Viewport;\n setViewport: (next: Viewport) => void;\n /** Optional: agent presence cursor (for the visualizer). */\n setAgentCursor?: (cursor: RemoteCursor | null) => void;\n};\n\nexport type WhiteboardBridgeOptions = {\n adapter: WhiteboardBridgeAdapter;\n /** Identity used when the agent stamps authorId on items / cursor. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst VALID_SHAPES: ShapeKind[] = [\"rect\", \"rounded-rect\", \"ellipse\", \"diamond\", \"triangle\", \"line\", \"arrow\", \"text\"];\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst bool = (v: unknown, fallback = false): boolean => (typeof v === \"boolean\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerWhiteboardBridge — wires a full MCP tool set against a fancy-\n * whiteboard session controlled by the host. Returns a Bridge handle the\n * host can dispose to tear everything down.\n */\nexport function registerWhiteboardBridge(\n host: ToolHost,\n options: WhiteboardBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Register agent_undo / agent_redo / agent_history once per server. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n // Cursor narration is the agent's responsibility — call\n // whiteboard_set_agent_cursor as a separate prerequisite before any\n // mutation. This keeps the protocol honest: each tool does one thing.\n\n // Activity-target resolver shared by every mutation tool. Pulls the id\n // from the freshly-created item (structuredContent) when present, falls\n // back to the args id (for update/delete tools).\n const wbTarget = (args: any, result: any): AgentTarget => ({\n kind: \"whiteboard\",\n elementId: (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\n });\n\n\n const reg = (\n name: string,\n description: string,\n inputProperties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n /** Optional: resolve the activity target so the presence layer can render\n * a focus indicator on the touched element. Read tools omit this. */\n resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"whiteboard\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: inputProperties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"whiteboard_get_state\", \"Get the full board state: viewport, all items, strokes.\", {}, [], () => {\n const state = {\n viewport: adapter.getViewport(),\n notes: adapter.getNotes(),\n shapes: adapter.getShapes(),\n connectors: adapter.getConnectors(),\n strokes: adapter.getStrokes(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"whiteboard_list_items\", \"List notes, shapes, and connectors with id, kind, and bounds.\", {}, [], () => {\n const items: Array<{ id: string; kind: string; summary: string }> = [];\n for (const n of adapter.getNotes()) {\n items.push({\n id: n.id,\n kind: \"sticky\",\n summary: `\"${(n.text ?? \"\").slice(0, 40)}\" @(${Math.round(n.x)},${Math.round(n.y)}) ${n.width}×${n.height}`,\n });\n }\n for (const s of adapter.getShapes()) {\n items.push({\n id: s.id,\n kind: `shape:${s.shape}`,\n summary: `${s.text ? `\"${s.text}\" ` : \"\"}@(${Math.round(s.x)},${Math.round(s.y)}) ${s.width}×${s.height}`,\n });\n }\n for (const c of adapter.getConnectors()) {\n items.push({ id: c.id, kind: \"connector\", summary: `from=${JSON.stringify(c.from)} to=${JSON.stringify(c.to)}` });\n }\n return textResult(items.map((i) => `${i.kind} ${i.id}: ${i.summary}`).join(\"\\n\") || \"(empty board)\", items);\n });\n\n reg(\n \"whiteboard_get_item\",\n \"Get a single item (sticky / shape / connector) by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const all: BoardItem[] = [...adapter.getNotes(), ...adapter.getShapes(), ...adapter.getConnectors()];\n const found = all.find((x) => x.id === id);\n if (!found) return errorResult(`No item with id ${id}`);\n return textResult(JSON.stringify(found, null, 2), found);\n },\n );\n\n // ───────────── Sticky CRUD ─────────────\n\n reg(\n \"whiteboard_add_sticky\",\n \"Add a sticky note. Position is in world coordinates.\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n text: { type: \"string\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n color: { type: \"string\", description: \"CSS color, e.g. #fde68a\" },\n },\n [\"x\", \"y\"],\n async (args) => {\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width, 180);\n const height = num(args.height, 140);\n// (cursor narration is now an explicit separate tool call)\n const note: StickyNoteItem = {\n id: newId(\"n\"),\n kind: \"sticky\",\n x, y, width, height,\n text: str(args.text),\n color: typeof args.color === \"string\" ? args.color : \"#fde68a\",\n authorId: agent.id,\n };\n adapter.setNotes((all) => [...all, note]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"whiteboard\",\n action: \"whiteboard_add_sticky\",\n label: `Added sticky ${note.id}`,\n undo: () => adapter.setNotes((all) => all.filter((n) => n.id !== note.id)),\n redo: () => adapter.setNotes((all) => [...all, note]),\n });\n return textResult(`Added sticky ${note.id}`, note);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_stream_text\",\n \"Type text into a sticky note character-by-character so the human can read it forming. The tool returns once streaming finishes.\",\n {\n id: { type: \"string\" },\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n append: { type: \"boolean\", description: \"Append to existing text instead of replacing. Default false.\" },\n },\n [\"id\", \"text\"],\n async (args) => {\n const id = str(args.id);\n const target = str(args.text);\n const cps = Math.max(1, num(args.cps, 25));\n const append = bool(args.append);\n const startNote = adapter.getNotes().find((n) => n.id === id);\n if (!startNote) return errorResult(`No sticky with id ${id}`);\n const base = append ? (startNote.text ?? \"\") : \"\";\n const interval = Math.max(8, Math.round(1000 / cps));\n for (let i = 0; i <= target.length; i++) {\n const nextText = base + target.slice(0, i);\n adapter.setNotes((all) => all.map((n) => (n.id === id ? { ...n, text: nextText } : n)));\n if (i < target.length) await new Promise((r) => setTimeout(r, interval));\n }\n return textResult(`Streamed ${target.length} chars to ${id}`, { id, text: base + target });\n },\n );\n\n reg(\n \"whiteboard_update_sticky\",\n \"Update fields on a sticky note. Only provided fields are changed.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n color: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getNotes().find((n) => n.id === id);\n if (!existing) return errorResult(`No sticky with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: StickyNoteItem | null = null;\n adapter.setNotes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated sticky ${id}`, updated);\n },\n wbTarget,\n );\n\n // ───────────── Shape CRUD ─────────────\n\n reg(\n \"whiteboard_add_shape\",\n `Add a shape. Kind must be one of: ${VALID_SHAPES.join(\", \")}.`,\n {\n shape: { type: \"string\", enum: VALID_SHAPES },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n flipX: { type: \"boolean\" },\n flipY: { type: \"boolean\" },\n },\n [\"shape\", \"x\", \"y\", \"width\", \"height\"],\n async (args) => {\n const kind = str(args.shape) as ShapeKind;\n if (!VALID_SHAPES.includes(kind)) return errorResult(`Invalid shape kind: ${kind}`);\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width);\n const height = num(args.height);\n// (cursor narration is now an explicit separate tool call)\n const shape: ShapeItem = {\n id: newId(\"s\"),\n kind: \"shape\",\n shape: kind,\n x, y, width, height,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n ...(args.flipX !== undefined ? { flipX: bool(args.flipX) } : {}),\n ...(args.flipY !== undefined ? { flipY: bool(args.flipY) } : {}),\n };\n adapter.setShapes((all) => [...all, shape]);\n return textResult(`Added ${kind} ${shape.id}`, shape);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_update_shape\",\n \"Update fields on a shape.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getShapes().find((s) => s.id === id);\n if (!existing) return errorResult(`No shape with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: ShapeItem | null = null;\n adapter.setShapes((all) =>\n all.map((s) => {\n if (s.id !== id) return s;\n updated = {\n ...s,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated shape ${id}`, updated);\n },\n wbTarget,\n );\n\n // ───────────── Connectors ─────────────\n\n reg(\n \"whiteboard_add_connector\",\n \"Connect two items by id, or specify explicit world-space points.\",\n {\n from: { description: \"Item id (string) or {x,y}\" },\n to: { description: \"Item id (string) or {x,y}\" },\n color: { type: \"string\" },\n },\n [\"from\", \"to\"],\n (args) => {\n const c: ConnectorItem = {\n id: newId(\"c\"),\n kind: \"connector\",\n from: args.from as any,\n to: args.to as any,\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n adapter.setConnectors((all) => [...all, c]);\n return textResult(`Added connector ${c.id}`, c);\n },\n wbTarget,\n );\n\n // ───────────── Drawing ─────────────\n\n reg(\n \"whiteboard_add_stroke\",\n \"Add a freeform pen stroke. Points are absolute screen coords (matching the Drawing layer).\",\n {\n points: {\n type: \"array\",\n description: \"Array of {x,y} points\",\n },\n color: { type: \"string\" },\n size: { type: \"number\" },\n },\n [\"points\"],\n (args) => {\n const points = (Array.isArray(args.points) ? args.points : []).map((p: any) => ({\n x: num(p?.x),\n y: num(p?.y),\n }));\n if (!points.length) return errorResult(\"Stroke requires at least one point\");\n const stroke: Stroke = {\n id: newId(\"st\"),\n points,\n color: typeof args.color === \"string\" ? args.color : \"#0f172a\",\n size: typeof args.size === \"number\" ? args.size : 2,\n authorId: agent.id,\n };\n adapter.setStrokes((all) => [...all, stroke]);\n return textResult(`Added stroke ${stroke.id} (${points.length} points)`, stroke);\n },\n wbTarget,\n );\n\n // ───────────── Generic delete ─────────────\n\n reg(\n \"whiteboard_delete_item\",\n \"Remove any item by id (sticky / shape / connector / stroke).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n // Snapshot the items being removed so undo can re-insert them.\n const removedNotes = adapter.getNotes().filter((x) => x.id === id);\n const removedShapes = adapter.getShapes().filter((x) => x.id === id);\n const removedConnectors = adapter.getConnectors().filter((x) => x.id === id);\n const removedStrokes = adapter.getStrokes().filter((x) => x.id === id);\n const removed = removedNotes.length + removedShapes.length + removedConnectors.length + removedStrokes.length > 0;\n if (!removed) return errorResult(`No item with id ${id}`);\n adapter.setNotes((all) => all.filter((x) => x.id !== id));\n adapter.setShapes((all) => all.filter((x) => x.id !== id));\n adapter.setConnectors((all) => all.filter((x) => x.id !== id));\n adapter.setStrokes((all) => all.filter((x) => x.id !== id));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"whiteboard\",\n action: \"whiteboard_delete_item\",\n label: `Deleted ${id}`,\n undo: () => {\n if (removedNotes.length) adapter.setNotes((all) => [...all, ...removedNotes]);\n if (removedShapes.length) adapter.setShapes((all) => [...all, ...removedShapes]);\n if (removedConnectors.length) adapter.setConnectors((all) => [...all, ...removedConnectors]);\n if (removedStrokes.length) adapter.setStrokes((all) => [...all, ...removedStrokes]);\n },\n redo: () => {\n adapter.setNotes((all) => all.filter((x) => x.id !== id));\n adapter.setShapes((all) => all.filter((x) => x.id !== id));\n adapter.setConnectors((all) => all.filter((x) => x.id !== id));\n adapter.setStrokes((all) => all.filter((x) => x.id !== id));\n },\n });\n return textResult(`Deleted ${id}`);\n },\n wbTarget,\n );\n\n // ───────────── Viewport / agent presence ─────────────\n\n reg(\n \"whiteboard_set_viewport\",\n \"Pan / zoom the viewport.\",\n { x: { type: \"number\" }, y: { type: \"number\" }, zoom: { type: \"number\" } },\n [],\n (args) => {\n const v = adapter.getViewport();\n const next: Viewport = {\n x: args.x !== undefined ? num(args.x) : v.x,\n y: args.y !== undefined ? num(args.y) : v.y,\n zoom: args.zoom !== undefined ? num(args.zoom) : v.zoom,\n };\n adapter.setViewport(next);\n return textResult(`Viewport → ${JSON.stringify(next)}`, next);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_set_agent_cursor\",\n \"Move the agent's presence cursor (or pass null to hide it).\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n hide: { type: \"boolean\" },\n },\n [],\n (args) => {\n if (!adapter.setAgentCursor) return errorResult(\"Host did not provide setAgentCursor\");\n if (bool(args.hide)) {\n adapter.setAgentCursor(null);\n return textResult(\"Agent cursor hidden\");\n }\n const cursor: RemoteCursor = {\n userId: agent.id,\n name: agent.name,\n color: agent.color,\n x: num(args.x),\n y: num(args.y),\n };\n adapter.setAgentCursor(cursor);\n return textResult(`Cursor → (${cursor.x}, ${cursor.y})`, cursor);\n },\n wbTarget,\n );\n\n return {\n id: \"whiteboard\",\n title: \"Whiteboard\",\n dispose: () => {\n for (const d of disposers) d();\n adapter.setAgentCursor?.(null);\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bridges/grid.ts"],"names":[],"mappings":"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","file":"chunk-MIDZWKIF.js","sourcesContent":["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 { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport type { AgentTarget } from \"../presence/types\";\n\n/**\n * Loose grid types — the public state shape of `@particle-academy/fancy-grid`,\n * mirrored here rather than imported.\n *\n * Same reason the scene bridge mirrors fancy-3d's descriptor: a bridge must not\n * drag its surface package into every consumer's tree. fancy-grid keeps\n * TanStack Table and Virtual as PEERS specifically so nothing bundles them, and\n * an `import type` here would still make fancy-grid a build-time dependency of\n * agent-integrations. The state is four small JSON shapes; the coupling is not\n * worth it.\n */\nexport type GridSort = { id: string; desc: boolean };\nexport type GridFilter = { id: string; value: string };\nexport type GridPagination = { pageIndex: number; pageSize: number };\n\nexport type GridState = {\n sorting?: GridSort[];\n filters?: GridFilter[];\n /** Keyed by row id — see the grid's `getRowId`. */\n rowSelection?: Record<string, boolean>;\n pagination?: GridPagination;\n};\n\nexport type GridBridgeAdapter = {\n id: string;\n title?: string;\n screenId?: string;\n /** Controlled state — the same object the grid's `onStateChange` emits. */\n getState: () => GridState;\n setState: (next: GridState) => void;\n /**\n * Column ids an agent may address. Supplied so a tool can REJECT an unknown\n * column instead of writing a sort nothing applies — a silently ignored sort\n * looks identical to a grid that simply is not sorted.\n */\n getColumnIds?: () => string[];\n /** Row ids currently on screen, for `grid_select_rows` validation. */\n getRowIds?: () => string[];\n /**\n * Write one cell. Absent when the grid is read-only, in which case\n * `grid_edit_cell` is not registered at all rather than failing at call time\n * — an agent should discover the capability from the tool list.\n */\n editCell?: (rowId: string, columnId: string, value: unknown) => void | Promise<void>;\n};\n\nexport type GridBridgeOptions = {\n adapter: GridBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n /**\n * Gate writes behind a human confirmation. `grid_edit_cell` is the only\n * mutation that changes DATA rather than view state, so it is the one that\n * matters here — sorting a grid is not a trust-but-verify action.\n */\n pendingMode?: boolean;\n onPending?: (staged: { id: string; label: string; apply: () => void | Promise<void> }) => void;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerGridBridge — MCP access to a `fancy-grid` surface.\n *\n * `grid_sort`, `grid_filter`, `grid_select_rows` and `grid_edit_cell`, plus a\n * read tool. View state (sort / filter / selection / page) goes through one\n * `setState` channel because that is how the grid is controlled — a bridge that\n * mutated pieces separately would drift from what the component actually\n * accepts.\n */\nexport function registerGridBridge(host: ToolHost, options: GridBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target = (part?: string): AgentTarget => ({\n kind: \"grid\",\n screenId: adapter.screenId,\n elementId: part ? `${adapter.id}:${part}` : adapter.id,\n label: part ? `${adapter.title ?? adapter.id} → ${part}` : (adapter.title ?? adapter.id),\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<ReturnType<typeof textResult>> | ReturnType<typeof textResult>,\n isMutation: boolean,\n partFromArgs?: (args: JsonObject) => string | undefined,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"grid\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(partFromArgs?.(args)),\n })\n : wrapped;\n\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as never, required, additionalProperties: false },\n },\n final as never,\n ),\n );\n };\n\n /** Reject an unknown column rather than writing state nothing applies. */\n const assertColumn = (id: string): void => {\n const known = adapter.getColumnIds?.();\n if (known && !known.includes(id)) {\n throw new Error(`Unknown column \"${id}\". Available: ${known.join(\", \")}`);\n }\n };\n\n const commit = (next: GridState, action: string, label: string, previous: GridState): void => {\n adapter.setState(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: `grid:${adapter.id}`,\n action,\n label,\n undo: () => adapter.setState(previous),\n redo: () => adapter.setState(next),\n });\n };\n\n // ───────────── Read ─────────────\n\n reg(\n \"grid_get\",\n \"Read the grid's view state — sorting, filters, selected row ids, pagination — plus the addressable column and row ids.\",\n {},\n [],\n () => {\n const state = adapter.getState();\n return textResult(\n JSON.stringify(\n {\n id: adapter.id,\n title: adapter.title,\n sorting: state.sorting ?? [],\n filters: state.filters ?? [],\n selectedRowIds: Object.entries(state.rowSelection ?? {})\n .filter(([, on]) => on)\n .map(([id]) => id),\n pagination: state.pagination,\n columnIds: adapter.getColumnIds?.() ?? null,\n rowIds: adapter.getRowIds?.() ?? null,\n editable: Boolean(adapter.editCell),\n },\n null,\n 2,\n ),\n );\n },\n false,\n );\n\n // ───────────── View state ─────────────\n\n reg(\n \"grid_sort\",\n \"Sort the grid. Pass an empty array to clear sorting. Multiple entries sort by each in order.\",\n {\n sorting: {\n type: \"array\",\n description: 'e.g. [{ \"id\": \"createdAt\", \"desc\": true }]',\n items: {\n type: \"object\",\n properties: { id: { type: \"string\" }, desc: { type: \"boolean\" } },\n required: [\"id\"],\n additionalProperties: false,\n },\n },\n },\n [\"sorting\"],\n (args) => {\n const raw = Array.isArray(args.sorting) ? (args.sorting as GridSort[]) : [];\n const sorting = raw.map((s) => {\n assertColumn(String(s.id));\n return { id: String(s.id), desc: Boolean(s.desc) };\n });\n\n const previous = adapter.getState();\n commit({ ...previous, sorting }, \"grid_sort\", `Sorted by ${sorting.map((s) => s.id).join(\", \") || \"nothing\"}`, previous);\n return textResult(`Sorted by ${sorting.map((s) => `${s.id}${s.desc ? \" desc\" : \"\"}`).join(\", \") || \"nothing\"}.`);\n },\n true,\n (args) => (Array.isArray(args.sorting) && args.sorting[0] ? String((args.sorting[0] as GridSort).id) : undefined),\n );\n\n reg(\n \"grid_filter\",\n \"Filter the grid. Pass an empty array to clear all filters.\",\n {\n filters: {\n type: \"array\",\n description: 'e.g. [{ \"id\": \"status\", \"value\": \"open\" }]',\n items: {\n type: \"object\",\n properties: { id: { type: \"string\" }, value: { type: \"string\" } },\n required: [\"id\", \"value\"],\n additionalProperties: false,\n },\n },\n },\n [\"filters\"],\n (args) => {\n const raw = Array.isArray(args.filters) ? (args.filters as GridFilter[]) : [];\n const filters = raw.map((f) => {\n assertColumn(String(f.id));\n return { id: String(f.id), value: String(f.value) };\n });\n\n const previous = adapter.getState();\n commit({ ...previous, filters }, \"grid_filter\", `Filtered ${filters.map((f) => f.id).join(\", \") || \"cleared\"}`, previous);\n return textResult(`Filtering on ${filters.map((f) => `${f.id}=${f.value}`).join(\", \") || \"nothing\"}.`);\n },\n true,\n (args) => (Array.isArray(args.filters) && args.filters[0] ? String((args.filters[0] as GridFilter).id) : undefined),\n );\n\n reg(\n \"grid_select_rows\",\n \"Replace the grid's row selection with the given row ids. Pass an empty array to clear.\",\n { rowIds: { type: \"array\", items: { type: \"string\" }, description: \"Row ids, per the grid's getRowId.\" } },\n [\"rowIds\"],\n (args) => {\n const ids = Array.isArray(args.rowIds) ? args.rowIds.map(String) : [];\n const known = adapter.getRowIds?.();\n if (known) {\n const missing = ids.filter((id) => !known.includes(id));\n if (missing.length) {\n // Selecting a row that is not loaded looks like it worked and shows\n // nothing — worth an error rather than a silent no-op.\n throw new Error(`Row id(s) not on this page: ${missing.join(\", \")}`);\n }\n }\n\n const previous = adapter.getState();\n const rowSelection: Record<string, boolean> = {};\n for (const id of ids) rowSelection[id] = true;\n\n commit({ ...previous, rowSelection }, \"grid_select_rows\", `Selected ${ids.length} row${ids.length === 1 ? \"\" : \"s\"}`, previous);\n return textResult(`Selected ${ids.length} row${ids.length === 1 ? \"\" : \"s\"}.`);\n },\n true,\n );\n\n // ───────────── Data ─────────────\n\n if (adapter.editCell) {\n reg(\n \"grid_edit_cell\",\n \"Write one cell. This changes DATA, not just the view.\",\n {\n rowId: { type: \"string\" },\n columnId: { type: \"string\" },\n value: { description: \"New value. Any JSON scalar or object the column accepts.\" },\n },\n [\"rowId\", \"columnId\"],\n async (args) => {\n const rowId = String(args.rowId);\n const columnId = String(args.columnId);\n assertColumn(columnId);\n\n const apply = async () => {\n await adapter.editCell?.(rowId, columnId, args.value);\n };\n\n if (options.pendingMode) {\n // Trust-but-verify: the only tool here that changes stored data\n // stages instead of writing. Sorting a grid is not a destructive act;\n // editing a cell is.\n const id = `grid-edit-${Date.now().toString(36)}`;\n options.onPending?.({ id, label: `set ${columnId} on row ${rowId}`, apply });\n return textResult(`Staged: set ${columnId} on row ${rowId}. Awaiting confirmation.`);\n }\n\n await apply();\n return textResult(`Set ${columnId} on row ${rowId}.`);\n },\n true,\n (args) => `${String(args.rowId)}:${String(args.columnId)}`,\n );\n }\n\n return {\n id: `grid:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => {\n for (const d of disposers) d();\n disposers.length = 0;\n },\n };\n}\n"]}