@outerlayer/cli 0.8.0 → 0.8.2

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 (91) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +27 -9
  3. package/dist/{agent-setup-C7PLRXZO.js → agent-setup-C5X4356W.js} +10 -10
  4. package/dist/{build-MS34XEGN.js → build-3FSJR5OO.js} +1 -1
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-G52A6GW2.js → builder-QZA2Z3M3.js} +3 -3
  7. package/dist/{check-FOF3PUKI.js → check-HQHFAOXW.js} +30 -29
  8. package/dist/{chunk-R7STSBLC.js → chunk-2E2MG3KW.js} +1 -1
  9. package/dist/{chunk-OD2VTIHN.js → chunk-2FWL7CE2.js} +3 -2
  10. package/dist/{chunk-K35RW5HP.js → chunk-33GOCSRO.js} +4 -4
  11. package/dist/{chunk-4A5E2G4E.js → chunk-3J476JZC.js} +11 -11
  12. package/dist/{chunk-MQ3IPHIZ.js → chunk-47RS42OZ.js} +6 -3
  13. package/dist/{chunk-3S4P55NE.js → chunk-4ZZR5SKG.js} +3 -3
  14. package/dist/{chunk-PWBILI5P.js → chunk-7KI224YS.js} +1 -1
  15. package/dist/{chunk-5TNS3PL7.js → chunk-CLURXEWV.js} +4 -3
  16. package/dist/{chunk-7ZR5UPMB.js → chunk-CMFCCIQN.js} +167 -1
  17. package/dist/{chunk-AX23QKHS.js → chunk-CRLAB4PM.js} +1 -1
  18. package/dist/{chunk-CM5QTKM4.js → chunk-EQG7L6LM.js} +311 -29
  19. package/dist/{chunk-OEK4JEB3.js → chunk-ERI5GBNI.js} +18 -3
  20. package/dist/{chunk-ILEA3YHM.js → chunk-EWBM2USM.js} +2 -2
  21. package/dist/{chunk-EV3M3EH7.js → chunk-G54QHBTI.js} +2 -2
  22. package/dist/{chunk-M3SQ4YGD.js → chunk-GXSMDL4M.js} +1 -1
  23. package/dist/{chunk-GAYWY4GI.js → chunk-HN2JBGSI.js} +2 -1
  24. package/dist/{chunk-ZOAEPWGL.js → chunk-HWMYGAKF.js} +1 -1
  25. package/dist/chunk-I2UOAV7X.js +133 -0
  26. package/dist/{chunk-ABIWDUMS.js → chunk-IS4DIGBQ.js} +13 -1
  27. package/dist/{chunk-WVGSB3Z2.js → chunk-J5DPVNL3.js} +2 -2
  28. package/dist/{chunk-VXLJORHL.js → chunk-JXH6LEEH.js} +1 -1
  29. package/dist/{chunk-JPR2WHHF.js → chunk-KI7VPNKC.js} +1 -1
  30. package/dist/{chunk-TUUMW4TC.js → chunk-LSPJHYHM.js} +1 -1
  31. package/dist/{chunk-7VNURP6M.js → chunk-M2F2RAMK.js} +82 -26
  32. package/dist/{chunk-NALVDFIS.js → chunk-MJLUWGUD.js} +2 -2
  33. package/dist/{chunk-5FWNEQNZ.js → chunk-NACLOOXP.js} +5 -5
  34. package/dist/{chunk-U3GOI2B4.js → chunk-NPBLDMSD.js} +1 -1
  35. package/dist/{chunk-BOLTI6LR.js → chunk-PLMTLGYH.js} +1 -1
  36. package/dist/{chunk-IRCBTGWF.js → chunk-QJPO42VI.js} +6 -6
  37. package/dist/{chunk-5QLNZGAQ.js → chunk-R5SPFO6F.js} +6 -6
  38. package/dist/{chunk-M5POMKKW.js → chunk-V7NIVOFD.js} +5 -5
  39. package/dist/{chunk-IJBVPLZZ.js → chunk-VUGDEUMM.js} +71 -143
  40. package/dist/{chunk-4ACZCY4I.js → chunk-WMPO3SKK.js} +3 -3
  41. package/dist/{chunk-TTNFGMHO.js → chunk-Y7UQHKFY.js} +19 -1
  42. package/dist/{chunk-BCLJSQCV.js → chunk-YO4PSLVB.js} +1 -1
  43. package/dist/{chunk-AIL2R4SI.js → chunk-YU4Z2O3W.js} +5 -5
  44. package/dist/{chunk-ZZXLM64C.js → chunk-ZJ3WRVRG.js} +1 -1
  45. package/dist/{cli-AOJPAVFX.js → cli-OWM54BIU.js} +120 -93
  46. package/dist/{command-SY3SVLAI.js → command-LIHTWJHQ.js} +31 -25
  47. package/dist/{config-Z3USDBLU.js → config-OOBPCY7Q.js} +2 -2
  48. package/dist/{connect-cmd-PNZ6IJLJ.js → connect-cmd-NV7WVBY7.js} +3 -3
  49. package/dist/{context-adopt-CE4KDXS3.js → context-adopt-PPCNSN5D.js} +7 -7
  50. package/dist/{context-materialize-QL33HDJN.js → context-materialize-YR3JQCUF.js} +7 -7
  51. package/dist/{dist-3ZTZF2TP.js → dist-2LNAXGPZ.js} +1 -1
  52. package/dist/{docker-676FD3CQ.js → docker-RSALMGPL.js} +4 -4
  53. package/dist/{doctor-WR6TRPSU.js → doctor-PKT42NOJ.js} +59 -25
  54. package/dist/{emit-artifact-cmd-AVM4YXMQ.js → emit-artifact-cmd-BZYXRBCV.js} +8 -8
  55. package/dist/{emit-cmd-2QRMYPYO.js → emit-cmd-IRYNFHPM.js} +3 -3
  56. package/dist/{emit-criteria-cmd-LDBE4YDS.js → emit-criteria-cmd-PSZYZ32B.js} +6 -6
  57. package/dist/{emit-finding-cmd-6R5WBPCH.js → emit-finding-cmd-VTSYDJYZ.js} +6 -6
  58. package/dist/{emit-result-cmd-2DMN6O6U.js → emit-result-cmd-5P7ZFWMZ.js} +8 -8
  59. package/dist/{exec-client-NPYNUAF3.js → exec-client-2UX6NHAO.js} +3 -3
  60. package/dist/{guest-init-JWNNAH2H.js → guest-init-VHQNFCFS.js} +3 -3
  61. package/dist/{hook-fast-XBOZ3N6L.js → hook-fast-OCHVQZTU.js} +1 -1
  62. package/dist/{host-key-KDYZ5ECC.js → host-key-YMLXY6QB.js} +1 -1
  63. package/dist/{import-capture-cmd-T4556ELW.js → import-capture-cmd-2QFLZQFY.js} +3 -3
  64. package/dist/{import-ruler-cmd-SG3UVGI7.js → import-ruler-cmd-BD22GUJS.js} +1 -1
  65. package/dist/index.js +3 -3
  66. package/dist/{init-R2FJ5KNS.js → init-CY4IMZE4.js} +22 -22
  67. package/dist/{init-KDK5QLQZ.js → init-TQUN5RF7.js} +20 -20
  68. package/dist/{init-cmd-BYZYAJ5P.js → init-cmd-F4TZXQJH.js} +11 -11
  69. package/dist/{install-FHTVJZS6.js → install-C33LT5KQ.js} +3 -3
  70. package/dist/{install-cmd-DCF7TVXD.js → install-cmd-5HYMXLEW.js} +2 -1
  71. package/dist/{loop-AG3PLXPO.js → loop-NZP5FAC3.js} +30 -29
  72. package/dist/{machine-LV6WBRRK.js → machine-RUSNVLKO.js} +19 -19
  73. package/dist/{mcp-install-cmd-RLK4SO3N.js → mcp-install-cmd-4AQMSIGY.js} +1 -1
  74. package/dist/{mcp-serve-cmd-N6UD2KBX.js → mcp-serve-cmd-3KVYEUXG.js} +3 -3
  75. package/dist/{real-deps-SU24ZA2K.js → real-deps-TK6JMQSW.js} +3 -2
  76. package/dist/{session-sender-Q5HAMOL2.js → session-sender-EECVKXTC.js} +7 -7
  77. package/dist/{starter-pack-MUXMAU4S.js → starter-pack-VNWPYP5U.js} +3 -3
  78. package/dist/{status-HH4OSOHR.js → status-KCONQLOD.js} +31 -25
  79. package/dist/{sync-cmd-CAEPJR7B.js → sync-cmd-R54ZBHXX.js} +6 -6
  80. package/dist/{watch-LAAZFBHH.js → watch-YTFNBO3S.js} +6 -6
  81. package/dist/{work-claim-cmd-ARIYZARE.js → work-claim-cmd-HRPJ4VUF.js} +10 -10
  82. package/dist/{work-cmd-B3FOXZAL.js → work-cmd-W4GQUUBC.js} +7 -7
  83. package/dist/{work-comment-cmd-O5WGRI6K.js → work-comment-cmd-DDZ4SZ35.js} +7 -7
  84. package/dist/{work-open-pr-cmd-M6CQW7KW.js → work-open-pr-cmd-GXULDTSC.js} +8 -8
  85. package/dist/{work-pr-cmd-C4YEGKD6.js → work-pr-cmd-T6SU4TYN.js} +7 -7
  86. package/package.json +2 -2
  87. package/skill-pack/maintained/amend/SKILL.md +22 -6
  88. package/skill-pack/maintained/outerlayer/SKILL.md +12 -2
  89. package/skill-pack/maintained/outerlayer/references/open-pull-request.md +29 -0
  90. package/skill-pack/template/build/SKILL.md +3 -2
  91. package/skill-pack/template/build/references/release.md +11 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - a90aed2: Name the right command or source in three messages. A missing credential now reads "a login or OUTERLAYER_API_KEY" instead of the deprecated `--api-key` flag. `work claim` and `work renew` help says the API key holds a lease, not the host. `import capture` tells you to run `outerlayer context emit`.
