@cotal-ai/cli 0.6.0 → 0.8.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 (135) hide show
  1. package/dist/commands/channels.d.ts +4 -2
  2. package/dist/commands/channels.d.ts.map +1 -1
  3. package/dist/commands/channels.js +17 -18
  4. package/dist/commands/channels.js.map +1 -1
  5. package/dist/commands/console.d.ts.map +1 -1
  6. package/dist/commands/console.js +13 -29
  7. package/dist/commands/console.js.map +1 -1
  8. package/dist/commands/down-manifest.d.ts +6 -0
  9. package/dist/commands/down-manifest.d.ts.map +1 -0
  10. package/dist/commands/down-manifest.js +282 -0
  11. package/dist/commands/down-manifest.js.map +1 -0
  12. package/dist/commands/down.d.ts +5 -3
  13. package/dist/commands/down.d.ts.map +1 -1
  14. package/dist/commands/down.js +30 -3
  15. package/dist/commands/down.js.map +1 -1
  16. package/dist/commands/history.d.ts.map +1 -1
  17. package/dist/commands/history.js +6 -13
  18. package/dist/commands/history.js.map +1 -1
  19. package/dist/commands/join.d.ts.map +1 -1
  20. package/dist/commands/join.js +20 -7
  21. package/dist/commands/join.js.map +1 -1
  22. package/dist/commands/meshes.d.ts +5 -0
  23. package/dist/commands/meshes.d.ts.map +1 -0
  24. package/dist/commands/meshes.js +25 -0
  25. package/dist/commands/meshes.js.map +1 -0
  26. package/dist/commands/mint.d.ts.map +1 -1
  27. package/dist/commands/mint.js +2 -1
  28. package/dist/commands/mint.js.map +1 -1
  29. package/dist/commands/setup.d.ts.map +1 -1
  30. package/dist/commands/setup.js +66 -16
  31. package/dist/commands/setup.js.map +1 -1
  32. package/dist/commands/spawn-manifest.d.ts +10 -0
  33. package/dist/commands/spawn-manifest.d.ts.map +1 -0
  34. package/dist/commands/spawn-manifest.js +197 -0
  35. package/dist/commands/spawn-manifest.js.map +1 -0
  36. package/dist/commands/spawn.d.ts +4 -2
  37. package/dist/commands/spawn.d.ts.map +1 -1
  38. package/dist/commands/spawn.js +84 -25
  39. package/dist/commands/spawn.js.map +1 -1
  40. package/dist/commands/topology.d.ts +10 -0
  41. package/dist/commands/topology.d.ts.map +1 -0
  42. package/dist/commands/topology.js +46 -0
  43. package/dist/commands/topology.js.map +1 -0
  44. package/dist/commands/up.d.ts +4 -0
  45. package/dist/commands/up.d.ts.map +1 -1
  46. package/dist/commands/up.js +223 -6
  47. package/dist/commands/up.js.map +1 -1
  48. package/dist/commands/use.d.ts +7 -0
  49. package/dist/commands/use.d.ts.map +1 -0
  50. package/dist/commands/use.js +27 -0
  51. package/dist/commands/use.js.map +1 -0
  52. package/dist/commands/web.d.ts.map +1 -1
  53. package/dist/commands/web.js +60 -28
  54. package/dist/commands/web.js.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +27 -2
  57. package/dist/index.js.map +1 -1
  58. package/dist/lib/connect.d.ts +74 -0
  59. package/dist/lib/connect.d.ts.map +1 -0
  60. package/dist/lib/connect.js +91 -0
  61. package/dist/lib/connect.js.map +1 -0
  62. package/dist/lib/delivery-proc.d.ts.map +1 -1
  63. package/dist/lib/delivery-proc.js +2 -1
  64. package/dist/lib/delivery-proc.js.map +1 -1
  65. package/dist/lib/manager-proc.d.ts +4 -0
  66. package/dist/lib/manager-proc.d.ts.map +1 -1
  67. package/dist/lib/manager-proc.js +17 -0
  68. package/dist/lib/manager-proc.js.map +1 -1
  69. package/dist/lib/manifest/apply.d.ts +29 -0
  70. package/dist/lib/manifest/apply.d.ts.map +1 -0
  71. package/dist/lib/manifest/apply.js +138 -0
  72. package/dist/lib/manifest/apply.js.map +1 -0
  73. package/dist/lib/manifest/errors.d.ts +21 -0
  74. package/dist/lib/manifest/errors.d.ts.map +1 -0
  75. package/dist/lib/manifest/errors.js +19 -0
  76. package/dist/lib/manifest/errors.js.map +1 -0
  77. package/dist/lib/manifest/index.d.ts +13 -0
  78. package/dist/lib/manifest/index.d.ts.map +1 -0
  79. package/dist/lib/manifest/index.js +21 -0
  80. package/dist/lib/manifest/index.js.map +1 -0
  81. package/dist/lib/manifest/ledger.d.ts +81 -0
  82. package/dist/lib/manifest/ledger.d.ts.map +1 -0
  83. package/dist/lib/manifest/ledger.js +213 -0
  84. package/dist/lib/manifest/ledger.js.map +1 -0
  85. package/dist/lib/manifest/live.d.ts +25 -0
  86. package/dist/lib/manifest/live.d.ts.map +1 -0
  87. package/dist/lib/manifest/live.js +61 -0
  88. package/dist/lib/manifest/live.js.map +1 -0
  89. package/dist/lib/manifest/model.d.ts +71 -0
  90. package/dist/lib/manifest/model.d.ts.map +1 -0
  91. package/dist/lib/manifest/model.js +2 -0
  92. package/dist/lib/manifest/model.js.map +1 -0
  93. package/dist/lib/manifest/preflight.d.ts +12 -0
  94. package/dist/lib/manifest/preflight.d.ts.map +1 -0
  95. package/dist/lib/manifest/preflight.js +43 -0
  96. package/dist/lib/manifest/preflight.js.map +1 -0
  97. package/dist/lib/manifest/prepare.d.ts +57 -0
  98. package/dist/lib/manifest/prepare.d.ts.map +1 -0
  99. package/dist/lib/manifest/prepare.js +95 -0
  100. package/dist/lib/manifest/prepare.js.map +1 -0
  101. package/dist/lib/manifest/render.d.ts +41 -0
  102. package/dist/lib/manifest/render.d.ts.map +1 -0
  103. package/dist/lib/manifest/render.js +177 -0
  104. package/dist/lib/manifest/render.js.map +1 -0
  105. package/dist/lib/manifest/resolve.d.ts +5 -0
  106. package/dist/lib/manifest/resolve.d.ts.map +1 -0
  107. package/dist/lib/manifest/resolve.js +185 -0
  108. package/dist/lib/manifest/resolve.js.map +1 -0
  109. package/dist/lib/manifest/schema.d.ts +103 -0
  110. package/dist/lib/manifest/schema.d.ts.map +1 -0
  111. package/dist/lib/manifest/schema.js +77 -0
  112. package/dist/lib/manifest/schema.js.map +1 -0
  113. package/dist/lib/manifest/spawn-plan.d.ts +87 -0
  114. package/dist/lib/manifest/spawn-plan.d.ts.map +1 -0
  115. package/dist/lib/manifest/spawn-plan.js +75 -0
  116. package/dist/lib/manifest/spawn-plan.js.map +1 -0
  117. package/dist/lib/meshes.d.ts +2 -0
  118. package/dist/lib/meshes.d.ts.map +1 -0
  119. package/dist/lib/meshes.js +6 -0
  120. package/dist/lib/meshes.js.map +1 -0
  121. package/dist/lib/onboard.js +6 -6
  122. package/dist/lib/onboard.js.map +1 -1
  123. package/dist/lib/paths.js +1 -1
  124. package/dist/lib/paths.js.map +1 -1
  125. package/dist/lib/status.d.ts.map +1 -1
  126. package/dist/lib/status.js +2 -1
  127. package/dist/lib/status.js.map +1 -1
  128. package/dist/lib/transient.d.ts +7 -6
  129. package/dist/lib/transient.d.ts.map +1 -1
  130. package/dist/lib/transient.js +6 -25
  131. package/dist/lib/transient.js.map +1 -1
  132. package/dist/web/graph.html +207 -0
  133. package/dist/web/graph.js +508 -0
  134. package/dist/web/index.html +6 -0
  135. package/package.json +6 -2
