@pleri/olam-cli 0.1.180 → 0.1.185

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 (209) hide show
  1. package/dist/agent-stream/agent-sdk-to-chunks.js +44 -30
  2. package/dist/ask/checkout.d.ts +19 -0
  3. package/dist/ask/checkout.d.ts.map +1 -0
  4. package/dist/ask/checkout.js +40 -0
  5. package/dist/ask/checkout.js.map +1 -0
  6. package/dist/ask/knowledge-pack-builder.d.ts +72 -0
  7. package/dist/ask/knowledge-pack-builder.d.ts.map +1 -0
  8. package/dist/ask/knowledge-pack-builder.js +91 -0
  9. package/dist/ask/knowledge-pack-builder.js.map +1 -0
  10. package/dist/ask/knowledge-pack.generated.d.ts +8 -0
  11. package/dist/ask/knowledge-pack.generated.d.ts.map +1 -0
  12. package/dist/ask/knowledge-pack.generated.js +1947 -0
  13. package/dist/ask/knowledge-pack.generated.js.map +1 -0
  14. package/dist/ask/one-shot.d.ts +21 -0
  15. package/dist/ask/one-shot.d.ts.map +1 -0
  16. package/dist/ask/one-shot.js +50 -0
  17. package/dist/ask/one-shot.js.map +1 -0
  18. package/dist/ask/repl.d.ts +30 -0
  19. package/dist/ask/repl.d.ts.map +1 -0
  20. package/dist/ask/repl.js +109 -0
  21. package/dist/ask/repl.js.map +1 -0
  22. package/dist/ask/sdk-client.d.ts +87 -0
  23. package/dist/ask/sdk-client.d.ts.map +1 -0
  24. package/dist/ask/sdk-client.js +118 -0
  25. package/dist/ask/sdk-client.js.map +1 -0
  26. package/dist/ask/system-prompt.d.ts +30 -0
  27. package/dist/ask/system-prompt.d.ts.map +1 -0
  28. package/dist/ask/system-prompt.js +31 -0
  29. package/dist/ask/system-prompt.js.map +1 -0
  30. package/dist/commands/ask.d.ts +27 -0
  31. package/dist/commands/ask.d.ts.map +1 -0
  32. package/dist/commands/ask.js +63 -0
  33. package/dist/commands/ask.js.map +1 -0
  34. package/dist/commands/auth-list-json.d.ts +53 -0
  35. package/dist/commands/auth-list-json.d.ts.map +1 -0
  36. package/dist/commands/auth-list-json.js +47 -0
  37. package/dist/commands/auth-list-json.js.map +1 -0
  38. package/dist/commands/auth.d.ts.map +1 -1
  39. package/dist/commands/auth.js +80 -19
  40. package/dist/commands/auth.js.map +1 -1
  41. package/dist/commands/config.d.ts.map +1 -1
  42. package/dist/commands/config.js +93 -0
  43. package/dist/commands/config.js.map +1 -1
  44. package/dist/commands/destroy.d.ts +41 -0
  45. package/dist/commands/destroy.d.ts.map +1 -1
  46. package/dist/commands/destroy.js +81 -33
  47. package/dist/commands/destroy.js.map +1 -1
  48. package/dist/commands/dispatch-resolve.d.ts +54 -0
  49. package/dist/commands/dispatch-resolve.d.ts.map +1 -0
  50. package/dist/commands/dispatch-resolve.js +105 -0
  51. package/dist/commands/dispatch-resolve.js.map +1 -0
  52. package/dist/commands/dispatch.d.ts.map +1 -1
  53. package/dist/commands/dispatch.js +40 -9
  54. package/dist/commands/dispatch.js.map +1 -1
  55. package/dist/commands/doctor.js +11 -11
  56. package/dist/commands/doctor.js.map +1 -1
  57. package/dist/commands/flywheel/k5-validate.d.ts +31 -0
  58. package/dist/commands/flywheel/k5-validate.d.ts.map +1 -1
  59. package/dist/commands/flywheel/k5-validate.js +80 -19
  60. package/dist/commands/flywheel/k5-validate.js.map +1 -1
  61. package/dist/commands/keys-list-json.d.ts +55 -0
  62. package/dist/commands/keys-list-json.d.ts.map +1 -0
  63. package/dist/commands/keys-list-json.js +54 -0
  64. package/dist/commands/keys-list-json.js.map +1 -0
  65. package/dist/commands/keys.d.ts.map +1 -1
  66. package/dist/commands/keys.js +6 -0
  67. package/dist/commands/keys.js.map +1 -1
  68. package/dist/commands/kg-classify.d.ts.map +1 -1
  69. package/dist/commands/kg-classify.js +20 -0
  70. package/dist/commands/kg-classify.js.map +1 -1
  71. package/dist/commands/kg-doctor.d.ts +67 -6
  72. package/dist/commands/kg-doctor.d.ts.map +1 -1
  73. package/dist/commands/kg-doctor.js +126 -46
  74. package/dist/commands/kg-doctor.js.map +1 -1
  75. package/dist/commands/lanes-list-json.d.ts +69 -0
  76. package/dist/commands/lanes-list-json.d.ts.map +1 -0
  77. package/dist/commands/lanes-list-json.js +42 -0
  78. package/dist/commands/lanes-list-json.js.map +1 -0
  79. package/dist/commands/lanes.d.ts.map +1 -1
  80. package/dist/commands/lanes.js +18 -7
  81. package/dist/commands/lanes.js.map +1 -1
  82. package/dist/commands/list.d.ts +27 -0
  83. package/dist/commands/list.d.ts.map +1 -1
  84. package/dist/commands/list.js +67 -19
  85. package/dist/commands/list.js.map +1 -1
  86. package/dist/commands/memory/status.d.ts +18 -0
  87. package/dist/commands/memory/status.d.ts.map +1 -1
  88. package/dist/commands/memory/status.js +38 -2
  89. package/dist/commands/memory/status.js.map +1 -1
  90. package/dist/commands/memory-service-container.d.ts +44 -0
  91. package/dist/commands/memory-service-container.d.ts.map +1 -1
  92. package/dist/commands/memory-service-container.js +49 -0
  93. package/dist/commands/memory-service-container.js.map +1 -1
  94. package/dist/commands/plans-list-json.d.ts +77 -0
  95. package/dist/commands/plans-list-json.d.ts.map +1 -0
  96. package/dist/commands/plans-list-json.js +61 -0
  97. package/dist/commands/plans-list-json.js.map +1 -0
  98. package/dist/commands/plans.d.ts.map +1 -1
  99. package/dist/commands/plans.js +10 -0
  100. package/dist/commands/plans.js.map +1 -1
  101. package/dist/commands/ps.d.ts +32 -0
  102. package/dist/commands/ps.d.ts.map +1 -1
  103. package/dist/commands/ps.js +34 -0
  104. package/dist/commands/ps.js.map +1 -1
  105. package/dist/commands/repos-list-json.d.ts +58 -0
  106. package/dist/commands/repos-list-json.d.ts.map +1 -0
  107. package/dist/commands/repos-list-json.js +45 -0
  108. package/dist/commands/repos-list-json.js.map +1 -0
  109. package/dist/commands/repos.d.ts +1 -1
  110. package/dist/commands/repos.d.ts.map +1 -1
  111. package/dist/commands/repos.js +12 -2
  112. package/dist/commands/repos.js.map +1 -1
  113. package/dist/commands/runbooks.d.ts +32 -0
  114. package/dist/commands/runbooks.d.ts.map +1 -1
  115. package/dist/commands/runbooks.js +79 -22
  116. package/dist/commands/runbooks.js.map +1 -1
  117. package/dist/commands/services.d.ts +47 -1
  118. package/dist/commands/services.d.ts.map +1 -1
  119. package/dist/commands/services.js +59 -33
  120. package/dist/commands/services.js.map +1 -1
  121. package/dist/commands/skills-source.d.ts.map +1 -1
  122. package/dist/commands/skills-source.js +77 -2
  123. package/dist/commands/skills-source.js.map +1 -1
  124. package/dist/commands/skills.d.ts +27 -0
  125. package/dist/commands/skills.d.ts.map +1 -1
  126. package/dist/commands/skills.js +17 -2
  127. package/dist/commands/skills.js.map +1 -1
  128. package/dist/commands/upgrade-history.d.ts +0 -2
  129. package/dist/commands/upgrade-history.d.ts.map +1 -1
  130. package/dist/commands/upgrade-history.js +0 -6
  131. package/dist/commands/upgrade-history.js.map +1 -1
  132. package/dist/commands/upgrade-lock.d.ts +0 -9
  133. package/dist/commands/upgrade-lock.d.ts.map +1 -1
  134. package/dist/commands/upgrade-lock.js +1 -1
  135. package/dist/commands/upgrade-lock.js.map +1 -1
  136. package/dist/commands/workspace-list-json.d.ts +73 -0
  137. package/dist/commands/workspace-list-json.d.ts.map +1 -0
  138. package/dist/commands/workspace-list-json.js +59 -0
  139. package/dist/commands/workspace-list-json.js.map +1 -0
  140. package/dist/commands/workspace.d.ts.map +1 -1
  141. package/dist/commands/workspace.js +7 -1
  142. package/dist/commands/workspace.js.map +1 -1
  143. package/dist/commands/world-snapshot.d.ts +13 -0
  144. package/dist/commands/world-snapshot.d.ts.map +1 -1
  145. package/dist/commands/world-snapshot.js +81 -1
  146. package/dist/commands/world-snapshot.js.map +1 -1
  147. package/dist/commands/yolo.d.ts +0 -4
  148. package/dist/commands/yolo.d.ts.map +1 -1
  149. package/dist/commands/yolo.js +2 -2
  150. package/dist/commands/yolo.js.map +1 -1
  151. package/dist/image-digests.json +8 -8
  152. package/dist/index.js +6097 -2563
  153. package/dist/index.js.map +1 -1
  154. package/dist/lib/anthropic-base-url-file.d.ts +37 -0
  155. package/dist/lib/anthropic-base-url-file.d.ts.map +1 -0
  156. package/dist/lib/anthropic-base-url-file.js +46 -0
  157. package/dist/lib/anthropic-base-url-file.js.map +1 -0
  158. package/dist/lib/auth-remote.d.ts +9 -0
  159. package/dist/lib/auth-remote.d.ts.map +1 -1
  160. package/dist/lib/auth-remote.js +19 -4
  161. package/dist/lib/auth-remote.js.map +1 -1
  162. package/dist/lib/cf-access-token.d.ts +32 -0
  163. package/dist/lib/cf-access-token.d.ts.map +1 -0
  164. package/dist/lib/cf-access-token.js +52 -0
  165. package/dist/lib/cf-access-token.js.map +1 -0
  166. package/dist/lib/config.d.ts +17 -3
  167. package/dist/lib/config.d.ts.map +1 -1
  168. package/dist/lib/config.js +28 -4
  169. package/dist/lib/config.js.map +1 -1
  170. package/dist/lib/k8s-bootstrap.d.ts.map +1 -1
  171. package/dist/lib/k8s-bootstrap.js +13 -1
  172. package/dist/lib/k8s-bootstrap.js.map +1 -1
  173. package/dist/lib/k8s-secret-render.d.ts +2 -0
  174. package/dist/lib/k8s-secret-render.d.ts.map +1 -1
  175. package/dist/lib/k8s-secret-render.js +27 -0
  176. package/dist/lib/k8s-secret-render.js.map +1 -1
  177. package/dist/lib/kubectl-context.d.ts +49 -0
  178. package/dist/lib/kubectl-context.d.ts.map +1 -1
  179. package/dist/lib/kubectl-context.js +64 -2
  180. package/dist/lib/kubectl-context.js.map +1 -1
  181. package/dist/lib/peripheral-registry.d.ts +1 -1
  182. package/dist/lib/peripheral-registry.d.ts.map +1 -1
  183. package/dist/lib/peripheral-registry.js +13 -0
  184. package/dist/lib/peripheral-registry.js.map +1 -1
  185. package/dist/lib/upgrade-kubernetes.d.ts +13 -0
  186. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
  187. package/dist/lib/upgrade-kubernetes.js +42 -9
  188. package/dist/lib/upgrade-kubernetes.js.map +1 -1
  189. package/dist/mcp-server.js +2624 -1041
  190. package/hermes-bundle/version.json +1 -1
  191. package/host-cp/k8s/manifests/30-configmap.yaml +11 -6
  192. package/host-cp/k8s/manifests/45-pvc.yaml +6 -2
  193. package/host-cp/k8s/manifests/50-deployment.yaml +15 -1
  194. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
  195. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
  196. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
  197. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
  198. package/host-cp/k8s/templates/chunks-postgres-secret-template.yaml +24 -0
  199. package/host-cp/k8s/templates/plan-chat-service-secret-template.yaml +35 -0
  200. package/host-cp/observability/trace-summary.mjs +267 -0
  201. package/host-cp/src/bootstrap-selective.mjs +30 -28
  202. package/host-cp/src/host-stream.mjs +52 -0
  203. package/host-cp/src/plan-chat-service.mjs +99 -74
  204. package/host-cp/src/redirect.mjs +7 -0
  205. package/host-cp/src/router.mjs +168 -0
  206. package/host-cp/src/serve-only-config.mjs +85 -0
  207. package/host-cp/src/server.mjs +482 -217
  208. package/host-cp/src/world-services.mjs +136 -0
  209. package/package.json +4 -2
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Pure JSON serialiser for `olam repos list --json`.
3
+ *
4
+ * Kept separate from the command action so the wire contract is
5
+ * unit-testable without a filesystem round-trip (mirrors the pattern
6
+ * used by `auth-list-json.ts`, `renderPsJson` in ps.ts, and
7
+ * `servicesStatusJson` in services.ts).
8
+ *
9
+ * WHY this exists: agent/script drivers (CI pipelines, Rico, flywheel
10
+ * chain skills) need to discover registered repo paths before spawning
11
+ * worlds or dispatching work with `--repo`. The human table is colorized
12
+ * and reflows per terminal width, so scraping it is brittle and breaks
13
+ * when column widths change. This serialiser gives drivers a stable,
14
+ * color-free array: each entry carries the name, resolved path, and
15
+ * optional metadata needed to pick a repo without re-querying the registry.
16
+ *
17
+ * Secret redaction: the optional `url` field can carry HTTPS credentials
18
+ * in the URL userinfo component (e.g. `https://token:x-oauth-basic@github.com/...`).
19
+ * The serialiser redacts userinfo credentials with `***` before emitting,
20
+ * matching the same pattern used by `olam skills source list --json`.
21
+ * The `path` field is a local filesystem path and carries no secrets.
22
+ */
23
+ import type { RepoEntry } from '@olam/core/src/global-config/schema.js';
24
+ /**
25
+ * Per-repo row in the `repos list --json` payload.
26
+ * Field names are load-bearing — add new fields freely, never rename.
27
+ */
28
+ export interface RepoListJsonEntry {
29
+ /** Registered repo name (lowercase, digits, dash). */
30
+ readonly name: string;
31
+ /** Resolved absolute filesystem path (may still be tilde-prefixed when stored as such). */
32
+ readonly path: string;
33
+ /**
34
+ * Git remote URL, if registered, with credentials redacted.
35
+ * null when the entry has no url field.
36
+ */
37
+ readonly url: string | null;
38
+ /** Optional human-readable description. */
39
+ readonly description: string | null;
40
+ /** Default branch name (e.g. "main"). null when not set. */
41
+ readonly defaultBranch: string | null;
42
+ /** Unix epoch ms when the entry was first registered. */
43
+ readonly addedAt: number;
44
+ /** Unix epoch ms of the last update. */
45
+ readonly updatedAt: number;
46
+ }
47
+ /** Top-level shape emitted by `olam repos list --json`. */
48
+ export interface ReposListJson {
49
+ /** Number of registered repos. */
50
+ readonly count: number;
51
+ readonly repos: readonly RepoListJsonEntry[];
52
+ }
53
+ /**
54
+ * Serialise the global repo registry to the stable `--json` wire shape.
55
+ * Returns a JSON string (no trailing newline — caller adds it).
56
+ */
57
+ export declare function renderReposListJson(entries: readonly RepoEntry[]): string;
58
+ //# sourceMappingURL=repos-list-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repos-list-json.d.ts","sourceRoot":"","sources":["../../src/commands/repos-list-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAGxE;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAkBzE"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Pure JSON serialiser for `olam repos list --json`.
3
+ *
4
+ * Kept separate from the command action so the wire contract is
5
+ * unit-testable without a filesystem round-trip (mirrors the pattern
6
+ * used by `auth-list-json.ts`, `renderPsJson` in ps.ts, and
7
+ * `servicesStatusJson` in services.ts).
8
+ *
9
+ * WHY this exists: agent/script drivers (CI pipelines, Rico, flywheel
10
+ * chain skills) need to discover registered repo paths before spawning
11
+ * worlds or dispatching work with `--repo`. The human table is colorized
12
+ * and reflows per terminal width, so scraping it is brittle and breaks
13
+ * when column widths change. This serialiser gives drivers a stable,
14
+ * color-free array: each entry carries the name, resolved path, and
15
+ * optional metadata needed to pick a repo without re-querying the registry.
16
+ *
17
+ * Secret redaction: the optional `url` field can carry HTTPS credentials
18
+ * in the URL userinfo component (e.g. `https://token:x-oauth-basic@github.com/...`).
19
+ * The serialiser redacts userinfo credentials with `***` before emitting,
20
+ * matching the same pattern used by `olam skills source list --json`.
21
+ * The `path` field is a local filesystem path and carries no secrets.
22
+ */
23
+ import { redactUrl } from '@olam/core/src/skill-sources/index.js';
24
+ /**
25
+ * Serialise the global repo registry to the stable `--json` wire shape.
26
+ * Returns a JSON string (no trailing newline — caller adds it).
27
+ */
28
+ export function renderReposListJson(entries) {
29
+ const rows = entries.map((e) => ({
30
+ name: e.name,
31
+ path: e.path,
32
+ // Redact credentials from URL userinfo (e.g. `https://token:x@host` → `https://token:***@host`).
33
+ url: e.url != null ? redactUrl(e.url) : null,
34
+ description: e.description ?? null,
35
+ defaultBranch: e.defaultBranch ?? null,
36
+ addedAt: e.addedAt,
37
+ updatedAt: e.updatedAt,
38
+ }));
39
+ const payload = {
40
+ count: rows.length,
41
+ repos: rows,
42
+ };
43
+ return JSON.stringify(payload);
44
+ }
45
+ //# sourceMappingURL=repos-list-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repos-list-json.js","sourceRoot":"","sources":["../../src/commands/repos-list-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAiClE;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,IAAI,GAAwB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,iGAAiG;QACjG,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QAC5C,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;QAClC,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI;QACtC,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,CAAC,CAAC,SAAS;KACvB,CAAC,CAAC,CAAC;IAEJ,MAAM,OAAO,GAAkB;QAC7B,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,KAAK,EAAE,IAAI;KACZ,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * olam repos — manage the global repo registry (~/.olam/config.json).
3
3
  *
