@particle-academy/agent-integrations 0.25.0 → 0.26.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 (60) hide show
  1. package/dist/bridges-charts.cjs +77 -0
  2. package/dist/bridges-charts.cjs.map +1 -1
  3. package/dist/bridges-charts.js +2 -1
  4. package/dist/bridges-code.cjs +77 -0
  5. package/dist/bridges-code.cjs.map +1 -1
  6. package/dist/bridges-code.js +2 -1
  7. package/dist/bridges-files.cjs +1 -1
  8. package/dist/bridges-files.cjs.map +1 -1
  9. package/dist/bridges-files.js +1 -1
  10. package/dist/bridges-flow.cjs +77 -0
  11. package/dist/bridges-flow.cjs.map +1 -1
  12. package/dist/bridges-flow.js +2 -0
  13. package/dist/bridges-flow.js.map +1 -1
  14. package/dist/bridges-forms.cjs +77 -0
  15. package/dist/bridges-forms.cjs.map +1 -1
  16. package/dist/bridges-forms.js +2 -1
  17. package/dist/bridges-map.cjs +1 -1
  18. package/dist/bridges-map.cjs.map +1 -1
  19. package/dist/bridges-map.js +1 -1
  20. package/dist/bridges-scene.cjs +77 -0
  21. package/dist/bridges-scene.cjs.map +1 -1
  22. package/dist/bridges-scene.js +2 -1
  23. package/dist/bridges-screens.cjs +77 -0
  24. package/dist/bridges-screens.cjs.map +1 -1
  25. package/dist/bridges-screens.js +2 -1
  26. package/dist/bridges-sheets.cjs +77 -0
  27. package/dist/bridges-sheets.cjs.map +1 -1
  28. package/dist/bridges-sheets.js +2 -1
  29. package/dist/bridges-slides.cjs +77 -0
  30. package/dist/bridges-slides.cjs.map +1 -1
  31. package/dist/bridges-slides.js +2 -1
  32. package/dist/{chunk-DR7X4TWE.js → chunk-46H4C5AP.js} +4 -2
  33. package/dist/chunk-46H4C5AP.js.map +1 -0
  34. package/dist/{chunk-5AD35HS5.js → chunk-775LJJTJ.js} +4 -2
  35. package/dist/chunk-775LJJTJ.js.map +1 -0
  36. package/dist/{chunk-UOMSY7MZ.js → chunk-CLFDQ2BW.js} +3 -3
  37. package/dist/{chunk-UOMSY7MZ.js.map → chunk-CLFDQ2BW.js.map} +1 -1
  38. package/dist/{chunk-SJ7H242B.js → chunk-EP3G4LYW.js} +4 -2
  39. package/dist/chunk-EP3G4LYW.js.map +1 -0
  40. package/dist/{chunk-VUMFO2UW.js → chunk-K3S6WSHZ.js} +4 -2
  41. package/dist/chunk-K3S6WSHZ.js.map +1 -0
  42. package/dist/{chunk-3VRQGDKV.js → chunk-NKRSLCS7.js} +3 -3
  43. package/dist/{chunk-3VRQGDKV.js.map → chunk-NKRSLCS7.js.map} +1 -1
  44. package/dist/{chunk-FYGMFIY5.js → chunk-QDF37J3V.js} +4 -2
  45. package/dist/chunk-QDF37J3V.js.map +1 -0
  46. package/dist/{chunk-HIMTURWL.js → chunk-V5BXBX7U.js} +4 -2
  47. package/dist/chunk-V5BXBX7U.js.map +1 -0
  48. package/dist/{chunk-CKK4QKD2.js → chunk-YMX7G3XM.js} +4 -2
  49. package/dist/chunk-YMX7G3XM.js.map +1 -0
  50. package/dist/index.cjs +85 -78
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.js +10 -10
  53. package/package.json +1 -1
  54. package/dist/chunk-5AD35HS5.js.map +0 -1
  55. package/dist/chunk-CKK4QKD2.js.map +0 -1
  56. package/dist/chunk-DR7X4TWE.js.map +0 -1
  57. package/dist/chunk-FYGMFIY5.js.map +0 -1
  58. package/dist/chunk-HIMTURWL.js.map +0 -1
  59. package/dist/chunk-SJ7H242B.js.map +0 -1
  60. package/dist/chunk-VUMFO2UW.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/charts.ts"],"names":[],"mappings":"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","file":"chunk-EP3G4LYW.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 type { AgentTarget } from \"../presence/types\";\n\n/**\n * Adapter wires a single fancy-echarts chart to the bridge. Charts are\n * already prop-driven, so the adapter just exposes the data + option\n * setters and a way to read what's currently rendered.\n */\nexport type ChartsBridgeAdapter = {\n /** Stable id for this chart instance. */\n id: string;\n title?: string;\n screenId?: string;\n /** Read the current ECharts option object the chart is rendering. */\n getOption: () => Record<string, unknown>;\n /** Replace the entire option. */\n setOption: (option: Record<string, unknown>) => void;\n /** Convenience: shallow-merge a partial option update. */\n updateOption?: (partial: Record<string, unknown>) => void;\n /** Read just the data series (subset of option for quick agent reads). */\n getData?: () => unknown;\n /** Update only the data, leaving axes/colors/etc. alone. */\n updateData?: (data: unknown) => void;\n};\n\nexport type ChartsBridgeOptions = {\n adapter: ChartsBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerChartsBridge — schema-aware MCP access to a single chart.\n */\nexport function registerChartsBridge(\n host: ToolHost,\n options: ChartsBridgeOptions,\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: \"chart\",\n screenId: adapter.screenId,\n elementId: adapter.id,\n label: adapter.title ?? adapter.id,\n };\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try { return await handler(args); }\n catch (e) { return errorResult(e instanceof Error ? e.message : String(e)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"chart\", screenId: adapter.screenId,\n resolveTarget: () => target,\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 \"chart_describe\",\n `Describe the chart \"${adapter.id}\" — series count, type guesses, axis info.`,\n {},\n [],\n () => {\n const opt = adapter.getOption();\n const series = Array.isArray(opt.series) ? opt.series : [];\n const summary = {\n id: adapter.id,\n title: adapter.title,\n seriesCount: series.length,\n seriesTypes: series.map((s: any) => s?.type ?? \"unknown\"),\n hasXAxis: !!opt.xAxis,\n hasYAxis: !!opt.yAxis,\n };\n return textResult(JSON.stringify(summary), summary);\n },\n false,\n );\n\n reg(\n \"chart_get_option\",\n \"Read the full ECharts option object the chart is rendering.\",\n {},\n [],\n () => {\n const opt = adapter.getOption();\n return textResult(JSON.stringify(opt, null, 2), opt);\n },\n false,\n );\n\n reg(\n \"chart_set_option\",\n \"Replace the entire ECharts option. Use chart_update_option for partial updates.\",\n { option: { type: \"object\" } },\n [\"option\"],\n (args) => {\n const opt = (args.option && typeof args.option === \"object\") ? args.option as Record<string, unknown> : {};\n adapter.setOption(opt);\n return textResult(\"Replaced chart option\", { });\n },\n true,\n );\n\n reg(\n \"chart_update_option\",\n \"Shallow-merge a partial option update — only the keys you provide change.\",\n { partial: { type: \"object\" } },\n [\"partial\"],\n (args) => {\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n if (adapter.updateOption) {\n adapter.updateOption(partial);\n } else {\n adapter.setOption({ ...adapter.getOption(), ...partial });\n }\n return textResult(\"Merged chart option\", { keys: Object.keys(partial) });\n },\n true,\n );\n\n reg(\n \"chart_update_data\",\n \"Update only the data (typically the `series` field). Leaves layout / axes / colors alone.\",\n { data: { description: \"New series array (or whatever shape the host's adapter expects).\" } },\n [\"data\"],\n (args) => {\n if (!adapter.updateData) return errorResult(\"Host did not provide updateData.\");\n adapter.updateData(args.data);\n return textResult(\"Updated chart data\", { });\n },\n true,\n );\n\n return {\n id: `chart:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { ensureUndoToolsRegistered } from './chunk-KJ5AOOV7.js';
