@outerlayer/cli 0.17.0 → 0.18.0

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 (144) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +15 -0
  3. package/dist/agent-setup-RBTEACYU.js +28 -0
  4. package/dist/{artifact-link-cmd-2F47LT7F.js → artifact-link-cmd-AVM2EKTV.js} +4 -3
  5. package/dist/{build-BG2YENGK.js → build-TQ6X5PYN.js} +5 -4
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-2D3WSOOY.js → builder-DUI2ZH2H.js} +5 -6
  8. package/dist/{check-5XE7XMC4.js → check-5C4YDZYV.js} +53 -50
  9. package/dist/{chunk-R7PF5OOU.js → chunk-3CWUOFV6.js} +21 -14
  10. package/dist/{chunk-G5NPRL2K.js → chunk-3OFZM4X6.js} +548 -68
  11. package/dist/{chunk-2MNPHL23.js → chunk-47TTLEDX.js} +6 -5
  12. package/dist/{chunk-PLMTLGYH.js → chunk-52NC2FIU.js} +4 -3
  13. package/dist/chunk-6CHIYEZZ.js +564 -0
  14. package/dist/{chunk-TI7B7UEO.js → chunk-AMFWYESY.js} +1 -1
  15. package/dist/{chunk-YRYMNBGQ.js → chunk-ANPNT6PM.js} +2 -1
  16. package/dist/{chunk-YU3VKZ5F.js → chunk-B3UKB46N.js} +6 -6
  17. package/dist/{chunk-JXYVA45C.js → chunk-BMYGAGBJ.js} +1050 -304
  18. package/dist/{chunk-4Q7OMKAT.js → chunk-BQXFBI7T.js} +81 -5
  19. package/dist/chunk-CRB3POP4.js +34 -0
  20. package/dist/{chunk-F47JBIAW.js → chunk-DSF2FWAZ.js} +2 -1
  21. package/dist/{chunk-N5FOE5PS.js → chunk-ECODQ7II.js} +4 -33
  22. package/dist/{chunk-NBGDBTO2.js → chunk-ESC6UR76.js} +6 -5
  23. package/dist/{chunk-HHJDN6AU.js → chunk-ESVW4MJY.js} +1 -1
  24. package/dist/{chunk-42ZI52JW.js → chunk-F4XSVQJ4.js} +4 -3
  25. package/dist/{chunk-LWSJQJC6.js → chunk-FUB7LRUE.js} +7 -7
  26. package/dist/chunk-G2YNJIGF.js +44 -0
  27. package/dist/{chunk-QKFB4K7X.js → chunk-GGOMT6KF.js} +1 -1
  28. package/dist/{chunk-VQYBXPI7.js → chunk-GOBOJMOJ.js} +5 -5
  29. package/dist/{chunk-N6LURUEF.js → chunk-GOSFARMS.js} +1 -1
  30. package/dist/chunk-JBJTC3UU.js +35 -0
  31. package/dist/{chunk-NWQTTSBB.js → chunk-JF42URPU.js} +16 -15
  32. package/dist/{chunk-ADJRGVZC.js → chunk-KDVIU23F.js} +1 -1
  33. package/dist/{chunk-S3NYLI2P.js → chunk-KK4VBOH6.js} +93 -37
  34. package/dist/{chunk-KMDLFI4P.js → chunk-L2USZT6T.js} +1 -1
  35. package/dist/{chunk-WTE3MQML.js → chunk-LXAY4A2G.js} +3 -12
  36. package/dist/{chunk-V7NIVOFD.js → chunk-M2ZWWTWZ.js} +1 -1
  37. package/dist/{chunk-ERI5GBNI.js → chunk-MLAAT4S6.js} +3 -3
  38. package/dist/{chunk-POJMEEJJ.js → chunk-MNTSH4CL.js} +1 -1
  39. package/dist/{chunk-WUYTWNMA.js → chunk-MQJSXHV7.js} +1 -1
  40. package/dist/{chunk-O765JR4W.js → chunk-MTP2QEVO.js} +1 -1
  41. package/dist/{chunk-ZM2IMMYN.js → chunk-N2PXGQRL.js} +9 -1
  42. package/dist/{chunk-J5M7BSJQ.js → chunk-N3CUDFCW.js} +9 -3
  43. package/dist/{chunk-4KSQKQXE.js → chunk-NACDBXUG.js} +19 -15
  44. package/dist/{chunk-ONKJUM6R.js → chunk-NL4XPC7W.js} +1 -1
  45. package/dist/{chunk-WVUIRTWA.js → chunk-QQM2UJ6T.js} +31 -26
  46. package/dist/{chunk-KG5ECZGJ.js → chunk-RAZTWYZN.js} +10 -9
  47. package/dist/{chunk-4NPZVMJU.js → chunk-S26M3YBJ.js} +60 -4
  48. package/dist/{chunk-UGP76IZ5.js → chunk-S5PCA3SN.js} +1 -1
  49. package/dist/{chunk-3NSNIIBE.js → chunk-S76AYB4M.js} +17 -16
  50. package/dist/{chunk-RMWLBUCJ.js → chunk-SADUQSO4.js} +1 -1
  51. package/dist/{chunk-OZGHL5Y5.js → chunk-SWCTGCSC.js} +2 -2
  52. package/dist/{chunk-GQD22KKN.js → chunk-T2Q7ISPE.js} +2 -1
  53. package/dist/{chunk-C5Y5ZJJZ.js → chunk-T4Y6SCG3.js} +5 -4
  54. package/dist/{chunk-BWQ66M6N.js → chunk-ULSIJGLS.js} +45 -13
  55. package/dist/{chunk-NNRTPG7X.js → chunk-UYOYTKE2.js} +4 -4
  56. package/dist/{chunk-PTW6W5NR.js → chunk-VYAL7PUE.js} +1 -1
  57. package/dist/{chunk-YZ5F4PIS.js → chunk-W5VPCONO.js} +146 -247
  58. package/dist/{chunk-6Y5RUTHO.js → chunk-WBT5X3NH.js} +5 -4
  59. package/dist/{chunk-RLYZLUQ7.js → chunk-WGAUY5LE.js} +2 -2
  60. package/dist/{chunk-RSNSZ2LJ.js → chunk-X5H2WYMB.js} +1 -1
  61. package/dist/{chunk-OHVJA253.js → chunk-X5N6KC6V.js} +47 -29
  62. package/dist/{chunk-22RMZBGW.js → chunk-XGP3VYOG.js} +1 -1
  63. package/dist/{chunk-HYZRY4KZ.js → chunk-XNGMQ27R.js} +16 -6
  64. package/dist/{chunk-HGECYFEI.js → chunk-Y5GE76XC.js} +131 -54
  65. package/dist/{chunk-MAK5LYRF.js → chunk-Y5MXET4M.js} +277 -535
  66. package/dist/{chunk-XCK2YAY5.js → chunk-YVZJ6GKF.js} +3 -2
  67. package/dist/{chunk-YO4PSLVB.js → chunk-ZRL6HKBY.js} +1 -1
  68. package/dist/claude-launcher-YVXI76NX.js +102 -0
  69. package/dist/{cli-A76AXELQ.js → cli-C77H54BV.js} +468 -161
  70. package/dist/{command-R2QCVX55.js → command-H5CILO4S.js} +40 -37
  71. package/dist/{config-N3C6DFQA.js → config-FXDG4NPJ.js} +2 -3
  72. package/dist/{connect-cmd-JBKAQNSF.js → connect-cmd-ZW5FV3ZW.js} +9 -8
  73. package/dist/{context-adopt-NFHCLVUB.js → context-adopt-O5OFXMKI.js} +13 -12
  74. package/dist/context-materialize-Y5IJ4MQT.js +23 -0
  75. package/dist/{dist-LKDWQWZ7.js → dist-QTX4RSCL.js} +2 -2
  76. package/dist/{docker-4J77Q2BF.js → docker-RC3PRX3Q.js} +7 -8
  77. package/dist/{doctor-4TAIARIG.js → doctor-2NQQML6P.js} +46 -39
  78. package/dist/{emit-artifact-cmd-MPZVR56N.js → emit-artifact-cmd-7MP63KXU.js} +25 -22
  79. package/dist/emit-cmd-PPN4QQF2.js +14 -0
  80. package/dist/{emit-criteria-cmd-EFGYI23V.js → emit-criteria-cmd-3RXPDLNK.js} +16 -14
  81. package/dist/{emit-finding-cmd-5GF3V4LR.js → emit-finding-cmd-OL7JB6H3.js} +18 -16
  82. package/dist/{emit-result-cmd-I4OADKMD.js → emit-result-cmd-UZVMOCF4.js} +20 -17
  83. package/dist/{exec-client-CQV746UF.js → exec-client-7UMESIE2.js} +3 -4
  84. package/dist/governing-source-BUU4IABS.js +35 -0
  85. package/dist/guest-init-KPBQOFE5.js +9 -0
  86. package/dist/{hook-fast-R4FVSZ2H.js → hook-fast-W5MKHMJT.js} +4 -1
  87. package/dist/host-key-U4B5QETR.js +8 -0
  88. package/dist/{import-capture-cmd-EQ35EARA.js → import-capture-cmd-ZO6KGHI2.js} +7 -5
  89. package/dist/{import-ruler-cmd-BGAZXCQM.js → import-ruler-cmd-KJMWL5V6.js} +5 -3
  90. package/dist/index.js +8 -4
  91. package/dist/init-VWXIZEAN.js +54 -0
  92. package/dist/{init-PWU5YVL7.js → init-WNXXYMO7.js} +38 -35
  93. package/dist/{init-cmd-XAVO7HYZ.js → init-cmd-WS6TIRYT.js} +28 -24
  94. package/dist/{init-update-CVCWD6VS.js → init-update-E3J6TVIN.js} +27 -26
  95. package/dist/{install-HDBIPHTX.js → install-CBWIEF3R.js} +4 -5
  96. package/dist/{install-cmd-5HYMXLEW.js → install-cmd-QDOTR4OM.js} +5 -4
  97. package/dist/{login-browser-QZCS3WW6.js → login-browser-O63QZN7D.js} +4 -3
  98. package/dist/{logout-cmd-QAUFDJ6J.js → logout-cmd-5V5MMBSY.js} +3 -2
  99. package/dist/{logs-H55NWW4H.js → logs-AMLKC3VP.js} +3 -1
  100. package/dist/loop-UGI2BJOT.js +76 -0
  101. package/dist/machine-JOW4RNZ7.js +49 -0
  102. package/dist/{mcp-install-cmd-FDTPQQS6.js → mcp-install-cmd-GGWB3JJ2.js} +3 -2
  103. package/dist/{mcp-serve-cmd-3KVYEUXG.js → mcp-serve-cmd-DOTY5FKY.js} +10 -8
  104. package/dist/paths-7XP63OAX.js +7 -0
  105. package/dist/pending-532ABZYC.js +8 -0
  106. package/dist/{pidfile-UZRH774M.js → pidfile-3DM4OBKO.js} +4 -2
  107. package/dist/{record-C43U4PKS.js → record-3WP6V2K5.js} +3 -2
  108. package/dist/{runner-env-EN7YE7QX.js → runner-env-4NB2GA7O.js} +5 -6
  109. package/dist/{runner-key-6SLBI7PP.js → runner-key-TC3NFWFV.js} +38 -35
  110. package/dist/{session-sender-FO3LCREV.js → session-sender-NNVPSPY7.js} +17 -14
  111. package/dist/spec-cmd-OWVTBB4J.js +116 -0
  112. package/dist/{starter-pack-KF66HGZR.js → starter-pack-OPWUDOWX.js} +7 -5
  113. package/dist/{status-7VNQN5PW.js → status-TKCLLKFG.js} +42 -39
  114. package/dist/{statusline-fast-SVTMBMD7.js → statusline-fast-KN3BX67H.js} +2 -1
  115. package/dist/{sync-cmd-GVPPFZ3G.js → sync-cmd-Q6VYNPWG.js} +16 -13
  116. package/dist/{watch-23HSAEI6.js → watch-ARAGADTF.js} +16 -13
  117. package/dist/{work-claim-cmd-LKL3GHFQ.js → work-claim-cmd-34FERLYX.js} +25 -27
  118. package/dist/work-cmd-7S5B2H2P.js +25 -0
  119. package/dist/{work-comment-cmd-AWHP56M2.js → work-comment-cmd-SZJSPM5S.js} +15 -13
  120. package/dist/{work-launch-R5HTAP6X.js → work-launch-LEQ2MPM3.js} +3 -1
  121. package/dist/{work-open-pr-cmd-IOM4AVQQ.js → work-open-pr-cmd-RPXKCBWS.js} +17 -15
  122. package/dist/work-pr-cmd-5LGANL32.js +26 -0
  123. package/package.json +3 -2
  124. package/skill-pack/maintained/outerlayer-amend/SKILL.md +4 -2
  125. package/skill-pack/shipped.json +17 -2
  126. package/skill-pack/template/build/SKILL.md +23 -10
  127. package/skill-pack/template/build/references/agent-briefs.md +3 -1
  128. package/skill-pack/template/build/references/criteria-judge.md +27 -0
  129. package/skill-pack/template/build/references/release.md +19 -28
  130. package/skill-pack/template/spec/SKILL.md +35 -10
  131. package/skill-pack/validators/acceptance-criteria.yaml +25 -26
  132. package/dist/agent-setup-T624CWPD.js +0 -27
  133. package/dist/chunk-BYT5O5RV.js +0 -61
  134. package/dist/context-materialize-IV2TUUFO.js +0 -22
  135. package/dist/emit-cmd-IJ3GVRFD.js +0 -12
  136. package/dist/guest-init-LJP5GPZF.js +0 -9
  137. package/dist/host-key-YMLXY6QB.js +0 -7
  138. package/dist/init-6XPDRDTC.js +0 -51
  139. package/dist/loop-FK3LPMMZ.js +0 -73
  140. package/dist/machine-SQXEBAM2.js +0 -46
  141. package/dist/paths-OYKMVYJP.js +0 -6
  142. package/dist/pending-MXLSRYMO.js +0 -7
  143. package/dist/work-cmd-Z2WXLZPH.js +0 -23
  144. package/dist/work-pr-cmd-HNEUIEN7.js +0 -24
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { authorEnvironment, withHooksPath } from './chunk-BYT5O5RV.js';
4
3
  import { existsSync, unlinkSync, chmodSync } from 'fs';