8
+ - aa88449: `outerlayer doctor` on a runner host has a new "Build hosts" check. With `builtin:container` or `builtin:vm` hooks and no `runner.build.allowHosts`, it warns that a build can reach every public host. Its fix line lists the public hosts past builds reached, read from each job's tunnel record, ready to review and paste into `allowHosts`. With the list set, the check passes.
9
+ - 6cb841e: A host check can now read the work item, the diff and the agent's sessions from the folder that `OUTERLAYER_EVAL_INPUT` names. The code that extracts commands from a session is now exported from `@outerlayer/context-format`.
10
+ - 0ac3dfe: `outerlayer mcp install` writes its entry into `.outerlayer/mcp.json` when that file exists, so the next `outerlayer context emit` keeps it.
11
+ - 91fcd91: A session's local cost estimate counts a negative, NaN or infinite token count as zero tokens, so a corrupt transcript can no longer give a negative or NaN cost.
12
+ - 75423c1: The README's privacy section says what the runner heartbeat, the npm self-update and `emit artifact` send, and how `OUTERLAYER_TIER` and a factory key affect uploads.
13
+ - 87c0cdc: `work claim`, `work renew` and `work release` describe the lease as held by the API key, not the host, which matches how the gateway decides. `work release` help also says a lease held by a different key is refused.
14
+ - dca9a52: A runner build whose command exits 0 while its work item has no pull request is now released `incomplete`, not `ok`. The build skill's pull request step points to a new maintained file, `.outerlayer/skills/outerlayer/references/open-pull-request.md`. It tells a runner build to open its pull request with `outerlayer work open-pr`, and a local session to use `gh pr create` and `outerlayer work pr <number>`. Run `outerlayer context emit` to pick up the new copy.
15
+ - 3b4943d: Upgrading a runner by hand no longer needs a root restart. After `outerlayer runner install` points `current` at a different version, a runner its service started through `current` takes no new work, waits for its running builds to finish, and exits so the service starts the new version. The new version runs its checks at its first start and goes back to the previous one if they fail, as a self-update does. `runner install` says this when it moves `current`. A runner started by hand with `outerlayer runner start` keeps running and logs that a restart picks the new version up.
16
+ - 19e8d45: `outerlayer runner status --recent` marks an attempt whose claim someone else released first as "(already released)", not "(release failed)".
17
+ - 92b9091: `outerlayer runner init --vm` now gives the Mac's Linux VM enough CPUs for every build to have whole cores of its own. Each container build is pinned to `runner.build.cpus` cores, rounded up. The VM gets that count times `concurrency`, plus one, still capped at the Mac's CPUs. With a fractional `runner.build.cpus`, the VM was sized from the rounded-up product instead, so builds running at once shared a core. For example, four builds of 2.5 CPUs now get a 13-CPU VM rather than 11.
18
+
19
+ ## 0.8.1
20
+
21
+ ### Patch Changes
22
+
23
+ - 2bfa3a8: The `amend` skill now works in a build a runner started. It posts its closing report on the work item's general thread with `outerlayer work comment`, because a build's GitHub token cannot comment on the pull request. A local session posts the report there too, and still comments on the pull request. The SSH keep-alive advice for a dropped push now applies only to a local session pushing over SSH. Run `outerlayer context emit` to pick up the new copy.
24
+ - d2ad3fc: A microVM build's root disk and build disk are made in containers held to `runner.build.memory`, with no swap, like the build's image builds. Docker runs those containers outside the runner's own cgroup, so nothing else limited them.
25
+ - cf56a33: Three runner fixes:
26
+
27
+ - `outerlayer runner install` no longer moves a runner back to an older version. When the CLI you run is older than the version the runner updated itself to, the command refuses and names both versions. Run `~/.local/bin/outerlayer runner install` instead, which runs the newer version. Pass `--allow-downgrade` to install the older one on purpose. `runner install --service` and `runner init` refuse the same way.
28
+ - Housekeeping no longer logs an error when the runner's image builder has not started yet. It leaves the build cache for a later pass and logs that it did.
29
+ - A container build now sees only its own CPU cores: `runner.build.cpus`, rounded up. `nproc` inside the build reports that count, not the host's. Builds running at once get different cores while the host has enough. `runner.build.cpus` stays the limit.
30
+
31
+ - 857e376: Update the bundled `structured-headers` library from 2.0.3 to 2.1.0. The runner uses it to sign its requests to the gateway; signed requests are unchanged.
32
+
3
33
  ## 0.8.0
