@pleri/olam-cli 0.1.144 → 0.1.146

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 (117) hide show
  1. package/dist/commands/doctor.d.ts +53 -23
  2. package/dist/commands/doctor.d.ts.map +1 -1
  3. package/dist/commands/doctor.js +117 -46
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/logs.d.ts +17 -3
  6. package/dist/commands/logs.d.ts.map +1 -1
  7. package/dist/commands/logs.js +38 -35
  8. package/dist/commands/logs.js.map +1 -1
  9. package/dist/commands/memory/bridge.d.ts +57 -0
  10. package/dist/commands/memory/bridge.d.ts.map +1 -0
  11. package/dist/commands/memory/bridge.js +156 -0
  12. package/dist/commands/memory/bridge.js.map +1 -0
  13. package/dist/commands/memory/index.d.ts +3 -0
  14. package/dist/commands/memory/index.d.ts.map +1 -1
  15. package/dist/commands/memory/index.js +10 -1
  16. package/dist/commands/memory/index.js.map +1 -1
  17. package/dist/commands/memory/reclassify.d.ts +56 -0
  18. package/dist/commands/memory/reclassify.d.ts.map +1 -0
  19. package/dist/commands/memory/reclassify.js +177 -0
  20. package/dist/commands/memory/reclassify.js.map +1 -0
  21. package/dist/commands/memory/stats.d.ts +69 -0
  22. package/dist/commands/memory/stats.d.ts.map +1 -0
  23. package/dist/commands/memory/stats.js +164 -0
  24. package/dist/commands/memory/stats.js.map +1 -0
  25. package/dist/commands/skills-doctor.d.ts +14 -0
  26. package/dist/commands/skills-doctor.d.ts.map +1 -0
  27. package/dist/commands/skills-doctor.js +126 -0
  28. package/dist/commands/skills-doctor.js.map +1 -0
  29. package/dist/commands/skills-hook.d.ts +19 -0
  30. package/dist/commands/skills-hook.d.ts.map +1 -0
  31. package/dist/commands/skills-hook.js +99 -0
  32. package/dist/commands/skills-hook.js.map +1 -0
  33. package/dist/commands/skills-migrate-back.d.ts +21 -0
  34. package/dist/commands/skills-migrate-back.d.ts.map +1 -0
  35. package/dist/commands/skills-migrate-back.js +222 -0
  36. package/dist/commands/skills-migrate-back.js.map +1 -0
  37. package/dist/commands/skills-migrate.d.ts +33 -0
  38. package/dist/commands/skills-migrate.d.ts.map +1 -0
  39. package/dist/commands/skills-migrate.js +216 -0
  40. package/dist/commands/skills-migrate.js.map +1 -0
  41. package/dist/commands/skills-onboard.d.ts +26 -0
  42. package/dist/commands/skills-onboard.d.ts.map +1 -0
  43. package/dist/commands/skills-onboard.js +227 -0
  44. package/dist/commands/skills-onboard.js.map +1 -0
  45. package/dist/commands/skills-shadow-backups.d.ts +15 -0
  46. package/dist/commands/skills-shadow-backups.d.ts.map +1 -0
  47. package/dist/commands/skills-shadow-backups.js +132 -0
  48. package/dist/commands/skills-shadow-backups.js.map +1 -0
  49. package/dist/commands/skills-source.d.ts +37 -0
  50. package/dist/commands/skills-source.d.ts.map +1 -0
  51. package/dist/commands/skills-source.js +431 -0
  52. package/dist/commands/skills-source.js.map +1 -0
  53. package/dist/commands/skills.d.ts +11 -0
  54. package/dist/commands/skills.d.ts.map +1 -0
  55. package/dist/commands/skills.js +170 -0
  56. package/dist/commands/skills.js.map +1 -0
  57. package/dist/commands/status.d.ts +27 -0
  58. package/dist/commands/status.d.ts.map +1 -1
  59. package/dist/commands/status.js +102 -1
  60. package/dist/commands/status.js.map +1 -1
  61. package/dist/commands/substrate-audit-log.d.ts +49 -0
  62. package/dist/commands/substrate-audit-log.d.ts.map +1 -0
  63. package/dist/commands/substrate-audit-log.js +148 -0
  64. package/dist/commands/substrate-audit-log.js.map +1 -0
  65. package/dist/commands/substrate.d.ts +60 -0
  66. package/dist/commands/substrate.d.ts.map +1 -0
  67. package/dist/commands/substrate.js +175 -0
  68. package/dist/commands/substrate.js.map +1 -0
  69. package/dist/commands/upgrade.d.ts +10 -0
  70. package/dist/commands/upgrade.d.ts.map +1 -1
  71. package/dist/commands/upgrade.js +30 -0
  72. package/dist/commands/upgrade.js.map +1 -1
  73. package/dist/image-digests.json +7 -7
  74. package/dist/index.js +8394 -3876
  75. package/dist/index.js.map +1 -1
  76. package/dist/lib/config.d.ts +69 -0
  77. package/dist/lib/config.d.ts.map +1 -0
  78. package/dist/lib/config.js +146 -0
  79. package/dist/lib/config.js.map +1 -0
  80. package/dist/lib/health-probes.d.ts +72 -0
  81. package/dist/lib/health-probes.d.ts.map +1 -1
  82. package/dist/lib/health-probes.js +218 -0
  83. package/dist/lib/health-probes.js.map +1 -1
  84. package/dist/lib/instrumentation.d.ts +85 -0
  85. package/dist/lib/instrumentation.d.ts.map +1 -0
  86. package/dist/lib/instrumentation.js +104 -0
  87. package/dist/lib/instrumentation.js.map +1 -0
  88. package/dist/lib/kubectl-wrap.d.ts +59 -0
  89. package/dist/lib/kubectl-wrap.d.ts.map +1 -0
  90. package/dist/lib/kubectl-wrap.js +130 -0
  91. package/dist/lib/kubectl-wrap.js.map +1 -0
  92. package/dist/lib/manifest-refresh.d.ts +95 -0
  93. package/dist/lib/manifest-refresh.d.ts.map +1 -0
  94. package/dist/lib/manifest-refresh.js +222 -0
  95. package/dist/lib/manifest-refresh.js.map +1 -0
  96. package/dist/lib/port-forward.d.ts +101 -0
  97. package/dist/lib/port-forward.d.ts.map +1 -0
  98. package/dist/lib/port-forward.js +240 -0
  99. package/dist/lib/port-forward.js.map +1 -0
  100. package/dist/lib/upgrade-kubernetes.d.ts +77 -0
  101. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -0
  102. package/dist/lib/upgrade-kubernetes.js +277 -0
  103. package/dist/lib/upgrade-kubernetes.js.map +1 -0
  104. package/dist/mcp-server.js +3328 -1166
  105. package/host-cp/k8s/manifests/00-namespace.yaml +7 -0
  106. package/host-cp/k8s/manifests/10-serviceaccount.yaml +8 -0
  107. package/host-cp/k8s/manifests/20-rbac.yaml +34 -0
  108. package/host-cp/k8s/manifests/30-configmap.yaml +30 -0
  109. package/host-cp/k8s/manifests/45-pvc.yaml +27 -0
  110. package/host-cp/k8s/manifests/50-deployment.yaml +148 -0
  111. package/host-cp/k8s/manifests/60-service.yaml +22 -0
  112. package/host-cp/k8s/templates/40-secret-template.yaml +32 -0
  113. package/host-cp/src/agent-runtime-trigger.mjs +74 -4
  114. package/host-cp/src/engine-identity.mjs +32 -0
  115. package/host-cp/src/plan-chat-service.mjs +31 -7
  116. package/host-cp/src/server.mjs +219 -9
  117. package/package.json +3 -2