@@ -2,12 +2,18 @@ import { spawn } from "node:child_process";
2
2
  import { mkdirSync, writeFileSync, readFileSync, existsSync, openSync, statSync, readSync, closeSync, } from "node:fs";
3
3
  import { resolve } from "node:path";
4
4
  import { parseArgs } from "node:util";
5
- import { isReachable, DEFAULT_SERVER, authDir, createSpaceAuth, loadSpaceAuth, saveSpaceAuth, serverConfig, mintCreds, newIdentity, setupSpaceStreams, seedChannelRegistry, } from "@cotal-ai/core";
5
+ import { isReachable, DEFAULT_SERVER, createSpaceAuth, serverConfig, mintCreds, mintMembershipObserverCreds, newIdentity, setupSpaceStreams, seedChannelRegistry, } from "@cotal-ai/core";
6
+ import { authDir, loadSpaceAuth, saveSpaceAuth, clearCurrent, findMesh, getCurrent, loadMeshes, recordMesh, removeMesh, setCurrent, } from "@cotal-ai/workspace";
6
7
  import { resolveSpace } from "../lib/status.js";
7
8
  import { c } from "../ui.js";
8
9
  import { resolveNatsServer } from "../lib/nats-bin.js";
9
10
  import { cotalPath, cotalRoot } from "../lib/paths.js";
10
11
  import { ensureDelivery, stopDelivery, stopOldHostingManagerIfPresent } from "../lib/delivery-proc.js";
