@outerlayer/cli 0.12.0 → 0.14.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 (98) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +9 -4
  3. package/dist/agent-setup-CN2HUBEJ.js +26 -0
  4. package/dist/{build-LELVCWHV.js → build-BG2YENGK.js} +2 -2
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-OF67QKDS.js → builder-2D3WSOOY.js} +4 -4
  7. package/dist/{check-RJOJU2WA.js → check-SRGR36KI.js} +37 -37
  8. package/dist/{chunk-XR3BJN33.js → chunk-22RMZBGW.js} +20 -1
  9. package/dist/{chunk-AHZQBGD2.js → chunk-2M63GG56.js} +1 -1
  10. package/dist/{chunk-SZOVKFWB.js → chunk-3NLOVYJQ.js} +4 -4
  11. package/dist/{chunk-USO2DKBD.js → chunk-4KSQKQXE.js} +8 -2
  12. package/dist/{chunk-QEESCZ26.js → chunk-4NPZVMJU.js} +2 -2
  13. package/dist/{chunk-DVT73QJO.js → chunk-4OGPT6I2.js} +14 -14
  14. package/dist/{chunk-ZQUCTFXC.js → chunk-FOJGZYFC.js} +11 -5
  15. package/dist/{chunk-G5XY6CVG.js → chunk-HFKKFTXU.js} +12 -16
  16. package/dist/{chunk-ANW7VHMH.js → chunk-HFKQIZXL.js} +95 -16
  17. package/dist/{chunk-325272HM.js → chunk-J5M7BSJQ.js} +11 -4
  18. package/dist/{chunk-NPXQXYVA.js → chunk-JJEGKEFV.js} +6 -8
  19. package/dist/{chunk-3ZPYPFNM.js → chunk-JXYVA45C.js} +1 -1
  20. package/dist/{chunk-IBB4D4KE.js → chunk-JYIEHQIF.js} +1 -1
  21. package/dist/{chunk-5TGQHOUX.js → chunk-KFRM23WD.js} +3 -3
  22. package/dist/{chunk-GGMRZPEA.js → chunk-KMDLFI4P.js} +1 -1
  23. package/dist/{chunk-G5IEVZGI.js → chunk-LCEXHCHD.js} +1 -1
  24. package/dist/{chunk-27Y7AX2O.js → chunk-MSASO5O4.js} +44 -8
  25. package/dist/chunk-MTF3PHVZ.js +161 -0
  26. package/dist/{chunk-G4RXNF2L.js → chunk-NHDVD7DU.js} +12 -12
  27. package/dist/{chunk-GATMPAMK.js → chunk-NPQWKGUA.js} +2 -2
  28. package/dist/{chunk-YEQL54G5.js → chunk-PQUM37BK.js} +1 -1
  29. package/dist/{chunk-GEBQXUFY.js → chunk-Q2UK3C4P.js} +24 -10
  30. package/dist/{chunk-SKHN72JO.js → chunk-RBKIH5ST.js} +13 -13
  31. package/dist/{chunk-2KLBKHT4.js → chunk-RLYZLUQ7.js} +1 -1
  32. package/dist/chunk-RMWLBUCJ.js +50 -0
  33. package/dist/{chunk-PDRYXERC.js → chunk-SMHOCDCI.js} +5 -5
  34. package/dist/{chunk-6FH2AHJY.js → chunk-SWHQ4LUM.js} +30 -17
  35. package/dist/{agent-setup-52LRZ6AY.js → chunk-SXWS25JC.js} +8 -21
  36. package/dist/{chunk-VK25O2ZM.js → chunk-T5VPP6H7.js} +1 -1
  37. package/dist/{chunk-JOXYKGUV.js → chunk-WUYTWNMA.js} +4 -2
  38. package/dist/{chunk-A56PYPDF.js → chunk-XCK2YAY5.js} +14 -4
  39. package/dist/{chunk-C7N4TDHW.js → chunk-YDSMROTB.js} +5 -5
  40. package/dist/{chunk-FO7KKPYG.js → chunk-ZA5CHAFY.js} +2 -2
  41. package/dist/{cli-JSSRGA6V.js → cli-UW2H3UUW.js} +138 -85
  42. package/dist/{command-3WYZ2ML5.js → command-5LD7G2QQ.js} +27 -27
  43. package/dist/{config-MKBX2ZQD.js → config-N3C6DFQA.js} +1 -1
  44. package/dist/{connect-cmd-A5NGODCJ.js → connect-cmd-JUAW6MU4.js} +5 -5
  45. package/dist/{context-adopt-BAHGXJZV.js → context-adopt-PJUMW2EZ.js} +6 -6
  46. package/dist/{context-materialize-45OVRRK2.js → context-materialize-FDHYKNDT.js} +6 -6
  47. package/dist/{dist-EQDW7MZW.js → dist-LKDWQWZ7.js} +2 -2
  48. package/dist/{docker-VGWEJWI7.js → docker-4J77Q2BF.js} +5 -5
  49. package/dist/{doctor-4FFXTQJ2.js → doctor-H7REBSLQ.js} +29 -29
  50. package/dist/{emit-artifact-cmd-QS7XNKBT.js → emit-artifact-cmd-FOGNJXVR.js} +18 -21
  51. package/dist/emit-cmd-ZEYWLC2C.js +11 -0
  52. package/dist/{emit-criteria-cmd-XN6AKA53.js → emit-criteria-cmd-HBP6XS5C.js} +8 -11
  53. package/dist/{emit-finding-cmd-SQJSEHYS.js → emit-finding-cmd-DLI4MKMN.js} +8 -11
  54. package/dist/{emit-result-cmd-56RHPHOA.js → emit-result-cmd-MUSL7GQA.js} +12 -15
  55. package/dist/{hook-fast-HLESEJAL.js → hook-fast-WYQD6D7T.js} +1 -1
  56. package/dist/{import-capture-cmd-NHMAFDM6.js → import-capture-cmd-6QVCOIHK.js} +10 -13
  57. package/dist/{import-ruler-cmd-UYB32YUT.js → import-ruler-cmd-KLRGRBCP.js} +7 -10
  58. package/dist/index.js +3 -3
  59. package/dist/{init-UZKD4RY7.js → init-NTXA3SN7.js} +28 -28
  60. package/dist/{init-6AY5T3P6.js → init-UBXK6MF7.js} +47 -37
  61. package/dist/{init-cmd-XGSX2BCC.js → init-cmd-NARDUPIG.js} +20 -13
  62. package/dist/init-update-O5YYFGF4.js +165 -0
  63. package/dist/{install-VXXI7UR6.js → install-HDBIPHTX.js} +2 -2
  64. package/dist/{login-browser-7XGSV7MA.js → login-browser-QZCS3WW6.js} +2 -1
  65. package/dist/{loop-4NMI2USY.js → loop-SW2M5VDD.js} +37 -37
  66. package/dist/{machine-4JX2D4TS.js → machine-U66FKVDP.js} +23 -23
  67. package/dist/mcp-install-cmd-FDTPQQS6.js +9 -0
  68. package/dist/{runner-env-WAXTJXZK.js → runner-env-XTC53CHN.js} +3 -3
  69. package/dist/runner-key-3JSMDRJA.js +154 -0
  70. package/dist/{session-sender-T7PN4YRC.js → session-sender-4M247XSV.js} +7 -7
  71. package/dist/starter-pack-IB4UUIX3.js +11 -0
  72. package/dist/{status-OXBIRWJ7.js → status-STZYPU3W.js} +30 -30
  73. package/dist/{sync-cmd-EVXNR47N.js → sync-cmd-UWD5JOFU.js} +6 -6
  74. package/dist/{watch-7NSFOAL5.js → watch-DBNB7R6X.js} +6 -6
  75. package/dist/{work-claim-cmd-KR7UR2AB.js → work-claim-cmd-LY4U6QHN.js} +13 -13
  76. package/dist/{work-cmd-JPM37MLF.js → work-cmd-RVRQ32EH.js} +7 -7
  77. package/dist/{work-comment-cmd-3DC6BC34.js → work-comment-cmd-FFUM4TJU.js} +10 -13
  78. package/dist/{work-open-pr-cmd-XZQRJBNZ.js → work-open-pr-cmd-HLDWP4T2.js} +10 -13
  79. package/dist/{work-pr-cmd-WHGZOP22.js → work-pr-cmd-L77K32WK.js} +7 -7
  80. package/package.json +1 -1
  81. package/skill-pack/maintained/emitting-evidence/SKILL.md +8 -2
  82. package/skill-pack/shipped.json +70 -0
  83. package/skill-pack/template/build/SKILL.md +66 -35
  84. package/skill-pack/template/build/references/agent-briefs.md +4 -2
  85. package/skill-pack/template/build/references/release.md +36 -8
  86. package/skill-pack/template/build/references/review-loop.md +6 -2
  87. package/skill-pack/template/build/scripts/record-criteria.mjs +109 -143
  88. package/skill-pack/template/spec/SKILL.md +33 -22
  89. package/skill-pack/template/writing-specs/SKILL.md +36 -3
  90. package/skill-pack/template/writing-specs/references/agents-snippet.md +57 -0
  91. package/skill-pack/template/writing-tests/SKILL.md +117 -0
  92. package/skill-pack/validators/acceptance-criteria.yaml +35 -0
  93. package/skill-pack/validators/code-review.yaml +4 -2
  94. package/dist/chunk-T6OIJQRT.js +0 -31
  95. package/dist/emit-cmd-LXEIDKLT.js +0 -10
  96. package/dist/mcp-install-cmd-XZARXNYT.js +0 -9
  97. package/dist/starter-pack-Z22VRFPF.js +0 -11
  98. package/dist/{chunk-3FMPZPJQ.js → chunk-R7PF5OOU.js} +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4921c80: `outerlayer init --update` brings the files `init` wrote once up to the installed CLI's version: the template skills, `.outerlayer/policy.yaml`, the `code-review.yaml` and `acceptance-criteria.yaml` checks in `.outerlayer/validators/`, and the `outerlayer` and `outerlayer-docs` MCP entries. A file still equal to what an earlier release wrote is replaced, a missing one is written, and a file you edited is never touched. It then runs `outerlayer context emit` and leaves the changes uncommitted. `--dry-run` prints the plan, with a command to compare each edited file. `outerlayer doctor` adds a **Starter files** check that reports each file as current, outdated, edited or missing. An `outerlayer` MCP entry an earlier `init` wrote is reported there, not by the **MCP server** check. The quickstart no longer says the MCP server needs a global install.
