agent-yes 1.130.0 → 1.132.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.
@@ -0,0 +1,8 @@
1
+ import "./ts-FPleHqxr.js";
2
+ import "./logger-B9h0djqx.js";
3
+ import "./versionChecker-4ovR76r7.js";
4
+ import "./pidStore-DWQoGxxA.js";
5
+ import "./globalPidIndex-C7r2m6s7.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-eDyeNYJQ.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-BcbPKaqz.js";
1
+ import { t as CLIS_CONFIG } from "./ts-FPleHqxr.js";
2
2
 
3
3
  //#region ts/SUPPORTED_CLIS.ts
4
4
  const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
5
5
 
6
6
  //#endregion
7
7
  export { SUPPORTED_CLIS as t };
8
- //# sourceMappingURL=SUPPORTED_CLIS-DgpRWiWM.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-eDyeNYJQ.js.map
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import { n as logger } from "./logger-B9h0djqx.js";
3
- import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-Bty629vj.js";
3
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-4ovR76r7.js";
4
4
  import { argv } from "process";
5
5
  import { execFileSync, spawn } from "child_process";
6
6
  import ms from "ms";
@@ -482,7 +482,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
482
482
  {
483
483
  const rawArg = process.argv[2];
484
484
  const isHelpFlag = rawArg === "-h" || rawArg === "--help";
485
- const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-D9CFDaVM.js");
485
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-CjrE1pU-.js");
486
486
  if (isHelpFlag && process.argv.length === 3) {
487
487
  cmdHelp();
488
488
  process.exit(0);
@@ -515,7 +515,7 @@ if (config.useRust) {
515
515
  }
516
516
  }
517
517
  if (rustBinary) {
518
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BD3Ly7re.js");
518
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DnObTI1A.js");
519
519
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
520
520
  if (config.verbose) {
521
521
  console.log(`[rust] Using binary: ${rustBinary}`);
@@ -545,7 +545,7 @@ if (config.showVersion) {
545
545
  process.exit(0);
546
546
  }
547
547
  if (config.appendPrompt) {
548
- const { PidStore } = await import("./pidStore-C4c2O15q.js");
548
+ const { PidStore } = await import("./pidStore-BweOirbR.js");
549
549
  const ipcPath = await PidStore.findActiveFifo(process.cwd());
550
550
  if (!ipcPath) {
551
551
  console.error("No active agent with IPC found in current directory.");
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-BcbPKaqz.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-FPleHqxr.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-Bty629vj.js";
4
- import "./pidStore-CGKIhaJO.js";
3
+ import "./versionChecker-4ovR76r7.js";
4
+ import "./pidStore-DWQoGxxA.js";
5
5
  import "./globalPidIndex-C7r2m6s7.js";
6
6
 
7
7
  export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
@@ -0,0 +1,5 @@
1
+ import "./logger-B9h0djqx.js";
2
+ import { t as PidStore } from "./pidStore-DWQoGxxA.js";
3
+ import "./globalPidIndex-C7r2m6s7.js";
4
+
5
+ export { PidStore };
@@ -4,6 +4,7 @@ import { a as updateGlobalPidStatus, n as maybeCompactGlobalPids, r as pruneOldL
4
4
  import { closeSync, existsSync, fsyncSync, openSync } from "fs";
5
5
  import { appendFile, mkdir, readFile, rename, writeFile } from "fs/promises";
6
6
  import path from "path";
7
+ import { randomBytes } from "node:crypto";
7
8
  import { lock } from "proper-lockfile";
8
9
 
9
10
  //#region ts/JsonlStore.ts
@@ -208,6 +209,8 @@ var PidStore = class PidStore {
208
209
  const argsJson = JSON.stringify(args);
209
210
  const logFile = this.getRawLogPath(pid);
210
211
  const fifoFile = this.getFifoPath(pid);
212
+ const existing = this.store.findOne((doc) => doc.pid === pid);
213
+ const agentId = existing?.agentId ?? randomBytes(6).toString("hex");
211
214
  const record = {
212
215
  pid,
213
216
  cli,
@@ -218,9 +221,9 @@ var PidStore = class PidStore {
218
221
  fifoFile,
219
222
  status: "active",
220
223
  exitReason: "",
221
- startedAt: now
224
+ startedAt: now,
225
+ agentId
222
226
  };
223
- const existing = this.store.findOne((doc) => doc.pid === pid);
224
227
  if (existing) await this.store.updateById(existing._id, record);
225
228
  else await this.store.append(record);
226
229
  const result = this.store.findOne((doc) => doc.pid === pid);
@@ -242,7 +245,8 @@ var PidStore = class PidStore {
242
245
  exit_reason: null,
243
246
  started_at: now,
244
247
  wrapper_pid: wrapperPid ?? null,
245
- parent_pid: parentPid ?? null
248
+ parent_pid: parentPid ?? null,
249
+ agent_id: agentId
246
250
  }).then(() => maybeCompactGlobalPids()).catch(() => null);
247
251
  return result;
248
252
  }
@@ -363,4 +367,4 @@ pid-db/
363
367
 
364
368
  //#endregion
365
369
  export { PidStore as t };
366
- //# sourceMappingURL=pidStore-CGKIhaJO.js.map
370
+ //# sourceMappingURL=pidStore-DWQoGxxA.js.map
@@ -1,9 +1,9 @@
1
- import "./ts-BcbPKaqz.js";
1
+ import "./ts-FPleHqxr.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-Bty629vj.js";
4
- import "./pidStore-CGKIhaJO.js";
3
+ import "./versionChecker-4ovR76r7.js";
4
+ import "./pidStore-DWQoGxxA.js";
5
5
  import "./globalPidIndex-C7r2m6s7.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DgpRWiWM.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-eDyeNYJQ.js";
7
7
  import { n as resolveSpawnCwd } from "./workspaceConfig-BJO4fzEn.js";
8
8
  import { createHash } from "node:crypto";
9
9
 
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
141
141
 
142
142
  //#endregion
143
143
  export { cmdSchedule };
144
- //# sourceMappingURL=schedule-8L8M2WD3.js.map
144
+ //# sourceMappingURL=schedule-B53gHsN7.js.map
@@ -1,13 +1,13 @@
1
- import "./ts-BcbPKaqz.js";
1
+ import "./ts-FPleHqxr.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import { r as getInstalledPackage } from "./versionChecker-Bty629vj.js";
4
- import "./pidStore-CGKIhaJO.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-4ovR76r7.js";
4
+ import "./pidStore-DWQoGxxA.js";
5
5
  import { a as updateGlobalPidStatus } from "./globalPidIndex-C7r2m6s7.js";
6
6
  import { t as pgidForWrapper } from "./reaper-BkjPN7mw.js";
7
7
  import "./configShared-C5QaNPnz.js";
8
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DgpRWiWM.js";
8
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-eDyeNYJQ.js";
9
9
  import "./remotes-D8GvSbhf.js";
10
- import { d as listRecords, g as resolveOne, i as controlCodeFromName, m as renderRawLog, p as readNotes, s as extractTaskCounts, x as writeToIpc, y as snapshotStatus } from "./subcommands-BjxWxxGq.js";
10
+ import { d as listRecords, g as resolveOne, i as controlCodeFromName, m as renderRawLog, p as readNotes, s as extractTaskCounts, x as writeToIpc, y as snapshotStatus } from "./subcommands-CpEK563F.js";
11
11
  import yargs from "yargs";
12
12
  import { mkdir, open, readFile, stat, writeFile } from "fs/promises";
13
13
  import { homedir, hostname, userInfo } from "os";
@@ -1142,4 +1142,4 @@ Options:
1142
1142
 
1143
1143
  //#endregion
1144
1144
  export { cmdServe };
1145
- //# sourceMappingURL=serve-DYcTukF5.js.map
1145
+ //# sourceMappingURL=serve-Bu-QzAlr.js.map
@@ -32,7 +32,7 @@ async function cmdSetup(rest) {
32
32
  if (!existsSync(abs)) process.stderr.write(` note: that directory doesn't exist yet — create it, or agents spawned there will fail\n`);
33
33
  if (noShare) return 0;
34
34
  process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
35
- const { cmdServe } = await import("./serve-DYcTukF5.js");
35
+ const { cmdServe } = await import("./serve-Bu-QzAlr.js");
36
36
  return cmdServe([
37
37
  "install",
38
38
  "--share",
@@ -42,4 +42,4 @@ async function cmdSetup(rest) {
42
42
 
43
43
  //#endregion
44
44
  export { cmdSetup };
45
- //# sourceMappingURL=setup-Ba4q-a7V.js.map
45
+ //# sourceMappingURL=setup-DTgN_sqc.js.map
@@ -2,6 +2,6 @@ import "./logger-B9h0djqx.js";
2
2
  import "./globalPidIndex-C7r2m6s7.js";
3
3
  import "./configShared-C5QaNPnz.js";
4
4
  import "./remotes-D8GvSbhf.js";
5
- import { _ as resolveReadWindow, a as cursorAbs, b as stopTipForCli, c as finalizedLines, d as listRecords, f as matchKeyword, g as resolveOne, h as renderRawLogLines, i as controlCodeFromName, l as isPidAlive, m as renderRawLog, n as READ_PAGE_DEFAULT, o as extractNeedsInput, p as readNotes, r as cmdHelp, s as extractTaskCounts, t as GRACEFUL_EXIT_COMMANDS, u as isSubcommand, v as runSubcommand, x as writeToIpc, y as snapshotStatus } from "./subcommands-BjxWxxGq.js";
5
+ import { _ as resolveReadWindow, a as cursorAbs, b as stopTipForCli, c as finalizedLines, d as listRecords, f as matchKeyword, g as resolveOne, h as renderRawLogLines, i as controlCodeFromName, l as isPidAlive, m as renderRawLog, n as READ_PAGE_DEFAULT, o as extractNeedsInput, p as readNotes, r as cmdHelp, s as extractTaskCounts, t as GRACEFUL_EXIT_COMMANDS, u as isSubcommand, v as runSubcommand, x as writeToIpc, y as snapshotStatus } from "./subcommands-CpEK563F.js";
6
6
 
7
7
  export { cmdHelp, isSubcommand, runSubcommand };
@@ -524,15 +524,15 @@ async function runSubcommand(argv) {
524
524
  case "restart": return await cmdRestart(rest);
525
525
  case "note": return await cmdNote(rest);
526
526
  case "serve": {
527
- const { cmdServe } = await import("./serve-DYcTukF5.js");
527
+ const { cmdServe } = await import("./serve-Bu-QzAlr.js");
528
528
  return cmdServe(rest);
529
529
  }
530
530
  case "setup": {
531
- const { cmdSetup } = await import("./setup-Ba4q-a7V.js");
531
+ const { cmdSetup } = await import("./setup-DTgN_sqc.js");
532
532
  return cmdSetup(rest);
533
533
  }
534
534
  case "schedule": {
535
- const { cmdSchedule } = await import("./schedule-8L8M2WD3.js");
535
+ const { cmdSchedule } = await import("./schedule-B53gHsN7.js");
536
536
  return cmdSchedule(rest);
537
537
  }
538
538
  case "remote": {
@@ -562,6 +562,7 @@ function matchKeyword(record, keyword) {
562
562
  if (record.cwd.toLowerCase().includes(kw)) return true;
563
563
  if (record.cli.toLowerCase() === kw) return true;
564
564
  if (record.prompt && record.prompt.toLowerCase().includes(kw)) return true;
565
+ if (record.agent_id && record.agent_id.toLowerCase().startsWith(kw)) return true;
565
566
  return false;
566
567
  }
567
568
  async function listRecords(keyword, opts) {
@@ -2407,4 +2408,4 @@ async function cmdResultSet(rest) {
2407
2408
 
2408
2409
  //#endregion
2409
2410
  export { resolveReadWindow as _, cursorAbs as a, stopTipForCli as b, finalizedLines as c, listRecords as d, matchKeyword as f, resolveOne as g, renderRawLogLines as h, controlCodeFromName as i, isPidAlive as l, renderRawLog as m, READ_PAGE_DEFAULT as n, extractNeedsInput as o, readNotes as p, cmdHelp as r, extractTaskCounts as s, GRACEFUL_EXIT_COMMANDS as t, isSubcommand as u, runSubcommand as v, writeToIpc as x, snapshotStatus as y };
2410
- //# sourceMappingURL=subcommands-BjxWxxGq.js.map
2411
+ //# sourceMappingURL=subcommands-CpEK563F.js.map
@@ -1,8 +1,8 @@
1
1
  import { n as logger, t as addTransport } from "./logger-B9h0djqx.js";
2
- import { r as getInstalledPackage } from "./versionChecker-Bty629vj.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-4ovR76r7.js";
3
3
  import { t as agentYesHome } from "./agentYesHome-BvaUOzCV.js";
4
4
  import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-CJxsoGdb.js";
5
- import { t as PidStore } from "./pidStore-CGKIhaJO.js";
5
+ import { t as PidStore } from "./pidStore-DWQoGxxA.js";
6
6
  import { i as readGlobalPids } from "./globalPidIndex-C7r2m6s7.js";
7
7
  import { n as register, r as sweep } from "./reaper-BkjPN7mw.js";
8
8
  import { arch, platform } from "process";
@@ -1787,4 +1787,4 @@ function sleep(ms) {
1787
1787
 
1788
1788
  //#endregion
1789
1789
  export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
1790
- //# sourceMappingURL=ts-BcbPKaqz.js.map
1790
+ //# sourceMappingURL=ts-FPleHqxr.js.map
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
7
7
 
8
8
  //#region package.json
9
9
  var name = "agent-yes";
10
- var version = "1.130.0";
10
+ var version = "1.132.0";
11
11
 
12
12
  //#endregion
13
13
  //#region ts/versionChecker.ts
@@ -215,4 +215,4 @@ async function displayVersion() {
215
215
 
216
216
  //#endregion
217
217
  export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
218
- //# sourceMappingURL=versionChecker-Bty629vj.js.map
218
+ //# sourceMappingURL=versionChecker-4ovR76r7.js.map
@@ -291,8 +291,9 @@ e2e keys = HKDF(S, "ay/ay-e2e-1/key/…") → never leave your machine or bro
291
291
  <footer>
292
292
  Curious how it's built? The whole thing is about 200 lines:
293
293
  <code>lab/ui/e2e.js</code> (the shared crypto), <code>ts/share.ts</code> (host), and the
294
- console client in <code>lab/ui/index.html</code>. ·
295
- <a href="https://agent-yes.com/">← back to the console</a>
294
+ console client in <code>lab/ui/index.html</code>. <br /><br />
295
+ <a href="/blog/">← all posts</a> · <a href="/architecture.html">Architecture map</a> ·
296
+ <a href="/w/">Console</a> · <a href="/">agent-yes.com</a>
296
297
  </footer>
297
298
  </main>
298
299
  </body>
@@ -0,0 +1,174 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>agent-yes — blog &amp; design notes</title>
7
+ <meta
8
+ name="description"
9
+ content="Design notes and write-ups for agent-yes: the architecture graph, end-to-end-encrypted share links, and more."
10
+ />
11
+ <link
12
+ rel="icon"
13
+ href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ctext y='14' font-size='14'%3E%E2%9C%93%3C/text%3E%3C/svg%3E"
14
+ />
15
+ <style>
16
+ :root {
17
+ --bg: #0d1117;
18
+ --fg: #e6edf3;
19
+ --muted: #8b949e;
20
+ --accent: #58a6ff;
21
+ --green: #3fb950;
22
+ --card: #161b22;
23
+ --border: #30363d;
24
+ }
25
+ @media (prefers-color-scheme: light) {
26
+ :root {
27
+ --bg: #ffffff;
28
+ --fg: #1f2328;
29
+ --muted: #59636e;
30
+ --accent: #0969da;
31
+ --green: #1a7f37;
32
+ --card: #f6f8fa;
33
+ --border: #d0d7de;
34
+ }
35
+ }
36
+ * {
37
+ box-sizing: border-box;
38
+ }
39
+ body {
40
+ background: var(--bg);
41
+ color: var(--fg);
42
+ font:
43
+ 16px/1.65 -apple-system,
44
+ BlinkMacSystemFont,
45
+ "Segoe UI",
46
+ Helvetica,
47
+ Arial,
48
+ sans-serif;
49
+ margin: 0;
50
+ padding: 0 20px;
51
+ }
52
+ main {
53
+ max-width: 760px;
54
+ margin: 0 auto;
55
+ padding: 40px 0 96px;
56
+ }
57
+ header {
58
+ display: flex;
59
+ align-items: center;
60
+ justify-content: space-between;
61
+ padding: 4px 0 28px;
62
+ }
63
+ .brand {
64
+ font-weight: 700;
65
+ font-size: 18px;
66
+ letter-spacing: -0.01em;
67
+ }
68
+ .brand .tick {
69
+ color: var(--green);
70
+ }
71
+ nav a {
72
+ color: var(--muted);
73
+ margin-left: 18px;
74
+ font-size: 14px;
75
+ }
76
+ a {
77
+ color: var(--accent);
78
+ text-decoration: none;
79
+ }
80
+ a:hover {
81
+ text-decoration: underline;
82
+ }
83
+ h1 {
84
+ font-size: 2em;
85
+ line-height: 1.2;
86
+ margin: 12px 0 6px;
87
+ }
88
+ .sub {
89
+ color: var(--muted);
90
+ margin: 0 0 28px;
91
+ }
92
+ .post {
93
+ display: block;
94
+ background: var(--card);
95
+ border: 1px solid var(--border);
96
+ border-radius: 12px;
97
+ padding: 18px 20px;
98
+ margin: 14px 0;
99
+ color: inherit;
100
+ }
101
+ .post:hover {
102
+ text-decoration: none;
103
+ border-color: var(--accent);
104
+ }
105
+ .post .tag {
106
+ display: inline-block;
107
+ font-size: 0.72em;
108
+ font-weight: 600;
109
+ letter-spacing: 0.04em;
110
+ text-transform: uppercase;
111
+ color: var(--accent);
112
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
113
+ border-radius: 999px;
114
+ padding: 2px 9px;
115
+ margin-bottom: 9px;
116
+ }
117
+ .post h2 {
118
+ font-size: 1.18em;
119
+ margin: 0 0 6px;
120
+ }
121
+ .post p {
122
+ margin: 0;
123
+ color: var(--muted);
124
+ font-size: 0.95em;
125
+ }
126
+ footer {
127
+ color: var(--muted);
128
+ font-size: 0.9em;
129
+ margin-top: 40px;
130
+ border-top: 1px solid var(--border);
131
+ padding-top: 20px;
132
+ }
133
+ </style>
134
+ </head>
135
+ <body>
136
+ <main>
137
+ <header>
138
+ <div class="brand"><span class="tick">✓</span> agent-yes</div>
139
+ <nav>
140
+ <a href="/">Home</a>
141
+ <a href="/w/">Console</a>
142
+ <a href="/architecture.html">Architecture</a>
143
+ <a href="https://github.com/snomiao/agent-yes">GitHub</a>
144
+ </nav>
145
+ </header>
146
+
147
+ <h1>Blog &amp; design notes</h1>
148
+ <p class="sub">How agent-yes is built, and where it's going.</p>
149
+
150
+ <a class="post" href="/architecture.html">
151
+ <span class="tag">Architecture · living map</span>
152
+ <h2>The agent-yes graph — today &amp; tomorrow</h2>
153
+ <p>
154
+ An interactive map of the whole system: one agent → one local fabric → one API handler →
155
+ many transports → one URL. What's built, what's experimental, and what's next.
156
+ </p>
157
+ </a>
158
+
159
+ <a class="post" href="/blog/e2ee-share-links/">
160
+ <span class="tag">Security</span>
161
+ <h2>End-to-end encryption for agent-yes share links</h2>
162
+ <p>
163
+ How share links stay private even if the signaling relay is compromised: an HKDF key
164
+ split, AES-256-GCM with per-connection keys, and a fail-closed handshake.
165
+ </p>
166
+ </a>
167
+
168
+ <footer>
169
+ <a href="/">← agent-yes.com</a> · <a href="/w/">Console</a> ·
170
+ <a href="https://github.com/snomiao/agent-yes">GitHub</a>
171
+ </footer>
172
+ </main>
173
+ </body>
174
+ </html>
package/lab/ui/index.html CHANGED
@@ -2506,12 +2506,17 @@
2506
2506
 
2507
2507
  // The local source is only worth polling when this page is actually backed
2508
2508
  // by an ay serve: localhost, or served by `ay serve --http` (which leaves a
2509
- // token), or when there are no rooms to fall back on. On the public origin
2510
- // with rooms, skip it so we don't hammer a 404 every poll.
2509
+ // token), or when there are no rooms to fall back on. The public
2510
+ // agent-yes.com origin serves only static assets + WS rooms (no same-origin
2511
+ // /api), so never probe it — otherwise a bare /w/ visit (e.g. the landing's
2512
+ // "Console" link) 404s on /api/ls + /api/ls/subscribe every poll.
2511
2513
  function ensureLocalSource() {
2512
2514
  const isLocalhost = ["localhost", "127.0.0.1", "[::1]"].includes(location.hostname);
2513
2515
  const hasToken = !!localStorage.getItem("ay.localToken");
2514
- const enabled = isLocalhost || hasToken || Object.keys(loadRooms()).length === 0;
2516
+ const isPublicOrigin =
2517
+ location.hostname === "agent-yes.com" || location.hostname.endsWith(".agent-yes.com");
2518
+ const enabled =
2519
+ isLocalhost || hasToken || (!isPublicOrigin && Object.keys(loadRooms()).length === 0);
2515
2520
  if (enabled && !sources.has(LOCAL)) {
2516
2521
  const s = {
2517
2522
  id: LOCAL,
@@ -199,6 +199,7 @@
199
199
  <div class="brand"><span class="tick">✓</span> agent-yes</div>
200
200
  <nav>
201
201
  <a href="/w/">Console</a>
202
+ <a href="/architecture.html">Architecture</a>
202
203
  <a href="/blog/">Blog</a>
203
204
  <a href="https://github.com/snomiao/agent-yes">GitHub</a>
204
205
  </nav>
@@ -263,8 +264,8 @@ powershell -c "irm https://agent-yes.com/setup.ps1 | iex"</code></pre>
263
264
 
264
265
  <footer class="wrap" style="padding-left: 0; padding-right: 0">
265
266
  <div>
266
- <a href="/w/">Console</a> · <a href="/blog/">Blog</a> ·
267
- <a href="https://github.com/snomiao/agent-yes">GitHub</a> ·
267
+ <a href="/w/">Console</a> · <a href="/architecture.html">Architecture</a> ·
268
+ <a href="/blog/">Blog</a> · <a href="https://github.com/snomiao/agent-yes">GitHub</a> ·
268
269
  <a href="https://www.npmjs.com/package/agent-yes">npm</a>
269
270
  </div>
270
271
  <div style="margin-top: 8px">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.130.0",
3
+ "version": "1.132.0",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
@@ -55,6 +55,29 @@ describe("globalPidIndex", () => {
55
55
  });
56
56
  });
57
57
 
58
+ it("round-trips agent_id and preserves it through a status update", async () => {
59
+ const mod = await loadModule();
60
+ await mod.appendGlobalPid({
61
+ pid: 31313,
62
+ cli: "claude",
63
+ prompt: null,
64
+ cwd: "/a",
65
+ log_file: null,
66
+ status: "active",
67
+ exit_code: null,
68
+ exit_reason: null,
69
+ started_at: 1,
70
+ agent_id: "deadbeef0001",
71
+ });
72
+ // updateStatus appends a merged record by pid; agent_id must survive since
73
+ // the patch doesn't include it (last-line-wins merge spreads the prior doc).
74
+ await mod.updateGlobalPidStatus(31313, { status: "idle" });
75
+
76
+ const records = await mod.readGlobalPids();
77
+ expect(records).toHaveLength(1);
78
+ expect(records[0]).toMatchObject({ pid: 31313, status: "idle", agent_id: "deadbeef0001" });
79
+ });
80
+
58
81
  it("merges multiple appends for the same pid (last write wins)", async () => {
59
82
  const mod = await loadModule();
60
83
  await mod.appendGlobalPid({
@@ -47,6 +47,11 @@ export interface GlobalPidRecord {
47
47
  // started from a human shell. Builds the agent>subagent tree: a child links to
48
48
  // its parent via child.parent_pid === parent.wrapper_pid. See buildAgentForest.
49
49
  parent_pid?: number | null;
50
+ // Stable id minted once at registration so a share grant or `ay <cmd> <id>`
51
+ // can reference this agent without its ephemeral pid. Mirrors Rust's `agent_id`
52
+ // (snake_case). Currently per-process; cross-restart re-binding is a follow-up
53
+ // (see docs/agent-sharing.md). Preserved verbatim through merges/compaction.
54
+ agent_id?: string | null;
50
55
  }
51
56
 
52
57
  /**
package/ts/pidStore.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { mkdir, writeFile } from "fs/promises";
2
+ import { randomBytes } from "node:crypto";
2
3
  import path from "path";
3
4
  import { logger } from "./logger.ts";
4
5
  import { JsonlStore } from "./JsonlStore.ts";
@@ -23,6 +24,8 @@ export interface PidRecord {
23
24
  exitReason: string;
24
25
  exitCode?: number;
25
26
  startedAt: number;
27
+ // Stable id minted at registration; mirrored to the global index as `agent_id`.
28
+ agentId?: string;
26
29
  }
27
30
 
28
31
  export class PidStore {
@@ -73,6 +76,11 @@ export class PidStore {
73
76
  const logFile = this.getRawLogPath(pid);
74
77
  const fifoFile = this.getFifoPath(pid);
75
78
 
79
+ // Upsert by pid. Reuse an existing record's agent id so re-registration
80
+ // (e.g. status churn) keeps the id stable; mint a fresh 12-hex id otherwise.
81
+ const existing = this.store.findOne((doc) => doc.pid === pid);
82
+ const agentId = existing?.agentId ?? randomBytes(6).toString("hex");
83
+
76
84
  const record: Omit<PidRecord, "_id"> = {
77
85
  pid,
78
86
  cli,
@@ -84,10 +92,9 @@ export class PidStore {
84
92
  status: "active",
85
93
  exitReason: "",
86
94
  startedAt: now,
95
+ agentId,
87
96
  };
88
97
 
89
- // Upsert by pid
90
- const existing = this.store.findOne((doc) => doc.pid === pid);
91
98
  if (existing) {
92
99
  await this.store.updateById(existing._id!, record);
93
100
  } else {
@@ -119,6 +126,7 @@ export class PidStore {
119
126
  started_at: now,
120
127
  wrapper_pid: wrapperPid ?? null,
121
128
  parent_pid: parentPid ?? null,
129
+ agent_id: agentId,
122
130
  })
123
131
  .then(() => maybeCompactGlobalPids())
124
132
  .catch(() => null);
@@ -140,6 +140,16 @@ describe("subcommands.matchKeyword", () => {
140
140
  const r = { ...baseRecord, prompt: null };
141
141
  expect(matchKeyword(r, "parser")).toBe(false);
142
142
  });
143
+
144
+ it("matches by agent_id prefix", async () => {
145
+ const { matchKeyword } = await loadModule();
146
+ const r = { ...baseRecord, agent_id: "a1b2c3d4e5f6" };
147
+ expect(matchKeyword(r, "a1b2c3d4e5f6")).toBe(true); // full id
148
+ expect(matchKeyword(r, "a1b2c3")).toBe(true); // prefix
149
+ expect(matchKeyword(r, "A1B2C3")).toBe(true); // case-insensitive
150
+ expect(matchKeyword(r, "b2c3")).toBe(false); // not a prefix (mid-string)
151
+ expect(matchKeyword({ ...baseRecord, agent_id: null }, "a1b2")).toBe(false);
152
+ });
143
153
  });
144
154
 
145
155
  describe("subcommands.runSubcommand routing", () => {
package/ts/subcommands.ts CHANGED
Binary file
@@ -1,8 +0,0 @@
1
- import "./ts-BcbPKaqz.js";
2
- import "./logger-B9h0djqx.js";
3
- import "./versionChecker-Bty629vj.js";
4
- import "./pidStore-CGKIhaJO.js";
5
- import "./globalPidIndex-C7r2m6s7.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DgpRWiWM.js";
7
-
8
- export { SUPPORTED_CLIS };
@@ -1,5 +0,0 @@
1
- import "./logger-B9h0djqx.js";
2
- import { t as PidStore } from "./pidStore-CGKIhaJO.js";
3
- import "./globalPidIndex-C7r2m6s7.js";
4
-
5
- export { PidStore };