@pleri/olam-cli 0.1.186 → 0.1.195

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 (189) hide show
  1. package/README.md +1 -1
  2. package/dist/ask/knowledge-pack-builder.d.ts.map +1 -1
  3. package/dist/ask/knowledge-pack-builder.js +5 -0
  4. package/dist/ask/knowledge-pack-builder.js.map +1 -1
  5. package/dist/ask/knowledge-pack.generated.d.ts.map +1 -1
  6. package/dist/ask/knowledge-pack.generated.js +442 -33
  7. package/dist/ask/knowledge-pack.generated.js.map +1 -1
  8. package/dist/commands/auth-status.js +2 -2
  9. package/dist/commands/auth-status.js.map +1 -1
  10. package/dist/commands/auth.js +1 -1
  11. package/dist/commands/auth.js.map +1 -1
  12. package/dist/commands/bootstrap.d.ts +4 -0
  13. package/dist/commands/bootstrap.d.ts.map +1 -1
  14. package/dist/commands/bootstrap.js +6 -9
  15. package/dist/commands/bootstrap.js.map +1 -1
  16. package/dist/commands/clean.js +1 -1
  17. package/dist/commands/clean.js.map +1 -1
  18. package/dist/commands/completion.d.ts.map +1 -1
  19. package/dist/commands/completion.js +1 -4
  20. package/dist/commands/completion.js.map +1 -1
  21. package/dist/commands/create.d.ts.map +1 -1
  22. package/dist/commands/create.js +10 -0
  23. package/dist/commands/create.js.map +1 -1
  24. package/dist/commands/crystallize.js +12 -14
  25. package/dist/commands/crystallize.js.map +1 -1
  26. package/dist/commands/destroy.d.ts +13 -1
  27. package/dist/commands/destroy.d.ts.map +1 -1
  28. package/dist/commands/destroy.js +52 -6
  29. package/dist/commands/destroy.js.map +1 -1
  30. package/dist/commands/dispatch.d.ts +9 -0
  31. package/dist/commands/dispatch.d.ts.map +1 -1
  32. package/dist/commands/dispatch.js +21 -2
  33. package/dist/commands/dispatch.js.map +1 -1
  34. package/dist/commands/doctor.d.ts +1 -1
  35. package/dist/commands/doctor.d.ts.map +1 -1
  36. package/dist/commands/doctor.js +29 -22
  37. package/dist/commands/doctor.js.map +1 -1
  38. package/dist/commands/enter.d.ts +3 -3
  39. package/dist/commands/enter.d.ts.map +1 -1
  40. package/dist/commands/enter.js +57 -44
  41. package/dist/commands/enter.js.map +1 -1
  42. package/dist/commands/flywheel/index.d.ts.map +1 -1
  43. package/dist/commands/flywheel/index.js +1 -1
  44. package/dist/commands/flywheel/index.js.map +1 -1
  45. package/dist/commands/host-cp.d.ts.map +1 -1
  46. package/dist/commands/host-cp.js +2 -1
  47. package/dist/commands/host-cp.js.map +1 -1
  48. package/dist/commands/implode.d.ts.map +1 -1
  49. package/dist/commands/implode.js +1 -1
  50. package/dist/commands/implode.js.map +1 -1
  51. package/dist/commands/init.d.ts +20 -0
  52. package/dist/commands/init.d.ts.map +1 -1
  53. package/dist/commands/init.js +102 -9
  54. package/dist/commands/init.js.map +1 -1
  55. package/dist/commands/install.js +2 -2
  56. package/dist/commands/install.js.map +1 -1
  57. package/dist/commands/kg-build.d.ts.map +1 -1
  58. package/dist/commands/kg-build.js +3 -0
  59. package/dist/commands/kg-build.js.map +1 -1
  60. package/dist/commands/kg-classify.d.ts +20 -0
  61. package/dist/commands/kg-classify.d.ts.map +1 -1
  62. package/dist/commands/kg-classify.js +59 -42
  63. package/dist/commands/kg-classify.js.map +1 -1
  64. package/dist/commands/kg-mirror.d.ts +40 -0
  65. package/dist/commands/kg-mirror.d.ts.map +1 -0
  66. package/dist/commands/kg-mirror.js +228 -0
  67. package/dist/commands/kg-mirror.js.map +1 -0
  68. package/dist/commands/mcp/index.js +1 -1
  69. package/dist/commands/mcp/index.js.map +1 -1
  70. package/dist/commands/memory/index.d.ts.map +1 -1
  71. package/dist/commands/memory/index.js +1 -1
  72. package/dist/commands/memory/index.js.map +1 -1
  73. package/dist/commands/resume.d.ts.map +1 -1
  74. package/dist/commands/resume.js +1 -1
  75. package/dist/commands/resume.js.map +1 -1
  76. package/dist/commands/services-tls.d.ts +120 -0
  77. package/dist/commands/services-tls.d.ts.map +1 -0
  78. package/dist/commands/services-tls.js +434 -0
  79. package/dist/commands/services-tls.js.map +1 -0
  80. package/dist/commands/services.d.ts.map +1 -1
  81. package/dist/commands/services.js +40 -1
  82. package/dist/commands/services.js.map +1 -1
  83. package/dist/commands/setup-linux-gate.d.ts.map +1 -1
  84. package/dist/commands/setup-linux-gate.js +1 -3
  85. package/dist/commands/setup-linux-gate.js.map +1 -1
  86. package/dist/commands/setup-metrics.d.ts.map +1 -1
  87. package/dist/commands/setup-metrics.js +1 -2
  88. package/dist/commands/setup-metrics.js.map +1 -1
  89. package/dist/commands/setup-phase-5a-skill-source.d.ts +17 -1
  90. package/dist/commands/setup-phase-5a-skill-source.d.ts.map +1 -1
  91. package/dist/commands/setup-phase-5a-skill-source.js +69 -6
  92. package/dist/commands/setup-phase-5a-skill-source.js.map +1 -1
  93. package/dist/commands/setup.d.ts +26 -1
  94. package/dist/commands/setup.d.ts.map +1 -1
  95. package/dist/commands/setup.js +189 -47
  96. package/dist/commands/setup.js.map +1 -1
  97. package/dist/commands/skills-onboard.d.ts.map +1 -1
  98. package/dist/commands/skills-onboard.js +4 -1
  99. package/dist/commands/skills-onboard.js.map +1 -1
  100. package/dist/commands/skills-source.d.ts.map +1 -1
  101. package/dist/commands/skills-source.js +20 -4
  102. package/dist/commands/skills-source.js.map +1 -1
  103. package/dist/commands/status.d.ts.map +1 -1
  104. package/dist/commands/status.js +5 -1
  105. package/dist/commands/status.js.map +1 -1
  106. package/dist/commands/upgrade.d.ts.map +1 -1
  107. package/dist/commands/upgrade.js +1 -3
  108. package/dist/commands/upgrade.js.map +1 -1
  109. package/dist/commands/yolo.d.ts.map +1 -1
  110. package/dist/commands/yolo.js +1 -1
  111. package/dist/commands/yolo.js.map +1 -1
  112. package/dist/context.d.ts +4 -0
  113. package/dist/context.d.ts.map +1 -1
  114. package/dist/context.js +3 -2
  115. package/dist/context.js.map +1 -1
  116. package/dist/image-digests.json +8 -8
  117. package/dist/index.js +4409 -2375
  118. package/dist/index.js.map +1 -1
  119. package/dist/lib/auth-refresh-kubernetes.d.ts.map +1 -1
  120. package/dist/lib/auth-refresh-kubernetes.js +14 -5
  121. package/dist/lib/auth-refresh-kubernetes.js.map +1 -1
  122. package/dist/lib/bootstrap-kubernetes.d.ts +41 -0
  123. package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -1
  124. package/dist/lib/bootstrap-kubernetes.js +289 -36
  125. package/dist/lib/bootstrap-kubernetes.js.map +1 -1
  126. package/dist/lib/cf-access-token.d.ts.map +1 -1
  127. package/dist/lib/cf-access-token.js +2 -3
  128. package/dist/lib/cf-access-token.js.map +1 -1
  129. package/dist/lib/health-probes.d.ts +14 -0
  130. package/dist/lib/health-probes.d.ts.map +1 -1
  131. package/dist/lib/health-probes.js +41 -3
  132. package/dist/lib/health-probes.js.map +1 -1
  133. package/dist/lib/help-groups.d.ts +36 -0
  134. package/dist/lib/help-groups.d.ts.map +1 -0
  135. package/dist/lib/help-groups.js +124 -0
  136. package/dist/lib/help-groups.js.map +1 -0
  137. package/dist/lib/k8s-bootstrap.d.ts +6 -0
  138. package/dist/lib/k8s-bootstrap.d.ts.map +1 -1
  139. package/dist/lib/k8s-bootstrap.js +15 -2
  140. package/dist/lib/k8s-bootstrap.js.map +1 -1
  141. package/dist/lib/k8s-secret-render.d.ts.map +1 -1
  142. package/dist/lib/k8s-secret-render.js +17 -10
  143. package/dist/lib/k8s-secret-render.js.map +1 -1
  144. package/dist/lib/memory-secret.d.ts +15 -2
  145. package/dist/lib/memory-secret.d.ts.map +1 -1
  146. package/dist/lib/memory-secret.js +25 -8
  147. package/dist/lib/memory-secret.js.map +1 -1
  148. package/dist/lib/upgrade-check.d.ts +60 -0
  149. package/dist/lib/upgrade-check.d.ts.map +1 -0
  150. package/dist/lib/upgrade-check.js +169 -0
  151. package/dist/lib/upgrade-check.js.map +1 -0
  152. package/dist/lib/upgrade-kubernetes.d.ts +17 -0
  153. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
  154. package/dist/lib/upgrade-kubernetes.js +125 -1
  155. package/dist/lib/upgrade-kubernetes.js.map +1 -1
  156. package/dist/mcp-server.js +2687 -2818
  157. package/hermes-bundle/version.json +1 -1
  158. package/host-cp/k8s/manifests/30-configmap.yaml +8 -1
  159. package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
  160. package/host-cp/k8s/manifests/60-service.yaml +12 -4
  161. package/host-cp/k8s/manifests/70-ingressroute.yaml +58 -0
  162. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
  163. package/host-cp/k8s/manifests/chunks-electric/10-serviceaccount.yaml +8 -0
  164. package/host-cp/k8s/manifests/chunks-electric/20-rbac.yaml +27 -0
  165. package/host-cp/k8s/manifests/chunks-electric/30-configmap.yaml +23 -0
  166. package/host-cp/k8s/manifests/chunks-electric/45-pvc.yaml +19 -0
  167. package/host-cp/k8s/manifests/chunks-electric/50-deployment.yaml +84 -0
  168. package/host-cp/k8s/manifests/chunks-electric/60-service.yaml +17 -0
  169. package/host-cp/k8s/manifests/chunks-postgres/10-serviceaccount.yaml +8 -0
  170. package/host-cp/k8s/manifests/chunks-postgres/20-rbac.yaml +29 -0
  171. package/host-cp/k8s/manifests/chunks-postgres/30-configmap.yaml +185 -0
  172. package/host-cp/k8s/manifests/chunks-postgres/45-pvc.yaml +24 -0
  173. package/host-cp/k8s/manifests/chunks-postgres/50-deployment.yaml +101 -0
  174. package/host-cp/k8s/manifests/chunks-postgres/60-service.yaml +24 -0
  175. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
  176. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
  177. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
  178. package/host-cp/k8s/manifests/plan-chat-service/10-serviceaccount.yaml +8 -0
  179. package/host-cp/k8s/manifests/plan-chat-service/20-rbac.yaml +29 -0
  180. package/host-cp/k8s/manifests/plan-chat-service/30-configmap.yaml +36 -0
  181. package/host-cp/k8s/manifests/plan-chat-service/45-pvc.yaml +24 -0
  182. package/host-cp/k8s/manifests/plan-chat-service/50-deployment.yaml +135 -0
  183. package/host-cp/k8s/manifests/plan-chat-service/60-service.yaml +17 -0
  184. package/host-cp/src/plan-chat-secret.mjs +16 -1
  185. package/host-cp/src/plan-chat-service.mjs +709 -11
  186. package/host-cp/src/planning-sessions.mjs +252 -0
  187. package/host-cp/src/pr-cache.mjs +11 -2
  188. package/host-cp/src/server.mjs +128 -22
  189. package/package.json +2 -1