8
+ - 23aa007: The starter skills `outerlayer init` installs gain three practices. `/spec` decides a docs verdict and a structural verdict for every issue, each with a one-line reason, and `writing-specs` defines both. A new `writing-tests` template holds a language-neutral test standard: strong assertions, the right seam, a criterion id in a comment above its test, and an optional mutation check. `writing-specs/references/agents-snippet.md` holds optional writing rules to paste into an instructions file. The `writing-specs` frontmatter now parses as YAML, so tools that read it see its description.
9
+ - 789f55f: `outerlayer sync` prints a line for each artifact it uploads, with its file name, caption and dashboard link, so an agent can pass the link straight to `outerlayer emit code-review --link`. `sync --json` lists them under `uploadedArtifacts`, and the spool state records each artifact's server id and link against its client id. `outerlayer emit artifact` prints the link when it uploads at once, and inside a session says the next `sync` prints it.
10
+ - ef97624: `outerlayer init` writes a second check, `.outerlayer/validators/acceptance-criteria.yaml`, only when it is missing. The starter `/build` skill records its criteria judge's verdict on that check, so every pull request it opens has a row for it. The build records pass only when the judge found every criterion it judged satisfied, and fail when it found one unmet. When there is no criterion to judge, it records nothing, so the row reads "not proven".
11
+
12
+ ### Patch Changes
13
+
14
+ - 0e6256b: `work comment`, `work threads`, `work pr`, `work open-pr`, `emit result`, `emit artifact`, `emit criteria`, `emit finding`, `context emit`, `import capture` and `import ruler` no longer print ANSI color codes when output is piped or `NO_COLOR` is set. They follow the same color rules as the rest of the CLI, including `--no-color` and `FORCE_COLOR`. Output on a terminal is unchanged.
15
+
16
+ ## 0.13.0
17
+
18
+ ### Minor Changes
19
+
20
+ - 76222d4: The starter `/build` skill no longer parses fixed shapes out of an issue. The agent reads the issue's acceptance criteria in any form and keeps their text as written. `record-criteria.mjs` now takes the agent's file with `--criteria-file`. It keeps the issue's ids when every criterion has one that fits the id grammar, and otherwise numbers them `AC-<item>-NN`. A partly numbered list is now numbered and recorded, not skipped. When an issue has no criteria, the build drafts them from the description and runs the script with `--drafted`, which records the list with `drafted: true`. `outerlayer emit criteria` reads an optional top-level `"drafted": true` from its file and sends it with the list.
21
+ - 07677fd: `outerlayer runner init` creates the runner's API key from your login when the config file has none. It uses the Runner preset, names the key after the machine (`--key-name` to override), creates it on the factory `--app-id` names, and checks it before any VM or service step. On a Mac with `--vm`, the key goes straight into the VM and is never written on the Mac. A login that cannot create keys gets a refusal naming the pasted-key path, which still works as before.
22
+
23
+ ### Patch Changes
24
+
25
+ - b831165: Fix rough edges a first-time user meets. `init` writes an MCP server entry that runs through npx, so it starts without a global install, and `doctor` warns when the entry's command is not on PATH. `init` marks a connection whose repository still needs linking with `!` and names the factory by its slug. `login` suggests `init` in a repository that is not set up. `doctor` warns when a factory has no connected repository, stops listing one Claude Code install twice, and says the first hook run creates the spool. `work build` names the item and the issue separately, prints the item's page, and honours NO_COLOR and non-terminal output. A runner keeps the build's item key in its own owner-only file instead of `job.json`. The starter build skill uses the branch a host allows, and the code review check says the report's link can take a minute to appear. `runner init`, `runner check` and `runner start` refuse an empty or blank runner key or factory id, or one still holding a `<...>` placeholder, naming the field and the config file.
26
+ - 836d0e0: A validator file can no longer declare `artifact`, `finding` or `findings` as its emit name, the same as `criteria`. Each is an `outerlayer emit` subcommand, so `outerlayer emit <name>` ran the subcommand and the check could never be recorded. A file that declares one now fails to load with a policy error naming the subcommand.
27
+
3
28
  ## 0.12.0
