@cotal-ai/cli 0.10.1 → 0.11.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 (145) hide show
  1. package/dist/command.d.ts.map +1 -1
  2. package/dist/command.js +17 -4
  3. package/dist/command.js.map +1 -1
  4. package/dist/commands/agents.d.ts.map +1 -1
  5. package/dist/commands/agents.js +30 -13
  6. package/dist/commands/agents.js.map +1 -1
  7. package/dist/commands/channels.d.ts.map +1 -1
  8. package/dist/commands/channels.js +16 -6
  9. package/dist/commands/channels.js.map +1 -1
  10. package/dist/commands/clean.d.ts +40 -0
  11. package/dist/commands/clean.d.ts.map +1 -0
  12. package/dist/commands/clean.js +138 -0
  13. package/dist/commands/clean.js.map +1 -0
  14. package/dist/commands/completion.js +5 -5
  15. package/dist/commands/console.d.ts +1 -1
  16. package/dist/commands/console.d.ts.map +1 -1
  17. package/dist/commands/console.js +17 -11
  18. package/dist/commands/console.js.map +1 -1
  19. package/dist/commands/doctor.d.ts +14 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +171 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/down-manifest.js +15 -15
  24. package/dist/commands/down.d.ts +16 -0
  25. package/dist/commands/down.d.ts.map +1 -1
  26. package/dist/commands/down.js +83 -32
  27. package/dist/commands/down.js.map +1 -1
  28. package/dist/commands/ext.d.ts.map +1 -1
  29. package/dist/commands/ext.js +30 -17
  30. package/dist/commands/ext.js.map +1 -1
  31. package/dist/commands/feedback.js +2 -2
  32. package/dist/commands/history.d.ts +3 -2
  33. package/dist/commands/history.d.ts.map +1 -1
  34. package/dist/commands/history.js +6 -17
  35. package/dist/commands/history.js.map +1 -1
  36. package/dist/commands/join.d.ts.map +1 -1
  37. package/dist/commands/join.js +14 -7
  38. package/dist/commands/join.js.map +1 -1
  39. package/dist/commands/meshes.js +2 -2
  40. package/dist/commands/mint.d.ts.map +1 -1
  41. package/dist/commands/mint.js +16 -5
  42. package/dist/commands/mint.js.map +1 -1
  43. package/dist/commands/models.js +1 -1
  44. package/dist/commands/models.js.map +1 -1
  45. package/dist/commands/personas.js +4 -4
  46. package/dist/commands/send.js +1 -1
  47. package/dist/commands/setup.js +27 -27
  48. package/dist/commands/setup.js.map +1 -1
  49. package/dist/commands/spawn-manifest.d.ts.map +1 -1
  50. package/dist/commands/spawn-manifest.js +47 -25
  51. package/dist/commands/spawn-manifest.js.map +1 -1
  52. package/dist/commands/spawn.d.ts +6 -0
  53. package/dist/commands/spawn.d.ts.map +1 -1
  54. package/dist/commands/spawn.js +257 -46
  55. package/dist/commands/spawn.js.map +1 -1
  56. package/dist/commands/status.d.ts.map +1 -1
  57. package/dist/commands/status.js +85 -22
  58. package/dist/commands/status.js.map +1 -1
  59. package/dist/commands/topology.js +2 -2
  60. package/dist/commands/up.d.ts +5 -0
  61. package/dist/commands/up.d.ts.map +1 -1
  62. package/dist/commands/up.js +272 -49
  63. package/dist/commands/up.js.map +1 -1
  64. package/dist/commands/use.js +1 -1
  65. package/dist/console/commands.js +2 -2
  66. package/dist/console/mesh.js +1 -1
  67. package/dist/console/mesh.js.map +1 -1
  68. package/dist/console/root.d.ts +15 -3
  69. package/dist/console/root.d.ts.map +1 -1
  70. package/dist/console/root.js +12 -7
  71. package/dist/console/root.js.map +1 -1
  72. package/dist/console/ui/Confirm.js +1 -1
  73. package/dist/console/ui/Confirm.js.map +1 -1
  74. package/dist/console/ui/Feed.js +1 -1
  75. package/dist/console/ui/Feed.js.map +1 -1
  76. package/dist/console/ui/Help.js +2 -2
  77. package/dist/console/ui/Help.js.map +1 -1
  78. package/dist/console/ui/NeedsYou.js +1 -1
  79. package/dist/console/ui/NeedsYou.js.map +1 -1
  80. package/dist/console/ui/SpacePicker.js +1 -1
  81. package/dist/console/ui/SpacePicker.js.map +1 -1
  82. package/dist/console/ui/Tiles.js +1 -1
  83. package/dist/console/ui/topo/Map.js +1 -1
  84. package/dist/console/ui/topo/Map.js.map +1 -1
  85. package/dist/console/ui/topo/Matrix.js +2 -2
  86. package/dist/console/ui/topo/Matrix.js.map +1 -1
  87. package/dist/console/ui/topo/Sequence.js +1 -1
  88. package/dist/console/ui/topo/Sequence.js.map +1 -1
  89. package/dist/ext-loader.d.ts.map +1 -1
  90. package/dist/ext-loader.js +20 -8
  91. package/dist/ext-loader.js.map +1 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +47 -18
  94. package/dist/index.js.map +1 -1
  95. package/dist/lib/attach-client.js +1 -1
  96. package/dist/lib/auth-proc.d.ts +19 -0
  97. package/dist/lib/auth-proc.d.ts.map +1 -0
  98. package/dist/lib/auth-proc.js +81 -0
  99. package/dist/lib/auth-proc.js.map +1 -0
  100. package/dist/lib/connect.d.ts +1 -1
  101. package/dist/lib/connect.d.ts.map +1 -1
  102. package/dist/lib/connect.js +2 -2
  103. package/dist/lib/connect.js.map +1 -1
  104. package/dist/lib/control.d.ts +14 -6
  105. package/dist/lib/control.d.ts.map +1 -1
  106. package/dist/lib/control.js +31 -13
  107. package/dist/lib/control.js.map +1 -1
  108. package/dist/lib/delivery-proc.js +2 -2
  109. package/dist/lib/manifest/apply.d.ts +3 -2
  110. package/dist/lib/manifest/apply.d.ts.map +1 -1
  111. package/dist/lib/manifest/apply.js +7 -2
  112. package/dist/lib/manifest/apply.js.map +1 -1
  113. package/dist/lib/manifest/ledger.js +4 -4
  114. package/dist/lib/manifest/live.d.ts +23 -9
  115. package/dist/lib/manifest/live.d.ts.map +1 -1
  116. package/dist/lib/manifest/live.js +22 -12
  117. package/dist/lib/manifest/live.js.map +1 -1
  118. package/dist/lib/manifest/model.d.ts +4 -1
  119. package/dist/lib/manifest/model.d.ts.map +1 -1
  120. package/dist/lib/manifest/prepare.d.ts +2 -0
  121. package/dist/lib/manifest/prepare.d.ts.map +1 -1
  122. package/dist/lib/manifest/prepare.js +5 -2
  123. package/dist/lib/manifest/prepare.js.map +1 -1
  124. package/dist/lib/manifest/render.d.ts.map +1 -1
  125. package/dist/lib/manifest/render.js +14 -13
  126. package/dist/lib/manifest/render.js.map +1 -1
  127. package/dist/lib/manifest/resolve.js +19 -6
  128. package/dist/lib/manifest/resolve.js.map +1 -1
  129. package/dist/lib/manifest/schema.d.ts +4 -1
  130. package/dist/lib/manifest/schema.d.ts.map +1 -1
  131. package/dist/lib/manifest/schema.js +10 -2
  132. package/dist/lib/manifest/schema.js.map +1 -1
  133. package/dist/lib/setup-log.js +1 -1
  134. package/dist/lib/status.d.ts +1 -1
  135. package/dist/lib/status.js +1 -1
  136. package/dist/lib/transient.d.ts +8 -10
  137. package/dist/lib/transient.d.ts.map +1 -1
  138. package/dist/lib/transient.js +11 -11
  139. package/dist/lib/transient.js.map +1 -1
  140. package/dist/render.js +2 -2
  141. package/dist/ui.d.ts +5 -0
  142. package/dist/ui.d.ts.map +1 -1
  143. package/dist/ui.js +13 -1
  144. package/dist/ui.js.map +1 -1
  145. package/package.json +3 -3
