@outerlayer/cli 0.14.1 → 0.16.1

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 (70) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/{agent-setup-CN2HUBEJ.js → agent-setup-K3ABU5NL.js} +8 -7
  3. package/dist/build-info.json +1 -1
  4. package/dist/{check-SRGR36KI.js → check-CNTMSGOG.js} +20 -17
  5. package/dist/{chunk-HFKKFTXU.js → chunk-2MNPHL23.js} +19 -11
  6. package/dist/{chunk-FOJGZYFC.js → chunk-42ZI52JW.js} +1 -1
  7. package/dist/{chunk-SXWS25JC.js → chunk-5FEK6PNE.js} +6 -6
  8. package/dist/{chunk-PQUM37BK.js → chunk-6JNURGOA.js} +1 -1
  9. package/dist/{chunk-SWHQ4LUM.js → chunk-6QRMLNH3.js} +21 -3
  10. package/dist/{chunk-FI5UYJMQ.js → chunk-ADJRGVZC.js} +1 -1
  11. package/dist/chunk-C5Y5ZJJZ.js +88 -0
  12. package/dist/{chunk-Q2UK3C4P.js → chunk-CA3XMYFN.js} +3 -3
  13. package/dist/{chunk-NHDVD7DU.js → chunk-EHAAPRWY.js} +13 -11
  14. package/dist/{chunk-RBKIH5ST.js → chunk-EWORLJMO.js} +19 -5
  15. package/dist/{chunk-SMHOCDCI.js → chunk-FWX735W7.js} +18 -4
  16. package/dist/{chunk-3NLOVYJQ.js → chunk-JEHRUE3F.js} +47 -22
  17. package/dist/{chunk-MTF3PHVZ.js → chunk-NBGDBTO2.js} +3 -3
  18. package/dist/{chunk-2M63GG56.js → chunk-OHVJA253.js} +1 -1
  19. package/dist/{chunk-KFRM23WD.js → chunk-ONRCEE6D.js} +2 -2
  20. package/dist/{chunk-T5VPP6H7.js → chunk-OZGHL5Y5.js} +1 -1
  21. package/dist/{chunk-ZA5CHAFY.js → chunk-POJMEEJJ.js} +21 -4
  22. package/dist/{chunk-4OGPT6I2.js → chunk-R4ZQQ7U2.js} +28 -6
  23. package/dist/{chunk-JYIEHQIF.js → chunk-RSPXEVDX.js} +1 -1
  24. package/dist/{chunk-MSASO5O4.js → chunk-U3HXXRTY.js} +1 -1
  25. package/dist/{chunk-HFKQIZXL.js → chunk-W3EKCZSQ.js} +12 -5
  26. package/dist/{chunk-LCEXHCHD.js → chunk-WTE3MQML.js} +1 -1
  27. package/dist/{cli-UW2H3UUW.js → cli-AEWH62UE.js} +61 -58
  28. package/dist/{command-5LD7G2QQ.js → command-HHPBR6CS.js} +8 -7
  29. package/dist/{context-adopt-PJUMW2EZ.js → context-adopt-VMMGFRUZ.js} +5 -4
  30. package/dist/{context-materialize-FDHYKNDT.js → context-materialize-2WXTS4CW.js} +5 -4
  31. package/dist/{doctor-H7REBSLQ.js → doctor-N6Y7HKK3.js} +11 -10
  32. package/dist/{emit-artifact-cmd-FOGNJXVR.js → emit-artifact-cmd-H5MH3AOP.js} +2 -2
  33. package/dist/{emit-cmd-ZEYWLC2C.js → emit-cmd-IJ3GVRFD.js} +4 -3
  34. package/dist/{emit-finding-cmd-DLI4MKMN.js → emit-finding-cmd-ZXDRL6PG.js} +158 -45
  35. package/dist/{emit-result-cmd-MUSL7GQA.js → emit-result-cmd-RFKALS5Z.js} +2 -2
  36. package/dist/{hook-fast-WYQD6D7T.js → hook-fast-D7HV4IXG.js} +1 -1
  37. package/dist/{import-capture-cmd-6QVCOIHK.js → import-capture-cmd-EQ35EARA.js} +3 -3
  38. package/dist/{import-ruler-cmd-KLRGRBCP.js → import-ruler-cmd-BGAZXCQM.js} +1 -1
  39. package/dist/index.js +3 -3
  40. package/dist/{init-UBXK6MF7.js → init-FBCA4DRA.js} +10 -9
  41. package/dist/{init-NTXA3SN7.js → init-MYX7YMIH.js} +10 -9
  42. package/dist/{init-cmd-NARDUPIG.js → init-cmd-CAG572UE.js} +9 -8
  43. package/dist/{init-update-O5YYFGF4.js → init-update-VDFF4K3B.js} +9 -8
  44. package/dist/{loop-SW2M5VDD.js → loop-75J4YXLZ.js} +17 -16
  45. package/dist/{machine-U66FKVDP.js → machine-A6ZCTUGS.js} +8 -7
  46. package/dist/{runner-env-XTC53CHN.js → runner-env-EN7YE7QX.js} +1 -1
  47. package/dist/{runner-key-3JSMDRJA.js → runner-key-W25ISHI3.js} +10 -9
  48. package/dist/{session-sender-4M247XSV.js → session-sender-24L5EW25.js} +3 -3
  49. package/dist/{starter-pack-IB4UUIX3.js → starter-pack-KF66HGZR.js} +3 -3
  50. package/dist/{status-STZYPU3W.js → status-XHSGEYO5.js} +11 -10
  51. package/dist/{sync-cmd-UWD5JOFU.js → sync-cmd-5G5EIEHD.js} +2 -2
  52. package/dist/{watch-DBNB7R6X.js → watch-UTOXO4SE.js} +2 -2
  53. package/dist/{work-claim-cmd-LY4U6QHN.js → work-claim-cmd-RKHYFE5Y.js} +4 -4
  54. package/dist/{work-cmd-RVRQ32EH.js → work-cmd-DJQJEZVB.js} +1 -1
  55. package/dist/{work-comment-cmd-FFUM4TJU.js → work-comment-cmd-A55CUSYE.js} +1 -1
  56. package/dist/{work-open-pr-cmd-HLDWP4T2.js → work-open-pr-cmd-E6O53IJD.js} +1 -1
  57. package/package.json +1 -1
  58. package/skill-pack/maintained/{amend → outerlayer-amend}/SKILL.md +2 -2
  59. package/skill-pack/maintained/{outerlayer → outerlayer-cli}/SKILL.md +3 -3
  60. package/skill-pack/maintained/{emitting-evidence → outerlayer-evidence}/SKILL.md +1 -1
  61. package/skill-pack/maintained/{reporting-findings → outerlayer-findings}/SKILL.md +24 -30
  62. package/skill-pack/shipped.json +10 -1
  63. package/skill-pack/template/build/SKILL.md +5 -1
  64. package/skill-pack/template/build/references/agent-briefs.md +7 -1
  65. package/skill-pack/template/build/references/evidence.md +1 -1
  66. package/skill-pack/template/build/references/release.md +1 -1
  67. package/skill-pack/template/build/references/review-briefs.md +6 -0
  68. package/skill-pack/template/writing-specs/SKILL.md +1 -1
  69. /package/skill-pack/maintained/{outerlayer → outerlayer-cli}/references/open-pull-request.md +0 -0
  70. /package/skill-pack/maintained/{emitting-evidence → outerlayer-evidence}/references/agents-snippet.md +0 -0
