@outerlayer/cli 0.16.1 → 0.17.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 (65) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +11 -11
  3. package/dist/{agent-setup-K3ABU5NL.js → agent-setup-T624CWPD.js} +2 -2
  4. package/dist/artifact-link-cmd-2F47LT7F.js +24 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/{check-CNTMSGOG.js → check-5XE7XMC4.js} +14 -14
  7. package/dist/{chunk-YDSMROTB.js → chunk-3NSNIIBE.js} +8 -4
  8. package/dist/{chunk-NPQWKGUA.js → chunk-6Y5RUTHO.js} +1 -1
  9. package/dist/{chunk-6JNURGOA.js → chunk-BWQ66M6N.js} +1 -1
  10. package/dist/{chunk-R4ZQQ7U2.js → chunk-G5NPRL2K.js} +7 -8
  11. package/dist/{chunk-W3EKCZSQ.js → chunk-HGECYFEI.js} +55 -5
  12. package/dist/{chunk-5FEK6PNE.js → chunk-KG5ECZGJ.js} +1 -1
  13. package/dist/{chunk-FWX735W7.js → chunk-LWSJQJC6.js} +3 -3
  14. package/dist/{chunk-EWORLJMO.js → chunk-MAK5LYRF.js} +16 -7
  15. package/dist/{chunk-ONRCEE6D.js → chunk-NNRTPG7X.js} +2 -2
  16. package/dist/{chunk-U3HXXRTY.js → chunk-NWQTTSBB.js} +1 -1
  17. package/dist/{chunk-RSPXEVDX.js → chunk-ONKJUM6R.js} +1 -1
  18. package/dist/{chunk-6QRMLNH3.js → chunk-S3NYLI2P.js} +3 -3
  19. package/dist/{chunk-CA3XMYFN.js → chunk-VQYBXPI7.js} +3 -3
  20. package/dist/{chunk-EHAAPRWY.js → chunk-WVUIRTWA.js} +7 -7
  21. package/dist/{chunk-JJEGKEFV.js → chunk-YU3VKZ5F.js} +1 -1
  22. package/dist/{chunk-JEHRUE3F.js → chunk-YZ5F4PIS.js} +91 -20
  23. package/dist/{cli-AEWH62UE.js → cli-A76AXELQ.js} +71 -63
  24. package/dist/{command-HHPBR6CS.js → command-R2QCVX55.js} +6 -6
  25. package/dist/{connect-cmd-JUAW6MU4.js → connect-cmd-JBKAQNSF.js} +1 -1
  26. package/dist/{context-adopt-VMMGFRUZ.js → context-adopt-NFHCLVUB.js} +1 -1
  27. package/dist/{context-materialize-2WXTS4CW.js → context-materialize-IV2TUUFO.js} +1 -1
  28. package/dist/{doctor-N6Y7HKK3.js → doctor-4TAIARIG.js} +10 -9
  29. package/dist/{emit-artifact-cmd-H5MH3AOP.js → emit-artifact-cmd-MPZVR56N.js} +4 -4
  30. package/dist/{emit-criteria-cmd-HBP6XS5C.js → emit-criteria-cmd-EFGYI23V.js} +2 -2
  31. package/dist/{emit-finding-cmd-ZXDRL6PG.js → emit-finding-cmd-5GF3V4LR.js} +2 -2
  32. package/dist/{emit-result-cmd-RFKALS5Z.js → emit-result-cmd-I4OADKMD.js} +4 -4
  33. package/dist/hidden-prompt-UXBFMQC5.js +68 -0
  34. package/dist/{hook-fast-D7HV4IXG.js → hook-fast-R4FVSZ2H.js} +1 -1
  35. package/dist/index.js +3 -3
  36. package/dist/{init-MYX7YMIH.js → init-6XPDRDTC.js} +7 -7
  37. package/dist/{init-FBCA4DRA.js → init-PWU5YVL7.js} +49 -25
  38. package/dist/{init-cmd-CAG572UE.js → init-cmd-XAVO7HYZ.js} +5 -5
  39. package/dist/{init-update-VDFF4K3B.js → init-update-CVCWD6VS.js} +3 -3
  40. package/dist/{loop-75J4YXLZ.js → loop-FK3LPMMZ.js} +14 -14
  41. package/dist/{machine-A6ZCTUGS.js → machine-SQXEBAM2.js} +6 -6
  42. package/dist/runner-key-6SLBI7PP.js +174 -0
  43. package/dist/{session-sender-24L5EW25.js → session-sender-FO3LCREV.js} +3 -3
  44. package/dist/{status-XHSGEYO5.js → status-7VNQN5PW.js} +9 -9
  45. package/dist/{sync-cmd-5G5EIEHD.js → sync-cmd-GVPPFZ3G.js} +2 -2
  46. package/dist/{watch-UTOXO4SE.js → watch-23HSAEI6.js} +2 -2
  47. package/dist/{work-claim-cmd-RKHYFE5Y.js → work-claim-cmd-LKL3GHFQ.js} +5 -5
  48. package/dist/{work-cmd-DJQJEZVB.js → work-cmd-Z2WXLZPH.js} +3 -3
  49. package/dist/{work-comment-cmd-A55CUSYE.js → work-comment-cmd-AWHP56M2.js} +3 -3
  50. package/dist/{work-open-pr-cmd-E6O53IJD.js → work-open-pr-cmd-IOM4AVQQ.js} +4 -4
  51. package/dist/{work-pr-cmd-L77K32WK.js → work-pr-cmd-HNEUIEN7.js} +3 -3
  52. package/package.json +1 -1
  53. package/skill-pack/maintained/outerlayer-amend/SKILL.md +2 -0
  54. package/skill-pack/maintained/outerlayer-cli/SKILL.md +2 -0
  55. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +4 -2
  56. package/skill-pack/maintained/outerlayer-findings/SKILL.md +2 -0
  57. package/skill-pack/shipped.json +10 -3
  58. package/skill-pack/template/build/SKILL.md +2 -0
  59. package/skill-pack/template/build/references/release.md +13 -11
  60. package/skill-pack/template/build/scripts/criterion-citations.mjs +8 -3
  61. package/skill-pack/template/build/scripts/record-criteria.mjs +8 -2
  62. package/skill-pack/template/spec/SKILL.md +2 -0
  63. package/skill-pack/validators/acceptance-criteria.yaml +6 -5
  64. package/skill-pack/validators/code-review.yaml +6 -5
  65. package/dist/runner-key-W25ISHI3.js +0 -155
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-W3EKCZSQ.js';
3
+ import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-HGECYFEI.js';
4
4
  import './chunk-NBGDBTO2.js';
5
- import './chunk-6QRMLNH3.js';
6
- import './chunk-NPQWKGUA.js';
5
+ import './chunk-S3NYLI2P.js';
6
+ import './chunk-6Y5RUTHO.js';
7
7
  import './chunk-IP7BIBXJ.js';