@@ -0,0 +1,85 @@
1
+ /**
2
+ * instrumentation.ts — stdout JSON event emitter for olam-cli.
3
+ *
4
+ * Phase 1b A3 of olam-host-suite-phase-1b-k3s-beta-flavour (plan
5
+ * ~/.claude/plans/olam-host-suite-phase-1b-k3s-beta-flavour.md).
6
+ *
7
+ * Canonical event schema (Decision 21 — `olam.instr.v1`):
8
+ * {
9
+ * "schema": "olam.instr.v1",
10
+ * "event": "substrate.set" | "upgrade.complete",
11
+ * "install_id": "<uuid-v4-from-config>",
12
+ * "ts": "<ISO-8601-UTC>",
13
+ * <event-specific-fields>
14
+ * }
15
+ *
16
+ * Emission target: **stderr**, newline-delimited, each line prefixed with
17
+ * `OLAM_INSTR ` so consumers can grep-distinguish from other stderr output.
18
+ *
19
+ * Why stderr (and not stdout)? olam-cli's existing stdout-JSON contracts
20
+ * (e.g. `olam status --json`, `olam doctor --json`) reserve stdout for
21
+ * command output that consumers parse positionally. Mixing instrumentation
22
+ * into stdout breaks those contracts. stderr keeps the emitter
23
+ * grep-distinguishable AND segregated from the data-plane output.
24
+ *
25
+ * Consumers: month-6 aggregator script (`scripts/aggregate-substrate-events.mjs`,
26
+ * D20) groups events by `install_id` for Falsifiable signal thresholds 1+4.
27
+ *
28
+ * Defensive contract:
29
+ * - emit() MUST NOT throw if the config can't be read; falls back to a
30
+ * placeholder install_id ('unknown') + emits a one-line stderr WARN.
31
+ * - Schema is versioned (`olam.instr.v1`); v2 fields land additively.
32
+ * Consumers MUST tolerate unknown fields.
33
+ */
34
+ export declare const INSTRUMENTATION_SCHEMA: "olam.instr.v1";
35
+ export declare const INSTRUMENTATION_PREFIX: "OLAM_INSTR ";
36
+ export type SubstrateSetEvent = {
37
+ schema: typeof INSTRUMENTATION_SCHEMA;
38
+ event: 'substrate.set';
39
+ install_id: string;
40
+ ts: string;
41
+ substrate: 'compose' | 'kubernetes';
42
+ flavor?: string;
43
+ };
44
+ export type UpgradeCompleteEvent = {
45
+ schema: typeof INSTRUMENTATION_SCHEMA;
46
+ event: 'upgrade.complete';
47
+ install_id: string;
48
+ ts: string;
49
+ substrate: 'compose' | 'kubernetes';
50
+ duration_ms: number;
51
+ flavor?: string;
52
+ };
53
+ export type InstrumentationEvent = SubstrateSetEvent | UpgradeCompleteEvent;
54
+ export type EmitOpts = {
55
+ /** Inject a stderr-like sink for tests; defaults to process.stderr. */
56
+ stderr?: NodeJS.WritableStream;
57
+ /** Inject a clock for tests; defaults to Date.now(). */
58
+ now?: () => Date;
59
+ /** Inject a config-reader for tests; defaults to readConfig(). */
60
+ installIdProvider?: () => string;
61
+ };
62
+ /**
63
+ * Emit a `substrate.set` event. Called by `olam substrate set` ONLY on success
64
+ * (failure paths emit nothing — by design; thresholds count successful switches).
65
+ *
66
+ * @param payload — substrate + optional flavor
67
+ * @param opts — test-only injection points (stderr / now / installIdProvider)
68
+ */
69
+ export declare function emitSubstrateSet(payload: {
70
+ substrate: 'compose' | 'kubernetes';
71
+ flavor?: string;
72
+ }, opts?: EmitOpts): void;
73
+ /**
74
+ * Emit an `upgrade.complete` event. Called by Phase C C2's substrate-aware
75
+ * `olam upgrade` ONLY on success.
76
+ *
77
+ * @param payload — substrate + duration_ms (and optional flavor)
78
+ * @param opts — test-only injection points
79
+ */
80
+ export declare function emitUpgradeComplete(payload: {
81
+ substrate: 'compose' | 'kubernetes';
82
+ duration_ms: number;
83
+ flavor?: string;
84
+ }, opts?: EmitOpts): void;
85
+ //# sourceMappingURL=instrumentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/lib/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,eAAO,MAAM,sBAAsB,EAAG,eAAwB,CAAC;AAC/D,eAAO,MAAM,sBAAsB,EAAG,aAAsB,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,SAAS,GAAG,YAAY,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,SAAS,GAAG,YAAY,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAE5E,MAAM,MAAM,QAAQ,GAAG;IACrB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;CAClC,CAAC;AAmCF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,GAAG,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,IAAI,GAAE,QAAa,GAClB,IAAI,CAUN;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IACP,SAAS,EAAE,SAAS,GAAG,YAAY,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,EACD,IAAI,GAAE,QAAa,GAClB,IAAI,CAWN"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * instrumentation.ts — stdout JSON event emitter for olam-cli.
3
+ *
4
+ * Phase 1b A3 of olam-host-suite-phase-1b-k3s-beta-flavour (plan
5
+ * ~/.claude/plans/olam-host-suite-phase-1b-k3s-beta-flavour.md).
6
+ *
7
+ * Canonical event schema (Decision 21 — `olam.instr.v1`):
8
+ * {
9
+ * "schema": "olam.instr.v1",
10
+ * "event": "substrate.set" | "upgrade.complete",
11
+ * "install_id": "<uuid-v4-from-config>",
12
+ * "ts": "<ISO-8601-UTC>",
13
+ * <event-specific-fields>
14
+ * }
15
+ *
16
+ * Emission target: **stderr**, newline-delimited, each line prefixed with
17
+ * `OLAM_INSTR ` so consumers can grep-distinguish from other stderr output.
18
+ *
19
+ * Why stderr (and not stdout)? olam-cli's existing stdout-JSON contracts
20
+ * (e.g. `olam status --json`, `olam doctor --json`) reserve stdout for
21
+ * command output that consumers parse positionally. Mixing instrumentation
22
+ * into stdout breaks those contracts. stderr keeps the emitter
23
+ * grep-distinguishable AND segregated from the data-plane output.
24
+ *
25
+ * Consumers: month-6 aggregator script (`scripts/aggregate-substrate-events.mjs`,
26
+ * D20) groups events by `install_id` for Falsifiable signal thresholds 1+4.
27
+ *
28
+ * Defensive contract:
29
+ * - emit() MUST NOT throw if the config can't be read; falls back to a
30
+ * placeholder install_id ('unknown') + emits a one-line stderr WARN.
31
+ * - Schema is versioned (`olam.instr.v1`); v2 fields land additively.
32
+ * Consumers MUST tolerate unknown fields.
33
+ */
34
+ import { readConfig } from './config.js';
35
+ export const INSTRUMENTATION_SCHEMA = 'olam.instr.v1';
36
+ export const INSTRUMENTATION_PREFIX = 'OLAM_INSTR ';
37
+ function nowIso(now) {
38
+ const d = now ? now() : new Date();
39
+ return d.toISOString();
40
+ }
41
+ function resolveInstallId(opts) {
42
+ try {
43
+ if (opts.installIdProvider)
44
+ return opts.installIdProvider();
45
+ const cfg = readConfig();
46
+ return cfg.install_id;
47
+ }
48
+ catch {
49
+ return 'unknown';
50
+ }
51
+ }
52
+ function writeLine(stderr, payload) {
53
+ try {
54
+ const line = `${INSTRUMENTATION_PREFIX}${JSON.stringify(payload)}\n`;
55
+ stderr.write(line);
56
+ }
57
+ catch (err) {
58
+ // emit must never throw; surface the failure tersely to stderr.
59
+ try {
60
+ stderr.write(`[WARN] olam instrumentation emit failed: ${err instanceof Error ? err.message : String(err)}\n`);
61
+ }
62
+ catch {
63
+ // give up; emitter contract is best-effort.
64
+ }
65
+ }
66
+ }
67
+ /**
68
+ * Emit a `substrate.set` event. Called by `olam substrate set` ONLY on success
69
+ * (failure paths emit nothing — by design; thresholds count successful switches).
70
+ *
71
+ * @param payload — substrate + optional flavor
72
+ * @param opts — test-only injection points (stderr / now / installIdProvider)
73
+ */
74
+ export function emitSubstrateSet(payload, opts = {}) {
75
+ const event = {
76
+ schema: INSTRUMENTATION_SCHEMA,
77
+ event: 'substrate.set',
78
+ install_id: resolveInstallId(opts),
79
+ ts: nowIso(opts.now),
80
+ substrate: payload.substrate,
81
+ ...(payload.flavor !== undefined ? { flavor: payload.flavor } : {}),
82
+ };
83
+ writeLine(opts.stderr ?? process.stderr, event);
84
+ }
85
+ /**
86
+ * Emit an `upgrade.complete` event. Called by Phase C C2's substrate-aware
87
+ * `olam upgrade` ONLY on success.
88
+ *
89
+ * @param payload — substrate + duration_ms (and optional flavor)
90
+ * @param opts — test-only injection points
91
+ */
92
+ export function emitUpgradeComplete(payload, opts = {}) {
93
+ const event = {
94
+ schema: INSTRUMENTATION_SCHEMA,
95
+ event: 'upgrade.complete',
96
+ install_id: resolveInstallId(opts),
97
+ ts: nowIso(opts.now),
98
+ substrate: payload.substrate,
99
+ duration_ms: payload.duration_ms,
100
+ ...(payload.flavor !== undefined ? { flavor: payload.flavor } : {}),
101
+ };
102
+ writeLine(opts.stderr ?? process.stderr, event);
103
+ }
104
+ //# sourceMappingURL=instrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/lib/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,eAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAsB,CAAC;AAgC7D,SAAS,MAAM,CAAC,GAAgB;IAC9B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAc;IACtC,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,UAAU,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,MAA6B,EAAE,OAA6B;IAC7E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,sBAAsB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;QACrE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gEAAgE;QAChE,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CACV,4CACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,IAAI,CACL,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAiE,EACjE,OAAiB,EAAE;IAEnB,MAAM,KAAK,GAAsB;QAC/B,MAAM,EAAE,sBAAsB;QAC9B,KAAK,EAAE,eAAe;QACtB,UAAU,EAAE,gBAAgB,CAAC,IAAI,CAAC;QAClC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;IACF,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAIC,EACD,OAAiB,EAAE;IAEnB,MAAM,KAAK,GAAyB;QAClC,MAAM,EAAE,sBAAsB;QAC9B,KAAK,EAAE,kBAAkB;QACzB,UAAU,EAAE,gBAAgB,CAAC,IAAI,CAAC;QAClC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;IACF,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * kubectl-wrap.ts — subprocess timeout wrapper for kubectl invocations.
3
+ *
4
+ * Phase 1b C1 of olam-host-suite-phase-1b-k3s-beta-flavour (plan
5
+ * ~/.claude/plans/olam-host-suite-phase-1b-k3s-beta-flavour.md).
6
+ *
7
+ * ALL kubectl invocations in olam-cli MUST go through `kubectlWrap`.
8
+ * Direct `child_process.spawn('kubectl', ...)` calls outside this module
9
+ * break the timeout guarantee and fail `audit:kubectl-callers` (Seam C1).
10
+ *
11
+ * Timeout lifecycle:
12
+ * 1. Spawn kubectl with the provided args.
13
+ * 2. Start wall-clock timer (default 120 000 ms; per-call configurable).
14
+ * 3. On timer fire: SIGTERM the process; wait 5 000 ms; SIGKILL if still alive.
15
+ * 4. Returns { ok: false, reason: 'timeout', … } immediately after the kill
16
+ * sequence completes (does not wait further for exit after SIGKILL).
17
+ *
18
+ * Returns:
19
+ * { ok: true, stdout, stderr, exitCode } — clean exit 0
20
+ * { ok: false, stdout, stderr, exitCode, reason } — non-zero exit or timeout
21
+ *
22
+ * reason values:
23
+ * 'timeout' — wall-clock limit exceeded; process SIGKILLed
24
+ * 'spawn' — spawn itself failed (e.g. kubectl not on PATH)
25
+ * 'nonzero' — kubectl exited with non-zero status
26
+ */
27
+ import { spawn } from 'node:child_process';
28
+ export declare const DEFAULT_TIMEOUT_MS = 120000;
29
+ export type KubectlResult = {
30
+ ok: true;
31
+ stdout: string;
32
+ stderr: string;
33
+ exitCode: number;
34
+ } | {
35
+ ok: false;
36
+ stdout: string;
37
+ stderr: string;
38
+ exitCode: number;
39
+ reason: 'timeout' | 'spawn' | 'nonzero';
40
+ };
41
+ export interface KubectlWrapOpts {
42
+ /** Per-call timeout override (ms). Defaults to DEFAULT_TIMEOUT_MS (120 s). */
43
+ readonly timeout?: number;
44
+ /** Additional environment variables to merge into the subprocess env. */
45
+ readonly env?: Record<string, string>;
46
+ /**
47
+ * spawn factory — injectable for tests so unit tests never fork a real kubectl.
48
+ * Signature matches `child_process.spawn` return type.
49
+ */
50
+ readonly spawnImpl?: typeof spawn;
51
+ }
52
+ /**
53
+ * Invoke kubectl with a timeout.
54
+ *
55
+ * @param args - kubectl arguments (e.g. ['get', 'pods', '-n', 'olam'])
56
+ * @param opts - timeout, env overrides, and spawn factory for injection
57
+ */
58
+ export declare function kubectlWrap(args: readonly string[], opts?: KubectlWrapOpts): Promise<KubectlResult>;
59
+ //# sourceMappingURL=kubectl-wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubectl-wrap.d.ts","sourceRoot":"","sources":["../../src/lib/kubectl-wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAG1C,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;CAAE,CAAC;AAE7G,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,aAAa,CAAC,CAuFxB"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * kubectl-wrap.ts — subprocess timeout wrapper for kubectl invocations.
3
+ *
4
+ * Phase 1b C1 of olam-host-suite-phase-1b-k3s-beta-flavour (plan
5
+ * ~/.claude/plans/olam-host-suite-phase-1b-k3s-beta-flavour.md).
6
+ *
7
+ * ALL kubectl invocations in olam-cli MUST go through `kubectlWrap`.
8
+ * Direct `child_process.spawn('kubectl', ...)` calls outside this module
9
+ * break the timeout guarantee and fail `audit:kubectl-callers` (Seam C1).
10
+ *
11
+ * Timeout lifecycle:
12
+ * 1. Spawn kubectl with the provided args.
13
+ * 2. Start wall-clock timer (default 120 000 ms; per-call configurable).
14
+ * 3. On timer fire: SIGTERM the process; wait 5 000 ms; SIGKILL if still alive.
15
+ * 4. Returns { ok: false, reason: 'timeout', … } immediately after the kill
16
+ * sequence completes (does not wait further for exit after SIGKILL).
17
+ *
18
+ * Returns:
19
+ * { ok: true, stdout, stderr, exitCode } — clean exit 0
20
+ * { ok: false, stdout, stderr, exitCode, reason } — non-zero exit or timeout
21
+ *
22
+ * reason values:
23
+ * 'timeout' — wall-clock limit exceeded; process SIGKILLed
24
+ * 'spawn' — spawn itself failed (e.g. kubectl not on PATH)
25
+ * 'nonzero' — kubectl exited with non-zero status
26
+ */
27
+ import { spawn } from 'node:child_process';
28
+ export const DEFAULT_TIMEOUT_MS = 120_000;
29
+ const SIGKILL_GRACE_MS = 5_000;
30
+ /**
31
+ * Invoke kubectl with a timeout.
32
+ *
33
+ * @param args - kubectl arguments (e.g. ['get', 'pods', '-n', 'olam'])
34
+ * @param opts - timeout, env overrides, and spawn factory for injection
35
+ */
36
+ export async function kubectlWrap(args, opts = {}) {
37
+ const timeoutMs = opts.timeout ?? DEFAULT_TIMEOUT_MS;
38
+ const spawnImpl = opts.spawnImpl ?? spawn;
39
+ const stdout = [];
40
+ const stderr = [];
41
+ return new Promise((resolve) => {
42
+ let resolved = false;
43
+ let killTimer = null;
44
+ let sigkillTimer = null;
45
+ function safeResolve(r) {
46
+ if (resolved)
47
+ return;
48
+ resolved = true;
49
+ if (killTimer !== null) {
50
+ clearTimeout(killTimer);
51
+ killTimer = null;
52
+ }
53
+ if (sigkillTimer !== null) {
54
+ clearTimeout(sigkillTimer);
55
+ sigkillTimer = null;
56
+ }
57
+ resolve(r);
58
+ }
59
+ let child;
60
+ try {
61
+ child = spawnImpl('kubectl', [...args], {
62
+ stdio: ['ignore', 'pipe', 'pipe'],
63
+ env: { ...process.env, ...(opts.env ?? {}) },
64
+ });
65
+ }
66
+ catch (err) {
67
+ resolve({
68
+ ok: false,
69
+ stdout: '',
70
+ stderr: err instanceof Error ? err.message : String(err),
71
+ exitCode: -1,
72
+ reason: 'spawn',
73
+ });
74
+ return;
75
+ }
76
+ if (child.stdout) {
77
+ child.stdout.on('data', (chunk) => { stdout.push(chunk.toString('utf8')); });
78
+ }
79
+ if (child.stderr) {
80
+ child.stderr.on('data', (chunk) => { stderr.push(chunk.toString('utf8')); });
81
+ }
82
+ child.on('error', (err) => {
83
+ safeResolve({
84
+ ok: false,
85
+ stdout: stdout.join(''),
86
+ stderr: err.message,
87
+ exitCode: -1,
88
+ reason: 'spawn',
89
+ });
90
+ });
91
+ child.on('exit', (code) => {
92
+ const exitCode = code ?? -1;
93
+ const stdoutStr = stdout.join('');
94
+ const stderrStr = stderr.join('');
95
+ if (exitCode === 0) {
96
+ safeResolve({ ok: true, stdout: stdoutStr, stderr: stderrStr, exitCode });
97
+ }
98
+ else {
99
+ safeResolve({ ok: false, stdout: stdoutStr, stderr: stderrStr, exitCode, reason: 'nonzero' });
100
+ }
101
+ });
102
+ // Wall-clock timeout: SIGTERM then SIGKILL after grace period.
103
+ killTimer = setTimeout(() => {
104
+ killTimer = null;
105
+ // SIGTERM — polite shutdown request.
106
+ try {
107
+ child.kill('SIGTERM');
108
+ }
109
+ catch { /* already exited */ }
110
+ // SIGKILL after 5 s grace — hard kill if SIGTERM wasn't enough.
111
+ sigkillTimer = setTimeout(() => {
112
+ sigkillTimer = null;
113
+ try {
114
+ child.kill('SIGKILL');
115
+ }
116
+ catch { /* already exited */ }
117
+ // Resolve immediately after SIGKILL without waiting for the 'exit' event.
118
+ // The 'exit' event may fire after this resolve; safeResolve is idempotent.
119
+ safeResolve({
120
+ ok: false,
121
+ stdout: stdout.join(''),
122
+ stderr: stderr.join(''),
123
+ exitCode: -1,
124
+ reason: 'timeout',
125
+ });
126
+ }, SIGKILL_GRACE_MS);
127
+ }, timeoutMs);
128
+ });
129
+ }
130
+ //# sourceMappingURL=kubectl-wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubectl-wrap.js","sourceRoot":"","sources":["../../src/lib/kubectl-wrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * manifest-refresh.ts — D14 --force-refresh-manifests flag implementation.
3
+ *
4
+ * Phase 1b C2 of olam-host-suite-phase-1b-k3s-beta-flavour (plan
5
+ * ~/.claude/plans/olam-host-suite-phase-1b-k3s-beta-flavour.md).
6
+ *
7
+ * Decisions consumed:
8
+ * D14 — --force-refresh-manifests flag (NOT a subcommand); requires
9
+ * --accept-security-regression when security-sensitive fields differ.
10
+ *
11
+ * Security-sensitive manifest fields (refuse without --accept-security-regression):
12
+ * - securityContext (pod or container level)
13
+ * - resources.limits
14
+ * - capabilities (add/drop lists)
15
+ * - readOnlyRootFilesystem
16
+ * - RBAC Role rules (rules[].verbs / resources / apiGroups)
17
+ *
18
+ * Audit log:
19
+ * ~/.olam/state/manifest-refresh-audit.jsonl (mode 0600; append-only)
20
+ * ENOSPC aborts the refresh with "audit log unavailable: <error>".
21
+ * The file is created on first write; mode set via writeFileSync options.
22
+ *
23
+ * Two functions are exported:
24
+ * diffManifestSecurityFields — pure diff, no I/O; testable.
25
+ * runManifestRefresh — performs the full refresh with audit-log.
26
+ */
27
+ import * as fs from 'node:fs';
28
+ export declare const MANIFEST_REFRESH_AUDIT_LOG: string;
29
+ /** Security-sensitive field paths checked by the diff. */
30
+ export declare const SECURITY_SENSITIVE_FIELDS: readonly ["securityContext", "resources.limits", "capabilities", "readOnlyRootFilesystem", "rules"];
31
+ export type SecuritySensitiveField = (typeof SECURITY_SENSITIVE_FIELDS)[number];
32
+ export interface ManifestDiffResult {
33
+ /** True when any security-sensitive field value differs between old and new. */
34
+ hasSecurityRegression: boolean;
35
+ /** List of field keys that changed. */
36
+ changedFields: SecuritySensitiveField[];
37
+ }
38
+ export interface ManifestRefreshAuditEntry {
39
+ ts: string;
40
+ manifests_path: string;
41
+ security_regression: boolean;
42
+ changed_fields: string[];
43
+ accepted: boolean;
44
+ operator_pid: number;
45
+ }
46
+ export interface ManifestRefreshDeps {
47
+ /** Override state dir for tests. */
48
+ readonly stateDir?: string;
49
+ /** Override manifests dir for tests. */
50
+ readonly manifestsDir?: string;
51
+ /** Override audit log path for tests. */
52
+ readonly auditLogPath?: string;
53
+ /** Override fs.readdirSync for tests. */
54
+ readonly readdirSync?: typeof fs.readdirSync;
55
+ /** Override fs.readFileSync for tests. */
56
+ readonly readFileSync?: typeof fs.readFileSync;
57
+ /** Override fs.writeFileSync for tests. */
58
+ readonly writeFileSync?: typeof fs.writeFileSync;
59
+ /** Override fs.existsSync for tests. */
60
+ readonly existsSync?: typeof fs.existsSync;
61
+ /** Override Date.now for tests. */
62
+ readonly now?: () => Date;
63
+ }
64
+ /**
65
+ * Pure diff between two YAML manifest file contents (as strings).
66
+ * Parses each as JSON (manifests may be JSON or YAML; we handle JSON
67
+ * and treat parse failures as "content changed" = regression to be safe).
68
+ *
69
+ * Used by runManifestRefresh and directly by tests.
70
+ */
71
+ export declare function diffManifestSecurityFields(oldContent: string, newContent: string): ManifestDiffResult;
72
+ export type ManifestRefreshResult = {
73
+ ok: true;
74
+ message: string;
75
+ } | {
76
+ ok: false;
77
+ message: string;
78
+ };
79
+ /**
80
+ * Run the manifest refresh check.
81
+ *
82
+ * @param manifestsDir — path to ~/.olam/k8s/manifests/
83
+ * @param acceptRegression — true when --accept-security-regression is set
84
+ * @param deps — injectable for tests
85
+ *
86
+ * Returns ok=false when:
87
+ * - Security-sensitive fields differ AND !acceptRegression.
88
+ * - Audit log write fails (ENOSPC).
89
+ *
90
+ * On ok=true the audit log entry is written with accepted=true (or
91
+ * accepted=false when no regression was detected — regression-free
92
+ * refreshes are still audited).
93
+ */
94
+ export declare function runManifestRefresh(manifestsDir: string, acceptRegression: boolean, deps?: ManifestRefreshDeps): Promise<ManifestRefreshResult>;
95
+ //# sourceMappingURL=manifest-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-refresh.d.ts","sourceRoot":"","sources":["../../src/lib/manifest-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAI9B,eAAO,MAAM,0BAA0B,QAA4D,CAAC;AAEpG,0DAA0D;AAC1D,eAAO,MAAM,yBAAyB,qGAM5B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uCAAuC;IACvC,aAAa,EAAE,sBAAsB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC;IAC7C,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC;IAC/C,2CAA2C;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC;IACjD,wCAAwC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC;IAC3C,mCAAmC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAkCD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,kBAAkB,CA4BpB;AAyBD,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,OAAO,EACzB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,qBAAqB,CAAC,CAqFhC"}