agent-yes 1.200.0 → 1.202.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 (38) hide show
  1. package/default.config.yaml +8 -8
  2. package/dist/{SUPPORTED_CLIS-Dt-oEBTl.js → SUPPORTED_CLIS-Cc4YcXL_.js} +2 -2
  3. package/dist/SUPPORTED_CLIS-ChdPabFX.js +9 -0
  4. package/dist/{agentShare-D-9ppbuL.js → agentShare-e4ErqbAZ.js} +2 -2
  5. package/dist/cli.js +4 -4
  6. package/dist/index.js +2 -2
  7. package/dist/{notifyDaemon-CQZ_wPhN.js → notifyDaemon-Bo-RiQ2N.js} +2 -2
  8. package/dist/{rustBinary-C5SrmIUM.js → rustBinary-Dd7-HOFy.js} +2 -2
  9. package/dist/{schedule-lPUt6BkE.js → schedule-Hu3krhNK.js} +4 -4
  10. package/dist/{serve-DlUJ7Hg9.js → serve-D4B43UQC.js} +12 -12
  11. package/dist/{setup-Dalhb8_0.js → setup-hUonzP6V.js} +2 -2
  12. package/dist/{subcommands-g1kLml5I.js → subcommands-DQmW41_L.js} +1 -1
  13. package/dist/{subcommands-DvXyUjWT.js → subcommands-DbiyHGKA.js} +53 -11
  14. package/dist/{ts-Oyau4Eap.js → ts--ZOQIaTr.js} +2 -2
  15. package/dist/{versionChecker-CeLrr-kQ.js → versionChecker-D2egG8Wk.js} +2 -2
  16. package/dist/{ws-DZDjlG3o.js → ws-CygS4IEs.js} +2 -2
  17. package/lab/ui/console-logic.js +32 -2
  18. package/lab/ui/index.html +99 -24
  19. package/lab/ui/qrcode.js +548 -565
  20. package/lab/ui/room-client.js +70 -91
  21. package/lab/ui/sw.js +17 -7
  22. package/package.json +7 -7
  23. package/scripts/build-rgui.ts +3 -1
  24. package/ts/agentShare.spec.ts +5 -3
  25. package/ts/badges.spec.ts +84 -1
  26. package/ts/badges.ts +69 -5
  27. package/ts/notifyDaemon.spec.ts +2 -8
  28. package/ts/notifyDaemon.ts +32 -33
  29. package/ts/notifyInbox.spec.ts +2 -1
  30. package/ts/notifyRouter.spec.ts +7 -11
  31. package/ts/notifyStore.spec.ts +4 -1
  32. package/ts/notifyStore.ts +18 -14
  33. package/ts/serve.spec.ts +4 -6
  34. package/ts/serve.ts +69 -17
  35. package/ts/subcommands.ts +46 -18
  36. package/ts/ws.spec.ts +31 -7
  37. package/ts/ws.ts +15 -4
  38. package/dist/SUPPORTED_CLIS-D8PoWxsA.js +0 -9
package/lab/ui/index.html CHANGED
@@ -1835,7 +1835,11 @@
1835
1835
  <button id="portsbtn" class="viewbtn" title="manage exposed localhost ports">
1836
1836
  ⇄ ports
1837
1837
  </button>
1838
- <button id="rguibtn" class="viewbtn" title="open the agent graph view (/r/) for this fleet">
1838
+ <button
1839
+ id="rguibtn"
1840
+ class="viewbtn"
1841
+ title="open the agent graph view (/r/) for this fleet"
1842
+ >
1839
1843
  ⌗ graph
1840
1844
  </button>
1841
1845
  <button id="newbtn" class="newbtn" title="spawn a new agent on this fleet">