8
8
  import './chunk-F47JBIAW.js';
9
9
  import './chunk-BKO6JEZI.js';
10
10
  import './chunk-XCK2YAY5.js';
11
11
  import './chunk-42ZI52JW.js';
12
- import './chunk-YDSMROTB.js';
12
+ import './chunk-3NSNIIBE.js';
13
13
  import './chunk-WUYTWNMA.js';
14
14
  import './chunk-JXYVA45C.js';
15
15
  import './chunk-4KSQKQXE.js';
@@ -28,7 +28,7 @@ import './chunk-EABW6AJQ.js';
28
28
  import { resolveVersion } from './chunk-RA3O54FC.js';
29
29
  import './chunk-V7NIVOFD.js';
30
30
  import './chunk-ZM2IMMYN.js';
31
- import { hookFiredMarkerPath, installedCliDistDir } from './chunk-6JNURGOA.js';
31
+ import { hookFiredMarkerPath, installedCliDistDir } from './chunk-BWQ66M6N.js';
32
32
  import { managedHookScripts, removeJournalHooks, installPreCommitGuardHook, removePreCommitGuardHook } from './chunk-XCCLFVXM.js';
33
33
  import './chunk-BJ3KTMDH.js';
34
34
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -3632,7 +3632,7 @@ function printLauncher(result, summary) {
3632
3632
  const line = summary(result.launcher);
3633
3633
  if (line !== void 0) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
3634
3634
  `);
3635
- for (const note of result.launcher.notes) process.stdout.write(`${C.yellow}${note}${C.reset}
3635
+ for (const note of result.launcher.notes) process.stdout.write(`${C.yellow}!${C.reset} ${note}
3636
3636
  `);
3637
3637
  }