5
4
  import { request as request$1, createServer } from 'http';
6
5
  import { request } from 'https';
@@ -345,6 +344,61 @@ async function startBuildServices(input) {
345
344
  }
346
345
  }
347
346
 
347
+ // src/runner/commit-identity.ts
348
+ var NOREPLY_SUFFIX = "@users.noreply.github.com";
349
+ var MAX_LENGTH = 200;
350
+ function parseIdentity(value) {
351
+ if (typeof value !== "object" || value === null) return void 0;
352
+ const { name, email } = value;
353
+ if (typeof name !== "string" || typeof email !== "string") return void 0;
354
+ if (name.trim() === "" || name.length > MAX_LENGTH || /[\r\n\0<>]/.test(name)) return void 0;
355
+ if (email.length > MAX_LENGTH || !email.endsWith(NOREPLY_SUFFIX) || /[\s\0<>]/.test(email) || email.length === NOREPLY_SUFFIX.length) return void 0;
356
+ return { name, email };
357
+ }
358
+ function parseClaimIdentity(data) {
359
+ const author = parseIdentity(data.commitAuthor);
360
+ if (author === void 0) return void 0;
361
+ const coAuthor = parseIdentity(data.coAuthor);
362
+ return coAuthor === void 0 ? { author } : { author, coAuthor };
363
+ }
364
+ function authorEnvironment(identity) {
365
+ if (identity === void 0) return {};
366
+ return {
367
+ GIT_AUTHOR_NAME: identity.name,
368
+ GIT_AUTHOR_EMAIL: identity.email,
369
+ GIT_COMMITTER_NAME: identity.name,
370
+ GIT_COMMITTER_EMAIL: identity.email
371
+ };
372
+ }
373
+ function configCount(env) {
374
+ const raw = String(env.GIT_CONFIG_COUNT);
375
+ return /^[0-9]+$/.test(raw) ? Number(raw) : 0;
376
+ }
377
+ function withGitConfig(env, key, value) {
378
+ const at = configCount(env);
379
+ return {
380
+ ...env,
381
+ GIT_CONFIG_COUNT: String(at + 1),
382
+ [`GIT_CONFIG_KEY_${at}`]: key,
383
+ [`GIT_CONFIG_VALUE_${at}`]: value
384
+ };
385
+ }
386
+ function tokenHeader(token) {
387
+ return `Authorization: Basic ${Buffer.from(`x-access-token:${token}`).toString("base64")}`;
388
+ }
389
+ function withTokenHeader(env, url, token) {
390
+ return withGitConfig(env, `http.${url}.extraHeader`, tokenHeader(token));
391
+ }
392
+ function withHooksPath(env, dir) {
393
+ return withGitConfig(env, "core.hooksPath", dir);
394
+ }
395
+ function commitIdentityRecord(identity) {
396
+ return {
397
+ author: identity === void 0 ? "host" : "app",
398
+ coAuthor: identity?.coAuthor !== void 0 && identity.hooksPath !== void 0 ? "credited" : "none"
399
+ };
400
+ }
401
+
348
402
  // src/runner/repositories.ts