4
34
 
5
35
  ### Minor Changes
package/README.md CHANGED
@@ -40,7 +40,8 @@ and never upload.
40
40
  sessions.** It runs when you run it. The hooks also fire `outerlayer sync
41
41
  --quiet` in the background after each agent turn and when a session ends, at
42
42
  most once every five minutes, as soon as `outerlayer login` has saved
43
- credentials and `outerlayer connect` has chosen the repository's factory. So a launched session uploads while it is still running, not
43
+ credentials and `outerlayer connect` has chosen the repository's factory,
44
+ or a factory key is saved. So a launched session uploads while it is still running, not
44
45
  only once it is over. Set `"autoSync": false` in `~/.outerlayer/config.json`
45
46
  to leave every automatic upload — the background sync and the daemon's
46
47
  streaming below — to your own command.
@@ -99,6 +100,10 @@ content:
99
100
  the end of every poll: the host, the CLI version, the poll interval, the
100
101
  slots in use and total, and the result of that poll's own request for
101
102
  work — success, or the error code and message the platform returned.
103
+ After a self-update it adds the update's outcome. While the runner holds
104
+ off for want of disk it adds the free and needed bytes. While a check of
105
+ its own stops it claiming, it adds one sentence saying why, which can
106
+ include the host's usable memory and Docker's own error text, unscrubbed.
102
107
  When a build's command exits 0, it reads that work item once more, for its