3638
3638
  function writeJson(value) {
@@ -3806,7 +3806,7 @@ ${starter.output}`),
3806
3806
  }
3807
3807
  }
3808
3808
  async function realConnectDepsForCwd() {
3809
- const { realConnectDeps } = await import('./connect-cmd-JUAW6MU4.js');
3809
+ const { realConnectDeps } = await import('./connect-cmd-JBKAQNSF.js');
3810
3810
  const { resolveRepoIdentity } = await import('./dist-LKDWQWZ7.js');
3811
3811
  return {
3812
3812
  ...realConnectDeps(),
@@ -3828,7 +3828,7 @@ function buildProgram(argv = process.argv) {
3828
3828
  "\nIn a repository, init runs four steps: connect the repository to a\nfactory (`outerlayer connect`), install the hooks, set up the coding agent,\nand run `outerlayer doctor`. It never signs in and asks nothing. With no\nlogin it skips the connect step and says to run `outerlayer login`. With\n--json it prints one document naming the outcome of each step: done,\nskipped or failed. The exit code is 1 when a step failed.\n\nThe agent setup step installs the starter skills and the `outerlayer` skill\ninto .outerlayer/skills/, writes .outerlayer/config.json for Claude Code when\nthere is none, runs `outerlayer context emit` so the skills appear in\n.claude/skills/, and adds the outerlayer and outerlayer-docs MCP servers to\n.mcp.json. Nothing you wrote is changed: an existing config, policy, edited\nskill, MCP entry or root CLAUDE.md and AGENTS.md is left as it is, and a\nhand-written file the emit would replace is kept and listed. The files are\nleft uncommitted.\nThe step is skipped outside a git repository and in a repository whose\ncontext comes from a control plane, where it arrives at session start.\n\n--local installs only the hooks: no connect step, no agent setup and no\nnetwork call. Add `--template default` to also write the starter skills and\na policy file into .outerlayer/ without compiling them; `outerlayer context\nemit` does that.\n\nIdempotent: settings are backed up before any write, and a second run\nchanges nothing. Wrapping adds one spawn per hook firing; undo it with\n`outerlayer hooks unwrap`. An occupied status-line slot is wrapped, never\nreplaced.\n\nThree of the starter skills are copied once and are yours to edit. The\nothers are rewritten from this CLI on every `context emit`.\n\n--update brings the files init wrote once up to this CLI's version: the\ntemplate skills, the policy, the two starter checks and the two MCP\nentries. A file still equal to a version an earlier release wrote is\nreplaced, and a missing one is written. A file you edited is never\ntouched. It then runs `outerlayer context emit` and leaves the changes\nuncommitted. --dry-run prints the plan, with a command to compare each\nedited file, and writes nothing. `outerlayer doctor` reports the same\nstates under Starter files.\n"
3829
3829
  ).action(async (opts) => {
3830
3830
  if (opts.update || opts.dryRun) {
3831
- const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-VDFF4K3B.js');
3831
+ const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-CVCWD6VS.js');
3832
3832
  const problem = updateFlagProblem(opts);
3833
3833
  if (problem !== void 0) {
3834
3834
  fail(problem);
@@ -3873,7 +3873,7 @@ function buildProgram(argv = process.argv) {
3873
3873
  else process.stdout.write(outcome.text);
3874
3874
  return;
3875
3875
  }
3876
- const { runInitCommand } = await import('./init-cmd-CAG572UE.js');
3876
+ const { runInitCommand } = await import('./init-cmd-XAVO7HYZ.js');
3877
3877
  const code = await runInitCommand(
3878
3878
  { json: opts.json, factory: opts.factory },
3879
3879
  {
@@ -3885,7 +3885,7 @@ function buildProgram(argv = process.argv) {
3885
3885
  return { ok, text, detail };
3886
3886
  },
3887
3887
  runAgentSetup: async () => {
3888
- const { runAgentSetup } = await import('./agent-setup-K3ABU5NL.js');
3888
+ const { runAgentSetup } = await import('./agent-setup-T624CWPD.js');
3889
3889
  return runAgentSetup({ cwd: process.cwd() });
3890
3890
  },
3891
3891
  runDoctorChecks: gatherDoctorChecks
@@ -3897,7 +3897,7 @@ function buildProgram(argv = process.argv) {
3897
3897
  "after",
3898
3898
  "\nRun it in a repository, after `outerlayer login`. With a login, connect lists\nthe factories you can use and takes the first rule that leaves one answer:\n 1. --factory <org>/<factory>, or a factory id\n 2. the factory this repository is already connected to\n 3. the one factory this repository is linked to\n 4. the one factory you can use\n 5. on a terminal, ask; with no terminal, exit 1 and list each --factory value\n\nIt says what it chose and why. The choice is saved in this repository's git\ndirectory (outerlayer/connection.json), shared by every worktree of the\nclone and never committed. A factory key already belongs to one factory, so\nconnect changes nothing for it. Connect never links a repository.\n\nAfter it saves the choice, connect checks that this repository is linked to\nthe factory. If it is not, connect says so, prints the factory's Work page\nlink where you link it, and exits 2. The choice is saved either way. Run\nconnect again once the repository is linked. With --json, the document has\nlinked (true, false, or null when it could not be checked) and, when false,\nlinkUrl.\n"
3899
3899
  ).action(async (opts) => {
3900
- const { runConnectCommand } = await import('./connect-cmd-JUAW6MU4.js');
3900
+ const { runConnectCommand } = await import('./connect-cmd-JBKAQNSF.js');
3901
3901
  const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
3902
3902
  stdout: process.stdout,
3903
3903
  stderr: process.stderr
@@ -3940,12 +3940,19 @@ function buildProgram(argv = process.argv) {
3940
3940
  const code = await runLogoutCommand(realLogoutDeps());
3941
3941
  if (code !== 0) process.exitCode = code;
3942
3942
  });
3943
- program2.command("sync").description("Send local coding-agent sessions to OuterLayer cloud").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").option("--tier <tier>", "capture tier: metrics | redacted | full (default: full)").option("--dry-run", "print what would leave this machine, send nothing").option("--all", "ignore the sync checkpoint and re-send everything").option("--limit <n>", "only the N most recent sessions", (v) => parseInt(v, 10)).option("--json", "machine-readable JSON output").option("--quiet", "no output; exit code only").option("--root <dir>", "Claude Code transcript root (default ~/.claude/projects)").option("--codex-root <dir>", "Codex sessions root (default ~/.codex/sessions)").option("--cursor-root <dir>", "Cursor chats root (default ~/.cursor/chats)").addHelpText(
3943
+ program2.command("sync").description("Send local coding-agent sessions to OuterLayer cloud").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").option("--tier <tier>", "capture tier: metrics | redacted | full (default: full)").option("--dry-run", "print what would leave this machine, send nothing").option("--all", "ignore the sync checkpoint and re-send everything").option("--limit <n>", "only the N most recent sessions", (v) => parseInt(v, 10)).option("--json", "machine-readable JSON output").option("--quiet", "no output; exit code only").option("--link <artifactId>", "print the dashboard link of an artifact already uploaded; sends nothing").option("--root <dir>", "Claude Code transcript root (default ~/.claude/projects)").option("--codex-root <dir>", "Codex sessions root (default ~/.codex/sessions)").option("--cursor-root <dir>", "Cursor chats root (default ~/.cursor/chats)").addHelpText(
3944
3944
  "after",
3945
3945
  "\nIncremental: only sessions newer than the last checkpoint ship. The tier\nis applied on this machine before anything leaves it; `--dry-run` prints\nexactly what would. The hook-triggered background sync runs `--quiet`.\nExit 2 means the server rejected at least one session.\n"
3946
3946
  ).action(async (opts) => {
3947
3947
  warnIfApiKeyFlag(opts);
3948
- const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-5G5EIEHD.js');
3948
+ if (opts.link !== void 0) {
3949
+ const { lookupArtifactLink } = await import('./artifact-link-cmd-2F47LT7F.js');
3950
+ const found = lookupArtifactLink(opts.link);
3951
+ if (found.ok) process.stdout.write(found.url + "\n");
3952
+ else fail(found.reason);
3953
+ return;
3954
+ }
3955
+ const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-GVPPFZ3G.js');
3949
3956
  try {
3950
3957
  const result = await runSync({
3951
3958
  url: opts.url,
@@ -3974,7 +3981,7 @@ function buildProgram(argv = process.argv) {
3974
3981
  if (invokedCommandToken(argv) === "watch") {
3975
3982
  warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
3976
3983
  }
3977
- const { runWatch } = await import('./watch-UTOXO4SE.js');
3984
+ const { runWatch } = await import('./watch-23HSAEI6.js');
3978
3985
  await runWatch({ once: opts.once });
3979
3986
  });
3980
3987
  program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
@@ -4028,7 +4035,7 @@ function buildProgram(argv = process.argv) {
4028
4035
  }
4029
4036
  });
4030
4037
  program2.command("session-sender", { hidden: true }).description("stream a runner build's sessions to its work item while the build runs").action(async () => {
4031
- const { runSessionSender } = await import('./session-sender-24L5EW25.js');
4038
+ const { runSessionSender } = await import('./session-sender-FO3LCREV.js');
4032
4039
  try {
4033
4040
  await runSessionSender();
4034
4041
  } catch (err) {
@@ -4086,7 +4093,7 @@ function registerEmitCommands(program2) {
4086
4093
  return;
4087
4094
  }
4088
4095
  warnIfApiKeyFlag(opts);
4089
- const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-RFKALS5Z.js');
4096
+ const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-I4OADKMD.js');
4090
4097
  try {
4091
4098
  const result = await runEmitResult({
4092
4099
  name,
@@ -4137,7 +4144,7 @@ locally so it never uploads. One correction can retire several duplicates.
4137
4144
  `
4138
4145
  ).action(async (file, opts) => {
4139
4146
  warnIfApiKeyFlag(opts);
4140
- const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-H5MH3AOP.js');
4147
+ const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-MPZVR56N.js');
4141
4148
  let pr;
4142
4149
  if (opts.pr !== void 0) {
4143
4150
  pr = parseTrackerNumber(opts.pr);
@@ -4172,7 +4179,7 @@ locally so it never uploads. One correction can retire several duplicates.
4172
4179
  '\n outerlayer emit finding --id gate-skip --category tooling \\\n --title "The pre-push gate prints green when a step was skipped" \\\n --file scripts/git/pre-push-checks.mjs --where "build session"\n\nRecords one problem you hit in the factory: an instruction that is wrong or\nmissing (context), a flaky test, a misbehaving script (tooling), a local\nsetup trap (environment), a bug outside your own change (defect), or\nanything else. A problem in your own change is fixed, not recorded.\nA context finding needs --rule-path and --rule-relation, and --rule-quote\nunless the relation is missing. Add --cause, --detail and --suggestion, and\n--command, --error (first error line), --test or --symbol when there is one.\n\nEvery finding joins a factory-level problem. When one of its keys matches a\nknown problem it joins that problem. Otherwise nothing is stored: the command\nprints the closest problems and exits with code 3. Run it again with\n--problem <id> --link-reason <why> (repeat --problem for each problem the\nfinding reports), or with --new if none of them is the same problem.\nA finding records the time it cost, read from two events of your session or\nits subagents. The start is --started-at, else the first tool output that\nshows --error. The end is --ended-at, else the newest event. When the session\nhas events and no start is found, nothing is stored: the command lists the\nrecent events with their ids. --find <text> searches all of them.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically.\n'
4173
4180
  ).action(async (opts) => {
4174
4181
  warnIfApiKeyFlag(opts);
4175
- const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-ZXDRL6PG.js');
4182
+ const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-5GF3V4LR.js');
4176
4183
  try {
4177
4184
  refuseRemovedFindingFlags(opts);
4178
4185
  const result = await runEmitFinding({
@@ -4225,7 +4232,7 @@ locally so it never uploads. One correction can retire several duplicates.
4225
4232
  '\n outerlayer emit findings review.json --item 412\n\nRecords a whole batch at once \u2014 a FindingBatch JSON file (schemaVersion 3,\noptional headSha / contextSourceSha, and 1-500 findings), validated against\nthe same contract `emit finding` uses before anything is sent. Re-emitting\nan id already on the item replaces that row rather than adding a second one.\nFindings that need a choice between candidate problems are listed and not\nstored; the rest are stored, and the exit code is 3.\nEach finding records its time as `emit finding` does: "startedAt" is an event\nid, else the first tool output that shows its "error"; "endedAt" defaults to\nthe newest event. A finding with neither, in a session that has events, stops\nthe whole batch. "untimed": true records one with no time on purpose.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n'
4226
4233
  ).action(async (file, opts) => {
4227
4234
  warnIfApiKeyFlag(opts);
4228
- const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-ZXDRL6PG.js');
4235
+ const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-5GF3V4LR.js');
4229
4236
  try {
4230
4237
  const result = await runEmitFindings({
4231
4238
  file,
@@ -4265,7 +4272,7 @@ session was launched for is used automatically.
4265
4272
  `
4266
4273
  ).action(async (file, opts) => {
4267
4274
  warnIfApiKeyFlag(opts);
4268
- const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-HBP6XS5C.js');
4275
+ const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-EFGYI23V.js');
4269
4276
  try {
4270
4277
  const result = await runEmitCriteria({
4271
4278
  file,
@@ -4292,7 +4299,7 @@ function registerWorkCommands(program2) {
4292
4299
  "\n outerlayer work build --issue 42 # a host builds it\n outerlayer work build --item 7 # retry an item already on Work\n outerlayer work build --issue 42 --local # you build it\n outerlayer work build --issue ENG-123 --tracker linear # a Linear issue\n\nWithout --local, records a build request: a host takes the item when it\nhas a free slot. It never links the calling session and never takes a\nlease, even run from inside one.\n\nWith --local, puts the item on Work with no build request, so no host\ntakes it, and prints the line that starts your session on it. That\nsession links itself and holds the item's lease while it works.\n"
4293
4300
  ).action(async (opts) => {
4294
4301
  warnIfApiKeyFlag(opts);
4295
- const { runWorkBuild, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4302
+ const { runWorkBuild, WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4296
4303
  try {
4297
4304
  await runWorkBuild(opts);
4298
4305
  } catch (err) {
@@ -4308,7 +4315,7 @@ function registerWorkCommands(program2) {
4308
4315
  "\n outerlayer work link-session 42\n\nNames an item that already exists on the calling session \u2014 it never\ncreates one. Create one with `outerlayer work build --local`. Linking\nthe same session to the same item twice is a no-op. Also takes or\nrenews that session's own 20-minute lease, unless --no-lease or\n--ended is given, or another worker already holds a live one.\n"
4309
4316
  ).action(async (number, opts) => {
4310
4317
  warnIfApiKeyFlag(opts);
4311
- const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4318
+ const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4312
4319
  try {
4313
4320
  await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
4314
4321
  } catch (err) {
@@ -4333,8 +4340,8 @@ most one action flag may be given.
4333
4340
  `
4334
4341
  ).action(async (opts) => {
4335
4342
  warnIfApiKeyFlag(opts);
4336
- const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-A55CUSYE.js');
4337
- const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4343
+ const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-AWHP56M2.js');
4344
+ const { WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4338
4345
  try {
4339
4346
  await runWorkComment(opts);
4340
4347
  } catch (err) {
@@ -4350,8 +4357,8 @@ most one action flag may be given.
4350
4357
  "\n outerlayer work threads --item 7\n\nPrints the item's general thread, then one thread per acceptance\ncriterion that carries proof or a comment, each with who is waiting\non whom next.\n"
4351
4358
  ).action(async (opts) => {
4352
4359
  warnIfApiKeyFlag(opts);
4353
- const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-A55CUSYE.js');
4354
- const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4360
+ const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-AWHP56M2.js');
4361
+ const { WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4355
4362
  try {
4356
4363
  await runWorkThreads(opts);
4357
4364
  } catch (err) {
@@ -4373,7 +4380,7 @@ live addition remains on it.
4373
4380
  `
4374
4381
  ).action(async (opts) => {
4375
4382
  warnIfApiKeyFlag(opts);
4376
- const { runWorkRemove, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4383
+ const { runWorkRemove, WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4377
4384
  try {
4378
4385
  await runWorkRemove(opts);
4379
4386
  } catch (err) {
@@ -4386,7 +4393,7 @@ live addition remains on it.
4386
4393
  });
4387
4394
  workCmd.command("status").description("Show one item's stage, gate ledger, and additions").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
4388
4395
  warnIfApiKeyFlag(opts);
4389
- const { runWorkStatus, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4396
+ const { runWorkStatus, WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4390
4397
  try {
4391
4398
  await runWorkStatus(opts);
4392
4399
  } catch (err) {
@@ -4399,7 +4406,7 @@ live addition remains on it.
4399
4406
  });
4400
4407
  workCmd.command("list").description("List live work items for this factory").option("--stage <spec|build|review>", "filter by stage").option("--section <attention|waiting|flowing>", "filter by Queue section").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--unclaimed", "only items with no live lease").option("--claimed", "only items with a live lease, held by a host or a local session").option("--startable", "only items a host can start: a build request, no open PR, no live lease").option("--needs <amend>", "only items with a thread waiting on an agent").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
4401
4408
  warnIfApiKeyFlag(opts);
4402
- const { runWorkList, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4409
+ const { runWorkList, WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4403
4410
  try {
4404
4411
  await runWorkList(opts);
4405
4412
  } catch (err) {
@@ -4415,7 +4422,7 @@ live addition remains on it.
4415
4422
  "\n outerlayer work claim --item 42 --kind implement\n\nRecords a lease held by the API key that sends it. A live lease held\nby a different key is refused; claiming again with the same key extends\nit. --host is a label only.\n"
4416
4423
  ).action(async (opts) => {
4417
4424
  warnIfApiKeyFlag(opts);
4418
- const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4425
+ const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-LKL3GHFQ.js');
4419
4426
  try {
4420
4427
  await runWorkClaim(opts);
4421
4428
  } catch (err) {
@@ -4431,7 +4438,7 @@ live addition remains on it.
4431
4438
  "\n outerlayer work renew --item 42\n\nExtends the live lease this API key holds. Refused with a 410 if the\nlease has expired, or a 403 if a different key holds it.\n"
4432
4439
  ).action(async (opts) => {
4433
4440
  warnIfApiKeyFlag(opts);
4434
- const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4441
+ const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-LKL3GHFQ.js');
4435
4442
  try {
4436
4443
  await runWorkRenew(opts);
4437
4444
  } catch (err) {
@@ -4450,7 +4457,7 @@ live addition remains on it.
4450
4457
  "\n outerlayer work release --item 42 --outcome ok\n outerlayer work release --item 42\n\nMarks the lease this API key holds released, optionally with an\noutcome. A lease held by a different key is refused. Releasing an\nalready-released lease is a no-op that returns the recorded release\ntime and outcome.\n\nRun inside a session with no --host, it releases that session's own\nlease instead, so the item's review opens without ending the\nsession. It never releases another session's lease. --outcome\napplies to a host's lease only. A later tool call in the session\ntakes the lease again.\n"
4451
4458
  ).action(async (opts) => {
4452
4459
  warnIfApiKeyFlag(opts);
4453
- const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4460
+ const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-LKL3GHFQ.js');
4454
4461
  try {
4455
4462
  await runWorkRelease(opts);
4456
4463
  } catch (err) {
@@ -4466,7 +4473,7 @@ live addition remains on it.
4466
4473
  "\n outerlayer work pr 481\n outerlayer work pr 481 --withdraw --item 250\n\nRun inside a session already on a work item. Records that pull\nrequest 481 in the checkout's repository belongs to the item named by\nOUTERLAYER_WORK, or refuses when the session is not on it. The same\nfact a `pr-link` in the session's own transcript records on sync.\nIdempotent: declaring the same pull request twice is a no-op.\n\n--withdraw removes one item's declaration of the pull request. It\nneeds your own login; an agent session or a factory key is refused.\n"
4467
4474
  ).action(async (number, opts) => {
4468
4475
  warnIfApiKeyFlag(opts);
4469
- const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-L77K32WK.js');
4476
+ const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-HNEUIEN7.js');
4470
4477
  try {
4471
4478
  await runWorkPr({ ...opts, number });
4472
4479
  } catch (err) {
@@ -4482,8 +4489,8 @@ live addition remains on it.
4482
4489
  '\n outerlayer work open-pr --title "Add the thing" --body-file pr.md\n outerlayer work open-pr --repository acme/web --title "Add the thing" --body-file pr.md\n\nIn a host build, which holds an item key, the gateway opens the pull\nrequest as the factory\'s GitHub App, from the branch the claim named,\nor edits the one already open on that branch. No gh command runs.\nIn your own session it runs `gh pr create` (or `gh pr edit`) under your\nlogin, then declares the pull request on the item, as `work pr` does.\nRun it again after a change to the title or description.\n'
4483
4490
  ).action(async (opts) => {
4484
4491
  warnIfApiKeyFlag(opts);
4485
- const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-E6O53IJD.js');
4486
- const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4492
+ const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-IOM4AVQQ.js');
4493
+ const { WorkCommandError } = await import('./work-cmd-Z2WXLZPH.js');
4487
4494
  try {
4488
4495
  await runWorkOpenPr(opts);
4489
4496
  } catch (err) {
@@ -4500,7 +4507,7 @@ function registerRunnerCommands(program2) {
4500
4507
  const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
4501
4508
  runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
4502
4509
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
4503
- const { start, RunnerStartError } = await import('./loop-75J4YXLZ.js');
4510
+ const { start, RunnerStartError } = await import('./loop-FK3LPMMZ.js');
4504
4511
  const { RunnerAlreadyRunningError } = await import('./pidfile-UZRH774M.js');
4505
4512
  const configPath = opts.config ?? defaultRunnerConfigPath();
4506
4513
  try {
@@ -4516,7 +4523,7 @@ function registerRunnerCommands(program2) {
4516
4523
  });
4517
4524
  runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
4518
4525
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4519
- const { runRunnerCheck } = await import('./check-CNTMSGOG.js');
4526
+ const { runRunnerCheck } = await import('./check-5XE7XMC4.js');
4520
4527
  const configPath = opts.config ?? defaultRunnerConfigPath();
4521
4528
  const result = await runRunnerCheck(configPath);
4522
4529
  if (!result.ok) {
@@ -4545,7 +4552,7 @@ function registerRunnerCommands(program2) {
4545
4552
  }
4546
4553
  try {
4547
4554
  if (opts.service === true) {
4548
- const { installServiceCommand } = await import('./command-HHPBR6CS.js');
4555
+ const { installServiceCommand } = await import('./command-R2QCVX55.js');
4549
4556
  const result2 = await installServiceCommand({
4550
4557
  configPath,
4551
4558
  print: opts.print,
@@ -4601,21 +4608,21 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
4601
4608
  return;
4602
4609
  }
4603
4610
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4604
- const { uninstallServiceCommand } = await import('./command-HHPBR6CS.js');
4611
+ const { uninstallServiceCommand } = await import('./command-R2QCVX55.js');
4605
4612
  const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
4606
4613
  if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
4607
4614
  `);
4608
4615
  else fail(result.lines.length > 0 ? result.lines.join("\n ") : "the service was not removed");
4609
4616
  });
4610
- runnerCmd.command("init").description("Write a runner block that fits this machine; on macOS, offers a Linux VM").option("--config <path>", configOption).option("--vm", "on macOS, run the runner in a Linux VM (Lima), with container builds").option("--no-vm", "on macOS, skip the VM and run builds as unisolated processes").option("--allow-process-builds", "where builds cannot be isolated, run them as processes anyway").addOption(new Option("--config-stdin", "the VM-side hand-off: read the whole config as JSON on stdin").hideHelp()).option("--vm-cli-package <path>", "with --vm, install this packed CLI tarball in the VM").option("--unit-name <name>", "the service unit's name, to run a second runner beside the first").option("--agent <name>", "write commands that start this agent (claude); its credential comes on stdin").option("--app-id <id>", "factory id to create the runner key on, when it comes from your login").option("--key-name <name>", "name of the runner key created from your login (default: machine name)").addHelpText(
4617
+ runnerCmd.command("init").description("Write a runner block that fits this machine; on macOS, offers a Linux VM").option("--config <path>", configOption).option("--vm", "on macOS, run the runner in a Linux VM (Lima), with container builds").option("--no-vm", "on macOS, skip the VM and run builds as unisolated processes").option("--allow-process-builds", "where builds cannot be isolated, run them as processes anyway").addOption(new Option("--config-stdin", "the VM-side hand-off: read the whole config as JSON on stdin").hideHelp()).option("--vm-cli-package <path>", "with --vm, install this packed CLI tarball in the VM").option("--unit-name <name>", "the service unit's name, to run a second runner beside the first").option("--agent <name>", "write commands that start this agent (claude); its credential comes on stdin").option("--factory <org/factory>", "factory to create the runner key on, as <org>/<factory>").option("--app-id <id>", "factory id, instead of --factory (Settings \u2192 General)").addHelpText(
4611
4618
  "after",
4612
- "\nWith no apiKey in the config file, and a login saved by `outerlayer login`,\nrunner init creates the runner key itself, with the Runner preset, on the\nfactory --app-id names (or OUTERLAYER_APP_ID, or this repository's\nconnection). Your login needs factory_keys.insert on that factory.\n\nWith --agent claude, the queue commands start Claude Code instead of the\nplaceholder, and Claude's credential is read from stdin: a token from\n`claude setup-token` (sk-ant-oat...) or an API key (sk-ant-api...). It is\nnever printed, and is stored in the runner.env beside the config with mode\n600. Other lines in the file are kept. With nothing piped, a credential\nalready in runner.env is used.\n\n printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude\n"
4619
+ "\nWith no apiKey in the config file, and a login saved by `outerlayer login`,\nrunner init names the factory the runner is for: --factory, then --app-id,\nOUTERLAYER_APP_ID, or this repository's connection. With none of those, a\nlogin that can use one factory uses it, and one that can use several lists\nthem. It then prints the factory's API keys page, where you create a key with\nthe Runner preset, and asks you to paste it. Nothing is shown as you paste.\nWith no terminal to ask on, it stops and says what to put in the config file.\n\nWith --agent claude, the queue commands start Claude Code instead of the\nplaceholder, and Claude's credential is read from stdin: a token from\n`claude setup-token` (sk-ant-oat...) or an API key (sk-ant-api...). It is\nnever printed, and is stored in the runner.env beside the config with mode\n600. Other lines in the file are kept. With nothing piped, a credential\nalready in runner.env is used.\n\n printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude --factory <org>/<factory>\n"
4613
4620
  ).action(async (opts) => {
4614
4621
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
4615
- const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-MYX7YMIH.js');
4616
- const { createRunnerKey, runnerKeyLogin } = await import('./runner-key-W25ISHI3.js');
4617
- const { detectMachine } = await import('./machine-A6ZCTUGS.js');
4618
- const { chooseVm, runVmInit, VmInitError } = await import('./init-FBCA4DRA.js');
4622
+ const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-6XPDRDTC.js');
4623
+ const { obtainRunnerKey, runnerKeyLogin } = await import('./runner-key-6SLBI7PP.js');
4624
+ const { detectMachine } = await import('./machine-SQXEBAM2.js');
4625
+ const { chooseVm, runVmInit, VmInitError } = await import('./init-PWU5YVL7.js');
4619
4626
  const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-EN7YE7QX.js');
4620
4627
  const configPath = opts.config ?? defaultRunnerConfigPath();
4621
4628
  if (opts.agent !== void 0 && !isAgentName(opts.agent)) {
@@ -4640,8 +4647,8 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
4640
4647
  }
4641
4648
  const machine = detectMachine();
4642
4649
  if (opts.configStdin === true) {
4643
- if (opts.appId !== void 0 || opts.keyName !== void 0) {
4644
- fail("the VM-side hand-off carries its runner key in its config on stdin; pass no --app-id or --key-name with it.");
4650
+ if (opts.appId !== void 0 || opts.factory !== void 0) {
4651
+ fail("the VM-side hand-off carries its runner key in its config on stdin; pass no --app-id or --factory with it.");
4645
4652
  return;
4646
4653
  }
4647
4654
  const chunks = [];
@@ -4656,14 +4663,13 @@ hooks: ${result2.hooks}
4656
4663
  `);
4657
4664
  return;
4658
4665
  }
4659
- const login = runnerKeyLogin(configPath, { appId: opts.appId });
4660
- if (login === void 0 && opts.keyName !== void 0) {
4661
- fail(
4662
- `--key-name names the runner key runner init creates from your login, and it creates none here: ${configPath} already has an apiKey, or no login is saved. Run \`outerlayer login\` first, or leave --key-name out.`
4663
- );
4664
- return;
4665
- }
4666
- const makeKey = login === void 0 ? void 0 : () => createRunnerKey(login, { name: opts.keyName });
4666
+ const login = await runnerKeyLogin(configPath, { appId: opts.appId, factory: opts.factory });
4667
+ if (login?.note !== void 0) process.stdout.write(`${login.note}
4668
+ `);
4669
+ const { terminalPrompt } = await import('./hidden-prompt-UXBFMQC5.js');
4670
+ const readKey = login === void 0 ? void 0 : terminalPrompt();
4671
+ if (login !== void 0 && readKey === void 0) await obtainRunnerKey(login, { configPath, readKey });
4672
+ const makeKey = login === void 0 ? void 0 : () => obtainRunnerKey(login, { configPath, readKey });
4667
4673
  let declinedVm = opts.vm === false;
4668
4674
  const useVm = await chooseVm({
4669
4675
  platform: machine.platform,
@@ -4698,6 +4704,8 @@ hooks: ${result2.hooks}
4698
4704
  `)
4699
4705
  });
4700
4706
  for (const line of result2.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
4707
+ `);
4708
+ for (const line of result2.warnings) process.stdout.write(`${C.yellow}!${C.reset} ${line}
4701
4709
  `);
4702
4710
  return;
4703
4711
  }
@@ -4708,7 +4716,7 @@ hooks: ${result2.hooks}
4708
4716
  const { ensureHostKey } = await import('./host-key-YMLXY6QB.js');
4709
4717
  const hostKey = await ensureHostKey(configPath);
4710
4718
  if (created !== void 0) {
4711
- process.stdout.write(`${C.green}\u2713${C.reset} created the runner key ${created.name} from your login, with the Runner preset, and saved it in ${result.configPath}
4719
+ process.stdout.write(`${C.green}\u2713${C.reset} saved the runner key in ${result.configPath}
4712
4720
  `);
4713
4721
  }
4714
4722
  process.stdout.write(`${C.green}\u2713${C.reset} wrote a runner block into ${result.configPath}
@@ -4765,7 +4773,7 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
4765
4773
  let serviceUp = false;
4766
4774
  let restart;
4767
4775
  if (installedLayout) {
4768
- const { installServiceCommand } = await import('./command-HHPBR6CS.js');
4776
+ const { installServiceCommand } = await import('./command-R2QCVX55.js');
4769
4777
  const service = await installServiceCommand({
4770
4778
  configPath,
4771
4779
  entryPath: process.argv[1] ?? "",
@@ -4876,15 +4884,15 @@ Next:
4876
4884
  });
4877
4885
  runnerCmd.command("stop").description("Take no more work; wait for running jobs to finish, then exit").option("--config <path>", "the cloud config file naming the runner to stop").option("--now", "end running jobs immediately, with outcome stopped").action(async (opts) => {
4878
4886
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4879
- const { requestStop } = await import('./loop-75J4YXLZ.js');
4887
+ const { requestStop } = await import('./loop-FK3LPMMZ.js');
4880
4888
  const configPath = opts.config ?? defaultRunnerConfigPath();
4881
4889
  await requestStop(configPath, Boolean(opts.now));
4882
4890
  });
4883
4891
  runnerCmd.command("status").description("List running jobs; with --recent, finished ones too").option("--config <path>", "the cloud config file naming the runner to inspect").option("--recent", "also list finished jobs, newest first, capped at 20").option("--json", "machine-readable JSON output").action(async (opts) => {
4884
4892
  const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-N3C6DFQA.js');
4885
4893
  const { jobsDir, runnerDir } = await import('./paths-OYKMVYJP.js');
4886
- const { listJobFiles, runnerProcessState } = await import('./loop-75J4YXLZ.js');
4887
- const { renderStatus } = await import('./status-XHSGEYO5.js');
4894
+ const { listJobFiles, runnerProcessState } = await import('./loop-FK3LPMMZ.js');
4895
+ const { renderStatus } = await import('./status-7VNQN5PW.js');
4888
4896
  const { readHousekeepingRecord } = await import('./record-C43U4PKS.js');
4889
4897
  const path2 = await import('path');
4890
4898
  const configPath = opts.config ?? defaultRunnerConfigPath();
@@ -4940,7 +4948,7 @@ Next:
4940
4948
  });
4941
4949
  runnerCmd.command("logs").argument("<item>", "the work item's number in the factory").description("Print the newest attempt's log for one item").option("--config <path>", "the cloud config file naming the runner to inspect").option("-f, --follow", "keep printing as the log grows").action(async (itemArg, opts) => {
4942
4950
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4943
- const { listJobFiles } = await import('./loop-75J4YXLZ.js');
4951
+ const { listJobFiles } = await import('./loop-FK3LPMMZ.js');
4944
4952
  const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-H55NWW4H.js');
4945
4953
  const configPath = opts.config ?? defaultRunnerConfigPath();
4946
4954
  const item = parseTrackerNumber(itemArg);
@@ -5256,7 +5264,7 @@ function registerContextCommands(program2) {
5256
5264
  await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
5257
5265
  });
5258
5266
  contextCmd.command("adopt <stagedDir>", { hidden: true }).description("Copy context the runner staged into this checkout (container builds)").option("--json", "machine-readable JSON output").action(async (stagedDir) => {
5259
- const { runContextAdopt } = await import('./context-adopt-VMMGFRUZ.js');
5267
+ const { runContextAdopt } = await import('./context-adopt-NFHCLVUB.js');
5260
5268
  const { exitCode, stdout } = runContextAdopt(stagedDir, process.cwd());
5261
5269
  process.stdout.write(stdout);
5262
5270
  process.exitCode = exitCode;
@@ -5265,7 +5273,7 @@ function registerContextCommands(program2) {
5265
5273
  "after",
5266
5274
  "\nThe same flow SessionStart runs automatically, exposed for a manual retry or a\nfirst check outside a session. Writes AGENTS.md, .claude/**, and .outerlayer/**.\n"
5267
5275
  ).action(async (opts) => {
5268
- const { materializeContext } = await import('./context-materialize-2WXTS4CW.js');
5276
+ const { materializeContext } = await import('./context-materialize-IV2TUUFO.js');
5269
5277
  const result = await materializeContext({ cwd: process.cwd(), sessionId: `manual-${Date.now()}` });
5270
5278
  const output = formatContextMaterializeOutput(result);
5271
5279
  if (output.exitCode !== void 0) process.exitCode = output.exitCode;
@@ -5,14 +5,14 @@ import { runRunnerInstall, launcherSummary, restartNote } from './chunk-ERI5GBNI
5
5
  import './chunk-I2UOAV7X.js';
6
6
  import './chunk-PTW6W5NR.js';
7
7
  import { currentLink, execStartCommand } from './chunk-TI7B7UEO.js';
8
- import { detectMachine } from './chunk-RSPXEVDX.js';
9
- import './chunk-EWORLJMO.js';
8
+ import { detectMachine } from './chunk-ONKJUM6R.js';
9
+ import './chunk-MAK5LYRF.js';
10
10
  import './chunk-KMDLFI4P.js';
11
11
  import './chunk-QKFB4K7X.js';
12
12
  import './chunk-RSNSZ2LJ.js';
13
13
  import { installService, uninstallService, realTaskScheduler } from './chunk-RLYZLUQ7.js';
14
- import './chunk-6QRMLNH3.js';
15
- import './chunk-NPQWKGUA.js';
14
+ import './chunk-S3NYLI2P.js';
15
+ import './chunk-6Y5RUTHO.js';
16
16
  import './chunk-IP7BIBXJ.js';
17
17
  import { runnerVmOf, loadRunnerConfig } from './chunk-22RMZBGW.js';
18
18
  import './chunk-UXYLWVTQ.js';
@@ -26,14 +26,14 @@ import './chunk-4NPZVMJU.js';
26
26
  import './chunk-7RQ73DLO.js';
27
27
  import './chunk-4Q7OMKAT.js';
28
28
  import './chunk-CX22S5BA.js';
29
- import './chunk-YDSMROTB.js';
29
+ import './chunk-3NSNIIBE.js';
30
30
  import './chunk-WUYTWNMA.js';
31
31
  import './chunk-JXYVA45C.js';
32
32
  import './chunk-4KSQKQXE.js';
33
33
  import './chunk-N6LURUEF.js';
34
34
  import './chunk-YRYMNBGQ.js';
35
35
  import './chunk-WZBHBH3J.js';
36
- import './chunk-JEHRUE3F.js';
36
+ import './chunk-YZ5F4PIS.js';
37
37
  import './chunk-WTE3MQML.js';
38
38
  import './chunk-C5Y5ZJJZ.js';
39
39
  import './chunk-ZJSNLVCE.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { COMMIT_LINE, autoConnectedLine, fetchFactories, promptOnTerminal, realConnectDeps, runConnect, runConnectCommand, saveFactoryConnection, selectFactory } from './chunk-YDSMROTB.js';
3
+ export { COMMIT_LINE, autoConnectedLine, listText as factoryListText, slug as factorySlug, fetchFactories, promptOnTerminal, realConnectDeps, runConnect, runConnectCommand, saveFactoryConnection, selectFactory } from './chunk-3NSNIIBE.js';
4
4
  import './chunk-WUYTWNMA.js';
5
5
  import './chunk-JXYVA45C.js';
6
6
  import './chunk-4KSQKQXE.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { defaultGitRunner, hasSymlinkComponent } from './chunk-JEHRUE3F.js';
3
+ import { defaultGitRunner, hasSymlinkComponent } from './chunk-YZ5F4PIS.js';
4
4
  import { writeContextManifest, writePinIfChanged, touchLastCheck, clearDegraded, writeSourceCache, SOURCE_CACHE_TTL_SUCCESS_MS, writeBuildHold } from './chunk-WTE3MQML.js';
5
5
  import './chunk-C5Y5ZJJZ.js';
6
6
  import './chunk-ZJSNLVCE.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { defaultGitRunner, hasSymlinkComponent, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir } from './chunk-JEHRUE3F.js';
3
+ export { defaultGitRunner, hasSymlinkComponent, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir } from './chunk-YZ5F4PIS.js';
4
4
  import './chunk-WTE3MQML.js';
5
5
  import './chunk-C5Y5ZJJZ.js';
6
6
  import './chunk-ZJSNLVCE.js';
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-FWX735W7.js';
3
+ import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-LWSJQJC6.js';
4
4
  import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
5
5
  import { launcherCheck } from './chunk-PTW6W5NR.js';
6
6
  import './chunk-TI7B7UEO.js';
7
7
  import { RepoFilter } from './chunk-TBT347UY.js';
8
- import './chunk-CA3XMYFN.js';
9
- import { detectMachine, supportsContainerBuilds, describeMachineDocker, reachDockerStep, supportsMicroVmBuilds, microVmArchSupported, microVmAssetsPinned } from './chunk-RSPXEVDX.js';
10
- import { MIN_ENGINE_MAJOR } from './chunk-EWORLJMO.js';
8
+ import './chunk-VQYBXPI7.js';
9
+ import { detectMachine, supportsContainerBuilds, describeMachineDocker, reachDockerStep, supportsMicroVmBuilds, microVmArchSupported, microVmAssetsPinned } from './chunk-ONKJUM6R.js';
10
+ import { MIN_ENGINE_MAJOR } from './chunk-MAK5LYRF.js';
11
11
  import { resolveDevcontainerCli, spawnRun } from './chunk-KMDLFI4P.js';
12
12
  import './chunk-QKFB4K7X.js';
13
13
  import './chunk-RSNSZ2LJ.js';
14
14
  import './chunk-OZGHL5Y5.js';
15
15
  import './chunk-RLYZLUQ7.js';
16
16
  import './chunk-6MZSX4M7.js';
17
- import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-6QRMLNH3.js';
18
- import './chunk-NPQWKGUA.js';
17
+ import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-S3NYLI2P.js';
18
+ import './chunk-6Y5RUTHO.js';
19
19
  import './chunk-IP7BIBXJ.js';
20
20
  import { builtinKind } from './chunk-22RMZBGW.js';
21
21
  import { allowHostProblem, MAX_ALLOW_HOSTS } from './chunk-UXYLWVTQ.js';
@@ -27,14 +27,14 @@ import { buildxState } from './chunk-4NPZVMJU.js';
27
27
  import { parseSize } from './chunk-7RQ73DLO.js';
28
28
  import './chunk-4Q7OMKAT.js';
29
29
  import { CLAUDE_CODE_VERSION } from './chunk-CX22S5BA.js';
30
- import './chunk-YDSMROTB.js';
30
+ import './chunk-3NSNIIBE.js';
31
31
  import './chunk-WUYTWNMA.js';
32
32
  import { compareVersions } from './chunk-JXYVA45C.js';
33
33
  import './chunk-4KSQKQXE.js';
34
34
  import './chunk-N6LURUEF.js';
35
35
  import './chunk-YRYMNBGQ.js';
36
36
  import './chunk-WZBHBH3J.js';
37
- import { defaultGitRunner } from './chunk-JEHRUE3F.js';
37
+ import { defaultGitRunner } from './chunk-YZ5F4PIS.js';
38
38
  import './chunk-WTE3MQML.js';
39
39
  import './chunk-C5Y5ZJJZ.js';
40
40
  import './chunk-ZJSNLVCE.js';
@@ -403,7 +403,8 @@ async function controlPlaneAccessCheck(env, fetchImpl) {
403
403
  let sources;
404
404
  try {
405
405
  const { data } = await getJson(env.gateway.url, `/v1/context/source?repo=${encodeURIComponent(repository)}`, env.gateway.apiKey, env.gateway.appId, fetchImpl, signer);
406
- sources = data.sources ?? [];
406
+ const answer = data;
407
+ sources = answer.source === void 0 ? answer.sources ?? [] : answer.source === null ? [] : [{ repository: answer.source.repository, ref: answer.source.ref }];
407
408
  } catch (err) {
408
409
  warnings.push(`could not ask the gateway which repository governs ${repository}: ${err instanceof Error ? err.message : String(err)}`);
409
410
  continue;
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { staleBuildRefusal, staleBuildWarning, detectCi } from './chunk-U3HXXRTY.js';
3
+ import { staleBuildRefusal, staleBuildWarning, detectCi } from './chunk-NWQTTSBB.js';
4
4
  import { launchRefusalForSession } from './chunk-HHJDN6AU.js';
5
5
  import './chunk-TBT347UY.js';
6
- import { autoConnect } from './chunk-NPQWKGUA.js';
6
+ import { autoConnect } from './chunk-6Y5RUTHO.js';
7
7
  import { detectActiveSession } from './chunk-IP7BIBXJ.js';
8
8
  import './chunk-F7CU5ABH.js';
9
9
  import './chunk-BKO6JEZI.js';
10
- import './chunk-YDSMROTB.js';
10
+ import './chunk-3NSNIIBE.js';
11
11
  import { readEffectiveArtifactSpoolState, localArtifactIds, isArtifactTombstoned, artifactBlobsDir, appendArtifactRecord, artifactsSpoolPath, findPendingArtifactRecord, sanitizeTerminal, appendArtifactTombstone } from './chunk-WUYTWNMA.js';
12
12
  import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
13
13
  import './chunk-4KSQKQXE.js';
@@ -23,7 +23,7 @@ import { ARTIFACT_MAX_CAPTION_LENGTH, ArtifactCriterionIdSchema, ARTIFACT_MAX_FI
23
23
  import './chunk-EABW6AJQ.js';
24
24
  import './chunk-V7NIVOFD.js';
25
25
  import './chunk-ZM2IMMYN.js';
26
- import './chunk-6JNURGOA.js';
26
+ import './chunk-BWQ66M6N.js';
27
27
  import './chunk-XCCLFVXM.js';
28
28
  import './chunk-BJ3KTMDH.js';
29
29
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { launchRefusalForSession } from './chunk-HHJDN6AU.js';
4
- import { autoConnect } from './chunk-NPQWKGUA.js';
4
+ import { autoConnect } from './chunk-6Y5RUTHO.js';
5
5
  import { detectActiveSession } from './chunk-IP7BIBXJ.js';
6
- import './chunk-YDSMROTB.js';
6
+ import './chunk-3NSNIIBE.js';
7
7
  import './chunk-WUYTWNMA.js';
8
8
  import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
9
9
  import './chunk-4KSQKQXE.js';