@particle-academy/agent-integrations 0.22.0 → 0.24.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.
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var fancyAutoCommon = require('@particle-academy/fancy-auto-common');
4
+ var fancySheets = require('@particle-academy/fancy-sheets');
4
5
  var react = require('react');
5
6
  var fancySlides = require('@particle-academy/fancy-slides');
6
7
  var jsxRuntime = require('react/jsx-runtime');
@@ -437,8 +438,6 @@ function registerFormBridge(host, options) {
437
438
  }
438
439
  };
439
440
  }
440
-
441
- // src/bridges/sheets.ts
442
441
  var DEFAULT_AGENT2 = { id: "agent", name: "Agent", color: "#a855f7" };
443
442
  function registerSheetsBridge(host, options) {
444
443
  const { adapter } = options;
@@ -562,10 +561,8 @@ function registerSheetsBridge(host, options) {
562
561
  const address = String(args.address);
563
562
  const value = args.value;
564
563
  const wb = adapter.getWorkbook();
565
- const sheet = getSheet(wb, sheetId);
566
- if (!sheet) return errorResult(`No sheet ${sheetId}`);
567
- const next = mergeCells(wb, sheetId, { [address]: cellOf(address, value) });
568
- adapter.setWorkbook(next);
564
+ if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);
565
+ adapter.setWorkbook(fancySheets.reduceWorkbook(wb, setCellOp(sheetId, address, value)));
569
566
  return textResult(`${sheetId}!${address} \u2190 ${JSON.stringify(value)}`, { sheet: sheetId, address, value });
570
567
  },
571
568
  true,
@@ -582,12 +579,10 @@ function registerSheetsBridge(host, options) {
582
579
  (args) => {
583
580
  const sheetId = getSheetId(args);
584
581
  const wb = adapter.getWorkbook();
585
- const sheet = getSheet(wb, sheetId);
586
- if (!sheet) return errorResult(`No sheet ${sheetId}`);
582
+ if (!getSheet(wb, sheetId)) return errorResult(`No sheet ${sheetId}`);
587
583
  const cells = args.cells && typeof args.cells === "object" ? args.cells : {};
588
- const updates = {};
589
- for (const [addr, v] of Object.entries(cells)) updates[addr] = cellOf(addr, v);
590
- const next = mergeCells(wb, sheetId, updates);
584
+ let next = wb;
585
+ for (const [addr, v] of Object.entries(cells)) next = fancySheets.reduceWorkbook(next, setCellOp(sheetId, addr, v));
591
586
  adapter.setWorkbook(next);
592
587
  return textResult(`Set ${Object.keys(cells).length} cells in ${sheetId}`, { sheet: sheetId, count: Object.keys(cells).length });
593
588
  },
@@ -661,16 +656,11 @@ function registerSheetsBridge(host, options) {
661
656
  }
662
657
  };
663
658
  }
664
- function cellOf(address, value) {
665
- return { address, value };
666
- }
667
- function mergeCells(wb, sheetId, updates) {
668
- return {
669
- ...wb,
670
- sheets: wb.sheets.map(
671
- (s) => s.id !== sheetId ? s : { ...s, cells: { ...s.cells, ...updates } }
672
- )
673
- };
659
+ function setCellOp(sheet, address, value) {
660
+ if (typeof value === "string" && value.startsWith("=")) {
661
+ return { type: "set_cell", sheet, address, value, formula: value.slice(1) };
662
+ }
663
+ return { type: "set_cell", sheet, address, value };
674
664
  }
675
665
  function parseAddress(addr) {
676
666
  const m = /^([A-Za-z]+)(\d+)$/.exec(addr.trim());
@@ -1567,7 +1557,7 @@ function registerSlidesBridge(host, options) {
1567
1557
  ["title"],
1568
1558
  (args) => {
1569
1559
  const title = str(args.title);
1570
- adapter.apply({ kind: "deck_set_title", title });
1560
+ adapter.apply({ op: "deck.setTitle", title });
1571
1561
  return textResult(`Title set to "${title}"`, { title });
1572
1562
  },
1573
1563
  true,
@@ -1588,7 +1578,7 @@ function registerSlidesBridge(host, options) {
1588
1578
  } else {
1589
1579
  return errorResult("theme must be a string name or an object with a `name` field.");
1590
1580
  }
1591
- adapter.apply({ kind: "deck_apply_theme", theme });
1581
+ adapter.apply({ op: "deck.setTheme", theme });
1592
1582
  return textResult(`Applied theme: ${theme.name}`, { theme });
1593
1583
  },
1594
1584
  true,
@@ -1610,7 +1600,7 @@ function registerSlidesBridge(host, options) {
1610
1600
  } catch (e) {
1611
1601
  return errorResult(e instanceof Error ? e.message : String(e));
1612
1602
  }
1613
- adapter.apply({ kind: "deck_set", deck });
1603
+ adapter.apply({ op: "deck.replace", deck });
1614
1604
  return textResult(`Loaded deck "${deck.title}" (${deck.slides.length} slides)`, { id: deck.id, slides: deck.slides.length });
1615
1605
  },
1616
1606
  true,
@@ -1637,7 +1627,7 @@ function registerSlidesBridge(host, options) {
1637
1627
  metadata: incoming.metadata
1638
1628
  };
1639
1629
  const index = clamp(num(args.index, deck.slides.length), 0, deck.slides.length);
1640
- adapter.apply({ kind: "slide_add", index, slide });
1630
+ adapter.apply({ op: "slide.add", index, slide });
1641
1631
  return textResult(`Added slide ${slide.id} at index ${index}`, { id: slide.id, index });
1642
1632
  },