@@ -1,14 +1,14 @@
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-HFKQIZXL.js';
4
- import './chunk-MTF3PHVZ.js';
5
- import './chunk-SWHQ4LUM.js';
3
+ import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-W3EKCZSQ.js';
4
+ import './chunk-NBGDBTO2.js';
5
+ import './chunk-6QRMLNH3.js';
6
6
  import './chunk-NPQWKGUA.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
- import './chunk-FOJGZYFC.js';
11
+ import './chunk-42ZI52JW.js';
12
12
  import './chunk-YDSMROTB.js';
13
13
  import './chunk-WUYTWNMA.js';
14
14
  import './chunk-JXYVA45C.js';
@@ -17,17 +17,18 @@ import './chunk-N6LURUEF.js';
17
17
  import { C, NO_COLOR_FLAG, warnDeprecated, stripNoColor, API_KEY_FLAG_DEPRECATION } from './chunk-YRYMNBGQ.js';
18
18
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
19
19
  import { settingsPath, readSettings, SettingsParseError, listHookCandidates, wrapHooks, writeSettings, unwrapHooks, REGISTERED_EVENTS, cliCommand, removeHooks, removeStatusline, cliBinResolvable, mergeHooks, repointWrappedHooks, AUTO_WRAP_EVENTS, mergeStatusline } from './chunk-5QRP3MVS.js';
20
- import { pinExists } from './chunk-LCEXHCHD.js';
20
+ import { pinExists } from './chunk-WTE3MQML.js';
21
+ import './chunk-C5Y5ZJJZ.js';
21
22
  import './chunk-YO4PSLVB.js';
22
- import './chunk-ZA5CHAFY.js';
23
- import './chunk-2M63GG56.js';
23
+ import './chunk-POJMEEJJ.js';
24
+ import './chunk-OHVJA253.js';
24
25
  import './chunk-PLMTLGYH.js';
25
26
  import './chunk-J5M7BSJQ.js';
26
27
  import './chunk-EABW6AJQ.js';
27
28
  import { resolveVersion } from './chunk-RA3O54FC.js';
28
29
  import './chunk-V7NIVOFD.js';
29
30
  import './chunk-ZM2IMMYN.js';
30
- import { hookFiredMarkerPath, installedCliDistDir } from './chunk-PQUM37BK.js';
31
+ import { hookFiredMarkerPath, installedCliDistDir } from './chunk-6JNURGOA.js';
31
32
  import { managedHookScripts, removeJournalHooks, installPreCommitGuardHook, removePreCommitGuardHook } from './chunk-XCCLFVXM.js';
32
33
  import './chunk-BJ3KTMDH.js';
33
34
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -3645,7 +3646,7 @@ function warnIfApiKeyFlag(opts) {
3645
3646
  if (opts.apiKey !== void 0) warnDeprecated(API_KEY_FLAG_DEPRECATION);
3646
3647
  }