@@ -0,0 +1,434 @@
1
+ /**
2
+ * `olam services tls-install` — generate a locally-trusted TLS certificate
3
+ * for the K3d Traefik IngressRoute and apply it as a Kubernetes Secret.
4
+ *
5
+ * Why this exists: HTTP/1.1 inside `kubectl port-forward` hits the browser's
6
+ * 6-connection-per-origin cap under Electric SQL long-poll load (one shape
7
+ * subscription per concurrent route → SPA stalls at ~25s pending). Putting
8
+ * Traefik in front with TLS + HTTP/2 fixes both problems with one cert
9
+ * provisioning step. mkcert handles the root-CA dance so browsers trust
10
+ * `https://olam.local` natively — no padlock warnings, no `--insecure`.
11
+ *
12
+ * Flow:
13
+ * 1. Verify `mkcert` is on PATH (actionable error otherwise).
14
+ * 2. Run `mkcert -install` (idempotent — no-op if root CA already trusted).
15
+ * 3. Mint a cert in a tmp dir for `olam.local 127.0.0.1 ::1`.
16
+ * 4. Read tls.crt + tls.key, base64-encode, substitute into the template.
17
+ * 5. `kubectl apply -f -` against the rendered Secret manifest.
18
+ * 6. Suggest the /etc/hosts line (do NOT auto-edit).
19
+ *
20
+ * Idempotency: if `olam-host-cp-tls` already exists AND its NotAfter is
21
+ * more than 30 days away, skip the whole flow. Operators can force renewal
22
+ * with `kubectl -n olam delete secret olam-host-cp-tls`.
23
+ *
24
+ * Design constraints honoured:
25
+ * - No new npm deps (uses node:child_process + node:fs + node:os).
26
+ * - SAN list includes `127.0.0.1` + `::1` because modern browsers ignore
27
+ * CN and only honour SANs (Chrome 58+, Brave, Safari, Firefox).
28
+ * - `/etc/hosts` is printed, not auto-mutated — touching it behind the
29
+ * operator's back is a foot-gun (and would require sudo).
30
+ */
31
+ import { execFileSync, spawnSync } from 'node:child_process';
32
+ import { existsSync, mkdtempSync, readFileSync, readdirSync, writeFileSync, rmSync } from 'node:fs';
33
+ import { homedir, tmpdir } from 'node:os';
34
+ import { join, resolve } from 'node:path';
35
+ import { fileURLToPath } from 'node:url';
36
+ import { printError, printHeader, printInfo, printSuccess, printWarning } from '../output.js';
37
+ import { resolveKubectlContext } from '../lib/kubectl-context.js';
38
+ const SECRET_NAME = 'olam-host-cp-tls';
39
+ const NAMESPACE = 'olam';
40
+ const SAN_LIST = ['olam.local', '127.0.0.1', '::1'];
41
+ const RENEWAL_THRESHOLD_DAYS = 30;
42
+ const TRAEFIK_NAMESPACE = 'kube-system';
43
+ const TRAEFIK_SERVICE = 'traefik';
44
+ const MKCERT_INSTALL_URL = 'https://github.com/FiloSottile/mkcert#installation';
45
+ function defaultSpawn(cmd, args, opts) {
46
+ const r = spawnSync(cmd, [...args], {
47
+ encoding: 'utf-8',
48
+ timeout: opts?.timeout,
49
+ input: opts?.input,
50
+ });
51
+ return {
52
+ status: r.status,
53
+ stdout: r.stdout ?? '',
54
+ stderr: r.stderr ?? '',
55
+ };
56
+ }
57
+ /**
58
+ * Probe whether the mkcert root CA is already trusted on this machine.
59
+ *
60
+ * macOS: `mkcert -CAROOT` → directory; if `rootCA.pem` exists there AND
61
+ * `security find-certificate -c mkcert /Library/Keychains/System.keychain`
62
+ * exits 0, the CA is already in the system keychain.
63
+ * Linux/other: CA file existence alone is used as a proxy for "trusted"
64
+ * (nss-based stores don't need sudo and mkcert handles them idempotently).
65
+ *
66
+ * Returns false on any probe failure so the caller falls back to attempting
67
+ * `mkcert -install` (safe — mkcert itself is idempotent).
68
+ */
69
+ export function isMkcertRootTrusted(mkcertPath, spawn) {
70
+ // Find the CA root directory.
71
+ const carootResult = spawn(mkcertPath, ['-CAROOT']);
72
+ if (carootResult.status !== 0)
73
+ return false;
74
+ const caRoot = carootResult.stdout.trim();
75
+ if (caRoot.length === 0)
76
+ return false;
77
+ const caPem = join(caRoot, 'rootCA.pem');
78
+ if (!existsSync(caPem))
79
+ return false;
80
+ // macOS: verify the cert is actually in the system keychain.
81
+ if (process.platform === 'darwin') {
82
+ const check = spawn('security', [
83
+ 'find-certificate', '-c', 'mkcert', '/Library/Keychains/System.keychain',
84
+ ]);
85
+ return check.status === 0;
86
+ }
87
+ // Linux / other: CA file presence is sufficient (mkcert uses nss, no sudo needed).
88
+ return true;
89
+ }
90
+ /**
91
+ * Locate the bundled TLS Secret template. The CLI ships under
92
+ * `packages/cli/dist/commands/services-tls.js`; the manifests live under
93
+ * `packages/host-cp/k8s/manifests/` — three `..` hops from the dist file
94
+ * resolve to the package root. From source (`src/commands/services-tls.ts`)
95
+ * the same hop count works because the relative layout matches.
96
+ */
97
+ function defaultTemplatePath() {
98
+ const here = fileURLToPath(import.meta.url);
99
+ return resolve(here, '..', '..', '..', '..', 'host-cp', 'k8s', 'manifests', '65-tls-secret-template.yaml.tmpl');
100
+ }
101
+ /** Parse the NotAfter timestamp from PEM-encoded cert via `openssl x509`. */
102
+ function readCertNotAfter(pemBytes, spawnImpl) {
103
+ const r = spawnImpl('openssl', ['x509', '-noout', '-enddate'], { input: pemBytes });
104
+ if (r.status !== 0)
105
+ return null;
106
+ // openssl emits e.g. `notAfter=May 26 12:00:00 2028 GMT`
107
+ const match = r.stdout.match(/notAfter=(.+)/);
108
+ if (!match || match[1] === undefined)
109
+ return null;
110
+ const d = new Date(match[1].trim());
111
+ return Number.isNaN(d.getTime()) ? null : d;
112
+ }
113
+ /** Resolve mkcert binary, falling back to the well-known Homebrew location. */
114
+ function locateMkcert(deps) {
115
+ if (deps.mkcertPath !== undefined)
116
+ return deps.mkcertPath;
117
+ const spawn = deps.spawnImpl ?? defaultSpawn;
118
+ const which = spawn('which', ['mkcert']);
119
+ if (which.status === 0) {
120
+ const path = which.stdout.trim();
121
+ if (path.length > 0)
122
+ return path;
123
+ }
124
+ // Homebrew default fallback — common case on operator macs.
125
+ const brewPath = '/opt/homebrew/bin/mkcert';
126
+ const exists = spawn('test', ['-x', brewPath]);
127
+ if (exists.status === 0)
128
+ return brewPath;
129
+ return null;
130
+ }
131
+ /** Fetch the current TLS Secret's certificate body (PEM), or null when missing. */
132
+ function fetchExistingCertPem(kubectl, context, spawn) {
133
+ const r = spawn(kubectl, [
134
+ '--context', context,
135
+ '-n', NAMESPACE,
136
+ 'get', 'secret', SECRET_NAME,
137
+ '-o', 'jsonpath={.data.tls\\.crt}',
138
+ ]);
139
+ if (r.status !== 0 || r.stdout.trim().length === 0)
140
+ return null;
141
+ try {
142
+ return Buffer.from(r.stdout.trim(), 'base64').toString('utf-8');
143
+ }
144
+ catch {
145
+ return null;
146
+ }
147
+ }
148
+ /** Resolve Traefik's `websecure` NodePort (HTTPS edge), or null on failure. */
149
+ export function resolveTraefikHttpsPort(spawnArg, context) {
150
+ const spawn = spawnArg ?? defaultSpawn;
151
+ const args = [
152
+ ...(context !== undefined ? ['--context', context] : []),
153
+ '-n', TRAEFIK_NAMESPACE,
154
+ 'get', 'svc', TRAEFIK_SERVICE,
155
+ '-o', 'jsonpath={.spec.ports[?(@.name=="websecure")].nodePort}',
156
+ ];
157
+ const r = spawn('kubectl', args);
158
+ if (r.status !== 0)
159
+ return null;
160
+ const n = Number.parseInt(r.stdout.trim(), 10);
161
+ return Number.isFinite(n) && n > 0 ? n : null;
162
+ }
163
+ /** Check whether `olam.local` is already present in /etc/hosts. */
164
+ function isHostsEntryPresent() {
165
+ try {
166
+ const body = readFileSync('/etc/hosts', 'utf-8');
167
+ return /^[^#\n]*\bolam\.local\b/m.test(body);
168
+ }
169
+ catch {
170
+ return false;
171
+ }
172
+ }
173
+ /**
174
+ * Pure renderer: substitutes the placeholders in the TLS Secret template.
175
+ * Exported for snapshot testing.
176
+ */
177
+ export function renderTlsSecret(template, crtBase64, keyBase64) {
178
+ return template
179
+ .replace('__TLS_CRT_BASE64__', crtBase64)
180
+ .replace('__TLS_KEY_BASE64__', keyBase64);
181
+ }
182
+ /**
183
+ * The full tls-install flow. Returns a structured result so the caller in
184
+ * `services up` can decide whether to print the success URL or fall back.
185
+ */
186
+ export async function tlsInstall(deps = {}) {
187
+ const spawn = deps.spawnImpl ?? defaultSpawn;
188
+ const now = deps.now ?? new Date();
189
+ // 1. Resolve kubectl context.
190
+ let context = deps.kubectlContext;
191
+ if (context === undefined) {
192
+ const resolved = resolveKubectlContext();
193
+ if (resolved.error !== undefined || resolved.context === undefined) {
194
+ return {
195
+ action: 'failed',
196
+ reason: 'kubectl context not pinned. Fix one of these ways:\n' +
197
+ ' 1. Pin it for future runs: olam config set host.kubectl_context_pinned <your-context>\n' +
198
+ ' (current context = `kubectl config current-context`)\n' +
199
+ ' 2. One-off override: OLAM_K8S_CONTEXT_ACK=<your-context> olam services tls-install\n' +
200
+ 'See docs/architecture/peripheral-services-on-k3s.md for the full setup.',
201
+ };
202
+ }
203
+ context = resolved.context;
204
+ }
205
+ // 1b. Apply the IngressRoute manifest. The Secret + IngressRoute are a
206
+ // pair — without the IngressRoute, Traefik won't route olam.local
207
+ // to host-cp even though the cert is present. Applying here (not
208
+ // just in `services up`) makes `tls-install` work standalone.
209
+ // Non-fatal: a missing CRD (cluster without Traefik) shouldn't block
210
+ // cert provisioning; we surface a warning via debug log + continue.
211
+ const ingressResult = applyIngressManifests(context);
212
+ if (!ingressResult.ok && process.env['OLAM_DEBUG_TLS'] === '1') {
213
+ process.stderr.write(`[olam-tls] IngressRoute apply skipped: ${ingressResult.reason}\n`);
214
+ }
215
+ // 2. Locate mkcert.
216
+ const mkcert = locateMkcert(deps);
217
+ if (mkcert === null) {
218
+ return {
219
+ action: 'failed',
220
+ reason: `mkcert is required but was not found on PATH.\n` +
221
+ ` Install: brew install mkcert (macOS) or see ${MKCERT_INSTALL_URL}\n` +
222
+ ` Then re-run: olam services tls-install`,
223
+ };
224
+ }
225
+ // 3. Idempotency check — skip if cert is fresh enough.
226
+ const existingPem = fetchExistingCertPem('kubectl', context, spawn);
227
+ if (existingPem !== null) {
228
+ const notAfter = readCertNotAfter(existingPem, spawn);
229
+ if (notAfter !== null) {
230
+ const daysLeft = (notAfter.getTime() - now.getTime()) / (1000 * 60 * 60 * 24);
231
+ if (daysLeft > RENEWAL_THRESHOLD_DAYS) {
232
+ const httpsPort = resolveTraefikHttpsPort(spawn, context) ?? undefined;
233
+ return {
234
+ action: 'skipped',
235
+ reason: `existing cert valid for ${Math.floor(daysLeft)} more days; no action taken`,
236
+ httpsPort,
237
+ };
238
+ }
239
+ }
240
+ }
241
+ // 4. Trust the local CA root — skip when already trusted, handle non-TTY gracefully.
242
+ if (deps.skipRootInstall !== true) {
243
+ const alreadyTrusted = isMkcertRootTrusted(mkcert, spawn);
244
+ if (alreadyTrusted) {
245
+ if (process.env['OLAM_DEBUG_TLS'] === '1') {
246
+ process.stderr.write('[olam-tls] mkcert root CA already trusted — skipping -install\n');
247
+ }
248
+ }
249
+ else {
250
+ const isTty = (deps.isTtyAttached ?? (() => process.stdin.isTTY === true))();
251
+ if (!isTty) {
252
+ // No terminal — sudo prompt would hang. Surface an actionable hint instead.
253
+ return {
254
+ action: 'failed',
255
+ reason: 'mkcert root CA is not yet trusted, and this terminal can\'t prompt for sudo.\n' +
256
+ 'Run this once manually:\n' +
257
+ ' sudo mkcert -install\n' +
258
+ 'Then re-run: olam services tls-install',
259
+ };
260
+ }
261
+ // Interactive path — pass stdio through so the sudo prompt reaches the operator.
262
+ try {
263
+ execFileSync(mkcert, ['-install'], { stdio: 'inherit' });
264
+ }
265
+ catch {
266
+ return {
267
+ action: 'failed',
268
+ reason: 'mkcert -install failed — ensure mkcert is installed and try again.',
269
+ };
270
+ }
271
+ }
272
+ }
273
+ // 5. Mint the cert in a clean tmp dir so we don't pollute cwd.
274
+ const workDir = mkdtempSync(join(tmpdir(), 'olam-tls-'));
275
+ try {
276
+ const crtPath = join(workDir, 'tls.crt');
277
+ const keyPath = join(workDir, 'tls.key');
278
+ const mint = spawn(mkcert, [
279
+ '-cert-file', crtPath,
280
+ '-key-file', keyPath,
281
+ ...SAN_LIST,
282
+ ]);
283
+ if (mint.status !== 0) {
284
+ return {
285
+ action: 'failed',
286
+ reason: `mkcert failed to mint cert: ${mint.stderr.trim() || mint.stdout.trim()}`,
287
+ };
288
+ }
289
+ // mkcert sometimes writes via temp file → ensure both exist before reading.
290
+ const files = readdirSync(workDir);
291
+ if (!files.includes('tls.crt') || !files.includes('tls.key')) {
292
+ return {
293
+ action: 'failed',
294
+ reason: `mkcert succeeded but tls.crt/tls.key not found in ${workDir}`,
295
+ };
296
+ }
297
+ // 6. Generate the Secret manifest via kubectl itself. This eliminates the
298
+ // template-substitution failure mode (where any base64-encoding subtlety
299
+ // in the YAML produces the cryptic
300
+ // "illegal base64 data at input byte 0"
301
+ // server-side rejection). `kubectl create secret tls --dry-run=client`
302
+ // knows how to format a Secret correctly — no manual base64 step on our
303
+ // side. The two-step pipeline (generate → apply) preserves idempotency
304
+ // via `kubectl apply` and supports `--dry-run=client` so we never touch
305
+ // the cluster during the generate step.
306
+ const generate = spawn('kubectl', [
307
+ '--context', context,
308
+ '-n', NAMESPACE,
309
+ 'create', 'secret', 'tls', SECRET_NAME,
310
+ `--cert=${crtPath}`,
311
+ `--key=${keyPath}`,
312
+ '--dry-run=client',
313
+ '-o', 'yaml',
314
+ ]);
315
+ if (generate.status !== 0) {
316
+ return {
317
+ action: 'failed',
318
+ reason: `kubectl create secret tls --dry-run failed: ${generate.stderr.trim() || generate.stdout.trim()}`,
319
+ };
320
+ }
321
+ if (process.env['OLAM_DEBUG_TLS'] === '1') {
322
+ process.stderr.write(`[olam-tls] generated Secret manifest:\n${generate.stdout}\n`);
323
+ }
324
+ // 7. Apply the generated Secret. Idempotent — `kubectl apply` patches when
325
+ // the Secret already exists.
326
+ const apply = spawn('kubectl', [
327
+ '--context', context,
328
+ '-n', NAMESPACE,
329
+ 'apply', '-f', '-',
330
+ ], { input: generate.stdout });
331
+ if (apply.status !== 0) {
332
+ return {
333
+ action: 'failed',
334
+ reason: `kubectl apply failed: ${apply.stderr.trim() || apply.stdout.trim()}`,
335
+ };
336
+ }
337
+ const httpsPort = resolveTraefikHttpsPort(spawn, context) ?? undefined;
338
+ return {
339
+ action: existingPem === null ? 'installed' : 'renewed',
340
+ httpsPort,
341
+ };
342
+ }
343
+ finally {
344
+ rmSync(workDir, { recursive: true, force: true });
345
+ }
346
+ }
347
+ /** CLI rendering — formats the structured result for the operator. */
348
+ async function runTlsInstallCommand() {
349
+ printHeader('TLS install (k3d / Traefik)');
350
+ const result = await tlsInstall();
351
+ if (result.action === 'failed') {
352
+ printError(result.reason ?? 'tls-install failed');
353
+ return { exitCode: 1 };
354
+ }
355
+ if (result.action === 'skipped') {
356
+ printInfo(SECRET_NAME, result.reason ?? 'skipped');
357
+ }
358
+ else if (result.action === 'installed') {
359
+ printSuccess(`${SECRET_NAME} created`);
360
+ }
361
+ else {
362
+ printSuccess(`${SECRET_NAME} renewed`);
363
+ }
364
+ // Operator-facing post-conditions.
365
+ if (!isHostsEntryPresent()) {
366
+ printWarning(`Add olam.local to /etc/hosts before the SPA will resolve:\n` +
367
+ ` echo '127.0.0.1 olam.local' | sudo tee -a /etc/hosts`);
368
+ }
369
+ if (result.httpsPort !== undefined) {
370
+ printSuccess(`SPA reachable at https://olam.local:${result.httpsPort}`);
371
+ }
372
+ else {
373
+ printWarning('Could not discover Traefik websecure NodePort. Verify with:\n' +
374
+ ' kubectl -n kube-system get svc traefik');
375
+ }
376
+ return { exitCode: 0 };
377
+ }
378
+ /** Auto-invoke seam used by `olam services up` — silent when skipped, loud when failed. */
379
+ export async function ensureTlsInstalled() {
380
+ return tlsInstall();
381
+ }
382
+ export function registerServicesTls(services) {
383
+ services
384
+ .command('tls-install')
385
+ .description('Provision a locally-trusted TLS cert (mkcert) for the Traefik IngressRoute')
386
+ .action(async () => {
387
+ const result = await runTlsInstallCommand();
388
+ if (result.exitCode !== 0)
389
+ process.exitCode = result.exitCode;
390
+ });
391
+ }
392
+ /** Constants exported for tests + cross-module usage. */
393
+ export const TLS_SECRET_NAME = SECRET_NAME;
394
+ export const TLS_NAMESPACE = NAMESPACE;
395
+ export const TLS_RENEWAL_THRESHOLD_DAYS = RENEWAL_THRESHOLD_DAYS;
396
+ export const TLS_SAN_LIST = SAN_LIST;
397
+ /** Used by services.ts to write a "did we already do this" probe. */
398
+ export function tlsSecretExists(spawnArg, context) {
399
+ const spawn = spawnArg ?? defaultSpawn;
400
+ const args = [
401
+ ...(context !== undefined ? ['--context', context] : []),
402
+ '-n', NAMESPACE,
403
+ 'get', 'secret', SECRET_NAME,
404
+ '--ignore-not-found',
405
+ '-o', 'name',
406
+ ];
407
+ const r = spawn('kubectl', args);
408
+ return r.status === 0 && r.stdout.trim().length > 0;
409
+ }
410
+ /**
411
+ * Best-effort: `execFileSync('kubectl', ...)` to apply the bundled
412
+ * IngressRoute + Service manifests when `services up` first runs. Idempotent
413
+ * via `kubectl apply`. We DON'T do this from tls-install (single-responsibility:
414
+ * tls-install only handles certs); services.ts orchestrates the manifest apply.
415
+ */
416
+ export function applyIngressManifests(context) {
417
+ const here = fileURLToPath(import.meta.url);
418
+ const manifestDir = resolve(here, '..', '..', '..', '..', 'host-cp', 'k8s', 'manifests');
419
+ const ingressManifest = join(manifestDir, '70-ingressroute.yaml');
420
+ try {
421
+ execFileSync('kubectl', [
422
+ '--context', context,
423
+ 'apply', '-f', ingressManifest,
424
+ ], { stdio: 'pipe' });
425
+ return { ok: true };
426
+ }
427
+ catch (err) {
428
+ const msg = err instanceof Error && 'stderr' in err
429
+ ? String(err.stderr ?? '').trim()
430
+ : err instanceof Error ? err.message : String(err);
431
+ return { ok: false, reason: msg };
432
+ }
433
+ }
434
+ //# sourceMappingURL=services-tls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services-tls.js","sourceRoot":"","sources":["../../src/commands/services-tls.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/commands/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/commands/services.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ import { readConfig } from '../lib/config.js';
23
23
  import { kubectlWrap } from '../lib/kubectl-wrap.js';
24
24
  import { PERIPHERALS } from '../lib/peripheral-registry.js';
25
25
  import { resolveKubectlContext } from '../lib/kubectl-context.js';
26
+ import { applyIngressManifests, ensureTlsInstalled, registerServicesTls, resolveTraefikHttpsPort, tlsSecretExists, } from './services-tls.js';
26
27
  // ── McpAuthContainerController ────────────────────────────────────
27
28
  //
28
29
  // Mirrors AuthContainerController (packages/core/src/auth/container.ts).
@@ -164,6 +165,31 @@ export async function servicesUpKubernetes(deps = {}) {
164
165
  printSuccess(`${deploymentName}: scaled to 1 replica`);
165
166
  }
166
167
  }