1643
1633
  true,
@@ -1650,7 +1640,7 @@ function registerSlidesBridge(host, options) {
1650
1640
  ["id"],
1651
1641
  (args) => {
1652
1642
  const id = str(args.id);
1653
- adapter.apply({ kind: "slide_remove", id });
1643
+ adapter.apply({ op: "slide.remove", slideId: id });
1654
1644
  return textResult(`Removed slide ${id}`, { id });
1655
1645
  },
1656
1646
  true,
@@ -1664,7 +1654,7 @@ function registerSlidesBridge(host, options) {
1664
1654
  (args) => {
1665
1655
  const id = str(args.id);
1666
1656
  const toIndex = num(args.toIndex, 0);
1667
- adapter.apply({ kind: "slide_reorder", id, toIndex });
1657
+ adapter.apply({ op: "slide.reorder", slideId: id, toIndex });
1668
1658
  return textResult(`Moved slide ${id} \u2192 ${toIndex}`, { id, toIndex });
1669
1659
  },
1670
1660
  true,
@@ -1678,7 +1668,7 @@ function registerSlidesBridge(host, options) {
1678
1668
  (args) => {
1679
1669
  const id = str(args.id);
1680
1670
  const layout = str(args.layout);
1681
- adapter.apply({ kind: "slide_set_layout", id, layout: layout ?? "blank" });
1671
+ adapter.apply({ op: "slide.setLayout", slideId: id, layout: layout ?? "blank" });
1682
1672
  return textResult(`Slide ${id} layout \u2192 ${layout}`, { id, layout });
1683
1673
  },
1684
1674
  true,
@@ -1692,7 +1682,7 @@ function registerSlidesBridge(host, options) {
1692
1682
  (args) => {
1693
1683
  const id = str(args.id);
1694
1684
  const notes = str(args.notes);
1695
- adapter.apply({ kind: "slide_set_notes", id, notes });
1685
+ adapter.apply({ op: "slide.setNotes", slideId: id, notes });
1696
1686
  return textResult(`Notes updated on slide ${id}`, { id });
1697
1687
  },
1698
1688
  true,
@@ -1709,7 +1699,7 @@ function registerSlidesBridge(host, options) {
1709
1699
  (args) => {
1710
1700
  const id = str(args.id);
1711
1701
  const bg = args.background && typeof args.background === "object" ? args.background : void 0;
1712
- adapter.apply({ kind: "slide_set_background", id, background: bg });
1702
+ adapter.apply({ op: "slide.setBackground", slideId: id, background: bg });
1713
1703
  return textResult(`Background set on slide ${id}`, { id });
1714
1704
  },
1715
1705
  true,
@@ -1728,7 +1718,7 @@ function registerSlidesBridge(host, options) {
1728
1718
  (args) => {
1729
1719
  const id = str(args.id);
1730
1720
  const transition = args.transition && typeof args.transition === "object" ? args.transition : void 0;
1731
- adapter.apply({ kind: "slide_set_transition", id, transition });
1721
+ adapter.apply({ op: "slide.setTransition", slideId: id, transition });
1732
1722
  return textResult(`Transition set on slide ${id}`, { id });
1733
1723
  },
1734
1724
  true,
@@ -1750,7 +1740,7 @@ function registerSlidesBridge(host, options) {
1750
1740
  id: incoming.id ?? fancySlides.elementId(),
1751
1741
  ...incoming
1752
1742
  };
1753
- adapter.apply({ kind: "element_add", slideId, element });
1743
+ adapter.apply({ op: "element.add", slideId, element });
1754
1744
  return textResult(`Added ${element.type} element ${element.id} on ${slideId}`, { id: element.id, slideId });
1755
1745
  },
1756
1746
  true,
@@ -1764,7 +1754,7 @@ function registerSlidesBridge(host, options) {
1764
1754
  (args) => {
1765
1755
  const slideId = str(args.slideId);
1766
1756
  const elementId = str(args.elementId);
1767
- adapter.apply({ kind: "element_remove", slideId, elementId });
1757
+ adapter.apply({ op: "element.remove", slideId, elementId });
1768
1758
  return textResult(`Removed element ${elementId} from ${slideId}`, { slideId, elementId });
1769
1759
  },
1770
1760
  true,
@@ -1783,7 +1773,7 @@ function registerSlidesBridge(host, options) {
1783
1773
  const slideId = str(args.slideId);
1784
1774
  const elementId = str(args.elementId);
1785
1775
  const patch = args.patch && typeof args.patch === "object" ? args.patch : {};
1786
- adapter.apply({ kind: "element_update", slideId, elementId, patch });
1776
+ adapter.apply({ op: "element.update", slideId, elementId, patch });
1787
1777
  return textResult(`Patched element ${elementId}`, { keys: Object.keys(patch) });
1788
1778
  },
1789
1779
  true,
@@ -1804,7 +1794,7 @@ function registerSlidesBridge(host, options) {
1804
1794
  const elementId = str(args.elementId);
1805
1795
  const x = clamp(num(args.x, 0), 0, 1);
1806
1796
  const y = clamp(num(args.y, 0), 0, 1);
1807
- adapter.apply({ kind: "element_move", slideId, elementId, x, y });
1797
+ adapter.apply({ op: "element.move", slideId, elementId, x, y });
1808
1798
  return textResult(`Moved element ${elementId} \u2192 (${x}, ${y})`, { x, y });
1809
1799
  },
1810
1800
  true,
@@ -1825,7 +1815,7 @@ function registerSlidesBridge(host, options) {
1825
1815
  const elementId = str(args.elementId);
1826
1816
  const w = clamp(num(args.w, 0), 0, 1);
1827
1817
  const h = clamp(num(args.h, 0), 0, 1);
1828
- adapter.apply({ kind: "element_resize", slideId, elementId, w, h });
1818
+ adapter.apply({ op: "element.resize", slideId, elementId, w, h });
1829
1819
  return textResult(`Resized element ${elementId} \u2192 (${w}, ${h})`, { w, h });
1830
1820
  },
1831
1821
  true,
@@ -1846,7 +1836,7 @@ function registerSlidesBridge(host, options) {
1846
1836
  const slideId = str(args.slideId);
1847
1837
  const elementId = str(args.elementId);
1848
1838
  const animation = args.animation && typeof args.animation === "object" ? args.animation : void 0;
1849
- adapter.apply({ kind: "element_set_animation", slideId, elementId, animation });
1839
+ adapter.apply({ op: "element.setAnimation", slideId, elementId, animation });
1850
1840
  return textResult(`Animation ${animation ? "set on" : "cleared from"} element ${elementId}`, { elementId });
1851
1841
  },
1852
1842
  true,
@@ -2282,11 +2272,221 @@ function registerMapBridge(host, options) {
2282
2272
  };
2283
2273
  }
2284
2274
 
2275
+ // src/bridges/files.ts
2276
+ var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#0ea5e9" };
2277
+ var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
2278
+ var num3 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
2279
+ var asPaths = (v) => {
2280
+ if (typeof v === "string") {
2281
+ return [v];
2282
+ }
2283
+ if (Array.isArray(v)) {
2284
+ return v.filter((x) => typeof x === "string");
2285
+ }
2286
+ return [];
2287
+ };
2288
+ function registerFilesBridge(host, options) {
2289
+ const { adapter } = options;
2290
+ const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
2291
+ const disposers = [];
2292
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
2293
+ const fTarget = (args, _result) => ({
2294
+ kind: "files",
2295
+ elementId: args?.path ?? void 0
2296
+ });
2297
+ const reg = (name, description, properties, required, handler, resolveTarget) => {
2298
+ const wrapped = async (args) => {
2299
+ try {
2300
+ return await handler(args);
2301
+ } catch (e) {
2302
+ return errorResult(e instanceof Error ? e.message : String(e));
2303
+ }
2304
+ };
2305
+ const final = resolveTarget ? wrapToolWithActivity(wrapped, {
2306
+ toolName: name,
2307
+ agent: { id: agent.id, name: agent.name, color: agent.color },
2308
+ kind: "files",
2309
+ resolveTarget: ({ args, result }) => resolveTarget(args, result)
2310
+ }) : wrapped;
2311
+ disposers.push(
2312
+ host.registerTool(
2313
+ {
2314
+ name,
2315
+ description,
2316
+ inputSchema: {
2317
+ type: "object",
2318
+ properties,
2319
+ required,
2320
+ additionalProperties: false
2321
+ }
2322
+ },
2323
+ final
2324
+ )
2325
+ );
2326
+ };
2327
+ reg(
2328
+ "files_get_state",
2329
+ "Get the file browser's current directory, selected path(s), and expanded folders.",
2330
+ {},
2331
+ [],
2332
+ () => {
2333
+ const state = {
2334
+ path: adapter.getPath(),
2335
+ selected: adapter.getSelection(),
2336
+ expanded: adapter.getExpanded()
2337
+ };
2338
+ return textResult(JSON.stringify(state, null, 2), state);
2339
+ }
2340
+ );
2341
+ reg(
2342
+ "files_list",
2343
+ "List the direct children of a folder (files + subfolders). Omit `path` for the current directory. Loads lazily from the host's provider/snapshot \u2014 never an eager tree walk.",
2344
+ { path: { type: "string", description: "Folder path to list; defaults to the current directory." } },
2345
+ [],
2346
+ async (args) => {
2347
+ const path = args.path !== void 0 ? str3(args.path) : adapter.getPath();
2348
+ const entries = await adapter.listChildren(path);
2349
+ const summary = entries.map((e) => ({
2350
+ path: e.path,
2351
+ name: e.name,
2352
+ kind: e.kind,
2353
+ ...e.size !== void 0 ? { size: e.size } : {},
2354
+ ...e.mtime !== void 0 ? { mtime: e.mtime } : {}
2355
+ }));
2356
+ const text = summary.map((e) => `${e.kind === "dir" ? "\u{1F4C1}" : "\u{1F4C4}"} ${e.path}`).join("\n") || `(empty: ${path})`;
2357
+ return textResult(text, { path, entries: summary });
2358
+ }
2359
+ );
2360
+ reg(
2361
+ "files_navigate",
2362
+ "Set the current directory (as if the user clicked a breadcrumb or opened a folder).",
2363
+ { path: { type: "string" } },
2364
+ ["path"],
2365
+ (args) => {
2366
+ const path = str3(args.path);
2367
+ const prev = adapter.getPath();
2368
+ adapter.setPath(path);
2369
+ fancyAutoCommon.pushUndoEntry(agent.id, {
2370
+ timestamp: Date.now(),
2371
+ bridgeId: "files",
2372
+ action: "files_navigate",
2373
+ label: `Navigated to ${path}`,
2374
+ undo: () => adapter.setPath(prev),
2375
+ redo: () => adapter.setPath(path)
2376
+ });
2377
+ return textResult(`Current directory \u2192 ${path}`, { path });
2378
+ },
2379
+ fTarget
2380
+ );
2381
+ reg(
2382
+ "files_expand",
2383
+ "Expand a folder in the tree (loads its children if needed).",
2384
+ { path: { type: "string" } },
2385
+ ["path"],
2386
+ (args) => {
2387
+ const path = str3(args.path);
2388
+ if (adapter.getExpanded().includes(path)) {
2389
+ return textResult(`${path} already expanded`, { path, expanded: true });
2390
+ }
2391
+ adapter.setExpanded((prev) => [...prev, path]);
2392
+ fancyAutoCommon.pushUndoEntry(agent.id, {
2393
+ timestamp: Date.now(),
2394
+ bridgeId: "files",
2395
+ action: "files_expand",
2396
+ label: `Expanded ${path}`,
2397
+ undo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),
2398
+ redo: () => adapter.setExpanded((prev) => prev.includes(path) ? prev : [...prev, path])
2399
+ });
2400
+ return textResult(`Expanded ${path}`, { path, expanded: true });
2401
+ },
2402
+ fTarget
2403
+ );
2404
+ reg(
2405
+ "files_collapse",
2406
+ "Collapse a folder in the tree.",
2407
+ { path: { type: "string" } },
2408
+ ["path"],
2409
+ (args) => {
2410
+ const path = str3(args.path);
2411
+ if (!adapter.getExpanded().includes(path)) {
2412
+ return textResult(`${path} already collapsed`, { path, expanded: false });
2413
+ }
2414
+ adapter.setExpanded((prev) => prev.filter((p) => p !== path));
2415
+ fancyAutoCommon.pushUndoEntry(agent.id, {
2416
+ timestamp: Date.now(),
2417
+ bridgeId: "files",
2418
+ action: "files_collapse",
2419
+ label: `Collapsed ${path}`,
2420
+ undo: () => adapter.setExpanded((prev) => prev.includes(path) ? prev : [...prev, path]),
2421
+ redo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path))
2422
+ });
2423
+ return textResult(`Collapsed ${path}`, { path, expanded: false });
2424
+ },
2425
+ fTarget
2426
+ );
2427
+ reg(
2428
+ "files_select",
2429
+ "Set the selection to the given path(s). Pass a single `path`, or `paths` for a multi-select browser; either empty clears the selection.",
2430
+ {
2431
+ path: { type: "string", description: "A single path to select." },
2432
+ paths: { type: "array", items: { type: "string" }, description: "Multiple paths (multi-select browsers)." }
2433
+ },
2434
+ [],
2435
+ (args) => {
2436
+ const next = args.paths !== void 0 ? asPaths(args.paths) : asPaths(args.path);
2437
+ const prev = adapter.getSelection();
2438
+ adapter.setSelection(next);
2439
+ fancyAutoCommon.pushUndoEntry(agent.id, {
2440
+ timestamp: Date.now(),
2441
+ bridgeId: "files",
2442
+ action: "files_select",
2443
+ label: next.length ? `Selected ${next.join(", ")}` : "Cleared selection",
2444
+ undo: () => adapter.setSelection(prev),
2445
+ redo: () => adapter.setSelection(next)
2446
+ });
2447
+ return textResult(next.length ? `Selected ${next.join(", ")}` : "Cleared selection", {
2448
+ selected: next
2449
+ });
2450
+ },
2451
+ fTarget
2452
+ );
2453
+ reg(
2454
+ "files_request_snapshot",
2455
+ "Request a fresh snapshot subtree rooted at `path` (snapshot mode) \u2014 e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.",
2456
+ {
2457
+ path: { type: "string", description: "Root of the subtree; defaults to the current directory." },
2458
+ depth: { type: "number", description: "How many levels deep to materialize (host-defined default)." }
2459
+ },
2460
+ [],
2461
+ async (args) => {
2462
+ if (!adapter.requestSnapshot) {
2463
+ return errorResult("Host did not wire requestSnapshot (snapshot mode not enabled).");
2464
+ }
2465
+ const path = args.path !== void 0 ? str3(args.path) : adapter.getPath();
2466
+ const depth = args.depth !== void 0 ? num3(args.depth) : void 0;
2467
+ const tree = await adapter.requestSnapshot(path, depth);
2468
+ const count = Array.isArray(tree) ? tree.length : 0;
2469
+ return textResult(`Snapshot of ${path}: ${count} top-level entr${count === 1 ? "y" : "ies"}.`, {
2470
+ path,
2471
+ snapshot: tree
2472
+ });
2473
+ },
2474
+ fTarget
2475
+ );
2476
+ return {
2477
+ id: "files",
2478
+ title: "Files",
2479
+ dispose: () => {
2480
+ for (const d of disposers) d();
2481
+ }
2482
+ };
2483
+ }
2484
+
2285
2485
  // src/bridges/terminal.ts
2286
- var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#a855f7" };
2486
+ var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
2287
2487
  var truncate = (s, n = 60) => s.length > n ? s.slice(0, n) + "\u2026" : s;
2288
2488
  function registerTerminalBridge(host, options) {
2289
- const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
2489
+ const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2290
2490
  const pendingMode = options.pendingMode ?? false;
2291
2491
  const screenId = options.screenId ?? options.adapter?.screenId;
2292
2492
  const disposers = [];
@@ -2551,10 +2751,10 @@ function registerTerminalBridge(host, options) {
2551
2751
  }
2552
2752
 
2553
2753
  // src/bridges/navigation.ts
2554
- var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
2754
+ var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
2555
2755
  function registerNavigationBridge(host, options) {
2556
2756
  const { adapter } = options;
2557
- const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2757
+ const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
2558
2758
  const pendingMode = options.pendingMode ?? true;
2559
2759
  const disposers = [];
2560
2760
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
@@ -2759,12 +2959,12 @@ function registerNavigationBridge(host, options) {
2759
2959
  }
2760
2960
 
2761
2961
  // src/bridges/catalog.ts
2762
- var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
2763
- var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
2764
- var num3 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
2962
+ var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
2963
+ var str4 = (v, fallback = "") => typeof v === "string" ? v : fallback;
2964
+ var num4 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
2765
2965
  function registerCatalogBridge(host, options) {
2766
2966
  const { adapter } = options;
2767
- const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
2967
+ const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
2768
2968
  const pendingMode = options.pendingMode ?? true;
2769
2969
  const catalogId = adapter.id ?? "catalog";
2770
2970
  const disposers = [];
@@ -2834,7 +3034,7 @@ function registerCatalogBridge(host, options) {
2834
3034
  { id: { type: "string" }, withTrashed: { type: "boolean" } },
2835
3035
  ["id"],
2836
3036
  async (args) => {
2837
- const id = str3(args.id);
3037
+ const id = str4(args.id);
2838
3038
  const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });
2839
3039
  if (!product) return errorResult(`No product with id ${id}`);
2840
3040
  const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });
@@ -2850,7 +3050,7 @@ function registerCatalogBridge(host, options) {
2850
3050
  [],
2851
3051
  async (args) => {
2852
3052
  const withTrashed = args.withTrashed === true;
2853
- const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str3(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
3053
+ const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str4(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
2854
3054
  const list = prices.map((p) => ({
2855
3055
  id: p.id,
2856
3056
  productId: p.productId,
@@ -2876,13 +3076,13 @@ function registerCatalogBridge(host, options) {
2876
3076
  },
2877
3077
  ["name"],
2878
3078
  async (args) => {
2879
- const name = str3(args.name);
3079
+ const name = str4(args.name);
2880
3080
  if (!name) return errorResult("name is required.");
2881
3081
  const product = await adapter.createProduct({
2882
3082
  name,
2883
- ...args.description !== void 0 ? { description: str3(args.description) } : {},
3083
+ ...args.description !== void 0 ? { description: str4(args.description) } : {},
2884
3084
  ...args.active !== void 0 ? { active: args.active === true } : {},
2885
- ...args.lookupKey !== void 0 ? { lookupKey: str3(args.lookupKey) } : {},
3085
+ ...args.lookupKey !== void 0 ? { lookupKey: str4(args.lookupKey) } : {},
2886
3086
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
2887
3087
  });
2888
3088
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -2895,7 +3095,7 @@ function registerCatalogBridge(host, options) {
2895
3095
  });
2896
3096
  return textResult(`Created product ${product.id} (${product.name})`, product);
2897
3097
  },
2898
- (args) => target(void 0, `create product ${str3(args.name)}`)
3098
+ (args) => target(void 0, `create product ${str4(args.name)}`)
2899
3099
  );
2900
3100
  reg(
2901
3101
  "catalog_create_price",
@@ -2912,19 +3112,19 @@ function registerCatalogBridge(host, options) {
2912
3112
  },
2913
3113
  ["productId", "currency", "unitAmount", "type"],
2914
3114
  async (args) => {
2915
- const productId = str3(args.productId);
3115
+ const productId = str4(args.productId);
2916
3116
  const product = await adapter.products.find(productId);
2917
3117
  if (!product) return errorResult(`No product with id ${productId}`);
2918
- const type = str3(args.type);
3118
+ const type = str4(args.type);
2919
3119
  if (type !== "recurring" && type !== "one_time") return errorResult("type must be 'recurring' or 'one_time'.");
2920
3120
  const price = await adapter.createPrice({
2921
3121
  productId,
2922
- currency: str3(args.currency),
2923
- unitAmount: num3(args.unitAmount),
3122
+ currency: str4(args.currency),
3123
+ unitAmount: num4(args.unitAmount),
2924
3124
  type,
2925
- ...args.recurringInterval !== void 0 ? { recurringInterval: str3(args.recurringInterval) } : {},
2926
- ...args.nickname !== void 0 ? { nickname: str3(args.nickname) } : {},
2927
- ...args.lookupKey !== void 0 ? { lookupKey: str3(args.lookupKey) } : {},
3125
+ ...args.recurringInterval !== void 0 ? { recurringInterval: str4(args.recurringInterval) } : {},
3126
+ ...args.nickname !== void 0 ? { nickname: str4(args.nickname) } : {},
3127
+ ...args.lookupKey !== void 0 ? { lookupKey: str4(args.lookupKey) } : {},
2928
3128
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
2929
3129
  });
2930
3130
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -2937,7 +3137,7 @@ function registerCatalogBridge(host, options) {
2937
3137
  });
2938
3138
  return textResult(`Created ${type} price ${price.id} on ${productId}`, price);
2939
3139
  },
2940
- (args) => target(str3(args.productId), `create price on ${str3(args.productId)}`)
3140
+ (args) => target(str4(args.productId), `create price on ${str4(args.productId)}`)
2941
3141
  );
2942
3142
  reg(
2943
3143
  "catalog_delete_product",
@@ -2945,7 +3145,7 @@ function registerCatalogBridge(host, options) {
2945
3145
  { id: { type: "string" }, confirm: { type: "boolean" } },
2946
3146
  ["id"],
2947
3147
  async (args) => {
2948
- const id = str3(args.id);
3148
+ const id = str4(args.id);
2949
3149
  const product = await adapter.products.find(id, { withTrashed: true });
2950
3150
  if (!product) return errorResult(`No product with id ${id}`);
2951
3151
  const blocked = await guardDestructive("catalog_delete_product", id, product.name, args.confirm === true);
@@ -2962,7 +3162,7 @@ function registerCatalogBridge(host, options) {
2962
3162
  });
2963
3163
  return textResult(`Deleted product ${id}`, { id });
2964
3164
  },
2965
- (args) => target(str3(args.id), `delete product ${str3(args.id)}`)
3165
+ (args) => target(str4(args.id), `delete product ${str4(args.id)}`)
2966
3166
  );
2967
3167
  reg(
2968
3168
  "catalog_delete_price",
@@ -2970,7 +3170,7 @@ function registerCatalogBridge(host, options) {
2970
3170
  { id: { type: "string" }, confirm: { type: "boolean" } },
2971
3171
  ["id"],
2972
3172
  async (args) => {
2973
- const id = str3(args.id);
3173
+ const id = str4(args.id);
2974
3174
  const price = await adapter.prices.find(id, { withTrashed: true });
2975
3175
  if (!price) return errorResult(`No price with id ${id}`);
2976
3176
  const blocked = await guardDestructive("catalog_delete_price", id, id, args.confirm === true);
@@ -2987,7 +3187,7 @@ function registerCatalogBridge(host, options) {
2987
3187
  });
2988
3188
  return textResult(`Deleted price ${id}`, { id });
2989
3189
  },
2990
- (args) => target(str3(args.id), `delete price ${str3(args.id)}`)
3190
+ (args) => target(str4(args.id), `delete price ${str4(args.id)}`)
2991
3191
  );
2992
3192
  reg(
2993
3193
  "catalog_sync_product",
@@ -2996,13 +3196,13 @@ function registerCatalogBridge(host, options) {
2996
3196
  ["id"],
2997
3197
  async (args) => {
2998
3198
  if (!adapter.syncProductAndPrices) return errorResult("Host did not wire Stripe sync.");
2999
- const id = str3(args.id);
3199
+ const id = str4(args.id);
3000
3200
  const product = await adapter.products.find(id);
3001
3201
  if (!product) return errorResult(`No product with id ${id}`);
3002
3202
  const synced = await adapter.syncProductAndPrices(product);
3003
3203
  return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? "no external id"})`, synced);
3004
3204
  },
3005
- (args) => target(str3(args.id), `sync product ${str3(args.id)}`)
3205
+ (args) => target(str4(args.id), `sync product ${str4(args.id)}`)
3006
3206
  );
3007
3207
  reg(
3008
3208
  "catalog_test_connection",
@@ -3029,13 +3229,13 @@ function registerCatalogBridge(host, options) {
3029
3229
  },
3030
3230
  ["priceId", "successUrl", "cancelUrl"],
3031
3231
  async (args) => {
3032
- const priceId = str3(args.priceId);
3232
+ const priceId = str4(args.priceId);
3033
3233
  const price = await adapter.prices.find(priceId);
3034
3234
  if (!price) return errorResult(`No price with id ${priceId}`);
3035
3235
  const checkoutArgs = {
3036
- successUrl: str3(args.successUrl),
3037
- cancelUrl: str3(args.cancelUrl),
3038
- ...args.customer !== void 0 ? { customer: str3(args.customer) } : {},
3236
+ successUrl: str4(args.successUrl),
3237
+ cancelUrl: str4(args.cancelUrl),
3238
+ ...args.customer !== void 0 ? { customer: str4(args.customer) } : {},
3039
3239
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
3040
3240
  };
3041
3241
  let url;
@@ -3044,11 +3244,11 @@ function registerCatalogBridge(host, options) {
3044
3244
  url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);
3045
3245
  } else {
3046
3246
  if (!adapter.getOneTimeCheckoutUrl) return errorResult("Host did not wire one-time checkout.");
3047
- url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num3(args.quantity, 1) });
3247
+ url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num4(args.quantity, 1) });
3048
3248
  }
3049
3249
  return textResult(url || "(no url)", { priceId, type: price.type, url });
3050
3250
  },
3051
- (args) => target(str3(args.priceId), `checkout ${str3(args.priceId)}`)
3251
+ (args) => target(str4(args.priceId), `checkout ${str4(args.priceId)}`)
3052
3252
  );
3053
3253
  return {
3054
3254
  id: `catalog:${catalogId}`,
@@ -3060,12 +3260,12 @@ function registerCatalogBridge(host, options) {
3060
3260
  }
3061
3261
 
3062
3262
  // src/bridges/features.ts
3063
- var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
3064
- var str4 = (v, fallback = "") => typeof v === "string" ? v : fallback;
3065
- var num4 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
3263
+ var DEFAULT_AGENT13 = { id: "agent", name: "Agent", color: "#a855f7" };
3264
+ var str5 = (v, fallback = "") => typeof v === "string" ? v : fallback;
3265
+ var num5 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
3066
3266
  function registerFeaturesBridge(host, options) {
3067
3267
  const { adapter } = options;
3068
- const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
3268
+ const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
3069
3269
  const pendingMode = options.pendingMode ?? true;
3070
3270
  const featuresId = adapter.id ?? "features";
3071
3271
  const disposers = [];
@@ -3126,7 +3326,7 @@ function registerFeaturesBridge(host, options) {
3126
3326
  { feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
3127
3327
  ["feature"],
3128
3328
  async (args) => {
3129
- const feature = str4(args.feature);
3329
+ const feature = str5(args.feature);
3130
3330
  const allowed = await adapter.canAccess(feature, args.subject, args.context);
3131
3331
  const remaining = await adapter.remaining(feature, args.subject, args.context);
3132
3332
  const out = { feature, allowed, remaining };
@@ -3141,7 +3341,7 @@ function registerFeaturesBridge(host, options) {
3141
3341
  ["feature"],
3142
3342
  async (args) => {
3143
3343
  if (!adapter.explain) return errorResult("Host did not wire explain().");
3144
- const result = await adapter.explain(str4(args.feature), args.subject, args.context);
3344
+ const result = await adapter.explain(str5(args.feature), args.subject, args.context);
3145
3345
  return textResult(JSON.stringify(result, null, 2), result);
3146
3346
  },
3147
3347
  false
@@ -3170,15 +3370,15 @@ function registerFeaturesBridge(host, options) {
3170
3370
  },
3171
3371
  ["key"],
3172
3372
  (args) => {
3173
- const key = str4(args.key);
3373
+ const key = str5(args.key);
3174
3374
  if (!key) return errorResult("key is required.");
3175
3375
  const existed = adapter.registryKeys().includes(key);
3176
3376
  const definition = {
3177
- ...args.name !== void 0 ? { name: str4(args.name) } : {},
3178
- ...args.description !== void 0 ? { description: str4(args.description) } : {},
3179
- ...args.type !== void 0 ? { type: str4(args.type) } : {},
3377
+ ...args.name !== void 0 ? { name: str5(args.name) } : {},
3378
+ ...args.description !== void 0 ? { description: str5(args.description) } : {},
3379
+ ...args.type !== void 0 ? { type: str5(args.type) } : {},
3180
3380
  ...args.enabled !== void 0 ? { enabled: args.enabled === true } : {},
3181
- ...args.limit !== void 0 ? { limit: num4(args.limit) } : {}
3381
+ ...args.limit !== void 0 ? { limit: num5(args.limit) } : {}
3182
3382
  };
3183
3383
  adapter.registerFeature(key, definition);
3184
3384
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -3193,7 +3393,7 @@ function registerFeaturesBridge(host, options) {
3193
3393
  });
3194
3394
  return textResult(`${existed ? "Redefined" : "Defined"} feature ${key} (${definition.type ?? "boolean"})`, { key, definition });
3195
3395
  },
3196
- (args) => target(str4(args.key), `define ${str4(args.key)}`)
3396
+ (args) => target(str5(args.key), `define ${str5(args.key)}`)
3197
3397
  );
3198
3398
  reg(
3199
3399
  "features_grant",
@@ -3201,7 +3401,7 @@ function registerFeaturesBridge(host, options) {
3201
3401
  { subject: { description: "Opaque subject." }, group: { type: "string", description: "Feature group key." }, confirm: { type: "boolean" } },
3202
3402
  ["subject", "group"],
3203
3403
  async (args) => {
3204
- const groupKey = str4(args.group);
3404
+ const groupKey = str5(args.group);
3205
3405
  if (!groupKey) return errorResult("group is required.");
3206
3406
  const blocked = await guardGrant("features_grant", args.subject, groupKey, args.confirm === true);
3207
3407
  if (blocked) return blocked;
@@ -3220,7 +3420,7 @@ function registerFeaturesBridge(host, options) {
3220
3420
  });
3221
3421
  return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });
3222
3422
  },
3223
- (args) => target(str4(args.group), `grant ${str4(args.group)}`)
3423
+ (args) => target(str5(args.group), `grant ${str5(args.group)}`)
3224
3424
  );
3225
3425
  reg(
3226
3426
  "features_revoke",
@@ -3228,7 +3428,7 @@ function registerFeaturesBridge(host, options) {
3228
3428
  { subject: { description: "Opaque subject." }, group: { type: "string" }, confirm: { type: "boolean" } },
3229
3429
  ["subject", "group"],
3230
3430
  async (args) => {
3231
- const groupKey = str4(args.group);
3431
+ const groupKey = str5(args.group);
3232
3432
  if (!groupKey) return errorResult("group is required.");
3233
3433
  const blocked = await guardGrant("features_revoke", args.subject, groupKey, args.confirm === true);
3234
3434
  if (blocked) return blocked;
@@ -3246,7 +3446,7 @@ function registerFeaturesBridge(host, options) {
3246
3446
  });
3247
3447
  return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });
3248
3448
  },
3249
- (args) => target(str4(args.group), `revoke ${str4(args.group)}`)
3449
+ (args) => target(str5(args.group), `revoke ${str5(args.group)}`)
3250
3450
  );
3251
3451
  reg(
3252
3452
  "features_consume",
@@ -3255,14 +3455,14 @@ function registerFeaturesBridge(host, options) {
3255
3455
  ["feature", "subject"],
3256
3456
  async (args) => {
3257
3457
  if (!adapter.tryConsume) return errorResult("Host did not wire usage metering (tryConsume).");
3258
- const feature = str4(args.feature);
3259
- const amount = num4(args.amount, 1);
3458
+ const feature = str5(args.feature);
3459
+ const amount = num5(args.amount, 1);
3260
3460
  const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);
3261
3461
  const remaining = await adapter.remaining(feature, args.subject, args.context);
3262
3462
  const out = { feature, ok, amount, remaining };
3263
3463
  return textResult(JSON.stringify(out), out);
3264
3464
  },
3265
- (args) => target(str4(args.feature), `consume ${str4(args.feature)}`)
3465
+ (args) => target(str5(args.feature), `consume ${str5(args.feature)}`)
3266
3466
  );
3267
3467
  return {
3268
3468
  id: `features:${featuresId}`,
@@ -3467,11 +3667,11 @@ function attachSseRelay(server, options) {
3467
3667
 
3468
3668
  // src/sharing/use-co-browse-session.ts
3469
3669
  init_registry();
3470
- var DEFAULT_AGENT13 = { id: "agent", name: "Agent", color: "#a855f7" };
3670
+ var DEFAULT_AGENT14 = { id: "agent", name: "Agent", color: "#a855f7" };
3471
3671
  var USER = { id: "human", name: "You" };
3472
3672
  function useCoBrowseSession(options) {
3473
3673
  const { adapter, extraBridges } = options;
3474
- const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
3674
+ const agent = { ...DEFAULT_AGENT14, ...options.agent ?? {} };
3475
3675
  const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
3476
3676
  const serverRef = react.useRef(null);
3477
3677
  const relayRef = react.useRef(null);
@@ -4697,6 +4897,7 @@ exports.registerCatalogBridge = registerCatalogBridge;
4697
4897
  exports.registerChartsBridge = registerChartsBridge;
4698
4898
  exports.registerCodeBridge = registerCodeBridge;
4699
4899
  exports.registerFeaturesBridge = registerFeaturesBridge;
4900
+ exports.registerFilesBridge = registerFilesBridge;
4700
4901
  exports.registerFormBridge = registerFormBridge;
4701
4902
  exports.registerMapBridge = registerMapBridge;
4702
4903
  exports.registerNavigationBridge = registerNavigationBridge;