4
- * olam repos list
4
+ * olam repos list [--json]
5
5
  * olam repos add --name <n> --path <p> [--description <d>] [--default-branch <b>]
6
6
  * olam repos remove <name>
7
7
  * olam repos update <name> [--path <p>] [--description <d>] [--default-branch <b>]
@@ -1 +1 @@
1
- {"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../../src/commands/repos.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+EpD"}
1
+ {"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../../src/commands/repos.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwFpD"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * olam repos — manage the global repo registry (~/.olam/config.json).
3
3
  *
4
- * olam repos list
4
+ * olam repos list [--json]
5
5
  * olam repos add --name <n> --path <p> [--description <d>] [--default-branch <b>]
6
6
  * olam repos remove <name>
7
7
  * olam repos update <name> [--path <p>] [--description <d>] [--default-branch <b>]
@@ -9,6 +9,7 @@
9
9
  import pc from 'picocolors';
10
10
  import { listRepos, addRepo, removeRepo, updateRepo, } from '@olam/core/src/global-config/index.js';
11
11
  import { printError, printSuccess, printHeader } from '../output.js';
12
+ import { renderReposListJson } from './repos-list-json.js';
12
13
  function asMessage(err) {
13
14
  return err instanceof Error ? err.message : String(err);
14
15
  }
@@ -19,8 +20,17 @@ export function registerRepos(program) {
19
20
  repos
20
21
  .command('list')
21
22
  .description('List all registered repos')
22
- .action(() => {
23
+ .option('--json', 'Emit a machine-readable JSON object instead of the human table', false)
24
+ .action((opts) => {
23
25
  const all = listRepos();
26
+ // --json: stable, scriptable contract. Always an object with a `repos` array
27
+ // (empty when no repos registered). Consumers gate on `count`; drivers
28
+ // iterate `repos[].name` + `repos[].path` to pick a repo for `--repo` flags.
29
+ // url credentials are redacted before emission (`:***@` substitution).
30
+ if (opts.json) {
31
+ process.stdout.write(renderReposListJson(all) + '\n');
32
+ return;
33
+ }
24
34
  if (all.length === 0) {
25
35
  console.log(pc.dim('0 repo(s) registered. Add one with: olam repos add --name <n> --path <p>'));
26
36
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"repos.js","sourceRoot":"","sources":["../../src/commands/repos.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,OAAO,EACP,UAAU,EACV,UAAU,GACX,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,SAAS,SAAS,CAAC,GAAY;IAC7B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAElD,KAAK;SACF,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC,CAAC;YAChG,OAAO;QACT,CAAC;QACD,WAAW,CAAC,GAAG,GAAG,CAAC,MAAM,UAAU,CAAC,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CACT,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACvE,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,4BAA4B,CAAC;SACzC,cAAc,CAAC,eAAe,EAAE,qCAAqC,CAAC;SACtE,cAAc,CAAC,eAAe,EAAE,0CAA0C,CAAC;SAC3E,MAAM,CAAC,sBAAsB,EAAE,qCAAqC,CAAC;SACrE,MAAM,CAAC,2BAA2B,EAAE,iCAAiC,CAAC;SACtE,MAAM,CAAC,CAAC,IAAkF,EAAE,EAAE;QAC7F,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC;gBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;YACH,YAAY,CAAC,oBAAoB,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;SACzC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,YAAY,CAAC,iBAAiB,IAAI,GAAG,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0BAA0B,CAAC;SACvC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;SACzC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC;SACnC,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;SACjD,MAAM,CAAC,2BAA2B,EAAE,oBAAoB,CAAC;SACzD,MAAM,CAAC,CAAC,IAAY,EAAE,IAAqE,EAAE,EAAE;QAC9F,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE;gBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;YACH,YAAY,CAAC,iBAAiB,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"repos.js","sourceRoot":"","sources":["../../src/commands/repos.ts"],"names":[],"mappings":"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"}
@@ -9,5 +9,37 @@
9
9
  * olam runbooks check-ports <name>
10
10
  */
11
11
  import type { Command } from 'commander';
12
+ import type { PortConflict, Runbook } from '@olam/core/src/global-config/index.js';
13
+ /**
14
+ * Pure renderer for `olam runbooks list`.
15
+ *
16
+ * Extracted so the `--json` contract is unit-testable without the global
17
+ * config store or a TTY (Rule 9). The JSON shape is a stable, color-free
18
+ * array of `{ name, repos, description, portCount, updatedAt }` so agents
19
+ * and scripts can enumerate runbook inventory without screen-scraping the
20
+ * colorized human table.
21
+ */
22
+ export declare function renderRunbookList(runbooks: readonly Runbook[], opts: {
23
+ json: boolean;
24
+ }): string;
25
+ /** One declared-port row in the `check-ports --json` payload. */
26
+ export interface PortStatusRow {
27
+ readonly repoName: string;
28
+ readonly serviceName: string;
29
+ readonly port: number;
30
+ readonly free: boolean;
31
+ /** Populated only when `free` is false. */
32
+ readonly occupant?: PortConflict['occupant'];
33
+ }
34
+ /**
35
+ * Build the structured port-status rows for a runbook, pairing each declared
36
+ * port against the resolved conflict set. Pure + deterministic so the
37
+ * `check-ports --json` contract is testable without binding real TCP ports
38
+ * (Rule 9 — the WHY: scripts gating world creation must read conflict state
39
+ * machine-readably, not parse the ✓/✗ glyph table).
40
+ */
41
+ export declare function buildPortStatusRows(portMap: Runbook['portMap'], conflicts: readonly PortConflict[]): PortStatusRow[];
42
+ /** Pure JSON renderer for `olam runbooks check-ports --json`. */
43
+ export declare function renderCheckPortsJson(name: string, rows: readonly PortStatusRow[], conflictCount: number): string;
12
44
  export declare function registerRunbooks(program: Command): void;
13
45
  //# sourceMappingURL=runbooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runbooks.d.ts","sourceRoot":"","sources":["../../src/commands/runbooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmKvD"}
1
+ {"version":3,"file":"runbooks.d.ts","sourceRoot":"","sources":["../../src/commands/runbooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAOnF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,IAAI,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACtB,MAAM,CA4BR;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,EAC3B,SAAS,EAAE,SAAS,YAAY,EAAE,GACjC,aAAa,EAAE,CAajB;AAED,iEAAiE;AACjE,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,aAAa,EAAE,EAC9B,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAoCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkKvD"}
@@ -10,10 +10,65 @@
10
10
  */
11
11
  import pc from 'picocolors';
12
12
  import { listRunbooks, getRunbook, addRunbook, removeRunbook, validateRunbookPorts, } from '@olam/core/src/global-config/index.js';
13
- import { printError, printSuccess, printHeader } from '../output.js';
13
+ import { printError, printSuccess } from '../output.js';
14
14
  function asMessage(err) {
15
15
  return err instanceof Error ? err.message : String(err);
16
16
  }
17
+ /**
18
+ * Pure renderer for `olam runbooks list`.
19
+ *
20
+ * Extracted so the `--json` contract is unit-testable without the global
21
+ * config store or a TTY (Rule 9). The JSON shape is a stable, color-free
22
+ * array of `{ name, repos, description, portCount, updatedAt }` so agents
23
+ * and scripts can enumerate runbook inventory without screen-scraping the
24
+ * colorized human table.
25
+ */
26
+ export function renderRunbookList(runbooks, opts) {
27
+ if (opts.json) {
28
+ return JSON.stringify(runbooks.map((rb) => ({
29
+ name: rb.name,
30
+ repos: rb.repos,
31
+ description: rb.description ?? null,
32
+ portCount: rb.portMap
33
+ ? Object.values(rb.portMap).reduce((n, svc) => n + Object.keys(svc).length, 0)
34
+ : 0,
35
+ updatedAt: rb.updatedAt,
36
+ })), null, 2);
37
+ }
38
+ if (runbooks.length === 0) {
39
+ return pc.dim('0 runbook(s). Add one with: olam runbooks add <name> --repos <repo>');
40
+ }
41
+ const lines = [pc.bold(`${runbooks.length} runbook(s)`)];
42
+ for (const rb of runbooks) {
43
+ const when = new Date(rb.updatedAt).toISOString().slice(0, 10);
44
+ const repoList = rb.repos.join(', ');
45
+ lines.push(` ${pc.bold(rb.name.padEnd(24))} ${repoList.padEnd(40)} ${pc.dim(when)}`);
46
+ }
47
+ return lines.join('\n');
48
+ }
49
+ /**
50
+ * Build the structured port-status rows for a runbook, pairing each declared
51
+ * port against the resolved conflict set. Pure + deterministic so the
52
+ * `check-ports --json` contract is testable without binding real TCP ports
53
+ * (Rule 9 — the WHY: scripts gating world creation must read conflict state
54
+ * machine-readably, not parse the ✓/✗ glyph table).
55
+ */
56
+ export function buildPortStatusRows(portMap, conflicts) {
57
+ const rows = [];
58
+ for (const [repoName, svcMap] of Object.entries(portMap ?? {})) {
59
+ for (const [serviceName, port] of Object.entries(svcMap)) {
60
+ const conflict = conflicts.find((c) => c.port === port);
61
+ rows.push(conflict
62
+ ? { repoName, serviceName, port, free: false, occupant: conflict.occupant }
63
+ : { repoName, serviceName, port, free: true });
64
+ }
65
+ }
66
+ return rows;
67
+ }
68
+ /** Pure JSON renderer for `olam runbooks check-ports --json`. */
69
+ export function renderCheckPortsJson(name, rows, conflictCount) {
70
+ return JSON.stringify({ name, conflictCount, ports: rows }, null, 2);
71
+ }
17
72
  /** Parse "--port repo.svc=N" args into a nested portMap. */
18
73
  function parsePortFlags(ports) {
19
74
  const portMap = {};
@@ -53,18 +108,10 @@ export function registerRunbooks(program) {
53
108
  runbooks
54
109
  .command('list')
55
110
  .description('List all runbooks')
56
- .action(() => {
111
+ .option('--json', 'Emit machine-readable JSON instead of the text table', false)
112
+ .action((opts) => {
57
113
  const all = listRunbooks();
58
- if (all.length === 0) {
59
- console.log(pc.dim('0 runbook(s). Add one with: olam runbooks add <name> --repos <repo>'));
60
- return;
61
- }
62
- printHeader(`${all.length} runbook(s)`);
63
- for (const rb of all) {
64
- const when = new Date(rb.updatedAt).toISOString().slice(0, 10);
65
- const repoList = rb.repos.join(', ');
66
- console.log(` ${pc.bold(rb.name.padEnd(24))} ${repoList.padEnd(40)} ${pc.dim(when)}`);
67
- }
114
+ console.log(renderRunbookList(all, { json: opts.json === true }));
68
115
  });
69
116
  runbooks
70
117
  .command('show')
@@ -152,24 +199,34 @@ export function registerRunbooks(program) {
152
199
  .command('check-ports')
153
200
  .description('Check if runbook ports are available')
154
201
  .argument('<name>', 'Runbook name')
155
- .action((name) => {
202
+ .option('--json', 'Emit machine-readable JSON instead of the text table', false)
203
+ .action((name, opts) => {
156
204
  try {
157
205
  const rb = getRunbook(name);
158
206
  const { conflicts } = validateRunbookPorts(rb);
159
- if (!rb.portMap || Object.keys(rb.portMap).length === 0) {
207
+ const rows = buildPortStatusRows(rb.portMap, conflicts);
208
+ if (opts.json === true) {
209
+ // --json always emits the full structured payload (including the
210
+ // empty-ports case as `ports: []`), so consumers get one stable
211
+ // shape regardless of whether the runbook declares ports.
212
+ console.log(renderCheckPortsJson(name, rows, conflicts.length));
213
+ if (conflicts.length > 0)
214
+ process.exitCode = 1;
215
+ return;
216
+ }
217
+ if (rows.length === 0) {
160
218
  console.log(pc.dim(`runbook "${name}" declares no ports.`));
161
219
  return;
162
220
  }
163
221
  // Print all declared ports
164
- for (const [repoName, svcMap] of Object.entries(rb.portMap ?? {})) {
165
- for (const [svcName, port] of Object.entries(svcMap)) {
166
- const conflict = conflicts.find((c) => c.port === port);
167
- if (conflict) {
222
+ for (const row of rows) {
223
+ if (!row.free) {
224
+ const conflict = conflicts.find((c) => c.port === row.port);
225
+ if (conflict)
168
226
  console.log(formatConflict(conflict));
169
- }
170
- else {
171
- console.log(` ${pc.green('✓')} ${repoName}.${svcName}:${port} — free`);
172
- }
227
+ }
228
+ else {
229
+ console.log(` ${pc.green('✓')} ${row.repoName}.${row.serviceName}:${row.port} — free`);
173
230
  }
174
231
  }
175
232
  if (conflicts.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"runbooks.js","sourceRoot":"","sources":["../../src/commands/runbooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,oBAAoB,GACrB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,SAAS,SAAS,CAAC,GAAY;IAC7B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,4DAA4D;AAC5D,SAAS,cAAc,CAAC,KAAe;IACrC,MAAM,OAAO,GAA2C,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,wCAAwC,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,mCAAmC,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,CAAE,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IAChC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,CAAe;IACrC,MAAM,WAAW,GACf,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;QAC9B,CAAC,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,OAAO,UAAU;QAClD,CAAC,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,SAAS,qBAAqB,CAAC;IACxE,OAAO,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,MAAM,WAAW,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,sCAAsC,CAAC,CAAC;IAEvD,QAAQ;SACL,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC,CAAC;YAC3F,OAAO;QACT,CAAC;QACD,WAAW,CAAC,GAAG,GAAG,CAAC,MAAM,aAAa,CAAC,CAAC;QACxC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/D,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO,CAAC,GAAG,CACT,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,0BAA0B,CAAC;SACvC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;SAClC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,sBAAsB,CAAC;SACnC,QAAQ,CAAC,QAAQ,EAAE,wCAAwC,CAAC;SAC5D,cAAc,CAAC,oBAAoB,EAAE,yCAAyC,CAAC;SAC/E,MAAM,CAAC,sBAAsB,EAAE,qCAAqC,CAAC;SACrE,MAAM,CAAC,kBAAkB,EAAE,8CAA8C,CAAC;SAC1E,MAAM,CACL,CACE,IAAY,EACZ,IAAgE,EAChE,EAAE;QACF,IAAI,CAAC;YACH,MAAM,OAAO,GACX,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5E,MAAM,EAAE,GAAG,UAAU,CAAC;gBACpB,IAAI;gBACJ,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO;aACR,CAAC,CAAC;YACH,YAAY,CAAC,oBAAoB,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CACF,CAAC;IAEJ,QAAQ;SACL,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,kBAAkB,CAAC;SAC/B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,YAAY,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0DAA0D,CAAC;SACvE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;SAClC,MAAM,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,0BAA0B,CAAC;SACnD,MAAM,CAAC,CAAC,IAAY,EAAE,IAAsC,EAAE,EAAE;QAC/D,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC5B,iDAAiD;YACjD,MAAM,EAAE,SAAS,EAAE,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;YAC/C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,UAAU,CAAC,wCAAwC,IAAI,IAAI,CAAC,CAAC;gBAC7D,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;oBAC1B,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,CAAC,KAAK,CACX,KAAK,SAAS,CAAC,MAAM,mFAAmF,IAAI,IAAI,CACjH,CAAC;gBACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,yCAAyC;YACzC,sEAAsE;YACtE,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CACJ,oDAAoD,IAAI,aAAa,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAC7F,CACF,CAAC;YACF,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CACJ,kCAAkC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,wBAAwB,CACnK,CACF,CAAC;YACF,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,MAAM,CAAC,qFAAqF,CAAC,CACjG,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,sCAAsC,CAAC;SACnD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;SAClC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC5B,MAAM,EAAE,SAAS,EAAE,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;YAE/C,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,IAAI,sBAAsB,CAAC,CAAC,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,2BAA2B;YAC3B,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;gBAClE,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;oBACxD,IAAI,QAAQ,EAAE,CAAC;wBACb,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,QAAQ,IAAI,OAAO,IAAI,IAAI,SAAS,CAAC,CAAC;oBAC1E,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CACX,KAAK,SAAS,CAAC,MAAM,mFAAmF,IAAI,IAAI,CACjH,CAAC;gBACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"runbooks.js","sourceRoot":"","sources":["../../src/commands/runbooks.ts"],"names":[],"mappings":"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"}
@@ -123,8 +123,54 @@ export declare function servicesUp(): Promise<{
123
123
  export declare function servicesDown(): {
124
124
  exitCode: number;
125
125
  };
126
+ /** One service container's state in the `--json` projection. */
127
+ export interface ServiceStatusEntry {
128
+ /** Stable docker container name (e.g. `olam-auth`). */
129
+ readonly name: string;
130
+ /** Container lifecycle: `running` (up), `stopped` (exists, not running), `missing` (no container). */
131
+ readonly state: ContainerState;
132
+ /** Published host port the service listens on. */
133
+ readonly port: number;
134
+ /**
135
+ * 12-char short container id (matches `docker ps` truncation), or `null`
136
+ * when the container is `missing`. Short — not the full 64-char id — so the
137
+ * payload mirrors what operators see and never doubles as a handle to a
138
+ * full-id-gated operation.
139
+ */
140
+ readonly containerId: string | null;
141
+ }
142
+ /** Injectable controller surface — just the `.status()` method each controller exposes. */
143
+ interface ServiceStatusController {
144
+ status(): {
145
+ state: ContainerState;
146
+ port: number;
147
+ containerId?: string;
148
+ };
149
+ }
150
+ export interface ServicesStatusDeps {
151
+ readonly auth?: ServiceStatusController;
152
+ readonly mcpAuth?: ServiceStatusController;
153
+ readonly kgService?: ServiceStatusController;
154
+ readonly memoryService?: ServiceStatusController;
155
+ }
156
+ /**
157
+ * Pure collector: probe each service controller and return a stable, ordered
158
+ * array. Order is fixed (auth, mcp-auth, kg-service, memory-service) so JSON
159
+ * consumers can index positionally AND the human table order is preserved.
160
+ *
161
+ * Controllers are injectable for unit testing (mirrors the kg-doctor deps
162
+ * pattern) — no live docker daemon needed in tests.
163
+ */
164
+ export declare function collectServicesStatus(deps?: ServicesStatusDeps): ServiceStatusEntry[];
126
165
  /** Show container state for all services. */
127
- export declare function servicesStatus(): void;
166
+ export declare function servicesStatus(deps?: ServicesStatusDeps): void;
167
+ /**
168
+ * `--json` projection of `services status` (compose path). Emits a stable
169
+ * array to stdout. Exit-code contract is unchanged from the human path
170
+ * (always 0 — `services status` has never gated its exit code on container
171
+ * health).
172
+ */
173
+ export declare function servicesStatusJson(deps?: ServicesStatusDeps): void;
128
174
  export declare function registerServices(program: Command): void;
129
175
  export {};
130
176
  //# sourceMappingURL=services.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/commands/services.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AA+BrD,KAAK,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAExD,UAAU,eAAe;IACvB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,QAAQ,CAA8B;IAE9C,MAAM,IAAI,eAAe;IAiBzB,OAAO,CAAC,WAAW;IAInB,KAAK,IAAI,IAAI;IAgCb,IAAI,IAAI,IAAI;IAMZ,MAAM,IAAI,IAAI;IAIR,YAAY,CAAC,SAAS,SAA6B,GAAG,OAAO,CAAC,OAAO,CAAC;CAa7E;AA6BD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,WAAW,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA2B/B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B/B;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB/B;AAID,8CAA8C;AAC9C;;;;;;GAMG;AACH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,CACnB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAC5C;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAChE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,IAAI,GAAE,kBAAuB,GAAG,oBAAoB,CA6ClF;AAkBD,wBAAsB,UAAU,IAAI,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA4JhE;AAED,mCAAmC;AACnC,wBAAgB,YAAY,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAwCnD;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,IAAI,IAAI,CA2CrC;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2DvD"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/commands/services.ts"],"names":[],"mappings":"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"}
@@ -532,41 +532,60 @@ export function servicesDown() {
532
532
  }
533
533
  return { exitCode };
534
534
  }
535
- /** Show container state for all services. */
536
- export function servicesStatus() {
537
- const auth = new AuthContainerController();
538
- const mcpAuth = new McpAuthContainerController();
539
- const kgService = new KgServiceContainerController();
540
- const memoryService = new MemoryServiceContainerController();
541
- printHeader('Services status');
542
- const authState = auth.status();
543
- const authStateStr = authState.state === 'running'
544
- ? pc.green('running')
545
- : authState.state === 'stopped'
546
- ? pc.yellow('stopped')
547
- : pc.red('missing');
548
- printInfo('olam-auth', `${authStateStr} :${authState.port}`);
549
- const mcpState = mcpAuth.status();
550
- const mcpStateStr = mcpState.state === 'running'
551
- ? pc.green('running')
552
- : mcpState.state === 'stopped'
553
- ? pc.yellow('stopped')
554
- : pc.red('missing');
555
- printInfo('olam-mcp-auth', `${mcpStateStr} :${mcpState.port}`);
556
- const kgState = kgService.status();
557
- const kgStateStr = kgState.state === 'running'
558
- ? pc.green('running')
559
- : kgState.state === 'stopped'
560
- ? pc.yellow('stopped')
561
- : pc.red('missing');
562
- printInfo('olam-kg-service', `${kgStateStr} :${kgState.port}`);
563
- const memState = memoryService.status();
564
- const memStateStr = memState.state === 'running'
535
+ /**
536
+ * Pure collector: probe each service controller and return a stable, ordered
537
+ * array. Order is fixed (auth, mcp-auth, kg-service, memory-service) so JSON
538
+ * consumers can index positionally AND the human table order is preserved.
539
+ *
540
+ * Controllers are injectable for unit testing (mirrors the kg-doctor deps
541
+ * pattern) — no live docker daemon needed in tests.
542
+ */
543
+ export function collectServicesStatus(deps = {}) {
544
+ const auth = deps.auth ?? new AuthContainerController();
545
+ const mcpAuth = deps.mcpAuth ?? new McpAuthContainerController();
546
+ const kgService = deps.kgService ?? new KgServiceContainerController();
547
+ const memoryService = deps.memoryService ?? new MemoryServiceContainerController();
548
+ const project = (name, c) => {
549
+ const s = c.status();
550
+ return {
551
+ name,
552
+ state: s.state,
553
+ port: s.port,
554
+ containerId: s.containerId ? s.containerId.slice(0, 12) : null,
555
+ };
556
+ };
557
+ return [
558
+ project('olam-auth', auth),
559
+ project('olam-mcp-auth', mcpAuth),
560
+ project('olam-kg-service', kgService),
561
+ project('olam-memory-service', memoryService),
562
+ ];
563
+ }
564
+ /** Colorize a container state for the human table. */
565
+ function colorizeState(state) {
566
+ return state === 'running'
565
567
  ? pc.green('running')
566
- : memState.state === 'stopped'
568
+ : state === 'stopped'
567
569
  ? pc.yellow('stopped')
568
570
  : pc.red('missing');
569
- printInfo('olam-memory-service', `${memStateStr} :${memState.port}`);
571
+ }
572
+ /** Show container state for all services. */
573
+ export function servicesStatus(deps = {}) {
574
+ const entries = collectServicesStatus(deps);
575
+ printHeader('Services status');
576
+ for (const entry of entries) {
577
+ printInfo(entry.name, `${colorizeState(entry.state)} :${entry.port}`);
578
+ }
579
+ }
580
+ /**
581
+ * `--json` projection of `services status` (compose path). Emits a stable
582
+ * array to stdout. Exit-code contract is unchanged from the human path
583
+ * (always 0 — `services status` has never gated its exit code on container
584
+ * health).
585
+ */
586
+ export function servicesStatusJson(deps = {}) {
587
+ const entries = collectServicesStatus(deps);
588
+ process.stdout.write(JSON.stringify(entries, null, 2) + '\n');
570
589
  }
571
590
  // ── Commander registration ────────────────────────────────────────
572
591
  export function registerServices(program) {
@@ -608,11 +627,18 @@ export function registerServices(program) {
608
627
  services
609
628
  .command('status')
610
629
  .description('Show state of all service containers')
611
- .action(async () => {
630
+ .option('--json', 'Emit a machine-readable JSON array of service states (compose substrate only)')
631
+ .action(async (opts) => {
612
632
  const cfg = readConfig();
613
633
  if (cfg.host.substrate === 'kubernetes') {
634
+ // The kubernetes path reformats `kubectl get deployment` text and has no
635
+ // structured controller collector; --json is a no-op there for now (the
636
+ // human table is unchanged). Compose is the default + the path drivers hit.
614
637
  await servicesStatusKubernetes();
615
638
  }
639
+ else if (opts.json === true) {
640
+ servicesStatusJson();
641
+ }
616
642
  else {
617
643
  servicesStatus();
618
644
  }