168
+ // Apply the Traefik IngressRoute + bootstrap TLS on first run. Idempotent:
169
+ // `kubectl apply` is a no-op when the IngressRoute is unchanged, and the
170
+ // tls-install seam skips when the secret already exists with a fresh cert.
171
+ // Non-fatal — if Traefik isn't installed, the SPA still works via port-forward.
172
+ const ingressResult = applyIngressManifests(context);
173
+ if (!ingressResult.ok) {
174
+ printWarning(`IngressRoute apply failed (SPA still reachable via port-forward): ${ingressResult.reason ?? 'unknown'}`);
175
+ }
176
+ else {
177
+ printSuccess('IngressRoute applied (https://olam.local)');
178
+ }
179
+ if (!tlsSecretExists(undefined, context)) {
180
+ const tlsResult = await ensureTlsInstalled();
181
+ if (tlsResult.action === 'failed') {
182
+ printWarning(`TLS cert install skipped (SPA still reachable via port-forward): ${tlsResult.reason ?? 'unknown'}`);
183
+ }
184
+ else if (tlsResult.action === 'installed') {
185
+ printSuccess('TLS cert installed (mkcert)');
186
+ }
187
+ }
188
+ // Surface the HTTPS URL when discoverable.
189
+ const httpsPort = resolveTraefikHttpsPort(undefined, context);
190
+ if (httpsPort !== null) {
191
+ printInfo('SPA (HTTPS, h2)', `https://olam.local:${httpsPort}`);
192
+ }
167
193
  return { exitCode };