103
108
  evidence verdict, before releasing it: it sends nothing but the request.
104
109
  Just before that read, the runner runs the repository's host checks. A host
@@ -107,6 +112,13 @@ content:
107
112
  command in a new container, and sends one `POST /v1/emitted-results` for
108
113
  each: the check's name, pass or fail, and for a fail the exit status and the
109
114
  last line of its output, scrubbed.
115
+ Before each check's command runs, the runner writes a read-only folder for it
116
+ to read: the work item, from `GET /v1/work-items/{id}` with the runner's own
117
+ key; the branch's diff, from `git fetch` of the build's commits with the
118
+ host's own git credentials; and the build's sessions, copied out of the
119
+ build's own container or microVM and scrubbed of every key the runner holds.
120
+ The check's environment holds no key and nothing in that folder leaves the
121
+ host.
110
122
  Before a build's command starts, the runner also runs `git ls-remote` and
111
123
  `git fetch` in the job's workdir, with the host's own git credentials, to
112
124
  put it on the branch the claim named. Nothing about the job leaves the host
@@ -116,9 +128,11 @@ content:
116
128
  (`registry.npmjs.org`) for `@outerlayer/cli` only: that version's metadata
117
129
  at once, and once no build is in flight, its tarball and its provenance
118
130
  attestation, plus an `npm install` and an `npm audit signatures` run
119
- against that same registry. The calls carry no credentials and nothing
120
- about the host or the factory. Set `runner.autoUpdate` to `false` to stop
121
- them.
131
+ against that same registry. The runner's own requests carry no
132
+ credentials and nothing about the host or the factory. `npm install` also
133
+ fetches the package's dependencies, and both npm runs use this user's npm
134
+ configuration, including any registry token in `~/.npmrc`. Set
135
+ `runner.autoUpdate` to `false` to stop them.
122
136
  `runner check` makes a list call and a host-key lookup to confirm the key
123
137
  works and sends nothing else; `runner status` and `runner logs` make no network call at all.
124
138
  On a runner host, any command that uses the saved runner key signs each
@@ -142,7 +156,7 @@ content:
142
156
  - **`outerlayer work`** and **`outerlayer emit`**, in the subcommands named below, with a login and no saved
143
157
  connection for the repository send the same `GET /v1/me/factories?repository=<host/owner/name>`
144
158
  request before their own, to connect the repository when exactly one factory
145
- fits. They send nothing extra with a factory key, `--app-id` or `OUTERLAYER_APP_ID`. The subcommands are `work build`, `list`, `status`, `remove` and `pr`, and `emit artifact`, `result`, `criteria`, `finding` and `findings`. Other `work` subcommands never connect.
159
+ fits. They send nothing extra with a factory key, `--app-id` or `OUTERLAYER_APP_ID`. The subcommands are `work build`, `list`, `status`, `remove` and `pr`, and `emit artifact`, `criteria`, `finding`, `findings` and `emit <name>`. Other `work` subcommands never connect.
146
160
  - **`outerlayer connect`**, and the first step of `outerlayer init`, send a
147
161
  request with your login's token: `GET /v1/me/factories?repository=<host/owner/name>`,
148
162
  naming this checkout's remote. The gateway answers with the factories you can
@@ -259,7 +273,10 @@ content:
259
273
  `git ls-remote` against that control plane with the host's own git
260
274
  credentials, to say whether the host can read it.
261
275
  - **`outerlayer emit artifact`** uploads the file you name — a screenshot, a
262
- recording, a report, a log — along with its caption. With no recorded
276
+ recording, a report, a log — along with its caption, its name, type, size
277
+ and sha256, and the repository, branch, commit, pull request and CI run it
278
+ came from. The file is sent as it is: the secret scrub applies to session
279
+ content, not to files you emit. With no recorded
263
280
  session to attach it to, it uploads immediately, anchored to a pull request
264
281
  or to the git checkout.
265
282
  - **`outerlayer emit <name>`** sends one check's outcome for a work item.
@@ -316,8 +333,9 @@ before it gives up.
316
333
  `full`: message text, thinking, images, and tool input/output all ship.
317
334
  `--tier redacted` strips that content client-side, keeping only structure
318
335
  (repos, branches, file paths, tool names, error signatures) and metrics;
