@pleri/olam-cli 0.1.106 → 0.1.108

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * health-probes.ts — Shared host-health probe module.
3
+ *
4
+ * Phase A1 of olam-operator-onboarding-parity (plan
5
+ * ~/.claude/plans/olam-operator-onboarding-parity.md).
6
+ *
7
+ * The Seam (Decision 3): `olam doctor` + `olam diagnose` both consume
8
+ * these probes. No probe writes to disk; no probe spawns long-running
9
+ * processes; each is independently safe to run in parallel.
10
+ *
11
+ * Probe contract:
12
+ * - Each returns ProbeResult: { ok: true, message } | { ok: false, message, remedy }
13
+ * - Each is async; can run in parallel via Promise.all
14
+ * - Each accepts injectable deps (docker exec / fetch / OLAM_HOME) for testability
15
+ *
16
+ * Cap thresholds (probeKgStorage) mirror packages/cli/src/commands/kg-status.ts:
17
+ * - 1.5 GB soft-cap → ok:true with "soft-warn" message
18
+ * - 5.0 GB hard-cap → ok:false with prune remedy
19
+ *
20
+ * Daemon-reachability rule (Risk T5): callers that probe per-image
21
+ * presence MUST call probeDockerDaemon first and fast-fail on its
22
+ * failure. Image probes throw confusing "404 no such image" errors
23
+ * when the daemon is paused mid-check.
24
+ */
25
+ export type ProbeResult = {
26
+ readonly ok: true;
27
+ readonly message: string;
28
+ } | {
29
+ readonly ok: false;
30
+ readonly message: string;
31
+ readonly remedy: string;
32
+ };
33
+ export interface DockerExecResult {
34
+ readonly status: number | null;
35
+ readonly stdout: string;
36
+ readonly stderr: string;
37
+ }
38
+ export type DockerExec = (cmd: string, args: ReadonlyArray<string>) => DockerExecResult;
39
+ export type FetchLike = (input: string, init?: {
40
+ signal?: AbortSignal;
41
+ }) => Promise<Response>;
42
+ /**
43
+ * Verify docker daemon is reachable via `docker info --format`.
44
+ *
45
+ * MUST be called first by callers that probe per-image presence; image
46
+ * probes throw confusing "404 no such image" errors when the daemon is
47
+ * paused mid-check (Risk T5 mitigation).
48
+ */
49
+ export declare function probeDockerDaemon(dockerExec?: DockerExec): Promise<ProbeResult>;
50
+ /**
51
+ * Verify each ref is present locally via `docker image inspect`.
52
+ *
53
+ * Fast-fail: returns the first missing image; subsequent refs NOT
54
+ * probed. Caller decides ordering of refs.
55
+ */
56
+ export declare function probeImagePresence(refs: ReadonlyArray<string>, dockerExec?: DockerExec): Promise<ProbeResult>;
57
+ /**
58
+ * GET http://127.0.0.1:19000/health with 5s timeout; expect HTTP 200
59
+ * AND a JSON envelope matching the host-cp shape (defends against
60
+ * false-positives from a port-collision with some other 19000-bound
61
+ * process — audit finding HIGH body-shape).
62
+ *
63
+ * Real envelope (per `packages/host-cp/src/server.mjs:665-688`):
64
+ * { status: 'ok', phase, uptime_seconds: number, cache: {...},
65
+ * mode: { deployment, world_host }, registry: {...}, auth: {...} }
66
+ *
67
+ * Probe asserts three orthogonal fields (`phase` + `cache` object +
68
+ * `mode.deployment`) that no random web server would carry together.
69
+ * Substring-on-the-token-path was an earlier fragile heuristic; this
70
+ * version pins to actual server contract.
71
+ *
72
+ * Aborts via AbortController on timeout; failure mode is captured in
73
+ * the error path with reason ("timeout" / "ECONNREFUSED" / etc.).
74
+ *
75
+ * Always consumes the response body before returning (avoids undici
76
+ * socket leak when the probe is invoked in a loop).
77
+ */
78
+ export declare function probeHostCpHealth(fetchImpl?: FetchLike): Promise<ProbeResult>;
79
+ /**
80
+ * Read the canonical credentials vault at `<OLAM_HOME>/auth-data/accounts.json`
81
+ * (matching `packages/auth-service/src/store.ts:LOCAL_DATA_DIR` and
82
+ * `scripts/audit-credentials.mjs:resolveAccountsPath`); count active
83
+ * `claude` credentials.
84
+ *
85
+ * Vault shape (per packages/auth-service/src/types.ts): a flat JSON array
86
+ * of account objects. Each account has:
87
+ * - provider: 'claude' | 'codex' | ...
88
+ * - state?: 'active' | 'cooldown' | 'disabled'
89
+ * - rateLimited?: boolean (legacy fallback for state)
90
+ * - expiresAt?: number (epoch ms)
91
+ * - rateLimitResetsAt?: string (ISO 8601)
92
+ *
93
+ * Predicate mirrors `effectiveState()` from scripts/audit-credentials.mjs
94
+ * inline (the canonical helper is a .mjs script that we can't import from
95
+ * this TS module). If the canonical predicate evolves (new fields, new
96
+ * state literals), this mirror MUST be updated.
97
+ *
98
+ * Override: `OLAM_AUTH_DATA_PATH` env var lets CI/test fixtures point
99
+ * at an alternate accounts.json. Matches the canonical helper.
100
+ */
101
+ export declare function probeAuthVault(olamHomeOverride?: string): Promise<ProbeResult>;
102
+ /**
103
+ * Cumulative KG storage under OLAM_HOME (pristines + overlays).
104
+ * Soft warn at 1.5 GB; hard fail at 5 GB.
105
+ *
106
+ * Layout (mirrors packages/cli/src/commands/kg-status.ts):
107
+ * - Pristines: ~/.olam/kg/<workspace>/graphify-out/
108
+ * - Overlays: ~/.olam/worlds/<world>/<clone>/graphify-out/
109
+ *
110
+ * Cap constants duplicated rather than imported from kg-status.ts to
111
+ * keep this module self-contained (the Seam decision — see plan
112
+ * decision 3). A future PR may extract them to a single source if
113
+ * a third consumer lands.
114
+ */
115
+ export declare function probeKgStorage(olamHomeOverride?: string): Promise<ProbeResult>;
116
+ //# sourceMappingURL=health-probes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-probes.d.ts","sourceRoot":"","sources":["../../src/lib/health-probes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAM9E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,gBAAgB,CAAC;AAExF,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AA+B9F;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,WAAW,CAAC,CAUtB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,GAAE,SAAwB,GAClC,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAwBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqCpF;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuBpF"}
@@ -0,0 +1,390 @@
1
+ /**
2
+ * health-probes.ts — Shared host-health probe module.
3
+ *
4
+ * Phase A1 of olam-operator-onboarding-parity (plan
5
+ * ~/.claude/plans/olam-operator-onboarding-parity.md).
6
+ *
7
+ * The Seam (Decision 3): `olam doctor` + `olam diagnose` both consume
8
+ * these probes. No probe writes to disk; no probe spawns long-running
9
+ * processes; each is independently safe to run in parallel.
10
+ *
11
+ * Probe contract:
12
+ * - Each returns ProbeResult: { ok: true, message } | { ok: false, message, remedy }
13
+ * - Each is async; can run in parallel via Promise.all
14
+ * - Each accepts injectable deps (docker exec / fetch / OLAM_HOME) for testability
15
+ *
16
+ * Cap thresholds (probeKgStorage) mirror packages/cli/src/commands/kg-status.ts:
17
+ * - 1.5 GB soft-cap → ok:true with "soft-warn" message
18
+ * - 5.0 GB hard-cap → ok:false with prune remedy
19
+ *
20
+ * Daemon-reachability rule (Risk T5): callers that probe per-image
21
+ * presence MUST call probeDockerDaemon first and fast-fail on its
22
+ * failure. Image probes throw confusing "404 no such image" errors
23
+ * when the daemon is paused mid-check.
24
+ */
25
+ import { spawnSync } from 'node:child_process';
26
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
27
+ import { homedir } from 'node:os';
28
+ import path from 'node:path';
29
+ import { SOFT_CAP_BYTES, HARD_CAP_BYTES } from './kg-caps.js';
30
+ const HEALTH_TIMEOUT_MS = 5_000;
31
+ /**
32
+ * Default Docker exec implementation. Consumers MUST inject their own
33
+ * `exec` parameter in tests — this default reaches real
34
+ * `node:child_process.spawnSync` and will shell out to a real `docker`
35
+ * binary on the test runner (green on dev laptops with Docker running;
36
+ * red on CI runners without daemon). Audit finding HIGH-2.
37
+ */
38
+ const defaultDockerExec = (cmd, args) => {
39
+ const r = spawnSync(cmd, [...args], {
40
+ encoding: 'utf-8',
41
+ stdio: ['ignore', 'pipe', 'pipe'],
42
+ });
43
+ return {
44
+ status: r.status,
45
+ stdout: r.stdout ?? '',
46
+ stderr: r.stderr ?? '',
47
+ };
48
+ };
49
+ /**
50
+ * Default fetch implementation. Consumers MUST inject their own
51
+ * `fetchImpl` parameter in tests — this default reaches the global
52
+ * `fetch` and will make real network calls on the test runner.
53
+ * Audit finding HIGH-2.
54
+ */
55
+ const defaultFetch = (input, init) => fetch(input, init);
56
+ // ── Probes ─────────────────────────────────────────────────────────────
57
+ /**
58
+ * Verify docker daemon is reachable via `docker info --format`.
59
+ *
60
+ * MUST be called first by callers that probe per-image presence; image
61
+ * probes throw confusing "404 no such image" errors when the daemon is
62
+ * paused mid-check (Risk T5 mitigation).
63
+ */
64
+ export async function probeDockerDaemon(dockerExec = defaultDockerExec) {
65
+ const r = dockerExec('docker', ['info', '--format', '{{.ServerVersion}}']);
66
+ if (r.status === 0 && r.stdout.trim().length > 0) {
67
+ return { ok: true, message: `docker ${r.stdout.trim()} reachable` };
68
+ }
69
+ return {
70
+ ok: false,
71
+ message: 'docker daemon not reachable',
72
+ remedy: 'Start Docker Desktop (or your docker daemon) and re-run.',
73
+ };
74
+ }
75
+ /**
76
+ * Verify each ref is present locally via `docker image inspect`.
77
+ *
78
+ * Fast-fail: returns the first missing image; subsequent refs NOT
79
+ * probed. Caller decides ordering of refs.
80
+ */
81
+ export async function probeImagePresence(refs, dockerExec = defaultDockerExec) {
82
+ for (const ref of refs) {
83
+ const r = dockerExec('docker', ['image', 'inspect', '--format', '{{.Id}}', ref]);
84
+ if (r.status !== 0) {
85
+ return {
86
+ ok: false,
87
+ message: `image ${ref} not present locally`,
88
+ remedy: 'Run `olam bootstrap` to pull the published image, or build locally.',
89
+ };
90
+ }
91
+ }
92
+ return { ok: true, message: `${refs.length} image(s) present` };
93
+ }
94
+ /**
95
+ * GET http://127.0.0.1:19000/health with 5s timeout; expect HTTP 200
96
+ * AND a JSON envelope matching the host-cp shape (defends against
97
+ * false-positives from a port-collision with some other 19000-bound
98
+ * process — audit finding HIGH body-shape).
99
+ *
100
+ * Real envelope (per `packages/host-cp/src/server.mjs:665-688`):
101
+ * { status: 'ok', phase, uptime_seconds: number, cache: {...},
102
+ * mode: { deployment, world_host }, registry: {...}, auth: {...} }
103
+ *
104
+ * Probe asserts three orthogonal fields (`phase` + `cache` object +
105
+ * `mode.deployment`) that no random web server would carry together.
106
+ * Substring-on-the-token-path was an earlier fragile heuristic; this
107
+ * version pins to actual server contract.
108
+ *
109
+ * Aborts via AbortController on timeout; failure mode is captured in
110
+ * the error path with reason ("timeout" / "ECONNREFUSED" / etc.).
111
+ *
112
+ * Always consumes the response body before returning (avoids undici
113
+ * socket leak when the probe is invoked in a loop).
114
+ */
115
+ export async function probeHostCpHealth(fetchImpl = defaultFetch) {
116
+ const controller = new AbortController();
117
+ const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
118
+ try {
119
+ const res = await fetchImpl('http://127.0.0.1:19000/health', { signal: controller.signal });
120
+ const body = await res.text().catch(() => '');
121
+ if (res.status !== 200) {
122
+ return {
123
+ ok: false,
124
+ message: `host-cp /health returned ${res.status}`,
125
+ remedy: 'Restart host-cp via `olam host-cp start`; verify port 19000 is bound to 127.0.0.1.',
126
+ };
127
+ }
128
+ if (isHostCpHealthEnvelope(body)) {
129
+ return { ok: true, message: 'host-cp /health returned 200' };
130
+ }
131
+ return {
132
+ ok: false,
133
+ message: 'host-cp /health returned 200 but body did not match the host-cp envelope (possible port collision on :19000)',
134
+ remedy: 'Check `lsof -iTCP:19000`; another process may have bound the port. Restart host-cp via `olam host-cp start`.',
135
+ };
136
+ }
137
+ catch (err) {
138
+ const e = err;
139
+ const reason = e.name === 'AbortError' ? `timeout (${HEALTH_TIMEOUT_MS}ms)` : e.message;
140
+ return {
141
+ ok: false,
142
+ message: `host-cp /health unreachable: ${reason}`,
143
+ remedy: 'Restart host-cp via `olam host-cp start`; verify port 19000 is bound to 127.0.0.1.',
144
+ };
145
+ }
146
+ finally {
147
+ clearTimeout(timeout);
148
+ }
149
+ }
150
+ /**
151
+ * Match three orthogonal fields from host-cp's real /health envelope.
152
+ * Returns true only when ALL match (a random 19000-bound web server is
153
+ * very unlikely to ship all three in one response by accident).
154
+ */
155
+ function isHostCpHealthEnvelope(body) {
156
+ let parsed;
157
+ try {
158
+ parsed = JSON.parse(body);
159
+ }
160
+ catch {
161
+ return false;
162
+ }
163
+ if (!parsed || typeof parsed !== 'object')
164
+ return false;
165
+ const obj = parsed;
166
+ if (typeof obj.phase !== 'string')
167
+ return false;
168
+ if (!obj.cache || typeof obj.cache !== 'object')
169
+ return false;
170
+ const mode = obj.mode;
171
+ if (!mode || typeof mode !== 'object')
172
+ return false;
173
+ if (typeof mode.deployment !== 'string')
174
+ return false;
175
+ return true;
176
+ }
177
+ /**
178
+ * Read the canonical credentials vault at `<OLAM_HOME>/auth-data/accounts.json`
179
+ * (matching `packages/auth-service/src/store.ts:LOCAL_DATA_DIR` and
180
+ * `scripts/audit-credentials.mjs:resolveAccountsPath`); count active
181
+ * `claude` credentials.
182
+ *
183
+ * Vault shape (per packages/auth-service/src/types.ts): a flat JSON array
184
+ * of account objects. Each account has:
185
+ * - provider: 'claude' | 'codex' | ...
186
+ * - state?: 'active' | 'cooldown' | 'disabled'
187
+ * - rateLimited?: boolean (legacy fallback for state)
188
+ * - expiresAt?: number (epoch ms)
189
+ * - rateLimitResetsAt?: string (ISO 8601)
190
+ *
191
+ * Predicate mirrors `effectiveState()` from scripts/audit-credentials.mjs
192
+ * inline (the canonical helper is a .mjs script that we can't import from
193
+ * this TS module). If the canonical predicate evolves (new fields, new
194
+ * state literals), this mirror MUST be updated.
195
+ *
196
+ * Override: `OLAM_AUTH_DATA_PATH` env var lets CI/test fixtures point
197
+ * at an alternate accounts.json. Matches the canonical helper.
198
+ */
199
+ export async function probeAuthVault(olamHomeOverride) {
200
+ const vaultPath = resolveAccountsPath(olamHomeOverride);
201
+ if (!existsSync(vaultPath)) {
202
+ return {
203
+ ok: false,
204
+ message: `auth vault missing at ${vaultPath}`,
205
+ remedy: 'Run `olam auth up && olam auth login` to provision the vault.',
206
+ };
207
+ }
208
+ let parsed;
209
+ try {
210
+ parsed = JSON.parse(readFileSync(vaultPath, 'utf-8'));
211
+ }
212
+ catch (err) {
213
+ return {
214
+ ok: false,
215
+ message: `auth vault malformed: ${err.message}`,
216
+ remedy: 'Inspect the accounts.json file; restore from backup or re-run `olam auth up`.',
217
+ };
218
+ }
219
+ if (!Array.isArray(parsed)) {
220
+ return {
221
+ ok: false,
222
+ message: 'auth vault malformed: expected JSON array at top level',
223
+ remedy: 'Restore the vault from backup or re-run `olam auth up && olam auth login`.',
224
+ };
225
+ }
226
+ const accounts = parsed.filter((a) => a !== null && typeof a === 'object');
227
+ const now = Date.now();
228
+ const activeClaude = accounts.filter((a) => a.provider === 'claude' && effectiveState(a, now) === 'active');
229
+ if (activeClaude.length === 0) {
230
+ return {
231
+ ok: false,
232
+ message: `no active claude credentials (vault has ${accounts.length} account(s))`,
233
+ remedy: 'Run `olam auth login` to add a credential, or wait for the next reset.',
234
+ };
235
+ }
236
+ return { ok: true, message: `${activeClaude.length} active claude credential(s)` };
237
+ }
238
+ function resolveAccountsPath(olamHomeOverride) {
239
+ // OLAM_AUTH_DATA_PATH is the explicit override (matches the canonical
240
+ // helper at scripts/audit-credentials.mjs). Honoured first for CI fixtures.
241
+ const explicit = process.env.OLAM_AUTH_DATA_PATH;
242
+ if (explicit)
243
+ return explicit;
244
+ const olamHome = olamHomeOverride ?? process.env.OLAM_HOME ?? path.join(homedir(), '.olam');
245
+ return path.join(olamHome, 'auth-data', 'accounts.json');
246
+ }
247
+ /**
248
+ * Inline mirror of `effectiveState()` from scripts/audit-credentials.mjs.
249
+ *
250
+ * IMPORTANT: keep this in sync with the canonical helper. If the helper
251
+ * changes, this copy MUST change too (no compile-time link between them).
252
+ */
253
+ function effectiveState(account, now) {
254
+ const persisted = account.state ?? (account.rateLimited ? 'cooldown' : 'active');
255
+ if (persisted === 'disabled')
256
+ return 'disabled';
257
+ if (typeof account.expiresAt === 'number' && account.expiresAt <= now)
258
+ return 'expired';
259
+ if (persisted === 'cooldown') {
260
+ const reset = account.rateLimitResetsAt ? new Date(account.rateLimitResetsAt).getTime() : 0;
261
+ if (reset > 0 && reset <= now)
262
+ return 'active';
263
+ }
264
+ return persisted;
265
+ }
266
+ /**
267
+ * Cumulative KG storage under OLAM_HOME (pristines + overlays).
268
+ * Soft warn at 1.5 GB; hard fail at 5 GB.
269
+ *
270
+ * Layout (mirrors packages/cli/src/commands/kg-status.ts):
271
+ * - Pristines: ~/.olam/kg/<workspace>/graphify-out/
272
+ * - Overlays: ~/.olam/worlds/<world>/<clone>/graphify-out/
273
+ *
274
+ * Cap constants duplicated rather than imported from kg-status.ts to
275
+ * keep this module self-contained (the Seam decision — see plan
276
+ * decision 3). A future PR may extract them to a single source if
277
+ * a third consumer lands.
278
+ */
279
+ export async function probeKgStorage(olamHomeOverride) {
280
+ const olamHome = olamHomeOverride ?? process.env.OLAM_HOME ?? path.join(homedir(), '.olam');
281
+ const kgRoot = path.join(olamHome, 'kg');
282
+ const worldsRoot = path.join(olamHome, 'worlds');
283
+ const kgBytes = enumerateGraphifyOut(kgRoot, 'pristine');
284
+ const overlayBytes = enumerateGraphifyOut(worldsRoot, 'overlay');
285
+ const totalBytes = kgBytes + overlayBytes;
286
+ if (totalBytes >= HARD_CAP_BYTES) {
287
+ return {
288
+ ok: false,
289
+ message: `KG storage ${formatBytes(totalBytes)} exceeds 5 GB hard cap`,
290
+ remedy: 'Prune stale pristines: `rm -rf ~/.olam/kg/<workspace>` after operator review.',
291
+ };
292
+ }
293
+ if (totalBytes >= SOFT_CAP_BYTES) {
294
+ return {
295
+ ok: true,
296
+ message: `KG storage ${formatBytes(totalBytes)} (soft-warn — exceeds 1.5 GB; consider pruning)`,
297
+ };
298
+ }
299
+ return { ok: true, message: `KG storage ${formatBytes(totalBytes)} (under cap)` };
300
+ }
301
+ function enumerateGraphifyOut(root, layout) {
302
+ if (!existsSync(root))
303
+ return 0;
304
+ let total = 0;
305
+ let entries;
306
+ try {
307
+ entries = readdirSync(root, { withFileTypes: true });
308
+ }
309
+ catch {
310
+ return 0;
311
+ }
312
+ for (const entry of entries) {
313
+ if (!entry.isDirectory())
314
+ continue;
315
+ if (layout === 'pristine') {
316
+ total += dirSizeBytes(path.join(root, entry.name, 'graphify-out'));
317
+ }
318
+ else {
319
+ const worldDir = path.join(root, entry.name);
320
+ let clones;
321
+ try {
322
+ clones = readdirSync(worldDir, { withFileTypes: true });
323
+ }
324
+ catch {
325
+ continue;
326
+ }
327
+ for (const clone of clones) {
328
+ if (!clone.isDirectory())
329
+ continue;
330
+ total += dirSizeBytes(path.join(worldDir, clone.name, 'graphify-out'));
331
+ }
332
+ }
333
+ }
334
+ return total;
335
+ }
336
+ /**
337
+ * Recursive byte sum over a directory.
338
+ *
339
+ * Symlink policy: short-circuited via `entry.isSymbolicLink()` in the
340
+ * common case. KNOWN FALSE-POSITIVE CLASS (audit finding HIGH-3): on
341
+ * filesystems that don't populate `d_type` (some network mounts, FUSE,
342
+ * exotic overlay FS), `Dirent` flags report `UV_DIRENT_UNKNOWN` and
343
+ * both `isSymbolicLink()` and `isDirectory()` return `false`. Such an
344
+ * entry is then `statSync`'d as a file; if it's actually a symlink to
345
+ * a giant file, the target's bytes are counted. Probability is low on
346
+ * APFS/ext4; impact is "doctor false-fail on a healthy host with
347
+ * exotic FS." Mirrors the same shape in kg-status.ts:240.
348
+ */
349
+ function dirSizeBytes(dir) {
350
+ if (!existsSync(dir))
351
+ return 0;
352
+ let total = 0;
353
+ const stack = [dir];
354
+ while (stack.length > 0) {
355
+ const cur = stack.pop();
356
+ let entries;
357
+ try {
358
+ entries = readdirSync(cur, { withFileTypes: true });
359
+ }
360
+ catch {
361
+ continue;
362
+ }
363
+ for (const entry of entries) {
364
+ const full = path.join(cur, entry.name);
365
+ if (entry.isSymbolicLink())
366
+ continue;
367
+ if (entry.isDirectory()) {
368
+ stack.push(full);
369
+ continue;
370
+ }
371
+ try {
372
+ total += statSync(full).size;
373
+ }
374
+ catch {
375
+ // race: file disappeared between readdir + stat
376
+ }
377
+ }
378
+ }
379
+ return total;
380
+ }
381
+ function formatBytes(n) {
382
+ if (n < 1024)
383
+ return `${n} B`;
384
+ if (n < 1024 * 1024)
385
+ return `${(n / 1024).toFixed(1)} KB`;
386
+ if (n < 1024 * 1024 * 1024)
387
+ return `${(n / 1024 / 1024).toFixed(1)} MB`;
388
+ return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
389
+ }
390
+ //# sourceMappingURL=health-probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-probes.js","sourceRoot":"","sources":["../../src/lib/health-probes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * kg-caps.ts — KG storage cap thresholds (single source of truth).
3
+ *
4
+ * Phase A1 follow-up (audit finding HIGH-1: drift): A1's `health-probes.ts`
5
+ * and the pre-existing `commands/kg-status.ts` were both hard-coding the
6
+ * 1.5 GB soft / 5 GB hard cap thresholds. With doctor + diagnose + kg-status
7
+ * as three consumers (A1 added consumer #2; A3 makes it #3 transitively),
8
+ * the plan's "third-consumer threshold" has arrived. Pin the constants here
9
+ * so any future cap-policy change touches one file.
10
+ *
11
+ * Drift contract: every consumer of these constants MUST import from this
12
+ * module, NOT redefine inline. A grep for `1_500_000_000` or `5_000_000_000`
13
+ * across `packages/cli/src/` should match only this file.
14
+ */
15
+ /** Soft warn threshold — 1.5 GB. Below this: silent. Above: doctor prints a "consider pruning" note but still exits 0. */
16
+ export declare const SOFT_CAP_BYTES = 1500000000;
17
+ /** Hard fail threshold — 5 GB. At or above: doctor exits 1; `olam kg status` exits 1. */
18
+ export declare const HARD_CAP_BYTES = 5000000000;
19
+ //# sourceMappingURL=kg-caps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-caps.d.ts","sourceRoot":"","sources":["../../src/lib/kg-caps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,0HAA0H;AAC1H,eAAO,MAAM,cAAc,aAAgB,CAAC;AAE5C,yFAAyF;AACzF,eAAO,MAAM,cAAc,aAAgB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * kg-caps.ts — KG storage cap thresholds (single source of truth).
3
+ *
4
+ * Phase A1 follow-up (audit finding HIGH-1: drift): A1's `health-probes.ts`
5
+ * and the pre-existing `commands/kg-status.ts` were both hard-coding the
6
+ * 1.5 GB soft / 5 GB hard cap thresholds. With doctor + diagnose + kg-status
7
+ * as three consumers (A1 added consumer #2; A3 makes it #3 transitively),
8
+ * the plan's "third-consumer threshold" has arrived. Pin the constants here
9
+ * so any future cap-policy change touches one file.
10
+ *
11
+ * Drift contract: every consumer of these constants MUST import from this
12
+ * module, NOT redefine inline. A grep for `1_500_000_000` or `5_000_000_000`
13
+ * across `packages/cli/src/` should match only this file.
14
+ */
15
+ /** Soft warn threshold — 1.5 GB. Below this: silent. Above: doctor prints a "consider pruning" note but still exits 0. */
16
+ export const SOFT_CAP_BYTES = 1_500_000_000;
17
+ /** Hard fail threshold — 5 GB. At or above: doctor exits 1; `olam kg status` exits 1. */
18
+ export const HARD_CAP_BYTES = 5_000_000_000;
19
+ //# sourceMappingURL=kg-caps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-caps.js","sourceRoot":"","sources":["../../src/lib/kg-caps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,0HAA0H;AAC1H,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;AAE5C,yFAAyF;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.106",
3
+ "version": "0.1.108",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"