@pleri/olam-cli 0.1.69 → 0.1.72

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 (250) hide show
  1. package/dist/cli-version.d.ts +16 -0
  2. package/dist/cli-version.d.ts.map +1 -0
  3. package/dist/cli-version.js +39 -0
  4. package/dist/cli-version.js.map +1 -0
  5. package/dist/commands/create.d.ts.map +1 -1
  6. package/dist/commands/create.js +2 -0
  7. package/dist/commands/create.js.map +1 -1
  8. package/dist/commands/host-cp.d.ts.map +1 -1
  9. package/dist/commands/host-cp.js +10 -0
  10. package/dist/commands/host-cp.js.map +1 -1
  11. package/dist/commands/runbooks.d.ts +13 -0
  12. package/dist/commands/runbooks.d.ts.map +1 -0
  13. package/dist/commands/runbooks.js +189 -0
  14. package/dist/commands/runbooks.js.map +1 -0
  15. package/dist/commands/world-snapshot.d.ts +1 -0
  16. package/dist/commands/world-snapshot.d.ts.map +1 -1
  17. package/dist/commands/world-snapshot.js +126 -1
  18. package/dist/commands/world-snapshot.js.map +1 -1
  19. package/dist/commands/worldspec/compile.d.ts +20 -0
  20. package/dist/commands/worldspec/compile.d.ts.map +1 -0
  21. package/dist/commands/worldspec/compile.js +130 -0
  22. package/dist/commands/worldspec/compile.js.map +1 -0
  23. package/dist/commands/worldspec/index.d.ts +12 -0
  24. package/dist/commands/worldspec/index.d.ts.map +1 -0
  25. package/dist/commands/worldspec/index.js +23 -0
  26. package/dist/commands/worldspec/index.js.map +1 -0
  27. package/dist/commands/worldspec/init.d.ts +15 -0
  28. package/dist/commands/worldspec/init.d.ts.map +1 -0
  29. package/dist/commands/worldspec/init.js +166 -0
  30. package/dist/commands/worldspec/init.js.map +1 -0
  31. package/dist/commands/worldspec/schema.d.ts +11 -0
  32. package/dist/commands/worldspec/schema.d.ts.map +1 -0
  33. package/dist/commands/worldspec/schema.js +55 -0
  34. package/dist/commands/worldspec/schema.js.map +1 -0
  35. package/dist/commands/worldspec/validate.d.ts +15 -0
  36. package/dist/commands/worldspec/validate.d.ts.map +1 -0
  37. package/dist/commands/worldspec/validate.js +66 -0
  38. package/dist/commands/worldspec/validate.js.map +1 -0
  39. package/dist/exit-codes.d.ts +32 -0
  40. package/dist/exit-codes.d.ts.map +1 -1
  41. package/dist/exit-codes.js +32 -0
  42. package/dist/exit-codes.js.map +1 -1
  43. package/dist/image-digests.json +5 -5
  44. package/dist/index.js +4726 -1231
  45. package/dist/index.js.map +1 -1
  46. package/dist/mcp-server.js +1424 -321
  47. package/host-cp/compose.yaml +6 -0
  48. package/host-cp/src/global-config-source.mjs +71 -0
  49. package/host-cp/src/listening-server-poller.mjs +1 -1
  50. package/host-cp/src/plan-orchestrator.mjs +20 -1
  51. package/host-cp/src/port-bridge-manager.mjs +1 -1
  52. package/host-cp/src/server.mjs +46 -7
  53. package/host-cp/src/version-status.mjs +36 -0
  54. package/package.json +4 -2
  55. package/dist/__tests__/audit-publish-deps-contract.test.d.ts +0 -26
  56. package/dist/__tests__/audit-publish-deps-contract.test.d.ts.map +0 -1
  57. package/dist/__tests__/audit-publish-deps-contract.test.js +0 -86
  58. package/dist/__tests__/audit-publish-deps-contract.test.js.map +0 -1
  59. package/dist/__tests__/auth-status.test.d.ts +0 -2
  60. package/dist/__tests__/auth-status.test.d.ts.map +0 -1
  61. package/dist/__tests__/auth-status.test.js +0 -291
  62. package/dist/__tests__/auth-status.test.js.map +0 -1
  63. package/dist/__tests__/auth-upgrade.test.d.ts +0 -9
  64. package/dist/__tests__/auth-upgrade.test.d.ts.map +0 -1
  65. package/dist/__tests__/auth-upgrade.test.js +0 -397
  66. package/dist/__tests__/auth-upgrade.test.js.map +0 -1
  67. package/dist/__tests__/bootstrap-tag-mcp-auth.test.d.ts +0 -22
  68. package/dist/__tests__/bootstrap-tag-mcp-auth.test.d.ts.map +0 -1
  69. package/dist/__tests__/bootstrap-tag-mcp-auth.test.js +0 -63
  70. package/dist/__tests__/bootstrap-tag-mcp-auth.test.js.map +0 -1
  71. package/dist/__tests__/cli-mcp-revoke.test.d.ts +0 -8
  72. package/dist/__tests__/cli-mcp-revoke.test.d.ts.map +0 -1
  73. package/dist/__tests__/cli-mcp-revoke.test.js +0 -124
  74. package/dist/__tests__/cli-mcp-revoke.test.js.map +0 -1
  75. package/dist/__tests__/config.test.d.ts +0 -2
  76. package/dist/__tests__/config.test.d.ts.map +0 -1
  77. package/dist/__tests__/config.test.js +0 -95
  78. package/dist/__tests__/config.test.js.map +0 -1
  79. package/dist/__tests__/create-app-urls.test.d.ts +0 -2
  80. package/dist/__tests__/create-app-urls.test.d.ts.map +0 -1
  81. package/dist/__tests__/create-app-urls.test.js +0 -102
  82. package/dist/__tests__/create-app-urls.test.js.map +0 -1
  83. package/dist/__tests__/docker-host.test.d.ts +0 -14
  84. package/dist/__tests__/docker-host.test.d.ts.map +0 -1
  85. package/dist/__tests__/docker-host.test.js +0 -109
  86. package/dist/__tests__/docker-host.test.js.map +0 -1
  87. package/dist/__tests__/enter.test.d.ts +0 -2
  88. package/dist/__tests__/enter.test.d.ts.map +0 -1
  89. package/dist/__tests__/enter.test.js +0 -90
  90. package/dist/__tests__/enter.test.js.map +0 -1
  91. package/dist/__tests__/help-output.test.d.ts +0 -2
  92. package/dist/__tests__/help-output.test.d.ts.map +0 -1
  93. package/dist/__tests__/help-output.test.js +0 -74
  94. package/dist/__tests__/help-output.test.js.map +0 -1
  95. package/dist/__tests__/host-cp-gh-token.test.d.ts +0 -9
  96. package/dist/__tests__/host-cp-gh-token.test.d.ts.map +0 -1
  97. package/dist/__tests__/host-cp-gh-token.test.js +0 -119
  98. package/dist/__tests__/host-cp-gh-token.test.js.map +0 -1
  99. package/dist/__tests__/host-cp.test.d.ts +0 -9
  100. package/dist/__tests__/host-cp.test.d.ts.map +0 -1
  101. package/dist/__tests__/host-cp.test.js +0 -327
  102. package/dist/__tests__/host-cp.test.js.map +0 -1
  103. package/dist/__tests__/image-presence.test.d.ts +0 -2
  104. package/dist/__tests__/image-presence.test.d.ts.map +0 -1
  105. package/dist/__tests__/image-presence.test.js +0 -44
  106. package/dist/__tests__/image-presence.test.js.map +0 -1
  107. package/dist/__tests__/install-root.test.d.ts +0 -2
  108. package/dist/__tests__/install-root.test.d.ts.map +0 -1
  109. package/dist/__tests__/install-root.test.js +0 -119
  110. package/dist/__tests__/install-root.test.js.map +0 -1
  111. package/dist/__tests__/keys.test.d.ts +0 -9
  112. package/dist/__tests__/keys.test.d.ts.map +0 -1
  113. package/dist/__tests__/keys.test.js +0 -145
  114. package/dist/__tests__/keys.test.js.map +0 -1
  115. package/dist/__tests__/logs.test.d.ts +0 -9
  116. package/dist/__tests__/logs.test.d.ts.map +0 -1
  117. package/dist/__tests__/logs.test.js +0 -124
  118. package/dist/__tests__/logs.test.js.map +0 -1
  119. package/dist/__tests__/mcp-import.test.d.ts +0 -11
  120. package/dist/__tests__/mcp-import.test.d.ts.map +0 -1
  121. package/dist/__tests__/mcp-import.test.js +0 -134
  122. package/dist/__tests__/mcp-import.test.js.map +0 -1
  123. package/dist/__tests__/protocol-version.test.d.ts +0 -2
  124. package/dist/__tests__/protocol-version.test.d.ts.map +0 -1
  125. package/dist/__tests__/protocol-version.test.js +0 -170
  126. package/dist/__tests__/protocol-version.test.js.map +0 -1
  127. package/dist/__tests__/ps.test.d.ts +0 -2
  128. package/dist/__tests__/ps.test.d.ts.map +0 -1
  129. package/dist/__tests__/ps.test.js +0 -172
  130. package/dist/__tests__/ps.test.js.map +0 -1
  131. package/dist/__tests__/registry-allowlist.test.d.ts +0 -2
  132. package/dist/__tests__/registry-allowlist.test.d.ts.map +0 -1
  133. package/dist/__tests__/registry-allowlist.test.js +0 -129
  134. package/dist/__tests__/registry-allowlist.test.js.map +0 -1
  135. package/dist/__tests__/services.test.d.ts +0 -8
  136. package/dist/__tests__/services.test.d.ts.map +0 -1
  137. package/dist/__tests__/services.test.js +0 -185
  138. package/dist/__tests__/services.test.js.map +0 -1
  139. package/dist/__tests__/status-app-urls.test.d.ts +0 -2
  140. package/dist/__tests__/status-app-urls.test.d.ts.map +0 -1
  141. package/dist/__tests__/status-app-urls.test.js +0 -125
  142. package/dist/__tests__/status-app-urls.test.js.map +0 -1
  143. package/dist/__tests__/upgrade-gh-token-contract.test.d.ts +0 -19
  144. package/dist/__tests__/upgrade-gh-token-contract.test.d.ts.map +0 -1
  145. package/dist/__tests__/upgrade-gh-token-contract.test.js +0 -63
  146. package/dist/__tests__/upgrade-gh-token-contract.test.js.map +0 -1
  147. package/dist/__tests__/upgrade.test.d.ts +0 -9
  148. package/dist/__tests__/upgrade.test.d.ts.map +0 -1
  149. package/dist/__tests__/upgrade.test.js +0 -586
  150. package/dist/__tests__/upgrade.test.js.map +0 -1
  151. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts +0 -6
  152. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts.map +0 -1
  153. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js +0 -26
  154. package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js.map +0 -1
  155. package/dist/commands/__tests__/begin.test.d.ts +0 -7
  156. package/dist/commands/__tests__/begin.test.d.ts.map +0 -1
  157. package/dist/commands/__tests__/begin.test.js +0 -72
  158. package/dist/commands/__tests__/begin.test.js.map +0 -1
  159. package/dist/commands/__tests__/bootstrap.test.d.ts +0 -2
  160. package/dist/commands/__tests__/bootstrap.test.d.ts.map +0 -1
  161. package/dist/commands/__tests__/bootstrap.test.js +0 -370
  162. package/dist/commands/__tests__/bootstrap.test.js.map +0 -1
  163. package/dist/commands/__tests__/carry-uncommitted.test.d.ts +0 -14
  164. package/dist/commands/__tests__/carry-uncommitted.test.d.ts.map +0 -1
  165. package/dist/commands/__tests__/carry-uncommitted.test.js +0 -83
  166. package/dist/commands/__tests__/carry-uncommitted.test.js.map +0 -1
  167. package/dist/commands/__tests__/clean.test.d.ts +0 -9
  168. package/dist/commands/__tests__/clean.test.d.ts.map +0 -1
  169. package/dist/commands/__tests__/clean.test.js +0 -105
  170. package/dist/commands/__tests__/clean.test.js.map +0 -1
  171. package/dist/commands/__tests__/crystallize.test.d.ts +0 -2
  172. package/dist/commands/__tests__/crystallize.test.d.ts.map +0 -1
  173. package/dist/commands/__tests__/crystallize.test.js +0 -133
  174. package/dist/commands/__tests__/crystallize.test.js.map +0 -1
  175. package/dist/commands/__tests__/diagnose.test.d.ts +0 -9
  176. package/dist/commands/__tests__/diagnose.test.d.ts.map +0 -1
  177. package/dist/commands/__tests__/diagnose.test.js +0 -108
  178. package/dist/commands/__tests__/diagnose.test.js.map +0 -1
  179. package/dist/commands/__tests__/openHostCpUrl.test.d.ts +0 -2
  180. package/dist/commands/__tests__/openHostCpUrl.test.d.ts.map +0 -1
  181. package/dist/commands/__tests__/openHostCpUrl.test.js +0 -63
  182. package/dist/commands/__tests__/openHostCpUrl.test.js.map +0 -1
  183. package/dist/commands/__tests__/refresh.test.d.ts +0 -13
  184. package/dist/commands/__tests__/refresh.test.d.ts.map +0 -1
  185. package/dist/commands/__tests__/refresh.test.js +0 -170
  186. package/dist/commands/__tests__/refresh.test.js.map +0 -1
  187. package/dist/commands/__tests__/status.test.d.ts +0 -8
  188. package/dist/commands/__tests__/status.test.d.ts.map +0 -1
  189. package/dist/commands/__tests__/status.test.js +0 -62
  190. package/dist/commands/__tests__/status.test.js.map +0 -1
  191. package/dist/commands/__tests__/stop.test.d.ts +0 -5
  192. package/dist/commands/__tests__/stop.test.d.ts.map +0 -1
  193. package/dist/commands/__tests__/stop.test.js +0 -30
  194. package/dist/commands/__tests__/stop.test.js.map +0 -1
  195. package/dist/commands/__tests__/update.test.d.ts +0 -7
  196. package/dist/commands/__tests__/update.test.d.ts.map +0 -1
  197. package/dist/commands/__tests__/update.test.js +0 -224
  198. package/dist/commands/__tests__/update.test.js.map +0 -1
  199. package/dist/commands/__tests__/upgrade.all-three.test.d.ts +0 -19
  200. package/dist/commands/__tests__/upgrade.all-three.test.d.ts.map +0 -1
  201. package/dist/commands/__tests__/upgrade.all-three.test.js +0 -80
  202. package/dist/commands/__tests__/upgrade.all-three.test.js.map +0 -1
  203. package/dist/commands/__tests__/upgrade.compose-path.test.d.ts +0 -20
  204. package/dist/commands/__tests__/upgrade.compose-path.test.d.ts.map +0 -1
  205. package/dist/commands/__tests__/upgrade.compose-path.test.js +0 -140
  206. package/dist/commands/__tests__/upgrade.compose-path.test.js.map +0 -1
  207. package/dist/commands/__tests__/upgrade.history.test.d.ts +0 -15
  208. package/dist/commands/__tests__/upgrade.history.test.d.ts.map +0 -1
  209. package/dist/commands/__tests__/upgrade.history.test.js +0 -199
  210. package/dist/commands/__tests__/upgrade.history.test.js.map +0 -1
  211. package/dist/commands/__tests__/upgrade.lock.test.d.ts +0 -15
  212. package/dist/commands/__tests__/upgrade.lock.test.d.ts.map +0 -1
  213. package/dist/commands/__tests__/upgrade.lock.test.js +0 -253
  214. package/dist/commands/__tests__/upgrade.lock.test.js.map +0 -1
  215. package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts +0 -21
  216. package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts.map +0 -1
  217. package/dist/commands/__tests__/upgrade.olam-tag.test.js +0 -114
  218. package/dist/commands/__tests__/upgrade.olam-tag.test.js.map +0 -1
  219. package/dist/commands/__tests__/upgrade.poll.test.d.ts +0 -14
  220. package/dist/commands/__tests__/upgrade.poll.test.d.ts.map +0 -1
  221. package/dist/commands/__tests__/upgrade.poll.test.js +0 -136
  222. package/dist/commands/__tests__/upgrade.poll.test.js.map +0 -1
  223. package/dist/commands/__tests__/upgrade.recreate.test.d.ts +0 -17
  224. package/dist/commands/__tests__/upgrade.recreate.test.d.ts.map +0 -1
  225. package/dist/commands/__tests__/upgrade.recreate.test.js +0 -83
  226. package/dist/commands/__tests__/upgrade.recreate.test.js.map +0 -1
  227. package/dist/commands/__tests__/upgrade.rollback.test.d.ts +0 -12
  228. package/dist/commands/__tests__/upgrade.rollback.test.d.ts.map +0 -1
  229. package/dist/commands/__tests__/upgrade.rollback.test.js +0 -255
  230. package/dist/commands/__tests__/upgrade.rollback.test.js.map +0 -1
  231. package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts +0 -12
  232. package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts.map +0 -1
  233. package/dist/commands/__tests__/upgrade.sha-capture.test.js +0 -63
  234. package/dist/commands/__tests__/upgrade.sha-capture.test.js.map +0 -1
  235. package/dist/commands/__tests__/upgrade.smoke.test.d.ts +0 -19
  236. package/dist/commands/__tests__/upgrade.smoke.test.d.ts.map +0 -1
  237. package/dist/commands/__tests__/upgrade.smoke.test.js +0 -87
  238. package/dist/commands/__tests__/upgrade.smoke.test.js.map +0 -1
  239. package/dist/commands/__tests__/upgrade.swap.test.d.ts +0 -19
  240. package/dist/commands/__tests__/upgrade.swap.test.d.ts.map +0 -1
  241. package/dist/commands/__tests__/upgrade.swap.test.js +0 -312
  242. package/dist/commands/__tests__/upgrade.swap.test.js.map +0 -1
  243. package/dist/commands/__tests__/world-upgrade.test.d.ts +0 -8
  244. package/dist/commands/__tests__/world-upgrade.test.d.ts.map +0 -1
  245. package/dist/commands/__tests__/world-upgrade.test.js +0 -73
  246. package/dist/commands/__tests__/world-upgrade.test.js.map +0 -1
  247. package/dist/lib/__tests__/symlink-reconcile.test.d.ts +0 -2
  248. package/dist/lib/__tests__/symlink-reconcile.test.d.ts.map +0 -1
  249. package/dist/lib/__tests__/symlink-reconcile.test.js +0 -106
  250. package/dist/lib/__tests__/symlink-reconcile.test.js.map +0 -1
