@pleri/olam-cli 0.1.55 → 0.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/__tests__/services.test.d.ts +8 -0
  2. package/dist/__tests__/services.test.d.ts.map +1 -0
  3. package/dist/__tests__/services.test.js +185 -0
  4. package/dist/__tests__/services.test.js.map +1 -0
  5. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts +6 -0
  6. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts.map +1 -0
  7. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js +26 -0
  8. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js.map +1 -0
  9. package/dist/commands/__tests__/upgrade.all-three.test.js +1 -13
  10. package/dist/commands/__tests__/upgrade.all-three.test.js.map +1 -1
  11. package/dist/commands/__tests__/upgrade.compose-path.test.js +1 -13
  12. package/dist/commands/__tests__/upgrade.compose-path.test.js.map +1 -1
  13. package/dist/commands/__tests__/upgrade.olam-tag.test.js +1 -14
  14. package/dist/commands/__tests__/upgrade.olam-tag.test.js.map +1 -1
  15. package/dist/commands/__tests__/upgrade.recreate.test.js +1 -13
  16. package/dist/commands/__tests__/upgrade.recreate.test.js.map +1 -1
  17. package/dist/commands/__tests__/upgrade.rollback.test.js +1 -21
  18. package/dist/commands/__tests__/upgrade.rollback.test.js.map +1 -1
  19. package/dist/commands/__tests__/upgrade.smoke.test.js +9 -23
  20. package/dist/commands/__tests__/upgrade.smoke.test.js.map +1 -1
  21. package/dist/commands/__tests__/upgrade.swap.test.js +1 -22
  22. package/dist/commands/__tests__/upgrade.swap.test.js.map +1 -1
  23. package/dist/commands/auth.d.ts.map +1 -1
  24. package/dist/commands/auth.js +15 -38
  25. package/dist/commands/auth.js.map +1 -1
  26. package/dist/commands/bootstrap.d.ts +2 -0
  27. package/dist/commands/bootstrap.d.ts.map +1 -1
  28. package/dist/commands/bootstrap.js +3 -3
  29. package/dist/commands/bootstrap.js.map +1 -1
  30. package/dist/commands/create.d.ts.map +1 -1
  31. package/dist/commands/create.js +1 -9
  32. package/dist/commands/create.js.map +1 -1
  33. package/dist/commands/services.d.ts +39 -0
  34. package/dist/commands/services.d.ts.map +1 -0
  35. package/dist/commands/services.js +220 -0
  36. package/dist/commands/services.js.map +1 -0
  37. package/dist/commands/upgrade.d.ts +11 -12
  38. package/dist/commands/upgrade.d.ts.map +1 -1
  39. package/dist/commands/upgrade.js +81 -6
  40. package/dist/commands/upgrade.js.map +1 -1
  41. package/dist/image-digests.json +4 -3
  42. package/dist/index.js +1013 -1029
  43. package/dist/index.js.map +1 -1
  44. package/dist/mcp-server.js +310 -372
  45. package/package.json +1 -1