168
194
  }
169
195
  /**
@@ -379,6 +405,10 @@ export async function servicesUp() {
379
405
  if (!ready) {
380
406
  printError(`olam-auth started but /health did not respond within ${MCP_AUTH_HEALTH_TIMEOUT_MS / 1000}s.`);
381
407
  dumpContainerLogs('olam-auth');
408
+ printError('\nTry:');
409
+ printError(' - olam doctor # check service prereqs');
410
+ printError(' - docker logs olam-auth # full logs');
411
+ printError(' - docker restart olam-auth # restart');
382
412
  return { exitCode: 1 };
383
413
  }
384
414
  printSuccess('olam-auth started');
@@ -400,6 +430,10 @@ export async function servicesUp() {
400
430
  if (!ready) {
401
431
  printError(`olam-mcp-auth started but /health did not respond within ${MCP_AUTH_HEALTH_TIMEOUT_MS / 1000}s.`);
402
432
  dumpContainerLogs('olam-mcp-auth');
433
+ printError('\nTry:');
434
+ printError(' - olam doctor # check service prereqs');
435
+ printError(' - docker logs olam-mcp-auth # full logs');
436
+ printError(' - docker restart olam-mcp-auth # restart');
403
437
  return { exitCode: 1 };
404
438
  }
405
439
  printSuccess('olam-mcp-auth started');
@@ -480,6 +514,10 @@ export async function servicesUp() {
480
514
  if (!ready) {
481
515
  printError(`olam-memory-service started but /agentmemory/livez did not respond within ${MEMORY_SERVICE_HEALTH_TIMEOUT_MS / 1000}s.`);
482
516
  dumpContainerLogs('olam-memory-service');
517
+ printError('\nTry:');
518
+ printError(' - olam doctor # check service prereqs');
519
+ printError(' - docker logs olam-memory-service # full logs');
520
+ printError(' - docker restart olam-memory-service # restart');
483
521
  return { exitCode: 1 };
484
522
  }
485
523
  printSuccess('olam-memory-service started');
@@ -591,7 +629,7 @@ export function servicesStatusJson(deps = {}) {
591
629
  export function registerServices(program) {
592
630
  const services = program
593
631
  .command('services')
594
- .description('Manage Olam service containers. Substrate-aware: compose uses docker; kubernetes uses kubectl.');
632
+ .description('Manage Olam service containers (up/down/status/logs)');
595
633
  services
596
634
  .command('up')
597
635
  .description('Start all service containers (idempotent)')
@@ -643,6 +681,7 @@ export function registerServices(program) {
643
681
  servicesStatus();
644
682
  }
645
683
  });
684
+ registerServicesTls(services);
646
685
  services
647
686
  .command('restart <name>')
648
687
  .description('Restart a named service (kubernetes: kubectl rollout restart; compose: docker compose restart)')