@@ -0,0 +1,14 @@
1
+ import { type ParsedArgs } from "@cotal-ai/core";
2
+ export declare const doctorFlags: readonly [{
3
+ readonly name: "fix";
4
+ readonly type: "boolean";
5
+ readonly description: "execute the safe repairs (re-sign the manager-remintable daemon creds; needs the local signer)";
6
+ }];
7
+ /** `cotal doctor auth` — the ONE stale-credential repair surface (D5 slice 6). Read-only diagnosis
8
+ * of every managed credential file in this folder against the credential-lifetime matrix, rendered
9
+ * as healthy / near-expiry (yellow) / expired / unreadable (red) with the LAST-RENEWAL timestamp
10
+ * for manager-reminted creds — ending in either `healthy` or the exact next command (exit 1).
11
+ * `--fix` executes the one safe local repair (re-sign the class-2 daemon files for their existing
12
+ * nkeys); $SYS and agent creds are never auto-fixed — their repairs are printed, not guessed. */
13
+ export declare function doctor(args: ParsedArgs): Promise<void>;
14
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAaxB,eAAO,MAAM,WAAW;;;;EAEd,CAAC;AAaX;;;;;kGAKkG;AAClG,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD5D"}
@@ -0,0 +1,171 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { basename, join } from "node:path";
3
+ import { credentialLifetime, inspectCredHealth, } from "@cotal-ai/core";
4
+ import { authDir, findCotalRoot, loadSpaceAuth, readRenewalRecord, remintDaemonCreds, userAuthStateDir, writeRenewalRecord, } from "@cotal-ai/workspace";
5
+ import { displayCmd } from "../lib/self-exec.js";
6
+ import { c } from "../ui.js";
7
+ export const doctorFlags = [
8
+ { name: "fix", type: "boolean", description: "execute the safe repairs (re-sign the manager-remintable daemon creds; needs the local signer)" },
9
+ ];
10
+ /** `cotal doctor auth` — the ONE stale-credential repair surface (D5 slice 6). Read-only diagnosis
11
+ * of every managed credential file in this folder against the credential-lifetime matrix, rendered
12
+ * as healthy / near-expiry (yellow) / expired / unreadable (red) with the LAST-RENEWAL timestamp
13
+ * for manager-reminted creds — ending in either `healthy` or the exact next command (exit 1).
14
+ * `--fix` executes the one safe local repair (re-sign the class-2 daemon files for their existing
15
+ * nkeys); $SYS and agent creds are never auto-fixed — their repairs are printed, not guessed. */
16
+ export async function doctor(args) {
17
+ const sub = args.positionals[0];
18
+ if (sub !== "auth") {
19
+ console.error(`usage: ${displayCmd()} doctor auth [--fix] - credential-health diagnosis + repair for this folder's mesh`);
20
+ process.exitCode = 1;
21
+ return;
22
+ }
23
+ const values = args.values;
24
+ const root = findCotalRoot(process.cwd());
25
+ const auth = loadSpaceAuth(authDir(root));
26
+ console.log(c.bold("cotal doctor auth"));
27
+ console.log(` root ${root}`);
28
+ if (!auth) {
29
+ // An open mesh has no minted credentials at all — nothing to diagnose is a healthy answer,
30
+ // not a silent one.
31
+ console.log(c.green("\nauth: healthy - open mesh (no credential material in this folder)"));
32
+ return;
33
+ }
34
+ const userMode = existsSync(userAuthStateDir(root, auth.space));
35
+ console.log(` space ${auth.space}${userMode ? " · user-auth" : ""} · signer ${c.green("present")} (${join(authDir(root), "auth.json")})`);
36
+ let reports = inventory(root);
37
+ let problems = reports.filter((r) => r.problem);
38
+ // --fix: the one safe local repair — re-sign the remintable daemon files (same nkeys), exactly
39
+ // what the manager's renewal pass does, and record the pass so the audit trail stays honest
40
+ // (adoption is the DAEMON's explicit reload, which only the running manager requests — a doctor
41
+ // fix without a live manager is adopted by the daemon's 75% re-read backstop). Then re-diagnose:
42
+ // the doctor reports what IS, never what it hopes the fix did.
43
+ if (values.fix && problems.some((r) => isRemintable(r.kind))) {
44
+ console.log(c.dim("\n--fix: re-signing the remintable daemon creds…"));
45
+ const results = await remintDaemonCreds(root);
46
+ writeRenewalRecord(root, { ts: new Date().toISOString(), owner: "doctor --fix", results });
47
+ for (const r of results.filter((x) => !x.ok && !x.skipped))
48
+ console.error(c.red(` ✗ ${r.file}: ${r.error}`));
49
+ reports = inventory(root);
50
+ problems = reports.filter((r) => r.problem);
51
+ }
52
+ render("Daemon creds (manager-reminted - class 2)", reports.filter((r) => isRemintable(r.kind)));
53
+ renderRenewalRecord(root);
54
+ render("$SYS creds (rotation-renewed - never remintable from disk)", reports.filter((r) => r.kind === "membership-observer" || r.kind === "connection-evictor"));
55
+ render("Agent creds (static, pre-flip)", reports.filter((r) => r.kind === "agent"));
56
+ if (!problems.length) {
57
+ console.log(c.green("\nauth: healthy"));
58
+ return;
59
+ }
60
+ console.log(c.red(`\nauth: ${problems.length} problem${problems.length === 1 ? "" : "s"}`));
61
+ for (const p of problems)
62
+ console.log(` ${c.red("✗")} ${p.label}: ${p.problem}\n next: ${p.repair}`);
63
+ process.exitCode = 1;
64
+ }
65
+ function isRemintable(kind) {
66
+ return kind === "delivery" || kind === "membership-rw";
67
+ }
68
+ /** Inspect every managed credential file for this folder. Missing files are noted (with how they
69
+ * get provisioned) but only EXISTING-but-bad material is a problem — process presence is `cotal
70
+ * status`'s job; this surface owns credential health. */
71
+ function inventory(root) {
72
+ const cotal = (f) => join(root, ".cotal", f);
73
+ const fixed = [
74
+ { label: "delivery.creds", kind: "delivery", path: cotal("delivery.creds") },
75
+ { label: "membership-rw.creds", kind: "membership-rw", path: cotal("membership-rw.creds") },
76
+ { label: "membership-observer.creds", kind: "membership-observer", path: cotal("membership-observer.creds") },
77
+ { label: "connection-evictor.creds", kind: "connection-evictor", path: cotal("connection-evictor.creds") },
78
+ ];
79
+ const reports = fixed.map((f) => report(f.label, f.kind, f.path));
80
+ const agentDir = join(authDir(root), "creds");
81
+ if (existsSync(agentDir)) {
82
+ for (const f of readdirSync(agentDir).filter((f) => f.endsWith(".creds") && !f.endsWith(".sentinel.creds")).sort()) {
83
+ reports.push(report(basename(f), "agent", join(agentDir, f)));
84
+ }
85
+ }
86
+ return reports;
87
+ }
88
+ function report(label, kind, path) {
89
+ if (!existsSync(path))
90
+ return { label, kind, path };
91
+ const health = inspectCredHealth(readFileSync(path, "utf8"));
92
+ const r = { label, kind, path, health };
93
+ const policy = credentialLifetime(kind);
94
+ const standing = policy.class === "standing-renewable" || policy.class === "rotation-renewed";
95
+ const repair = isRemintable(kind)
96
+ ? `${displayCmd()} doctor auth --fix (or start the mesh's manager - it is the renewal owner and re-signs + reloads these every half-TTL)`
97
+ : kind === "agent"
98
+ ? `respawn the agent (\`${displayCmd()} spawn\`) - its old cred is dead by design`
99
+ : `system-account rotation: \`${displayCmd()} down\` then a fresh \`${displayCmd()} up\` regenerates the $SYS material`;
100
+ switch (health.state) {
101
+ case "unreadable":
102
+ r.problem = `unreadable credential file (${health.error})`;
103
+ r.repair = repair;
104
+ break;
105
+ case "expired":
106
+ r.problem = "EXPIRED - the broker denies this credential";
107
+ r.repair = repair;
108
+ break;
109
+ case "near-expiry":
110
+ if (standing) {
111
+ r.problem = `past its renewal point (renewal owner: ${policy.renewalOwner}) - expires ${at(health.exp)}`;
112
+ r.repair = repair;
113
+ }
114
+ break;
115
+ case "unbounded":
116
+ if (standing) {
117
+ r.problem = "unbounded standing credential (minted before the renewal slice) - a copied cred never dies";
118
+ r.repair = repair;
119
+ }
120
+ break;
121
+ }
122
+ return r;
123
+ }
124
+ function render(title, reports) {
125
+ console.log(`\n ${c.bold(title)}`);
126
+ if (!reports.length) {
127
+ console.log(c.dim(" none"));
128
+ return;
129
+ }
130
+ for (const r of reports) {
131
+ if (!r.health) {
132
+ console.log(` ${c.dim("−")} ${r.label} ${c.dim(`not provisioned here (written by \`${displayCmd()} up\`)`)}`);
133
+ continue;
134
+ }
135
+ const h = r.health;
136
+ const lastRenewal = h.iat ? c.dim(` · last renewal ${at(h.iat)}`) : "";
137
+ const expiry = h.exp ? c.dim(` · expires ${at(h.exp)}`) : "";
138
+ const badge = h.state === "healthy" ? c.green("● healthy")
139
+ : h.state === "near-expiry" ? c.yellow("◐ near-expiry")
140
+ : h.state === "unbounded" ? (r.problem ? c.red("∞ unbounded") : c.dim("∞ static (dies at the flip)"))
141
+ : c.red(`✗ ${h.state}`);
142
+ console.log(` ${badge} ${r.label}${lastRenewal}${expiry}`);
143
+ }
144
+ }
145
+ /** Render the renewal owner's audit record (written by the manager's pass / doctor --fix): when the
146
+ * last pass ran, who ran it, and whether the daemon EXPLICITLY adopted — the "file re-signed" vs
147
+ * "daemon adopted" distinction the D5 panel required. Absence is informational (a mesh started
148
+ * before the renewal owner existed, or an open mesh). */
149
+ function renderRenewalRecord(root) {
150
+ const rec = readRenewalRecord(root);
151
+ if (!rec) {
152
+ console.log(c.dim(" no renewal record yet (written by the manager's renewal pass)"));
153
+ return;
154
+ }
155
+ const resigned = rec.results.filter((r) => r.ok).map((r) => r.file);
156
+ const failed = rec.results.filter((r) => !r.ok && !r.skipped);
157
+ const adoption = rec.adoption === undefined
158
+ ? resigned.length
159
+ ? c.yellow("daemon adoption not requested by this pass - daemons adopt via the 75% re-read backstop or the manager's next renewal pass")
160
+ : c.dim("adoption: n/a (nothing re-signed)")
161
+ : rec.adoption.ok
162
+ ? c.green("daemon adopted ✓")
163
+ : c.yellow(`daemon adoption pending - ${rec.adoption.error ?? "unknown"}`);
164
+ console.log(` ${c.dim(`last renewal pass ${rec.ts} by ${rec.owner}`)} - re-signed [${resigned.join(", ") || "none"}] · ${adoption}`);
165
+ for (const f of failed)
166
+ console.log(` ${c.red("✗")} last pass failed on ${f.file}: ${f.error}`);
167
+ }
168
+ function at(sec) {
169
+ return sec ? new Date(sec * 1000).toISOString() : "?";
170
+ }
171
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -55,17 +55,17 @@ export async function downManifest(file, flags) {
55
55
  specPath = join(runParent ?? join(root, ".cotal", "run"), `${ledger.runId}.json`);
56
56
  }
57
57
  catch (e) {
58
- console.error(c.red(`✗ refusing teardown unsafe owned resource: ${e.message}`));
58
+ console.error(c.red(`✗ refusing teardown - unsafe owned resource: ${e.message}`));
59
59
  process.exit(1);
60
60
  }
61
61
  if (flags.dryRun) {
62
62
  console.log(c.bold("\nWould remove (dry run):"));
63
63
  for (const a of credPaths)
64
- console.log(` ${c.red("-")} agent ${a.name} ${c.dim(`(id ${a.id.slice(0, 8)}, creds ${a.path}) stopped only if name+id match live`)}`);
64
+ console.log(` ${c.red("-")} agent ${a.name} ${c.dim(`(id ${a.id.slice(0, 8)}, creds ${a.path}) - stopped only if name+id match live`)}`);
65
65
  for (const ch of ledger.created.channels)
66
66
  console.log(` ${c.red("-")} channel ${c.cyan("#" + ch)} ${c.dim("(auth mesh: only if no members remain · open mesh: metadata cleanup, no membership audit)")}`);
67
67
  console.log(` ${c.red("-")} run dir ${runDir ?? "(none)"} + ledger ${ledgerPath} ${c.dim("(only if every owned resource is removed/proven gone; else the ledger is kept)")}`);
68
- console.log(c.dim("\nDry run nothing was changed. The live membership check + actual disposition happen at apply."));
68
+ console.log(c.dim("\nDry run - nothing was changed. The live membership check + actual disposition happen at apply."));
69
69
  return;
70
70
  }
71
71
  // 4) Best-effort live teardown: stop owned agents (name AND id match) + remove childless owned
@@ -97,7 +97,7 @@ export async function downManifest(file, flags) {
97
97
  if (!l) {
98
98
  const sameName = live.find((r) => r.name === a.name);
99
99
  if (sameName)
100
- console.log(c.yellow(` ~ ${a.name}: a different agent (id ${sameName.id.slice(0, 8)}) holds this name NOT ours, left running`));
100
+ console.log(c.yellow(` ~ ${a.name}: a different agent (id ${sameName.id.slice(0, 8)}) holds this name - NOT ours, left running`));
101
101
  else
102
102
  console.log(c.dim(` • ${a.name}: not running`));
103
103
  continue;
@@ -108,7 +108,7 @@ export async function downManifest(file, flags) {
108
108
  console.log(c.green(` ✓ stopped ${l.name}`));
109
109
  }
110
110
  else {
111
- console.log(c.yellow(` ! ${l.name}: stop failed ${stop.error ?? "unknown"}`));
111
+ console.log(c.yellow(` ! ${l.name}: stop failed - ${stop.error ?? "unknown"}`));
112
112
  }
113
113
  }
114
114
  // Channel removal: skip on ANY uncertainty (best-effort, racy — said so in output). The
@@ -152,11 +152,11 @@ export async function downManifest(file, flags) {
152
152
  }
153
153
  }
154
154
  catch (e) {
155
- console.log(c.yellow(` ! ${ledger.server}: control plane unavailable (${e.message}) nothing torn down remotely; the ledger is RETAINED for a later \`down -f --run ${ledger.runId}\``));
155
+ console.log(c.yellow(` ! ${ledger.server}: control plane unavailable (${e.message}) - nothing torn down remotely; the ledger is RETAINED for a later \`down -f --run ${ledger.runId}\``));
156
156
  }