@@ -85,6 +85,12 @@ services:
85
85
  # which surfaces in the dashboard as a failed Connect Claude flow.
86
86
  OLAM_AUTH_SERVICE_URL: "http://host.docker.internal:9999"
87
87
  OLAM_AUTH_SECRET: "${OLAM_AUTH_SECRET:-}"
88
+ # Operator's CLI version, propagated by `olam host-cp start` via
89
+ # buildComposeEnv. Surfaces in /api/version/status so the
90
+ # dashboard's TopNav can render "the version we're working on."
91
+ # Empty when older CLI versions render this compose; the server
92
+ # falls back to host-cp's own package.json.
93
+ OLAM_CLI_VERSION: "${OLAM_CLI_VERSION:-}"
88
94
  # Upgrade-trigger feature: host-cp uses these to construct bind
89
95
  # mounts on the spawned upgrader container. The upgrader runs
90
96
  # `olam upgrade -y` and needs (a) the operator's ~/.olam state,
@@ -0,0 +1,71 @@
1
+ // E1 (Phase E — olam-repos-and-runbooks): read ~/.olam/config.json and
2
+ // expose it to the host-CP API endpoints (/api/repos, /api/runbooks).
3
+ //
4
+ // Never crashes: missing file → empty arrays, corrupt JSON → { error }.
5
+ // Mirrors the workspace-catalog.mjs pattern: pure function, env-driven
6
+ // path, no side effects at module load time.
7
+
8
+ import fs from 'node:fs';
9
+ import os from 'node:os';
10
+ import path from 'node:path';
11
+
12
+ const DEFAULT_CONFIG_PATH =
13
+ process.env.OLAM_CONFIG_PATH ??
14
+ path.join(os.homedir(), '.olam', 'config.json');
15
+
16
+ /**
17
+ * @typedef {object} RepoEntry
18
+ * @property {string} name
19
+ * @property {string} path
20
+ * @property {string} [description]
21
+ * @property {number} [addedAt]
22
+ * @property {number} [updatedAt]
23
+ */
24
+
25
+ /**
26
+ * @typedef {object} Runbook
27
+ * @property {string} name
28
+ * @property {string[]} repos
29
+ * @property {number} [updatedAt]
30
+ * @property {Record<string, Record<string, number>>} [portMap]
31
+ * @property {Record<string, Record<string, string>>} [env]
32
+ */
33
+
34
+ /**
35
+ * @typedef {{ repos: RepoEntry[], runbooks: Runbook[] }} GlobalConfig
36
+ * @typedef {{ error: string }} ConfigError
37
+ */
38
+
39
+ /**
40
+ * Load the global olam config from disk.
41
+ * - Missing file → `{ repos: [], runbooks: [] }`
42
+ * - Corrupt JSON → `{ error: string }`
43
+ * - Success → `{ repos: RepoEntry[], runbooks: Runbook[] }`
44
+ *
45
+ * @param {string} [configPath]
46
+ * @returns {GlobalConfig | ConfigError}
47
+ */
48
+ export function loadGlobalConfig(configPath = DEFAULT_CONFIG_PATH) {
49
+ if (!fs.existsSync(configPath)) {
50
+ return { repos: [], runbooks: [] };
51
+ }
52
+ let raw;
53
+ try {
54
+ raw = fs.readFileSync(configPath, 'utf-8');
55
+ } catch (err) {
56
+ return { error: `Failed to read ${configPath}: ${err.message}` };
57
+ }
58
+ let parsed;
59
+ try {
60
+ parsed = JSON.parse(raw);
61
+ } catch (err) {
62
+ return { error: `Invalid JSON in ${configPath}: ${err.message}` };
63
+ }
64
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
65
+ return { error: `${configPath} does not contain a JSON object` };
66
+ }
67
+ return {
68
+ repos: Array.isArray(parsed.repos) ? parsed.repos : [],
69
+ runbooks: Array.isArray(parsed.runbooks) ? parsed.runbooks : [],
70
+ };
71
+ }
@@ -8,7 +8,7 @@ import { spawnSync } from 'node:child_process';
8
8
 