@@ -2071,7 +2075,11 @@
2071
2075
  WebRTC tunnel (Service Worker proxies /w/p/<src>/<port>/*, no relay). -->
2072
2076
  <div class="preview-overlay" id="previewOverlay" hidden>
2073
2077
  <div class="preview-bar">
2074
- <span class="preview-badge" title="served over a direct P2P WebRTC tunnel — traffic does not go through agent-yes.com">⚡ P2P · no relay</span>
2078
+ <span
2079
+ class="preview-badge"
2080
+ title="served over a direct P2P WebRTC tunnel — traffic does not go through agent-yes.com"
2081
+ >⚡ P2P · no relay</span
2082
+ >
2075
2083
  <span class="preview-title" id="previewTitle"></span>
2076
2084
  <button id="previewReload" type="button" title="reload">↻</button>
2077
2085
  <button id="previewPop" type="button" title="open in a new tab">↗</button>
@@ -2086,7 +2094,7 @@
2086
2094
  <div class="omnibox">
2087
2095
  <input
2088
2096
  id="omni-input"
2089
- placeholder="Search agents by title, then output… · &quot;/&quot; commands · /ws workspaces"
2097
+ placeholder='Search agents by title, then output… · "/" commands · /ws workspaces'
2090
2098
  spellcheck="false"
2091
2099
  autocapitalize="off"
2092
2100
  autocomplete="off"
@@ -2317,7 +2325,12 @@
2317
2325
  },
2318
2326
  // Open a WS to the previewed port over the tunnel (Vite HMR etc.).
2319
2327
  previewWs(port, path, protocols, handlers) {
2320
- return chRoom.room.openWs(peerId, "/__codehost/port/" + port + path, protocols, handlers);
2328
+ return chRoom.room.openWs(
2329
+ peerId,
2330
+ "/__codehost/port/" + port + path,
2331
+ protocols,
2332
+ handlers,
2333
+ );
2321
2334
  },
2322
2335
  async fetchJSON(path) {
2323
2336
  let res;
@@ -2597,13 +2610,21 @@
2597
2610
  .then(async (res) => {
2598
2611
  const headers = {};
2599
2612
  res.headers.forEach((v, k) => (headers[k] = v));
2600
- port.postMessage({ type: "head", status: res.status, statusText: res.statusText, headers });
2613
+ port.postMessage({
2614
+ type: "head",
2615
+ status: res.status,
2616
+ statusText: res.statusText,
2617
+ headers,
2618
+ });
2601
2619
  if (res.body) {
2602
2620
  const reader = res.body.getReader();
2603
2621
  for (;;) {
2604
2622
  const { done, value } = await reader.read();
2605
2623
  if (done) break;
2606
- const buf = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
2624
+ const buf = value.buffer.slice(
2625
+ value.byteOffset,
2626
+ value.byteOffset + value.byteLength,
2627
+ );
2607
2628
  port.postMessage({ type: "body", chunk: buf }, [buf]);
2608
2629
  }
2609
2630
  }
@@ -2638,7 +2659,11 @@
2638
2659
  this._queue = [];
2639
2660
  const tx = sources.get(src)?.tx;
2640
2661
  const u = new URL(this.url, location.href);
2641
- const protoList = protocols ? (Array.isArray(protocols) ? protocols : [protocols]) : undefined;
2662
+ const protoList = protocols
2663
+ ? Array.isArray(protocols)
2664
+ ? protocols
2665
+ : [protocols]
2666
+ : undefined;
2642
2667
  if (!tx || !tx.previewWs) return void this._fail();
2643
2668
  tx.previewWs(port, u.pathname + u.search, protoList, {
2644
2669
  onOpenAck: (ok, proto) => {
@@ -2658,7 +2683,8 @@
2658
2683
  })
2659
2684
  .then((h) => {
2660
2685
  this._handle = h;
2661
- if (this.readyState === 3 && this._closeReq) h.close(this._closeReq.code, this._closeReq.reason);
2686
+ if (this.readyState === 3 && this._closeReq)
2687
+ h.close(this._closeReq.code, this._closeReq.reason);
2662
2688
  })
2663
2689
  .catch(() => this._fail());
2664
2690
  }
@@ -2671,8 +2697,10 @@
2671
2697
  const h = this._handle;
2672
2698
  if (!h) return;
2673
2699
  if (typeof data === "string") h.sendText(data);
2674
- else if (data instanceof Blob) data.arrayBuffer().then((b) => h.sendBin(new Uint8Array(b)));
2675
- else if (ArrayBuffer.isView(data)) h.sendBin(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
2700
+ else if (data instanceof Blob)
2701
+ data.arrayBuffer().then((b) => h.sendBin(new Uint8Array(b)));
2702
+ else if (ArrayBuffer.isView(data))
2703
+ h.sendBin(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
2676
2704
  else h.sendBin(new Uint8Array(data));
2677
2705
  }
2678
2706
  send(data) {
@@ -3772,7 +3800,8 @@
3772
3800
  } catch {}
3773
3801
  if (!info || !info.claim) {
3774
3802
  $("exposeEmpty").hidden = false;
3775
- $("exposeEmpty").textContent = "Couldn't expose port " + port + " (is `ay serve` reachable?).";
3803
+ $("exposeEmpty").textContent =
3804
+ "Couldn't expose port " + port + " (is `ay serve` reachable?).";
3776
3805
  return null;
3777
3806
  }
3778
3807
  return info;
@@ -3798,7 +3827,8 @@
3798
3827
  // the Service Worker proxies over the machine's WebRTC tunnel (no relay).
3799
3828
  function openPreview(src, port) {
3800
3829
  // Scope-relative so it works at both /w/ (agent-yes.com) and / (ay serve).
3801
- const url = new URL("p/" + encodeURIComponent(src) + "/" + port + "/", location.href).pathname;
3830
+ const url = new URL("p/" + encodeURIComponent(src) + "/" + port + "/", location.href)
3831
+ .pathname;
3802
3832
  const frame = $("previewFrame");
3803
3833
  if (!frame) return window.open(url, "_blank");
3804
3834
  $("previewTitle").textContent = "localhost:" + port;
@@ -3849,7 +3879,8 @@
3849
3879
  return;
3850
3880
  }
3851
3881
  if (Array.isArray(arr))
3852
- for (const ex of arr) rows.push({ ...ex, _srcName: s.name || s.id, _src: s.id, _tx: tx });
3882
+ for (const ex of arr)
3883
+ rows.push({ ...ex, _srcName: s.name || s.id, _src: s.id, _tx: tx });
3853
3884
  }),
3854
3885
  );
3855
3886
  list.textContent = "";
@@ -5335,10 +5366,10 @@
5335
5366
  $("rguibtn").addEventListener("click", () => {
5336
5367
  const [selRoom, selPid] = sel ? sel.split("#") : [null, null];
5337
5368
  let room = selRoom && selRoom !== LOCAL && loadRooms()[selRoom] ? selRoom : null;
5338
- if (!room)
5339
- room = [...sources.values()].find((s) => s.kind === "rtc" && s.live)?.id ?? null;
5340
- const frag =
5341
- room ? "#" + encodeURIComponent(room) + (room === selRoom && selPid ? ":" + selPid : "") : "";
5369
+ if (!room) room = [...sources.values()].find((s) => s.kind === "rtc" && s.live)?.id ?? null;
5370
+ const frag = room
5371
+ ? "#" + encodeURIComponent(room) + (room === selRoom && selPid ? ":" + selPid : "")
5372
+ : "";
5342
5373
  location.href = "/r/" + frag;
5343
5374
  });
5344
5375
  // Cycle the sort order: state → created → identity → state.
@@ -5516,16 +5547,17 @@
5516
5547
  },
5517
5548
  ];
5518
5549
  // Build the command rows for a "/…"-prefixed query, targeting the anchor agent.
5519
- // Empty when nothing is open (a command with no agent to act on is a no-op) so
5520
- // the omnibox falls through to its normal search/spawn behaviour.
5550
+ // Agent-scoped commands are omitted when nothing is open (a command with no
5551
+ // agent to act on is a no-op); global commands (/filter) are always offered,
5552
+ // and with no rows at all the omnibox falls back to search/spawn behaviour.
5521
5553
  function omniCommandRows(q) {
5522
5554
  const target = omniAnchor();
5523
5555
  // Match on the FIRST token so a command can carry args after it
5524
5556
  // (e.g. "/fork fix the auth bug" → cmd "fork", topic "fix the auth bug").
5525
5557
  const parts = q.slice(1).trim().split(/\s+/).filter(Boolean);
5526
5558
  const cmdTerm = (parts[0] || "").toLowerCase(); // command token after "/"
5527
- // Agent-targeted commands need an open agent to act on; /ws (below)
5528
- // doesn't, so the target check gates only these rows, not the builder.
5559
+ // Agent-targeted commands need an open agent to act on; /ws and /filter
5560
+ // (below) don't, so the target check gates only these rows, not the builder.
5529
5561
  const rows = !target
5530
5562
  ? []
5531
5563
  : OMNI_COMMANDS.filter((c) => c.cmd.slice(1).startsWith(cmdTerm)).map((c) => ({
@@ -5557,6 +5589,14 @@
5557
5589
  // in runOmni before this builder runs. Needs no anchor: workspaces exist
5558
5590
  // independently of any open agent.
5559
5591
  if ("ws".startsWith(cmdTerm)) rows.push({ kind: "wshint" });
5592
+ // "/filter [tokens…]" — global: sets the left panel's filter box (#q) to the
5593
+ // arguments, same tokens the box itself takes (space = AND, repo:x tags).
5594
+ // With no args it clears the filter. Needs no anchor agent — it acts on the
5595
+ // list, not an agent — so it's offered even when nothing is open. Listed
5596
+ // last so bare "/" still defaults to /restart.
5597
+ if ("filter".startsWith(cmdTerm)) {
5598
+ rows.push({ kind: "filter", value: parts.slice(1).join(" ") });
5599
+ }
5560
5600
  return rows;
5561
5601
  }
5562
5602
 
@@ -5756,6 +5796,20 @@
5756
5796
  <div class="omni-sub">⏎ to choose a working dir &nbsp;·&nbsp; prompt: ${esc(q || "(empty)")}</div>
5757
5797
  </div></div>`;
5758
5798
  }
5799
+ if (r.kind === "filter") {
5800
+ const cur = $("q").value.trim();
5801
+ const title = r.value
5802
+ ? `⌕ Filter list: <b>${esc(r.value)}</b> <span style="opacity:.55">/filter</span>`
5803
+ : cur
5804
+ ? `⌕ Clear list filter <span style="opacity:.55">(now: ${esc(cur)})</span>`
5805
+ : `⌕ Filter list… <span style="opacity:.55">/filter repo:x claude</span>`;
5806
+ return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
5807
+ <span class="dot idle"></span>
5808
+ <div class="omni-main">
5809
+ <div class="omni-title">${title}</div>
5810
+ <div class="omni-sub">sets the left panel filter &nbsp;·&nbsp; space = AND, tags like repo:/wt:/cli:/host:</div>
5811
+ </div></div>`;
5812
+ }
5759
5813
  if (r.kind === "wshint") {
5760
5814
  return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
5761
5815
  <span class="dot active"></span>
@@ -5776,7 +5830,9 @@
5776
5830
  <span class="dot ${live ? "active" : "exited"}"></span>
5777
5831
  <div class="omni-main">
5778
5832
  <div class="omni-title">▤ ${esc(wsSpecOf(r.ws))}${
5779
- live ? ` <span style="opacity:.7">· ${live} agent${live > 1 ? "s" : ""}</span>` : ""
5833
+ live
5834
+ ? ` <span style="opacity:.7">· ${live} agent${live > 1 ? "s" : ""}</span>`
5835
+ : ""
5780
5836
  }${multi ? ` <span style="opacity:.55">@ ${esc(r.host)}</span>` : ""}</div>
5781
5837
  <div class="omni-sub">${esc(r.ws.path)}${st ? " &nbsp;·&nbsp; <b>" + esc(st) + "</b>" : ""} &nbsp;·&nbsp; ⏎ spawn agent here</div>
5782
5838
  </div></div>`;
@@ -5939,6 +5995,14 @@
5939
5995
  await row.cmd.run(row.target);
5940
5996
  return;
5941
5997
  }
5998
+ // "/filter …" sets the left panel's filter box; the input event does the
5999
+ // rest (persists ay.filter + re-renders the list), exactly as if typed.
6000
+ if (row && row.kind === "filter") {
6001
+ closeOmni(false);
6002
+ $("q").value = row.value;
6003
+ $("q").dispatchEvent(new Event("input"));
6004
+ return;
6005
+ }
5942
6006
  // /ws rows — handled BEFORE the ⌘⏎ spawn-here fallthrough: in the
5943
6007
  // workspace browser the typed text is a filter, not a prompt, so
5944
6008
  // "spawn here with this prompt" is never the right reading of it.
@@ -6538,14 +6602,25 @@
6538
6602
  // picker (options from /api/spawn-config `clis`), preselected from the
6539
6603
  // chain: selected agent's cli → last used cli → explicit user pick.
6540
6604
  const LAST_CLI_KEY = "ay.lastSpawnCli";
6541
- const CLI_FALLBACK = ["claude", "codex", "gemini", "copilot", "cursor-agent", "goose", "aider"];
6605
+ const CLI_FALLBACK = [
6606
+ "claude",
6607
+ "codex",
6608
+ "gemini",
6609
+ "copilot",
6610
+ "cursor-agent",
6611
+ "goose",
6612
+ "aider",
6613
+ ];
6542
6614
  function cliOptions(clis, preferred) {
6543
6615
  const list = clis && clis.length ? clis : CLI_FALLBACK;
6544
6616
  const has = preferred && list.includes(preferred);
6545
6617
  return (
6546
6618
  `<option value=""${has ? "" : " selected"} disabled>choose a CLI…</option>` +
6547
6619
  list
6548
- .map((c) => `<option value="${esc(c)}"${c === preferred && has ? " selected" : ""}>${esc(c)}</option>`)
6620
+ .map(
6621
+ (c) =>
6622
+ `<option value="${esc(c)}"${c === preferred && has ? " selected" : ""}>${esc(c)}</option>`,
6623
+ )
6549
6624
  .join("")
6550
6625
  );
6551
6626
  }