@particle-academy/agent-integrations 0.46.0 → 0.47.1

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 (96) hide show
  1. package/CHANGELOG.md +885 -0
  2. package/LICENSE +21 -0
  3. package/README.md +53 -3
  4. package/dist/bridges/artboard.d.cts +3 -3
  5. package/dist/bridges/artboard.d.ts +3 -3
  6. package/dist/bridges/catalog.d.cts +3 -3
  7. package/dist/bridges/catalog.d.ts +3 -3
  8. package/dist/bridges/charts.d.cts +3 -3
  9. package/dist/bridges/charts.d.ts +3 -3
  10. package/dist/bridges/cms.d.cts +3 -3
  11. package/dist/bridges/cms.d.ts +3 -3
  12. package/dist/bridges/code.d.cts +3 -3
  13. package/dist/bridges/code.d.ts +3 -3
  14. package/dist/bridges/doc.d.cts +3 -3
  15. package/dist/bridges/doc.d.ts +3 -3
  16. package/dist/bridges/features.d.cts +3 -3
  17. package/dist/bridges/features.d.ts +3 -3
  18. package/dist/bridges/files.d.cts +3 -3
  19. package/dist/bridges/files.d.ts +3 -3
  20. package/dist/bridges/flow.d.cts +3 -3
  21. package/dist/bridges/flow.d.ts +3 -3
  22. package/dist/bridges/forms.d.cts +3 -3
  23. package/dist/bridges/forms.d.ts +3 -3
  24. package/dist/bridges/git.d.cts +3 -3
  25. package/dist/bridges/git.d.ts +3 -3
  26. package/dist/bridges/grid.d.cts +3 -3
  27. package/dist/bridges/grid.d.ts +3 -3
  28. package/dist/bridges/map.d.cts +3 -3
  29. package/dist/bridges/map.d.ts +3 -3
  30. package/dist/bridges/navigation.d.cts +140 -0
  31. package/dist/bridges/navigation.d.ts +140 -0
  32. package/dist/bridges/passkeys.d.cts +4 -4
  33. package/dist/bridges/passkeys.d.ts +4 -4
  34. package/dist/bridges/scene.d.cts +3 -3
  35. package/dist/bridges/scene.d.ts +3 -3
  36. package/dist/bridges/screens.d.cts +3 -3
  37. package/dist/bridges/screens.d.ts +3 -3
  38. package/dist/bridges/sheets.d.cts +3 -3
  39. package/dist/bridges/sheets.d.ts +3 -3
  40. package/dist/bridges/slides.d.cts +3 -3
  41. package/dist/bridges/slides.d.ts +3 -3
  42. package/dist/bridges/terminal.d.cts +3 -3
  43. package/dist/bridges/terminal.d.ts +3 -3
  44. package/dist/bridges/tui.d.cts +2 -2
  45. package/dist/bridges/tui.d.ts +2 -2
  46. package/dist/bridges/whiteboard.d.cts +3 -3
  47. package/dist/bridges/whiteboard.d.ts +3 -3
  48. package/dist/bridges-navigation.cjs +437 -0
  49. package/dist/bridges-navigation.cjs.map +1 -0
  50. package/dist/bridges-navigation.js +7 -0
  51. package/dist/bridges-navigation.js.map +1 -0
  52. package/dist/bridges-passkeys.cjs.map +1 -1
  53. package/dist/bridges-passkeys.js +1 -1
  54. package/dist/{chunk-PWYEW6NL.js → chunk-G6CRHFWU.js} +2 -2
  55. package/dist/{chunk-PWYEW6NL.js.map → chunk-G6CRHFWU.js.map} +1 -1
  56. package/dist/chunk-OHNGURUJ.js +317 -0
  57. package/dist/chunk-OHNGURUJ.js.map +1 -0
  58. package/dist/dom-navigation/index.d.cts +175 -0
  59. package/dist/dom-navigation/index.d.ts +175 -0
  60. package/dist/dom-navigation/script.d.cts +3 -0
  61. package/dist/dom-navigation/script.d.ts +3 -0
  62. package/dist/dom-navigation-script.cjs +11 -0
  63. package/dist/dom-navigation-script.cjs.map +1 -0
  64. package/dist/dom-navigation-script.js +9 -0
  65. package/dist/dom-navigation-script.js.map +1 -0
  66. package/dist/dom-navigation.cjs +405 -0
  67. package/dist/dom-navigation.cjs.map +1 -0
  68. package/dist/dom-navigation.js +388 -0
  69. package/dist/dom-navigation.js.map +1 -0
  70. package/dist/index.cjs +94 -48
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.cts +10 -125
  73. package/dist/index.d.ts +10 -125
  74. package/dist/index.js +12 -275
  75. package/dist/index.js.map +1 -1
  76. package/dist/mcp/index.d.cts +5 -5
  77. package/dist/mcp/index.d.ts +5 -5
  78. package/dist/mcp/stdio.d.cts +3 -3
  79. package/dist/mcp/stdio.d.ts +3 -3
  80. package/dist/presence/index.d.cts +1 -1
  81. package/dist/presence/index.d.ts +1 -1
  82. package/dist/{server-BIcA3ZtK.d.cts → server-1y0n61R5.d.cts} +2 -2
  83. package/dist/{server-DnUyeavY.d.ts → server-vq6qVl3T.d.ts} +2 -2
  84. package/dist/sharing/index.d.cts +3 -3
  85. package/dist/sharing/index.d.ts +3 -3
  86. package/dist/sheets-adapter.d.cts +3 -3
  87. package/dist/sheets-adapter.d.ts +3 -3
  88. package/dist/{tool-host-LVBgCN5m.d.cts → tool-host-D67N2a2h.d.cts} +1 -1
  89. package/dist/{tool-host-Wo0pkY83.d.ts → tool-host-LYfdPE8u.d.ts} +1 -1
  90. package/dist/{types-EcElKOlk.d.cts → types-DP5yQZQU.d.cts} +1 -1
  91. package/dist/{types-BxNRKSVd.d.ts → types-VX_9je7w.d.ts} +1 -1
  92. package/dist/{types-C2DtnHIn.d.cts → types-gzIpsUDE.d.cts} +1 -1
  93. package/dist/{types-C2DtnHIn.d.ts → types-gzIpsUDE.d.ts} +1 -1
  94. package/dist/undo/index.d.cts +2 -2
  95. package/dist/undo/index.d.ts +2 -2
  96. package/package.json +35 -3