9
9
  const DOCKER_HOST = process.env.DOCKER_HOST ?? 'docker-cli';
10
10
  // Skip well-known infra ports — these are always running and not user servers
11
- const INFRA_PORTS = new Set([8080, 7681]);
11
+ const INFRA_PORTS = new Set([8080, 7681, 7682]);
12
12
 
13
13
  // Per-world cache: worldId → { ts, servers, error? }
14
14
  const cache = new Map();
@@ -19,6 +19,8 @@ import { SessionManager } from '@mariozechner/pi-coding-agent';
19
19
  import { PERSONAS, DEFAULT_PERSONA_ID, getPersona } from './plan/personas.mjs';
20
20
  import { AgentRegistry } from './plan/agent-registry.mjs';
21
21
  import { HandoffEngine } from './plan/handoff-engine.mjs';
22
+ import { RopeEngine } from './plan/rope-engine.mjs';
23
+ import { loadAuthorityConfig } from './plan/authority-config.mjs';
22
24
 
23
25
  // ── Paths ─────────────────────────────────────────────────────────────────────
24
26
 
@@ -62,6 +64,7 @@ export class PlanOrchestrator {
62
64
  #authServiceSecret;
63
65
  #registry;
64
66
  #handoffEngine;
67
+ #ropeEngine;
65
68
 
66
69
  /** Tracks the active persona per conversationId: Map<conversationId, personaId> */
67
70
  #activePersona = new Map();
@@ -148,6 +151,14 @@ export class PlanOrchestrator {
148
151
  CREATE INDEX IF NOT EXISTS plan_sidebar_chunk_idx
149
152
  ON plan_sidebar_signals(chunk_id);
150
153
  `);
154
+
155
+ const authorityConfig = loadAuthorityConfig();
156
+ this.#ropeEngine = new RopeEngine({
157
+ registry: this.#registry,
158
+ db: this.#db,
159
+ broadcast: (conversationId, eventName, data) => this.#broadcast(conversationId, eventName, data),
160
+ authorityConfig,
161
+ });
151
162
  }
152
163
 
153
164
  // ── Auth-service credential fetching ──────────────────────────────────────
@@ -670,6 +681,14 @@ export class PlanOrchestrator {
670
681
  this.#broadcast(conversationId, 'tool_stub_call', { persona: personaId, ...event });
671
682
  };
672
683
 
684
+ // Run autoRope delegation (e.g. PM→Scout evidence gathering) before the main turn.
685
+ const promptContent = await this.#ropeEngine.autoDelegateIfNeeded({
686
+ conversationId,
687
+ callerPersonaId: personaId,
688
+ content,
689
+ fetchToken: () => this.#fetchToken(),
690
+ });
691
+
673
692
  const { session, authStorage } = await this.#registry.getAgent(conversationId, personaId, { onStubCall });
674
693
 
675
694
  // Wire events on first use (idempotent because pi de-duplicates subscribers).
@@ -681,7 +700,7 @@ export class PlanOrchestrator {
681
700
 
682
701
  const turnId = randomUUID();
683
702
 
684
- session.prompt(content).catch((err) => {
703
+ session.prompt(promptContent).catch((err) => {
685
704
  console.error(`[plan] prompt error ${conversationId}/${personaId}:`, err.message);
686
705
  this.#broadcast(conversationId, 'error', {
687
706
  message: err.message,
@@ -12,7 +12,7 @@ const DOCKER_HOST = process.env.DOCKER_HOST ?? 'docker-cli';
12
12
  const SOCAT_IMAGE = 'alpine/socat';
13
13
  const HOST_PORT_MIN = 25000;
14
14
  const HOST_PORT_MAX = 25999;
15
- const INFRA_PORTS = new Set([8080, 7681]);
15
+ const INFRA_PORTS = new Set([8080, 7681, 7682]);
16
16
 
17
17
  let BRIDGES_PATH =
18
18
  process.env.OLAM_PORT_BRIDGES_PATH ??
@@ -44,6 +44,7 @@ import {
44
44
  projectsFromWorkspaces,
45
45
  matchWorkspacesByProjects,
46
46
  } from './workspace-catalog.mjs';
47
+ import { loadGlobalConfig } from './global-config-source.mjs';
47
48
  import {
48
49
  createWorldNamesStore,
49
50
  inferNameFromTask,
@@ -810,7 +811,7 @@ const server = http.createServer(async (req, res) => {
810
811
  }
811
812
  // Infra ports must never be published — filter both client-side (PublishModal)
812
813
  // and here so direct API callers cannot tunnel the terminal or per-world CP.
813
- const INFRA_PORTS = new Set([7681, 8080]);
814
+ const INFRA_PORTS = new Set([7681, 7682, 8080]);
814
815
  const validServices = parsed.services
815
816
  .filter((svc) => typeof svc.name === 'string')
816
817
  .map((svc) => ({ name: svc.name, port: Number(svc.port) }))
@@ -908,6 +909,26 @@ const server = http.createServer(async (req, res) => {
908
909
  return;
909
910
  }
910
911
 
912
+ // /api/repos (Phase E — olam-repos-and-runbooks): list registered repos
913
+ // from ~/.olam/config.json. Returns { repos: RepoEntry[] }.
914
+ if (url.pathname === '/api/repos' && req.method === 'GET') {
915
+ const config = loadGlobalConfig();
916
+ if ('error' in config) {
917
+ return jsonReply(res, 500, { error: config.error });
918
+ }
919
+ return jsonReply(res, 200, { repos: config.repos });
920
+ }
921
+
922
+ // /api/runbooks (Phase E — olam-repos-and-runbooks): list runbooks
923
+ // from ~/.olam/config.json. Returns { runbooks: Runbook[] }.
924
+ if (url.pathname === '/api/runbooks' && req.method === 'GET') {
925
+ const config = loadGlobalConfig();
926
+ if ('error' in config) {
927
+ return jsonReply(res, 500, { error: config.error });
928
+ }
929
+ return jsonReply(res, 200, { runbooks: config.runbooks });
930
+ }
931
+
911
932
  // ── Host-level auth proxy (/api/auth/*) ───────────────────────────
912
933
  //
913
934
  // Proxies to the olam-auth container (port 9999). These are distinct from
@@ -1199,6 +1220,18 @@ const server = http.createServer(async (req, res) => {
1199
1220
  return;
1200
1221
  }
1201
1222
 
1223
+ // /api/world/<id>/ttyd-shell/* → proxy to the shell ttyd (port 7682).
1224
+ // Serves the [Terminal] tab's standalone shell session, separate from
1225
+ // the claude-main session on port 7681.
1226
+ if (subPath.startsWith('/ttyd-shell/') || subPath === '/ttyd-shell') {
1227
+ const portOffset = port - 19080;
1228
+ const ttydPort = 17682 + portOffset;
1229
+ const ttydBase = `http://${HOST_FOR_WORLD}:${ttydPort}`;
1230
+ const ttydSubPath = (subPath === '/ttyd-shell' ? '/' : subPath.slice('/ttyd-shell'.length)) + url.search;
1231
+ proxyToWorld({ req, res, subPath: ttydSubPath, targetBase: ttydBase, secret: '' });
1232
+ return;
1233
+ }
1234
+
1202
1235
  let secret;
1203
1236
  try {
1204
1237
  secret = await getSecret(worldId);
@@ -1866,6 +1899,7 @@ const WELL_KNOWN_PORTS = {
1866
1899
  3000: 'atlas-core (Rails)',
1867
1900
  5175: 'diner-app (Vite)',
1868
1901
  7681: 'Terminal (ttyd)',
1902
+ 7682: 'Terminal Shell (ttyd)',
1869
1903
  8080: 'Per-world CP',
1870
1904
  };
1871
1905
 
@@ -2003,13 +2037,14 @@ const DIST_DIR = (() => {
2003
2037
  return '/app/dist'; // fallback; readFile will surface ENOENT
2004
2038
  })();
2005
2039
 
2006
- const SPA_ROUTES = new Set(['/', '/worlds', '/workspaces', '/inbox']);
2007
- const SPA_PREFIX = ['/world/', '/worlds/', '/workspaces/', '/inbox/'];
2040
+ const SPA_ROUTES = new Set(['/', '/worlds', '/workspaces', '/inbox', '/repos', '/runbooks']);
2041
+ const SPA_PREFIX = ['/world/', '/worlds/', '/workspaces/', '/inbox/', '/repos/', '/runbooks/'];
2008
2042
 
2009
2043
  // Top-level path segments that are NOT world IDs. Mirrors RESERVED_SEGMENTS
2010
2044
  // in lib/worldId.ts — keep in sync.
2011
2045
  const RESERVED_TOP_LEVEL = new Set([
2012
2046
  'sandbox', 'world', 'inbox', 'worlds', 'workspaces',
2047
+ 'repos', 'runbooks',
2013
2048
  'api', 'assets', 'health', 'favicon.ico',
2014
2049
  'session', 'hooks', 'dispatch', 'lanes', 'codex', 'review',
2015
2050
  ]);
@@ -2221,7 +2256,7 @@ let _spaCacheMtime = 0;
2221
2256
  // and the token-comparison check skips reload when the cookie
2222
2257
  // already matches (so non-rotation 401s — e.g. genuine auth
2223
2258
  // failures — don't cause a refresh loop).
2224
- const BOOTSTRAP_SCRIPT = `<script>(function(){function ck(){var m=document.cookie.match(/olam_host_cp_token=([^;]+)/);return m?m[1]:'';}function sw(t){document.cookie='olam_host_cp_token='+t+'; path=/; samesite=strict';}try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);sw(d.token);}}catch(e){console.error('[host-cp bootstrap]',e);}var reloading=false;function recover(){if(reloading)return;try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);if(d.token&&ck()!==d.token){reloading=true;sw(d.token);console.warn('[host-cp auth recover] token rotated; reloading');location.reload();}}}catch(e){console.error('[host-cp auth recover]',e);}}var HN=['/api/bootstrap','/api/worlds','/api/projects','/api/workspaces','/api/workspaces/match','/api/auth','/health'];var WP=['/api/','/session/','/hooks/','/dispatch','/lanes','/codex/','/review/'];function sr(p){if(typeof p!=='string')return false;if(p.startsWith('/api/world/'))return false;for(var i=0;i<HN.length;i++){var n=HN[i];if(p===n||p.startsWith(n+'?')||p.startsWith(n+'/'))return false;}for(var j=0;j<WP.length;j++){var w=WP[j];if(p===w||p===w.replace(/\\/$/,'')||p.startsWith(w)||p.startsWith(w.replace(/\\/$/,'')+'?')||p.startsWith(w.replace(/\\/$/,'')+'/'))return true;}return false;}function wid(){var p=location.pathname;var m=p.match(/^\\/(world|inbox)\\/([^/?#]+)/);if(m)return m[2];if(/^\\/(?:worlds?|workspaces?|world|sandbox|inbox|plan|design|assets|api|health|favicon)($|\\/|\\?)/.test(p))return null;var r=p.match(/^\\/([a-z][a-z0-9-]+)(?:\\/|$|\\?)/);return r?r[1]:null;}function rw(p){var w=wid();return w?'/api/world/'+w+p:p;}var of=window.fetch.bind(window);window.fetch=function(input,init){var pr;if(typeof input==='string'&&sr(input))pr=of(rw(input),init);else if(input&&typeof input.url==='string'&&sr(input.url))pr=of(new Request(rw(input.url),input),init);else pr=of(input,init);return pr.then(function(res){if(res&&res.status===401)recover();return res;});};var OE=window.EventSource;if(OE){window.EventSource=function(u,i){var s=u;if(typeof s==='string'&&sr(s))s=rw(s);var es=new OE(s,i);es.addEventListener('error',function(){if(es.readyState===OE.CLOSED)recover();});return es;};window.EventSource.prototype=OE.prototype;window.EventSource.CONNECTING=OE.CONNECTING;window.EventSource.OPEN=OE.OPEN;window.EventSource.CLOSED=OE.CLOSED;}})();</script>`;
2259
+ const BOOTSTRAP_SCRIPT = `<script>(function(){function ck(){var m=document.cookie.match(/olam_host_cp_token=([^;]+)/);return m?m[1]:'';}function sw(t){document.cookie='olam_host_cp_token='+t+'; path=/; samesite=strict';}try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);sw(d.token);}}catch(e){console.error('[host-cp bootstrap]',e);}var reloading=false;function recover(){if(reloading)return;try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);if(d.token&&ck()!==d.token){reloading=true;sw(d.token);console.warn('[host-cp auth recover] token rotated; reloading');location.reload();}}}catch(e){console.error('[host-cp auth recover]',e);}}var HN=['/api/bootstrap','/api/worlds','/api/projects','/api/workspaces','/api/workspaces/match','/api/repos','/api/runbooks','/api/auth','/health'];var WP=['/api/','/session/','/hooks/','/dispatch','/lanes','/codex/','/review/'];function sr(p){if(typeof p!=='string')return false;if(p.startsWith('/api/world/'))return false;for(var i=0;i<HN.length;i++){var n=HN[i];if(p===n||p.startsWith(n+'?')||p.startsWith(n+'/'))return false;}for(var j=0;j<WP.length;j++){var w=WP[j];if(p===w||p===w.replace(/\\/$/,'')||p.startsWith(w)||p.startsWith(w.replace(/\\/$/,'')+'?')||p.startsWith(w.replace(/\\/$/,'')+'/'))return true;}return false;}function wid(){var p=location.pathname;var m=p.match(/^\\/(world|inbox)\\/([^/?#]+)/);if(m)return m[2];if(/^\\/(?:worlds?|workspaces?|world|sandbox|inbox|plan|design|repos|runbooks|assets|api|health|favicon)($|\\/|\\?)/.test(p))return null;var r=p.match(/^\\/([a-z][a-z0-9-]+)(?:\\/|$|\\?)/);return r?r[1]:null;}function rw(p){var w=wid();return w?'/api/world/'+w+p:p;}var of=window.fetch.bind(window);window.fetch=function(input,init){var pr;if(typeof input==='string'&&sr(input))pr=of(rw(input),init);else if(input&&typeof input.url==='string'&&sr(input.url))pr=of(new Request(rw(input.url),input),init);else pr=of(input,init);return pr.then(function(res){if(res&&res.status===401)recover();return res;});};var OE=window.EventSource;if(OE){window.EventSource=function(u,i){var s=u;if(typeof s==='string'&&sr(s))s=rw(s);var es=new OE(s,i);es.addEventListener('error',function(){if(es.readyState===OE.CLOSED)recover();});return es;};window.EventSource.prototype=OE.prototype;window.EventSource.CONNECTING=OE.CONNECTING;window.EventSource.OPEN=OE.OPEN;window.EventSource.CLOSED=OE.CLOSED;}})();</script>`;
2225
2260
 
2226
2261
  async function renderSpaShell(filePath) {
2227
2262
  const stat = fs.statSync(filePath);
@@ -2255,13 +2290,17 @@ server.on('upgrade', (req, clientSocket, head) => {
2255
2290
  const { worldId, subPath } = parsed;
2256
2291
  const port = WORLDS[worldId];
2257
2292
  if (port === undefined) { clientSocket.destroy(); return; }
2258
- if (!subPath.startsWith('/ttyd/') && subPath !== '/ttyd') {
2293
+ const isTtyd = subPath.startsWith('/ttyd/') || subPath === '/ttyd';
2294
+ const isTtydShell = subPath.startsWith('/ttyd-shell/') || subPath === '/ttyd-shell';
2295
+ if (!isTtyd && !isTtydShell) {
2259
2296
  clientSocket.destroy();
2260
2297
  return;
2261
2298
  }
2262
2299
  const portOffset = port - 19080;
2263
- const ttydPort = 17681 + portOffset;
2264
- const ttydSubPath = subPath === '/ttyd' ? '/' : subPath.slice('/ttyd'.length);
2300
+ const ttydPort = isTtydShell ? 17682 + portOffset : 17681 + portOffset;
2301
+ const ttydSubPath = isTtydShell
2302
+ ? (subPath === '/ttyd-shell' ? '/' : subPath.slice('/ttyd-shell'.length))
2303
+ : (subPath === '/ttyd' ? '/' : subPath.slice('/ttyd'.length));
2265
2304
  const ttydPath = ttydSubPath + (url.search || '');
2266
2305
  /** @type {Record<string, string | string[]>} */
2267
2306
  const outHeaders = {};
@@ -24,6 +24,7 @@ import path from 'node:path';
24
24
  * @property {ComponentVersion} devbox
25
25
  * @property {string} operatorHead - resolved HEAD or 'unknown'
26
26
  * @property {string} checkedAt - ISO timestamp
27
+ * @property {string} cliVersion - operator's CLI semver (e.g. "0.1.69") or 'unknown'
27
28
  */
28
29
 
29
30
  /**
@@ -187,6 +188,14 @@ export async function buildVersionSnapshot({ authServiceUrl, dockerApiBase }) {
187
188
 
188
189
  const hostCpRunning = process.env.OLAM_BUILD_SHA ?? 'unknown';
189
190
 
191
+ // CLI version is propagated by `olam host-cp start` via the
192
+ // OLAM_CLI_VERSION env (see packages/cli/src/commands/host-cp.ts
193
+ // buildComposeEnv). Falls back to host-cp's own package.json when
194
+ // an older CLI started this container without setting the env.
195
+ const cliVersion = process.env.OLAM_CLI_VERSION
196
+ || readHostCpPackageVersion()
197
+ || 'unknown';
198
+
190
199
  return {
191
200
  hostCp: {
192
201
  running: hostCpRunning,
@@ -205,5 +214,32 @@ export async function buildVersionSnapshot({ authServiceUrl, dockerApiBase }) {
205
214
  },
206
215
  operatorHead,
207
216
  checkedAt: new Date().toISOString(),
217
+ cliVersion,
208
218
  };
209
219
  }
220
+
221
+ /**
222
+ * Read host-cp's bundled package.json version as the CLI-version
223
+ * fallback when OLAM_CLI_VERSION isn't propagated. The container
224
+ * Dockerfile copies the manifest into /app, so the lookup walks up
225
+ * from this module's location.
226
+ *
227
+ * @returns {string | null}
228
+ */
229
+ function readHostCpPackageVersion() {
230
+ try {
231
+ const here = path.dirname(new URL(import.meta.url).pathname);
232
+ for (const candidate of [
233
+ path.join(here, '..', 'package.json'),
234
+ path.join(here, '..', '..', 'package.json'),
235
+ ]) {
236
+ if (fs.existsSync(candidate)) {
237
+ const pkg = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
238
+ if (typeof pkg.version === 'string' && pkg.version.length > 0) return pkg.version;
239
+ }
240
+ }
241
+ } catch {
242
+ // best-effort
243
+ }
244
+ return null;
245
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.69",
3
+ "version": "0.1.72",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"
@@ -29,6 +29,7 @@
29
29
  "dev": "tsx src/index.ts",
30
30
  "test": "vitest run --passWithNoTests",
31
31
  "test:ci": "vitest run --reporter=basic --passWithNoTests",
32
+ "test:docker": "vitest run --config vitest.config.docker.ts",
32
33
  "audit:publish-deps": "node scripts/audit-publish-deps.mjs"
33
34
  },
34
35
  "dependencies": {
@@ -39,6 +40,7 @@
39
40
  "ora": "^8.0.0",
40
41
  "picocolors": "^1.1.0",
41
42
  "ssh2": "^1.16.0",
42
- "yaml": "^2.7.0"
43
+ "yaml": "^2.7.0",
44
+ "zod-to-json-schema": "^3.24.0"
43
45
  }
44
46
  }
@@ -1,26 +0,0 @@
1
- /**
2
- * audit-publish-deps-contract.test.ts — contractual regression for the fix
3
- * that prevents the May-2026 release-pipeline wedge.
4
- *
5
- * Bug history: PR #375 added `_require('json-source-map')` to
6
- * src/commands/config.ts but rewrite-publish-package-json.mjs's hand-curated
7
- * PUBLISH_DEPS list never picked it up. Versions 0.1.66 / 0.1.67 / 0.1.68
8
- * published to npm without json-source-map declared. host-cp Dockerfile's
9
- * `npm install -g @pleri/olam-cli@latest && olam --version` crashed with
10
- * `Cannot find module 'json-source-map'`. Three consecutive release runs
11
- * failed; pipeline wedged because the host-cp build sat upstream of the
12
- * commit-and-publish-npm step that would have shipped the fix.
13
- *
14
- * Pin the contract:
15
- * 1. PUBLISH_DEPS must contain json-source-map.
16
- * 2. EXTERNAL must contain json-source-map (esbuild can't bundle dynamic
17
- * _require()'d modules; without external, the require survives in the
18
- * bundle and crashes if not also installed at runtime).
19
- * 3. The audit-publish-deps.mjs script exists and is wired into prepublishOnly
20
- * so this drift class fails fast rather than wedging the pipeline.
21
- * 4. The host-cp Dockerfile installs from a local tarball (cli.tgz), not
22
- * from npm @latest — eliminates the wedge class permanently.
23
- * 5. The release.yml workflow stages cli.tgz before the host-cp build.
24
- */
25
- export {};
26
- //# sourceMappingURL=audit-publish-deps-contract.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"audit-publish-deps-contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit-publish-deps-contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
@@ -1,86 +0,0 @@
1
- /**
2
- * audit-publish-deps-contract.test.ts — contractual regression for the fix
3
- * that prevents the May-2026 release-pipeline wedge.
4
- *
5
- * Bug history: PR #375 added `_require('json-source-map')` to
6
- * src/commands/config.ts but rewrite-publish-package-json.mjs's hand-curated
7
- * PUBLISH_DEPS list never picked it up. Versions 0.1.66 / 0.1.67 / 0.1.68
8
- * published to npm without json-source-map declared. host-cp Dockerfile's
9
- * `npm install -g @pleri/olam-cli@latest && olam --version` crashed with
10
- * `Cannot find module 'json-source-map'`. Three consecutive release runs
11
- * failed; pipeline wedged because the host-cp build sat upstream of the
12
- * commit-and-publish-npm step that would have shipped the fix.
13
- *
14
- * Pin the contract:
15
- * 1. PUBLISH_DEPS must contain json-source-map.
16
- * 2. EXTERNAL must contain json-source-map (esbuild can't bundle dynamic
17
- * _require()'d modules; without external, the require survives in the
18
- * bundle and crashes if not also installed at runtime).
19
- * 3. The audit-publish-deps.mjs script exists and is wired into prepublishOnly
20
- * so this drift class fails fast rather than wedging the pipeline.
21
- * 4. The host-cp Dockerfile installs from a local tarball (cli.tgz), not
22
- * from npm @latest — eliminates the wedge class permanently.
23
- * 5. The release.yml workflow stages cli.tgz before the host-cp build.
24
- */
25
- import { describe, it, expect } from 'vitest';
26
- import { readFileSync } from 'node:fs';
27
- import { join } from 'node:path';
28
- import { fileURLToPath } from 'node:url';
29
- import { dirname } from 'node:path';
30
- const __filename = fileURLToPath(import.meta.url);
31
- const __dirname = dirname(__filename);
32
- const CLI_ROOT = join(__dirname, '..', '..');
33
- const REPO_ROOT = join(CLI_ROOT, '..', '..');
34
- describe('release pipeline wedge — invariants', () => {
35
- it('PUBLISH_DEPS contains json-source-map', () => {
36
- const src = readFileSync(join(CLI_ROOT, 'scripts', 'rewrite-publish-package-json.mjs'), 'utf8');
37
- expect(src).toMatch(/['"]json-source-map['"]\s*:\s*['"]\^?0\.6\./);
38
- });
39
- it('bundle-cli.mjs marks json-source-map external (dynamic _require)', () => {
40
- const src = readFileSync(join(CLI_ROOT, 'scripts', 'bundle-cli.mjs'), 'utf8');
41
- // Must appear inside the EXTERNAL array literal.
42
- const externalBlock = src.slice(src.indexOf('const EXTERNAL = ['));
43
- expect(externalBlock).toMatch(/['"]json-source-map['"]/);
44
- });
45
- it('audit-publish-deps.mjs exists and is wired into prepublishOnly', () => {
46
- const auditScript = readFileSync(join(CLI_ROOT, 'scripts', 'audit-publish-deps.mjs'), 'utf8');
47
- expect(auditScript).toMatch(/PUBLISH_DEPS/);
48
- expect(auditScript).toMatch(/EXTERNAL/);
49
- const pkg = JSON.parse(readFileSync(join(CLI_ROOT, 'package.json'), 'utf8'));
50
- // prepublishOnly must run audit:publish-deps before rewrite-publish-package-json.
51
- expect(pkg.scripts.prepublishOnly).toMatch(/audit:publish-deps/);
52
- // The script itself must exist as an npm script too.
53
- expect(pkg.scripts['audit:publish-deps']).toBeDefined();
54
- });
55
- it('host-cp Dockerfile installs from local cli.tgz, not npm @latest', () => {
56
- const dockerfile = readFileSync(join(REPO_ROOT, 'packages', 'host-cp', 'Dockerfile'), 'utf8');
57
- // Must NOT pull from npm @latest — that's the wedge.
58
- // Match only ACTUAL run-shape lines (npm install at line start or after
59
- // backslash-continuation), not the comment block that documents the
60
- // historical bug.
61
- const runLines = dockerfile
62
- .split('\n')
63
- .filter((l) => !l.trim().startsWith('#'))
64
- .join('\n');
65
- expect(runLines).not.toMatch(/npm install -g @pleri\/olam-cli@latest/);
66
- // Must install from the staged tarball.
67
- expect(dockerfile).toMatch(/COPY cli\.tgz/);
68
- expect(dockerfile).toMatch(/npm install -g \/tmp\/olam-cli\.tgz/);
69
- });
70
- it('release.yml stages cli.tgz before host-cp docker build', () => {
71
- const workflow = readFileSync(join(REPO_ROOT, '.github', 'workflows', 'release.yml'), 'utf8');
72
- expect(workflow).toMatch(/scripts\/ci\/stage-host-cp-cli\.sh/);
73
- // Order matters: stage-host-cp-cli.sh must appear BEFORE the
74
- // docker/build-push-action@v6 invocation in publish-host-cp.
75
- const publishHostCpBlock = workflow.slice(workflow.indexOf('publish-host-cp:'));
76
- const stageIdx = publishHostCpBlock.indexOf('stage-host-cp-cli.sh');
77
- const buildIdx = publishHostCpBlock.indexOf('docker/build-push-action');
78
- expect(stageIdx).toBeGreaterThan(0);
79
- expect(buildIdx).toBeGreaterThan(stageIdx);
80
- });
81
- it('ci.yml audit job runs audit:publish-deps', () => {
82
- const ci = readFileSync(join(REPO_ROOT, '.github', 'workflows', 'ci.yml'), 'utf8');
83
- expect(ci).toMatch(/audit:publish-deps/);
84
- });
85
- });
86
- //# sourceMappingURL=audit-publish-deps-contract.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"audit-publish-deps-contract.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-publish-deps-contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAE7C,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,GAAG,GAAG,YAAY,CACtB,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,kCAAkC,CAAC,EAC7D,MAAM,CACP,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,GAAG,GAAG,YAAY,CACtB,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,gBAAgB,CAAC,EAC3C,MAAM,CACP,CAAC;QACF,iDAAiD;QACjD,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,WAAW,GAAG,YAAY,CAC9B,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,wBAAwB,CAAC,EACnD,MAAM,CACP,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAExC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACrD,CAAC;QACF,kFAAkF;QAClF,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACjE,qDAAqD;QACrD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,UAAU,GAAG,YAAY,CAC7B,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC,EACpD,MAAM,CACP,CAAC;QACF,qDAAqD;QACrD,wEAAwE;QACxE,oEAAoE;QACpE,kBAAkB;QAClB,MAAM,QAAQ,GAAG,UAAU;aACxB,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aACxC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;QACvE,wCAAwC;QACxC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC5C,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,QAAQ,GAAG,YAAY,CAC3B,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,EACtD,MAAM,CACP,CAAC;QACF,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QAC/D,6DAA6D;QAC7D,6DAA6D;QAC7D,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACxE,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,EAAE,GAAG,YAAY,CACrB,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,EACjD,MAAM,CACP,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=auth-status.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-status.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/auth-status.test.ts"],"names":[],"mappings":""}