319
- `--tier metrics` strips identifiers too (the server additionally clamps to
320
- your org's configured ceiling — sending more than it allows stores less).
336
+ `--tier metrics` strips identifiers too. `OUTERLAYER_TIER` sets the tier
337
+ when `--tier` is absent. The server also clamps to your org's configured
338
+ ceiling: sending more than it allows stores less.
321
339
  - **`--dry-run` shows exactly what would leave** — per-session rows, image
322
340
  bytes, and the precise field classes stripped at the chosen tier. Add
323
341
  `--json` to inspect the literal request payloads. Zero network calls.
@@ -353,7 +371,7 @@ before it gives up.
353
371
  | `outerlayer work open-pr --title <text> --body-file <path> [--repo] [--session-id] [--json]` | Opens the pull request for the work item this session is on, or edits the one already open on its branch. A host build, which holds an item key, sends it to the gateway, which opens it as the factory's GitHub App from the branch the claim named; no `gh` command runs. Your own session runs `gh pr create` or `gh pr edit` under your login and then declares the pull request on the item. Run it again after changing the title or description. |
354
372
  | `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. |
355
373
  | `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`). |
356
- | `outerlayer work release --item <n>\|--issue <n> [--repo] [--host] [--outcome]` | Marks this host's lease released, optionally recording how the attempt ended. Releasing an already-released lease is a no-op that returns the recorded release time and outcome. |
374
+ | `outerlayer work release --item <n>\|--issue <n> [--repo] [--host] [--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. |
357
375
  | `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. |
358
376
  | `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. |
359
377
  | `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. |
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { addStdioMcpEntryIfAbsent } from './chunk-MQ3IPHIZ.js';
4
- import { installStarterPack } from './chunk-M3SQ4YGD.js';
5
- import { runEmit } from './chunk-EV3M3EH7.js';
3
+ import { addStdioMcpEntryIfAbsent } from './chunk-47RS42OZ.js';
4
+ import { installStarterPack } from './chunk-GXSMDL4M.js';
5
+ import { runEmit } from './chunk-G54QHBTI.js';
6
6
  import { C } from './chunk-YRYMNBGQ.js';
7
- import { resolveGitCommonDir, defaultGitRunner } from './chunk-5FWNEQNZ.js';
7
+ import { resolveGitCommonDir, defaultGitRunner } from './chunk-NACLOOXP.js';
8
8
  import './chunk-ZJSNLVCE.js';
9
- import { pinExists, readContextManifest } from './chunk-ZZXLM64C.js';
10
- import { loadTemplateFiles, loadMaintainedFiles, skillDir } from './chunk-VXLJORHL.js';
11
- import { generatedHeaderSource } from './chunk-7ZR5UPMB.js';
12
- import './chunk-BCLJSQCV.js';
13
- import './chunk-BOLTI6LR.js';
9
+ import { pinExists, readContextManifest } from './chunk-ZJ3WRVRG.js';
10
+ import { loadTemplateFiles, loadMaintainedFiles, skillDir } from './chunk-JXH6LEEH.js';
11
+ import { generatedHeaderSource } from './chunk-CMFCCIQN.js';
12
+ import './chunk-YO4PSLVB.js';
13
+ import './chunk-PLMTLGYH.js';
14
14
  import './chunk-YNJEOGDL.js';
15
15
  import './chunk-EABW6AJQ.js';
16
16
  import './chunk-RA3O54FC.js';
17
- import './chunk-M5POMKKW.js';
17
+ import './chunk-V7NIVOFD.js';
18
18
  import './chunk-ZM2IMMYN.js';
19
19
  import './chunk-XCCLFVXM.js';
20
20
  import './chunk-BJ3KTMDH.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { buildRepositoryImage } from './chunk-TTNFGMHO.js';
3
+ export { buildRepositoryImage } from './chunk-Y7UQHKFY.js';
4
4
  import './chunk-N5FOE5PS.js';
5
5
  export { RecipeError } from './chunk-QOZKPLVJ.js';
6
6
  import './chunk-CX22S5BA.js';
@@ -1 +1 @@
1
- {"id":"2026-10-05T12:31:55.812Z+ff35a38","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-05T19:17:15.230Z+79d273b","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,10 +1,10 @@
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-5TNS3PL7.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-CLURXEWV.js';
4
4
  import './chunk-CX22S5BA.js';
5
- import './chunk-GAYWY4GI.js';
5
+ import './chunk-HN2JBGSI.js';
6
6
  import './chunk-7RQ73DLO.js';
7
- import './chunk-OD2VTIHN.js';
7
+ import './chunk-2FWL7CE2.js';
8
8
  import './chunk-HKMPVPO7.js';
9
9
  import './chunk-YNJEOGDL.js';
10
10
  import './chunk-ZM2IMMYN.js';
@@ -1,64 +1,65 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-IJBVPLZZ.js';
4
- import './chunk-ABIWDUMS.js';
5
- import './chunk-7VNURP6M.js';
3
+ import { probeCredentials } from './chunk-VUGDEUMM.js';
4
+ import './chunk-IS4DIGBQ.js';
5
+ import './chunk-I2UOAV7X.js';
6
+ import './chunk-M2F2RAMK.js';
6
7
  import './chunk-T6OIJQRT.js';
7
8
  import './chunk-AIW6GLET.js';
8
9
  import './chunk-UGP76IZ5.js';
9
- import './chunk-3S4P55NE.js';
10
- import './chunk-WVGSB3Z2.js';
11
- import './chunk-AIL2R4SI.js';
10
+ import './chunk-4ZZR5SKG.js';
11
+ import './chunk-J5DPVNL3.js';
12
+ import './chunk-YU4Z2O3W.js';
12
13
  import './chunk-HHJDN6AU.js';
13
- import { placeholderQueues, placeholderProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-IRCBTGWF.js';
14
+ import { placeholderQueues, placeholderProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-QJPO42VI.js';
14
15
  import './chunk-TI7B7UEO.js';
15
16
  import './chunk-YYYRBYWG.js';
16
17
  import './chunk-TBT347UY.js';
17
- import './chunk-NALVDFIS.js';
18
- import './chunk-TUUMW4TC.js';
19
- import './chunk-CM5QTKM4.js';
18
+ import './chunk-MJLUWGUD.js';
19
+ import './chunk-LSPJHYHM.js';
20
+ import './chunk-EQG7L6LM.js';
20
21
  import './chunk-JKIWMRFH.js';
21
- import './chunk-TTNFGMHO.js';
22
+ import './chunk-Y7UQHKFY.js';
22
23
  import './chunk-N5FOE5PS.js';
23
24
  import './chunk-OGFGZQA3.js';
24
- import './chunk-U3GOI2B4.js';
25
+ import './chunk-NPBLDMSD.js';
25
26
  import './chunk-QOZKPLVJ.js';
26
- import './chunk-5TNS3PL7.js';
27
+ import './chunk-CLURXEWV.js';
27
28
  import './chunk-CX22S5BA.js';
28
- import './chunk-ZOAEPWGL.js';
29
- import './chunk-R7STSBLC.js';
29
+ import './chunk-HWMYGAKF.js';
30
+ import './chunk-2E2MG3KW.js';
30
31
  import './chunk-F7CU5ABH.js';
31
32
  import './chunk-BKO6JEZI.js';
32
- import './chunk-5QLNZGAQ.js';
33
- import './chunk-4ACZCY4I.js';
33
+ import './chunk-R5SPFO6F.js';
34
+ import './chunk-WMPO3SKK.js';
34
35
  import './chunk-BFESLKPP.js';
35
- import './chunk-ILEA3YHM.js';
36
+ import './chunk-EWBM2USM.js';
36
37
  import './chunk-ZYHKJKSU.js';
37
- import './chunk-GAYWY4GI.js';
38
+ import './chunk-HN2JBGSI.js';
38
39
  import './chunk-USO2DKBD.js';
39
40
  import './chunk-N6LURUEF.js';
40
41
  import './chunk-YRYMNBGQ.js';
41
- import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-PWBILI5P.js';
42
+ import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-7KI224YS.js';
42
43
  import './chunk-UXYLWVTQ.js';
43
44
  import './chunk-7RQ73DLO.js';
44
- import './chunk-OD2VTIHN.js';
45
+ import './chunk-2FWL7CE2.js';
45
46
  import './chunk-HKMPVPO7.js';
46
47
  import './chunk-GQD22KKN.js';
47
48
  import './chunk-WZBHBH3J.js';
48
49
  import './chunk-5QRP3MVS.js';
49
- import './chunk-5FWNEQNZ.js';
50
+ import './chunk-NACLOOXP.js';
50
51
  import './chunk-ZJSNLVCE.js';
51
- import './chunk-ZZXLM64C.js';
52
- import './chunk-VXLJORHL.js';
53
- import './chunk-7ZR5UPMB.js';
54
- import './chunk-BCLJSQCV.js';
55
- import './chunk-BOLTI6LR.js';
52
+ import './chunk-ZJ3WRVRG.js';
53
+ import './chunk-JXH6LEEH.js';
54
+ import './chunk-CMFCCIQN.js';
55
+ import './chunk-YO4PSLVB.js';
56
+ import './chunk-PLMTLGYH.js';
56
57
  import './chunk-YNJEOGDL.js';
57
58
  import './chunk-EABW6AJQ.js';
58
59
  import './chunk-RA3O54FC.js';
59
- import './chunk-M5POMKKW.js';
60
+ import './chunk-V7NIVOFD.js';
60
61
  import './chunk-ZM2IMMYN.js';
61
- import './chunk-JPR2WHHF.js';
62
+ import './chunk-KI7VPNKC.js';
62
63
  import './chunk-XCCLFVXM.js';
63
64
  import './chunk-BJ3KTMDH.js';
64
65
  import './chunk-VNVZDWO3.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RELAY_PORT, GATEWAY_SOCKET, GATEWAY_PORT, CLAUDE_SOCKET, CLAUDE_PORT, DESTINATION_BASE_PORT } from './chunk-OD2VTIHN.js';
3
+ import { RELAY_PORT, GATEWAY_SOCKET, GATEWAY_PORT, CLAUDE_SOCKET, CLAUDE_PORT, DESTINATION_BASE_PORT } from './chunk-2FWL7CE2.js';
4
4
  import { symlinkSync, unlinkSync } from 'fs';
5
5
  import { join } from 'path';
6
6
 
@@ -348,6 +348,7 @@ async function startBuildServices(input) {
348
348
  // src/runner/container/environment.ts
349
349
  var RELAY_PORT = 3128;
350
350
  var JOB_MOUNT = "/outerlayer/job";
351
+ var EVAL_INPUT_DIR = `${JOB_MOUNT}/eval-input`;
351
352
  var CHECKOUT_DIR = "/build/work/checkout";
352
353
  var MAX_HOSTS = 200;
353
354
  function tokenVariables() {
@@ -464,7 +465,7 @@ function checkEnvironment(input) {
464
465
  builtIns: false
465
466
  });
466
467
  const withheld = /* @__PURE__ */ new Set(["OUTERLAYER_URL", "OUTERLAYER_API_KEY", ...CLAUDE_CREDENTIAL_VARIABLES]);
467
- const literals = {};
468
+ const literals = { OUTERLAYER_EVAL_INPUT: EVAL_INPUT_DIR };
468
469
  for (const [name, value] of Object.entries(env.literals)) if (!withheld.has(name)) literals[name] = value;
469
470
  const passed = {};
470
471
  for (const [name, value] of Object.entries(env.passed)) if (!withheld.has(name)) passed[name] = value;
@@ -503,4 +504,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
503
504
  };
504
505
  }
505
506
 
506
- export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseIsolation, proxyEnvironment, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
507
+ export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseIsolation, proxyEnvironment, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { autoConnect } from './chunk-4ACZCY4I.js';
3
+ import { autoConnect } from './chunk-WMPO3SKK.js';
4
4
  import { detectActiveSession } from './chunk-BFESLKPP.js';
5
- import { resolveRepoIdentity } from './chunk-GAYWY4GI.js';
5
+ import { resolveRepoIdentity } from './chunk-HN2JBGSI.js';
6
6
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
7
- import { defaultFetch } from './chunk-BCLJSQCV.js';
8
- import { unauthorizedMessage, resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
7
+ import { defaultFetch } from './chunk-YO4PSLVB.js';
8
+ import { unauthorizedMessage, resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
9
9
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
10
10
 
11
11
  createRequire(import.meta.url);
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { readStatuslineState, STATE_FRESH_MS } from './chunk-F47JBIAW.js';
4
- import { resolveCredentials, getJson, WorkCommandError } from './chunk-5QLNZGAQ.js';
5
- import { isLinkedRepository } from './chunk-ILEA3YHM.js';
4
+ import { resolveCredentials, getJson, WorkCommandError } from './chunk-R5SPFO6F.js';
5
+ import { isLinkedRepository } from './chunk-EWBM2USM.js';
6
6
  import { sanitizeTerminal } from './chunk-ZYHKJKSU.js';
7
- import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-GAYWY4GI.js';
7
+ import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-HN2JBGSI.js';
8
8
  import { C } from './chunk-YRYMNBGQ.js';
9
9
  import { readSettings, settingsPath, isOurStatuslineSlot, statuslineWrappedOriginal, REGISTERED_EVENTS, isOurHookCommand, ourCommandBins, cliBinResolvable, ourDirectScriptBins, wrappedOriginalCommand } from './chunk-5QRP3MVS.js';
10
- import { readPin, readContextManifest, readDegraded, readSourceCache } from './chunk-ZZXLM64C.js';
11
- import { defaultFetch } from './chunk-BCLJSQCV.js';
12
- import { resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
10
+ import { readPin, readContextManifest, readDegraded, readSourceCache } from './chunk-ZJ3WRVRG.js';
11
+ import { defaultFetch } from './chunk-YO4PSLVB.js';
12
+ import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
13
13
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
14
- import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-JPR2WHHF.js';
14
+ import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-KI7VPNKC.js';
15
15
  import { deadHooksState, preparePackageManagerCommand, contextExcludesPresent } from './chunk-XCCLFVXM.js';
16
16
  import { findGitDirs } from './chunk-BJ3KTMDH.js';
17
17
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -1004,7 +1004,7 @@ function doctorExitCode(checks) {
1004
1004
 
1005
1005
  // src/doctor-report.ts
1006
1006
  async function gatherDoctorChecks() {
1007
- const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-Z3USDBLU.js');
1007
+ const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-OOBPCY7Q.js');
1008
1008
  const configPath = defaultRunnerConfigPath();
1009
1009
  const checks = runDoctor({ runnerHost: hasRunnerBlock(configPath) });
1010
1010
  const credential = await credentialChecks();
@@ -1016,7 +1016,7 @@ async function gatherDoctorChecks() {
1016
1016
  const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
1017
1017
  checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
1018
1018
  } else if (hasRunnerBlock(configPath)) {
1019
- const { runnerHostChecks } = await import('./doctor-WR6TRPSU.js');
1019
+ const { runnerHostChecks } = await import('./doctor-PKT42NOJ.js');
1020
1020
  const hooks = (() => {
1021
1021
  try {
1022
1022
  return loadRunnerConfig(configPath).hooks;
@@ -1042,7 +1042,7 @@ async function gatherDoctorChecks() {
1042
1042
  const runner = (() => {
1043
1043
  try {
1044
1044
  const { concurrency, build, housekeeping } = loadRunnerConfig(configPath);
1045
- return { concurrency, buildMemory: build?.memory ?? "8g", minFreeDisk: housekeeping?.minFreeDisk };
1045
+ return { concurrency, buildMemory: build?.memory ?? "8g", minFreeDisk: housekeeping?.minFreeDisk, allowHosts: build?.allowHosts };
1046
1046
  } catch {
1047
1047
  return void 0;
1048
1048
  }
@@ -1051,7 +1051,7 @@ async function gatherDoctorChecks() {
1051
1051
  const { existsSync: existsSync2 } = await import('fs');
1052
1052
  if (process.platform !== "linux" || !existsSync2("/run/systemd/system")) return void 0;
1053
1053
  const { inspectService, realInspectProbes } = await import('./inspect-XAUSB7L3.js');
1054
- const { DEFAULT_UNIT_NAME } = await import('./install-FHTVJZS6.js');
1054
+ const { DEFAULT_UNIT_NAME } = await import('./install-C33LT5KQ.js');
1055
1055
  const { dirname: dirname2 } = await import('path');
1056
1056
  return inspectService(DEFAULT_UNIT_NAME, dirname2(configPath), realInspectProbes());
1057
1057
  })();
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { C } from './chunk-YRYMNBGQ.js';
4
4
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
5
- import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
5
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'fs';
6
6
  import { join, dirname } from 'path';
7
7
 
8
8
  createRequire(import.meta.url);
@@ -44,8 +44,11 @@ function readMcpDoc(absPath, relPath) {
44
44
  }
45
45
  return doc;
46
46
  }
47
+ function mcpTargetPath(repoRoot) {
48
+ return existsSync(join(repoRoot, ".outerlayer", "mcp.json")) ? ".outerlayer/mcp.json" : ".mcp.json";
49
+ }
47
50
  function addStdioMcpEntryIfAbsent(repoRoot, name = "outerlayer") {
48
- const relPath = existsSync(join(repoRoot, ".outerlayer", "mcp.json")) ? ".outerlayer/mcp.json" : ".mcp.json";
51
+ const relPath = mcpTargetPath(repoRoot);
49
52
  const absPath = join(repoRoot, relPath);
50
53
  const doc = readMcpDoc(absPath, relPath);
51
54
  const servers = doc.mcpServers;
@@ -66,7 +69,7 @@ function runMcpInstall(opts = {}) {
66
69
  const name = opts.name ?? "outerlayer";
67
70
  const transport = opts.transport ?? DEFAULT_MCP_TRANSPORT;
68
71
  const url = transport === "http" ? opts.url ?? defaultMcpUrl(opts.home) : opts.url ?? null;
69
- const relPath = ".mcp.json";
72
+ const relPath = mcpTargetPath(cwd);
70
73
  const absPath = join(cwd, relPath);
71
74
  const doc = readMcpDoc(absPath, relPath);
72
75
  const existingServers = doc.mcpServers && typeof doc.mcpServers === "object" && !Array.isArray(doc.mcpServers) ? doc.mcpServers : {};
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LiveUploader } from './chunk-AIL2R4SI.js';
4
- import { CaptureDaemon } from './chunk-GAYWY4GI.js';
3
+ import { LiveUploader } from './chunk-YU4Z2O3W.js';
4
+ import { CaptureDaemon } from './chunk-HN2JBGSI.js';
5
5
  import { parseWorkItemEnv } from './chunk-GQD22KKN.js';
6
- import { spoolDir } from './chunk-JPR2WHHF.js';
6
+ import { spoolDir } from './chunk-KI7VPNKC.js';
7
7
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
8
8
  import { mkdirSync, writeFileSync, rmSync } from 'fs';
9
9
  import { join } from 'path';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { MAX_ALLOW_HOSTS, allowHostProblem } from './chunk-UXYLWVTQ.js';
4
4
  import { parseSize } from './chunk-7RQ73DLO.js';
5
- import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-OD2VTIHN.js';
5
+ import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-2FWL7CE2.js';
6
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
7
7
  import { existsSync, statSync, accessSync, constants, readFileSync } from 'fs';
8
8
  import { hostname } from 'os';
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { BUILDKIT_IMAGE } from './chunk-CX22S5BA.js';
4
- import { compareVersions } from './chunk-GAYWY4GI.js';
4
+ import { compareVersions } from './chunk-HN2JBGSI.js';
5
5
  import { parseSize } from './chunk-7RQ73DLO.js';
6
- import { JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-OD2VTIHN.js';
6
+ import { JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-2FWL7CE2.js';
7
7
  import { runnerDir } from './chunk-ZM2IMMYN.js';
8
8
  import { createHash } from 'crypto';
9
9
  import { realpathSync } from 'fs';
@@ -27,7 +27,7 @@ function runnerLabelValue(configPath) {
27
27
  return createHash("sha256").update(resolvedRunnerDir(configPath)).digest("hex").slice(0, 12);
28
28
  }
29
29
  function hardened(input) {
30
- const { memory, cpus, pids } = input.limits;
30
+ const { memory, cpus, pids, cpuset } = input.limits;
31
31
  return [
32
32
  "--label",
33
33
  `${BUILD_LABEL}=${input.buildId}`,
@@ -49,6 +49,7 @@ function hardened(input) {
49
49
  memory,
50
50
  "--cpus",
51
51
  String(cpus),
52
+ ...cpuset === void 0 ? [] : ["--cpuset-cpus", cpuset],
52
53
  "--pids-limit",
53
54
  String(pids)
54
55
  ];