@pleri/olam-cli 0.1.7

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 (196) hide show
  1. package/dist/__tests__/auth-status.test.d.ts +2 -0
  2. package/dist/__tests__/auth-status.test.d.ts.map +1 -0
  3. package/dist/__tests__/auth-status.test.js +290 -0
  4. package/dist/__tests__/auth-status.test.js.map +1 -0
  5. package/dist/__tests__/auth-upgrade.test.d.ts +9 -0
  6. package/dist/__tests__/auth-upgrade.test.d.ts.map +1 -0
  7. package/dist/__tests__/auth-upgrade.test.js +161 -0
  8. package/dist/__tests__/auth-upgrade.test.js.map +1 -0
  9. package/dist/__tests__/create-app-urls.test.d.ts +2 -0
  10. package/dist/__tests__/create-app-urls.test.d.ts.map +1 -0
  11. package/dist/__tests__/create-app-urls.test.js +102 -0
  12. package/dist/__tests__/create-app-urls.test.js.map +1 -0
  13. package/dist/__tests__/enter.test.d.ts +2 -0
  14. package/dist/__tests__/enter.test.d.ts.map +1 -0
  15. package/dist/__tests__/enter.test.js +90 -0
  16. package/dist/__tests__/enter.test.js.map +1 -0
  17. package/dist/__tests__/host-cp-gh-token.test.d.ts +9 -0
  18. package/dist/__tests__/host-cp-gh-token.test.d.ts.map +1 -0
  19. package/dist/__tests__/host-cp-gh-token.test.js +119 -0
  20. package/dist/__tests__/host-cp-gh-token.test.js.map +1 -0
  21. package/dist/__tests__/host-cp.test.d.ts +9 -0
  22. package/dist/__tests__/host-cp.test.d.ts.map +1 -0
  23. package/dist/__tests__/host-cp.test.js +254 -0
  24. package/dist/__tests__/host-cp.test.js.map +1 -0
  25. package/dist/__tests__/keys.test.d.ts +9 -0
  26. package/dist/__tests__/keys.test.d.ts.map +1 -0
  27. package/dist/__tests__/keys.test.js +145 -0
  28. package/dist/__tests__/keys.test.js.map +1 -0
  29. package/dist/__tests__/logs.test.d.ts +9 -0
  30. package/dist/__tests__/logs.test.d.ts.map +1 -0
  31. package/dist/__tests__/logs.test.js +124 -0
  32. package/dist/__tests__/logs.test.js.map +1 -0
  33. package/dist/__tests__/ps.test.d.ts +2 -0
  34. package/dist/__tests__/ps.test.d.ts.map +1 -0
  35. package/dist/__tests__/ps.test.js +172 -0
  36. package/dist/__tests__/ps.test.js.map +1 -0
  37. package/dist/__tests__/status-app-urls.test.d.ts +2 -0
  38. package/dist/__tests__/status-app-urls.test.d.ts.map +1 -0
  39. package/dist/__tests__/status-app-urls.test.js +125 -0
  40. package/dist/__tests__/status-app-urls.test.js.map +1 -0
  41. package/dist/__tests__/upgrade.test.d.ts +9 -0
  42. package/dist/__tests__/upgrade.test.d.ts.map +1 -0
  43. package/dist/__tests__/upgrade.test.js +262 -0
  44. package/dist/__tests__/upgrade.test.js.map +1 -0
  45. package/dist/commands/__tests__/carry-uncommitted.test.d.ts +14 -0
  46. package/dist/commands/__tests__/carry-uncommitted.test.d.ts.map +1 -0
  47. package/dist/commands/__tests__/carry-uncommitted.test.js +83 -0
  48. package/dist/commands/__tests__/carry-uncommitted.test.js.map +1 -0
  49. package/dist/commands/__tests__/openHostCpUrl.test.d.ts +2 -0
  50. package/dist/commands/__tests__/openHostCpUrl.test.d.ts.map +1 -0
  51. package/dist/commands/__tests__/openHostCpUrl.test.js +63 -0
  52. package/dist/commands/__tests__/openHostCpUrl.test.js.map +1 -0
  53. package/dist/commands/__tests__/refresh.test.d.ts +13 -0
  54. package/dist/commands/__tests__/refresh.test.d.ts.map +1 -0
  55. package/dist/commands/__tests__/refresh.test.js +170 -0
  56. package/dist/commands/__tests__/refresh.test.js.map +1 -0
  57. package/dist/commands/auth-status.d.ts +43 -0
  58. package/dist/commands/auth-status.d.ts.map +1 -0
  59. package/dist/commands/auth-status.js +208 -0
  60. package/dist/commands/auth-status.js.map +1 -0
  61. package/dist/commands/auth-upgrade.d.ts +47 -0
  62. package/dist/commands/auth-upgrade.d.ts.map +1 -0
  63. package/dist/commands/auth-upgrade.js +277 -0
  64. package/dist/commands/auth-upgrade.js.map +1 -0
  65. package/dist/commands/auth.d.ts +16 -0
  66. package/dist/commands/auth.d.ts.map +1 -0
  67. package/dist/commands/auth.js +283 -0
  68. package/dist/commands/auth.js.map +1 -0
  69. package/dist/commands/create.d.ts +8 -0
  70. package/dist/commands/create.d.ts.map +1 -0
  71. package/dist/commands/create.js +512 -0
  72. package/dist/commands/create.js.map +1 -0
  73. package/dist/commands/crystallize.d.ts +8 -0
  74. package/dist/commands/crystallize.d.ts.map +1 -0
  75. package/dist/commands/crystallize.js +101 -0
  76. package/dist/commands/crystallize.js.map +1 -0
  77. package/dist/commands/destroy.d.ts +6 -0
  78. package/dist/commands/destroy.d.ts.map +1 -0
  79. package/dist/commands/destroy.js +54 -0
  80. package/dist/commands/destroy.js.map +1 -0
  81. package/dist/commands/dispatch.d.ts +9 -0
  82. package/dist/commands/dispatch.d.ts.map +1 -0
  83. package/dist/commands/dispatch.js +94 -0
  84. package/dist/commands/dispatch.js.map +1 -0
  85. package/dist/commands/enter.d.ts +63 -0
  86. package/dist/commands/enter.d.ts.map +1 -0
  87. package/dist/commands/enter.js +206 -0
  88. package/dist/commands/enter.js.map +1 -0
  89. package/dist/commands/host-cp.d.ts +191 -0
  90. package/dist/commands/host-cp.d.ts.map +1 -0
  91. package/dist/commands/host-cp.js +797 -0
  92. package/dist/commands/host-cp.js.map +1 -0
  93. package/dist/commands/init.d.ts +9 -0
  94. package/dist/commands/init.d.ts.map +1 -0
  95. package/dist/commands/init.js +143 -0
  96. package/dist/commands/init.js.map +1 -0
  97. package/dist/commands/install.d.ts +22 -0
  98. package/dist/commands/install.d.ts.map +1 -0
  99. package/dist/commands/install.js +203 -0
  100. package/dist/commands/install.js.map +1 -0
  101. package/dist/commands/keys.d.ts +26 -0
  102. package/dist/commands/keys.d.ts.map +1 -0
  103. package/dist/commands/keys.js +151 -0
  104. package/dist/commands/keys.js.map +1 -0
  105. package/dist/commands/lanes.d.ts +18 -0
  106. package/dist/commands/lanes.d.ts.map +1 -0
  107. package/dist/commands/lanes.js +122 -0
  108. package/dist/commands/lanes.js.map +1 -0
  109. package/dist/commands/list.d.ts +6 -0
  110. package/dist/commands/list.d.ts.map +1 -0
  111. package/dist/commands/list.js +39 -0
  112. package/dist/commands/list.js.map +1 -0
  113. package/dist/commands/logs.d.ts +38 -0
  114. package/dist/commands/logs.d.ts.map +1 -0
  115. package/dist/commands/logs.js +177 -0
  116. package/dist/commands/logs.js.map +1 -0
  117. package/dist/commands/observe.d.ts +9 -0
  118. package/dist/commands/observe.d.ts.map +1 -0
  119. package/dist/commands/observe.js +34 -0
  120. package/dist/commands/observe.js.map +1 -0
  121. package/dist/commands/policy-check.d.ts +14 -0
  122. package/dist/commands/policy-check.d.ts.map +1 -0
  123. package/dist/commands/policy-check.js +76 -0
  124. package/dist/commands/policy-check.js.map +1 -0
  125. package/dist/commands/pr.d.ts +17 -0
  126. package/dist/commands/pr.d.ts.map +1 -0
  127. package/dist/commands/pr.js +148 -0
  128. package/dist/commands/pr.js.map +1 -0
  129. package/dist/commands/ps.d.ts +25 -0
  130. package/dist/commands/ps.d.ts.map +1 -0
  131. package/dist/commands/ps.js +164 -0
  132. package/dist/commands/ps.js.map +1 -0
  133. package/dist/commands/refresh-helpers.d.ts +25 -0
  134. package/dist/commands/refresh-helpers.d.ts.map +1 -0
  135. package/dist/commands/refresh-helpers.js +56 -0
  136. package/dist/commands/refresh-helpers.js.map +1 -0
  137. package/dist/commands/refresh.d.ts +23 -0
  138. package/dist/commands/refresh.d.ts.map +1 -0
  139. package/dist/commands/refresh.js +237 -0
  140. package/dist/commands/refresh.js.map +1 -0
  141. package/dist/commands/status.d.ts +6 -0
  142. package/dist/commands/status.d.ts.map +1 -0
  143. package/dist/commands/status.js +51 -0
  144. package/dist/commands/status.js.map +1 -0
  145. package/dist/commands/upgrade.d.ts +67 -0
  146. package/dist/commands/upgrade.d.ts.map +1 -0
  147. package/dist/commands/upgrade.js +358 -0
  148. package/dist/commands/upgrade.js.map +1 -0
  149. package/dist/commands/workspace.d.ts +23 -0
  150. package/dist/commands/workspace.d.ts.map +1 -0
  151. package/dist/commands/workspace.js +198 -0
  152. package/dist/commands/workspace.js.map +1 -0
  153. package/dist/commands/world-snapshot.d.ts +18 -0
  154. package/dist/commands/world-snapshot.d.ts.map +1 -0
  155. package/dist/commands/world-snapshot.js +327 -0
  156. package/dist/commands/world-snapshot.js.map +1 -0
  157. package/dist/context.d.ts +26 -0
  158. package/dist/context.d.ts.map +1 -0
  159. package/dist/context.js +51 -0
  160. package/dist/context.js.map +1 -0
  161. package/dist/index.d.ts +9 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +18007 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/mcp-server.js +32236 -0
  166. package/dist/output.d.ts +10 -0
  167. package/dist/output.d.ts.map +1 -0
  168. package/dist/output.js +31 -0
  169. package/dist/output.js.map +1 -0
  170. package/host-cp/compose.yaml +126 -0
  171. package/host-cp/src/auth-secret-hint.mjs +45 -0
  172. package/host-cp/src/auth.mjs +155 -0
  173. package/host-cp/src/compose-worlds-sources.mjs +170 -0
  174. package/host-cp/src/container-secret-fetcher.mjs +163 -0
  175. package/host-cp/src/docker-events.mjs +184 -0
  176. package/host-cp/src/local-worlds-source.mjs +83 -0
  177. package/host-cp/src/plan-orchestrator.mjs +829 -0
  178. package/host-cp/src/plan-progress.mjs +282 -0
  179. package/host-cp/src/pr-cache.mjs +201 -0
  180. package/host-cp/src/pr-merge-poller.mjs +154 -0
  181. package/host-cp/src/process-poller.mjs +250 -0
  182. package/host-cp/src/proxy.mjs +245 -0
  183. package/host-cp/src/pylon-worlds-source.mjs +68 -0
  184. package/host-cp/src/redact.mjs +67 -0
  185. package/host-cp/src/secret-cache.mjs +104 -0
  186. package/host-cp/src/server.mjs +2215 -0
  187. package/host-cp/src/sse-gate.mjs +117 -0
  188. package/host-cp/src/version-status.mjs +209 -0
  189. package/host-cp/src/workspace-catalog.mjs +149 -0
  190. package/host-cp/src/world-names-store.mjs +176 -0
  191. package/host-cp/src/world-pr-state.mjs +97 -0
  192. package/host-cp/src/world-progress.mjs +322 -0
  193. package/host-cp/src/world-tunnel-manager.mjs +288 -0
  194. package/host-cp/src/worlds-db-source.mjs +191 -0
  195. package/host-cp/src/worlds-source.mjs +59 -0
  196. package/package.json +38 -0