@@ -0,0 +1,220 @@
1
+ /**
2
+ * `olam services` — umbrella verb for managing Olam service containers.
3
+ *
4
+ * Subcommands:
5
+ * olam services up — start olam-auth + olam-mcp-auth (idempotent)
6
+ * olam services down — stop both containers
7
+ * olam services status — show state of both containers
8
+ *
9
+ * `olam auth up/down/status` delegates here with a deprecation warning.
10
+ */
11
+ import { execFileSync, spawnSync } from 'node:child_process';
12
+ import pc from 'picocolors';
13
+ import { AuthContainerController } from '@olam/core/src/auth/index.js';
14
+ import { printError, printHeader, printInfo, printSuccess, printWarning } from '../output.js';
15
+ // ── McpAuthContainerController ────────────────────────────────────
16
+ //
17
+ // Mirrors AuthContainerController (packages/core/src/auth/container.ts).
18
+ // mcp-auth-service is not a @olam/core package, so the controller lives
19
+ // here in the CLI layer.
20
+ const MCP_AUTH_PORT = 9998;
21
+ const MCP_AUTH_VOLUME = 'olam-mcp-auth-data';
22
+ const MCP_AUTH_CONTAINER = 'olam-mcp-auth';
23
+ const MCP_AUTH_LOCAL_TAG = 'olam-mcp-auth:local';
24
+ const MCP_AUTH_PUBLISHED_TAG = 'ghcr.io/pleri/olam-mcp-auth:latest';
25
+ const MCP_AUTH_HEALTH_URL = `http://127.0.0.1:${MCP_AUTH_PORT}/health`;
26
+ const MCP_AUTH_HEALTH_TIMEOUT_MS = 15_000;
27
+ export class McpAuthContainerController {
28
+ imageTag = MCP_AUTH_LOCAL_TAG;
29
+ status() {
30
+ const r = spawnSync('docker', ['inspect', '--format', '{{.State.Status}}|{{.Id}}', MCP_AUTH_CONTAINER], { encoding: 'utf-8' });
31
+ if (r.status === 0) {
32
+ const [stateRaw, id] = r.stdout.trim().split('|');
33
+ return {
34
+ state: stateRaw === 'running' ? 'running' : 'stopped',
35
+ port: MCP_AUTH_PORT,
36
+ containerId: id,
37
+ };
38
+ }
39
+ return { state: 'missing', port: MCP_AUTH_PORT };
40
+ }
41
+ imageExists(tag = this.imageTag) {
42
+ return spawnSync('docker', ['image', 'inspect', tag], { encoding: 'utf-8' }).status === 0;
43
+ }
44
+ start() {
45
+ const current = this.status();
46
+ if (current.state === 'running')
47
+ return;
48
+ if (current.state === 'stopped') {
49
+ execFileSync('docker', ['start', MCP_AUTH_CONTAINER], { stdio: 'pipe' });
50
+ return;
51
+ }
52
+ if (!this.imageExists()) {
53
+ if (this.imageTag !== MCP_AUTH_PUBLISHED_TAG && this.imageExists(MCP_AUTH_PUBLISHED_TAG)) {
54
+ this.imageTag = MCP_AUTH_PUBLISHED_TAG;
55
+ }
56
+ else {
57
+ throw new Error(`mcp-auth image '${this.imageTag}' not found locally. ` +
58
+ 'Run `olam bootstrap` to pull the published image.');
59
+ }
60
+ }
61
+ execFileSync('docker', [
62
+ 'run',
63
+ '--detach',
64
+ '--name', MCP_AUTH_CONTAINER,
65
+ '--restart', 'unless-stopped',
66
+ '--publish', `${MCP_AUTH_PORT}:${MCP_AUTH_PORT}`,
67
+ '--volume', `${MCP_AUTH_VOLUME}:/mcp-auth-data`,
68
+ this.imageTag,
69
+ ], { stdio: 'pipe' });
70
+ }
71
+ stop() {
72
+ const current = this.status();
73
+ if (current.state !== 'running')
74
+ return;
75
+ execFileSync('docker', ['stop', MCP_AUTH_CONTAINER], { stdio: 'pipe' });
76
+ }
77
+ remove() {
78
+ spawnSync('docker', ['rm', '-f', MCP_AUTH_CONTAINER], { stdio: 'pipe' });
79
+ }
80
+ async waitForReady(timeoutMs = MCP_AUTH_HEALTH_TIMEOUT_MS) {
81
+ const deadline = Date.now() + timeoutMs;
82
+ while (Date.now() < deadline) {
83
+ try {
84
+ const res = await fetch(MCP_AUTH_HEALTH_URL, { signal: AbortSignal.timeout(1_500) });
85
+ if (res.ok)
86
+ return true;
87
+ }
88
+ catch {
89
+ // not ready yet
90
+ }
91
+ await sleep(500);
92
+ }
93
+ return false;
94
+ }
95
+ }
96
+ function sleep(ms) {
97
+ return new Promise((resolve) => setTimeout(resolve, ms));
98
+ }
99
+ // ── Services orchestration ────────────────────────────────────────
100
+ /** Start both auth containers, idempotent. */
101
+ export async function servicesUp() {
102
+ const auth = new AuthContainerController();
103
+ const mcpAuth = new McpAuthContainerController();
104
+ // Start olam-auth
105
+ const authStatus = auth.status();
106
+ if (authStatus.state === 'running') {
107
+ printSuccess(`olam-auth already running on :${authStatus.port}`);
108
+ }
109
+ else {
110
+ try {
111
+ auth.start();
112
+ }
113
+ catch (err) {
114
+ printError(`olam-auth failed to start: ${err instanceof Error ? err.message : String(err)}`);
115
+ return { exitCode: 1 };
116
+ }
117
+ const ready = await auth.waitForReady(15_000);
118
+ if (!ready) {
119
+ printWarning('olam-auth started but /health did not respond within 15s.');
120
+ return { exitCode: 1 };
121
+ }
122
+ printSuccess('olam-auth started');
123
+ }
124
+ // Start olam-mcp-auth
125
+ const mcpStatus = mcpAuth.status();
126
+ if (mcpStatus.state === 'running') {
127
+ printSuccess(`olam-mcp-auth already running on :${mcpStatus.port}`);
128
+ }
129
+ else {
130
+ try {
131
+ mcpAuth.start();
132
+ }
133
+ catch (err) {
134
+ printError(`olam-mcp-auth failed to start: ${err instanceof Error ? err.message : String(err)}`);
135
+ return { exitCode: 1 };
136
+ }
137
+ const ready = await mcpAuth.waitForReady();
138
+ if (!ready) {
139
+ printWarning('olam-mcp-auth started but /health did not respond within 15s.');
140
+ return { exitCode: 1 };
141
+ }
142
+ printSuccess('olam-mcp-auth started');
143
+ }
144
+ printHeader('Services up');
145
+ printInfo('olam-auth', ':9999');
146
+ printInfo('olam-mcp-auth', ':9998');
147
+ return { exitCode: 0 };
148
+ }
149
+ /** Stop both auth containers. */
150
+ export function servicesDown() {
151
+ const auth = new AuthContainerController();
152
+ const mcpAuth = new McpAuthContainerController();
153
+ let exitCode = 0;
154
+ try {
155
+ auth.stop();
156
+ printSuccess('olam-auth stopped.');
157
+ }
158
+ catch (err) {
159
+ printError(`olam-auth: ${err instanceof Error ? err.message : String(err)}`);
160
+ exitCode = 1;
161
+ }
162
+ try {
163
+ mcpAuth.stop();
164
+ printSuccess('olam-mcp-auth stopped.');
165
+ }
166
+ catch (err) {
167
+ printError(`olam-mcp-auth: ${err instanceof Error ? err.message : String(err)}`);
168
+ exitCode = 1;
169
+ }
170
+ return { exitCode };
171
+ }
172
+ /** Show container state for both services. */
173
+ export function servicesStatus() {
174
+ const auth = new AuthContainerController();
175
+ const mcpAuth = new McpAuthContainerController();
176
+ printHeader('Services status');
177
+ const authState = auth.status();
178
+ const authStateStr = authState.state === 'running'
179
+ ? pc.green('running')
180
+ : authState.state === 'stopped'
181
+ ? pc.yellow('stopped')
182
+ : pc.red('missing');
183
+ printInfo('olam-auth', `${authStateStr} :${authState.port}`);
184
+ const mcpState = mcpAuth.status();
185
+ const mcpStateStr = mcpState.state === 'running'
186
+ ? pc.green('running')
187
+ : mcpState.state === 'stopped'
188
+ ? pc.yellow('stopped')
189
+ : pc.red('missing');
190
+ printInfo('olam-mcp-auth', `${mcpStateStr} :${mcpState.port}`);
191
+ }
192
+ // ── Commander registration ────────────────────────────────────────
193
+ export function registerServices(program) {
194
+ const services = program
195
+ .command('services')
196
+ .description('Manage Olam service containers (olam-auth, olam-mcp-auth)');
197
+ services
198
+ .command('up')
199
+ .description('Start all service containers (idempotent)')
200
+ .action(async () => {
201
+ const result = await servicesUp();
202
+ if (result.exitCode !== 0)
203
+ process.exitCode = result.exitCode;
204
+ });
205
+ services
206
+ .command('down')
207
+ .description('Stop all service containers')
208
+ .action(() => {
209
+ const result = servicesDown();
210
+ if (result.exitCode !== 0)
211
+ process.exitCode = result.exitCode;
212
+ });
213
+ services
214
+ .command('status')
215
+ .description('Show state of all service containers')
216
+ .action(() => {
217
+ servicesStatus();
218
+ });
219
+ }
220
+ //# sourceMappingURL=services.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/commands/services.ts"],"names":[],"mappings":"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"}
@@ -144,18 +144,6 @@ export interface SmokeResult {
144
144
  readonly bakedSha: string | null;
145
145
  readonly error?: string;
146
146
  }