349
403
  function parseClaimedRepositories(value) {
350
404
  if (!Array.isArray(value) || value.length === 0) return void 0;
@@ -372,10 +426,19 @@ function primaryOf(repositories) {
372
426
  var RELAY_PORT = 3128;
373
427
  var JOB_MOUNT = "/outerlayer/job";
374
428
  var EVAL_INPUT_DIR = `${JOB_MOUNT}/eval-input`;
429
+ var BUILD_HOME = "/build/home";
375
430
  var CHECKOUT_DIR = "/build/work/checkout";
376
431
  var REPOS_DIR = "/build/work/repos";
377
432
  function checkoutPath(entry) {
378
- return entry.primary ? CHECKOUT_DIR : `${REPOS_DIR}/${entry.repository}`;
433
+ return entry.primary ? CHECKOUT_DIR : repositoryPath(entry.repository);
434
+ }
435
+ function repositoryPath(repository) {
436
+ return `${REPOS_DIR}/${repository.toLowerCase()}`;
437
+ }
438
+ function lifecycleWorkdir(repositories, governingRepository) {
439
+ const governing = governingRepository?.toLowerCase();
440
+ const entry = governing === void 0 ? void 0 : repositories.find((candidate) => candidate.repository.toLowerCase() === governing);
441
+ return entry === void 0 ? CHECKOUT_DIR : checkoutPath(entry);
379
442
  }
380
443
  var MAX_HOSTS = 200;
381
444
  function tokenVariables() {
@@ -404,10 +467,16 @@ function proxyEnvironment(proxyUrl, alsoNoProxy) {
404
467
  YARN_HTTP_PROXY: proxyUrl
405
468
  };
406
469
  }
470
+ var PROXY_WARNING_FLAG = "--disable-warning=UNDICI-EHPA";
471
+ function withProxyWarningHidden(options) {
472
+ const given = options?.trim() ?? "";
473
+ if (given.split(/\s+/).includes(PROXY_WARNING_FLAG)) return given;
474
+ return given === "" ? PROXY_WARNING_FLAG : `${given} ${PROXY_WARNING_FLAG}`;
475
+ }
407
476
  function runnerLiterals(repository, repositories = []) {
408
477
  return {
409
478
  OUTERLAYER_JOB_DIR: JOB_MOUNT,
410
- HOME: "/build/home",
479
+ HOME: BUILD_HOME,
411
480
  TMPDIR: "/tmp",
412
481
  ...proxyEnvironment(PROXY_URL),
413
482
  GIT_TERMINAL_PROMPT: "0",
@@ -466,6 +535,11 @@ function buildEnvironment(input) {
466
535
  passed[name] = value;
467
536
  variables.push(name);
468
537
  }
538
+ const nodeOptions = {};
539
+ if (input.imageEnv !== void 0) {
540
+ if (passed.NODE_OPTIONS !== void 0) passed.NODE_OPTIONS = withProxyWarningHidden(passed.NODE_OPTIONS);
541
+ else nodeOptions.NODE_OPTIONS = withProxyWarningHidden(recipe.NODE_OPTIONS ?? input.imageEnv.NODE_OPTIONS);
542
+ }
469
543
  const destinations = destinationEnvironment(input.config.build?.destinations, containerLocalAddress);
470
544
  const builtInLiterals = builtIns ? builtInEnvironment(containerBuiltInAddress, claudeCredential(input.hostEnv)) : {};
471
545
  const hooksPath = input.identity?.hooksPath;
@@ -483,6 +557,7 @@ function buildEnvironment(input) {
483
557
  return {
484
558
  literals: {
485
559
  ...recipe,
560
+ ...nodeOptions,
486
561
  ...destinations,
487
562
  ...runnerLiterals(input.repository, repositoriesOf({ repositories: input.repositories, repository: input.repository, branch: input.branch })),
488
563
  ...builtInLiterals,
@@ -502,7 +577,8 @@ function checkEnvironment(input) {
502
577
  repository: input.repository,
503
578
  hostEnv: input.hostEnv,
504
579
  containerEnv: input.containerEnv,
505
- builtIns: false
580
+ builtIns: false,
581
+ imageEnv: input.imageEnv
506
582
  });
507
583
  const withheld = /* @__PURE__ */ new Set(["OUTERLAYER_URL", "OUTERLAYER_API_KEY", ...CLAUDE_CREDENTIAL_VARIABLES]);
508
584
  const literals = { OUTERLAYER_EVAL_INPUT: EVAL_INPUT_DIR };
@@ -544,4 +620,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
544
620
  };
545
621
  }
546
622
 
547
- export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseClaimedRepositories, parseIsolation, primaryOf, proxyEnvironment, repositoriesOf, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
623
+ export { AGENT_CREDENTIAL_MISSING, BUILD_HOME, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, authorEnvironment, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, commitIdentityRecord, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, lifecycleWorkdir, parseClaimIdentity, parseClaimedRepositories, parseIsolation, primaryOf, proxyEnvironment, repositoriesOf, repositoryPath, resolveDestinations, sharedUserEnvironment, startBuildServices, tokenHeader, withGitConfig, withHooksPath, withProxyWarningHidden, withTokenHeader, withTunnelRecord };
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { homeFromEnv } from './chunk-VNVZDWO3.js';
4
+ import { join, sep } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ createRequire(import.meta.url);
8
+ var CLI_PACKAGE = "@outerlayer/cli";
9
+ function packageRunnerOf(bin) {
10
+ for (const part of bin.replace(/\\/g, "/").split("/")) {
11
+ if (part === "_npx") return "npx";
12
+ if (part === "dlx") return "pnpm dlx";
13
+ if (part.startsWith("dlx-")) return "yarn dlx";
14
+ if (part.startsWith("bunx-")) return "bunx";
15
+ }
16
+ return void 0;
17
+ }
18
+ function runningModule() {
19
+ try {
20
+ return fileURLToPath(import.meta.url);
21
+ } catch {
22
+ return "";
23
+ }
24
+ }
25
+ function cliInvocation(opts = {}) {
26
+ const bin = opts.bin ?? runningModule();
27
+ const runner = packageRunnerOf(bin);
28
+ if (runner !== void 0) return `${runner} ${CLI_PACKAGE}`;
29
+ const installedCopy = join(opts.home ?? homeFromEnv(), ".outerlayer", "cli") + sep;
30
+ if (bin.startsWith(installedCopy)) return `npx ${CLI_PACKAGE}`;
31
+ return "outerlayer";
32
+ }
33
+
34
+ export { cliInvocation, packageRunnerOf };
@@ -2,6 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { recordReportedCost } from './chunk-BKO6JEZI.js';
4
4
  import { decodeWrappedCommand } from './chunk-5QRP3MVS.js';
5
+ import { cliInvocation } from './chunk-CRB3POP4.js';
5
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
6
7
  import { readFileSync } from 'fs';
7
8
  import { spawn } from 'child_process';
@@ -69,7 +70,7 @@ function renderStatusline(stdin, state, now) {
69
70
  segments.push(`${state.unsynced} unsynced`);
70
71
  }
71
72
  if (!fresh) {
72
- segments.push(dim("outerlayer doctor"));
73
+ segments.push(dim(`${cliInvocation()} doctor`));
73
74
  }
74
75
  const prefix = "\u2B22 OL";
75
76
  return segments.length === 0 ? prefix : `${prefix} ${segments.join(dim(" \xB7 "))}`;
@@ -1,40 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
4
- import { readFileSync, existsSync, rmSync, mkdirSync, writeFileSync } from 'fs';
3
+ import { isSameProcess } from './chunk-JBJTC3UU.js';
4
+ import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
5
+ import { existsSync, readFileSync, rmSync, mkdirSync, writeFileSync } from 'fs';
5
6
  import { dirname } from 'path';
6
- import { execFileSync } from 'child_process';
7
7
 
8
8
  createRequire(import.meta.url);
9
- function startTimeOf(pid) {
10
- if (process.platform === "linux") return startTimeOfLinux(pid);
11
- return startTimeOfPs(pid);
12
- }
13
- function startTimeOfLinux(pid) {
14
- try {
15
- const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
16
- const afterComm = stat.slice(stat.lastIndexOf(")") + 1).trim();
17
- const fields = afterComm.split(/\s+/);
18
- if (fields[0] === "Z" || fields[0] === "X") return null;
19
- const starttime = fields[19];
20
- return starttime ?? null;
21
- } catch {
22
- return null;
23
- }
24
- }
25
- function startTimeOfPs(pid) {
26
- try {
27
- const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], { encoding: "utf8" }).trim();
28
- return out.length > 0 ? out : null;
29
- } catch {
30
- return null;
31
- }
32
- }
33
- function isSameProcess(pid, start) {
34
- return startTimeOf(pid) === start;
35
- }
36
-
37
- // src/runner/pidfile.ts
38
9
  function readPidFile(path) {
39
10
  if (!existsSync(path)) return null;
40
11
  try {
@@ -68,4 +39,4 @@ function claimPidFile(path, self, isSameProcessFn = isSameProcess) {
68
39
  writePidFile(path, self);
69
40
  }
70
41
 
71
- export { RunnerAlreadyRunningError, claimPidFile, isSameProcess, readPidFile, releasePidFile, startTimeOf };
42
+ export { RunnerAlreadyRunningError, claimPidFile, readPidFile, releasePidFile };
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { mcpTargetPath, INIT_STDIO_ENTRY, INIT_DOCS_ENTRY, DOCS_MCP_SERVER_NAME } from './chunk-XCK2YAY5.js';
4
- import { POLICY_CONTENT, VALIDATOR_FILES, VALIDATORS_DIR, POLICY_PATH } from './chunk-42ZI52JW.js';
5
- import { pinExists, readContextManifest } from './chunk-WTE3MQML.js';
6
- import { resolvePackRoot, loadTemplateFiles, skillDir } from './chunk-POJMEEJJ.js';
3
+ import { mcpTargetPath, INIT_STDIO_ENTRY, INIT_DOCS_ENTRY, DOCS_MCP_SERVER_NAME } from './chunk-YVZJ6GKF.js';
4
+ import { POLICY_CONTENT, VALIDATOR_FILES, VALIDATORS_DIR, POLICY_PATH } from './chunk-F4XSVQJ4.js';
5
+ import { pinExists, readContextManifest } from './chunk-LXAY4A2G.js';
6
+ import { resolvePackRoot, loadTemplateFiles, skillDir } from './chunk-MNTSH4CL.js';
7
7
  import { findGitDirs } from './chunk-BJ3KTMDH.js';
8
+ import { cliInvocation } from './chunk-CRB3POP4.js';
8
9
  import { createHash } from 'crypto';
9
10
  import { existsSync, readFileSync } from 'fs';
10
11
  import { join } from 'path';
@@ -109,7 +110,7 @@ function contextIsGoverned(root, gitCommonDir) {
109
110
  return pinExists(root) || readContextManifest(gitCommonDir) !== void 0;
110
111
  }
111
112
  var NAME = "Starter files";
112
- var UPDATE = "outerlayer init --update";
113
+ var UPDATE = `${cliInvocation()} init --update`;
113
114
  function shownPaths(items, all) {
114
115
  const shown = [];
115
116
  const whole = /* @__PURE__ */ new Set();
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { readLaunchSpoolState, launchesPath } from './chunk-GQD22KKN.js';
3
+ import { readLaunchSpoolState, launchesPath } from './chunk-T2Q7ISPE.js';
4
4
 
5
5
  createRequire(import.meta.url);
6
6
 
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { C } from './chunk-YRYMNBGQ.js';
4
- import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-POJMEEJJ.js';
3
+ import { C } from './chunk-ANPNT6PM.js';
4
+ import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-MNTSH4CL.js';
5
5
  import { resolvePackageVersion } from './chunk-RA3O54FC.js';
6
+ import { cliInvocation } from './chunk-CRB3POP4.js';
6
7
  import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
7
8
  import { join, dirname } from 'path';
8
9
 
@@ -98,7 +99,7 @@ function formatStarterPackOutput(result) {
98
99
  ...result.validatorsKept.map((path) => `${C.dim}${path} already exists \u2014 left as it is${C.reset}`),
99
100
  "",
100
101
  `Next: create .outerlayer/config.json naming your agent tools, for example {"targets": ["claude-code"]},`,
101
- `then run ${C.yellow}outerlayer context emit${C.reset} to compile the skills into their native files.`
102
+ `then run ${C.yellow}${cliInvocation()} context emit${C.reset} to compile the skills into their native files.`
102
103
  );
103
104
  return lines.join("\n") + "\n";
104
105
  }
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isPlaceholderCommand } from './chunk-VQYBXPI7.js';
4
- import { describeCallFailure } from './chunk-MAK5LYRF.js';
5
- import { WorkCommandError, getJson } from './chunk-S3NYLI2P.js';
6
- import { builtinKind } from './chunk-22RMZBGW.js';
7
- import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-4Q7OMKAT.js';
8
- import { sanitizeTerminal } from './chunk-WUYTWNMA.js';
9
- import { signerFor } from './chunk-V7NIVOFD.js';
3
+ import { isPlaceholderCommand } from './chunk-GOBOJMOJ.js';
4
+ import { describeCallFailure } from './chunk-6CHIYEZZ.js';
5
+ import { WorkCommandError, getJson } from './chunk-KK4VBOH6.js';
6
+ import { sanitizeTerminal } from './chunk-MQJSXHV7.js';
7
+ import { builtinKind } from './chunk-XGP3VYOG.js';
8
+ import { signerFor } from './chunk-M2ZWWTWZ.js';
9
+ import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-BQXFBI7T.js';
10
10
 
11
11
  createRequire(import.meta.url);
12
12
 
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+
4
+ createRequire(import.meta.url);
5
+
6
+ // src/control-plane-paths.ts
7
+ var CONTROL_PLANE_DIR_VARIABLE = "OUTERLAYER_CONTROL_PLANE_DIR";
8
+ var PROJECT_DIR_SPELLINGS = [
9
+ /"\$\{?CLAUDE_PROJECT_DIR\}?"\/\.claude(?![\w.-])/g,
10
+ /\$\{CLAUDE_PROJECT_DIR\}\/\.claude(?![\w.-])/g,
11
+ /\$CLAUDE_PROJECT_DIR\/\.claude(?![\w.-])/g
12
+ ];
13
+ var CONTROL_PLANE_VARIABLE_FORMS = [
14
+ new RegExp(`\\$\\{${CONTROL_PLANE_DIR_VARIABLE}:-[^}]*\\}/\\.claude(?![\\w.-])`, "g"),
15
+ new RegExp(`\\$\\{${CONTROL_PLANE_DIR_VARIABLE}\\}/\\.claude(?![\\w.-])`, "g"),
16
+ new RegExp(`\\$${CONTROL_PLANE_DIR_VARIABLE}/\\.claude(?![\\w.-])`, "g")
17
+ ];
18
+ function rewriteHookCommand(command, dir) {
19
+ return PROJECT_DIR_SPELLINGS.reduce((text, pattern) => text.replace(pattern, () => `${dir}/.claude`), command);
20
+ }
21
+ function rewriteControlPlanePaths(text, dir) {
22
+ return text.replace(/(?<![\w./~$}:-])(\.outerlayer|\.claude)\//g, (_match, root) => `${dir}/${root}/`);
23
+ }
24
+ function hookCommandEscapesControlPlane(command) {
25
+ const remaining = [...PROJECT_DIR_SPELLINGS, ...CONTROL_PLANE_VARIABLE_FORMS].reduce((text, pattern) => text.replace(pattern, " "), command);
26
+ return /\.claude(?:\/|["'\s;|&)]|$)/.test(remaining) || /\$\{?CLAUDE_PROJECT_DIR\}?"?\/\.claude/.test(remaining);
27
+ }
28
+ var MINIMUM_CLAUDE_VERSION = "2.1.284";
29
+ function versionParts(text) {
30
+ const found = /(\d+)\.(\d+)\.(\d+)/.exec(text);
31
+ return found === null ? void 0 : [Number(found[1]), Number(found[2]), Number(found[3])];
32
+ }
33
+ function versionAtLeast(text, minimum = MINIMUM_CLAUDE_VERSION) {
34
+ const have = versionParts(text);
35
+ const need = versionParts(minimum);
36
+ if (have === void 0 || need === void 0) return false;
37
+ const difference = have.map((part, i) => part - need[i]).find((delta) => delta !== 0);
38
+ return (difference ?? 0) >= 0;
39
+ }
40
+ var SHIM_SCRIPT = `#!/bin/sh
41
+ exec outerlayer claude "$@"
42
+ `;
43
+
44
+ export { CONTROL_PLANE_DIR_VARIABLE, MINIMUM_CLAUDE_VERSION, SHIM_SCRIPT, hookCommandEscapesControlPlane, rewriteControlPlanePaths, rewriteHookCommand, versionAtLeast };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EXEC_PORT } from './chunk-RSNSZ2LJ.js';
3
+ import { EXEC_PORT } from './chunk-X5H2WYMB.js';
4
4
  import { createConnection } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-ONKJUM6R.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-MAK5LYRF.js';
5
- import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-OZGHL5Y5.js';
6
- import { runnerCredentialProblem } from './chunk-22RMZBGW.js';
7
- import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-NL4XPC7W.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-Y5MXET4M.js';
5
+ import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-SWCTGCSC.js';
6
+ import { runnerCredentialProblem } from './chunk-XGP3VYOG.js';
7
+ import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
8
8
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
9
9
  import { dirname } from 'path';
10
10
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { C } from './chunk-YRYMNBGQ.js';
3
+ import { C } from './chunk-ANPNT6PM.js';
4
4
  import { readCloudConfig, removeCloudConfigKeys } from './chunk-EABW6AJQ.js';
5
5
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
6
6
 
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { readFileSync } from 'fs';
4
+ import { execFileSync } from 'child_process';
5
+
6
+ createRequire(import.meta.url);
7
+ function startTimeOf(pid) {
8
+ if (process.platform === "linux") return startTimeOfLinux(pid);
9
+ return startTimeOfPs(pid);
10
+ }
11
+ function startTimeOfLinux(pid) {
12
+ try {
13
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
14
+ const afterComm = stat.slice(stat.lastIndexOf(")") + 1).trim();
15
+ const fields = afterComm.split(/\s+/);
16
+ if (fields[0] === "Z" || fields[0] === "X") return null;
17
+ const starttime = fields[19];
18
+ return starttime ?? null;
19
+ } catch {
20
+ return null;
21
+ }
22
+ }
23
+ function startTimeOfPs(pid) {
24
+ try {
25
+ const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], { encoding: "utf8" }).trim();
26
+ return out.length > 0 ? out : null;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ function isSameProcess(pid, start) {
32
+ return startTimeOf(pid) === start;
33
+ }
34
+
35
+ export { isSameProcess, startTimeOf };
@@ -1,22 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LaunchFilter } from './chunk-HHJDN6AU.js';
3
+ import { LaunchFilter } from './chunk-ESVW4MJY.js';
4
4
  import { RepoFilter } from './chunk-TBT347UY.js';
5
+ import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-MQJSXHV7.js';
5
6
  import { hookExecSpoolPath } from './chunk-F7CU5ABH.js';
6
7
  import { applyReportedCost } from './chunk-BKO6JEZI.js';
7
- import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-WUYTWNMA.js';
8
- import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-JXYVA45C.js';
9
- import { C } from './chunk-YRYMNBGQ.js';
10
- import { readLaunchSpoolState, launchStatusIsDecisive, launchedItemsBySession, launchesPath } from './chunk-GQD22KKN.js';
11
- import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
12
- import { defaultFetch } from './chunk-YO4PSLVB.js';
13
- import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-PLMTLGYH.js';
14
- import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-J5M7BSJQ.js';
8
+ import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-BMYGAGBJ.js';
9
+ import { C } from './chunk-ANPNT6PM.js';
10
+ import { readLaunchSpoolState, launchStatusIsDecisive, launchedItemsBySession, launchesPath } from './chunk-T2Q7ISPE.js';
11
+ import { defaultFetch } from './chunk-ZRL6HKBY.js';
12
+ import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-52NC2FIU.js';
13
+ import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-N3CUDFCW.js';
15
14
  import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-EABW6AJQ.js';
16
- import { signerFor, signRunnerRequest } from './chunk-V7NIVOFD.js';
17
- import { writeSyncStatus, spoolDir } from './chunk-BWQ66M6N.js';
15
+ import { signerFor, signRunnerRequest } from './chunk-M2ZWWTWZ.js';
16
+ import { writeSyncStatus, spoolDir } from './chunk-ULSIJGLS.js';
18
17
  import { removeJournalHooks } from './chunk-XCCLFVXM.js';
18
+ import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
19
19
  import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
20
+ import { cliInvocation } from './chunk-CRB3POP4.js';
20
21
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
21
22
  import { dirname, basename, join } from 'path';
22
23
  import { statSync, readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync, rmSync } from 'fs';
@@ -668,7 +669,7 @@ var LiveUploader = class {
668
669
  const credential = this.env.OUTERLAYER_API_KEY;
669
670
  const appId = this.env.OUTERLAYER_APP_ID;
670
671
  if (!url || !credential || !appId) {
671
- this.warnOnce("incomplete", `live upload is idle: this build's environment lacks ${[!url && "OUTERLAYER_URL", !credential && "OUTERLAYER_API_KEY", !appId && "OUTERLAYER_APP_ID"].filter(Boolean).join(", ")}, so nothing streams until \`outerlayer sync\` runs.
672
+ this.warnOnce("incomplete", `live upload is idle: this build's environment lacks ${[!url && "OUTERLAYER_URL", !credential && "OUTERLAYER_API_KEY", !appId && "OUTERLAYER_APP_ID"].filter(Boolean).join(", ")}, so nothing streams until \`${cliInvocation()} sync\` runs.
672
673
  `);
673
674
  return false;
674
675
  }
@@ -724,7 +725,7 @@ var LiveUploader = class {
724
725
  this.stopped = true;
725
726
  this.onUnauthorized?.();
726
727
  this.stderr(
727
- destination.credential.startsWith("olu_") ? `live upload stopped: the login was refused (expired or revoked). No session streams from this daemon until you run \`outerlayer login\` and it restarts.
728
+ destination.credential.startsWith("olu_") ? `live upload stopped: the login was refused (expired or revoked). No session streams from this daemon until you run \`${cliInvocation()} login\` and it restarts.
728
729
  ` : `live upload stopped: the API key was refused. No session streams from this daemon until it restarts with a valid key.
729
730
  `
730
731
  );
@@ -739,7 +740,7 @@ var LiveUploader = class {
739
740
  lastError: reason,
740
741
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
741
742
  });
742
- this.stderr(`live upload stopped for session ${prepared.id}: ${reason}. The next \`outerlayer sync\` uploads it whole.
743
+ this.stderr(`live upload stopped for session ${prepared.id}: ${reason}. The next \`${cliInvocation()} sync\` uploads it whole.
743
744
  `);
744
745
  return true;
745
746
  }
@@ -1439,7 +1440,7 @@ async function runSyncInner(opts, stats) {
1439
1440
  if (opts.quiet || shippedBatches === 0) return;
1440
1441
  process.stderr.write(
1441
1442
  `
1442
- ${C.yellow}!${C.reset} progress saved: ${synced} session(s) in ${shippedBatches}/${batches.length} batch(es) shipped before the failure \u2014 re-run ${C.dim}outerlayer sync${C.reset} to resume from there.
1443
+ ${C.yellow}!${C.reset} progress saved: ${synced} session(s) in ${shippedBatches}/${batches.length} batch(es) shipped before the failure \u2014 re-run ${C.dim}${cliInvocation()} sync${C.reset} to resume from there.
1443
1444
  `
1444
1445
  );
1445
1446
  };
@@ -4,6 +4,6 @@ import { createRequire } from 'node:module';
4
4
  createRequire(import.meta.url);
5
5
 
6
6
  // src/runner/protocol.ts
7
- var RUNNER_PROTOCOL = 17;
7
+ var RUNNER_PROTOCOL = 19;
8
8
 
9
9
  export { RUNNER_PROTOCOL };