@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.
- package/dist/command.d.ts.map +1 -1
- package/dist/command.js +17 -4
- package/dist/command.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +30 -13
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/channels.d.ts.map +1 -1
- package/dist/commands/channels.js +16 -6
- package/dist/commands/channels.js.map +1 -1
- package/dist/commands/clean.d.ts +40 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +138 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/completion.js +5 -5
- package/dist/commands/console.d.ts +1 -1
- package/dist/commands/console.d.ts.map +1 -1
- package/dist/commands/console.js +17 -11
- package/dist/commands/console.js.map +1 -1
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +171 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/down-manifest.js +15 -15
- package/dist/commands/down.d.ts +16 -0
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +83 -32
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/ext.d.ts.map +1 -1
- package/dist/commands/ext.js +30 -17
- package/dist/commands/ext.js.map +1 -1
- package/dist/commands/feedback.js +2 -2
- package/dist/commands/history.d.ts +3 -2
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +6 -17
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/join.d.ts.map +1 -1
- package/dist/commands/join.js +14 -7
- package/dist/commands/join.js.map +1 -1
- package/dist/commands/meshes.js +2 -2
- package/dist/commands/mint.d.ts.map +1 -1
- package/dist/commands/mint.js +16 -5
- package/dist/commands/mint.js.map +1 -1
- package/dist/commands/models.js +1 -1
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/personas.js +4 -4
- package/dist/commands/send.js +1 -1
- package/dist/commands/setup.js +27 -27
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/spawn-manifest.d.ts.map +1 -1
- package/dist/commands/spawn-manifest.js +47 -25
- package/dist/commands/spawn-manifest.js.map +1 -1
- package/dist/commands/spawn.d.ts +6 -0
- package/dist/commands/spawn.d.ts.map +1 -1
- package/dist/commands/spawn.js +257 -46
- package/dist/commands/spawn.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +85 -22
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/topology.js +2 -2
- package/dist/commands/up.d.ts +5 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +272 -49
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/use.js +1 -1
- package/dist/console/commands.js +2 -2
- package/dist/console/mesh.js +1 -1
- package/dist/console/mesh.js.map +1 -1
- package/dist/console/root.d.ts +15 -3
- package/dist/console/root.d.ts.map +1 -1
- package/dist/console/root.js +12 -7
- package/dist/console/root.js.map +1 -1
- package/dist/console/ui/Confirm.js +1 -1
- package/dist/console/ui/Confirm.js.map +1 -1
- package/dist/console/ui/Feed.js +1 -1
- package/dist/console/ui/Feed.js.map +1 -1
- package/dist/console/ui/Help.js +2 -2
- package/dist/console/ui/Help.js.map +1 -1
- package/dist/console/ui/NeedsYou.js +1 -1
- package/dist/console/ui/NeedsYou.js.map +1 -1
- package/dist/console/ui/SpacePicker.js +1 -1
- package/dist/console/ui/SpacePicker.js.map +1 -1
- package/dist/console/ui/Tiles.js +1 -1
- package/dist/console/ui/topo/Map.js +1 -1
- package/dist/console/ui/topo/Map.js.map +1 -1
- package/dist/console/ui/topo/Matrix.js +2 -2
- package/dist/console/ui/topo/Matrix.js.map +1 -1
- package/dist/console/ui/topo/Sequence.js +1 -1
- package/dist/console/ui/topo/Sequence.js.map +1 -1
- package/dist/ext-loader.d.ts.map +1 -1
- package/dist/ext-loader.js +20 -8
- package/dist/ext-loader.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -18
- package/dist/index.js.map +1 -1
- package/dist/lib/attach-client.js +1 -1
- package/dist/lib/auth-proc.d.ts +19 -0
- package/dist/lib/auth-proc.d.ts.map +1 -0
- package/dist/lib/auth-proc.js +81 -0
- package/dist/lib/auth-proc.js.map +1 -0
- package/dist/lib/connect.d.ts +1 -1
- package/dist/lib/connect.d.ts.map +1 -1
- package/dist/lib/connect.js +2 -2
- package/dist/lib/connect.js.map +1 -1
- package/dist/lib/control.d.ts +14 -6
- package/dist/lib/control.d.ts.map +1 -1
- package/dist/lib/control.js +31 -13
- package/dist/lib/control.js.map +1 -1
- package/dist/lib/delivery-proc.js +2 -2
- package/dist/lib/manifest/apply.d.ts +3 -2
- package/dist/lib/manifest/apply.d.ts.map +1 -1
- package/dist/lib/manifest/apply.js +7 -2
- package/dist/lib/manifest/apply.js.map +1 -1
- package/dist/lib/manifest/ledger.js +4 -4
- package/dist/lib/manifest/live.d.ts +23 -9
- package/dist/lib/manifest/live.d.ts.map +1 -1
- package/dist/lib/manifest/live.js +22 -12
- package/dist/lib/manifest/live.js.map +1 -1
- package/dist/lib/manifest/model.d.ts +4 -1
- package/dist/lib/manifest/model.d.ts.map +1 -1
- package/dist/lib/manifest/prepare.d.ts +2 -0
- package/dist/lib/manifest/prepare.d.ts.map +1 -1
- package/dist/lib/manifest/prepare.js +5 -2
- package/dist/lib/manifest/prepare.js.map +1 -1
- package/dist/lib/manifest/render.d.ts.map +1 -1
- package/dist/lib/manifest/render.js +14 -13
- package/dist/lib/manifest/render.js.map +1 -1
- package/dist/lib/manifest/resolve.js +19 -6
- package/dist/lib/manifest/resolve.js.map +1 -1
- package/dist/lib/manifest/schema.d.ts +4 -1
- package/dist/lib/manifest/schema.d.ts.map +1 -1
- package/dist/lib/manifest/schema.js +10 -2
- package/dist/lib/manifest/schema.js.map +1 -1
- package/dist/lib/setup-log.js +1 -1
- package/dist/lib/status.d.ts +1 -1
- package/dist/lib/status.js +1 -1
- package/dist/lib/transient.d.ts +8 -10
- package/dist/lib/transient.d.ts.map +1 -1
- package/dist/lib/transient.js +11 -11
- package/dist/lib/transient.js.map +1 -1
- package/dist/render.js +2 -2
- package/dist/ui.d.ts +5 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +13 -1
- package/dist/ui.js.map +1 -1
- 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
|
|
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})
|
|
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
|
|
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
|
|
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
|
|
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})
|
|
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
|
|
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
|
|
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)})
|
|
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}
|
|
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
|
|
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
|
|
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(`
|
|
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(`
|
|
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)
|
|
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
|
}
|
package/dist/commands/down.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/commands/down.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
26
|
-
//
|
|
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
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
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
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
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;
|
|
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"}
|