@pleri/olam-cli 0.1.82 → 0.1.84

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.
@@ -4,6 +4,6 @@
4
4
  "host-cp": "sha256:ab8540c92b84b0fff082d9221b0792f0ccdfe7053143be261122b148501b0fc6",
5
5
  "mcp-auth": "sha256:e47169ad3fbc9cab216248fecbc56874343a5daab84b1f18d67529b7d415cf95",
6
6
  "$schema_version": 1,
7
- "$published_version": "0.1.82",
7
+ "$published_version": "0.1.84",
8
8
  "$registry": "ghcr.io/pleri"
9
9
  }
package/dist/index.js CHANGED
@@ -8268,6 +8268,7 @@ var init_baseline_diff = __esm({
8268
8268
  // ../core/dist/world/context-injection.js
8269
8269
  import * as fs15 from "node:fs";
8270
8270
  import * as path16 from "node:path";
8271
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
8271
8272
  function injectWorldContext(opts) {
8272
8273
  const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
8273
8274
  const claudeDir = path16.join(world.workspacePath, ".claude");
@@ -8342,82 +8343,22 @@ function injectWorldContext(opts) {
8342
8343
  sections.push("4. When done, push and the work will be available for review");
8343
8344
  sections.push("5. Your `AskUserQuestion` calls are intercepted and surfaced to the operator's host CP automatically. The operator answers in the SPA; claude resumes when keys are injected.");
8344
8345
  sections.push("");
8345
- sections.push("## Lane Orchestration");
8346
- sections.push("");
8347
- sections.push("You can create parallel work lanes via the container API at http://localhost:8080.");
8348
- sections.push("Lanes run independent Claude Code sessions in isolated git worktrees.");
8349
- sections.push("");
8350
- sections.push("### When to create lanes");
8351
- sections.push("- Task has 2+ independent scopes (different directories/modules)");
8352
- sections.push("- Work can be done simultaneously without file conflicts");
8353
- sections.push("- Estimated effort > ~30 tool calls per scope");
8354
- sections.push("");
8355
- sections.push("### When NOT to create lanes");
8356
- sections.push("- Simple tasks touching few files");
8357
- sections.push("- Sequential work where each step depends on the previous");
8358
- sections.push("- Everything is in one directory");
8359
- sections.push("");
8360
- sections.push("### Lane API (use curl from this session)");
8361
- sections.push("");
8362
- sections.push(`Create: \`curl -s -X POST -H 'Content-Type: application/json' -d '{"name":"auth-fix","task":"Fix auth bugs","scope":["src/auth/**"],"avoids":["tests/**"]}' http://localhost:8080/lanes/create\``);
8363
- sections.push("");
8364
- sections.push("List: `curl -s http://localhost:8080/lanes`");
8365
- sections.push("");
8366
- sections.push(`Dispatch to lane: \`curl -s -X POST -H 'Content-Type: application/json' -d '{"prompt":"Start by reviewing..."}' http://localhost:8080/lanes/auth-fix/dispatch\``);
8367
- sections.push("");
8368
- sections.push("Check status: `curl -s http://localhost:8080/lanes/auth-fix`");
8346
+ sections.push("## Lane Orchestration (advanced \u2014 read on demand)");
8369
8347
  sections.push("");
8370
- sections.push("Merge: `curl -s -X POST http://localhost:8080/lanes/auth-fix/merge`");
8348
+ sections.push("This world supports parallel work lanes via the container API at http://localhost:8080.");
8349
+ sections.push("Use only when the task has 2+ independent scopes that can run simultaneously.");
8371
8350
  sections.push("");
8372
- sections.push("Destroy: `curl -s -X DELETE http://localhost:8080/lanes/auth-fix`");
8351
+ sections.push("**Full lane API + workflow**: see `~/.olam/docs/lane-orchestration.md` (mounted into the world).");
8373
8352
  sections.push("");
8374
- sections.push("### Orchestration workflow");
8375
- sections.push("1. Analyze the task \u2014 identify independent work streams");
8376
- sections.push("2. Create lanes with non-overlapping scope globs");
8377
- sections.push("3. Dispatch initial prompts to each lane");
8378
- sections.push("4. **Monitor progress** \u2014 poll lane status every 30 seconds:");
8379
- sections.push(" ```bash");
8380
- sections.push(` while true; do STATUS=$(curl -s http://localhost:8080/lanes); RUNNING=$(echo "$STATUS" | jq '[.lanes[] | select(.status == "running")] | length'); echo "Running lanes: $RUNNING"; if [ "$RUNNING" = "0" ]; then echo "All lanes complete!"; break; fi; sleep 30; done`);
8381
- sections.push(" ```");
8382
- sections.push('5. **When a lane completes** (status is "completed" or no longer "running"):');
8383
- sections.push(" - Check its output: `curl -s http://localhost:8080/lanes/<name>`");
8384
- sections.push(" - If satisfactory, merge it: `curl -s -X POST http://localhost:8080/lanes/<name>/merge`");
8385
- sections.push(" - The merge automatically triggers a Codex adversarial review");
8386
- sections.push("6. **After ALL lanes are merged**:");
8387
- sections.push(" - Run tests to verify the merged result: `npm test` or equivalent");
8388
- sections.push(" - Review the combined changes: `git diff main...HEAD --stat`");
8389
- sections.push(' - Create a PR: `gh pr create --title "..." --body "..."`');
8390
- sections.push("7. Clean up lanes: `curl -s -X DELETE http://localhost:8080/lanes/<name>`");
8353
+ sections.push("## Creating PRs from inside this world");
8391
8354
  sections.push("");
8392
- sections.push("### Important: Do not just report completion \u2014 ACT on it");
8393
- sections.push("When all lanes are done, immediately start merging and creating the PR.");
8394
- sections.push("Do not wait for the user to tell you to merge. The workflow is:");
8395
- sections.push("lanes complete -> merge each -> run tests -> create PR -> report to user.");
8396
- sections.push("");
8397
- sections.push("### CRITICAL: `gh pr create` from inside an Olam world");
8398
- sections.push("");
8399
- sections.push("Calling `gh pr create` directly inside this container will HANG");
8400
- sections.push("FOREVER on a TTY confirmation prompt that you can't answer.");
8401
- sections.push("This is a known and reproduced issue.");
8402
- sections.push("");
8403
- sections.push("You MUST always invoke it through this exact pattern:");
8355
+ sections.push("`gh pr create` hangs on a TTY prompt inside the container. Always use:");
8404
8356
  sections.push("");
8405
8357
  sections.push("```bash");
8406
- sections.push("echo y | timeout 30 gh pr create \\");
8407
- sections.push(" --base main \\");
8408
- sections.push(" --head <branch> \\");
8409
- sections.push(' --title "<title>" \\');
8410
- sections.push(" --body-file /tmp/pr-body.md");
8358
+ sections.push('echo y | timeout 30 gh pr create --base main --head <branch> --title "..." --body-file /tmp/pr-body.md');
8411
8359
  sections.push("```");
8412
8360
  sections.push("");
8413
- sections.push("- `echo y |` answers the Submit confirmation up front.");
8414
- sections.push("- `timeout 30` is a hard deadline \u2014 if gh hangs anyway, the command");
8415
- sections.push(" exits non-zero and you can react instead of stalling the world.");
8416
- sections.push("- `--body-file` (not `--body`) avoids shell-escaping bugs in long bodies.");
8417
- sections.push("- Always pass `--head` and `--base` explicitly so gh has nothing to ask.");
8418
- sections.push("");
8419
- sections.push('If the command exits non-zero with an error like "no commits" or');
8420
- sections.push('"branch not found", `git push -u origin <branch>` first, then retry.');
8361
+ sections.push("**Why + full troubleshooting**: see `~/.olam/docs/gh-pr-create.md`.");
8421
8362
  sections.push("");
8422
8363
  sections.push("## Available Skills & Plugins");
8423
8364
  sections.push("");
@@ -8433,6 +8374,16 @@ function injectWorldContext(opts) {
8433
8374
  }
8434
8375
  const content = sections.join("\n");
8435
8376
  fs15.writeFileSync(path16.join(claudeDir, "CLAUDE.md"), content);
8377
+ writeOlamDocs(world.workspacePath);
8378
+ }
8379
+ function writeOlamDocs(workspacePath) {
8380
+ const docsDir = path16.join(workspacePath, ".olam", "docs");
8381
+ fs15.mkdirSync(docsDir, { recursive: true });
8382
+ for (const filename of ["lane-orchestration.md", "gh-pr-create.md"]) {
8383
+ const src = path16.join(TEMPLATES_DIR, filename);
8384
+ const dest = path16.join(docsDir, filename);
8385
+ fs15.copyFileSync(src, dest);
8386
+ }
8436
8387
  }
8437
8388
  function formatTaskSource(ctx) {
8438
8389
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -8453,9 +8404,11 @@ function hasPlanFile(world) {
8453
8404
  return false;
8454
8405
  }
8455
8406
  }
8407
+ var TEMPLATES_DIR;
8456
8408
  var init_context_injection = __esm({
8457
8409
  "../core/dist/world/context-injection.js"() {
8458
8410
  "use strict";
8411
+ TEMPLATES_DIR = fileURLToPath3(new URL("./templates", import.meta.url));
8459
8412
  }
8460
8413
  });
8461
8414
 
@@ -12269,7 +12222,7 @@ var init_session_aggregator = __esm({
12269
12222
  import * as http from "node:http";
12270
12223
  import * as fs23 from "node:fs";
12271
12224
  import * as path25 from "node:path";
12272
- import { fileURLToPath as fileURLToPath3 } from "node:url";
12225
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
12273
12226
  function jsonResponse(res, data, status = 200) {
12274
12227
  res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
12275
12228
  res.end(JSON.stringify(data));
@@ -12450,7 +12403,7 @@ function findSessionInWorld(registry, sessionId) {
12450
12403
  }
12451
12404
  function createDashboardServer(opts) {
12452
12405
  const { port, registry } = opts;
12453
- const thisDir = path25.dirname(fileURLToPath3(import.meta.url));
12406
+ const thisDir = path25.dirname(fileURLToPath4(import.meta.url));
12454
12407
  const defaultPublicDir = path25.resolve(thisDir, "../../../control-plane/public");
12455
12408
  const publicDir = opts.publicDir ?? defaultPublicDir;
12456
12409
  let hasPublicDir = fs23.existsSync(publicDir);
@@ -13805,9 +13758,9 @@ __export(install_root_exports, {
13805
13758
  });
13806
13759
  import { existsSync as existsSync23 } from "node:fs";
13807
13760
  import { dirname as dirname17, join as join28, resolve as resolve8 } from "node:path";
13808
- import { fileURLToPath as fileURLToPath4 } from "node:url";
13761
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
13809
13762
  function installRoot(metaUrl = import.meta.url) {
13810
- const here = fileURLToPath4(metaUrl);
13763
+ const here = fileURLToPath5(metaUrl);
13811
13764
  return resolve8(dirname17(here), "..");
13812
13765
  }
13813
13766
  function isDevMode(env = process.env, installRootDir = installRoot()) {
@@ -29835,6 +29835,8 @@ function formatBaselineSummary(result) {
29835
29835
  // ../core/dist/world/context-injection.js
29836
29836
  import * as fs16 from "node:fs";
29837
29837
  import * as path18 from "node:path";
29838
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
29839
+ var TEMPLATES_DIR = fileURLToPath2(new URL("./templates", import.meta.url));
29838
29840
  function injectWorldContext(opts) {
29839
29841
  const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
29840
29842
  const claudeDir = path18.join(world.workspacePath, ".claude");
@@ -29909,82 +29911,22 @@ function injectWorldContext(opts) {
29909
29911
  sections.push("4. When done, push and the work will be available for review");
29910
29912
  sections.push("5. Your `AskUserQuestion` calls are intercepted and surfaced to the operator's host CP automatically. The operator answers in the SPA; claude resumes when keys are injected.");
29911
29913
  sections.push("");
29912
- sections.push("## Lane Orchestration");
29913
- sections.push("");
29914
- sections.push("You can create parallel work lanes via the container API at http://localhost:8080.");
29915
- sections.push("Lanes run independent Claude Code sessions in isolated git worktrees.");
29916
- sections.push("");
29917
- sections.push("### When to create lanes");
29918
- sections.push("- Task has 2+ independent scopes (different directories/modules)");
29919
- sections.push("- Work can be done simultaneously without file conflicts");
29920
- sections.push("- Estimated effort > ~30 tool calls per scope");
29921
- sections.push("");
29922
- sections.push("### When NOT to create lanes");
29923
- sections.push("- Simple tasks touching few files");
29924
- sections.push("- Sequential work where each step depends on the previous");
29925
- sections.push("- Everything is in one directory");
29926
- sections.push("");
29927
- sections.push("### Lane API (use curl from this session)");
29928
- sections.push("");
29929
- sections.push(`Create: \`curl -s -X POST -H 'Content-Type: application/json' -d '{"name":"auth-fix","task":"Fix auth bugs","scope":["src/auth/**"],"avoids":["tests/**"]}' http://localhost:8080/lanes/create\``);
29930
- sections.push("");
29931
- sections.push("List: `curl -s http://localhost:8080/lanes`");
29932
- sections.push("");
29933
- sections.push(`Dispatch to lane: \`curl -s -X POST -H 'Content-Type: application/json' -d '{"prompt":"Start by reviewing..."}' http://localhost:8080/lanes/auth-fix/dispatch\``);
29914
+ sections.push("## Lane Orchestration (advanced \u2014 read on demand)");
29934
29915
  sections.push("");
29935
- sections.push("Check status: `curl -s http://localhost:8080/lanes/auth-fix`");
29916
+ sections.push("This world supports parallel work lanes via the container API at http://localhost:8080.");
29917
+ sections.push("Use only when the task has 2+ independent scopes that can run simultaneously.");
29936
29918
  sections.push("");
29937
- sections.push("Merge: `curl -s -X POST http://localhost:8080/lanes/auth-fix/merge`");
29919
+ sections.push("**Full lane API + workflow**: see `~/.olam/docs/lane-orchestration.md` (mounted into the world).");
29938
29920
  sections.push("");
29939
- sections.push("Destroy: `curl -s -X DELETE http://localhost:8080/lanes/auth-fix`");
29921
+ sections.push("## Creating PRs from inside this world");
29940
29922
  sections.push("");
29941
- sections.push("### Orchestration workflow");
29942
- sections.push("1. Analyze the task \u2014 identify independent work streams");
29943
- sections.push("2. Create lanes with non-overlapping scope globs");
29944
- sections.push("3. Dispatch initial prompts to each lane");
29945
- sections.push("4. **Monitor progress** \u2014 poll lane status every 30 seconds:");
29946
- sections.push(" ```bash");
29947
- sections.push(` while true; do STATUS=$(curl -s http://localhost:8080/lanes); RUNNING=$(echo "$STATUS" | jq '[.lanes[] | select(.status == "running")] | length'); echo "Running lanes: $RUNNING"; if [ "$RUNNING" = "0" ]; then echo "All lanes complete!"; break; fi; sleep 30; done`);
29948
- sections.push(" ```");
29949
- sections.push('5. **When a lane completes** (status is "completed" or no longer "running"):');
29950
- sections.push(" - Check its output: `curl -s http://localhost:8080/lanes/<name>`");
29951
- sections.push(" - If satisfactory, merge it: `curl -s -X POST http://localhost:8080/lanes/<name>/merge`");
29952
- sections.push(" - The merge automatically triggers a Codex adversarial review");
29953
- sections.push("6. **After ALL lanes are merged**:");
29954
- sections.push(" - Run tests to verify the merged result: `npm test` or equivalent");
29955
- sections.push(" - Review the combined changes: `git diff main...HEAD --stat`");
29956
- sections.push(' - Create a PR: `gh pr create --title "..." --body "..."`');
29957
- sections.push("7. Clean up lanes: `curl -s -X DELETE http://localhost:8080/lanes/<name>`");
29958
- sections.push("");
29959
- sections.push("### Important: Do not just report completion \u2014 ACT on it");
29960
- sections.push("When all lanes are done, immediately start merging and creating the PR.");
29961
- sections.push("Do not wait for the user to tell you to merge. The workflow is:");
29962
- sections.push("lanes complete -> merge each -> run tests -> create PR -> report to user.");
29963
- sections.push("");
29964
- sections.push("### CRITICAL: `gh pr create` from inside an Olam world");
29965
- sections.push("");
29966
- sections.push("Calling `gh pr create` directly inside this container will HANG");
29967
- sections.push("FOREVER on a TTY confirmation prompt that you can't answer.");
29968
- sections.push("This is a known and reproduced issue.");
29969
- sections.push("");
29970
- sections.push("You MUST always invoke it through this exact pattern:");
29923
+ sections.push("`gh pr create` hangs on a TTY prompt inside the container. Always use:");
29971
29924
  sections.push("");
29972
29925
  sections.push("```bash");
29973
- sections.push("echo y | timeout 30 gh pr create \\");
29974
- sections.push(" --base main \\");
29975
- sections.push(" --head <branch> \\");
29976
- sections.push(' --title "<title>" \\');
29977
- sections.push(" --body-file /tmp/pr-body.md");
29926
+ sections.push('echo y | timeout 30 gh pr create --base main --head <branch> --title "..." --body-file /tmp/pr-body.md');
29978
29927
  sections.push("```");
29979
29928
  sections.push("");
29980
- sections.push("- `echo y |` answers the Submit confirmation up front.");
29981
- sections.push("- `timeout 30` is a hard deadline \u2014 if gh hangs anyway, the command");
29982
- sections.push(" exits non-zero and you can react instead of stalling the world.");
29983
- sections.push("- `--body-file` (not `--body`) avoids shell-escaping bugs in long bodies.");
29984
- sections.push("- Always pass `--head` and `--base` explicitly so gh has nothing to ask.");
29985
- sections.push("");
29986
- sections.push('If the command exits non-zero with an error like "no commits" or');
29987
- sections.push('"branch not found", `git push -u origin <branch>` first, then retry.');
29929
+ sections.push("**Why + full troubleshooting**: see `~/.olam/docs/gh-pr-create.md`.");
29988
29930
  sections.push("");
29989
29931
  sections.push("## Available Skills & Plugins");
29990
29932
  sections.push("");
@@ -30000,6 +29942,16 @@ function injectWorldContext(opts) {
30000
29942
  }
30001
29943
  const content = sections.join("\n");
30002
29944
  fs16.writeFileSync(path18.join(claudeDir, "CLAUDE.md"), content);
29945
+ writeOlamDocs(world.workspacePath);
29946
+ }
29947
+ function writeOlamDocs(workspacePath) {
29948
+ const docsDir = path18.join(workspacePath, ".olam", "docs");
29949
+ fs16.mkdirSync(docsDir, { recursive: true });
29950
+ for (const filename of ["lane-orchestration.md", "gh-pr-create.md"]) {
29951
+ const src = path18.join(TEMPLATES_DIR, filename);
29952
+ const dest = path18.join(docsDir, filename);
29953
+ fs16.copyFileSync(src, dest);
29954
+ }
30003
29955
  }
30004
29956
  function formatTaskSource(ctx) {
30005
29957
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -32669,7 +32621,7 @@ import * as http2 from "node:http";
32669
32621
  import * as http from "node:http";
32670
32622
  import * as fs22 from "node:fs";
32671
32623
  import * as path25 from "node:path";
32672
- import { fileURLToPath as fileURLToPath2 } from "node:url";
32624
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
32673
32625
 
32674
32626
  // ../core/dist/dashboard/serialize.js
32675
32627
  function serializeTokenUsage(usage) {
@@ -33174,7 +33126,7 @@ function findSessionInWorld(registry2, sessionId) {
33174
33126
  }
33175
33127
  function createDashboardServer(opts) {
33176
33128
  const { port, registry: registry2 } = opts;
33177
- const thisDir = path25.dirname(fileURLToPath2(import.meta.url));
33129
+ const thisDir = path25.dirname(fileURLToPath3(import.meta.url));
33178
33130
  const defaultPublicDir = path25.resolve(thisDir, "../../../control-plane/public");
33179
33131
  const publicDir = opts.publicDir ?? defaultPublicDir;
33180
33132
  let hasPublicDir = fs22.existsSync(publicDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.82",
3
+ "version": "0.1.84",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"