@pleri/olam-cli 0.1.143 → 0.1.145
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/commands/doctor.d.ts +53 -23
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +117 -46
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/logs.d.ts +17 -3
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +38 -35
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/memory/bridge.d.ts +57 -0
- package/dist/commands/memory/bridge.d.ts.map +1 -0
- package/dist/commands/memory/bridge.js +156 -0
- package/dist/commands/memory/bridge.js.map +1 -0
- package/dist/commands/memory/index.d.ts +3 -0
- package/dist/commands/memory/index.d.ts.map +1 -1
- package/dist/commands/memory/index.js +10 -1
- package/dist/commands/memory/index.js.map +1 -1
- package/dist/commands/memory/reclassify.d.ts +56 -0
- package/dist/commands/memory/reclassify.d.ts.map +1 -0
- package/dist/commands/memory/reclassify.js +177 -0
- package/dist/commands/memory/reclassify.js.map +1 -0
- package/dist/commands/memory/stats.d.ts +69 -0
- package/dist/commands/memory/stats.d.ts.map +1 -0
- package/dist/commands/memory/stats.js +164 -0
- package/dist/commands/memory/stats.js.map +1 -0
- package/dist/commands/skills-source.d.ts +12 -0
- package/dist/commands/skills-source.d.ts.map +1 -0
- package/dist/commands/skills-source.js +133 -0
- package/dist/commands/skills-source.js.map +1 -0
- package/dist/commands/skills.d.ts +11 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +163 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.d.ts +27 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +102 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade.d.ts +24 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +73 -0
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/image-digests.json +7 -7
- package/dist/index.js +2093 -538
- package/dist/index.js.map +1 -1
- package/dist/lib/health-probes.d.ts +72 -0
- package/dist/lib/health-probes.d.ts.map +1 -1
- package/dist/lib/health-probes.js +218 -0
- package/dist/lib/health-probes.js.map +1 -1
- package/dist/mcp-server.js +1248 -353
- package/host-cp/src/agent-runtime-trigger.mjs +262 -0
- package/host-cp/src/engine-identity.mjs +32 -0
- package/host-cp/src/server.mjs +246 -2
- package/package.json +1 -1
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* olam doctor — pass/fail host-health command.
|
|
3
3
|
*
|
|
4
|
-
* Phase A3 of olam-operator-onboarding-parity (
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
4
|
+
* Phase A3 of olam-operator-onboarding-parity (original 5 probes) +
|
|
5
|
+
* Phase C / C2 of olam-host-cp-k3s-prereqs (engine + colima probes).
|
|
6
|
+
*
|
|
7
|
+
* Probe layout — Decision 16 positional contract for `--json` consumers:
|
|
8
|
+
*
|
|
9
|
+
* On engine=docker (default):
|
|
10
|
+
* 1. docker daemon — probeDockerDaemon (fast-fail gate)
|
|
11
|
+
* 2. images — probeImagePresence (per-image)
|
|
12
|
+
* 3. host-cp /health — probeHostCpHealth
|
|
13
|
+
* 4. auth vault — probeAuthVault
|
|
14
|
+
* 5. KG storage — probeKgStorage
|
|
15
|
+
* 6. engine — probeEngine (NEW Phase C / C2)
|
|
16
|
+
* 7. colima version — probeColimaVersion (NEW Phase C / C2)
|
|
17
|
+
*
|
|
18
|
+
* On engine=kubernetes:
|
|
19
|
+
* 1. api server — probeK8sApiReachable (slot replaced)
|
|
20
|
+
* 2. images — probeK8sImagePresence (slot replaced)
|
|
21
|
+
* 3. host-cp /health — probeHostCpHealth (unchanged)
|
|
22
|
+
* 4. auth vault — probeAuthVault (unchanged)
|
|
23
|
+
* 5. KG storage — probeKgStorage (unchanged)
|
|
24
|
+
* 6. engine — probeEngine (NEW)
|
|
25
|
+
* 7. colima version — probeColimaVersion (NEW)
|
|
26
|
+
*
|
|
27
|
+
* The `--json` payload's `probes[]` indexes are stable across engine swap:
|
|
28
|
+
* consumers parsing `probes[0]` for "daemon-reachability" still see a
|
|
29
|
+
* daemon-reachability probe; consumers parsing `probes[5]` for engine
|
|
30
|
+
* identity see it regardless of which runtime is active.
|
|
31
|
+
*
|
|
32
|
+
* Exit code:
|
|
33
|
+
* - 0 on all PASS
|
|
34
|
+
* - 0 on PASS+WARN (WARN doesn't block — Colima 0.10.x is a hint)
|
|
35
|
+
* - 1 on any FAIL
|
|
36
|
+
*
|
|
37
|
+
* Output format:
|
|
38
|
+
* - `[PASS]` / `[WARN]` / `[FAIL]` prefix per row.
|
|
39
|
+
* - Indented detail under WARN/FAIL.
|
|
40
|
+
* - `--json` emits the same probe array (canonical positional shape).
|
|
21
41
|
*/
|
|
22
42
|
import type { Command } from 'commander';
|
|
23
43
|
import { type ProbeResult, type DockerExec, type FetchLike } from '../lib/health-probes.js';
|
|
@@ -32,6 +52,7 @@ interface DoctorReport {
|
|
|
32
52
|
readonly rows: ReadonlyArray<ProbeRow>;
|
|
33
53
|
readonly summary: 'OK' | 'FAILED';
|
|
34
54
|
readonly failureCount: number;
|
|
55
|
+
readonly warnCount: number;
|
|
35
56
|
}
|
|
36
57
|
export interface RunDoctorDeps {
|
|
37
58
|
readonly dockerExec?: DockerExec;
|
|
@@ -39,20 +60,29 @@ export interface RunDoctorDeps {
|
|
|
39
60
|
readonly olamHomeOverride?: string;
|
|
40
61
|
/** Override registry prefix used to derive registry-prefixed image refs. Defaults to ghcr.io/pleri. */
|
|
41
62
|
readonly registry?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Phase C / C2: explicit engine override. When omitted the engine is
|
|
65
|
+
* derived from `OLAM_HOST_CP_ENGINE` (falls back to 'docker'). Tests
|
|
66
|
+
* use this hook to exercise both index-stability paths without
|
|
67
|
+
* spinning up a real K8s cluster.
|
|
68
|
+
*/
|
|
69
|
+
readonly engine?: 'docker' | 'kubernetes';
|
|
42
70
|
}
|
|
43
71
|
interface RunResult {
|
|
44
72
|
readonly exitCode: number;
|
|
45
73
|
readonly report: DoctorReport;
|
|
46
74
|
}
|
|
47
75
|
/**
|
|
48
|
-
* Run
|
|
49
|
-
* If it fails, the remaining probes are SKIPPED — image
|
|
50
|
-
* against a paused daemon
|
|
51
|
-
*
|
|
52
|
-
* is "start Docker" (Risk T5 mitigation per plan).
|
|
76
|
+
* Run probes against the host. Probe-1 (daemon / API) runs FIRST + ALONE.
|
|
77
|
+
* If it fails, the remaining slot-1+2 probes are SKIPPED — image presence
|
|
78
|
+
* probes against a paused daemon / unreachable cluster return confusing
|
|
79
|
+
* errors that misdirect the operator's fix (Risk T5 mitigation per plan).
|
|
53
80
|
*
|
|
54
|
-
* On daemon-success,
|
|
81
|
+
* On daemon-success, probes 2-7 run in parallel via Promise.all
|
|
55
82
|
* (P1 budget: doctor < 2s on healthy host).
|
|
83
|
+
*
|
|
84
|
+
* Phase C / C2: engine-aware. When `engine=kubernetes` we substitute
|
|
85
|
+
* positions 1 + 2 in-place to preserve the positional `--json` contract.
|
|
56
86
|
*/
|
|
57
87
|
export declare function runDoctor(opts: DoctorOptions, deps?: RunDoctorDeps): Promise<RunResult>;
|
|
58
88
|
export declare function registerDoctor(program: Command): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAUL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,yBAAyB,CAAC;AAqCjC,UAAU,aAAa;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,QAAQ;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,uGAAuG;IACvG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;CAC3C;AAED,UAAU,SAAS;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,EACnB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,SAAS,CAAC,CAwDpB;AAiFD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYrD"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,25 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* olam doctor — pass/fail host-health command.
|
|
3
3
|
*
|
|
4
|
-
* Phase A3 of olam-operator-onboarding-parity (
|
|
5
|
-
*
|
|
4
|
+
* Phase A3 of olam-operator-onboarding-parity (original 5 probes) +
|
|
5
|
+
* Phase C / C2 of olam-host-cp-k3s-prereqs (engine + colima probes).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* 1. probeDockerDaemon — first; fast-fails before per-image probes
|
|
9
|
-
* (Risk T5 mitigation — paused-daemon false-positives on image probes)
|
|
10
|
-
* 2. probeImagePresence — checks 4 canonical images via docker image inspect
|
|
11
|
-
* 3. probeHostCpHealth — 5s timeout fetch on 127.0.0.1:19000/health
|
|
12
|
-
* 4. probeAuthVault — OLAM_HOME/auth/data.json; active non-cooled claude count
|
|
13
|
-
* 5. probeKgStorage — pristine + overlay enumeration; 1.5GB soft / 5GB hard
|
|
7
|
+
* Probe layout — Decision 16 positional contract for `--json` consumers:
|
|
14
8
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* On engine=docker (default):
|
|
10
|
+
* 1. docker daemon — probeDockerDaemon (fast-fail gate)
|
|
11
|
+
* 2. images — probeImagePresence (per-image)
|
|
12
|
+
* 3. host-cp /health — probeHostCpHealth
|
|
13
|
+
* 4. auth vault — probeAuthVault
|
|
14
|
+
* 5. KG storage — probeKgStorage
|
|
15
|
+
* 6. engine — probeEngine (NEW Phase C / C2)
|
|
16
|
+
* 7. colima version — probeColimaVersion (NEW Phase C / C2)
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* On engine=kubernetes:
|
|
19
|
+
* 1. api server — probeK8sApiReachable (slot replaced)
|
|
20
|
+
* 2. images — probeK8sImagePresence (slot replaced)
|
|
21
|
+
* 3. host-cp /health — probeHostCpHealth (unchanged)
|
|
22
|
+
* 4. auth vault — probeAuthVault (unchanged)
|
|
23
|
+
* 5. KG storage — probeKgStorage (unchanged)
|
|
24
|
+
* 6. engine — probeEngine (NEW)
|
|
25
|
+
* 7. colima version — probeColimaVersion (NEW)
|
|
26
|
+
*
|
|
27
|
+
* The `--json` payload's `probes[]` indexes are stable across engine swap:
|
|
28
|
+
* consumers parsing `probes[0]` for "daemon-reachability" still see a
|
|
29
|
+
* daemon-reachability probe; consumers parsing `probes[5]` for engine
|
|
30
|
+
* identity see it regardless of which runtime is active.
|
|
31
|
+
*
|
|
32
|
+
* Exit code:
|
|
33
|
+
* - 0 on all PASS
|
|
34
|
+
* - 0 on PASS+WARN (WARN doesn't block — Colima 0.10.x is a hint)
|
|
35
|
+
* - 1 on any FAIL
|
|
36
|
+
*
|
|
37
|
+
* Output format:
|
|
38
|
+
* - `[PASS]` / `[WARN]` / `[FAIL]` prefix per row.
|
|
39
|
+
* - Indented detail under WARN/FAIL.
|
|
40
|
+
* - `--json` emits the same probe array (canonical positional shape).
|
|
21
41
|
*/
|
|
22
|
-
import { probeDockerDaemon, probeImagePresence, probeHostCpHealth, probeAuthVault, probeKgStorage, } from '../lib/health-probes.js';
|
|
42
|
+
import { probeDockerDaemon, probeImagePresence, probeHostCpHealth, probeAuthVault, probeKgStorage, probeEngine, probeColimaVersion, probeK8sApiReachable, probeK8sImagePresence, } from '../lib/health-probes.js';
|
|
23
43
|
import { printError, printSuccess, printWarning, printHeader } from '../output.js';
|
|
24
44
|
/** Default registry prefix for registry-tagged images. Mirrors bootstrap.ts's default. */
|
|
25
45
|
const DEFAULT_REGISTRY = 'ghcr.io/pleri';
|
|
@@ -54,52 +74,96 @@ function buildRequiredImageRefs(registry) {
|
|
|
54
74
|
return refs;
|
|
55
75
|
}
|
|
56
76
|
/**
|
|
57
|
-
* Run
|
|
58
|
-
* If it fails, the remaining probes are SKIPPED — image
|
|
59
|
-
* against a paused daemon
|
|
60
|
-
*
|
|
61
|
-
* is "start Docker" (Risk T5 mitigation per plan).
|
|
77
|
+
* Run probes against the host. Probe-1 (daemon / API) runs FIRST + ALONE.
|
|
78
|
+
* If it fails, the remaining slot-1+2 probes are SKIPPED — image presence
|
|
79
|
+
* probes against a paused daemon / unreachable cluster return confusing
|
|
80
|
+
* errors that misdirect the operator's fix (Risk T5 mitigation per plan).
|
|
62
81
|
*
|
|
63
|
-
* On daemon-success,
|
|
82
|
+
* On daemon-success, probes 2-7 run in parallel via Promise.all
|
|
64
83
|
* (P1 budget: doctor < 2s on healthy host).
|
|
84
|
+
*
|
|
85
|
+
* Phase C / C2: engine-aware. When `engine=kubernetes` we substitute
|
|
86
|
+
* positions 1 + 2 in-place to preserve the positional `--json` contract.
|
|
65
87
|
*/
|
|
66
88
|
export async function runDoctor(opts, deps = {}) {
|
|
67
89
|
const dockerExec = deps.dockerExec;
|
|
68
90
|
const fetchImpl = deps.fetchImpl;
|
|
69
91
|
const olamHomeOverride = deps.olamHomeOverride;
|
|
70
92
|
const registry = deps.registry ?? DEFAULT_REGISTRY;
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
93
|
+
const engine = deps.engine ?? resolveEngineFromEnv();
|
|
94
|
+
const isK8s = engine === 'kubernetes';
|
|
95
|
+
// Slot 1: daemon / API reachability (fast-fail gate). Engine-aware.
|
|
96
|
+
const slot1Result = isK8s
|
|
97
|
+
? await probeK8sApiReachable(dockerExec)
|
|
98
|
+
: await probeDockerDaemon(dockerExec);
|
|
99
|
+
const slot1Name = isK8s ? 'api server' : 'docker daemon';
|
|
100
|
+
const rows = [{ name: slot1Name, result: slot1Result }];
|
|
101
|
+
if (!slot1Result.ok) {
|
|
102
|
+
// Fast-fail: skip per-image / host-cp / auth / kg probes when the
|
|
103
|
+
// engine's daemon-equivalent is down. Engine + colima probes still
|
|
104
|
+
// surface for diagnostic context, though, since they may hint at WHY
|
|
105
|
+
// the daemon is unreachable (e.g. Colima 0.10.x kubernetes-mode bug).
|
|
106
|
+
const [engineRes, colimaRes] = await Promise.all([
|
|
107
|
+
probeEngine(fetchImpl),
|
|
108
|
+
probeColimaVersion(dockerExec),
|
|
109
|
+
]);
|
|
110
|
+
rows.push({ name: 'engine', result: engineRes }, { name: 'colima version', result: colimaRes });
|
|
111
|
+
return emit(makeReport(rows), opts);
|
|
78
112
|
}
|
|
79
|
-
//
|
|
113
|
+
// Slots 2-7: parallel (independent; no shared state).
|
|
80
114
|
const imageRefs = buildRequiredImageRefs(registry);
|
|
81
|
-
const
|
|
82
|
-
|
|
115
|
+
const slot2Promise = isK8s
|
|
116
|
+
? probeK8sImagePresence(imageRefs, dockerExec)
|
|
117
|
+
: probeImagePresence(imageRefs, dockerExec);
|
|
118
|
+
const [imageResult, hostCpResult, authResult, kgResult, engineResult, colimaResult] = await Promise.all([
|
|
119
|
+
slot2Promise,
|
|
83
120
|
probeHostCpHealth(fetchImpl),
|
|
84
121
|
probeAuthVault(olamHomeOverride),
|
|
85
122
|
probeKgStorage(olamHomeOverride),
|
|
123
|
+
probeEngine(fetchImpl),
|
|
124
|
+
probeColimaVersion(dockerExec),
|
|
86
125
|
]);
|
|
87
|
-
rows.push({ name: 'images', result: imageResult }, { name: 'host-cp /health', result: hostCpResult }, { name: 'auth vault', result: authResult }, { name: 'KG storage', result: kgResult });
|
|
126
|
+
rows.push({ name: 'images', result: imageResult }, { name: 'host-cp /health', result: hostCpResult }, { name: 'auth vault', result: authResult }, { name: 'KG storage', result: kgResult }, { name: 'engine', result: engineResult }, { name: 'colima version', result: colimaResult });
|
|
127
|
+
return emit(makeReport(rows), opts);
|
|
128
|
+
}
|
|
129
|
+
function makeReport(rows) {
|
|
88
130
|
const failureCount = rows.filter((r) => !r.result.ok).length;
|
|
131
|
+
const warnCount = rows.filter((r) => isWarn(r.result)).length;
|
|
89
132
|
const summary = failureCount === 0 ? 'OK' : 'FAILED';
|
|
90
|
-
return
|
|
133
|
+
return { rows, summary, failureCount, warnCount };
|
|
134
|
+
}
|
|
135
|
+
function resolveEngineFromEnv() {
|
|
136
|
+
const explicit = process.env.OLAM_HOST_CP_ENGINE;
|
|
137
|
+
if (explicit === 'kubernetes')
|
|
138
|
+
return 'kubernetes';
|
|
139
|
+
if (explicit === 'docker')
|
|
140
|
+
return 'docker';
|
|
141
|
+
// Autodetect via KUBERNETES_SERVICE_HOST (matches resolveHostCpEngine).
|
|
142
|
+
return process.env.KUBERNETES_SERVICE_HOST ? 'kubernetes' : 'docker';
|
|
143
|
+
}
|
|
144
|
+
function isWarn(r) {
|
|
145
|
+
return r.ok === true && r.warn === true;
|
|
91
146
|
}
|
|
92
147
|
function emit(report, opts) {
|
|
93
148
|
if (opts.json) {
|
|
94
149
|
process.stdout.write(JSON.stringify({
|
|
95
150
|
summary: report.summary,
|
|
96
151
|
failureCount: report.failureCount,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
152
|
+
warnCount: report.warnCount,
|
|
153
|
+
probes: report.rows.map((r) => {
|
|
154
|
+
const isFail = !r.result.ok;
|
|
155
|
+
const warn = isWarn(r.result);
|
|
156
|
+
const base = {
|
|
157
|
+
name: r.name,
|
|
158
|
+
ok: r.result.ok,
|
|
159
|
+
message: r.result.message,
|
|
160
|
+
};
|
|
161
|
+
if (warn)
|
|
162
|
+
base.warn = true;
|
|
163
|
+
if (isFail || warn)
|
|
164
|
+
base.remedy = r.result.remedy;
|
|
165
|
+
return base;
|
|
166
|
+
}),
|
|
103
167
|
}, null, 2) + '\n');
|
|
104
168
|
}
|
|
105
169
|
else {
|
|
@@ -113,17 +177,24 @@ function renderHuman(report) {
|
|
|
113
177
|
const namePad = Math.max(...report.rows.map((r) => r.name.length));
|
|
114
178
|
for (const row of report.rows) {
|
|
115
179
|
const label = row.name.padEnd(namePad);
|
|
116
|
-
if (row.result
|
|
117
|
-
|
|
180
|
+
if (isWarn(row.result)) {
|
|
181
|
+
printWarning(`[WARN] ${label} ${row.result.message}`);
|
|
182
|
+
const remedy = row.result.remedy;
|
|
183
|
+
if (remedy)
|
|
184
|
+
printWarning(`${''.padEnd(namePad + 7)} remedy: ${remedy}`);
|
|
185
|
+
}
|
|
186
|
+
else if (row.result.ok) {
|
|
187
|
+
printSuccess(`[PASS] ${label} ${row.result.message}`);
|
|
118
188
|
}
|
|
119
189
|
else {
|
|
120
|
-
printError(
|
|
121
|
-
printWarning(`${''.padEnd(namePad)} remedy: ${row.result.remedy}`);
|
|
190
|
+
printError(`[FAIL] ${label} ${row.result.message}`);
|
|
191
|
+
printWarning(`${''.padEnd(namePad + 7)} remedy: ${row.result.remedy}`);
|
|
122
192
|
}
|
|
123
193
|
}
|
|
124
194
|
process.stdout.write('\n');
|
|
125
195
|
if (report.summary === 'OK') {
|
|
126
|
-
|
|
196
|
+
const warnNote = report.warnCount > 0 ? ` (${report.warnCount} warn)` : '';
|
|
197
|
+
printSuccess(`OK — all ${report.rows.length} probes green${warnNote}`);
|
|
127
198
|
}
|
|
128
199
|
else {
|
|
129
200
|
printError(`FAILED — ${report.failureCount} of ${report.rows.length} probes failed`);
|
|
@@ -132,8 +203,8 @@ function renderHuman(report) {
|
|
|
132
203
|
export function registerDoctor(program) {
|
|
133
204
|
program
|
|
134
205
|
.command('doctor')
|
|
135
|
-
.description('Pass/fail host-health check. Exits 0 on a healthy host; 1 on any
|
|
136
|
-
+ 'Runs
|
|
206
|
+
.description('Pass/fail host-health check. Exits 0 on a healthy host (including WARN-only); 1 on any FAIL probe. '
|
|
207
|
+
+ 'Runs daemon / image / host-cp /health / auth / KG / engine / colima probes (7 total).')
|
|
137
208
|
.option('--json', 'emit the report as JSON instead of a human-readable table')
|
|
138
209
|
.action(async (opts) => {
|
|
139
210
|
const r = await runDoctor(opts);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/logs.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* olam logs <world> — Stream application logs from a world.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Phase C / C1 (engine-aware): on invocation, fetches /health to read the
|
|
5
|
+
* X-Olam-Engine header, then streams from `GET /v1/worlds/<id>/logs` on
|
|
6
|
+
* host-cp which delegates to the active ContainerEngine (Docker | K8s).
|
|
7
|
+
* Output is engine-agnostic newline-delimited:
|
|
8
|
+
* `<ISO timestamp> <pod-or-container>/<container> <line>`
|
|
9
|
+
*
|
|
10
|
+
* Pre-C the command consumed the per-world CP's /api/logs SSE channel via
|
|
11
|
+
* the host-cp proxy. That code path stays alive elsewhere in the codebase
|
|
12
|
+
* (per-world CP still serves the SSE stream) but olam-cli no longer calls
|
|
13
|
+
* it — revert this commit and the old behavior comes back wholesale.
|
|
6
14
|
*
|
|
7
15
|
* Options:
|
|
8
|
-
* --service <name> Stream a single
|
|
16
|
+
* --service <name> Stream a single container (K8s) / pass-through (Docker)
|
|
9
17
|
* --follow Stream indefinitely until Ctrl-C (default: false)
|
|
10
18
|
* --tail <n> Lines to show before exiting (default: 200)
|
|
11
19
|
*/
|
|
@@ -33,6 +41,12 @@ interface SseLine {
|
|
|
33
41
|
}
|
|
34
42
|
type SseEvent = SseReplay | SseLine;
|
|
35
43
|
export declare function parseSseEvent(raw: string): SseEvent | null;
|
|
44
|
+
export interface LogsRequestOpts {
|
|
45
|
+
readonly tail: number;
|
|
46
|
+
readonly follow: boolean;
|
|
47
|
+
readonly service?: string;
|
|
48
|
+
}
|
|
49
|
+
export declare function buildLogsUrl(worldId: string, opts: LogsRequestOpts, port?: number): string;
|
|
36
50
|
export declare function registerLogs(program: Command): void;
|
|
37
51
|
export {};
|
|
38
52
|
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAGlG;AAQD,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,KAAK,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAY1D;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CAOxG;AAMD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuGnD"}
|
package/dist/commands/logs.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* olam logs <world> — Stream application logs from a world.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Phase C / C1 (engine-aware): on invocation, fetches /health to read the
|
|
5
|
+
* X-Olam-Engine header, then streams from `GET /v1/worlds/<id>/logs` on
|
|
6
|
+
* host-cp which delegates to the active ContainerEngine (Docker | K8s).
|
|
7
|
+
* Output is engine-agnostic newline-delimited:
|
|
8
|
+
* `<ISO timestamp> <pod-or-container>/<container> <line>`
|
|
9
|
+
*
|
|
10
|
+
* Pre-C the command consumed the per-world CP's /api/logs SSE channel via
|
|
11
|
+
* the host-cp proxy. That code path stays alive elsewhere in the codebase
|
|
12
|
+
* (per-world CP still serves the SSE stream) but olam-cli no longer calls
|
|
13
|
+
* it — revert this commit and the old behavior comes back wholesale.
|
|
6
14
|
*
|
|
7
15
|
* Options:
|
|
8
|
-
* --service <name> Stream a single
|
|
16
|
+
* --service <name> Stream a single container (K8s) / pass-through (Docker)
|
|
9
17
|
* --follow Stream indefinitely until Ctrl-C (default: false)
|
|
10
18
|
* --tail <n> Lines to show before exiting (default: 200)
|
|
11
19
|
*/
|
|
@@ -57,15 +65,24 @@ export function parseSseEvent(raw) {
|
|
|
57
65
|
return null;
|
|
58
66
|
}
|
|
59
67
|
}
|
|
68
|
+
export function buildLogsUrl(worldId, opts, port = HOST_CP_PORT) {
|
|
69
|
+
const qs = new URLSearchParams({
|
|
70
|
+
tail: String(opts.tail),
|
|
71
|
+
follow: opts.follow ? '1' : '0',
|
|
72
|
+
});
|
|
73
|
+
if (opts.service)
|
|
74
|
+
qs.set('service', opts.service);
|
|
75
|
+
return `http://127.0.0.1:${port}/v1/worlds/${encodeURIComponent(worldId)}/logs?${qs.toString()}`;
|
|
76
|
+
}
|
|
60
77
|
// ---------------------------------------------------------------------------
|
|
61
78
|
// Command registration
|
|
62
79
|
// ---------------------------------------------------------------------------
|
|
63
80
|
export function registerLogs(program) {
|
|
64
81
|
program
|
|
65
82
|
.command('logs')
|
|
66
|
-
.description('Stream application logs from a world')
|
|
83
|
+
.description('Stream application logs from a world (engine-agnostic)')
|
|
67
84
|
.argument('<world>', 'World ID')
|
|
68
|
-
.option('--service <name>', 'Stream a specific
|
|
85
|
+
.option('--service <name>', 'Stream a specific container within the world')
|
|
69
86
|
.option('--follow', 'Stream indefinitely until Ctrl-C', false)
|
|
70
87
|
.option('--tail <n>', 'Number of lines to display before exiting', '200')
|
|
71
88
|
.action(async (worldId, opts) => {
|
|
@@ -88,12 +105,11 @@ export function registerLogs(program) {
|
|
|
88
105
|
return;
|
|
89
106
|
}
|
|
90
107
|
const tailLimit = Math.max(1, parseInt(opts.tail, 10) || 200);
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
:
|
|
95
|
-
|
|
96
|
-
let lineCount = 0;
|
|
108
|
+
const url = buildLogsUrl(worldId, {
|
|
109
|
+
tail: tailLimit,
|
|
110
|
+
follow: opts.follow,
|
|
111
|
+
...(opts.service ? { service: opts.service } : {}),
|
|
112
|
+
});
|
|
97
113
|
let done = false;
|
|
98
114
|
let resolveStream;
|
|
99
115
|
const streamDone = new Promise((r) => { resolveStream = r; });
|
|
@@ -103,15 +119,6 @@ export function registerLogs(program) {
|
|
|
103
119
|
resolveStream();
|
|
104
120
|
}
|
|
105
121
|
};
|
|
106
|
-
const emit = (line, service) => {
|
|
107
|
-
process.stdout.write(formatLine(line, service, showService) + '\n');
|
|
108
|
-
lineCount++;
|
|
109
|
-
if (!opts.follow && lineCount >= tailLimit) {
|
|
110
|
-
finish();
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
};
|
|
115
122
|
const req = http.get(url, { headers: { Authorization: `Bearer ${token}` } }, (res) => {
|
|
116
123
|
if (res.statusCode !== 200) {
|
|
117
124
|
printError(`Log stream returned HTTP ${res.statusCode ?? 'unknown'}`);
|
|
@@ -120,6 +127,10 @@ export function registerLogs(program) {
|
|
|
120
127
|
res.destroy();
|
|
121
128
|
return;
|
|
122
129
|
}
|
|
130
|
+
// Server emits one canonical line per record:
|
|
131
|
+
// `<ts> <pod>/<container> <line>\n`
|
|
132
|
+
// We pass the line through `colorLine` for level-based coloring
|
|
133
|
+
// and write to stdout verbatim. No SSE framing on the new path.
|
|
123
134
|
let buf = '';
|
|
124
135
|
res.on('data', (chunk) => {
|
|
125
136
|
if (done)
|
|
@@ -130,24 +141,16 @@ export function registerLogs(program) {
|
|
|
130
141
|
for (const raw of rawLines) {
|
|
131
142
|
if (done)
|
|
132
143
|
break;
|
|
133
|
-
|
|
134
|
-
if (!ev)
|
|
144
|
+
if (!raw)
|
|
135
145
|
continue;
|
|
136
|
-
|
|
137
|
-
for (const l of ev.lines) {
|
|
138
|
-
if (!emit(l, ev.service)) {
|
|
139
|
-
req.destroy();
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else if (ev.type === 'line') {
|
|
145
|
-
if (!emit(ev.line, ev.service))
|
|
146
|
-
req.destroy();
|
|
147
|
-
}
|
|
146
|
+
process.stdout.write(colorLine(raw) + '\n');
|
|
148
147
|
}
|
|
149
148
|
});
|
|
150
|
-
res.on('end', () =>
|
|
149
|
+
res.on('end', () => {
|
|
150
|
+
if (buf)
|
|
151
|
+
process.stdout.write(colorLine(buf) + '\n');
|
|
152
|
+
finish();
|
|
153
|
+
});
|
|
151
154
|
res.on('error', (err) => {
|
|
152
155
|
if (!done)
|
|
153
156
|
printError(`Stream error: ${err.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory bridge serve --local — embedded Miniflare bridge.
|
|
3
|
+
*
|
|
4
|
+
* `wrangler dev` is a dev iteration loop, not a production-style host
|
|
5
|
+
* for a long-lived service. This subcommand spawns
|
|
6
|
+
* `packages/memory-service/scripts/local-bridge-server.mjs` as a
|
|
7
|
+
* foreground Node process: operators wire it into launchd / systemd
|
|
8
|
+
* (Type=simple) and get the agent-memory bridge running on their
|
|
9
|
+
* laptop without a Cloudflare account.
|
|
10
|
+
*
|
|
11
|
+
* Flow:
|
|
12
|
+
* 1. Resolve packages/memory-service/ via the shared candidates list
|
|
13
|
+
* (handles workspace / bundled-CLI / cwd-checkout layouts).
|
|
14
|
+
* 2. Locate scripts/local-bridge-server.mjs inside it.
|
|
15
|
+
* 3. Ensure ~/.olam/memory-secret (0600) exists; pass it via
|
|
16
|
+
* AGENTMEMORY_SECRET env so the bridge can authenticate
|
|
17
|
+
* /bridge/stats callers without leaking the secret on argv.
|
|
18
|
+
* 4. Spawn the .mjs in foreground; stdin/stdout/stderr propagate so
|
|
19
|
+
* the service-manager journal captures the bridge's logs.
|
|
20
|
+
* 5. Forward SIGTERM/SIGINT to the child + exit with its code.
|
|
21
|
+
*
|
|
22
|
+
* Mirrors `start.ts`'s service-resolution + secret-handling pattern;
|
|
23
|
+
* differs in that the spawned process stays in foreground (start.ts
|
|
24
|
+
* detaches because the agentmemory engine is a separate long-lived
|
|
25
|
+
* service).
|
|
26
|
+
*
|
|
27
|
+
* Plan reference: architecture conversation in PR #612.
|
|
28
|
+
*/
|
|
29
|
+
import type { Command } from 'commander';
|
|
30
|
+
import { type ChildProcess } from 'node:child_process';
|
|
31
|
+
export interface BridgeServeOpts {
|
|
32
|
+
/** TCP port to bind on. Defaults to 8788. */
|
|
33
|
+
port?: number;
|
|
34
|
+
/** DO SQLite persistence directory. Default is in-memory (lost on restart). */
|
|
35
|
+
persistTo?: string;
|
|
36
|
+
/** Required for forward-compat with future `--cloud` / `--remote` flags. */
|
|
37
|
+
local?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** Test seam — runtime injection of the spawn path resolution + child factory. */
|
|
40
|
+
export interface BridgeDeps {
|
|
41
|
+
/** Override the memory-service directory lookup (testing). */
|
|
42
|
+
resolveServiceDir?: () => string;
|
|
43
|
+
/** Override the secret-resolver (testing). */
|
|
44
|
+
ensureSecret?: () => string;
|
|
45
|
+
/** Override the spawn entry point (testing). */
|
|
46
|
+
spawnChild?: (command: string, args: readonly string[], env: NodeJS.ProcessEnv) => ChildProcess;
|
|
47
|
+
}
|
|
48
|
+
export declare function resolveMemoryServiceDir(): string;
|
|
49
|
+
export declare function resolveLocalBridgeScript(serviceDir: string): string;
|
|
50
|
+
export declare function validateBridgeOpts(opts: BridgeServeOpts): {
|
|
51
|
+
port: number;
|
|
52
|
+
persistTo?: string;
|
|
53
|
+
local: boolean;
|
|
54
|
+
};
|
|
55
|
+
export declare function runBridgeServe(opts: BridgeServeOpts, deps?: BridgeDeps): Promise<number>;
|
|
56
|
+
export declare function registerMemoryBridge(cmd: Command): void;
|
|
57
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAS9D,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;IACjC,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,gDAAgD;IAChD,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,YAAY,CAAC;CACnB;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAQhD;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB,CAoBA;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,eAAe,EACrB,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CAsEjB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAsBvD"}
|