@@ -0,0 +1,512 @@
1
+ /**
2
+ * olam create — Provision a new isolated development world.
3
+ *
4
+ * Delegates to WorldManager.createWorld, same as the MCP server tool.
5
+ */
6
+ import { spawnSync } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { dirname, resolve } from 'node:path';
9
+ import ora from 'ora';
10
+ import pc from 'picocolors';
11
+ import { AuthPreflightError } from '@olam/core/src/world/manager.js';
12
+ import { getDevboxFreshness, formatFreshnessWarning, } from '@olam/core/src/world/devbox-freshness.js';
13
+ import { inferRepos, PICKER_CONFIDENCE_THRESHOLD, } from '@olam/core/src/world/infer-repos.js';
14
+ import { decideWorkspaceMatch, } from '@olam/core/src/world/match-workspace.js';
15
+ import { loadContext } from '../context.js';
16
+ import { printError, printInfo, printHeader, printWarning } from '../output.js';
17
+ import { probeHostCp, gatherProbeFailureDiagnostics, callHostCpProxy, openHostCpUrl } from './host-cp.js';
18
+ const HOST_CP_URL = 'http://127.0.0.1:19000';
19
+ /** Read the host-cp token from ~/.olam/host-cp.token for use in create. */
20
+ async function readHostCpTokenForCreate() {
21
+ try {
22
+ const { default: fs } = await import('node:fs');
23
+ const { default: os } = await import('node:os');
24
+ const { default: path } = await import('node:path');
25
+ const tp = path.join(process.env.OLAM_HOME ?? path.join(os.homedir(), '.olam'), 'host-cp.token');
26
+ if (!fs.existsSync(tp))
27
+ return null;
28
+ return fs.readFileSync(tp, 'utf-8').trim();
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ export function registerCreate(program) {
35
+ program
36
+ .command('create')
37
+ .description('Create a new development world')
38
+ .option('--name <name>', 'World name (required unless --from-prompt is set; auto-derived in that case)')
39
+ .option('--repos <repos...>', 'Repos to include (names from .olam/config.yaml; wins over --workspace)')
40
+ .option('--workspace <name>', 'Named workspace from the host catalog (~/.olam/workspaces/<name>.yaml)')
41
+ .option('--task <task>', 'Initial task to dispatch')
42
+ .option('--branch <branch>', 'Override default branch name')
43
+ .option('--plan <file>', 'Path to a plan file to inject')
44
+ .option('--no-auth', 'Skip auto-injecting host credentials')
45
+ // Phase F-2-D (D4): host CP integration. Default: emit a one-line
46
+ // hint if host CP is not running. --no-host-cp suppresses the hint
47
+ // entirely. Real auto-start ships in a future iteration; for now
48
+ // the hint keeps the operator's existing workflow unblocked while
49
+ // surfacing the host CP UI option.
50
+ .option('--no-host-cp', 'Suppress the host CP "you might want to start it" hint')
51
+ // Phase C9 (olam-dogfood-vision): opt-in flag spawns a parallel
52
+ // claude-lane-codex-review session alongside claude-main, prompted
53
+ // to monitor + critique main's work. Lives on the same world; sees
54
+ // the same workspace + thoughts. Auto-spawned at world creation
55
+ // time; the operator can destroy it via `olam lanes destroy <world>
56
+ // codex-review` if it gets noisy.
57
+ .option('--auto-codex-review', 'Spawn a parallel codex-review lane that critiques main as it works')
58
+ // Phase D6 (olam-dogfood-vision): open Host CP UI in browser on
59
+ // successful create. Default-on for interactive sessions; suppress
60
+ // with --no-open. Headless / CI / piped-output runs auto-skip.
61
+ .option('--no-open', 'Suppress auto-opening the Host CP UI in the browser on success')
62
+ // M5 dogfood follow-up (B1): when the devbox image is older than
63
+ // the source files baked into it, fresh worlds run stale code.
64
+ // --rebuild-base auto-invokes the build script; --no-freshness-check
65
+ // skips the warning entirely (CI/automation).
66
+ .option('--rebuild-base', 'Rebuild olam-devbox:latest before creating (slow)')
67
+ .option('--no-freshness-check', 'Skip the devbox image freshness check')
68
+ // CLI parity for the MCP `olam_create_from_prompt` tool. The prompt
69
+ // is dispatched as the world's task AND drives the workspace
70
+ // inference (same heuristic the MCP tool uses). When passed:
71
+ // - --name is auto-derived from the prompt (slugified, capped at 40 chars)
72
+ // - --workspace + --repos are inferred against the host-cp catalog
73
+ // - On low-confidence inference or N-way ambiguity, the CLI prints
74
+ // the picker payload and exits 1 so the operator can re-run with
75
+ // an explicit --workspace / --repos.
76
+ // Mutually exclusive with --task (the prompt IS the task) and
77
+ // overrides --name. --workspace/--repos still win if explicitly set.
78
+ .option('--from-prompt <prompt>', 'NL prompt → infer workspace + dispatch (CLI parity for olam_create_from_prompt MCP tool)')
79
+ .option('--keep-after-merge', "Disable auto-destroy when the world's PR merges (useful for inspection/debugging)")
80
+ // Phase B B3 (olam-session-stability): opt out of B1's strip step
81
+ // so the operator's in-progress edits make it into the world's
82
+ // worktree. Default OFF: world starts with a clean tree (the
83
+ // baseline-diff snapshot still runs so the reaper can scope claude's
84
+ // footprint). Use this when you've explicitly staged or modified
85
+ // files in your local checkout and want claude to continue from
86
+ // there.
87
+ .option('--carry-uncommitted', "Preserve operator's uncommitted edits in the world's worktree")
88
+ .action(async (opts) => {
89
+ // CLI parity for the MCP tool: when --from-prompt is set, treat
90
+ // it as the world's task AND use it to infer workspace + repos.
91
+ // Mutually exclusive with --task; explicit --workspace / --repos
92
+ // still win (operator override).
93
+ let resolvedName = opts.name;
94
+ let resolvedWorkspace = opts.workspace;
95
+ let resolvedRepos = opts.repos;
96
+ let resolvedTask = opts.task;
97
+ if (opts.fromPrompt) {
98
+ if (opts.task) {
99
+ printError('--from-prompt and --task are mutually exclusive (the prompt IS the task).');
100
+ process.exitCode = 1;
101
+ return;
102
+ }
103
+ resolvedTask = opts.fromPrompt;
104
+ if (!resolvedName) {
105
+ resolvedName = defaultNameFromPrompt(opts.fromPrompt);
106
+ }
107
+ // Infer when caller didn't already pin workspace + repos.
108
+ if (!resolvedWorkspace && !resolvedRepos) {
109
+ const inferenceSpinner = ora('Inferring workspace from prompt…').start();
110
+ try {
111
+ const catalog = await fetchHostCpWorkspaces();
112
+ const catalogRepos = Array.from(new Set(catalog.flatMap((w) => w.projects)));
113
+ const inferred = inferRepos({
114
+ prompt: opts.fromPrompt,
115
+ catalog: catalogRepos,
116
+ });
117
+ if (!inferred.proceed) {
118
+ inferenceSpinner.fail('Inference confidence too low');
119
+ const reason = inferred.repos.length === 0
120
+ ? 'no repo names extracted from prompt'
121
+ : `inference confidence ${inferred.confidence.toFixed(2)} below ${PICKER_CONFIDENCE_THRESHOLD}`;
122
+ printError(`Picker needed: ${reason}`);
123
+ if (catalogRepos.length > 0) {
124
+ console.log(pc.dim(` available repos: ${catalogRepos.join(', ')}`));
125
+ }
126
+ console.log(pc.dim(' rerun with explicit --workspace <name> or --repos <a> <b> <c>'));
127
+ process.exitCode = 1;
128
+ return;
129
+ }
130
+ const exactMatches = await fetchHostCpExactMatches(inferred.repos);
131
+ const decision = decideWorkspaceMatch({
132
+ inferredRepos: inferred.repos,
133
+ exactMatches,
134
+ fullCatalog: catalog,
135
+ });
136
+ if (decision.result === 'exact-1') {
137
+ resolvedWorkspace = decision.workspace.name;
138
+ }
139
+ else if (decision.result === 'subset-1') {
140
+ resolvedWorkspace = decision.workspace.name;
141
+ }
142
+ else if (decision.result === 'exact-N' || decision.result === 'subset-N') {
143
+ inferenceSpinner.fail(`Multiple workspaces match (${decision.result})`);
144
+ const cands = decision.result === 'exact-N'
145
+ ? decision.candidates.map((w) => w.name)
146
+ : decision.candidates.map((c) => c.workspace.name);
147
+ printError(`Picker needed: ${cands.join(', ')}`);
148
+ console.log(pc.dim(' rerun with explicit --workspace <name>'));
149
+ process.exitCode = 1;
150
+ return;
151
+ }
152
+ else {
153
+ // create-new — no existing workspace covers the inferred
154
+ // repo set. Pass repos through; WorldManager creates one.
155
+ resolvedRepos = [...inferred.repos];
156
+ }
157
+ inferenceSpinner.succeed(resolvedWorkspace
158
+ ? `Inferred workspace: ${resolvedWorkspace} (confidence ${inferred.confidence.toFixed(2)})`
159
+ : `Inferred new workspace from repos: ${inferred.repos.join(', ')}`);
160
+ }
161
+ catch (err) {
162
+ inferenceSpinner.fail('Inference failed');
163
+ printError(err instanceof Error ? err.message : String(err));
164
+ process.exitCode = 1;
165
+ return;
166
+ }
167
+ }
168
+ }
169
+ if (!resolvedName) {
170
+ printError('--name is required (omit only when --from-prompt is set).');
171
+ process.exitCode = 1;
172
+ return;
173
+ }
174
+ const { ctx, error } = await loadContext();
175
+ if (!ctx) {
176
+ printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
177
+ process.exitCode = 1;
178
+ return;
179
+ }
180
+ // M5 dogfood follow-up (B1): devbox staleness check. Resolves
181
+ // repo root by walking up from cwd until we hit a directory
182
+ // containing `packages/`. Falls back to cwd if not found.
183
+ if (opts.freshnessCheck) {
184
+ const repoRoot = resolveRepoRoot(process.cwd());
185
+ const freshness = getDevboxFreshness({ repoRoot });
186
+ if (freshness.isStale) {
187
+ if (opts.rebuildBase) {
188
+ const spinner = ora('Rebuilding olam-devbox:latest…').start();
189
+ const rebuild = spawnSync('bash', [resolve(repoRoot, 'packages/adapters/src/docker/build-devbox.sh')], { cwd: repoRoot, stdio: 'inherit' });
190
+ if (rebuild.status !== 0) {
191
+ spinner.fail('Devbox rebuild failed');
192
+ process.exitCode = 1;
193
+ return;
194
+ }
195
+ spinner.succeed('Devbox image rebuilt');
196
+ }
197
+ else {
198
+ const warning = formatFreshnessWarning(freshness);
199
+ if (warning)
200
+ printWarning(warning);
201
+ }
202
+ }
203
+ }
204
+ const spinner = ora('Creating world...').start();
205
+ try {
206
+ const world = await ctx.worldManager.createWorld({
207
+ name: resolvedName,
208
+ repos: resolvedRepos,
209
+ ...(resolvedWorkspace ? { workspace: resolvedWorkspace } : {}),
210
+ task: resolvedTask,
211
+ branchName: opts.branch,
212
+ planFile: opts.plan,
213
+ noAuth: !opts.auth,
214
+ // ADV-B3-LOW2: strict-boolean coercion. `?? false` would pass through
215
+ // truthy non-booleans (e.g. if the flag's shape ever grows to
216
+ // `--carry-uncommitted [mode]` where commander returns a string).
217
+ // `=== true` ensures only the literal boolean true reaches the
218
+ // manager, matching the manager's strict `if (!opts.carryUncommitted)`.
219
+ carryUncommitted: opts.carryUncommitted === true,
220
+ });
221
+ spinner.succeed('World created');
222
+ // --keep-after-merge: persist into the registry immediately so
223
+ // the host-cp polling loop sees it even if host-cp starts later.
224
+ if (opts.keepAfterMerge) {
225
+ const { WorldRegistry } = await import('@olam/core/src/world/registry.js');
226
+ const reg2 = new WorldRegistry();
227
+ try {
228
+ reg2.update(world.id, { autoDestroyOnMerge: false });
229
+ }
230
+ finally {
231
+ reg2.close();
232
+ }
233
+ }
234
+ printHeader(world.name);
235
+ printInfo('ID', world.id);
236
+ printInfo('Status', world.status);
237
+ printInfo('Repos', world.repos.join(', ') || '(all configured)');
238
+ printInfo('Branch', world.branch);
239
+ printInfo('Port Offset', String(world.portOffset));
240
+ printInfo('Provider', world.computeProvider);
241
+ printInfo('Workspace', world.workspacePath);
242
+ if (world.dashboardUrl) {
243
+ printInfo('Dashboard', world.dashboardUrl);
244
+ }
245
+ if (world.appPortUrls && world.appPortUrls.length > 0) {
246
+ world.appPortUrls.forEach((ap, i) => {
247
+ printInfo(i === 0 ? 'Apps' : '', `${ap.repoName} ${ap.url}`);
248
+ });
249
+ }
250
+ if (resolvedTask) {
251
+ printInfo('Task', resolvedTask);
252
+ }
253
+ if (world.credentialsInjected?.claude) {
254
+ console.log(`\n${pc.green('Credentials injected. World is ready for dispatch.')}`);
255
+ }
256
+ else if (world.dashboardUrl) {
257
+ console.log(`\n${pc.yellow('Authenticate at')} ${world.dashboardUrl}`);
258
+ }
259
+ // host-cp reliability fix: use HTTP probe instead of docker-only detection.
260
+ // Supports both bare-node and container deployments.
261
+ if (opts.hostCp !== false) {
262
+ const probeResult = await probeHostCp().catch(() => null);
263
+ if (!probeResult) {
264
+ // Fail-loud: the world IS created but auto-registration failed.
265
+ const diag = await gatherProbeFailureDiagnostics().catch(() => ({
266
+ bootstrapStatus: 'probe error',
267
+ containerStatus: 'probe error',
268
+ }));
269
+ process.stderr.write([
270
+ '',
271
+ pc.red('Host CP probe failed.'),
272
+ ` tried: http://127.0.0.1:19000/api/bootstrap → ${diag.bootstrapStatus}`,
273
+ ` tried: docker container "olam-host-cp" → ${diag.containerStatus}`,
274
+ '',
275
+ pc.yellow('World was created but the SPA inbox will not show it until you:'),
276
+ ` ${pc.cyan('olam host-cp start')} (start the host CP)`,
277
+ ` ${pc.cyan(`olam host-cp register --world ${world.id}`)} (register manually)`,
278
+ ` OR pass ${pc.dim('--no-host-cp')} on next create to suppress this check.`,
279
+ '',
280
+ ].join('\n'));
281
+ process.exitCode = 1;
282
+ return;
283
+ }
284
+ // Auto-register the new world so it appears in the host CP UI
285
+ // immediately. Per-world CP base port = 19080 + offset.
286
+ const cpPort = 19080 + world.portOffset;
287
+ const hostCpUrl = probeResult.url;
288
+ const reg = await (async () => {
289
+ const token = await readHostCpTokenForCreate();
290
+ if (!token)
291
+ return { ok: false, status: 0, error: 'no token' };
292
+ const url = `${hostCpUrl}/api/admin/registry`;
293
+ try {
294
+ const res = await fetch(url, {
295
+ method: 'POST',
296
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
297
+ body: JSON.stringify({ id: world.id, port: cpPort }),
298
+ });
299
+ if (!res.ok) {
300
+ const text = await res.text().catch(() => '');
301
+ return { ok: false, status: res.status, error: text || `HTTP ${res.status}` };
302
+ }
303
+ return { ok: true, status: res.status };
304
+ }
305
+ catch (err) {
306
+ return { ok: false, status: 0, error: err instanceof Error ? err.message : String(err) };
307
+ }
308
+ })();
309
+ if (!reg.ok) {
310
+ process.stderr.write([
311
+ '',
312
+ pc.red('Host CP registry POST failed.'),
313
+ ` url: ${hostCpUrl}/api/admin/registry`,
314
+ ` status: ${reg.status}`,
315
+ ` error: ${reg.error}`,
316
+ '',
317
+ pc.yellow('World was created but not registered. Run manually:'),
318
+ ` ${pc.cyan(`olam host-cp register --world ${world.id}`)}`,
319
+ '',
320
+ ].join('\n'));
321
+ process.exitCode = 1;
322
+ return;
323
+ }
324
+ printInfo('Host CP', `registered → :${cpPort} (mode: ${probeResult.mode})`);
325
+ // Propagate the friendly name from the CLI's --name flag.
326
+ try {
327
+ const token = await readHostCpTokenForCreate();
328
+ if (token && world.name && world.name !== world.id) {
329
+ await fetch(`${hostCpUrl}/api/worlds/${encodeURIComponent(world.id)}`, {
330
+ method: 'PATCH',
331
+ headers: {
332
+ Authorization: `Bearer ${token}`,
333
+ 'Content-Type': 'application/json',
334
+ },
335
+ body: JSON.stringify({ name: world.name }),
336
+ });
337
+ }
338
+ // --keep-after-merge: record auto_destroy_on_merge=false.
339
+ if (opts.keepAfterMerge && token) {
340
+ await fetch(`${hostCpUrl}/api/admin/world-pr`, {
341
+ method: 'POST',
342
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
343
+ body: JSON.stringify({ worldId: world.id, prUrl: null, autoDestroyOnMerge: false }),
344
+ signal: AbortSignal.timeout(3000),
345
+ });
346
+ printInfo('Keep-after-merge', 'auto-destroy disabled for this world');
347
+ }
348
+ }
349
+ catch {
350
+ // Silent — the world is registered; the name is just UI sugar.
351
+ }
352
+ // Phase C9: spawn the auto-codex-review lane.
353
+ if (opts.autoCodexReview && reg.ok) {
354
+ const reviewTask = 'You are the codex-review sub-lane. Watch the main session ' +
355
+ '(claude-main) as it works on the world\'s primary task. ' +
356
+ 'Periodically read its recent thought_nodes (filter by ' +
357
+ 'session_id=claude-main) and surface concrete concerns: ' +
358
+ 'security risks, plumbing bugs, premature abstractions. ' +
359
+ 'Adversarial-reviewer voice; constructive but blunt.';
360
+ try {
361
+ const result = await callHostCpProxy('POST', world.id, '/lanes/create', { name: 'codex-review', task: reviewTask });
362
+ if (result.ok) {
363
+ printInfo('Auto-review', 'spawned claude-lane-codex-review');
364
+ }
365
+ else {
366
+ printWarning(`Auto-review spawn failed (HTTP ${result.status}): ${result.error}. Retry with \`olam lanes create ${world.id} --name codex-review --task '...'\`.`);
367
+ }
368
+ }
369
+ catch (err) {
370
+ printWarning(`Auto-review spawn errored: ${err instanceof Error ? err.message : String(err)}`);
371
+ }
372
+ }
373
+ const worldUrl = `${hostCpUrl}/world/${encodeURIComponent(world.id)}`;
374
+ console.log(`\n${pc.cyan('Host CP UI:')} ${worldUrl}`);
375
+ // Phase D6: auto-open in browser unless --no-open.
376
+ if (opts.open !== false && reg.ok) {
377
+ const openResult = openHostCpUrl(worldUrl);
378
+ if (openResult.opened) {
379
+ printInfo('Browser', 'opened');
380
+ }
381
+ else if (openResult.reason) {
382
+ printInfo('Browser', `not opened (${openResult.reason})`);
383
+ }
384
+ }
385
+ }
386
+ }
387
+ catch (err) {
388
+ spinner.fail('Failed to create world');
389
+ if (err instanceof AuthPreflightError) {
390
+ printError(err.message);
391
+ if (err.remedy)
392
+ console.log(` ${pc.dim(err.remedy)}`);
393
+ }
394
+ else {
395
+ printError(err instanceof Error ? err.message : String(err));
396
+ }
397
+ process.exitCode = 1;
398
+ }
399
+ });
400
+ }
401
+ /**
402
+ * Walk up from `start` until we find a directory containing `packages/`.
403
+ * Used by the B1 freshness check to locate paths relative to the repo
404
+ * root regardless of which subdirectory the operator invoked the CLI
405
+ * from. Falls back to `start` if no marker is found before /.
406
+ */
407
+ function resolveRepoRoot(start) {
408
+ let cur = start;
409
+ while (true) {
410
+ // Repo root signature: top-level package.json + packages/ dir.
411
+ if (existsSync(resolve(cur, 'packages')) && existsSync(resolve(cur, 'package.json'))) {
412
+ return cur;
413
+ }
414
+ const parent = dirname(cur);
415
+ if (parent === cur)
416
+ return start; // walked to filesystem root
417
+ cur = parent;
418
+ }
419
+ }
420
+ /**
421
+ * Slugify an NL prompt into a default world name. Lowercase, kebab-
422
+ * case, max 40 chars. Mirrors the MCP tool's `defaultNameFromPrompt`
423
+ * helper at packages/mcp-server/src/tools/create-from-prompt.ts so
424
+ * --from-prompt produces the same slug shape regardless of entry
425
+ * point.
426
+ */
427
+ function defaultNameFromPrompt(prompt) {
428
+ const slug = prompt
429
+ .toLowerCase()
430
+ .replace(/[^a-z0-9\s-]/g, '')
431
+ .trim()
432
+ .replace(/\s+/g, '-')
433
+ .slice(0, 40);
434
+ return slug || 'unnamed';
435
+ }
436
+ /**
437
+ * Read host-cp's startup token. Defensive — returns null on every
438
+ * failure (file missing, permissions, etc.) so --from-prompt can
439
+ * still fall through to a "host-cp not running" picker error rather
440
+ * than throwing.
441
+ */
442
+ async function readHostCpToken() {
443
+ try {
444
+ const { default: fs } = await import('node:fs');
445
+ const { default: os } = await import('node:os');
446
+ const { default: path } = await import('node:path');
447
+ const tp = path.join(os.homedir(), '.olam', 'host-cp.token');
448
+ if (!fs.existsSync(tp))
449
+ return null;
450
+ const raw = fs.readFileSync(tp, 'utf-8').trim();
451
+ return raw.length > 0 ? raw : null;
452
+ }
453
+ catch {
454
+ return null;
455
+ }
456
+ }
457
+ /**
458
+ * Fetch the operator's workspace catalog from host-cp's
459
+ * GET /api/workspaces. Empty array on any failure (host-cp not
460
+ * running, network, parse) — the caller's inference will then run
461
+ * with empty catalog and degrade to a low-confidence picker rather
462
+ * than crash.
463
+ */
464
+ async function fetchHostCpWorkspaces() {
465
+ try {
466
+ const token = await readHostCpToken();
467
+ if (!token)
468
+ return [];
469
+ const res = await fetch(`${HOST_CP_URL}/api/workspaces`, {
470
+ headers: { Authorization: `Bearer ${token}` },
471
+ });
472
+ if (!res.ok)
473
+ return [];
474
+ const data = (await res.json());
475
+ const arr = Array.isArray(data) ? data : (data.workspaces ?? []);
476
+ return arr
477
+ .filter((w) => typeof w.name === 'string' && Array.isArray(w.projects))
478
+ .map((w) => ({ name: w.name, projects: w.projects ?? [] }));
479
+ }
480
+ catch {
481
+ return [];
482
+ }
483
+ }
484
+ /**
485
+ * Fetch host-cp's POST /api/workspaces/match exact-match candidates
486
+ * for a given inferred repo set. Empty array on any failure.
487
+ */
488
+ async function fetchHostCpExactMatches(projects) {
489
+ try {
490
+ const token = await readHostCpToken();
491
+ if (!token)
492
+ return [];
493
+ const res = await fetch(`${HOST_CP_URL}/api/workspaces/match`, {
494
+ method: 'POST',
495
+ headers: {
496
+ Authorization: `Bearer ${token}`,
497
+ 'Content-Type': 'application/json',
498
+ },
499
+ body: JSON.stringify({ projects }),
500
+ });
501
+ if (!res.ok)
502
+ return [];
503
+ const data = (await res.json());
504
+ return (data.matches ?? [])
505
+ .filter((w) => typeof w.name === 'string' && Array.isArray(w.projects))
506
+ .map((w) => ({ name: w.name, projects: w.projects ?? [] }));
507
+ }
508
+ catch {
509
+ return [];
510
+ }
511
+ }
512
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * olam crystallize <world> — Save a world's thoughts to Pleri Plane.
3
+ *
4
+ * Mirrors the MCP server's olam_crystallize tool.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerCrystallize(program: Command): void;
8
+ //# sourceMappingURL=crystallize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crystallize.d.ts","sourceRoot":"","sources":["../../src/commands/crystallize.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuG1D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * olam crystallize <world> — Save a world's thoughts to Pleri Plane.
3
+ *
4
+ * Mirrors the MCP server's olam_crystallize tool.
5
+ */
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ import ora from 'ora';
9
+ import { loadContext } from '../context.js';
10
+ import { printError, printInfo, printHeader } from '../output.js';
11
+ import { getWorldDbPath } from '@olam/core/src/world-paths.js';
12
+ export function registerCrystallize(program) {
13
+ program
14
+ .command('crystallize')
15
+ .description('Crystallize thoughts from a world to Pleri Plane')
16
+ .argument('<world>', 'World ID')
17
+ .action(async (worldId) => {
18
+ const { ctx, error } = await loadContext();
19
+ if (!ctx) {
20
+ printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
21
+ process.exitCode = 1;
22
+ return;
23
+ }
24
+ if (!ctx.pleriClient) {
25
+ printError('Pleri Plane is not configured. Add pleri section to .olam/config.yaml.');
26
+ process.exitCode = 1;
27
+ return;
28
+ }
29
+ const world = ctx.worldManager.getWorld(worldId);
30
+ if (!world) {
31
+ printError(`World "${worldId}" not found.`);
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ const thoughtDbPath = getWorldDbPath(world.workspacePath);
36
+ if (!fs.existsSync(thoughtDbPath)) {
37
+ printError(`No thoughts captured yet for "${worldId}". Run a dispatch first.`);
38
+ process.exitCode = 1;
39
+ return;
40
+ }
41
+ const spinner = ora('Crystallizing thoughts...').start();
42
+ try {
43
+ const { ThoughtLocalStore } = await import('@olam/core/src/thought/local-store.js');
44
+ const { computeGraphChecksum } = await import('@olam/core/src/crystallize/checksum.js');
45
+ const store = new ThoughtLocalStore(thoughtDbPath);
46
+ const nodes = store.getAllNodes();
47
+ const edges = store.getAllEdges();
48
+ store.close();
49
+ if (nodes.length === 0) {
50
+ spinner.warn('Empty thought store. Run a dispatch first.');
51
+ return;
52
+ }
53
+ const checksum = computeGraphChecksum(nodes, edges);
54
+ const result = await ctx.pleriClient.crystallize({
55
+ worldId,
56
+ sessionId: nodes[0].sessionId ?? `session-${Date.now()}`,
57
+ checksum,
58
+ nodes: nodes.map((n) => ({
59
+ id: n.id,
60
+ nodeType: n.nodeType,
61
+ summary: n.summary,
62
+ content: n.content,
63
+ sourceRef: n.sourceRef,
64
+ sequenceNum: n.sequenceNum,
65
+ createdAt: n.createdAt,
66
+ })),
67
+ edges: edges.map((e) => ({
68
+ id: e.id,
69
+ sourceId: e.sourceId,
70
+ targetId: e.targetId,
71
+ edgeType: e.edgeType,
72
+ metadata: e.metadata,
73
+ createdAt: e.createdAt,
74
+ })),
75
+ metadata: {
76
+ worldName: world.name,
77
+ branch: world.branch,
78
+ repos: world.repos,
79
+ totalNodes: nodes.length,
80
+ totalEdges: edges.length,
81
+ },
82
+ });
83
+ if (result === null) {
84
+ spinner.warn('Could not reach Pleri. Request queued for retry.');
85
+ return;
86
+ }
87
+ spinner.succeed('Crystallization complete');
88
+ printHeader('Crystal');
89
+ printInfo('ID', result.crystallizationId);
90
+ printInfo('Nodes', String(result.nodeCount));
91
+ printInfo('Edges', String(result.edgeCount));
92
+ printInfo('New', String(result.isNew));
93
+ }
94
+ catch (err) {
95
+ spinner.fail('Crystallization failed');
96
+ printError(err instanceof Error ? err.message : String(err));
97
+ process.exitCode = 1;
98
+ }
99
+ });
100
+ }
101
+ //# sourceMappingURL=crystallize.js.map