1
2
  import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
2
3
  import { textResult, errorResult } from './chunk-4KAIV6OD.js';
3
4
 
@@ -7,6 +8,7 @@ function registerSceneBridge(host, options) {
7
8
  const { adapter } = options;
8
9
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
9
10
  const disposers = [];
11
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
10
12
  const target = (objectId) => ({
11
13
  kind: "scene",
12
14
  screenId: adapter.screenId,
@@ -199,5 +201,5 @@ function parseTriple(v) {
199
201
  }
200
202
 
201
203
  export { registerSceneBridge };
202
- //# sourceMappingURL=chunk-VUMFO2UW.js.map
203
- //# sourceMappingURL=chunk-VUMFO2UW.js.map
204
+ //# sourceMappingURL=chunk-K3S6WSHZ.js.map
205
+ //# sourceMappingURL=chunk-K3S6WSHZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/scene.ts"],"names":[],"mappings":"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","file":"chunk-K3S6WSHZ.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 type { AgentTarget } from \"../presence/types\";\n\n/**\n * Loose Scene types — mirror the public surface of fancy-3d's Scene\n * descriptor (engine-agnostic JSON the package's adapters consume).\n */\nexport type SceneObjectKind = \"box\" | \"sphere\" | \"cylinder\" | \"plane\" | \"screen\" | \"group\" | \"custom\";\n\nexport type SceneObject = {\n id: string;\n kind: SceneObjectKind | string;\n position?: [number, number, number];\n rotation?: [number, number, number];\n scale?: [number, number, number];\n color?: string;\n /** Free-form per-kind config (e.g. text content for screens). */\n props?: Record<string, unknown>;\n children?: SceneObject[];\n};\n\nexport type SceneCamera = {\n position?: [number, number, number];\n target?: [number, number, number];\n fov?: number;\n};\n\nexport type SceneState = {\n objects: SceneObject[];\n camera?: SceneCamera;\n background?: string;\n};\n\nexport type SceneBridgeAdapter = {\n id: string;\n title?: string;\n screenId?: string;\n getScene: () => SceneState;\n setScene: (next: SceneState) => void;\n /** Convenience: set just the camera without touching objects. */\n setCamera?: (next: SceneCamera) => void;\n};\n\nexport type SceneBridgeOptions = {\n adapter: SceneBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerSceneBridge — schema-aware MCP access to a fancy-3d Scene.\n * Tools cover read, add/update/delete object, set camera, set background.\n */\nexport function registerSceneBridge(\n host: ToolHost,\n options: SceneBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // 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 = (objectId?: string): AgentTarget => ({\n kind: \"scene\",\n screenId: adapter.screenId,\n elementId: objectId ? `${adapter.id}:${objectId}` : adapter.id,\n label: objectId ? `${adapter.title ?? adapter.id} → ${objectId}` : adapter.title ?? adapter.id,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n objectIdFromArgs?: (args: JsonObject) => string | undefined,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try { return await handler(args); }\n catch (e) { return errorResult(e instanceof Error ? e.message : String(e)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"scene\", screenId: adapter.screenId,\n resolveTarget: ({ args }) => target(objectIdFromArgs?.(args)),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n const newId = (kind: string) => `${kind}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n\n // ───────────── Read ─────────────\n\n reg(\n \"scene_describe\",\n \"Describe the scene — object count, kinds, camera position.\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n const summary = {\n id: adapter.id,\n objectCount: scene.objects.length,\n kinds: scene.objects.map((o) => o.kind),\n camera: scene.camera,\n background: scene.background,\n };\n return textResult(JSON.stringify(summary, null, 2), summary);\n },\n false,\n );\n\n reg(\n \"scene_get_state\",\n \"Read the full SceneState (objects + camera + background).\",\n {},\n [],\n () => {\n const scene = adapter.getScene();\n return textResult(JSON.stringify(scene, null, 2), scene);\n },\n false,\n );\n\n // ───────────── Mutations ─────────────\n\n reg(\n \"scene_add_object\",\n \"Add an object to the scene root. Returns the new object's id.\",\n {\n kind: { type: \"string\", description: \"box | sphere | cylinder | plane | screen | group | custom kind\" },\n position: { type: \"array\", description: \"[x, y, z]\" },\n rotation: { type: \"array\", description: \"[x, y, z] euler\" },\n scale: { type: \"array\", description: \"[x, y, z]\" },\n color: { type: \"string\" },\n props: { type: \"object\", description: \"Per-kind config.\" },\n },\n [\"kind\"],\n (args) => {\n const obj: SceneObject = {\n id: newId(String(args.kind)),\n kind: String(args.kind),\n position: parseTriple(args.position),\n rotation: parseTriple(args.rotation),\n scale: parseTriple(args.scale),\n color: typeof args.color === \"string\" ? args.color : undefined,\n props: (args.props && typeof args.props === \"object\") ? args.props as Record<string, unknown> : undefined,\n };\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, objects: [...scene.objects, obj] });\n return textResult(`Added ${obj.kind} ${obj.id}`, obj);\n },\n true,\n (args) => undefined, // id resolved from result.structuredContent.id\n );\n\n reg(\n \"scene_update_object\",\n \"Update fields on an object. Only provided fields change.\",\n {\n id: { type: \"string\" },\n position: { type: \"array\" },\n rotation: { type: \"array\" },\n scale: { type: \"array\" },\n color: { type: \"string\" },\n props: { type: \"object\" },\n },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const idx = scene.objects.findIndex((o) => o.id === id);\n if (idx === -1) return errorResult(`No object ${id}`);\n const orig = scene.objects[idx];\n const next: SceneObject = {\n ...orig,\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.rotation !== undefined ? { rotation: parseTriple(args.rotation) } : {}),\n ...(args.scale !== undefined ? { scale: parseTriple(args.scale) } : {}),\n ...(args.color !== undefined ? { color: String(args.color) } : {}),\n ...(args.props && typeof args.props === \"object\" ? { props: { ...(orig.props ?? {}), ...(args.props as Record<string, unknown>) } } : {}),\n };\n const objects = [...scene.objects];\n objects[idx] = next;\n adapter.setScene({ ...scene, objects });\n return textResult(`Updated ${id}`, next);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_delete_object\",\n \"Remove an object from the scene root.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = String(args.id);\n const scene = adapter.getScene();\n const next = scene.objects.filter((o) => o.id !== id);\n if (next.length === scene.objects.length) return errorResult(`No object ${id}`);\n adapter.setScene({ ...scene, objects: next });\n return textResult(`Deleted ${id}`);\n },\n true,\n (args) => String(args.id ?? \"\"),\n );\n\n reg(\n \"scene_set_camera\",\n \"Move the camera. Pass any subset of position/target/fov.\",\n {\n position: { type: \"array\", description: \"[x, y, z]\" },\n target: { type: \"array\", description: \"[x, y, z] look-at point\" },\n fov: { type: \"number\" },\n },\n [],\n (args) => {\n const scene = adapter.getScene();\n const next: SceneCamera = {\n ...(scene.camera ?? {}),\n ...(args.position !== undefined ? { position: parseTriple(args.position) } : {}),\n ...(args.target !== undefined ? { target: parseTriple(args.target) } : {}),\n ...(args.fov !== undefined ? { fov: Number(args.fov) } : {}),\n };\n if (adapter.setCamera) {\n adapter.setCamera(next);\n } else {\n adapter.setScene({ ...scene, camera: next });\n }\n return textResult(`Camera updated`, next);\n },\n true,\n );\n\n reg(\n \"scene_set_background\",\n \"Change the scene background color (CSS color).\",\n { color: { type: \"string\" } },\n [\"color\"],\n (args) => {\n const scene = adapter.getScene();\n adapter.setScene({ ...scene, background: String(args.color) });\n return textResult(`Background → ${args.color}`, { background: args.color });\n },\n true,\n );\n\n return {\n id: `scene:${adapter.id}`,\n title: adapter.title ?? adapter.id,\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n\nfunction parseTriple(v: unknown): [number, number, number] | undefined {\n if (!Array.isArray(v) || v.length !== 3) return undefined;\n const out = v.map((x) => Number(x));\n if (out.some((x) => !Number.isFinite(x))) return undefined;\n return out as [number, number, number];\n}\n"]}
@@ -3,7 +3,7 @@ import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
3
3
  import { textResult, errorResult } from './chunk-4KAIV6OD.js';
4
4
 
5
5
  // src/bridges/map.ts
6
- var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#7c3aed" };
6
+ var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
7
7
  var num = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
8
8
  var str = (v, fallback = "") => typeof v === "string" ? v : fallback;
9
9
  var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
@@ -330,5 +330,5 @@ function registerMapBridge(host, options) {
330
330
  }
331
331
 
332
332
  export { registerMapBridge };
333
- //# sourceMappingURL=chunk-3VRQGDKV.js.map
334
- //# sourceMappingURL=chunk-3VRQGDKV.js.map
333
+ //# sourceMappingURL=chunk-NKRSLCS7.js.map
334
+ //# sourceMappingURL=chunk-NKRSLCS7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bridges/map.ts"],"names":[],"mappings":"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","file":"chunk-3VRQGDKV.js","sourcesContent":["// Loose types so this bridge builds standalone without a hard dep on\n// @particle-academy/fancy-map. Hosts that use fancy-map pass its own\n// MapMarker / MapView values straight through — the shapes match.\ntype LatLng = { lat: number; lng: number };\ntype MapView = { center: LatLng; zoom: number; bearing?: number; pitch?: number };\ntype MapMarker = {\n id: string;\n position: LatLng;\n label?: string;\n color?: string;\n icon?: string;\n draggable?: boolean;\n data?: Record<string, unknown>;\n};\n\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget as MapAgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Adapter the host provides — getters/setters over the SAME controlled state it\n * passes to fancy-map's `<Map>` (view, markers, selection), plus optional\n * `fitBounds` (from the map's onReady handle) and `setFollow` (drives the map's\n * `follow` prop so an agent can make the camera track a moving marker).\n */\nexport type MapBridgeAdapter = {\n getView: () => MapView;\n setView: (next: MapView) => void;\n getMarkers: () => MapMarker[];\n setMarkers: (next: MapMarker[] | ((prev: MapMarker[]) => MapMarker[])) => void;\n getSelected: () => string | null;\n setSelected: (id: string | null) => void;\n /** Fit the camera to points (wire to the `MapHandle.fitBounds` from `<Map onReady>`). */\n fitBounds?: (points: LatLng[], padding?: number) => void;\n /** Make the camera follow a marker as it moves (drives the map's `follow` prop). */\n setFollow?: (id: string | null) => void;\n};\n\nexport type MapBridgeOptions = {\n adapter: MapBridgeAdapter;\n /** Identity tagged onto agent-authored markers. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#7c3aed\" };\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 newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerMapBridge — an MCP tool set over a fancy-map `<Map>`'s controlled\n * state, so a human and an agent cohabit one map. The agent moves the camera,\n * drops/updates/removes markers, selects, fits bounds, and follows a live\n * track; every mutation broadcasts AgentActivity (for presence) and pushes an\n * undo entry (so the human can step the agent back). Mirrors the whiteboard /\n * flow bridges in shape.\n */\nexport function registerMapBridge(host: ToolHost, options: MapBridgeOptions): 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 host. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const mTarget = (args: any, result: any): MapAgentTarget => ({\n kind: \"map\",\n elementId:\n (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n resolveTarget?: (args: JsonObject, result: any) => MapAgentTarget | 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: \"map\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read ─────────────\n\n reg(\"map_get_state\", \"Get the map's camera, markers, and current selection.\", {}, [], () => {\n const state = {\n view: adapter.getView(),\n markers: adapter.getMarkers(),\n selectedId: adapter.getSelected(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n // ───────────── Camera ─────────────\n\n reg(\n \"map_set_view\",\n \"Move the camera to an absolute position. Any omitted field is left unchanged.\",\n {\n lat: { type: \"number\", description: \"New center latitude.\" },\n lng: { type: \"number\", description: \"New center longitude.\" },\n zoom: { type: \"number\", description: \"New zoom level (higher = closer).\" },\n },\n [],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = {\n center: {\n lat: args.lat !== undefined ? num(args.lat) : prev.center.lat,\n lng: args.lng !== undefined ? num(args.lng) : prev.center.lng,\n },\n zoom: args.zoom !== undefined ? num(args.zoom) : prev.zoom,\n };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_set_view\",\n label: `Moved camera to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`,\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Camera → ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_pan\",\n \"Pan the camera by a relative offset in degrees (positive dLat = north, positive dLng = east).\",\n { dLat: { type: \"number\" }, dLng: { type: \"number\" } },\n [],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = {\n ...prev,\n center: { lat: prev.center.lat + num(args.dLat), lng: prev.center.lng + num(args.dLng) },\n };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_pan\",\n label: \"Panned camera\",\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Panned to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_zoom\",\n \"Zoom the camera by a relative delta (e.g. +1 zooms in one level, -2 out two).\",\n { delta: { type: \"number\" } },\n [\"delta\"],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = { ...prev, zoom: prev.zoom + num(args.delta) };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_zoom\",\n label: `Zoom → ${next.zoom}`,\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Zoom → ${next.zoom}`, next);\n },\n );\n\n reg(\n \"map_fit_bounds\",\n \"Fit the camera to enclose points. Pass `points`, or omit to fit all current markers.\",\n {\n points: {\n type: \"array\",\n description: \"Points to enclose, e.g. [{lat,lng},…].\",\n items: {\n type: \"object\",\n properties: { lat: { type: \"number\" }, lng: { type: \"number\" } },\n required: [\"lat\", \"lng\"],\n },\n },\n padding: { type: \"number\", description: \"Padding in pixels (default 40).\" },\n },\n [],\n (args) => {\n if (!adapter.fitBounds) {\n return errorResult(\"Host did not wire fitBounds (pass the <Map onReady> handle's fitBounds).\");\n }\n const points: LatLng[] = Array.isArray(args.points)\n ? (args.points as any[]).map((p) => ({ lat: num(p?.lat), lng: num(p?.lng) }))\n : adapter.getMarkers().map((m) => m.position);\n if (!points.length) {\n return errorResult(\"No points to fit (map has no markers).\");\n }\n adapter.fitBounds(points, args.padding !== undefined ? num(args.padding) : undefined);\n return textResult(`Fit camera to ${points.length} point(s).`);\n },\n );\n\n // ───────────── Markers ─────────────\n\n reg(\n \"map_add_marker\",\n \"Drop a marker. `id` is optional (auto-generated); `icon` is an emoji or 1–2 chars.\",\n {\n id: { type: \"string\" },\n lat: { type: \"number\" },\n lng: { type: \"number\" },\n label: { type: \"string\" },\n color: { type: \"string\", description: \"CSS color, e.g. #2563eb.\" },\n icon: { type: \"string\", description: \"Emoji / short text in the pin.\" },\n draggable: { type: \"boolean\" },\n data: { type: \"object\", description: \"Arbitrary JSON payload carried with the marker.\" },\n },\n [\"lat\", \"lng\"],\n (args) => {\n const id = args.id ? str(args.id) : newId(\"m\");\n if (adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`A marker with id ${id} already exists — use map_update_marker.`);\n }\n const marker: MapMarker = {\n id,\n position: { lat: num(args.lat), lng: num(args.lng) },\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n ...(args.icon !== undefined ? { icon: str(args.icon) } : {}),\n ...(args.draggable !== undefined ? { draggable: !!args.draggable } : {}),\n ...(args.data && typeof args.data === \"object\"\n ? { data: args.data as Record<string, unknown> }\n : {}),\n };\n adapter.setMarkers((all) => [...all, marker]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_add_marker\",\n label: `Added marker ${id}`,\n undo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id)),\n redo: () => adapter.setMarkers((all) => [...all, marker]),\n });\n return textResult(`Added marker ${id} at ${marker.position.lat.toFixed(4)},${marker.position.lng.toFixed(4)}`, marker);\n },\n mTarget,\n );\n\n reg(\n \"map_update_marker\",\n \"Update a marker. Only provided fields change — update lat/lng repeatedly to drive a live track.\",\n {\n id: { type: \"string\" },\n lat: { type: \"number\" },\n lng: { type: \"number\" },\n label: { type: \"string\" },\n color: { type: \"string\" },\n icon: { type: \"string\" },\n draggable: { type: \"boolean\" },\n },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const prev = adapter.getMarkers().find((m) => m.id === id);\n if (!prev) {\n return errorResult(`No marker with id ${id}`);\n }\n const next: MapMarker = {\n ...prev,\n position: {\n lat: args.lat !== undefined ? num(args.lat) : prev.position.lat,\n lng: args.lng !== undefined ? num(args.lng) : prev.position.lng,\n },\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n ...(args.icon !== undefined ? { icon: str(args.icon) } : {}),\n ...(args.draggable !== undefined ? { draggable: !!args.draggable } : {}),\n };\n adapter.setMarkers((all) => all.map((m) => (m.id === id ? next : m)));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_update_marker\",\n label: `Updated marker ${id}`,\n undo: () => adapter.setMarkers((all) => all.map((m) => (m.id === id ? prev : m))),\n redo: () => adapter.setMarkers((all) => all.map((m) => (m.id === id ? next : m))),\n });\n return textResult(`Updated marker ${id}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_remove_marker\",\n \"Remove a marker by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const prev = adapter.getMarkers().find((m) => m.id === id);\n if (!prev) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setMarkers((all) => all.filter((m) => m.id !== id));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_remove_marker\",\n label: `Removed marker ${id}`,\n undo: () => adapter.setMarkers((all) => [...all, prev]),\n redo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id)),\n });\n return textResult(`Removed marker ${id}`);\n },\n mTarget,\n );\n\n reg(\n \"map_select\",\n \"Select a marker (or pass no id / null to clear the selection).\",\n { id: { type: \"string\" } },\n [],\n (args) => {\n const prev = adapter.getSelected();\n const id = args.id === undefined || args.id === null ? null : str(args.id);\n if (id !== null && !adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setSelected(id);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_select\",\n label: id ? `Selected ${id}` : \"Cleared selection\",\n undo: () => adapter.setSelected(prev),\n redo: () => adapter.setSelected(id),\n });\n return textResult(id ? `Selected marker ${id}` : \"Cleared selection\", { selectedId: id });\n },\n mTarget,\n );\n\n // ───────────── Live tracking (camera follow) ─────────────\n\n reg(\n \"map_start_track\",\n \"Make the camera follow a marker as its position updates (live tracking). Requires the host to wire setFollow.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n if (!adapter.setFollow) {\n return errorResult(\"Host did not wire setFollow (pass the map's `follow` setter).\");\n }\n const id = str(args.id);\n if (!adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setFollow(id);\n return textResult(`Camera now following ${id}`, { follow: id });\n },\n mTarget,\n );\n\n reg(\n \"map_stop_track\",\n \"Stop following any marker (releases the camera). Requires the host to wire setFollow.\",\n {},\n [],\n () => {\n if (!adapter.setFollow) {\n return errorResult(\"Host did not wire setFollow.\");\n }\n adapter.setFollow(null);\n return textResult(\"Camera released (no longer following).\", { follow: null });\n },\n );\n\n return {\n id: \"map\",\n title: \"Map\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/bridges/map.ts"],"names":[],"mappings":"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","file":"chunk-NKRSLCS7.js","sourcesContent":["// Loose types so this bridge builds standalone without a hard dep on\n// @particle-academy/fancy-map. Hosts that use fancy-map pass its own\n// MapMarker / MapView values straight through — the shapes match.\ntype LatLng = { lat: number; lng: number };\ntype MapView = { center: LatLng; zoom: number; bearing?: number; pitch?: number };\ntype MapMarker = {\n id: string;\n position: LatLng;\n label?: string;\n color?: string;\n icon?: string;\n draggable?: boolean;\n data?: Record<string, unknown>;\n};\n\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget as MapAgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Adapter the host provides — getters/setters over the SAME controlled state it\n * passes to fancy-map's `<Map>` (view, markers, selection), plus optional\n * `fitBounds` (from the map's onReady handle) and `setFollow` (drives the map's\n * `follow` prop so an agent can make the camera track a moving marker).\n */\nexport type MapBridgeAdapter = {\n getView: () => MapView;\n setView: (next: MapView) => void;\n getMarkers: () => MapMarker[];\n setMarkers: (next: MapMarker[] | ((prev: MapMarker[]) => MapMarker[])) => void;\n getSelected: () => string | null;\n setSelected: (id: string | null) => void;\n /** Fit the camera to points (wire to the `MapHandle.fitBounds` from `<Map onReady>`). */\n fitBounds?: (points: LatLng[], padding?: number) => void;\n /** Make the camera follow a marker as it moves (drives the map's `follow` prop). */\n setFollow?: (id: string | null) => void;\n};\n\nexport type MapBridgeOptions = {\n adapter: MapBridgeAdapter;\n /** Identity tagged onto agent-authored markers. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\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 newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerMapBridge — an MCP tool set over a fancy-map `<Map>`'s controlled\n * state, so a human and an agent cohabit one map. The agent moves the camera,\n * drops/updates/removes markers, selects, fits bounds, and follows a live\n * track; every mutation broadcasts AgentActivity (for presence) and pushes an\n * undo entry (so the human can step the agent back). Mirrors the whiteboard /\n * flow bridges in shape.\n */\nexport function registerMapBridge(host: ToolHost, options: MapBridgeOptions): 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 host. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const mTarget = (args: any, result: any): MapAgentTarget => ({\n kind: \"map\",\n elementId:\n (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n resolveTarget?: (args: JsonObject, result: any) => MapAgentTarget | 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: \"map\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read ─────────────\n\n reg(\"map_get_state\", \"Get the map's camera, markers, and current selection.\", {}, [], () => {\n const state = {\n view: adapter.getView(),\n markers: adapter.getMarkers(),\n selectedId: adapter.getSelected(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n // ───────────── Camera ─────────────\n\n reg(\n \"map_set_view\",\n \"Move the camera to an absolute position. Any omitted field is left unchanged.\",\n {\n lat: { type: \"number\", description: \"New center latitude.\" },\n lng: { type: \"number\", description: \"New center longitude.\" },\n zoom: { type: \"number\", description: \"New zoom level (higher = closer).\" },\n },\n [],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = {\n center: {\n lat: args.lat !== undefined ? num(args.lat) : prev.center.lat,\n lng: args.lng !== undefined ? num(args.lng) : prev.center.lng,\n },\n zoom: args.zoom !== undefined ? num(args.zoom) : prev.zoom,\n };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_set_view\",\n label: `Moved camera to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`,\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Camera → ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_pan\",\n \"Pan the camera by a relative offset in degrees (positive dLat = north, positive dLng = east).\",\n { dLat: { type: \"number\" }, dLng: { type: \"number\" } },\n [],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = {\n ...prev,\n center: { lat: prev.center.lat + num(args.dLat), lng: prev.center.lng + num(args.dLng) },\n };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_pan\",\n label: \"Panned camera\",\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Panned to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_zoom\",\n \"Zoom the camera by a relative delta (e.g. +1 zooms in one level, -2 out two).\",\n { delta: { type: \"number\" } },\n [\"delta\"],\n (args) => {\n const prev = adapter.getView();\n const next: MapView = { ...prev, zoom: prev.zoom + num(args.delta) };\n adapter.setView(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_zoom\",\n label: `Zoom → ${next.zoom}`,\n undo: () => adapter.setView(prev),\n redo: () => adapter.setView(next),\n });\n return textResult(`Zoom → ${next.zoom}`, next);\n },\n );\n\n reg(\n \"map_fit_bounds\",\n \"Fit the camera to enclose points. Pass `points`, or omit to fit all current markers.\",\n {\n points: {\n type: \"array\",\n description: \"Points to enclose, e.g. [{lat,lng},…].\",\n items: {\n type: \"object\",\n properties: { lat: { type: \"number\" }, lng: { type: \"number\" } },\n required: [\"lat\", \"lng\"],\n },\n },\n padding: { type: \"number\", description: \"Padding in pixels (default 40).\" },\n },\n [],\n (args) => {\n if (!adapter.fitBounds) {\n return errorResult(\"Host did not wire fitBounds (pass the <Map onReady> handle's fitBounds).\");\n }\n const points: LatLng[] = Array.isArray(args.points)\n ? (args.points as any[]).map((p) => ({ lat: num(p?.lat), lng: num(p?.lng) }))\n : adapter.getMarkers().map((m) => m.position);\n if (!points.length) {\n return errorResult(\"No points to fit (map has no markers).\");\n }\n adapter.fitBounds(points, args.padding !== undefined ? num(args.padding) : undefined);\n return textResult(`Fit camera to ${points.length} point(s).`);\n },\n );\n\n // ───────────── Markers ─────────────\n\n reg(\n \"map_add_marker\",\n \"Drop a marker. `id` is optional (auto-generated); `icon` is an emoji or 1–2 chars.\",\n {\n id: { type: \"string\" },\n lat: { type: \"number\" },\n lng: { type: \"number\" },\n label: { type: \"string\" },\n color: { type: \"string\", description: \"CSS color, e.g. #2563eb.\" },\n icon: { type: \"string\", description: \"Emoji / short text in the pin.\" },\n draggable: { type: \"boolean\" },\n data: { type: \"object\", description: \"Arbitrary JSON payload carried with the marker.\" },\n },\n [\"lat\", \"lng\"],\n (args) => {\n const id = args.id ? str(args.id) : newId(\"m\");\n if (adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`A marker with id ${id} already exists — use map_update_marker.`);\n }\n const marker: MapMarker = {\n id,\n position: { lat: num(args.lat), lng: num(args.lng) },\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n ...(args.icon !== undefined ? { icon: str(args.icon) } : {}),\n ...(args.draggable !== undefined ? { draggable: !!args.draggable } : {}),\n ...(args.data && typeof args.data === \"object\"\n ? { data: args.data as Record<string, unknown> }\n : {}),\n };\n adapter.setMarkers((all) => [...all, marker]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_add_marker\",\n label: `Added marker ${id}`,\n undo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id)),\n redo: () => adapter.setMarkers((all) => [...all, marker]),\n });\n return textResult(`Added marker ${id} at ${marker.position.lat.toFixed(4)},${marker.position.lng.toFixed(4)}`, marker);\n },\n mTarget,\n );\n\n reg(\n \"map_update_marker\",\n \"Update a marker. Only provided fields change — update lat/lng repeatedly to drive a live track.\",\n {\n id: { type: \"string\" },\n lat: { type: \"number\" },\n lng: { type: \"number\" },\n label: { type: \"string\" },\n color: { type: \"string\" },\n icon: { type: \"string\" },\n draggable: { type: \"boolean\" },\n },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const prev = adapter.getMarkers().find((m) => m.id === id);\n if (!prev) {\n return errorResult(`No marker with id ${id}`);\n }\n const next: MapMarker = {\n ...prev,\n position: {\n lat: args.lat !== undefined ? num(args.lat) : prev.position.lat,\n lng: args.lng !== undefined ? num(args.lng) : prev.position.lng,\n },\n ...(args.label !== undefined ? { label: str(args.label) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n ...(args.icon !== undefined ? { icon: str(args.icon) } : {}),\n ...(args.draggable !== undefined ? { draggable: !!args.draggable } : {}),\n };\n adapter.setMarkers((all) => all.map((m) => (m.id === id ? next : m)));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_update_marker\",\n label: `Updated marker ${id}`,\n undo: () => adapter.setMarkers((all) => all.map((m) => (m.id === id ? prev : m))),\n redo: () => adapter.setMarkers((all) => all.map((m) => (m.id === id ? next : m))),\n });\n return textResult(`Updated marker ${id}`, next);\n },\n mTarget,\n );\n\n reg(\n \"map_remove_marker\",\n \"Remove a marker by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const prev = adapter.getMarkers().find((m) => m.id === id);\n if (!prev) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setMarkers((all) => all.filter((m) => m.id !== id));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_remove_marker\",\n label: `Removed marker ${id}`,\n undo: () => adapter.setMarkers((all) => [...all, prev]),\n redo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id)),\n });\n return textResult(`Removed marker ${id}`);\n },\n mTarget,\n );\n\n reg(\n \"map_select\",\n \"Select a marker (or pass no id / null to clear the selection).\",\n { id: { type: \"string\" } },\n [],\n (args) => {\n const prev = adapter.getSelected();\n const id = args.id === undefined || args.id === null ? null : str(args.id);\n if (id !== null && !adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setSelected(id);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"map\",\n action: \"map_select\",\n label: id ? `Selected ${id}` : \"Cleared selection\",\n undo: () => adapter.setSelected(prev),\n redo: () => adapter.setSelected(id),\n });\n return textResult(id ? `Selected marker ${id}` : \"Cleared selection\", { selectedId: id });\n },\n mTarget,\n );\n\n // ───────────── Live tracking (camera follow) ─────────────\n\n reg(\n \"map_start_track\",\n \"Make the camera follow a marker as its position updates (live tracking). Requires the host to wire setFollow.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n if (!adapter.setFollow) {\n return errorResult(\"Host did not wire setFollow (pass the map's `follow` setter).\");\n }\n const id = str(args.id);\n if (!adapter.getMarkers().some((m) => m.id === id)) {\n return errorResult(`No marker with id ${id}`);\n }\n adapter.setFollow(id);\n return textResult(`Camera now following ${id}`, { follow: id });\n },\n mTarget,\n );\n\n reg(\n \"map_stop_track\",\n \"Stop following any marker (releases the camera). Requires the host to wire setFollow.\",\n {},\n [],\n () => {\n if (!adapter.setFollow) {\n return errorResult(\"Host did not wire setFollow.\");\n }\n adapter.setFollow(null);\n return textResult(\"Camera released (no longer following).\", { follow: null });\n },\n );\n\n return {\n id: \"map\",\n title: \"Map\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { ensureUndoToolsRegistered } from './chunk-KJ5AOOV7.js';
1
2
  import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
2
3
  import { textResult, errorResult } from './chunk-4KAIV6OD.js';
3
4
 
@@ -7,6 +8,7 @@ function registerCodeBridge(host, options) {
7
8
  const { adapter } = options;
8
9
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
9
10
  const disposers = [];
11
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
10
12
  const target = {
11
13
  kind: "code",
12
14
  screenId: adapter.screenId,
@@ -168,5 +170,5 @@ function registerCodeBridge(host, options) {
168
170
  }
169
171
 
170
172
  export { registerCodeBridge };
171
- //# sourceMappingURL=chunk-FYGMFIY5.js.map
172
- //# sourceMappingURL=chunk-FYGMFIY5.js.map
173
+ //# sourceMappingURL=chunk-QDF37J3V.js.map
174
+ //# sourceMappingURL=chunk-QDF37J3V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/code.ts"],"names":[],"mappings":"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","file":"chunk-QDF37J3V.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 type { AgentTarget } from \"../presence/types\";\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 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 adapter.setValue(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 next = adapter.getValue() + text;\n adapter.setValue(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 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 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 adapter.replaceSelection(String(args.text ?? \"\"));\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 adapter.setLanguage(lang);\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 true,\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,3 +1,4 @@
1
+ import { ensureUndoToolsRegistered } from './chunk-KJ5AOOV7.js';
1
2
  import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
2
3
  import { textResult, errorResult } from './chunk-4KAIV6OD.js';
3
4
 
@@ -7,6 +8,7 @@ function registerSheetsBridge(host, options) {
7
8
  const { adapter } = options;
8
9
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
9
10
  const disposers = [];
11
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
10
12
  const target = (sheetId, address) => ({
11
13
  kind: "sheet",
12
14
  screenId: adapter.screenId,
@@ -269,5 +271,5 @@ function readRange(sheet, startAddr, endAddr) {
269
271
  }
270
272
 
271
273
  export { registerSheetsBridge };
272
- //# sourceMappingURL=chunk-HIMTURWL.js.map
273
- //# sourceMappingURL=chunk-HIMTURWL.js.map
274
+ //# sourceMappingURL=chunk-V5BXBX7U.js.map
275
+ //# sourceMappingURL=chunk-V5BXBX7U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/sheets.ts"],"names":[],"mappings":"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","file":"chunk-V5BXBX7U.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 type { AgentTarget } from \"../presence/types\";\nimport type { CellValue, SheetData, SheetOp, WorkbookData } from \"@particle-academy/fancy-sheets\";\n\n/**\n * Cell writes funnel through fancy-sheets' own `reduceWorkbook` + `SheetOp` —\n * the same reducer that drives `<SheetWorkbook>` — so agent edits recalculate\n * formulas and land byte-identical to human edits, mirroring how the slides\n * bridge works. Types come straight from the package (no drift); the reducer\n * VALUE is lazy-imported inside the mutation handlers so the package barrel\n * never statically pulls this optional peer (see issue #3).\n */\n\nexport type SheetsBridgeAdapter = {\n /** fancy-screens screen id (optional) so activity events know which screen the sheet lives in. */\n screenId?: string;\n /** Read the current workbook. */\n getWorkbook: () => WorkbookData;\n /** Replace the workbook. Host wires this to its onChange. */\n setWorkbook: (next: WorkbookData) => void;\n /** Optional: programmatically change the active cell. */\n setActiveCell?: (sheetId: string, address: string) => void;\n};\n\nexport type SheetsBridgeOptions = {\n adapter: SheetsBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerSheetsBridge — schema-aware MCP access to a fancy-sheets workbook.\n * Tools are sheet-aware (every mutator takes an explicit `sheet` id, defaulting\n * to the active sheet when omitted) so an agent can author multi-sheet docs.\n */\nexport function registerSheetsBridge(\n host: ToolHost,\n options: SheetsBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // 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 = (sheetId: string, address?: string): AgentTarget => ({\n kind: \"sheet\",\n screenId: adapter.screenId,\n elementId: address ? `${sheetId}!${address}` : sheetId,\n label: address ? `${sheetId}!${address}` : sheetId,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n isMutation: boolean,\n resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent,\n kind: \"sheet\",\n screenId: adapter.screenId,\n resolveTarget: ({ args, result }) =>\n resolveTarget?.(args, result) ?? target(getSheetId(args)),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false },\n },\n final as any,\n ),\n );\n };\n\n function activeSheetId(): string {\n return adapter.getWorkbook().activeSheetId;\n }\n function getSheetId(args: JsonObject): string {\n return typeof args.sheet === \"string\" ? args.sheet : activeSheetId();\n }\n function getSheet(workbook: WorkbookData, sheetId: string): SheetData | undefined {\n return workbook.sheets.find((s) => s.id === sheetId);\n }\n\n // ───────────── Read tools ─────────────\n\n reg(\n \"sheet_describe\",\n \"Describe the workbook: every sheet's id, name, dimensions, cell count, active sheet. Call before reading or writing.\",\n {},\n [],\n () => {\n const wb = adapter.getWorkbook();\n const summary = {\n activeSheetId: wb.activeSheetId,\n sheets: wb.sheets.map((s) => ({\n id: s.id,\n name: s.name,\n cellCount: Object.keys(s.cells).length,\n columnCount: Object.keys(s.columnWidths).length,\n frozenRows: s.frozenRows,\n frozenCols: s.frozenCols,\n })),\n };\n const text = `Active: ${summary.activeSheetId}\\n` + summary.sheets\n .map((s) => `${s.id} \"${s.name}\" — ${s.cellCount} cells`)\n .join(\"\\n\");\n return textResult(text, summary);\n },\n false,\n );\n\n reg(\n \"sheet_get_cell\",\n \"Read a single cell's raw + computed value.\",\n {\n sheet: { type: \"string\", description: \"Sheet id (defaults to active).\" },\n address: { type: \"string\", description: \"A1-style address, e.g. \\\"B12\\\".\" },\n },\n [\"address\"],\n (args) => {\n const sheetId = getSheetId(args);\n const address = String(args.address);\n const sheet = getSheet(adapter.getWorkbook(), sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const cell = sheet.cells[address];\n if (!cell) {\n return textResult(`(empty)`, { sheet: sheetId, address, value: null });\n }\n return textResult(`${address} = ${JSON.stringify(cell.computedValue ?? cell.value)}`, { ...cell, sheet: sheetId, address });\n },\n false,\n );\n\n reg(\n \"sheet_get_range\",\n \"Read a rectangular range as a 2D array of values.\",\n {\n sheet: { type: \"string\" },\n start: { type: \"string\", description: \"Top-left A1 address.\" },\n end: { type: \"string\", description: \"Bottom-right A1 address.\" },\n },\n [\"start\", \"end\"],\n (args) => {\n const sheetId = getSheetId(args);\n const sheet = getSheet(adapter.getWorkbook(), sheetId);\n if (!sheet) return errorResult(`No sheet ${sheetId}`);\n const grid = readRange(sheet, String(args.start), String(args.end));\n return textResult(JSON.stringify(grid), { sheet: sheetId, start: args.start, end: args.end, values: grid });\n },\n false,\n );\n\n // ───────────── Mutation tools ─────────────\n\n reg(\n \"sheet_set_cell\",\n \"Set a single cell's value. To set a formula, pass a string starting with '='.\",\n {\n sheet: { type: \"string\" },\n address: { type: \"string\" },\n value: { description: \"string | number | boolean | null. Strings starting with '=' are stored as formulas.\" },\n },\n [\"address\", \"value\"],\n async (args) => {\n const sheetId = getSheetId(args);\n const address = String(args.address);\n const value = args.value as CellValue;\n const wb = adapter.getWorkbook();\n if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);\n const { reduceWorkbook } = await import(\"@particle-academy/fancy-sheets\");\n adapter.setWorkbook(reduceWorkbook(wb, setCellOp(sheetId, address, value)));\n return textResult(`${sheetId}!${address} ← ${JSON.stringify(value)}`, { sheet: sheetId, address, value });\n },\n true,\n (args) => target(getSheetId(args), String(args.address ?? \"\")),\n );\n\n reg(\n \"sheet_set_range\",\n \"Set many cells atomically. `cells` is an object map of { \\\"A1\\\": value, \\\"B2\\\": value, ... }.\",\n {\n sheet: { type: \"string\" },\n cells: { type: \"object\" },\n },\n [\"cells\"],\n async (args) => {\n const sheetId = getSheetId(args);\n const wb = adapter.getWorkbook();\n if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);\n const cells = (args.cells && typeof args.cells === \"object\") ? args.cells as Record<string, CellValue> : {};\n const { reduceWorkbook } = await import(\"@particle-academy/fancy-sheets\");\n let next = wb;\n for (const [addr, v] of Object.entries(cells)) next = reduceWorkbook(next, setCellOp(sheetId, addr, v));\n adapter.setWorkbook(next);\n return textResult(`Set ${Object.keys(cells).length} cells in ${sheetId}`, { sheet: sheetId, count: Object.keys(cells).length });\n },\n true,\n );\n\n reg(\n \"sheet_add_sheet\",\n \"Add a new sheet (tab) to the workbook.\",\n { id: { type: \"string\" }, name: { type: \"string\" } },\n [\"id\", \"name\"],\n (args) => {\n const wb = adapter.getWorkbook();\n const id = String(args.id);\n const name = String(args.name);\n if (wb.sheets.find((s) => s.id === id)) return errorResult(`Sheet ${id} already exists`);\n const next: WorkbookData = {\n ...wb,\n sheets: [\n ...wb.sheets,\n {\n id, name, cells: {}, columnWidths: {}, mergedRegions: [],\n columnFilters: {}, frozenRows: 0, frozenCols: 0,\n },\n ],\n };\n adapter.setWorkbook(next);\n return textResult(`Added sheet ${id} (\"${name}\")`, { id, name });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"sheet_set_active\",\n \"Switch to a different sheet tab.\",\n { sheet: { type: \"string\" } },\n [\"sheet\"],\n (args) => {\n const sheetId = String(args.sheet);\n const wb = adapter.getWorkbook();\n if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);\n adapter.setWorkbook({ ...wb, activeSheetId: sheetId });\n return textResult(`Active sheet → ${sheetId}`, { sheet: sheetId });\n },\n true,\n );\n\n reg(\n \"sheet_set_active_cell\",\n \"Move the active cell selection (host implements DOM focus + scroll).\",\n { sheet: { type: \"string\" }, address: { type: \"string\" } },\n [\"address\"],\n (args) => {\n if (!adapter.setActiveCell) return errorResult(\"Host did not provide setActiveCell.\");\n const sheetId = getSheetId(args);\n adapter.setActiveCell(sheetId, String(args.address));\n return textResult(`Active cell → ${sheetId}!${args.address}`, { sheet: sheetId, address: args.address });\n },\n true,\n (args) => target(getSheetId(args), String(args.address ?? \"\")),\n );\n\n return {\n id: \"sheets\",\n title: \"Sheets\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n\n// ───────────── helpers ─────────────\n\n/** Build a `set_cell` op, treating a leading-\"=\" string as a formula — matching\n * the in-app editor (value keeps the raw \"=…\"; formula drops the \"=\"). */\nfunction setCellOp(sheet: string, address: string, value: CellValue): SheetOp {\n if (typeof value === \"string\" && value.startsWith(\"=\")) {\n return { type: \"set_cell\", sheet, address, value, formula: value.slice(1) };\n }\n return { type: \"set_cell\", sheet, address, value };\n}\n\n/** Parse \"B12\" → { col: 1, row: 11 }. Letters are 1-based, rows 1-based. */\nfunction parseAddress(addr: string): { col: number; row: number } {\n const m = /^([A-Za-z]+)(\\d+)$/.exec(addr.trim());\n if (!m) throw new Error(`Bad address: ${addr}`);\n const letters = m[1].toUpperCase();\n let col = 0;\n for (let i = 0; i < letters.length; i++) {\n col = col * 26 + (letters.charCodeAt(i) - 64);\n }\n return { col: col - 1, row: parseInt(m[2], 10) - 1 };\n}\n\nfunction colToLetter(col: number): string {\n let s = \"\";\n let n = col + 1;\n while (n > 0) {\n const r = (n - 1) % 26;\n s = String.fromCharCode(65 + r) + s;\n n = Math.floor((n - 1) / 26);\n }\n return s;\n}\n\nfunction readRange(sheet: SheetData, startAddr: string, endAddr: string): CellValue[][] {\n const start = parseAddress(startAddr);\n const end = parseAddress(endAddr);\n const r0 = Math.min(start.row, end.row);\n const r1 = Math.max(start.row, end.row);\n const c0 = Math.min(start.col, end.col);\n const c1 = Math.max(start.col, end.col);\n const grid: CellValue[][] = [];\n for (let r = r0; r <= r1; r++) {\n const row: CellValue[] = [];\n for (let c = c0; c <= c1; c++) {\n const addr = `${colToLetter(c)}${r + 1}`;\n const cell = sheet.cells[addr];\n row.push(cell?.computedValue ?? cell?.value ?? null);\n }\n grid.push(row);\n }\n return grid;\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { ensureUndoToolsRegistered } from './chunk-KJ5AOOV7.js';
1
2
  import { wrapToolWithActivity } from './chunk-ULJL53DL.js';
2
3
  import { textResult, errorResult } from './chunk-4KAIV6OD.js';
3
4
 
@@ -7,6 +8,7 @@ function registerScreensBridge(host, options) {
7
8
  const { adapter } = options;
8
9
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
9
10
  const disposers = [];
11
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
10
12
  const target = (screenId) => ({
11
13
  kind: "screens",
12
14
  screenId,
@@ -176,5 +178,5 @@ function registerScreensBridge(host, options) {
176
178
  }
177
179
 
178
180
  export { registerScreensBridge };
179
- //# sourceMappingURL=chunk-CKK4QKD2.js.map
180
- //# sourceMappingURL=chunk-CKK4QKD2.js.map
181
+ //# sourceMappingURL=chunk-YMX7G3XM.js.map
182
+ //# sourceMappingURL=chunk-YMX7G3XM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridges/screens.ts"],"names":[],"mappings":"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","file":"chunk-YMX7G3XM.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 type { AgentTarget } from \"../presence/types\";\n\n/**\n * Loose snapshot of a screen — what's in fancy-screens' ScreenMeta plus\n * the host's optional activity status. Kept here so this bridge has no\n * hard dep on fancy-screens.\n */\nexport type ScreenSnapshot = {\n id: string;\n title?: string;\n /** Whether this screen is the one the human / agent is looking at. */\n active: boolean;\n /** Optional category / kind (e.g. \"form\", \"whiteboard\"). */\n kind?: string;\n};\n\n/**\n * Spec for a dynamically-created screen. The host's `createScreen`\n * implementation looks up `kind` in its template registry and instantiates\n * the matching surface (form / whiteboard / sheet / chart / markdown / etc.).\n */\nexport type ScreenCreateSpec = {\n id: string;\n title?: string;\n /** Template kind. Hosts decide the catalog. */\n kind: string;\n /** Template-specific config. Form: { fields }. Sheet: { headers }. etc. */\n config?: Record<string, unknown>;\n};\n\n/**\n * Adapter exposes the host's screen-navigation surface to the bridge.\n * Hosts wire this up against react-router, a custom tab state, or the\n * fancy-screens registry — wherever \"current screen\" lives.\n *\n * The optional create / destroy / update hooks let agents author screens\n * dynamically against a host-defined template catalog.\n */\nexport type ScreensBridgeAdapter = {\n /** List every available screen. */\n listScreens: () => ScreenSnapshot[];\n /** Read which screen is currently active. */\n getActive: () => string | null;\n /** Navigate to a screen by id. Host updates router / tab state. */\n setActive: (screenId: string) => void;\n /** Optional: instantiate a new screen from a template + config. */\n createScreen?: (spec: ScreenCreateSpec) => void;\n /** Optional: remove a previously-created screen. */\n destroyScreen?: (screenId: string) => void;\n /** Optional: shallow-merge new config into an existing screen. */\n updateScreenContent?: (screenId: string, partial: Record<string, unknown>) => void;\n /** Optional: enumerate the kinds the host knows how to instantiate. */\n listKinds?: () => Array<{ kind: string; label?: string; description?: string; configSchema?: unknown }>;\n};\n\nexport type ScreensBridgeOptions = {\n adapter: ScreensBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * registerScreensBridge — top-level navigation bridge so agents can\n * switch between screens (`screens_navigate`) and discover what surfaces\n * exist (`screens_list`, `screens_describe_active`).\n *\n * Pair with the per-surface bridges (whiteboard, form, sheet, etc.) so\n * the agent has both navigation and per-screen control.\n */\nexport function registerScreensBridge(\n host: ToolHost,\n options: ScreensBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // 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(e instanceof Error ? e.message : String(e)); }\n };\n const final = isMutation\n ? wrapToolWithActivity(wrapped, {\n toolName: name, agent, kind: \"screens\",\n resolveTarget: ({ args }) => targetFromArgs?.(args) ?? null,\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as any, required, additionalProperties: false } },\n final as any,\n ),\n );\n };\n\n reg(\n \"screens_list\",\n \"List every screen the host has registered. Returns id, title, active flag, and optional kind.\",\n {},\n [],\n () => {\n const screens = adapter.listScreens();\n const text = screens\n .map((s) => `${s.active ? \"▸\" : \" \"} ${s.id}${s.title ? ` — ${s.title}` : \"\"}${s.kind ? ` [${s.kind}]` : \"\"}`)\n .join(\"\\n\");\n return textResult(text || \"(no screens)\", { screens, active: adapter.getActive() });\n },\n false,\n );\n\n reg(\n \"screens_describe_active\",\n \"Get the currently-active screen id (or null).\",\n {},\n [],\n () => {\n const active = adapter.getActive();\n return textResult(active ?? \"(none)\", { active });\n },\n false,\n );\n\n reg(\n \"screens_list_kinds\",\n \"List the screen kinds (templates) the host knows how to instantiate. Use this before screens_create to know what's available.\",\n {},\n [],\n () => {\n if (!adapter.listKinds) return errorResult(\"Host did not register a kind catalog. Cannot create screens dynamically.\");\n const kinds = adapter.listKinds();\n const text = kinds.map((k) => `${k.kind}${k.label ? ` — ${k.label}` : \"\"}${k.description ? ` (${k.description})` : \"\"}`).join(\"\\n\");\n return textResult(text || \"(no kinds registered)\", kinds);\n },\n false,\n );\n\n reg(\n \"screens_create\",\n \"Instantiate a new screen from a template kind + config. Switches the active view to the new screen.\",\n {\n id: { type: \"string\", description: \"Stable screen id. Must be unique.\" },\n title: { type: \"string\" },\n kind: { type: \"string\", description: \"Template kind — call screens_list_kinds for the catalog.\" },\n config: { type: \"object\", description: \"Template-specific config (e.g. { fields: [...] } for a form).\" },\n },\n [\"id\", \"kind\"],\n (args) => {\n if (!adapter.createScreen) return errorResult(\"Host did not provide createScreen.\");\n const id = String(args.id);\n const kind = String(args.kind);\n if (adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`Screen ${id} already exists. Use screens_destroy first or pick a fresh id.`);\n }\n adapter.createScreen({\n id,\n title: typeof args.title === \"string\" ? args.title : undefined,\n kind,\n config: (args.config && typeof args.config === \"object\") ? args.config as Record<string, unknown> : undefined,\n });\n adapter.setActive(id);\n return textResult(`Created ${kind} screen \"${id}\"`, { id, kind });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_destroy\",\n \"Remove a previously-created screen. Active screen falls back to the first remaining one (or null).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n if (!adapter.destroyScreen) return errorResult(\"Host did not provide destroyScreen.\");\n const id = String(args.id);\n if (!adapter.listScreens().find((s) => s.id === id)) {\n return errorResult(`No screen with id ${id}`);\n }\n adapter.destroyScreen(id);\n return textResult(`Destroyed screen ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_set_layout\",\n \"Change the layout of an existing composite screen. Layouts: 'single', 'split-h' (left/right), 'split-v' (top/bottom), 'grid-2x2', 'stack' (tabs).\",\n {\n id: { type: \"string\" },\n layout: { type: \"string\", enum: [\"single\", \"split-h\", \"split-v\", \"grid-2x2\", \"stack\"] },\n },\n [\"id\", \"layout\"],\n (args) => {\n if (!adapter.updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n adapter.updateScreenContent(String(args.id), { layout: String(args.layout) });\n return textResult(`Layout of ${args.id} → ${args.layout}`, { id: args.id, layout: args.layout });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_update_content\",\n \"Merge new config into an existing screen (e.g. add a field to a form, append a sheet column, change chart series).\",\n {\n id: { type: \"string\" },\n partial: { type: \"object\", description: \"Shallow-merged into the screen's config.\" },\n },\n [\"id\", \"partial\"],\n (args) => {\n if (!adapter.updateScreenContent) return errorResult(\"Host did not provide updateScreenContent.\");\n const id = String(args.id);\n const partial = (args.partial && typeof args.partial === \"object\") ? args.partial as Record<string, unknown> : {};\n adapter.updateScreenContent(id, partial);\n return textResult(`Updated content of ${id}`, { id });\n },\n true,\n (args) => target(String(args.id ?? \"\")),\n );\n\n reg(\n \"screens_navigate\",\n \"Switch the human's view to a different screen. The host updates its router / tab state and re-renders.\",\n { screen: { type: \"string\", description: \"Screen id to activate.\" } },\n [\"screen\"],\n (args) => {\n const screenId = String(args.screen ?? \"\");\n const screens = adapter.listScreens();\n if (!screens.find((s) => s.id === screenId)) {\n return errorResult(`No screen registered with id \"${screenId}\". Call screens_list first.`);\n }\n adapter.setActive(screenId);\n return textResult(`Navigated to ${screenId}`, { screen: screenId });\n },\n true,\n (args) => target(String(args.screen ?? \"\")),\n );\n\n return {\n id: \"screens\",\n title: \"Screens\",\n dispose: () => { for (const d of disposers) d(); },\n };\n}\n"]}