147
- /**
148
- * Run docker create + docker inspect for a single image.
149
- *
150
- * Returns ok=true when:
151
- * - `docker create <image>` exits 0 (image manifest valid, layers downloadable).
152
- * - `docker inspect <image> --format '{{index .Config.Labels "olam.build.sha"}}'`
153
- * returns the expected `targetSha`.
154
- *
155
- * The container created by `docker create` is removed via `docker rm` even on
156
- * failure paths (best-effort cleanup; orphans are harmless and pruned by the
157
- * daemon's GC eventually).
158
- */
159
147
  export declare function smokeImage(image: string, targetSha: string): SmokeResult;
160
148
  /**
161
149
  * Per-image swap mapping (Phase 2a — A6).
@@ -383,6 +371,17 @@ export interface UpgradePullDeps {
383
371
  ok: boolean;
384
372
  error?: string;
385
373
  }>;
374
+ /**
375
+ * mcp-auth-service recreate driver. Default: stop + rm + start the
376
+ * mcp-auth container. Only invoked when the mcp-auth digest is present
377
+ * in the digests manifest — older tarballs without the entry skip this
378
+ * step entirely (tracker test "exits 0 and skips mcp-auth recreate when
379
+ * digest absent"). Tests inject a stub.
380
+ */
381
+ readonly recreateMcpAuth?: () => Promise<{
382
+ ok: boolean;
383
+ error?: string;
384
+ }>;
386
385
  /**
387
386
  * Path to packages/host-cp/compose.yaml. Defaults to findComposeFile()
388
387
  * (bundled path first, then monorepo cwd fallbacks).
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAaxB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAaxD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE;IAAE,WAAW,EAAE,OAAO,CAAA;CAAE,EAC9B,GAAG,EAAE,MAAM,GACV;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAQlD;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAWzF;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IACpC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,WAAW,CAqBd;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE;AAuDD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWzD;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,IAAI,CAInF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAuBD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAmExE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,QAAQ,CAIxD,CAAC;AAEF,0CAA0C;AAC1C,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAiBvE;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,UAAU,CA2E3E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG;IAClE,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB,CAeA;AA8BD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3G,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;IAChH,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3G,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,SAAS,EAClB,cAAc,SAAQ,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAAC,CAyBjE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GAAG,IAAI,GAC/B,MAAM,CAYR;AAoGD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CACxB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC7B;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClF;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAgN5B;AAstBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuFtD"}
@@ -221,11 +221,20 @@ export function checkRollbackSetExists(plan) {
221
221
  * failure paths (best-effort cleanup; orphans are harmless and pruned by the
222
222
  * daemon's GC eventually).
223
223
  */