4
29
 
5
30
  ### Minor Changes
package/README.md CHANGED
@@ -142,9 +142,14 @@ content:
142
142
  request it makes with the host key, the way the runner does. The signature
143
143
  covers the request's method, path, query and body, and adds nothing else
144
144
  to it.
145
- - **`outerlayer runner init`** makes no network call, except `runner init --vm`
146
- on a Mac. That runs `limactl`, and Lima downloads a Linux VM image. Inside
147
- the VM, `apt` downloads Node and `npm` downloads this CLI. Your runner key goes to the VM on the standard
145
+ - **`outerlayer runner init`** makes no network call when the config file
146
+ already holds a runner key. With no key there and a saved login, it
147
+ creates one: `POST /v1/api-keys` with your login's token, sending the key's
148
+ name (this machine's name, or `--key-name`), the Runner preset's
149
+ permissions and the factory id. It then checks the new key, unsigned, with
150
+ `GET /v1/runner/host-key`. `runner init --vm` on a Mac also runs `limactl`,
151
+ and Lima downloads a Linux VM image. Inside the VM, `apt` downloads Node and
152
+ `npm` downloads this CLI. Your runner key goes to the VM on the standard
148
153
  input of a `limactl shell` command and is never a file or an argument on the
149
154
  Mac.
150
155
  - **`outerlayer login`**, with no key on stdin, signs in to your account by
@@ -386,7 +391,7 @@ before it gives up.
386
391
  | `outerlayer work claim --item <n>\|--issue <n> --kind implement\|amend [--repo] [--host] [--seconds]` | Records a lease for this host (default: its own hostname), so two hosts never build the same item at once. The lease belongs to the runner key that claimed it: a live lease held by a different key is refused, even under the same host name, and claiming again with the same key extends it. The first claim creates the host key (`host-key.pem` beside the config file) and binds the runner key to it; from then on every request made with that key is signed. Lease length defaults to 900 seconds, the server's own cap. |
387
392
  | `outerlayer work renew --item <n>\|--issue <n> [--repo] [--host] [--seconds]` | Extends this host's own live lease. Refused if the lease has expired, or if a different runner key holds it (403 `claim_not_held`). |
388
393
  | `outerlayer work release --item <n>\|--issue <n> [--repo] [--host] [--session-id] [--outcome]` | Marks the lease this API key holds released, optionally recording how the attempt ended. Releasing an already-released lease is a no-op that returns the recorded release time and outcome. Run inside a session with no `--host`, it releases that session's own lease instead (`--session-id` names the session when it cannot be detected), so the item's review opens without ending the session. |
389
- | `outerlayer runner init [--vm\|--no-vm] [--config <path>]` | Writes a `runner` block with defaults, keeping every key the config already had. It names `builtin:vm` on a Linux machine where the user can use `/dev/kvm` and Docker Engine can build images once the guest kernel and helper are published (not yet), `builtin:container` on that machine until then, `builtin:container` on any other machine with Docker Engine, and `builtin:process` on one without, and writes no hook script. Refuses rather than overwriting an existing block. On macOS it asks whether to create a Linux VM with Lima, installs Docker Engine and the runner in it, and starts both at login; `--vm` answers yes and `--no-vm` answers no, and a run with no terminal answers no. The runner key and the host key then live only in the VM: the Mac's config loses `apiKey` and `runner` and gains a `runnerVm` note, which `outerlayer doctor` reads. |
394
+ | `outerlayer runner init [--vm\|--no-vm] [--app-id <id>] [--key-name <name>] [--config <path>]` | Writes a `runner` block with defaults, keeping every key the config already had. With no `apiKey` in the config and a saved login, it first creates a runner key from the login with the Runner preset, named after the machine or `--key-name`, on the factory `--app-id` names, and checks it before anything else changes. It names `builtin:vm` on a Linux machine where the user can use `/dev/kvm` and Docker Engine can build images once the guest kernel and helper are published (not yet), `builtin:container` on that machine until then, `builtin:container` on any other machine with Docker Engine, and `builtin:process` on one without, and writes no hook script. Refuses rather than overwriting an existing block. On macOS it asks whether to create a Linux VM with Lima, installs Docker Engine and the runner in it, and starts both at login; `--vm` answers yes and `--no-vm` answers no, and a run with no terminal answers no. The runner key and the host key then live only in the VM: the Mac's config loses `apiKey` and `runner` and gains a `runnerVm` note, which `outerlayer doctor` reads. |
390
395
  | `outerlayer runner check [--config <path>]` | Validates the config, the hooks and the key, prints the settings the runner would use, and exits non-zero on a problem. Takes no work and writes no pid file. |
391
396
  | `outerlayer runner start [--config <path>]` | Runs the loop: claim work, run it, sync, clean up, report, release with an outcome. Repeat. Reads the `runner` block from the config file (default `~/.outerlayer/config.json`). Refuses to start on a bad config, an unrunnable hook, or a refused key. |
392
397
  | `outerlayer runner image --repository <owner/name> [--remote <url>] [--config <path>] [--json]` | Builds the image a repository's builds run in. Fetches the head of the default branch into the runner's cache, builds its `.devcontainer/devcontainer.json` with the devcontainer CLI, ignores every setting that reaches the host or widens the container's privileges, and adds this CLI and a pinned Claude Code. Reuses the image until the recipe or the tools change, keeps the newest three, and writes `recipe.json` beside the image record. Refuses a Compose recipe (`recipe_needs_docker`) and a repository with only named configurations (`recipe_ambiguous`). |
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ export { keepHandWritten, runAgentSetup } from './chunk-SXWS25JC.js';
4
+ import './chunk-HFKKFTXU.js';
5
+ import './chunk-XCK2YAY5.js';
6
+ import './chunk-FOJGZYFC.js';
7
+ import './chunk-YRYMNBGQ.js';
8
+ import './chunk-3NLOVYJQ.js';
9
+ import './chunk-LCEXHCHD.js';
10
+ import './chunk-ZJSNLVCE.js';
11
+ import './chunk-YO4PSLVB.js';
12
+ import './chunk-BYT5O5RV.js';
13
+ import './chunk-ZA5CHAFY.js';
14
+ import './chunk-2M63GG56.js';
15
+ import './chunk-PLMTLGYH.js';
16
+ import './chunk-J5M7BSJQ.js';
17
+ import './chunk-EABW6AJQ.js';
18
+ import './chunk-RA3O54FC.js';
19
+ import './chunk-V7NIVOFD.js';
20
+ import './chunk-ZM2IMMYN.js';
21
+ import './chunk-XCCLFVXM.js';
22
+ import './chunk-BJ3KTMDH.js';
23
+ import './chunk-VNVZDWO3.js';
24
+ import './chunk-Z5GEFMRW.js';
25
+
26
+ createRequire(import.meta.url);
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { buildRepositoryImage } from './chunk-3FMPZPJQ.js';
4
- import './chunk-N5FOE5PS.js';
3
+ export { buildRepositoryImage } from './chunk-R7PF5OOU.js';
5
4
  export { RecipeError } from './chunk-QOZKPLVJ.js';
5
+ import './chunk-N5FOE5PS.js';
6
6
  import './chunk-CX22S5BA.js';
7
7
  import './chunk-BYT5O5RV.js';
8
8
  import './chunk-ZM2IMMYN.js';
@@ -1 +1 @@
1
- {"id":"2026-10-08T01:27:55.356Z+5a1c8e3","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-08T21:15:36.925Z+415a9ac","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-QEESCZ26.js';
4
- import './chunk-CX22S5BA.js';
5
- import './chunk-3ZPYPFNM.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-4NPZVMJU.js';
6
4
  import './chunk-7RQ73DLO.js';
7
5
  import './chunk-4Q7OMKAT.js';
8
- import './chunk-325272HM.js';
6
+ import './chunk-CX22S5BA.js';
7
+ import './chunk-JXYVA45C.js';
9
8
  import './chunk-BYT5O5RV.js';
9
+ import './chunk-J5M7BSJQ.js';
10
10
  import './chunk-ZM2IMMYN.js';
11
11
  import './chunk-Z5GEFMRW.js';
12
12
 
@@ -1,69 +1,69 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-G4RXNF2L.js';
4
- import './chunk-DVT73QJO.js';
3
+ import { probeCredentials } from './chunk-NHDVD7DU.js';
4
+ import './chunk-4OGPT6I2.js';
5
5
  import './chunk-O765JR4W.js';
6
6
  import './chunk-UGP76IZ5.js';
7
7
  import './chunk-3JVYMD4G.js';
8
- import './chunk-T6OIJQRT.js';
9
- import './chunk-I2UOAV7X.js';
10
8
  import './chunk-YETTWTAY.js';
9
+ import './chunk-RMWLBUCJ.js';
10
+ import './chunk-I2UOAV7X.js';
11
+ import './chunk-HYZRY4KZ.js';
11
12
  import './chunk-FI5UYJMQ.js';
12
- import './chunk-5TGQHOUX.js';
13
- import './chunk-27Y7AX2O.js';
13
+ import './chunk-KFRM23WD.js';
14
+ import './chunk-MSASO5O4.js';
14
15
  import './chunk-HHJDN6AU.js';
15
- import './chunk-HYZRY4KZ.js';
16
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-PDRYXERC.js';
16
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-SMHOCDCI.js';
17
17
  import './chunk-YYYRBYWG.js';
18
18
  import './chunk-TI7B7UEO.js';
19
19
  import './chunk-TBT347UY.js';
20
- import './chunk-GEBQXUFY.js';
21
- import './chunk-IBB4D4KE.js';
22
- import './chunk-SKHN72JO.js';
23
- import './chunk-VK25O2ZM.js';
24
- import './chunk-2KLBKHT4.js';
20
+ import './chunk-Q2UK3C4P.js';
21
+ import './chunk-JYIEHQIF.js';
22
+ import './chunk-RBKIH5ST.js';
23
+ import './chunk-KMDLFI4P.js';
24
+ import './chunk-QKFB4K7X.js';
25
+ import './chunk-RSNSZ2LJ.js';
26
+ import './chunk-T5VPP6H7.js';
27
+ import './chunk-RLYZLUQ7.js';
25
28
  import { parseRunnerEnv } from './chunk-6MZSX4M7.js';
26
- import './chunk-3FMPZPJQ.js';
29
+ import './chunk-SWHQ4LUM.js';
30
+ import './chunk-NPQWKGUA.js';
31
+ import './chunk-IP7BIBXJ.js';
32
+ import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-22RMZBGW.js';
33
+ import './chunk-UXYLWVTQ.js';
34
+ import './chunk-R7PF5OOU.js';
35
+ import './chunk-QOZKPLVJ.js';
27
36
  import './chunk-N5FOE5PS.js';
28
37
  import './chunk-OGFGZQA3.js';
29
- import './chunk-GGMRZPEA.js';
30
- import './chunk-QOZKPLVJ.js';
31
- import './chunk-QEESCZ26.js';
38
+ import './chunk-4NPZVMJU.js';
39
+ import './chunk-7RQ73DLO.js';
40
+ import './chunk-4Q7OMKAT.js';
32
41
  import './chunk-CX22S5BA.js';
33
- import './chunk-QKFB4K7X.js';
34
- import './chunk-RSNSZ2LJ.js';
35
42
  import './chunk-F7CU5ABH.js';
36
43
  import './chunk-BKO6JEZI.js';
37
- import './chunk-6FH2AHJY.js';
38
- import './chunk-GATMPAMK.js';
39
- import './chunk-IP7BIBXJ.js';
40
- import './chunk-C7N4TDHW.js';
41
- import './chunk-JOXYKGUV.js';
42
- import './chunk-3ZPYPFNM.js';
43
- import './chunk-USO2DKBD.js';
44
+ import './chunk-YDSMROTB.js';
45
+ import './chunk-WUYTWNMA.js';
46
+ import './chunk-JXYVA45C.js';
47
+ import './chunk-4KSQKQXE.js';
44
48
  import './chunk-N6LURUEF.js';
45
49
  import './chunk-YRYMNBGQ.js';
46
- import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-XR3BJN33.js';
47
- import './chunk-UXYLWVTQ.js';
48
- import './chunk-7RQ73DLO.js';
49
- import './chunk-4Q7OMKAT.js';
50
50
  import './chunk-GQD22KKN.js';
51
51
  import './chunk-WZBHBH3J.js';
52
52
  import './chunk-5QRP3MVS.js';
53
- import './chunk-SZOVKFWB.js';
53
+ import './chunk-3NLOVYJQ.js';
54
+ import './chunk-LCEXHCHD.js';
54
55
  import './chunk-ZJSNLVCE.js';
55
- import './chunk-FO7KKPYG.js';
56
- import './chunk-G5IEVZGI.js';
57
- import './chunk-AHZQBGD2.js';
58
56
  import './chunk-YO4PSLVB.js';
57
+ import './chunk-BYT5O5RV.js';
58
+ import './chunk-ZA5CHAFY.js';
59
+ import './chunk-2M63GG56.js';
59
60
  import './chunk-PLMTLGYH.js';
60
- import './chunk-325272HM.js';
61
+ import './chunk-J5M7BSJQ.js';
61
62
  import './chunk-EABW6AJQ.js';
62
- import './chunk-BYT5O5RV.js';
63
63
  import './chunk-RA3O54FC.js';
64
64
  import './chunk-V7NIVOFD.js';
65
65
  import './chunk-ZM2IMMYN.js';
66
- import './chunk-YEQL54G5.js';
66
+ import './chunk-PQUM37BK.js';
67
67
  import './chunk-XCCLFVXM.js';
68
68
  import './chunk-BJ3KTMDH.js';
69
69
  import './chunk-VNVZDWO3.js';
@@ -47,6 +47,23 @@ function defaultRunnerConfigPath(home = homeFromEnv()) {
47
47
  function fail(configPath, key, reason) {
48
48
  throw new RunnerConfigError(`${configPath}: ${key} ${reason}`);
49
49
  }
50
+ var PLACEHOLDER = /[<>]/;
51
+ function runnerCredentialProblem(config) {
52
+ for (const field of ["url", "apiKey", "appId"]) {
53
+ const value = config[field];
54
+ if (value === void 0) return { field, reason: "is missing" };
55
+ if (typeof value !== "string") return { field, reason: "is not text" };
56
+ if (value.trim() === "") return { field, reason: "is empty" };
57
+ }
58
+ if (PLACEHOLDER.test(config.apiKey)) {
59
+ return { field: "apiKey", reason: "is still a <...> placeholder. Put the factory's runner key there: an API key made with the Runner preset" };
60
+ }
61
+ const appId = config.appId;
62
+ if (PLACEHOLDER.test(appId)) {
63
+ return { field: "appId", reason: `is still the placeholder ${JSON.stringify(appId)}. Put the Factory Id from the factory's Settings \u2192 General there` };
64
+ }
65
+ return void 0;
66
+ }
50
67
  function readConfigFile(configPath) {
51
68
  if (!existsSync(configPath)) return {};
52
69
  const text = readFileSync(configPath, "utf8");
@@ -171,6 +188,8 @@ function loadRunnerConfig(configPath) {
171
188
  if (!config.url || !config.apiKey || !config.appId) {
172
189
  fail(configPath, "url/apiKey/appId", "missing \u2014 pipe a factory key into `outerlayer login` for this config file first; a runner uses a factory key, never a person's login");
173
190
  }
191
+ const credentialProblem = runnerCredentialProblem(config);
192
+ if (credentialProblem !== void 0) fail(configPath, credentialProblem.field, credentialProblem.reason);
174
193
  const runner = config.runner;
175
194
  if (!runner) {
176
195
  fail(configPath, "runner", "block is missing");
@@ -379,4 +398,4 @@ function resolveBuild(configPath, block) {
379
398
  };
380
399
  }
381
400
 
382
- export { DEFAULT_CHECK_TIME_LIMIT_MINUTES, DEFAULT_UPDATE_MAX_WAIT_HOURS, RunnerConfigError, builtinKind, checkHooks, defaultRunnerConfigPath, hasRunnerBlock, isBuiltinContainer, isBuiltinProcess, isBuiltinVm, loadRunnerConfig, resolveBuild, resolveHousekeeping, runnerVmOf };
401
+ export { DEFAULT_CHECK_TIME_LIMIT_MINUTES, DEFAULT_UPDATE_MAX_WAIT_HOURS, RunnerConfigError, builtinKind, checkHooks, defaultRunnerConfigPath, hasRunnerBlock, isBuiltinContainer, isBuiltinProcess, isBuiltinVm, loadRunnerConfig, resolveBuild, resolveHousekeeping, runnerCredentialProblem, runnerVmOf };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RESERVED_EMIT_NAMES, ARTIFACT_KINDS, ArtifactCriterionIdSchema } from './chunk-325272HM.js';
3
+ import { RESERVED_EMIT_NAMES, ARTIFACT_KINDS, ArtifactCriterionIdSchema } from './chunk-J5M7BSJQ.js';
4
4
  import { __commonJS, __require, __toESM } from './chunk-Z5GEFMRW.js';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
+ import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, isLastCheckFresh, readDegraded, touchLastCheck, clearDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh } from './chunk-LCEXHCHD.js';
3
4
  import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
4
- import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-FO7KKPYG.js';
5
- import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, isLastCheckFresh, readDegraded, touchLastCheck, clearDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh } from './chunk-G5IEVZGI.js';
6
- import { normalizeRepoName, parseGoverns, CONTEXT_SOURCE_CONFIG_PATH, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-AHZQBGD2.js';
7
5
  import { defaultFetch } from './chunk-YO4PSLVB.js';
8
- import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
9
6
  import { withTokenHeader } from './chunk-BYT5O5RV.js';
7
+ import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-ZA5CHAFY.js';
8
+ import { normalizeRepoName, parseGoverns, CONTEXT_SOURCE_CONFIG_PATH, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-2M63GG56.js';
9
+ import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
10
10
  import { ensureContextExcludes, ensurePreCommitGuardHook } from './chunk-XCCLFVXM.js';
11
11
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
12
12
  import { execFileSync } from 'child_process';
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module';
3
3
  import { revokeTokenOnDashboard } from './chunk-N6LURUEF.js';
4
4
  import { C } from './chunk-YRYMNBGQ.js';
5
5
  import { readCloudConfig, writeCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
6
+ import { findGitDirs } from './chunk-BJ3KTMDH.js';
6
7
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
7
8
  import { generateKeyPairSync, privateDecrypt, constants, createPrivateKey } from 'crypto';
8
9
  import { spawn } from 'child_process';
@@ -269,14 +270,19 @@ async function finishApproved(flags, deps, home, dashboard, approved, privateKey
269
270
  }
270
271
  deps.stdout.write(
271
272
  `${C.green}\u2713${C.reset} Logged in as ${approved.email}. Saved the login to ${path}
272
- Next: run \`outerlayer connect\` to choose a factory.
273
- `
273
+ ` + nextAfterLogin(deps.cwd ?? process.cwd())
274
274
  );
275
275
  if (before.apiKey) {
276
276
  deps.stdout.write("A factory key is also saved on this machine, so commands here keep using the key, not this login.\n");
277
277
  }
278
278
  return 0;
279
279
  }
280
+ function nextAfterLogin(cwd) {
281
+ const dirs = findGitDirs(cwd);
282
+ if (dirs === void 0) return "Next: in your repository, run `outerlayer init --factory <org>/<factory>`.\n";
283
+ if (existsSync(join(dirs.repoRoot, ".outerlayer"))) return "Next: run `outerlayer connect` to choose a factory.\n";
284
+ return "Next: run `outerlayer init --factory <org>/<factory>` to set up this repository.\n";
285
+ }
280
286
  function fail(deps, message) {
281
287
  deps.stderr.write(`${C.red}\u2717${C.reset} ${message}
282
288
  `);
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { BUILDKIT_IMAGE } from './chunk-CX22S5BA.js';
4
- import { compareVersions } from './chunk-3ZPYPFNM.js';
5
3
  import { parseSize } from './chunk-7RQ73DLO.js';
6
4
  import { JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-4Q7OMKAT.js';
5
+ import { BUILDKIT_IMAGE } from './chunk-CX22S5BA.js';
6
+ import { compareVersions } from './chunk-JXYVA45C.js';
7
7
  import { runnerDir } from './chunk-ZM2IMMYN.js';
8
8
  import { createHash } from 'crypto';
9
9
  import { realpathSync } from 'fs';
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { writeJobFile, readJobFile } from './chunk-T6OIJQRT.js';
4
- import { senderPidfile } from './chunk-5TGQHOUX.js';
5
- import { installScrubContext } from './chunk-27Y7AX2O.js';
3
+ import { writeJobFile, readJobFile } from './chunk-RMWLBUCJ.js';
6
4
  import { DOCKERD_LOG } from './chunk-HYZRY4KZ.js';
7
- import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, createRunnerLog, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, formatDuration, retrySend, formatClock, containerSenderCommand, syncInContainer, copyTranscriptsFromContainer, GH_CONFIG_YML, ghHostsYml, ADDED_USER, isLiteralAddress, signalInContainer, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript } from './chunk-SKHN72JO.js';
8
- import { readBranchHead, diffBetween, fetchCommit } from './chunk-3FMPZPJQ.js';
9
- import { isSameProcess, startTimeOf } from './chunk-N5FOE5PS.js';
10
- import { childEnvironment } from './chunk-GGMRZPEA.js';
11
- import { CLAUDE_CODE_VERSION } from './chunk-CX22S5BA.js';
5
+ import { senderPidfile } from './chunk-KFRM23WD.js';
6
+ import { installScrubContext } from './chunk-MSASO5O4.js';
7
+ import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, createRunnerLog, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, formatDuration, retrySend, formatClock, containerSenderCommand, syncInContainer, copyTranscriptsFromContainer, GH_CONFIG_YML, ghHostsYml, ADDED_USER, isLiteralAddress, signalInContainer, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript } from './chunk-RBKIH5ST.js';
8
+ import { childEnvironment } from './chunk-KMDLFI4P.js';
12
9
  import { waitForAgent, vmExecArgs } from './chunk-QKFB4K7X.js';
13
10
  import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-RSNSZ2LJ.js';
14
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-6FH2AHJY.js';
15
- import { planArtifactUpload } from './chunk-JOXYKGUV.js';
16
- import { scrubText } from './chunk-3ZPYPFNM.js';
17
- import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-XR3BJN33.js';
11
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-SWHQ4LUM.js';
12
+ import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-22RMZBGW.js';
13
+ import { readBranchHead, diffBetween, fetchCommit } from './chunk-R7PF5OOU.js';
14
+ import { isSameProcess, startTimeOf } from './chunk-N5FOE5PS.js';
18
15
  import { parseSize } from './chunk-7RQ73DLO.js';
19
16
  import { claudeCredential, repositoriesOf, primaryOf, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, withTunnelRecord, RELAY_PORT, checkEnvironment, EVAL_INPUT_DIR } from './chunk-4Q7OMKAT.js';
20
- import { parsePolicy } from './chunk-AHZQBGD2.js';
21
- import { readCloudConfig } from './chunk-EABW6AJQ.js';
17
+ import { CLAUDE_CODE_VERSION } from './chunk-CX22S5BA.js';
18
+ import { planArtifactUpload } from './chunk-WUYTWNMA.js';
19
+ import { scrubText } from './chunk-JXYVA45C.js';
22
20
  import { withHooksPath, authorEnvironment, commitIdentityRecord } from './chunk-BYT5O5RV.js';
21
+ import { parsePolicy } from './chunk-2M63GG56.js';
22
+ import { readCloudConfig } from './chunk-EABW6AJQ.js';
23
23
  import { resolveVersion } from './chunk-RA3O54FC.js';
24
24
  import { signerFor } from './chunk-V7NIVOFD.js';
25
25
  import { runnerDir, buildDir, vsockPath, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { C } from './chunk-YRYMNBGQ.js';
4
- import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-FO7KKPYG.js';
4
+ import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-ZA5CHAFY.js';
5
5
  import { resolvePackageVersion } from './chunk-RA3O54FC.js';
6
6
  import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
7
7
  import { join, dirname } from 'path';
@@ -10,7 +10,10 @@ createRequire(import.meta.url);
10
10
  var DEFAULT_TEMPLATE = "default";
11
11
  var POLICY_PATH = ".outerlayer/policy.yaml";
12
12
  var POLICY_CONTENT = "review: required\n";
13
- var VALIDATOR_FILES = ["code-review.yaml"];
13
+ var VALIDATOR_FILES = [
14
+ { name: "code-review.yaml", label: "the code review check" },
15
+ { name: "acceptance-criteria.yaml", label: "the criteria judge check" }
16
+ ];
14
17
  var VALIDATORS_DIR = ".outerlayer/validators";
15
18
  var StarterPackError = class extends Error {
16
19
  };
@@ -24,7 +27,7 @@ function installStarterPack(opts) {
24
27
  const version = opts.version ?? resolvePackageVersion();
25
28
  const templateFiles = loadTemplateFiles(packRoot, version);
26
29
  const maintainedFiles = loadMaintainedFiles(packRoot, version);
27
- const validatorFiles = VALIDATOR_FILES.map((name) => ({
30
+ const validatorFiles = VALIDATOR_FILES.map(({ name }) => ({
28
31
  path: `${VALIDATORS_DIR}/${name}`,
29
32
  content: readFileSync(join(packRoot, "validators", name), "utf8")
30
33
  }));
@@ -72,6 +75,9 @@ function installStarterPack(opts) {
72
75
  };
73
76
  }
74
77
  var skillFile = (skill) => `${skillDir(skill)}/SKILL.md`;
78
+ function validatorLabel(path) {
79
+ return VALIDATOR_FILES.find(({ name }) => path === `${VALIDATORS_DIR}/${name}`)?.label ?? "a check";
80
+ }
75
81
  function formatStarterPackOutput(result) {
76
82
  const lines = [];
77
83
  lines.push(`${C.green}\u2713${C.reset} Installed the starter skills in .outerlayer/skills/`, "");
@@ -87,7 +93,7 @@ function formatStarterPackOutput(result) {
87
93
  "",
88
94
  result.policy === "written" ? `${C.green}\u2713${C.reset} Wrote ${POLICY_PATH} (review required)` : `${C.dim}${POLICY_PATH} already exists \u2014 left as it is${C.reset}`,
89
95
  ...result.validatorsWritten.map(
90
- (path) => `${C.green}\u2713${C.reset} Wrote ${path} (yours to edit \u2014 the code review check)`
96
+ (path) => `${C.green}\u2713${C.reset} Wrote ${path} (yours to edit \u2014 ${validatorLabel(path)})`
91
97
  ),
92
98
  ...result.validatorsKept.map((path) => `${C.dim}${path} already exists \u2014 left as it is${C.reset}`),
93
99
  "",
@@ -97,4 +103,4 @@ function formatStarterPackOutput(result) {
97
103
  return lines.join("\n") + "\n";
98
104
  }
99
105
 
100
- export { StarterPackError, assertKnownTemplate, formatStarterPackOutput, installStarterPack };
106
+ export { POLICY_CONTENT, POLICY_PATH, StarterPackError, VALIDATORS_DIR, VALIDATOR_FILES, assertKnownTemplate, formatStarterPackOutput, installStarterPack };
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-FO7KKPYG.js';
4
- import { emitTree, parseOuterlayerConfig, classifyTree, generatedHeaderSource, CONTEXT_PIN_FILENAME, normalizePath } from './chunk-AHZQBGD2.js';
3
+ import { C } from './chunk-YRYMNBGQ.js';
4
+ import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-ZA5CHAFY.js';
5
+ import { emitTree, parseOuterlayerConfig, classifyTree, generatedHeaderSource, CONTEXT_PIN_FILENAME, normalizePath } from './chunk-2M63GG56.js';
5
6
  import { existsSync, readFileSync, mkdirSync, writeFileSync, copyFileSync, readdirSync } from 'fs';
6
7
  import { join, dirname, relative, sep } from 'path';
7
8
 
@@ -9,11 +10,6 @@ createRequire(import.meta.url);
9
10
  var CONTENT_KINDS = /* @__PURE__ */ new Set(["instructions", "skill", "skill-reference", "command", "mcp"]);
10
11
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git"]);
11
12
  var NO_CONFIG_MESSAGE = 'no .outerlayer/config.json with a non-empty targets array \u2014 create one, e.g. {"targets": ["claude-code"]}';
12
- var GREEN = "\x1B[32m";
13
- var YELLOW = "\x1B[33m";
14
- var RED = "\x1B[31m";
15
- var DIM = "\x1B[2m";
16
- var RESET = "\x1B[0m";
17
13
  var EmitError = class extends Error {
18
14
  };
19
15
  function resolveTargetsFromConfig(repoRoot) {
@@ -87,20 +83,20 @@ function writeOutputs(repoRoot, result, maintained) {
87
83
  function renderSuccess(targets, files, copies, maintained) {
88
84
  const copySuffix = copies.length > 0 ? `, ${copies.length} ${copies.length === 1 ? "copy" : "copies"}` : "";
89
85
  const lines = [
90
- `${GREEN}\u2713${RESET} emitted ${files.length} file${files.length === 1 ? "" : "s"}${copySuffix} for ${DIM}${targets.join(", ")}${RESET}`
86
+ `${C.green}\u2713${C.reset} emitted ${files.length} file${files.length === 1 ? "" : "s"}${copySuffix} for ${C.dim}${targets.join(", ")}${C.reset}`
91
87
  ];
92
- for (const path of maintained) lines.push(` ${DIM}updated ${path} to this CLI's version${RESET}`);
88
+ for (const path of maintained) lines.push(` ${C.dim}updated ${path} to this CLI's version${C.reset}`);
93
89
  return lines.join("\n");
94
90
  }
95
91
  function renderFailure(errors) {
96
- const lines = [`${RED}\u2717${RESET} emit failed \u2014 nothing written`];
97
- for (const e of errors) lines.push(` ${RED}\u2717${RESET} ${e.path}: ${e.message}`);
92
+ const lines = [`${C.red}\u2717${C.reset} emit failed \u2014 nothing written`];
93
+ for (const e of errors) lines.push(` ${C.red}\u2717${C.reset} ${e.path}: ${e.message}`);
98
94
  return lines.join("\n");
99
95
  }
100
96
  function renderCheck(targets, drift) {
101
- if (drift.length === 0) return `${GREEN}\u2713${RESET} up to date for ${DIM}${targets.join(", ")}${RESET}`;
102
- const lines = [`${RED}\u2717${RESET} drift detected (${drift.length}) \u2014 run \`outerlayer emit\` to update`];
103
- for (const d of drift) lines.push(` ${RED}\u2717${RESET} ${d.kind.padEnd(8)} ${d.path}`);
97
+ if (drift.length === 0) return `${C.green}\u2713${C.reset} up to date for ${C.dim}${targets.join(", ")}${C.reset}`;
98
+ const lines = [`${C.red}\u2717${C.reset} drift detected (${drift.length}) \u2014 run \`outerlayer emit\` to update`];
99
+ for (const d of drift) lines.push(` ${C.red}\u2717${C.reset} ${d.kind.padEnd(8)} ${d.path}`);
104
100
  return lines.join("\n");
105
101
  }
106
102
  function compareFile(repoRoot, path, expectedContent) {
@@ -205,7 +201,7 @@ function runEmit(opts = {}) {
205
201
  process.stderr.write(output + "\n");
206
202
  } else {
207
203
  process.stdout.write(output + "\n");
208
- for (const w of result.warnings) process.stderr.write(` ${YELLOW}!${RESET} ${w.path}: ${w.message}
204
+ for (const w of result.warnings) process.stderr.write(` ${C.yellow}!${C.reset} ${w.path}: ${w.message}
209
205
  `);
210
206
  }
211
207
  }
@@ -249,7 +245,7 @@ function runCheck(cwd, opts, targets, result, hasErrors, sourcePaths, maintained
249
245
  process.stderr.write(output + "\n");
250
246
  } else {
251
247
  process.stdout.write(output + "\n");
252
- for (const w of result.warnings) process.stderr.write(` ${YELLOW}!${RESET} ${w.path}: ${w.message}
248
+ for (const w of result.warnings) process.stderr.write(` ${C.yellow}!${C.reset} ${w.path}: ${w.message}
253
249
  `);
254
250
  }
255
251
  }