157
157
  }
158
158
  else {
159
- console.log(c.yellow(` ! ${ledger.server} unreachable can't stop processes or remove channels; the ledger is RETAINED for a later \`down -f --run ${ledger.runId}\``));
159
+ console.log(c.yellow(` ! ${ledger.server} unreachable - can't stop processes or remove channels; the ledger is RETAINED for a later \`down -f --run ${ledger.runId}\``));
160
160
  }
161
161
  // 5) Remote resolution: which owned REMOTE resources are NOT proven handled. An agent is unresolved
162
162
  // if the broker was unreachable, or it's still live under our recorded id and its stop failed (an
@@ -186,11 +186,11 @@ export async function downManifest(file, flags) {
186
186
  if (sub === undefined)
187
187
  continue; // no cred file — proven absent
188
188
  if (sub === null) {
189
- console.error(c.yellow(` ! ${cp.name} creds: unreadable/unverifiable left in place (resolve by hand if it's a stale cred)`));
189
+ console.error(c.yellow(` ! ${cp.name} creds: unreadable/unverifiable - left in place (resolve by hand if it's a stale cred)`));
190
190
  continue;
191
191
  }
192
192
  if (sub !== cp.id) {
193
- console.error(c.yellow(` ~ ${cp.name} creds belong to a different agent (id ${sub.slice(0, 8)} ≠ ${cp.id.slice(0, 8)}) ours is gone, left in place`));
193
+ console.error(c.yellow(` ~ ${cp.name} creds belong to a different agent (id ${sub.slice(0, 8)} ≠ ${cp.id.slice(0, 8)}) - ours is gone, left in place`));
194
194
  continue;
195
195
  }
196
196
  try {
@@ -198,7 +198,7 @@ export async function downManifest(file, flags) {
198
198
  console.log(c.dim(` • removed creds for ${cp.name}`));
199
199
  }
200
200
  catch (e) {
201
- console.error(c.yellow(` ! ${cp.name} creds: ${e.message} retained for retry`));
201
+ console.error(c.yellow(` ! ${cp.name} creds: ${e.message} - retained for retry`));
202
202
  unresolvedCredIds.add(cp.id); // OUR id-verified cred, unlink failed (recoverable) → keep the record
203
203
  }
204
204
  }
@@ -209,9 +209,9 @@ export async function downManifest(file, flags) {
209
209
  const retainIds = new Set([...unresolvedIds, ...unresolvedCredIds]);
210
210
  const complete = retainIds.size === 0 && unresolvedChannels.length === 0;
211
211
  for (const s of skipped)
212
- console.log(c.yellow(` ~ left ${c.cyan("#" + s.channel)}: ${s.why}`) + c.dim(" (best-effort membership check racy)"));
212
+ console.log(c.yellow(` ~ left ${c.cyan("#" + s.channel)}: ${s.why}`) + c.dim(" (best-effort membership check - racy)"));
213
213
  if (openNoFeed.length)
214
- console.log(c.dim(` note: removed ${openNoFeed.length} channel(s) on an OPEN mesh with no membership feed no ACL isolation to protect, no membership proof: ${openNoFeed.map((n) => "#" + n).join(", ")}`));
214
+ console.log(c.dim(` note: removed ${openNoFeed.length} channel(s) on an OPEN mesh with no membership feed - no ACL isolation to protect, no membership proof: ${openNoFeed.map((n) => "#" + n).join(", ")}`));
215
215
  if (complete) {
216
216
  // Everything owned is removed/proven gone — safe to delete the run dir + launch spec + ledger.
217
217
  try {
@@ -228,7 +228,7 @@ export async function downManifest(file, flags) {
228
228
  catch (e) {
229
229
  console.error(c.yellow(` ! ledger: ${e.message}`));
230
230
  }
231
- console.log(c.green(`✓ torn down run ${ledger.runId}`) + (removed.length ? c.dim(` removed ${removed.length} channel(s): ${removed.map((n) => "#" + n).join(", ")}`) : ""));
231
+ console.log(c.green(`✓ torn down run ${ledger.runId}`) + (removed.length ? c.dim(` - removed ${removed.length} channel(s): ${removed.map((n) => "#" + n).join(", ")}`) : ""));
232
232
  }
233
233
  else {
234
234
  // Partial: rewrite the ledger DOWN to the unresolved resources so a later `down -f --run` finishes.
@@ -236,9 +236,9 @@ export async function downManifest(file, flags) {
236
236
  const remaining = { ...ledger, created: { channels: unresolvedChannels, agents: remainAgents } };
237
237
  writeLedger(root, remaining, { update: true });
238
238
  console.log(c.yellow(`! partial teardown of run ${ledger.runId}`) +
239
- c.dim(` ${remainAgents.length} agent(s) + ${unresolvedChannels.length} channel(s) still owned; ledger kept`));
239
+ c.dim(` - ${remainAgents.length} agent(s) + ${unresolvedChannels.length} channel(s) still owned; ledger kept`));
240
240
  if (unresolvedCredIds.size)
241
- console.log(c.dim(` local credential cleanup incomplete for ${unresolvedCredIds.size} agent(s) ledger kept for retry`));
241
+ console.log(c.dim(` local credential cleanup incomplete for ${unresolvedCredIds.size} agent(s) - ledger kept for retry`));
242
242
  console.log(c.dim(` finish later (broker up / members gone): cotal down -f ${ledger.manifestPath} --run ${ledger.runId}`));
243
243
  process.exitCode = 1; // not a full success
244
244
  }
@@ -4,4 +4,20 @@ import { type ParsedArgs } from "@cotal-ai/core";
4
4
  * an ownership-scoped teardown of a `spawn -f` deploy instead — removing ONLY what that run created
5
5
  * (its agents + the channels it added), from the ledger, never the whole shared mesh. */
6
6
  export declare function down(args: ParsedArgs): Promise<void>;
7
+ /** Every pidfile a background mesh records under `.cotal/`, in stop order (manager → delivery →
8
+ * auth service → web → nats: the manager's graceful shutdown releases its lease OVER nats, so nats
9
+ * must outlive it). Shared with `cotal clean`, which refuses local-state deletion while any of
10
+ * these is still alive. */
11
+ export declare function pidfileTargets(space: string): Array<[file: string, label: string]>;
12
+ export declare const isAlive: (pid: number) => boolean;
13
+ export type PidfileState = {
14
+ pid?: number;
15
+ live: boolean;
16
+ note?: string;
17
+ };
18
+ /** Read one pidfile and probe liveness with ONE hardened semantics, shared by `down`, `clean`,
19
+ * and `status` so they can never drift: only a positive integer pid counts (an empty/corrupt
20
+ * pidfile parses to 0, and POSIX `kill(0, 0)` probes our own process group), and EPERM reads as
21
+ * ALIVE (the process exists, we merely can't signal it). */
22
+ export declare function pidfileState(path: string): PidfileState;
7
23
  //# sourceMappingURL=down.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOjD;;;0FAG0F;AAC1F,wBAAsB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC1D"}
1
+ {"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOjD;;;0FAG0F;AAC1F,wBAAsB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC1D;AAED;;;4BAG4B;AAC5B,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAQlF;AAGD,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,OAOrC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E;;;6DAG6D;AAC7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAKvD"}
@@ -1,8 +1,8 @@
1
- import { existsSync, readFileSync, rmSync } from "node:fs";
1
+ import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import {} from "@cotal-ai/core";
3
- import { clearCurrent, getCurrent, removeMesh } from "@cotal-ai/workspace";
3
+ import { removeMeshesByRoot } from "@cotal-ai/workspace";
4
4
  import { c } from "../ui.js";
5
- import { cotalPath } from "../lib/paths.js";
5
+ import { cotalPath, cotalRoot } from "../lib/paths.js";
6
6
  import { resolveSpace } from "../lib/status.js";
7
7
  import { downManifest } from "./down-manifest.js";
8
8
  /** Stop the background processes started by `cotal up --detach`: the manager, the
@@ -15,21 +15,28 @@ export async function down(args) {
15
15
  await downManifest(values.file ?? "<run>", { run: values.run, dryRun: Boolean(values["dry-run"]) });
16
16
  return;
17
17
  }
18
- const targets = [
19
- ["manager.pid", "manager"],
20
- ["delivery.pid", "delivery daemon"],
21
- ["web.pid", "web dashboard"],
22
- ["nats.pid", "nats-server"],
23
- ];
18
+ // The auth service's pid file is SPACE-scoped (auth-service.<space>.pid) — resolve the space
19
+ // first, so `down` can only ever stop THIS folder's space's daemon, never another space's.
20
+ const space = resolveSpace(process.cwd());
21
+ const targets = pidfileTargets(space);
24
22
  let any = false;
25
- // Sequential, in declared order (manager → delivery → web → nats): the manager's graceful shutdown
26
- // releases its lease OVER nats, so nats must outlive it. Each stop awaits the real exit.
23
+ let allStopped = true;
24
+ // Sequential, in declared (stop) order see pidfileTargets. Each stop awaits the real exit.
27
25
  for (const [file, label] of targets) {
28
26
  const pidPath = cotalPath(file);
29
27
  if (!existsSync(pidPath))
30
28
  continue;
31
29
  any = true;
32
- await stop(pidPath, label);
30
+ if (!(await stop(pidPath, label)))
31
+ allStopped = false;
32
+ }
33
+ // A process we could not stop (EPERM, or a SIGKILL survivor) is still RUNNING: presenting the
34
+ // mesh as cleanly down — sweeping artifacts and the registry entry — would let a later `clean`
35
+ // delete the store underneath it. Keep everything and fail loud instead.
36
+ if (!allStopped) {
37
+ console.error(c.red("✗ not cleanly stopped - keeping the pidfiles, artifacts, and registry entry"));
38
+ process.exitCode = 1;
39
+ return;
33
40
  }
34
41
  // Non-pid control-plane artifacts: the delivery daemon's scoped creds + the manager's delivery-aware
35
42
  // marker. Drop them with the processes so a stale creds file / marker never lingers.
@@ -38,43 +45,82 @@ export async function down(args) {
38
45
  // Transient `cotal up -f` launch artifacts (launch specs + materialized runtime personas). `up -f`
39
46
  // owns the whole mesh, so tearing it down clears all run dirs — they're never authoritative source.
40
47
  rmSync(cotalPath("run"), { recursive: true, force: true });
41
- // Drop this folder's mesh from the registry (and the `current` pointer if it was the default).
42
- const space = resolveSpace(process.cwd());
43
- removeMesh(space);
44
- if (getCurrent() === space)
45
- clearCurrent();
48
+ // Drop this folder's meshes from the registry (and the `current` pointer per removed entry),
49
+ // keyed by ROOT - a named OPEN mesh has no auth material, so a space-name key would resolve to
50
+ // the default space and delete an unrelated mesh's entry (see removeMeshesByRoot).
51
+ removeMeshesByRoot(cotalRoot());
46
52
  if (!any) {
47
53
  console.error(c.red("Nothing running here (no .cotal/*.pid). Was it started with `cotal up` / `cotal setup`?"));
48
54
  process.exit(1);
49
55
  }
50
56
  }
57
+ /** Every pidfile a background mesh records under `.cotal/`, in stop order (manager → delivery →
58
+ * auth service → web → nats: the manager's graceful shutdown releases its lease OVER nats, so nats
59
+ * must outlive it). Shared with `cotal clean`, which refuses local-state deletion while any of
60
+ * these is still alive. */
61
+ export function pidfileTargets(space) {
62
+ return [
63
+ ["manager.pid", "manager"],
64
+ ["delivery.pid", "delivery daemon"],
65
+ [`auth-service.${encodeURIComponent(space)}.pid`, "user-auth service"],
66
+ ["web.pid", "web dashboard"],
67
+ ["nats.pid", "nats-server"],
68
+ ];
69
+ }
51
70
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
52
- const isAlive = (pid) => {
71
+ export const isAlive = (pid) => {
53
72
  try {
54
73
  process.kill(pid, 0);
55
74
  return true;
56
75
  }
57
- catch {
58
- return false;
76
+ catch (e) {
77
+ // EPERM = the process EXISTS but we may not signal it (e.g. launched from a differently
78
+ // elevated context). For safety that counts as alive; only ESRCH-style "no such process"
79
+ // reads as dead.
80
+ return e.code === "EPERM";
59
81
  }
60
82
  };
83
+ /** Read one pidfile and probe liveness with ONE hardened semantics, shared by `down`, `clean`,
84
+ * and `status` so they can never drift: only a positive integer pid counts (an empty/corrupt
85
+ * pidfile parses to 0, and POSIX `kill(0, 0)` probes our own process group), and EPERM reads as
86
+ * ALIVE (the process exists, we merely can't signal it). */
87
+ export function pidfileState(path) {
88
+ if (!existsSync(path))
89
+ return { live: false, note: "no pidfile" };
90
+ const pid = Number(readFileSync(path, "utf8").trim());
91
+ if (!Number.isInteger(pid) || pid <= 0)
92
+ return { live: false, note: "bad pidfile" };
93
+ return isAlive(pid) ? { pid, live: true } : { pid, live: false, note: "stale pidfile" };
94
+ }
61
95
  /** Stop one recorded process and AWAIT its actual exit — SIGTERM starts a graceful shutdown (a
62
96
  * manager reaps its agents and releases its JetStream lease over NATS, which isn't instant), so
63
97
  * returning before the process is really gone would let callers (and `up`-style smokes) race a
64
- * still-dying manager. Poll the pid, escalate to SIGKILL if it overstays, then confirm it's gone. */
98
+ * still-dying manager. Poll the pid, escalate to SIGKILL if it overstays, then confirm it's gone.
99
+ * Returns whether the process is confirmed absent. The pidfile is removed only once that is
100
+ * established: erasing the record of a process we could NOT stop (EPERM — alive but
101
+ * unsignalable) would let a later `cotal clean` delete the store underneath a live broker. */
65
102
  async function stop(pidPath, label) {
66
- const pid = Number(readFileSync(pidPath, "utf8").trim());
67
- // Drop the pidfile up front so a concurrent `down` can't double-signal a reused pid.
68
- rmSync(pidPath, { force: true });
69
- if (!Number.isFinite(pid))
70
- return;
103
+ const s = pidfileState(pidPath);
104
+ if (!s.live) {
105
+ // Dead or unusable record (stale pid, empty/corrupt file) nothing to stop, drop it.
106
+ rmSync(pidPath, { force: true });
107
+ if (s.pid)
108
+ console.log(c.dim(`${label} (pid ${s.pid}) was not running.`));
109
+ return true;
110
+ }
111
+ const pid = s.pid;
71
112
  try {
72
113
  process.kill(pid, "SIGTERM");
73
114
  }
74
- catch {
75
- console.log(c.dim(`${label} (pid ${pid}) was not running.`));
76
- return;
115
+ catch (e) {
116
+ // The probe said alive, the signal was refused: EPERM (differently elevated context) or
117
+ // similar. The process is still running — keep its pidfile and fail loud.
118
+ console.error(c.red(`✗ cannot stop ${label} (pid ${pid}): ${e.code ?? e.message}`));
119
+ return false;
77
120
  }
121
+ // Signal accepted — this `down` owns the stop. Drop the pidfile now so a concurrent `down`
122
+ // can't double-signal a reused pid.
123
+ rmSync(pidPath, { force: true });
78
124
  const graceDeadline = Date.now() + 15_000;
79
125
  while (isAlive(pid) && Date.now() < graceDeadline)
80
126
  await sleep(100);
@@ -87,8 +133,13 @@ async function stop(pidPath, label) {
87
133
  while (isAlive(pid) && Date.now() < hardDeadline)
88
134
  await sleep(100);
89
135
  }
90
- console.log(isAlive(pid)
91
- ? c.red(`✗ ${label} (pid ${pid}) did not exit`)
92
- : c.green(`✓ stopped ${label} (pid ${pid})`));
136
+ if (isAlive(pid)) {
137
+ // A SIGKILL survivor is still running — restore the record it must keep.
138
+ writeFileSync(pidPath, String(pid));
139
+ console.log(c.red(`✗ ${label} (pid ${pid}) did not exit`));
140
+ return false;
141
+ }
142
+ console.log(c.green(`✓ stopped ${label} (pid ${pid})`));
143
+ return true;
93
144
  }
94
145
  //# sourceMappingURL=down.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ext.d.ts","sourceRoot":"","sources":["../../src/commands/ext.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAczE;;;;;;;;;;;;;;GAcG;AAEH,wBAAsB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzD"}
1
+ {"version":3,"file":"ext.d.ts","sourceRoot":"","sources":["../../src/commands/ext.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAyBzE;;;;;;;;;;;;;;GAcG;AAEH,wBAAsB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzD"}