224
+ // Cap each docker shellout. The smoke path expects the image to already
225
+ // be present locally (post-pull), so docker create / inspect / rm are
226
+ // sub-second on the happy path. The cap protects two real-world hangs:
227
+ // (1) a wedged dockerd not responding, and (2) a missing image where
228
+ // docker tries to pull from Docker Hub and the registry's 404 is slow
229
+ // enough to blow vitest's default test budget. 30s is generous for the
230
+ // happy path and bounded enough for production callers.
231
+ const SMOKE_DOCKER_TIMEOUT_MS = 30_000;
224
232
  export function smokeImage(image, targetSha) {
225
233
  // 1. docker create — allocates the container; doesn't start the entrypoint.
226
234
  const createResult = spawnSync('docker', ['create', '--name', `olam-smoke-${Date.now()}`, image], {
227
235
  encoding: 'utf-8',
228
236
  stdio: ['ignore', 'pipe', 'pipe'],
237
+ timeout: SMOKE_DOCKER_TIMEOUT_MS,
229
238
  });
230
239
  if (createResult.status !== 0) {
231
240
  return {
@@ -240,12 +249,14 @@ export function smokeImage(image, targetSha) {
240
249
  const inspectResult = spawnSync('docker', ['inspect', '--format', '{{index .Config.Labels "olam.build.sha"}}', image], {
241
250
  encoding: 'utf-8',
242
251
  stdio: ['ignore', 'pipe', 'pipe'],
252
+ timeout: SMOKE_DOCKER_TIMEOUT_MS,
243
253
  });
244
254
  // 3. Cleanup — best-effort; ignore exit code.
245
255
  if (containerId.length > 0) {
246
256
  spawnSync('docker', ['rm', '-f', containerId], {
247
257
  encoding: 'utf-8',
248
258
  stdio: ['ignore', 'ignore', 'ignore'],
259
+ timeout: SMOKE_DOCKER_TIMEOUT_MS,
249
260
  });
250
261
  }
251
262
  if (inspectResult.status !== 0) {
@@ -658,13 +669,23 @@ export async function runUpgradePullByDigest(deps = {}) {
658
669
  return { exitCode: EXIT_GENERIC_ERROR, summary: 'docker daemon not reachable' };
659
670
  }
660
671
  infoSpinner.succeed('docker daemon reachable');
661
- // Step 2 — parallel pull all 3 images by digest.
662
- const imageRefs = [
672
+ // Step 2 — parallel pull images by digest. mcp-auth is conditional on
673
+ // the digest being present in the manifest (older tarballs don't have
674
+ // it; pre-mcp-auth releases shipped 3 images, post-mcp-auth ship 4).
675
+ const hasMcpAuthDigest = typeof digests['mcp-auth'] === 'string' && digests['mcp-auth'].length > 0;
676
+ const baseRefs = [
663
677
  { name: 'host-cp', ref: `${registry}/olam-host-cp@${digests['host-cp']}` },
664
678
  { name: 'auth', ref: `${registry}/olam-auth@${digests.auth}` },
665
679
  { name: 'devbox', ref: `${registry}/olam-devbox@${digests.devbox}` },
666
680
  ];
667
- const pullSpinner = ora('Pulling images (3 parallel)').start();
681
+ if (hasMcpAuthDigest) {
682
+ baseRefs.push({
683
+ name: 'mcp-auth',
684
+ ref: `${registry}/olam-mcp-auth@${digests['mcp-auth']}`,
685
+ });
686
+ }
687
+ const imageRefs = baseRefs;
688
+ const pullSpinner = ora(`Pulling images (${imageRefs.length} parallel)`).start();
668
689
  const pullStart = Date.now();
669
690
  const pullResults = await Promise.all(imageRefs.map(async ({ name, ref }) => ({
670
691
  name,
@@ -687,7 +708,7 @@ export async function runUpgradePullByDigest(deps = {}) {
687
708
  summary: `pull failed: ${failed.map((r) => r.name).join(', ')}`,
688
709
  };
689
710
  }
690
- pullSpinner.succeed(`Pulled 3 images in ${pullElapsed}s`);
711
+ pullSpinner.succeed(`Pulled ${imageRefs.length} images in ${pullElapsed}s`);
691
712
  // Step 3 — protocol-version handshake on every image.
692
713
  const handshakeSpinner = ora('Verifying olam.protocol.versions handshake').start();
693
714
  for (const { name, ref } of imageRefs) {
@@ -709,7 +730,7 @@ export async function runUpgradePullByDigest(deps = {}) {
709
730
  };
710
731
  }
711
732
  }
712
- handshakeSpinner.succeed('Protocol handshake passed (all 3 images)');
733
+ handshakeSpinner.succeed(`Protocol handshake passed (all ${imageRefs.length} images)`);
713
734
  // Step 4 — re-tag pulled-by-digest images to the canonical local tags
714
735
  // that compose.yaml + AuthContainerController expect. Pulling by
715
736
  // digest only writes a content-addressed reference; compose / the
@@ -729,7 +750,7 @@ export async function runUpgradePullByDigest(deps = {}) {
729
750
  // Fix: retag BOTH names. The bare-name tag is kept for legacy callers
730
751
  // (e.g. `docker run olam-host-cp:latest` in scripts); the registry-
731
752
  // prefixed tag is what compose + AuthContainerController actually use.
732
- const tagPlan = [
753
+ const tagPlanBase = [
733
754
  { from: imageRefs[0].ref, to: 'olam-host-cp:latest', name: 'host-cp (bare)' },
734
755
  { from: imageRefs[0].ref, to: `${registry}/olam-host-cp:latest`, name: 'host-cp (registry)' },
735
756
  { from: imageRefs[1].ref, to: 'olam-auth:local', name: 'auth (bare)' },
@@ -737,6 +758,10 @@ export async function runUpgradePullByDigest(deps = {}) {
737
758
  { from: imageRefs[2].ref, to: 'olam-devbox:latest', name: 'devbox (bare)' },
738
759
  { from: imageRefs[2].ref, to: `${registry}/olam-devbox:latest`, name: 'devbox (registry)' },
739
760
  ];
761
+ if (hasMcpAuthDigest && imageRefs[3]) {
762
+ tagPlanBase.push({ from: imageRefs[3].ref, to: 'olam-mcp-auth:local', name: 'mcp-auth (bare)' }, { from: imageRefs[3].ref, to: `${registry}/olam-mcp-auth:latest`, name: 'mcp-auth (registry)' });
763
+ }
764
+ const tagPlan = tagPlanBase;
740
765
  const tagSpinner = ora('Tagging digests → canonical local refs').start();
741
766
  const tagger = deps.tagImpl ?? dockerTag;
742
767
  for (const t of tagPlan) {
@@ -778,12 +803,62 @@ export async function runUpgradePullByDigest(deps = {}) {
778
803
  return { exitCode: EXIT_GENERIC_ERROR, summary: 'auth recreate failed' };
779
804
  }
780
805
  authSpinner.succeed('auth-service running on new image');
806
+ // Step 7 — recreate mcp-auth-service when its digest is in the manifest.
807
+ // Older tarballs (pre-services-bringup) skip this step entirely.
808
+ if (hasMcpAuthDigest) {
809
+ const mcpSpinner = ora('recreate mcp-auth-service').start();
810
+ const mcpRecreate = deps.recreateMcpAuth ?? defaultRecreateMcpAuthForUpgrade;
811
+ const mcpResult = await mcpRecreate();
812
+ if (!mcpResult.ok) {
813
+ mcpSpinner.fail('mcp-auth-service recreate failed');
814
+ process.stderr.write(`${pc.red('error')} ${mcpResult.error ?? 'unknown failure'}\n`);
815
+ return { exitCode: EXIT_GENERIC_ERROR, summary: 'mcp-auth recreate failed' };
816
+ }
817
+ mcpSpinner.succeed('mcp-auth-service running on new image');
818
+ }
781
819
  printSuccess('Upgrade complete (pull-by-digest)');
782
820
  printInfo('host-cp', `running (${digests['host-cp'].slice(0, 19)}…)`);
783
821
  printInfo('auth', `running (${digests.auth.slice(0, 19)}…)`);
784
822
  printInfo('devbox', `pulled (${digests.devbox.slice(0, 19)}…)`);
823
+ if (hasMcpAuthDigest) {
824
+ printInfo('mcp-auth', `running (${digests['mcp-auth'].slice(0, 19)}…)`);
825
+ }
785
826
  return { exitCode: 0, summary: 'stack upgraded' };
786
827
  }
828
+ /**
829
+ * Default mcp-auth-service recreate driver for the pull-by-digest upgrade
830
+ * path. Stops the existing container, removes it, then starts a fresh one
831
+ * via the new image. Mirrors `defaultRecreateAuthForUpgrade` shape.
832
+ *
833
+ * Implementation lives in @olam/core's container controllers — but for the
834
+ * upgrade path we just docker-rm + docker-run because the controller
835
+ * encapsulates start-with-image semantics that match what we want here.
836
+ */
837
+ async function defaultRecreateMcpAuthForUpgrade() {
838
+ // Reuse the existing recreateAuthService logic as a template — the
839
+ // mcp-auth service follows the same lifecycle (atomic-rename store,
840
+ // health-checked start). When the McpAuthContainerController lands as
841
+ // a sibling, this function should switch to controller.start().
842
+ try {
843
+ const { spawnSync: ss } = await import('node:child_process');
844
+ ss('docker', ['stop', 'olam-mcp-auth'], { stdio: 'ignore' });
845
+ ss('docker', ['rm', '-f', 'olam-mcp-auth'], { stdio: 'ignore' });
846
+ const startResult = ss('docker', [
847
+ 'run', '-d', '--name', 'olam-mcp-auth',
848
+ '-p', '9998:9998',
849
+ '-v', 'olam-mcp-auth-data:/mcp-auth-data',
850
+ '--restart', 'unless-stopped',
851
+ 'olam-mcp-auth:local',
852
+ ], { stdio: 'pipe' });
853
+ if (startResult.status !== 0) {
854
+ return { ok: false, error: `docker run failed: ${startResult.stderr?.toString() ?? 'unknown'}` };
855
+ }
856
+ return { ok: true };
857
+ }
858
+ catch (err) {
859
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
860
+ }
861
+ }
787
862
  /**
788
863
  * Default auth-recreate driver for the pull-by-digest upgrade path.
789
864
  * Mirrors recreateAuthService() defined later in this file but trimmed