12
+ import { startManagerDetached } from "../lib/manager-proc.js";
13
+ import { loadManifest } from "../lib/manifest/index.js";
14
+ import { buildLaunchSpec, genRunId, manifestToChannels, preflightConnectors, writeLaunchSpec } from "../lib/manifest/apply.js";
15
+ import { renderUpPlan, renderInherited, renderWarnings } from "../lib/manifest/render.js";
16
+ import { failManifest } from "./topology.js";
11
17
  export async function up(argv) {
12
18
  const { values } = parseArgs({
13
19
  args: argv,
@@ -20,13 +26,48 @@ export async function up(argv) {
20
26
  channels: { type: "string" }, // seed the channel registry from this JSON file
21
27
  detach: { type: "boolean" }, // run the server in the background (pid in .cotal/nats.pid)
22
28
  host: { type: "string" }, // bind address (default 127.0.0.1 — loopback; 0.0.0.0 to expose with auth)
29
+ runtime: { type: "string" }, // with -f: override the manifest's runtime (pty | tmux | cmux)
30
+ file: { type: "string", short: "f" }, // a mesh manifest (cotal.yaml) — fresh broker + channels + agents
31
+ "dry-run": { type: "boolean" }, // with -f: print the plan, mutate nothing
23
32
  },
24
33
  });
34
+ // `up -f cotal.yaml` is a distinct path: bring up a FRESH mesh described by a manifest (broker +
35
+ // channels + booted agents). It owns the whole space; deploying onto a RUNNING mesh is `spawn -f`.
36
+ // CLI flags override the manifest (flag > manifest > default) so the same file runs at a different
37
+ // port / runtime / space / auth without editing it.
38
+ if (values.file) {
39
+ await upManifest(values.file, {
40
+ dryRun: Boolean(values["dry-run"]),
41
+ server: values.server,
42
+ host: values.host,
43
+ space: values.space,
44
+ runtime: values.runtime,
45
+ open: values.open,
46
+ });
47
+ return;
48
+ }
25
49
  const server = values.server ?? DEFAULT_SERVER;
26
50
  const host = values.host ?? "127.0.0.1";
27
51
  if (await isReachable(server)) {
28
- console.log(c.green(`✓ NATS already running at ${server}`));
29
- return;
52
+ const space = values.space ?? resolveSpace(process.cwd());
53
+ const root = cotalRoot();
54
+ // A broker is already on this port. Only treat it as a no-op refresh when the registry confirms
55
+ // it's THIS exact mesh (same server + root + space). Anything else — a different space/root, or a
56
+ // broker we never recorded — we must NOT adopt: recording our space over it would let a later
57
+ // `spawn --space <s>` load the wrong root's creds. Today one broker serves one space (auth binds
58
+ // them), so a different space on this port can't be added to it yet — fail loudly and tell the
59
+ // user to free the port. (Hosting several spaces on one broker is the planned multi-space work.)
60
+ const held = loadMeshes().find((m) => m.server === server);
61
+ if (held && held.root === root && held.space === space) {
62
+ // A refresh of the SAME already-running mesh — its mode is fixed by how the live broker was
63
+ // started; preserve `held.mode` rather than relabel it from this invocation's `--open`.
64
+ recordOurMesh({ space, server, root, mode: held.mode, ts: new Date().toISOString() });
65
+ console.log(c.green(`✓ NATS already running at ${server}`));
66
+ return;
67
+ }
68
+ const who = held ? `mesh "${held.space}" (${held.root})` : "a broker not started here";
69
+ console.error(c.red(`✗ ${server} is already in use by ${who} — to run "${space}" use \`--server nats://${host}:<port>\` with a free port`));
70
+ process.exit(1);
30
71
  }
31
72
  if (values.detach) {
32
73
  const { pid, source } = await startMeshDetached({
@@ -45,6 +86,8 @@ export async function up(argv) {
45
86
  mkdirSync(storeDir, { recursive: true });
46
87
  const useAuth = !values.open;
47
88
  const space = values.space ?? resolveSpace(process.cwd());
89
+ assertAuthMatchesSpace(useAuth, space);
90
+ await claimSpace(space, server, cotalRoot());
48
91
  const seedFile = loadChannelsFile(values.channels);
49
92
  const setup = useAuth ? await authSetup(storeDir, server, space, host) : undefined;
50
93
  const port = Number(new URL(server).port) || 4222;
@@ -62,15 +105,116 @@ export async function up(argv) {
62
105
  const stop = () => { stopDelivery(); child.kill("SIGTERM"); };
63
106
  process.on("SIGINT", stop);
64
107
  process.on("SIGTERM", stop);
65
- child.on("exit", (code) => { stopDelivery(); process.exit(code ?? 0); });
108
+ // The broker is gone — drop it from the registry (and the `current` pointer if it was the default)
109
+ // so a later `cotal spawn` doesn't try to join a dead mesh.
110
+ child.on("exit", (code) => {
111
+ stopDelivery();
112
+ // Only unrecord if the registry still points at THIS broker. A newer broker for the same space
113
+ // (a concurrent `up`, or a different-port re-up that recorded after us) may have replaced our
114
+ // record — removing by name would clobber the live winner and hide it from the registry.
115
+ const mine = findMesh(space);
116
+ if (mine && mine.server === server && mine.root === cotalRoot()) {
117
+ removeMesh(space);
118
+ if (getCurrent() === space)
119
+ clearCurrent();
120
+ }
121
+ process.exit(code ?? 0);
122
+ });
66
123
  if (await waitReady(server, setup?.creds)) {
67
124
  await postStart(server, space, setup, seedFile);
68
125
  // Bring up the delivery daemon WITH the server (auth mode only — it self-gates on `.cotal/auth`).
69
126
  // It is part of the server, so `cotal up` starts it by default; open dev mode has no daemon.
70
127
  await startDeliveryWithBroker(space, server);
128
+ recordOurMesh({ space, server, root: cotalRoot(), mode: useAuth ? "auth" : "open", ts: new Date().toISOString() });
71
129
  }
72
130
  await new Promise(() => { });
73
131
  }
132
+ /** `cotal up -f cotal.yaml` — bring up a FRESH mesh from a manifest (broker + channels + booted
133
+ * agents). `up -f` is a broker-CREATION command: `broker.servers` is the bind address for the NEW
134
+ * local broker, never a connect target. A broker already reachable there (local OR remote) means
135
+ * "deploy onto it" — refuse and redirect to `spawn -f`; an unbindable/remote address makes the
136
+ * broker fail to start (no silent local fallback). It owns the whole space, so `cotal down` tears it
137
+ * down and no ownership ledger is needed (that's `spawn -f`). */
138
+ async function upManifest(file, opts) {
139
+ let prepared;
140
+ try {
141
+ prepared = loadManifest(resolve(file));
142
+ }
143
+ catch (e) {
144
+ failManifest(e);
145
+ }
146
+ if (opts.runtime && !["pty", "tmux", "cmux"].includes(opts.runtime)) {
147
+ console.error(c.red(`✗ unknown --runtime "${opts.runtime}" — expected pty, tmux, or cmux`));
148
+ process.exit(1);
149
+ }
150
+ // Apply CLI overrides to one effective manifest (flag > manifest > default) so render + seed +
151
+ // broker + launch all agree on the same values.
152
+ const eff = applyUpOverrides(prepared, opts);
153
+ const m = eff.manifest;
154
+ const server = m.broker?.servers ?? DEFAULT_SERVER;
155
+ const host = m.broker?.host ?? "127.0.0.1";
156
+ const open = m.broker?.auth === false; // default is auth
157
+ const runtime = m.runtime ?? "pty";
158
+ if (opts.dryRun) {
159
+ console.log(renderUpPlan(eff, server));
160
+ return;
161
+ }
162
+ // up -f never adopts a running broker. Reachable at the bind address ⇒ redirect to spawn -f.
163
+ if (await isReachable(server)) {
164
+ console.error(c.red(`✗ ${server} already has a broker — deploy this manifest onto it with \`cotal spawn -f ${file}\``));
165
+ process.exit(1);
166
+ }
167
+ // Connectors + their required binaries must exist before any mutation (no fallback).
168
+ const conn = preflightConnectors(prepared);
169
+ if (conn) {
170
+ console.error(c.red(`✗ connector preflight failed: ${conn}`));
171
+ process.exit(1);
172
+ }
173
+ // 1) fresh broker + space streams + channels seeded from the manifest (in-memory seed).
174
+ let pid;
175
+ try {
176
+ ({ pid } = await startMeshDetached({ server, space: m.space, open, host, seed: manifestToChannels(eff) }));
177
+ }
178
+ catch (e) {
179
+ console.error(c.red(`✗ ${e.message}`));
180
+ process.exit(1);
181
+ }
182
+ console.log(c.green(`✓ mesh "${m.space}" up at ${server}`) + c.dim(` (broker pid ${pid})`));
183
+ console.log(c.dim(` seeded ${m.channels.length} channel(s): ${m.channels.map((ch) => "#" + ch.name).join(", ")}`));
184
+ // 2) write the resolved launch spec + boot agents through a manager (it materializes each transient
185
+ // persona and mints creds from the resolved policy — never re-reading a file for authority).
186
+ const specPath = writeLaunchSpec(cotalRoot(), buildLaunchSpec(eff, genRunId()));
187
+ startManagerDetached({ space: m.space, server, runtime, launch: specPath });
188
+ console.log(c.green(`✓ launching ${eff.agents.length} agent(s)`) + c.dim(` via manager (${runtime}) — see .cotal/manager.log`));
189
+ // Loud summary: any persona-inherited access an `include` manifest dragged in, plus warnings.
190
+ const inherited = renderInherited(eff);
191
+ if (inherited)
192
+ console.log("\n" + inherited);
193
+ if (eff.warnings.length)
194
+ console.log("\n" + renderWarnings(eff.warnings));
195
+ console.log(c.dim(`\nWatch: \`cotal console --space ${m.space}\` or \`cotal web\` · Tear down: \`cotal down\``));
196
+ }
197
+ /** Return a copy of the prepared manifest with CLI overrides applied to broker/space/runtime, so the
198
+ * whole launch (render, seed, broker, manager, launch spec) runs against one effective manifest. */
199
+ function applyUpOverrides(prepared, o) {
200
+ const m = prepared.manifest;
201
+ const broker = { ...m.broker };
202
+ if (o.server)
203
+ broker.servers = o.server;
204
+ if (o.host)
205
+ broker.host = o.host;
206
+ if (o.open)
207
+ broker.auth = false;
208
+ return {
209
+ ...prepared,
210
+ manifest: {
211
+ ...m,
212
+ broker: Object.keys(broker).length ? broker : undefined,
213
+ space: o.space ?? m.space,
214
+ runtime: o.runtime ?? m.runtime,
215
+ },
216
+ };
217
+ }
74
218
  /** Start the server-side delivery daemon alongside the broker (auth mode only): old-manager preflight
75
219
  * first (so an old hosting manager can't double-bind), then the auth-gated daemon (a no-op in open
76
220
  * mode). Coupled to the broker by the daemon's own broker-gone watchdog + the `up`/`down` teardown. */
@@ -96,7 +240,9 @@ export async function startMeshDetached(opts = {}) {
96
240
  mkdirSync(storeDir, { recursive: true });
97
241
  const useAuth = !opts.open;
98
242
  const space = opts.space ?? resolveSpace(process.cwd());
99
- const seedFile = loadChannelsFile(opts.channels);
243
+ assertAuthMatchesSpace(useAuth, space);
244
+ await claimSpace(space, server, cotalRoot());
245
+ const seedFile = opts.seed ?? loadChannelsFile(opts.channels);
100
246
  const host = opts.host ?? "127.0.0.1";
101
247
  const setup = useAuth ? await authSetup(storeDir, server, space, host) : undefined;
102
248
  const port = Number(new URL(server).port) || 4222;
@@ -121,8 +267,54 @@ export async function startMeshDetached(opts = {}) {
121
267
  await postStart(server, space, setup, seedFile);
122
268
  // Bring up the delivery daemon WITH the detached broker (auth mode only; `cotal down` tears both down).
123
269
  await startDeliveryWithBroker(space, server);
270
+ // Detached: the registry entry outlives this process — `cotal down` removes it.
271
+ recordOurMesh({ space, server, root: cotalRoot(), mode: useAuth ? "auth" : "open", ts: new Date().toISOString() });
124
272
  return { server, pid: child.pid ?? 0, source };
125
273
  }
274
+ /** Today a root's `.cotal/auth` is created for one space (its account is space-bound), so starting it
275
+ * under a *different* explicit `--space` would run that space's name against the other space's trust
276
+ * material — the registry would then point a `spawn --space` at mismatched creds. Reject it. (When
277
+ * multi-space-per-root lands, this becomes provision-the-new-space instead of an error.) */
278
+ function assertAuthMatchesSpace(useAuth, space) {
279
+ if (!useAuth)
280
+ return;
281
+ const existing = loadSpaceAuth(authDir(cotalRoot()));
282
+ if (existing && existing.space !== space) {
283
+ console.error(c.red(`✗ this root's trust material is for space "${existing.space}", not "${space}" — drop \`--space\` (it defaults to "${existing.space}"), or run "${space}" from its own root`));
284
+ process.exit(1);
285
+ }
286
+ }
287
+ /** A space name maps to one mesh in the registry (the key `--space`/`use`/`down` act on). Before
288
+ * starting a broker, refuse to reuse a space already claimed by a DIFFERENT live mesh — a stale/dead
289
+ * holder is reclaimed. Re-`up`ping the same mesh (same server + root) is a refresh (port-reachable
290
+ * path). NOTE: this is a best-effort sequential guard — two `cotal up --space X` racing from
291
+ * different roots within the same instant can both pass the check before either records; that
292
+ * concurrent case is out of scope (a single-operator CLI action), not synchronized with a lock. */
293
+ async function claimSpace(space, server, root) {
294
+ const existing = findMesh(space);
295
+ if (!existing || (existing.server === server && existing.root === root))
296
+ return;
297
+ if (await isReachable(existing.server)) {
298
+ console.error(c.red(`✗ space "${space}" is already in use by a mesh at ${existing.server} (${existing.root}) — pick a different \`--space\`, or \`cotal down\` it first`));
299
+ process.exit(1);
300
+ }
301
+ removeMesh(space); // the prior holder's broker is gone — reclaim the name
302
+ }
303
+ /** Record this mesh in the registry, and set it as the `current` default when there's no usable one
304
+ * — i.e. the first mesh, OR when `current` dangles at a space that's no longer in the registry (a
305
+ * ghost pointer is not a default). Never silently redirect a `current` that still resolves to a live
306
+ * mesh; just say another is the default and how to switch. */
307
+ function recordOurMesh(m) {
308
+ const cur = getCurrent();
309
+ const usableCurrent = cur && findMesh(cur) ? cur : undefined; // compute before recording m
310
+ recordMesh(m);
311
+ if (!usableCurrent) {
312
+ setCurrent(m.space);
313
+ return;
314
+ }
315
+ if (usableCurrent !== m.space)
316
+ console.log(c.dim(`"${m.space}" up; current is still "${usableCurrent}" — \`cotal use ${m.space}\` to switch`));
317
+ }
126
318
  /** Poll a growing log file and forward newly-appended lines until `stopped()` is true. */
127
319
  function tailLines(path, from, onLine, stopped) {
128
320
  let offset = from;
@@ -191,7 +383,8 @@ async function authSetup(storeDir, server, space, host = "127.0.0.1") {
191
383
  let auth = loadSpaceAuth(dir);
192
384
  if (!auth) {
193
385
  auth = await createSpaceAuth(space);
194
- saveSpaceAuth(dir, auth);
386
+ saveSpaceAuth(dir, auth); // strips the $SYS seed on disk, but leaves the in-memory `auth` intact …
387
+ await provisionMembershipCreds(auth); // … so the observer can still be minted here (fresh-space only)
195
388
  }
196
389
  const port = Number(new URL(server).port) || 4222;
197
390
  const confPath = resolve(dir, "server.conf");
@@ -199,4 +392,28 @@ async function authSetup(storeDir, server, space, host = "127.0.0.1") {
199
392
  const creds = await mintCreds(auth, newIdentity(), "manager"); // privileged, ephemeral
200
393
  return { confPath, creds };
201
394
  }
395
+ /** Mint the two scoped creds the delivery daemon's membership feed loads (broker-sourced graph
396
+ * membership), at the FRESH `cotal up` while the in-memory `$SYS` signing seed still exists:
397
+ * - `membership-observer.creds` — SYSTEM-account CONNZ reader (the only window it can be minted: the
398
+ * `$SYS` seed is never persisted).
399
+ * - `membership-rw.creds` — DATA-account members-read + feed-write.
400
+ * - `membership.json` — the DATA account id (the CONNZ/event subjects pin it; non-secret, but kept
401
+ * 0600 alongside the creds).
402
+ * All 0600. Best-effort: a failure logs and leaves the feed disabled (the graph degrades to traffic-
403
+ * only, delivery is untouched). Runs only on a FRESH space (the `if (!auth)` branch); a normal down/up
404
+ * keeps `.cotal/auth` + these creds and reuses them. A space provisioned before this feature has no
405
+ * in-memory `$SYS` seed, so it gains membership only when its auth is regenerated (a fresh `.cotal/auth`)
406
+ * — a documented migration property, not a silent no-op. */
407
+ async function provisionMembershipCreds(auth) {
408
+ try {
409
+ const observer = await mintMembershipObserverCreds(auth, newIdentity());
410
+ const rw = await mintCreds(auth, newIdentity(), "membership-rw");
411
+ writeFileSync(cotalPath("membership-observer.creds"), observer, { mode: 0o600 });
412
+ writeFileSync(cotalPath("membership-rw.creds"), rw, { mode: 0o600 });
413
+ writeFileSync(cotalPath("membership.json"), JSON.stringify({ accountId: auth.account.pub }), { mode: 0o600 });
414
+ }
415
+ catch (e) {
416
+ console.error(c.dim(`• broker-sourced membership not provisioned: ${e.message}`));
417
+ }
418
+ }
202
419
  //# sourceMappingURL=up.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"up.js","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"up.js","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CompletionResult } from "@cotal-ai/core";
2
+ /** `cotal use <space>` — set the default mesh a bare `cotal spawn` (and friends) targets when more
3
+ * than one is running. The kubectl `use-context` analogue. Validated against the live registry, so
4
+ * you can't point `current` at a mesh that isn't up. */
5
+ export declare function use(argv: string[]): Promise<void>;
6
+ export declare function useComplete(argv: string[]): CompletionResult;
7
+ //# sourceMappingURL=use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.d.ts","sourceRoot":"","sources":["../../src/commands/use.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKvD;;yDAEyD;AACzD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAI5D"}
@@ -0,0 +1,27 @@
1
+ import { findMesh, loadMeshes, setCurrent } from "@cotal-ai/workspace";
2
+ import { c } from "../ui.js";
3
+ import { pruneStaleMeshes } from "../lib/meshes.js";
4
+ /** `cotal use <space>` — set the default mesh a bare `cotal spawn` (and friends) targets when more
5
+ * than one is running. The kubectl `use-context` analogue. Validated against the live registry, so
6
+ * you can't point `current` at a mesh that isn't up. */
7
+ export async function use(argv) {
8
+ const space = argv[0];
9
+ if (!space) {
10
+ console.error(c.red("usage: cotal use <space>"));
11
+ process.exit(1);
12
+ }
13
+ await pruneStaleMeshes();
14
+ const m = findMesh(space);
15
+ if (!m) {
16
+ console.error(c.red(`✗ no mesh named "${space}" is running — see \`cotal meshes\``));
17
+ process.exit(1);
18
+ }
19
+ setCurrent(space);
20
+ console.log(c.green(`✓ current mesh → ${space}`), c.dim(`(${m.server})`));
21
+ }
22
+ export function useComplete(argv) {
23
+ if (argv.length <= 1)
24
+ return { items: loadMeshes().map((m) => ({ value: m.space })), directive: "nofiles" };
25
+ return { items: [], directive: "nofiles" };
26
+ }
27
+ //# sourceMappingURL=use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.js","sourceRoot":"","sources":["../../src/commands/use.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;yDAEyD;AACzD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,gBAAgB,EAAE,CAAC;IACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,oBAAoB,KAAK,qCAAqC,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,UAAU,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IACxF,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AA2BA;;;+DAG+D;AAC/D,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,OAAO,iCAAwC,CAAC;AAO7D;;0EAE0E;AAC1E,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgLvD;AAOD,+EAA+E;AAC/E,wBAAgB,KAAK,CAAC,IAAI,GAAE,MAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAY/D;AAED;;wFAEwF;AACxF,wBAAgB,gBAAgB,CAAC,CAAC,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAkB1G;AAED;gGACgG;AAChG,wBAAsB,SAAS,CAAC,CAAC,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAKvH"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAwBA;;;+DAG+D;AAC/D,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,OAAO,iCAAwC,CAAC;AAS7D;;0EAE0E;AAC1E,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6LvD;AAgBD,+EAA+E;AAC/E,wBAAgB,KAAK,CAAC,IAAI,GAAE,MAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAY/D;AAED;;wFAEwF;AACxF,wBAAgB,gBAAgB,CAAC,CAAC,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAkB1G;AAED;gGACgG;AAChG,wBAAsB,SAAS,CAAC,CAAC,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAKvH"}
@@ -5,9 +5,10 @@ import { connect } from "node:net";
5
5
  import { readFileSync, writeFileSync, openSync, closeSync } from "node:fs";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { dirname, join } from "node:path";
8
- import { CotalEndpoint, isReachable, DEFAULT_SERVER, deliveryOf, parseSubject, spaceWildcard, authDir, loadSpaceAuth, mintCreds, newIdentity, clearChannel, } from "@cotal-ai/core";
8
+ import { CotalEndpoint, deliveryOf, parseSubject, spaceWildcard, mintCreds, newIdentity, clearChannel, } from "@cotal-ai/core";
9
+ import { cotalPath } from "../lib/paths.js";
9
10
  import { resolveSpace } from "../lib/status.js";
10
- import { cotalPath, cotalRoot } from "../lib/paths.js";
11
+ import { connectOrExit } from "../lib/connect.js";
11
12
  import { c } from "../ui.js";
12
13
  import { selfArgv } from "../lib/self-exec.js";
13
14
  const here = dirname(fileURLToPath(import.meta.url));
@@ -20,6 +21,8 @@ export const WEB_URL = `http://cotal.localhost:${WEB_PORT}/`;
20
21
  const PAGE = {
21
22
  "/": { path: join(here, "../web/index.html"), type: "text/html; charset=utf-8" },
22
23
  "/app.js": { path: join(here, "../web/app.js"), type: "text/javascript; charset=utf-8" },
24
+ "/graph": { path: join(here, "../web/graph.html"), type: "text/html; charset=utf-8" },
25
+ "/graph.js": { path: join(here, "../web/graph.js"), type: "text/javascript; charset=utf-8" },
23
26
  };
24
27
  /** A live observability dashboard for a space, served over HTTP + SSE. A read-only
25
28
  * observer endpoint (invisible to peers) feeds the page presence, channel history,
@@ -36,28 +39,18 @@ export async function web(argv) {
36
39
  creds: { type: "string" },
37
40
  },
38
41
  });
39
- const space = values.space ?? resolveSpace(process.cwd());
40
- const server = values.server ?? DEFAULT_SERVER;
42
+ // Resolve WHICH running mesh + creds (admin god-view: shows DMs + anycast), then DROP the account
43
+ // seed. The dashboard is a loopback HTTP process; holding the space signing seed (`auth` — it can
44
+ // mint ANY identity/role) for the whole session would make a dashboard compromise = full account
45
+ // control. Instead pre-mint ONE scoped `manager` cred for the only write path (channel delete) and
46
+ // let the seed fall out of scope here, so it isn't reachable from the request handlers. `--creds`
47
+ // / open mode have no seed → the connection creds carry the purge rights.
48
+ const { server, space, creds, purgeCreds } = await (async () => {
49
+ const conn = await connectOrExit(values, "admin");
50
+ const purge = conn.auth ? await mintCreds(conn.auth, newIdentity(), "manager") : conn.creds;
51
+ return { server: conn.server, space: conn.space, creds: conn.creds, purgeCreds: purge };
52
+ })();
41
53
  const port = values.port ? Number(values.port) : WEB_PORT;
42
- // The dashboard is always an admin god-view (no read-only viewer mode) so it can show DMs
43
- // and anycast. Auth mode (`.cotal/auth` present): self-mint an `admin` cred so it joins the
44
- // authed mesh with no manual --creds — like `cotal spawn`, it holds the space signing key.
45
- // An explicit --creds still wins. Open mode (no auth): connect bare.
46
- // Loaded once at function scope: the observer connects with a read-only `admin` cred, but
47
- // the channel-delete write path mints an ephemeral `manager` cred from this same material.
48
- const auth = loadSpaceAuth(authDir(cotalRoot()));
49
- let creds = values.creds ? readFileSync(values.creds, "utf8") : undefined;
50
- if (!creds && auth) {
51
- if (auth.space !== space) {
52
- console.error(c.red(`Auth here is for space "${auth.space}", not "${space}". Use --space ${auth.space} (or pass --creds).`));
53
- process.exit(1);
54
- }
55
- creds = await mintCreds(auth, newIdentity(), "admin");
56
- }
57
- if (!(await isReachable(server, { creds }))) {
58
- console.error(c.red(`Can't reach NATS at ${server}. Run: pnpm cotal up`));
59
- process.exit(1);
60
- }
61
54
  // Observer: never registers presence, never consumes an inbox — invisible to peers.
62
55
  const ep = new CotalEndpoint({
63
56
  space,
@@ -80,6 +73,20 @@ export async function web(argv) {
80
73
  };
81
74
  // Presence changes → push the whole roster; the client just re-renders it.
82
75
  ep.on("presence", () => broadcast("roster", ep.getRoster()));
76
+ // Broker-sourced channel membership (the authoritative graph spokes): push a `membership` SSE event
77
+ // on every feed change (debounced; the client re-reads the snapshot). Best-effort — a space without the
78
+ // feed (no delivery daemon, or provisioned before this feature) simply never emits, and the graph
79
+ // degrades to traffic-only. The admin cred carries the read grant; agents never do.
80
+ let membershipWatch;
81
+ const pushMembership = debounce(() => {
82
+ void ep.readMembership().then((m) => broadcast("membership", m)).catch(() => { });
83
+ }, 150);
84
+ try {
85
+ membershipWatch = await ep.watchMembership(pushMembership);
86
+ }
87
+ catch (e) {
88
+ console.error(c.dim(`• membership feed unavailable — graph shows traffic only (${e.message})`));
89
+ }
83
90
  // Every comm on the mesh (chat / unicast / anycast) → push to the live feed. The admin cred
84
91
  // allows the whole space, so the observer taps everything — DMs + anycast included.
85
92
  const tapSubject = spaceWildcard(space);
@@ -103,6 +110,10 @@ export async function web(argv) {
103
110
  });
104
111
  clients.add(res);
105
112
  send(res, "roster", ep.getRoster());
113
+ // Seed this client's graph with the current membership snapshot (the live tap only carries
114
+ // post-connect traffic; membership is state, so a fresh client needs it explicitly).
115
+ void ep.readMembership().then((m) => { if (!res.writableEnded)
116
+ send(res, "membership", m); }).catch(() => { });
106
117
  req.on("close", () => clients.delete(res));
107
118
  return;
108
119
  }
@@ -110,6 +121,16 @@ export async function web(argv) {
110
121
  return json(res, { space });
111
122
  if (path === "/api/roster")
112
123
  return json(res, ep.getRoster());
124
+ if (path === "/api/membership") {
125
+ // Authoritative who-is-subscribed (broker-sourced); {asOf, members:[{id,live,durable,observedAt}]}.
126
+ // An unavailable feed returns an empty snapshot so the graph cleanly degrades to traffic-only.
127
+ try {
128
+ return json(res, await ep.readMembership());
129
+ }
130
+ catch {
131
+ return json(res, { asOf: undefined, members: [] });
132
+ }
133
+ }
113
134
  if (path === "/api/channels")
114
135
  return json(res, await ep.listChannels());
115
136
  if (path === "/api/activity") {
@@ -136,9 +157,9 @@ export async function web(argv) {
136
157
  return json(res, await ep.channelHistory(name, { limit }));
137
158
  }
138
159
  // Delete a channel and its content. The only write path on this otherwise read-only
139
- // dashboard, so it's POST-gated and guarded by a confirm in the UI. The observer's admin
140
- // cred can't purge; mint an ephemeral manager cred (auth mode) for the op, else connect
141
- // bare (open mode has full rights). A wildcard / missing channel is a 400.
160
+ // dashboard, so it's POST-gated and guarded by a confirm in the UI. Uses the manager cred
161
+ // pre-minted at startup (auth mode) or the connection creds (open / --creds), NOT the account
162
+ // seed (which we dropped). A wildcard / missing channel is a 400.
142
163
  if (path === "/api/channel/delete" && req.method === "POST") {
143
164
  const body = await readBody(req).catch(() => ({}));
144
165
  const channel = typeof body.channel === "string" ? body.channel : "";
@@ -148,7 +169,6 @@ export async function web(argv) {
148
169
  return;
149
170
  }
150
171
  try {
151
- const purgeCreds = auth ? await mintCreds(auth, newIdentity(), "manager") : creds;
152
172
  const result = await clearChannel({ servers: server, space, channel, creds: purgeCreds });
153
173
  return json(res, { ok: true, ...result });
154
174
  }
@@ -160,7 +180,9 @@ export async function web(argv) {
160
180
  }
161
181
  const file = PAGE[path];
162
182
  if (file) {
163
- res.writeHead(200, { "content-type": file.type });
183
+ // no-cache: always revalidate so a `cotal` upgrade's new dashboard code is picked up on
184
+ // reload — a stale cached graph.js silently runs old behavior (e.g. pre-fix filters).
185
+ res.writeHead(200, { "content-type": file.type, "cache-control": "no-cache" });
164
186
  res.end(readFileSync(file.path));
165
187
  return;
166
188
  }
@@ -189,6 +211,7 @@ export async function web(argv) {
189
211
  openBrowser(url);
190
212
  const shutdown = async () => {
191
213
  clearInterval(ping);
214
+ membershipWatch?.stop();
192
215
  for (const res of clients)
193
216
  res.end();
194
217
  httpServer.close();
@@ -203,6 +226,15 @@ function json(res, data) {
203
226
  res.writeHead(200, { "content-type": "application/json" });
204
227
  res.end(JSON.stringify(data));
205
228
  }
229
+ /** Trailing-edge debounce — coalesces a burst of membership-feed deltas into one push. */
230
+ function debounce(fn, ms) {
231
+ let t;
232
+ return () => {
233
+ if (t)
234
+ clearTimeout(t);
235
+ t = setTimeout(fn, ms);
236
+ };
237
+ }
206
238
  /** True if something is already listening on the dashboard port (loopback). */
207
239
  export function webUp(port = WEB_PORT) {
208
240
  return new Promise((res) => {