3647
3648
  async function installStarterPackInRepo() {
3648
- const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-IB4UUIX3.js');
3649
+ const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-KF66HGZR.js');
3649
3650
  const cwd = process.cwd();
3650
3651
  let repoRoot = cwd;
3651
3652
  try {
@@ -3827,7 +3828,7 @@ function buildProgram(argv = process.argv) {
3827
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"
3828
3829
  ).action(async (opts) => {
3829
3830
  if (opts.update || opts.dryRun) {
3830
- const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-O5YYFGF4.js');
3831
+ const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-VDFF4K3B.js');
3831
3832
  const problem = updateFlagProblem(opts);
3832
3833
  if (problem !== void 0) {
3833
3834
  fail(problem);
@@ -3841,7 +3842,7 @@ function buildProgram(argv = process.argv) {
3841
3842
  }
3842
3843
  let starterTemplate;
3843
3844
  if (opts.template !== void 0) {
3844
- const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-IB4UUIX3.js');
3845
+ const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-KF66HGZR.js');
3845
3846
  try {
3846
3847
  assertKnownTemplate(opts.template);
3847
3848
  } catch (err) {
@@ -3872,7 +3873,7 @@ function buildProgram(argv = process.argv) {
3872
3873
  else process.stdout.write(outcome.text);
3873
3874
  return;
3874
3875
  }
3875
- const { runInitCommand } = await import('./init-cmd-NARDUPIG.js');
3876
+ const { runInitCommand } = await import('./init-cmd-CAG572UE.js');
3876
3877
  const code = await runInitCommand(
3877
3878
  { json: opts.json, factory: opts.factory },
3878
3879
  {
@@ -3884,7 +3885,7 @@ function buildProgram(argv = process.argv) {
3884
3885
  return { ok, text, detail };
3885
3886
  },
3886
3887
  runAgentSetup: async () => {
3887
- const { runAgentSetup } = await import('./agent-setup-CN2HUBEJ.js');
3888
+ const { runAgentSetup } = await import('./agent-setup-K3ABU5NL.js');
3888
3889
  return runAgentSetup({ cwd: process.cwd() });
3889
3890
  },
3890
3891
  runDoctorChecks: gatherDoctorChecks
@@ -3944,7 +3945,7 @@ function buildProgram(argv = process.argv) {
3944
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"
3945
3946
  ).action(async (opts) => {
3946
3947
  warnIfApiKeyFlag(opts);
3947
- const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-UWD5JOFU.js');
3948
+ const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-5G5EIEHD.js');
3948
3949
  try {
3949
3950
  const result = await runSync({
3950
3951
  url: opts.url,
@@ -3973,7 +3974,7 @@ function buildProgram(argv = process.argv) {
3973
3974
  if (invokedCommandToken(argv) === "watch") {
3974
3975
  warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
3975
3976
  }
3976
- const { runWatch } = await import('./watch-DBNB7R6X.js');
3977
+ const { runWatch } = await import('./watch-UTOXO4SE.js');
3977
3978
  await runWatch({ once: opts.once });
3978
3979
  });
3979
3980
  program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
@@ -4027,7 +4028,7 @@ function buildProgram(argv = process.argv) {
4027
4028
  }
4028
4029
  });
4029
4030
  program2.command("session-sender", { hidden: true }).description("stream a runner build's sessions to its work item while the build runs").action(async () => {
4030
- const { runSessionSender } = await import('./session-sender-4M247XSV.js');
4031
+ const { runSessionSender } = await import('./session-sender-24L5EW25.js');
4031
4032
  try {
4032
4033
  await runSessionSender();
4033
4034
  } catch (err) {
@@ -4062,7 +4063,7 @@ async function runCli(processArgv) {
4062
4063
  await buildProgram(argv).parseAsync(argv);
4063
4064
  }
4064
4065
  async function compileContext(opts) {
4065
- const { runEmit, EmitError } = await import('./emit-cmd-ZEYWLC2C.js');
4066
+ const { runEmit, EmitError } = await import('./emit-cmd-IJ3GVRFD.js');
4066
4067
  try {
4067
4068
  const result = runEmit({ cwd: opts.dir, check: opts.check, json: opts.json });
4068
4069
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
@@ -4085,7 +4086,7 @@ function registerEmitCommands(program2) {
4085
4086
  return;
4086
4087
  }
4087
4088
  warnIfApiKeyFlag(opts);
4088
- const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-MUSL7GQA.js');
4089
+ const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-RFKALS5Z.js');
4089
4090
  try {
4090
4091
  const result = await runEmitResult({
4091
4092
  name,
@@ -4136,7 +4137,7 @@ locally so it never uploads. One correction can retire several duplicates.
4136
4137
  `
4137
4138
  ).action(async (file, opts) => {
4138
4139
  warnIfApiKeyFlag(opts);
4139
- const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-FOGNJXVR.js');
4140
+ const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-H5MH3AOP.js');
4140
4141
  let pr;
4141
4142
  if (opts.pr !== void 0) {
4142
4143
  pr = parseTrackerNumber(opts.pr);
@@ -4166,12 +4167,12 @@ locally so it never uploads. One correction can retire several duplicates.
4166
4167
  throw err;
4167
4168
  }
4168
4169
  });
4169
- emitCmd.command("finding").description("Record one finding: a problem you hit in the factory").requiredOption("--id <id>", "client id \u2014 re-emitting the same id replaces it").option("--category <context|flaky-test|tooling|environment|defect|other>", "what kind of problem this is").requiredOption("--title <text>", "one sentence").requiredOption("--file <path>", "the file the problem is in, or the instruction's own path").option("--line <number>", "line number in --file").option("--rule-path <path>", "the instruction's own path \u2014 required for a context finding").option("--rule-line <number>", "line number in --rule-path").option("--rule-quote <text>", "the instruction's quoted sentence \u2014 required unless --rule-relation is missing").option("--rule-relation <wrong|broken|missing>", "how the instruction fails \u2014 required for a context finding").requiredOption("--where <label>", 'where this was recorded, e.g. "build session"').option("--detail <text>", "what happened, a few paragraphs").option("--cause <text>", 'what is actually wrong, or "unknown"').option("--suggestion <text>", "what would help").option("--command <text>", "the command that misbehaved").option("--error <text>", "the first error line").option("--test <name>", "the test name, for a flaky test").option("--symbol <name>", "the function the problem is in, for a defect").option("--started-at <event>", "event id where you first hit the problem (ids are listed when you omit this)").option("--ended-at <event>", "event id where you got past it").option("--problem <id>", "a problem this finding reports; repeat for each one (needs --link-reason)", (value, previous = []) => [...previous, value]).option("--link-reason <text>", "why the finding reports each --problem").option("--new", "record a new problem instead of linking an existing one").option("--trace-id <id>", "the session's trace id, when there is one").option("--turn <number>", "turn index within the session").option("--round <number>", "round number, when there is one").addOption(new Option("--subject <value>").hideHelp()).addOption(new Option("--kind <value>").hideHelp()).addOption(new Option("--severity <value>").hideHelp()).addOption(new Option("--verdict <value>").hideHelp()).addOption(new Option("--fixed").hideHelp()).addOption(new Option("--source <value>").hideHelp()).option("--head-sha <sha>", "the commit this batch was recorded against").option("--context-source-sha <sha>", "the context-source commit this batch was recorded against").option("--item <number>", "work item to record on directly, by its number in this factory").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)").addHelpText(
4170
+ emitCmd.command("finding").description("Record one finding: a problem you hit in the factory").requiredOption("--id <id>", "client id \u2014 re-emitting the same id replaces it").option("--category <context|flaky-test|tooling|environment|defect|other>", "what kind of problem this is").requiredOption("--title <text>", "one sentence").requiredOption("--file <path>", "the file the problem is in, or the instruction's own path").option("--line <number>", "line number in --file").option("--rule-path <path>", "the instruction's own path \u2014 required for a context finding").option("--rule-line <number>", "line number in --rule-path").option("--rule-quote <text>", "the instruction's quoted sentence \u2014 required unless --rule-relation is missing").option("--rule-relation <wrong|broken|missing>", "how the instruction fails \u2014 required for a context finding").requiredOption("--where <label>", 'where this was recorded, e.g. "build session"').option("--detail <text>", "what happened, a few paragraphs").option("--cause <text>", 'what is actually wrong, or "unknown"').option("--suggestion <text>", "what would help").option("--command <text>", "the command that misbehaved").option("--error <text>", "the first error line").option("--test <name>", "the test name, for a flaky test").option("--symbol <name>", "the function the problem is in, for a defect").option("--started-at <event>", "event id where you hit the problem (default: first output showing --error)").option("--ended-at <event>", "event id where you got past it (default: the newest event)").option("--untimed", "record no time, only when the problem cost none in this session").option("--find <text>", "list this session's events that contain the text, and record nothing").option("--problem <id>", "a problem this finding reports; repeat for each one (needs --link-reason)", (value, previous = []) => [...previous, value]).option("--link-reason <text>", "why the finding reports each --problem").option("--new", "record a new problem instead of linking an existing one").option("--trace-id <id>", "the session's trace id, when there is one").option("--turn <number>", "turn index within the session").option("--round <number>", "round number, when there is one").addOption(new Option("--subject <value>").hideHelp()).addOption(new Option("--kind <value>").hideHelp()).addOption(new Option("--severity <value>").hideHelp()).addOption(new Option("--verdict <value>").hideHelp()).addOption(new Option("--fixed").hideHelp()).addOption(new Option("--source <value>").hideHelp()).option("--head-sha <sha>", "the commit this batch was recorded against").option("--context-source-sha <sha>", "the context-source commit this batch was recorded against").option("--item <number>", "work item to record on directly, by its number in this factory").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)").addHelpText(
4170
4171
  "after",
4171
- '\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.\nWithout --started-at and --ended-at it lists your recent session events with\nids and times; name the event where you hit the problem and the one where\nyou got past it to record the time it cost.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically.\n'
4172
+ '\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'
4172
4173
  ).action(async (opts) => {
4173
4174
  warnIfApiKeyFlag(opts);
4174
- const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-DLI4MKMN.js');
4175
+ const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-ZXDRL6PG.js');
4175
4176
  try {
4176
4177
  refuseRemovedFindingFlags(opts);
4177
4178
  const result = await runEmitFinding({
@@ -4194,6 +4195,8 @@ locally so it never uploads. One correction can retire several duplicates.
4194
4195
  symbol: opts.symbol,
4195
4196
  startedAt: opts.startedAt,
4196
4197
  endedAt: opts.endedAt,
4198
+ untimed: opts.untimed,
4199
+ find: opts.find,
4197
4200
  problem: opts.problem,
4198
4201
  linkReason: opts.linkReason,
4199
4202
  new: opts.new,
@@ -4219,10 +4222,10 @@ locally so it never uploads. One correction can retire several duplicates.
4219
4222
  });
4220
4223
  emitCmd.command("findings <file>").description("Record a batch of findings from a FindingBatch JSON file (- for standard input)").option("--item <number>", "work item to record on directly, by its number in this factory").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)").addHelpText(
4221
4224
  "after",
4222
- "\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.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n"
4225
+ '\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'
4223
4226
  ).action(async (file, opts) => {
4224
4227
  warnIfApiKeyFlag(opts);
4225
- const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-DLI4MKMN.js');
4228
+ const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-ZXDRL6PG.js');
4226
4229
  try {
4227
4230
  const result = await runEmitFindings({
4228
4231
  file,
@@ -4289,7 +4292,7 @@ function registerWorkCommands(program2) {
4289
4292
  "\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"
4290
4293
  ).action(async (opts) => {
4291
4294
  warnIfApiKeyFlag(opts);
4292
- const { runWorkBuild, WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4295
+ const { runWorkBuild, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4293
4296
  try {
4294
4297
  await runWorkBuild(opts);
4295
4298
  } catch (err) {
@@ -4305,7 +4308,7 @@ function registerWorkCommands(program2) {
4305
4308
  "\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"
4306
4309
  ).action(async (number, opts) => {
4307
4310
  warnIfApiKeyFlag(opts);
4308
- const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4311
+ const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4309
4312
  try {
4310
4313
  await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
4311
4314
  } catch (err) {
@@ -4330,8 +4333,8 @@ most one action flag may be given.
4330
4333
  `
4331
4334
  ).action(async (opts) => {
4332
4335
  warnIfApiKeyFlag(opts);
4333
- const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-FFUM4TJU.js');
4334
- const { WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4336
+ const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-A55CUSYE.js');
4337
+ const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4335
4338
  try {
4336
4339
  await runWorkComment(opts);
4337
4340
  } catch (err) {
@@ -4347,8 +4350,8 @@ most one action flag may be given.
4347
4350
  "\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"
4348
4351
  ).action(async (opts) => {
4349
4352
  warnIfApiKeyFlag(opts);
4350
- const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-FFUM4TJU.js');
4351
- const { WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4353
+ const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-A55CUSYE.js');
4354
+ const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4352
4355
  try {
4353
4356
  await runWorkThreads(opts);
4354
4357
  } catch (err) {
@@ -4370,7 +4373,7 @@ live addition remains on it.
4370
4373
  `
4371
4374
  ).action(async (opts) => {
4372
4375
  warnIfApiKeyFlag(opts);
4373
- const { runWorkRemove, WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4376
+ const { runWorkRemove, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4374
4377
  try {
4375
4378
  await runWorkRemove(opts);
4376
4379
  } catch (err) {
@@ -4383,7 +4386,7 @@ live addition remains on it.
4383
4386
  });
4384
4387
  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) => {
4385
4388
  warnIfApiKeyFlag(opts);
4386
- const { runWorkStatus, WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4389
+ const { runWorkStatus, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4387
4390
  try {
4388
4391
  await runWorkStatus(opts);
4389
4392
  } catch (err) {
@@ -4396,7 +4399,7 @@ live addition remains on it.
4396
4399
  });
4397
4400
  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) => {
4398
4401
  warnIfApiKeyFlag(opts);
4399
- const { runWorkList, WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4402
+ const { runWorkList, WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4400
4403
  try {
4401
4404
  await runWorkList(opts);
4402
4405
  } catch (err) {
@@ -4412,7 +4415,7 @@ live addition remains on it.
4412
4415
  "\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"
4413
4416
  ).action(async (opts) => {
4414
4417
  warnIfApiKeyFlag(opts);
4415
- const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-LY4U6QHN.js');
4418
+ const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4416
4419
  try {
4417
4420
  await runWorkClaim(opts);
4418
4421
  } catch (err) {
@@ -4428,7 +4431,7 @@ live addition remains on it.
4428
4431
  "\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"
4429
4432
  ).action(async (opts) => {
4430
4433
  warnIfApiKeyFlag(opts);
4431
- const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-LY4U6QHN.js');
4434
+ const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4432
4435
  try {
4433
4436
  await runWorkRenew(opts);
4434
4437
  } catch (err) {
@@ -4447,7 +4450,7 @@ live addition remains on it.
4447
4450
  "\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"
4448
4451
  ).action(async (opts) => {
4449
4452
  warnIfApiKeyFlag(opts);
4450
- const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-LY4U6QHN.js');
4453
+ const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-RKHYFE5Y.js');
4451
4454
  try {
4452
4455
  await runWorkRelease(opts);
4453
4456
  } catch (err) {
@@ -4479,8 +4482,8 @@ live addition remains on it.
4479
4482
  '\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'
4480
4483
  ).action(async (opts) => {
4481
4484
  warnIfApiKeyFlag(opts);
4482
- const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-HLDWP4T2.js');
4483
- const { WorkCommandError } = await import('./work-cmd-RVRQ32EH.js');
4485
+ const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-E6O53IJD.js');
4486
+ const { WorkCommandError } = await import('./work-cmd-DJQJEZVB.js');
4484
4487
  try {
4485
4488
  await runWorkOpenPr(opts);
4486
4489
  } catch (err) {
@@ -4497,7 +4500,7 @@ function registerRunnerCommands(program2) {
4497
4500
  const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
4498
4501
  runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
4499
4502
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
4500
- const { start, RunnerStartError } = await import('./loop-SW2M5VDD.js');
4503
+ const { start, RunnerStartError } = await import('./loop-75J4YXLZ.js');
4501
4504
  const { RunnerAlreadyRunningError } = await import('./pidfile-UZRH774M.js');
4502
4505
  const configPath = opts.config ?? defaultRunnerConfigPath();
4503
4506
  try {
@@ -4513,7 +4516,7 @@ function registerRunnerCommands(program2) {
4513
4516
  });
4514
4517
  runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
4515
4518
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4516
- const { runRunnerCheck } = await import('./check-SRGR36KI.js');
4519
+ const { runRunnerCheck } = await import('./check-CNTMSGOG.js');
4517
4520
  const configPath = opts.config ?? defaultRunnerConfigPath();
4518
4521
  const result = await runRunnerCheck(configPath);
4519
4522
  if (!result.ok) {
@@ -4542,7 +4545,7 @@ function registerRunnerCommands(program2) {
4542
4545
  }
4543
4546
  try {
4544
4547
  if (opts.service === true) {
4545
- const { installServiceCommand } = await import('./command-5LD7G2QQ.js');
4548
+ const { installServiceCommand } = await import('./command-HHPBR6CS.js');
4546
4549
  const result2 = await installServiceCommand({
4547
4550
  configPath,
4548
4551
  print: opts.print,
@@ -4598,7 +4601,7 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
4598
4601
  return;
4599
4602
  }
4600
4603
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4601
- const { uninstallServiceCommand } = await import('./command-5LD7G2QQ.js');
4604
+ const { uninstallServiceCommand } = await import('./command-HHPBR6CS.js');
4602
4605
  const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
4603
4606
  if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
4604
4607
  `);
@@ -4609,11 +4612,11 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
4609
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"
4610
4613
  ).action(async (opts) => {
4611
4614
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
4612
- const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-NTXA3SN7.js');
4613
- const { createRunnerKey, runnerKeyLogin } = await import('./runner-key-3JSMDRJA.js');
4614
- const { detectMachine } = await import('./machine-U66FKVDP.js');
4615
- const { chooseVm, runVmInit, VmInitError } = await import('./init-UBXK6MF7.js');
4616
- const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-XTC53CHN.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');
4619
+ const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-EN7YE7QX.js');
4617
4620
  const configPath = opts.config ?? defaultRunnerConfigPath();
4618
4621
  if (opts.agent !== void 0 && !isAgentName(opts.agent)) {
4619
4622
  fail(`--agent ${opts.agent}: runner init writes commands for ${Object.keys(AGENT_COMMANDS).join(", ")}. For another agent, leave --agent out and edit runner.commands.`);
@@ -4762,7 +4765,7 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
4762
4765
  let serviceUp = false;
4763
4766
  let restart;
4764
4767
  if (installedLayout) {
4765
- const { installServiceCommand } = await import('./command-5LD7G2QQ.js');
4768
+ const { installServiceCommand } = await import('./command-HHPBR6CS.js');
4766
4769
  const service = await installServiceCommand({
4767
4770
  configPath,
4768
4771
  entryPath: process.argv[1] ?? "",
@@ -4873,15 +4876,15 @@ Next:
4873
4876
  });
4874
4877
  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) => {
4875
4878
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4876
- const { requestStop } = await import('./loop-SW2M5VDD.js');
4879
+ const { requestStop } = await import('./loop-75J4YXLZ.js');
4877
4880
  const configPath = opts.config ?? defaultRunnerConfigPath();
4878
4881
  await requestStop(configPath, Boolean(opts.now));
4879
4882
  });
4880
4883
  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) => {
4881
4884
  const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-N3C6DFQA.js');
4882
4885
  const { jobsDir, runnerDir } = await import('./paths-OYKMVYJP.js');
4883
- const { listJobFiles, runnerProcessState } = await import('./loop-SW2M5VDD.js');
4884
- const { renderStatus } = await import('./status-STZYPU3W.js');
4886
+ const { listJobFiles, runnerProcessState } = await import('./loop-75J4YXLZ.js');
4887
+ const { renderStatus } = await import('./status-XHSGEYO5.js');
4885
4888
  const { readHousekeepingRecord } = await import('./record-C43U4PKS.js');
4886
4889
  const path2 = await import('path');
4887
4890
  const configPath = opts.config ?? defaultRunnerConfigPath();
@@ -4937,7 +4940,7 @@ Next:
4937
4940
  });
4938
4941
  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) => {
4939
4942
  const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
4940
- const { listJobFiles } = await import('./loop-SW2M5VDD.js');
4943
+ const { listJobFiles } = await import('./loop-75J4YXLZ.js');
4941
4944
  const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-H55NWW4H.js');
4942
4945
  const configPath = opts.config ?? defaultRunnerConfigPath();
4943
4946
  const item = parseTrackerNumber(itemArg);
@@ -5194,7 +5197,7 @@ function registerMcpCommands(program2) {
5194
5197
  function registerImportCommands(program2) {
5195
5198
  const importCmd = program2.command("import").description("Import an existing config format into .outerlayer/");
5196
5199
  importCmd.command("ruler").description("Port a .ruler/ tree into the equivalent .outerlayer/ tree").option("--dir <path>", "repo root to read from (default: cwd)").option("--json", "machine-readable JSON output").addHelpText("after", "\nRuler: https://github.com/intellectronica/ruler. Mostly a rename.\n").action(async (opts) => {
5197
- const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-KLRGRBCP.js');
5200
+ const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-BGAZXCQM.js');
5198
5201
  try {
5199
5202
  const result = runImportRuler({ cwd: opts.dir, json: opts.json });
5200
5203
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
@@ -5208,9 +5211,9 @@ function registerImportCommands(program2) {
5208
5211
  });
5209
5212
  importCmd.command("capture").description("Install the maintained skills into .outerlayer/").option("--dir <path>", "repo root to write into (default: cwd)").option("--json", "machine-readable JSON output").addHelpText(
5210
5213
  "after",
5211
- "\nInstalls the four maintained skills (emitting-evidence, amend,\nreporting-findings, outerlayer) and an AGENTS.md snippet teaching agents to run\n`emit artifact`. A skill that differs from this CLI's bundle is rewritten to it, and the output says so.\n"
5214
+ "\nInstalls the four maintained skills (outerlayer-evidence, outerlayer-amend,\nouterlayer-findings, outerlayer-cli) and an AGENTS.md snippet teaching agents to run\n`emit artifact`. A skill that differs from this CLI's bundle is rewritten to it, and the output says so.\n"
5212
5215
  ).action(async (opts) => {
5213
- const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-6QVCOIHK.js');
5216
+ const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-EQ35EARA.js');
5214
5217
  try {
5215
5218
  runImportCapture({ cwd: opts.dir, json: opts.json });
5216
5219
  } catch (err) {
@@ -5248,12 +5251,12 @@ function registerContextCommands(program2) {
5248
5251
  const contextCmd = program2.command("context").description("Compile and materialize agent context");
5249
5252
  contextCmd.command("emit").description("Compile .outerlayer/ into each configured target tool's native files").option("--check", "compare against disk, write nothing, exit 1 on drift (CI mode)").option("--dir <path>", "repo root to read from (default: cwd)").option("--json", "machine-readable JSON output").addHelpText(
5250
5253
  "after",
5251
- '\nTargets come from .outerlayer/config.json only; there is no --target flag.\nMissing or empty config: {"targets": [...]}, e.g. {"targets": ["claude-code"]}.\nKnown targets: claude-code, cursor, codex, copilot, factory.\n\nThe maintained skills (emitting-evidence, amend, reporting-findings, outerlayer)\nfollow this CLI: emit rewrites one that differs from its bundle, and --check reports it as\ndrift. Templates (spec, writing-specs, writing-tests, build) are never rewritten or reported.\n\nOrphan detection (--check) only covers header-carrying outputs: every markdown\ntarget file gets a generated-by comment, but .mcp.json and .cursor/mcp.json are\nJSON with no comment syntax, so they can never be flagged as orphaned; missing\nand content drift still apply to them.\n'
5254
+ '\nTargets come from .outerlayer/config.json only; there is no --target flag.\nMissing or empty config: {"targets": [...]}, e.g. {"targets": ["claude-code"]}.\nKnown targets: claude-code, cursor, codex, copilot, factory.\n\nThe maintained skills (outerlayer-evidence, outerlayer-amend, outerlayer-findings,\nouterlayer-cli) follow this CLI: emit rewrites one that differs from its bundle, and --check\nreports it as drift. A copy under an earlier name (amend, emitting-evidence,\nreporting-findings, outerlayer) is deleted, and --check reports it as retired.\nTemplates (spec, writing-specs, writing-tests, build) are never rewritten or reported.\n\nOrphan detection (--check) only covers header-carrying outputs: every markdown\ntarget file gets a generated-by comment, but .mcp.json and .cursor/mcp.json are\nJSON with no comment syntax, so they can never be flagged as orphaned; missing\nand content drift still apply to them.\n'
5252
5255
  ).action(async (opts) => {
5253
5256
  await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
5254
5257
  });
5255
5258
  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) => {
5256
- const { runContextAdopt } = await import('./context-adopt-PJUMW2EZ.js');
5259
+ const { runContextAdopt } = await import('./context-adopt-VMMGFRUZ.js');
5257
5260
  const { exitCode, stdout } = runContextAdopt(stagedDir, process.cwd());
5258
5261
  process.stdout.write(stdout);
5259
5262
  process.exitCode = exitCode;
@@ -5262,7 +5265,7 @@ function registerContextCommands(program2) {
5262
5265
  "after",
5263
5266
  "\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"
5264
5267
  ).action(async (opts) => {
5265
- const { materializeContext } = await import('./context-materialize-FDHYKNDT.js');
5268
+ const { materializeContext } = await import('./context-materialize-2WXTS4CW.js');
5266
5269
  const result = await materializeContext({ cwd: process.cwd(), sessionId: `manual-${Date.now()}` });
5267
5270
  const output = formatContextMaterializeOutput(result);
5268
5271
  if (output.exitCode !== void 0) process.exitCode = output.exitCode;
@@ -5,13 +5,13 @@ 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-JYIEHQIF.js';
9
- import './chunk-RBKIH5ST.js';
8
+ import { detectMachine } from './chunk-RSPXEVDX.js';
9
+ import './chunk-EWORLJMO.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-SWHQ4LUM.js';
14
+ import './chunk-6QRMLNH3.js';
15
15
  import './chunk-NPQWKGUA.js';
16
16
  import './chunk-IP7BIBXJ.js';
17
17
  import { runnerVmOf, loadRunnerConfig } from './chunk-22RMZBGW.js';
@@ -33,13 +33,14 @@ 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-3NLOVYJQ.js';
37
- import './chunk-LCEXHCHD.js';
36
+ import './chunk-JEHRUE3F.js';
37
+ import './chunk-WTE3MQML.js';
38
+ import './chunk-C5Y5ZJJZ.js';
38
39
  import './chunk-ZJSNLVCE.js';
39
40
  import './chunk-YO4PSLVB.js';
40
41
  import './chunk-BYT5O5RV.js';
41
- import './chunk-ZA5CHAFY.js';
42
- import './chunk-2M63GG56.js';
42
+ import './chunk-POJMEEJJ.js';
43
+ import './chunk-OHVJA253.js';
43
44
  import './chunk-PLMTLGYH.js';
44
45
  import './chunk-J5M7BSJQ.js';
45
46
  import './chunk-EABW6AJQ.js';
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { defaultGitRunner, hasSymlinkComponent } from './chunk-3NLOVYJQ.js';
4
- import { writeContextManifest, writePinIfChanged, touchLastCheck, clearDegraded, writeSourceCache, SOURCE_CACHE_TTL_SUCCESS_MS, writeBuildHold } from './chunk-LCEXHCHD.js';
3
+ import { defaultGitRunner, hasSymlinkComponent } from './chunk-JEHRUE3F.js';
4
+ import { writeContextManifest, writePinIfChanged, touchLastCheck, clearDegraded, writeSourceCache, SOURCE_CACHE_TTL_SUCCESS_MS, writeBuildHold } from './chunk-WTE3MQML.js';
5
+ import './chunk-C5Y5ZJJZ.js';
5
6
  import './chunk-ZJSNLVCE.js';
6
7
  import './chunk-YO4PSLVB.js';
7
8
  import './chunk-BYT5O5RV.js';
8
- import './chunk-ZA5CHAFY.js';
9
- import './chunk-2M63GG56.js';
9
+ import './chunk-POJMEEJJ.js';
10
+ import './chunk-OHVJA253.js';
10
11
  import './chunk-PLMTLGYH.js';
11
12
  import './chunk-J5M7BSJQ.js';
12
13
  import './chunk-EABW6AJQ.js';
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { defaultGitRunner, hasSymlinkComponent, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir } from './chunk-3NLOVYJQ.js';
4
- import './chunk-LCEXHCHD.js';
3
+ export { defaultGitRunner, hasSymlinkComponent, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir } from './chunk-JEHRUE3F.js';
4
+ import './chunk-WTE3MQML.js';
5
+ import './chunk-C5Y5ZJJZ.js';
5
6
  import './chunk-ZJSNLVCE.js';
6
7
  import './chunk-YO4PSLVB.js';
7
8
  import './chunk-BYT5O5RV.js';
8
- import './chunk-ZA5CHAFY.js';
9
- import './chunk-2M63GG56.js';
9
+ import './chunk-POJMEEJJ.js';
10
+ import './chunk-OHVJA253.js';
10
11
  import './chunk-PLMTLGYH.js';
11
12
  import './chunk-J5M7BSJQ.js';
12
13
  import './chunk-EABW6AJQ.js';
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-SMHOCDCI.js';
3
+ import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-FWX735W7.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-Q2UK3C4P.js';
9
- import { detectMachine, supportsContainerBuilds, describeMachineDocker, reachDockerStep, supportsMicroVmBuilds, microVmArchSupported, microVmAssetsPinned } from './chunk-JYIEHQIF.js';
10
- import { MIN_ENGINE_MAJOR } from './chunk-RBKIH5ST.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';
11
11
  import { resolveDevcontainerCli, spawnRun } from './chunk-KMDLFI4P.js';
12
12
  import './chunk-QKFB4K7X.js';
13
13
  import './chunk-RSNSZ2LJ.js';
14
- import './chunk-T5VPP6H7.js';
14
+ import './chunk-OZGHL5Y5.js';
15
15
  import './chunk-RLYZLUQ7.js';
16
16
  import './chunk-6MZSX4M7.js';
17
- import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-SWHQ4LUM.js';
17
+ import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-6QRMLNH3.js';
18
18
  import './chunk-NPQWKGUA.js';
19
19
  import './chunk-IP7BIBXJ.js';
20
20
  import { builtinKind } from './chunk-22RMZBGW.js';
@@ -34,13 +34,14 @@ 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-3NLOVYJQ.js';
38
- import './chunk-LCEXHCHD.js';
37
+ import { defaultGitRunner } from './chunk-JEHRUE3F.js';
38
+ import './chunk-WTE3MQML.js';
39
+ import './chunk-C5Y5ZJJZ.js';
39
40
  import './chunk-ZJSNLVCE.js';
40
41
  import { defaultFetch } from './chunk-YO4PSLVB.js';
41
42
  import './chunk-BYT5O5RV.js';
42
- import './chunk-ZA5CHAFY.js';
43
- import './chunk-2M63GG56.js';
43
+ import './chunk-POJMEEJJ.js';
44
+ import './chunk-OHVJA253.js';
44
45
  import './chunk-PLMTLGYH.js';
45
46
  import './chunk-J5M7BSJQ.js';
46
47
  import './chunk-EABW6AJQ.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { staleBuildRefusal, staleBuildWarning, detectCi } from './chunk-MSASO5O4.js';
3
+ import { staleBuildRefusal, staleBuildWarning, detectCi } from './chunk-U3HXXRTY.js';
4
4
  import { launchRefusalForSession } from './chunk-HHJDN6AU.js';
5
5
  import './chunk-TBT347UY.js';
6
6
  import { autoConnect } from './chunk-NPQWKGUA.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-PQUM37BK.js';
26
+ import './chunk-6JNURGOA.js';
27
27
  import './chunk-XCCLFVXM.js';
28
28
  import './chunk-BJ3KTMDH.js';
29
29
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { EmitError, runEmit } from './chunk-HFKKFTXU.js';
3
+ export { EmitError, runEmit } from './chunk-2MNPHL23.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
- import './chunk-ZA5CHAFY.js';
6
- import './chunk-2M63GG56.js';
5
+ import './chunk-C5Y5ZJJZ.js';
6
+ import './chunk-POJMEEJJ.js';
7
+ import './chunk-OHVJA253.js';
7
8
  import './chunk-J5M7BSJQ.js';
8
9
  import './chunk-RA3O54FC.js';
9
10
  import './chunk-Z5GEFMRW.js';