package/dist/index.cjs CHANGED
@@ -3416,14 +3416,30 @@ function registerTerminalBridge(host, options) {
3416
3416
 
3417
3417
  // src/bridges/navigation.ts
3418
3418
  var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
3419
+ var isControl = (code) => code < 32 || code >= 127 && code <= 159 || code === 8232 || code === 8233;
3420
+ function oneLine(value, max) {
3421
+ const raw = typeof value === "string" ? value : value == null ? "" : String(value);
3422
+ const bounded = raw.length > max * 4 ? raw.slice(0, max * 4) : raw;
3423
+ let out = "";
3424
+ for (const c of bounded) out += isControl(c.charCodeAt(0)) ? " " : c;
3425
+ out = out.replace(/\s+/g, " ").trim();
3426
+ return out.length > max ? out.slice(0, max - 3) + "..." : out;
3427
+ }
3428
+ var SAFE_HANDLE = /^[A-Za-z0-9_.:#@/-]{1,80}$/;
3429
+ var CAP = { url: 500, title: 200, role: 40, label: 200, heading: 200, text: 4e3, error: 300, headings: 50 };
3430
+ function formatReadout(r) {
3431
+ if (typeof r === "string") return oneLine(r, CAP.text);
3432
+ const headings = (Array.isArray(r.headings) ? r.headings : []).slice(0, CAP.headings).map((h) => `H${Math.min(6, Math.max(1, Math.trunc(Number(h?.level)) || 1))}: ${oneLine(h?.text, CAP.heading)}`);
3433
+ return [oneLine(r.title, CAP.title), ...headings, "", oneLine(r.text, CAP.text)].join("\n");
3434
+ }
3419
3435
  function registerNavigationBridge(host, options) {
3420
3436
  const { adapter } = options;
3421
3437
  const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
3422
3438
  const pendingMode = options.pendingMode ?? true;
3423
3439
  const disposers = [];
3424
3440
  let groundedRevision = null;
3425
- const staleIntent = () => {
3426
- const current = adapter.getRevision?.();
3441
+ const staleIntent = async () => {
3442
+ const current = await adapter.getRevision?.();
3427
3443
  if (current === void 0) return null;
3428
3444
  if (groundedRevision === null || groundedRevision !== current) {
3429
3445
  return errorResult(
@@ -3432,6 +3448,9 @@ function registerNavigationBridge(host, options) {
3432
3448
  }
3433
3449
  return null;
3434
3450
  };
3451
+ let aliases = /* @__PURE__ */ new Map();
3452
+ const pageHandle = (handle) => aliases.get(handle) ?? handle;
3453
+ const failure = (message, fallback) => errorResult(oneLine(message ?? fallback, CAP.error) || fallback);
3435
3454
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
3436
3455
  const target = (label, elementId) => ({
3437
3456
  kind: "navigation",
@@ -3444,7 +3463,7 @@ function registerNavigationBridge(host, options) {
3444
3463
  try {
3445
3464
  return await handler(args);
3446
3465
  } catch (e) {
3447
- return errorResult(e instanceof Error ? e.message : String(e));
3466
+ return failure(e instanceof Error ? e.message : String(e), `${name} failed`);
3448
3467
  }
3449
3468
  };
3450
3469
  const final = activity ? wrapToolWithActivity(wrapped, {
@@ -3470,18 +3489,30 @@ function registerNavigationBridge(host, options) {
3470
3489
  "Describe the current page: its URL, title, and the interactive elements you can act on (each with a stable `handle`, role, and label). Call this first, and again after navigating.",
3471
3490
  {},
3472
3491
  [],
3473
- () => {
3474
- const snap = adapter.describe();
3475
- const revision = adapter.getRevision?.();
3492
+ async () => {
3493
+ const raw = await adapter.describe();
3494
+ const next = /* @__PURE__ */ new Map();
3495
+ const actions = (Array.isArray(raw.actions) ? raw.actions : []).map((a) => {
3496
+ const handle = String(a.handle ?? "");
3497
+ if (SAFE_HANDLE.test(handle)) return a;
3498
+ const alias = `~${next.size}`;
3499
+ next.set(alias, handle);
3500
+ return { ...a, handle: alias };
3501
+ });
3502
+ aliases = next;
3503
+ const snap = { ...raw, actions };
3504
+ const revision = await adapter.getRevision?.();
3476
3505
  if (revision !== void 0) {
3477
3506
  snap.revision = revision;
3478
3507
  groundedRevision = revision;
3479
3508
  }
3480
3509
  const text = [
3481
- `URL: ${snap.url}`,
3482
- `Title: ${snap.title}`,
3510
+ `URL: ${oneLine(snap.url, CAP.url)}`,
3511
+ `Title: ${oneLine(snap.title, CAP.title)}`,
3483
3512
  "",
3484
- ...snap.actions.map((a) => `[${a.handle}] ${a.role}: ${a.label}${a.destructive ? " (destructive)" : ""}`)
3513
+ ...actions.map(
3514
+ (a) => `[${a.handle}] ${oneLine(a.role, CAP.role)}: ${oneLine(a.label, CAP.label)}${a.destructive ? " (destructive)" : ""}`
3515
+ )
3485
3516
  ].join("\n");
3486
3517
  return textResult(text, snap);
3487
3518
  },
@@ -3492,7 +3523,10 @@ function registerNavigationBridge(host, options) {
3492
3523
  "Read the page's visible text / heading outline for grounding.",
3493
3524
  {},
3494
3525
  [],
3495
- () => textResult(adapter.read ? adapter.read() : "(host did not provide page text)"),
3526
+ async () => {
3527
+ const r = adapter.read ? await adapter.read() : void 0;
3528
+ return textResult(r == null ? "(host did not provide page text)" : formatReadout(r));
3529
+ },
3496
3530
  () => target("Read page")
3497
3531
  );
3498
3532
  reg(
@@ -3500,15 +3534,16 @@ function registerNavigationBridge(host, options) {
3500
3534
  "Move the agent's visible focus to an interactive element by stable handle without activating it.",
3501
3535
  { handle: { type: "string" } },
3502
3536
  ["handle"],
3503
- (args) => {
3504
- const stale = staleIntent();
3537
+ async (args) => {
3538
+ const stale = await staleIntent();
3505
3539
  if (stale) return stale;
3506
- const handle = String(args.handle ?? "");
3507
- const action = adapter.describe().actions.find((candidate) => candidate.handle === handle);
3508
- if (!action) return errorResult(`No element for handle "${handle}"`);
3509
- return textResult(`Focused ${handle}`, {
3510
- handle,
3511
- rect: adapter.rectFor?.(handle) ?? void 0
3540
+ const shown = String(args.handle ?? "");
3541
+ const handle = pageHandle(shown);
3542
+ const action = (await adapter.describe()).actions.find((candidate) => candidate.handle === handle);
3543
+ if (!action) return failure(`No element for handle "${shown}"`, "No element for that handle");
3544
+ return textResult(`Focused ${oneLine(shown, CAP.label)}`, {
3545
+ handle: shown,
3546
+ rect: await adapter.rectFor?.(handle) ?? void 0
3512
3547
  });
3513
3548
  },
3514
3549
  (args) => target(`Focus ${String(args.handle ?? "")}`, String(args.handle ?? ""))
@@ -3519,7 +3554,7 @@ function registerNavigationBridge(host, options) {
3519
3554
  { url: { type: "string", description: "Path like /packages or an absolute URL." } },
3520
3555
  ["url"],
3521
3556
  async (args) => {
3522
- const stale = staleIntent();
3557
+ const stale = await staleIntent();
3523
3558
  if (stale) return stale;
3524
3559
  const url = String(args.url ?? "");
3525
3560
  if (!url) return errorResult("url is required");
@@ -3529,7 +3564,7 @@ function registerNavigationBridge(host, options) {
3529
3564
  `Refusing to navigate to a '${scheme}:' URL. Only http(s) URLs or same-site paths are allowed.`
3530
3565
  );
3531
3566
  }
3532
- const from = adapter.getLocation().url;
3567
+ const from = (await adapter.getLocation()).url;
3533
3568
  await adapter.visit(url);
3534
3569
  fancyAutoCommon.pushUndoEntry(agent.id, {
3535
3570
  timestamp: Date.now(),
@@ -3553,7 +3588,7 @@ function registerNavigationBridge(host, options) {
3553
3588
  {},
3554
3589
  [],
3555
3590
  async () => {
3556
- const stale = staleIntent();
3591
+ const stale = await staleIntent();
3557
3592
  if (stale) return stale;
3558
3593
  if (!adapter.back) return errorResult("Host did not provide back navigation.");
3559
3594
  await adapter.back();
@@ -3567,7 +3602,7 @@ function registerNavigationBridge(host, options) {
3567
3602
  {},
3568
3603
  [],
3569
3604
  async () => {
3570
- const stale = staleIntent();
3605
+ const stale = await staleIntent();
3571
3606
  if (stale) return stale;
3572
3607
  if (!adapter.forward) return errorResult("Host did not provide forward navigation.");
3573
3608
  await adapter.forward();
@@ -3584,16 +3619,20 @@ function registerNavigationBridge(host, options) {
3584
3619
  y: { type: "number" }
3585
3620
  },
3586
3621
  [],
3587
- (args) => {
3588
- const stale = staleIntent();
3622
+ async (args) => {
3623
+ const stale = await staleIntent();
3589
3624
  if (stale) return stale;
3590
- const handle = typeof args.handle === "string" ? args.handle : void 0;
3591
- adapter.scrollTo({
3625
+ const shown = typeof args.handle === "string" ? args.handle : void 0;
3626
+ const handle = shown === void 0 ? void 0 : pageHandle(shown);
3627
+ await adapter.scrollTo({
3592
3628
  handle,
3593
3629
  x: typeof args.x === "number" ? args.x : void 0,
3594
3630
  y: typeof args.y === "number" ? args.y : void 0
3595
3631
  });
3596
- return textResult("Scrolled", handle ? { handle, rect: adapter.rectFor?.(handle) ?? void 0 } : void 0);
3632
+ return textResult(
3633
+ "Scrolled",
3634
+ handle ? { handle: shown, rect: await adapter.rectFor?.(handle) ?? void 0 } : void 0
3635
+ );
3597
3636
  },
3598
3637
  () => target("Scroll")
3599
3638
  );
@@ -3602,10 +3641,10 @@ function registerNavigationBridge(host, options) {
3602
3641
  "Scroll the page by a vertical delta in pixels (negative scrolls up).",
3603
3642
  { dy: { type: "number" } },
3604
3643
  ["dy"],
3605
- (args) => {
3606
- const stale = staleIntent();
3644
+ async (args) => {
3645
+ const stale = await staleIntent();
3607
3646
  if (stale) return stale;
3608
- adapter.scrollBy(Number(args.dy ?? 0));
3647
+ await adapter.scrollBy(Number(args.dy ?? 0));
3609
3648
  return textResult(`Scrolled by ${Number(args.dy ?? 0)}px`);
3610
3649
  },
3611
3650
  () => target("Scroll")
@@ -3618,13 +3657,18 @@ function registerNavigationBridge(host, options) {
3618
3657
  value: { description: "Value to set; type matches the field." }
3619
3658
  },
3620
3659
  ["handle", "value"],
3621
- (args) => {
3622
- const stale = staleIntent();
3660
+ async (args) => {
3661
+ const stale = await staleIntent();
3623
3662
  if (stale) return stale;
3624
- const handle = String(args.handle ?? "");
3625
- const res = adapter.setField(handle, args.value);
3626
- if (!res.ok) return errorResult(res.error ?? `Could not set ${handle}`);
3627
- return textResult(`${handle} \u2190 ${JSON.stringify(args.value)}`, { handle, value: args.value, rect: adapter.rectFor?.(handle) ?? void 0 });
3663
+ const shown = String(args.handle ?? "");
3664
+ const handle = pageHandle(shown);
3665
+ const res = await adapter.setField(handle, args.value);
3666
+ if (!res.ok) return failure(res.error, `Could not set ${oneLine(shown, CAP.label)}`);
3667
+ return textResult(`${oneLine(shown, CAP.label)} \u2190 ${JSON.stringify(args.value)}`, {
3668
+ handle: shown,
3669
+ value: args.value,
3670
+ rect: await adapter.rectFor?.(handle) ?? void 0
3671
+ });
3628
3672
  },
3629
3673
  (args) => target(`Set ${String(args.handle ?? "")}`, String(args.handle ?? ""))
3630
3674
  );
@@ -3634,18 +3678,19 @@ function registerNavigationBridge(host, options) {
3634
3678
  { handle: { type: "string" } },
3635
3679
  ["handle"],
3636
3680
  async (args) => {
3637
- const stale = staleIntent();
3681
+ const stale = await staleIntent();
3638
3682
  if (stale) return stale;
3639
- const handle = String(args.handle ?? "");
3640
- const action = adapter.describe().actions.find((a) => a.handle === handle);
3641
- const rect = adapter.rectFor?.(handle) ?? void 0;
3683
+ const shown = String(args.handle ?? "");
3684
+ const handle = pageHandle(shown);
3685
+ const action = (await adapter.describe()).actions.find((a) => a.handle === handle);
3686
+ const rect = await adapter.rectFor?.(handle) ?? void 0;
3642
3687
  if (pendingMode && action?.destructive && adapter.confirm) {
3643
3688
  const ok = await adapter.confirm({ action: "click", handle, label: action.label });
3644
3689
  if (!ok) return errorResult("Declined by user");
3645
3690
  }
3646
- const res = adapter.click(handle);
3647
- if (!res.ok) return errorResult(res.error ?? `Could not click ${handle}`);
3648
- return textResult(`Clicked ${handle}`, { handle, rect });
3691
+ const res = await adapter.click(handle);
3692
+ if (!res.ok) return failure(res.error, `Could not click ${oneLine(shown, CAP.label)}`);
3693
+ return textResult(`Clicked ${oneLine(shown, CAP.label)}`, { handle: shown, rect });
3649
3694
  },
3650
3695
  (args) => target(`Click ${String(args.handle ?? "")}`, String(args.handle ?? ""))
3651
3696
  );
@@ -3655,17 +3700,18 @@ function registerNavigationBridge(host, options) {
3655
3700
  { handle: { type: "string" } },
3656
3701
  ["handle"],
3657
3702
  async (args) => {
3658
- const stale = staleIntent();
3703
+ const stale = await staleIntent();
3659
3704
  if (stale) return stale;
3660
- const handle = String(args.handle ?? "");
3661
- const rect = adapter.rectFor?.(handle) ?? void 0;
3705
+ const shown = String(args.handle ?? "");
3706
+ const handle = pageHandle(shown);
3707
+ const rect = await adapter.rectFor?.(handle) ?? void 0;
3662
3708
  if (pendingMode && adapter.confirm) {
3663
3709
  const ok = await adapter.confirm({ action: "submit", handle, label: handle });
3664
3710
  if (!ok) return errorResult("Declined by user");
3665
3711
  }
3666
3712
  const res = await adapter.submit(handle);
3667
- if (!res.ok) return errorResult(res.error ?? "Submit failed");
3668
- return textResult(`Submitted ${handle}`, { handle, rect });
3713
+ if (!res.ok) return failure(res.error, "Submit failed");
3714
+ return textResult(`Submitted ${oneLine(shown, CAP.label)}`, { handle: shown, rect });
3669
3715
  },
3670
3716
  (args) => target(`Submit ${String(args.handle ?? "")}`, String(args.handle ?? ""))
3671
3717
  );