@outerlayer/cli 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +11 -11
  3. package/dist/{agent-setup-K3ABU5NL.js → agent-setup-T624CWPD.js} +2 -2
  4. package/dist/artifact-link-cmd-2F47LT7F.js +24 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/{check-CNTMSGOG.js → check-5XE7XMC4.js} +14 -14
  7. package/dist/{chunk-YDSMROTB.js → chunk-3NSNIIBE.js} +8 -4
  8. package/dist/{chunk-NPQWKGUA.js → chunk-6Y5RUTHO.js} +1 -1
  9. package/dist/{chunk-6JNURGOA.js → chunk-BWQ66M6N.js} +1 -1
  10. package/dist/{chunk-R4ZQQ7U2.js → chunk-G5NPRL2K.js} +7 -8
  11. package/dist/{chunk-W3EKCZSQ.js → chunk-HGECYFEI.js} +55 -5
  12. package/dist/{chunk-5FEK6PNE.js → chunk-KG5ECZGJ.js} +1 -1
  13. package/dist/{chunk-FWX735W7.js → chunk-LWSJQJC6.js} +3 -3
  14. package/dist/{chunk-EWORLJMO.js → chunk-MAK5LYRF.js} +16 -7
  15. package/dist/{chunk-ONRCEE6D.js → chunk-NNRTPG7X.js} +2 -2
  16. package/dist/{chunk-U3HXXRTY.js → chunk-NWQTTSBB.js} +1 -1
  17. package/dist/{chunk-RSPXEVDX.js → chunk-ONKJUM6R.js} +1 -1
  18. package/dist/{chunk-6QRMLNH3.js → chunk-S3NYLI2P.js} +3 -3
  19. package/dist/{chunk-CA3XMYFN.js → chunk-VQYBXPI7.js} +3 -3
  20. package/dist/{chunk-EHAAPRWY.js → chunk-WVUIRTWA.js} +7 -7
  21. package/dist/{chunk-JJEGKEFV.js → chunk-YU3VKZ5F.js} +1 -1
  22. package/dist/{chunk-JEHRUE3F.js → chunk-YZ5F4PIS.js} +91 -20
  23. package/dist/{cli-AEWH62UE.js → cli-A76AXELQ.js} +71 -63
  24. package/dist/{command-HHPBR6CS.js → command-R2QCVX55.js} +6 -6
  25. package/dist/{connect-cmd-JUAW6MU4.js → connect-cmd-JBKAQNSF.js} +1 -1
  26. package/dist/{context-adopt-VMMGFRUZ.js → context-adopt-NFHCLVUB.js} +1 -1
  27. package/dist/{context-materialize-2WXTS4CW.js → context-materialize-IV2TUUFO.js} +1 -1
  28. package/dist/{doctor-N6Y7HKK3.js → doctor-4TAIARIG.js} +10 -9
  29. package/dist/{emit-artifact-cmd-H5MH3AOP.js → emit-artifact-cmd-MPZVR56N.js} +4 -4
  30. package/dist/{emit-criteria-cmd-HBP6XS5C.js → emit-criteria-cmd-EFGYI23V.js} +2 -2
  31. package/dist/{emit-finding-cmd-ZXDRL6PG.js → emit-finding-cmd-5GF3V4LR.js} +2 -2
  32. package/dist/{emit-result-cmd-RFKALS5Z.js → emit-result-cmd-I4OADKMD.js} +4 -4
  33. package/dist/hidden-prompt-UXBFMQC5.js +68 -0
  34. package/dist/{hook-fast-D7HV4IXG.js → hook-fast-R4FVSZ2H.js} +1 -1
  35. package/dist/index.js +3 -3
  36. package/dist/{init-MYX7YMIH.js → init-6XPDRDTC.js} +7 -7
  37. package/dist/{init-FBCA4DRA.js → init-PWU5YVL7.js} +49 -25
  38. package/dist/{init-cmd-CAG572UE.js → init-cmd-XAVO7HYZ.js} +5 -5
  39. package/dist/{init-update-VDFF4K3B.js → init-update-CVCWD6VS.js} +3 -3
  40. package/dist/{loop-75J4YXLZ.js → loop-FK3LPMMZ.js} +14 -14
  41. package/dist/{machine-A6ZCTUGS.js → machine-SQXEBAM2.js} +6 -6
  42. package/dist/runner-key-6SLBI7PP.js +174 -0
  43. package/dist/{session-sender-24L5EW25.js → session-sender-FO3LCREV.js} +3 -3
  44. package/dist/{status-XHSGEYO5.js → status-7VNQN5PW.js} +9 -9
  45. package/dist/{sync-cmd-5G5EIEHD.js → sync-cmd-GVPPFZ3G.js} +2 -2
  46. package/dist/{watch-UTOXO4SE.js → watch-23HSAEI6.js} +2 -2
  47. package/dist/{work-claim-cmd-RKHYFE5Y.js → work-claim-cmd-LKL3GHFQ.js} +5 -5
  48. package/dist/{work-cmd-DJQJEZVB.js → work-cmd-Z2WXLZPH.js} +3 -3
  49. package/dist/{work-comment-cmd-A55CUSYE.js → work-comment-cmd-AWHP56M2.js} +3 -3
  50. package/dist/{work-open-pr-cmd-E6O53IJD.js → work-open-pr-cmd-IOM4AVQQ.js} +4 -4
  51. package/dist/{work-pr-cmd-L77K32WK.js → work-pr-cmd-HNEUIEN7.js} +3 -3
  52. package/package.json +1 -1
  53. package/skill-pack/maintained/outerlayer-amend/SKILL.md +2 -0
  54. package/skill-pack/maintained/outerlayer-cli/SKILL.md +2 -0
  55. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +4 -2
  56. package/skill-pack/maintained/outerlayer-findings/SKILL.md +2 -0
  57. package/skill-pack/shipped.json +10 -3
  58. package/skill-pack/template/build/SKILL.md +2 -0
  59. package/skill-pack/template/build/references/release.md +13 -11
  60. package/skill-pack/template/build/scripts/criterion-citations.mjs +8 -3
  61. package/skill-pack/template/build/scripts/record-criteria.mjs +8 -2
  62. package/skill-pack/template/spec/SKILL.md +2 -0
  63. package/skill-pack/validators/acceptance-criteria.yaml +6 -5
  64. package/skill-pack/validators/code-review.yaml +6 -5
  65. package/dist/runner-key-W25ISHI3.js +0 -155
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 420b0db: `outerlayer runner init` takes `--factory <org>/<factory>`, the same name `outerlayer init --factory` takes, so a runner host no longer needs the Factory Id copied from the dashboard. With no factory named, a login that can use exactly one factory uses it and says which. A login that can use several is refused with each `--factory` value listed. `--app-id` still works, and a `--factory` and `--app-id` that name different factories are refused.
8
+
9
+ ### Patch Changes
10
+
11
+ - a3ac4ae: Count a test title such as `WC-01: counts words` as citing criterion WC-01. The starter `/build` skill's `criterion-citations.mjs` linked no test whose title put a colon straight after the id, so a build could report 0 of 4 criteria linked. A longer id such as `WC-010`, `WC-01a` or `WC-01:b` still does not cite WC-01.
12
+ - a897c68: The README says to install the CLI globally with `npm install -g @outerlayer/cli`, because `/build` and the other skills run the `outerlayer` command.
13
+ - 2a59794: Fix review results never being recorded on a new factory. The starter code-review and acceptance-criteria checks and the starter `/build` skill told agents to copy each report's link from the pull request's evidence comment, which a factory never posts until comments are turned on. They now take the link from the line `outerlayer sync` prints. A new `outerlayer sync --link <artifact id>` prints the link of an artifact an earlier sync already uploaded.
14
+ - 8196dc9: `outerlayer runner init` names the factory once when it picks the only one the login can use. A refused pasted key no longer repeats the gateway's "Mint a fresh key" advice beside its own step to create a new key with the Runner preset.
15
+ - 8196dc9: `outerlayer runner init` no longer tries to create the runner key with your login, which the gateway never allows. With no key in the config file, it prints the link to the factory's API keys page, asks you to paste a key made with the Runner preset (nothing is shown as you paste), checks it, and goes on. With no terminal it stops and prints the link and the config-file lines to use. `--key-name` is removed. Its output now marks warnings with `!` instead of a tick, no longer doubles ticks for lines from the VM, drops the PATH note about the VM's shell, and says whether capture on the Mac is affected when the runner key moves into the VM.
16
+ - 3ba60cd: No change in behaviour: the runner's wait for a stopped session sender's exit is simplified, and its tests check that the wait ends when the exit is logged.
17
+ - 0b7e87c: The starter skills run the CLI through `npx @outerlayer/cli` when `outerlayer` is not on PATH.
18
+ - f7553df: `outerlayer context materialize` and a container build now fetch the control plane and commit that OuterLayer stores for a repository, and read no `governs` list for it. `outerlayer doctor` reports which control plane governs the repository, its ref and the stored commit. `outerlayer connect` picks the factory that owns a repository linked to two factories, the one with the oldest connection, without asking.
19
+
3
20
  ## 0.16.1
4
21
 
5
22
  ### Patch Changes
package/README.md CHANGED
@@ -13,12 +13,13 @@ network, and when, is below.
13
13
  Launch a session naming the work it's for, then sync:
14
14
 
15
15
  ```
16
- npx @outerlayer/cli login # sign in, once per machine
17
- npx @outerlayer/cli init # connect this repository to a factory, install the capture hooks
18
- npx @outerlayer/cli work build --issue 42 --local # create the work item; prints its number
19
- OUTERLAYER_WORK=7 claude # launch a session naming that number
20
- npx @outerlayer/cli sync --dry-run # see exactly what would leave your machine
21
- npx @outerlayer/cli sync # upload sessions launched that way
16
+ npm install -g @outerlayer/cli # puts `outerlayer` on your PATH, once per machine
17
+ outerlayer login # sign in, once per machine
18
+ outerlayer init # connect this repository to a factory, install the capture hooks
19
+ outerlayer work build --issue 42 --local # create the work item; prints its number
20
+ OUTERLAYER_WORK=7 claude # launch a session naming that number
21
+ outerlayer sync --dry-run # see exactly what would leave your machine
22
+ outerlayer sync # upload sessions launched that way
22
23
  ```
23
24
 
24
25
  ## Privacy, stated plainly
@@ -144,10 +145,9 @@ content:
144
145
  to it.
145
146
  - **`outerlayer runner init`** makes no network call when the config file
146
147
  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`,
148
+ asks the gateway which factories the login can use (`GET /v1/me/factories`)
149
+ and prints the factory's API keys page. You create the key there and paste
150
+ it. It checks the pasted key, unsigned, with `GET /v1/runner/host-key`. `runner init --vm` on a Mac also runs `limactl`,
151
151
  and Lima downloads a Linux VM image. Inside the VM, `apt` downloads Node and
152
152
  `npm` downloads this CLI. Your runner key goes to the VM on the standard
153
153
  input of a `limactl shell` command and is never a file or an argument on the
@@ -391,7 +391,7 @@ before it gives up.
391
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. |
392
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`). |
393
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. |
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. |
394
+ | `outerlayer runner init [--vm\|--no-vm] [--factory <org>/<factory>] [--app-id <id>] [--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 prints the API keys page of the factory `--factory` or `--app-id` names (the only factory the login can use, when neither is given), asks you to paste a runner key made with the Runner preset, and checks it before anything else changes. With no terminal it stops and says what to put in the config. 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. |
395
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. |
396
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. |
397
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`). |
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { keepHandWritten, runAgentSetup } from './chunk-5FEK6PNE.js';
3
+ export { keepHandWritten, runAgentSetup } from './chunk-KG5ECZGJ.js';
4
4
  import './chunk-2MNPHL23.js';
5
5
  import './chunk-XCK2YAY5.js';
6
6
  import './chunk-42ZI52JW.js';
7
7
  import './chunk-YRYMNBGQ.js';
8
- import './chunk-JEHRUE3F.js';
8
+ import './chunk-YZ5F4PIS.js';
9
9
  import './chunk-WTE3MQML.js';
10
10
  import './chunk-C5Y5ZJJZ.js';
11
11
  import './chunk-ZJSNLVCE.js';
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { sanitizeTerminal, readEffectiveArtifactSpoolState } from './chunk-WUYTWNMA.js';
4
+ import './chunk-J5M7BSJQ.js';
5
+ import { homeFromEnv } from './chunk-VNVZDWO3.js';
6
+ import './chunk-Z5GEFMRW.js';
7
+
8
+ createRequire(import.meta.url);
9
+
10
+ // src/artifact-link-cmd.ts
11
+ function lookupArtifactLink(artifactId, home = homeFromEnv()) {
12
+ const shown = sanitizeTerminal(artifactId);
13
+ const entry = readEffectiveArtifactSpoolState(home).state.get(artifactId);
14
+ if (entry === void 0) return { ok: false, reason: `no artifact ${shown} is queued or uploaded on this machine` };
15
+ if (entry.state !== "uploaded") {
16
+ return { ok: false, reason: `artifact ${shown} is ${entry.state}, not uploaded yet \u2014 run \`outerlayer sync\` first` };
17
+ }
18
+ if (entry.url === void 0) {
19
+ return { ok: false, reason: `artifact ${shown} uploaded, but the gateway returned no link for it` };
20
+ }
21
+ return { ok: true, url: entry.url };
22
+ }
23
+
24
+ export { lookupArtifactLink };
@@ -1 +1 @@
1
- {"id":"2026-10-09T18:11:10.939Z+a3c670b","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-09T21:24:47.045Z+8773e8e","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,33 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-EHAAPRWY.js';
4
- import './chunk-R4ZQQ7U2.js';
3
+ import { probeCredentials } from './chunk-WVUIRTWA.js';
4
+ import './chunk-G5NPRL2K.js';
5
+ import './chunk-RMWLBUCJ.js';
5
6
  import './chunk-O765JR4W.js';
6
7
  import './chunk-UGP76IZ5.js';
7
8
  import './chunk-3JVYMD4G.js';
8
9
  import './chunk-YETTWTAY.js';
9
- import './chunk-RMWLBUCJ.js';
10
10
  import './chunk-I2UOAV7X.js';
11
+ import './chunk-NNRTPG7X.js';
11
12
  import './chunk-HYZRY4KZ.js';
12
13
  import './chunk-ADJRGVZC.js';
13
- import './chunk-ONRCEE6D.js';
14
- import './chunk-U3HXXRTY.js';
14
+ import './chunk-NWQTTSBB.js';
15
15
  import './chunk-HHJDN6AU.js';
16
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-FWX735W7.js';
16
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-LWSJQJC6.js';
17
17
  import './chunk-YYYRBYWG.js';
18
18
  import './chunk-TI7B7UEO.js';
19
19
  import './chunk-TBT347UY.js';
20
- import './chunk-CA3XMYFN.js';
21
- import './chunk-RSPXEVDX.js';
22
- import './chunk-EWORLJMO.js';
20
+ import './chunk-VQYBXPI7.js';
21
+ import './chunk-ONKJUM6R.js';
22
+ import './chunk-MAK5LYRF.js';
23
23
  import './chunk-KMDLFI4P.js';
24
24
  import './chunk-QKFB4K7X.js';
25
25
  import './chunk-RSNSZ2LJ.js';
26
26
  import './chunk-OZGHL5Y5.js';
27
27
  import './chunk-RLYZLUQ7.js';
28
28
  import { parseRunnerEnv } from './chunk-6MZSX4M7.js';
29
- import './chunk-6QRMLNH3.js';
30
- import './chunk-NPQWKGUA.js';
29
+ import './chunk-S3NYLI2P.js';
30
+ import './chunk-6Y5RUTHO.js';
31
31
  import './chunk-IP7BIBXJ.js';
32
32
  import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-22RMZBGW.js';
33
33
  import './chunk-UXYLWVTQ.js';
@@ -41,7 +41,7 @@ import './chunk-4Q7OMKAT.js';
41
41
  import './chunk-CX22S5BA.js';
42
42
  import './chunk-F7CU5ABH.js';
43
43
  import './chunk-BKO6JEZI.js';
44
- import './chunk-YDSMROTB.js';
44
+ import './chunk-3NSNIIBE.js';
45
45
  import './chunk-WUYTWNMA.js';
46
46
  import './chunk-JXYVA45C.js';
47
47
  import './chunk-4KSQKQXE.js';
@@ -50,7 +50,7 @@ import './chunk-YRYMNBGQ.js';
50
50
  import './chunk-GQD22KKN.js';
51
51
  import './chunk-WZBHBH3J.js';
52
52
  import './chunk-5QRP3MVS.js';
53
- import './chunk-JEHRUE3F.js';
53
+ import './chunk-YZ5F4PIS.js';
54
54
  import './chunk-WTE3MQML.js';
55
55
  import './chunk-C5Y5ZJJZ.js';
56
56
  import './chunk-ZJSNLVCE.js';
@@ -64,7 +64,7 @@ import './chunk-EABW6AJQ.js';
64
64
  import './chunk-RA3O54FC.js';
65
65
  import './chunk-V7NIVOFD.js';
66
66
  import './chunk-ZM2IMMYN.js';
67
- import './chunk-6JNURGOA.js';
67
+ import './chunk-BWQ66M6N.js';
68
68
  import './chunk-XCCLFVXM.js';
69
69
  import './chunk-BJ3KTMDH.js';
70
70
  import './chunk-VNVZDWO3.js';
@@ -78,6 +78,7 @@ var REASON_TEXT = {
78
78
  flag: "you passed --factory",
79
79
  saved: "already connected",
80
80
  linked: "the repository is linked to it",
81
+ owner: "it owns this repository",
81
82
  only: "the only factory you can use",
82
83
  prompt: "you chose it"
83
84
  };
@@ -128,18 +129,19 @@ function parseFactories(body) {
128
129
  name: sanitizeTerminal(org.name),
129
130
  displayName: sanitizeTerminal(typeof org.displayName === "string" ? org.displayName : org.name)
130
131
  },
131
- linked: typeof row.linked === "boolean" ? row.linked : null
132
+ linked: typeof row.linked === "boolean" ? row.linked : null,
133
+ owner: row.owner === true
132
134
  });
133
135
  }
134
136
  return out;
135
137
  }
136
138
  function listText(factories, repository) {
137
- return factories.map((f) => ` ${slug(f)} ${f.displayName}${f.linked === true ? ` (linked to ${repository})` : ""}`).join("\n");
139
+ return factories.map((f) => ` ${slug(f)} ${f.displayName}${f.linked === true && repository !== void 0 ? ` (linked to ${repository})` : ""}`).join("\n");
138
140
  }
139
141
  async function fetchFactories(fetchImpl, url, token, repository) {
140
142
  let res;
141
143
  try {
142
- res = await fetchImpl(`${url.replace(/\/+$/, "")}/v1/me/factories?${new URLSearchParams({ repository }).toString()}`, {
144
+ res = await fetchImpl(`${url.replace(/\/+$/, "")}/v1/me/factories${repository === void 0 ? "" : `?${new URLSearchParams({ repository }).toString()}`}`, {
143
145
  method: "GET",
144
146
  headers: { authorization: `Bearer ${token}` },
145
147
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
@@ -168,6 +170,8 @@ function selectFactory(factories, saved, repository) {
168
170
  if (remembered) return { factory: remembered, reason: "saved" };
169
171
  const linked = factories.filter((f) => f.linked === true);
170
172
  if (linked.length === 1) return { factory: linked[0], reason: "linked" };
173
+ const owners = factories.filter((f) => f.owner);
174
+ if (owners.length === 1) return { factory: owners[0], reason: "owner" };
171
175
  if (factories.length === 1) return { factory: factories[0], reason: "only" };
172
176
  return { factory: void 0, values: factories.map(slug), text: listText(factories, repository) };
173
177
  }
@@ -310,4 +314,4 @@ ${COMMIT_LINE}
310
314
  return r.code;
311
315
  }
312
316
 
313
- export { COMMIT_LINE, autoConnectedLine, fetchFactories, isLinkedRepository, promptOnTerminal, realConnectDeps, runConnect, runConnectCommand, saveFactoryConnection, selectFactory, workPageUrl };
317
+ export { COMMIT_LINE, autoConnectedLine, dashboardBase, fetchFactories, isLinkedRepository, listText, promptOnTerminal, realConnectDeps, runConnect, runConnectCommand, saveFactoryConnection, selectFactory, slug, workPageUrl };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-YDSMROTB.js';
3
+ import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-3NSNIIBE.js';
4
4
  import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
5
5
  import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
6
6
  import { findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
@@ -634,7 +634,7 @@ async function runHookFast(event, home = homeFromEnv(), read = readStdin, env =
634
634
  recordHookErrorsSeen(home, hookErrorsBytes);
635
635
  if (contextPossiblyGoverned(sessionCwd, home)) {
636
636
  try {
637
- const { materializeContext: materialize } = await import('./context-materialize-2WXTS4CW.js');
637
+ const { materializeContext: materialize } = await import('./context-materialize-IV2TUUFO.js');
638
638
  const sessionId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
639
639
  const result = await materialize({ cwd: sessionCwd, sessionId, home });
640
640
  materializeMessage = result.message;
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { writeJobFile, readJobFile } from './chunk-RMWLBUCJ.js';
4
+ import { senderPidfile } from './chunk-NNRTPG7X.js';
4
5
  import { DOCKERD_LOG } from './chunk-HYZRY4KZ.js';
5
- import { senderPidfile } from './chunk-ONRCEE6D.js';
6
- import { installScrubContext } from './chunk-U3HXXRTY.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-EWORLJMO.js';
6
+ import { installScrubContext } from './chunk-NWQTTSBB.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-MAK5LYRF.js';
8
8
  import { childEnvironment } from './chunk-KMDLFI4P.js';
9
9
  import { waitForAgent, vmExecArgs } from './chunk-QKFB4K7X.js';
10
10
  import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-RSNSZ2LJ.js';
11
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-6QRMLNH3.js';
11
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-S3NYLI2P.js';
12
12
  import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-22RMZBGW.js';
13
13
  import { readBranchHead, diffBetween, fetchCommit } from './chunk-R7PF5OOU.js';
14
14
  import { isSameProcess, startTimeOf } from './chunk-N5FOE5PS.js';
@@ -2074,19 +2074,18 @@ async function startSender(input) {
2074
2074
  const launch = launchFor(config, job, jobDir, deps);
2075
2075
  const fd = openSync(join(jobDir, "sender.log"), "a", RUNNER_FILE_MODE);
2076
2076
  let pid;
2077
+ let exitLogged;
2077
2078
  try {
2078
2079
  const child = spawnFn(launch.command, launch.args, { env: launch.env, cwd: launch.cwd, detached: true, stdio: ["ignore", fd, fd] });
2079
2080
  child.on("error", (err) => deps.log.error(`${tag} session sender failed: ${describeCallFailure(err)}`));
2080
- const exitLogged = new Promise((resolve) => {
2081
+ exitLogged = new Promise((resolve) => {
2081
2082
  child.on("exit", (code, signal) => {
2082
2083
  deps.log.line(`${tag} session sender exited \xB7 ${signal ?? `code ${code}`} \xB7 see sender.log`);
2083
- if (pid !== void 0) exitsLogged.delete(pid);
2084
2084
  resolve();
2085
2085
  });
2086
2086
  });
2087
2087
  child.unref?.();
2088
2088
  pid = child.pid;
2089
- if (pid !== void 0) exitsLogged.set(pid, exitLogged);
2090
2089
  } finally {
2091
2090
  closeSync(fd);
2092
2091
  }
@@ -2094,6 +2093,7 @@ async function startSender(input) {
2094
2093
  deps.log.line(`${tag} session sender did not start: no pid`);
2095
2094
  return void 0;
2096
2095
  }
2096
+ exitsLogged.set(pid, exitLogged);
2097
2097
  deps.log.line(`${tag} session sender started \xB7 pid ${pid}`);
2098
2098
  return { pid, start: startTimeOf(pid) ?? void 0 };
2099
2099
  } catch (err) {
@@ -2148,7 +2148,6 @@ async function signalInGuest(runtime, state, pidfile, signal) {
2148
2148
  }
2149
2149
  async function exitReported(pid) {
2150
2150
  const logged = exitsLogged.get(pid);
2151
- if (logged === void 0) return;
2152
2151
  let timer;
2153
2152
  const bound = new Promise((resolve) => {
2154
2153
  timer = setTimeout(resolve, EXIT_REPORT_WAIT_MS);
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { checkStarterFiles, contextIsGoverned } from './chunk-NBGDBTO2.js';
4
- import { resolveCredentials, getJson, WorkCommandError } from './chunk-6QRMLNH3.js';
4
+ import { resolveCredentials, getJson, WorkCommandError } from './chunk-S3NYLI2P.js';
5
5
  import { readStatuslineState, STATE_FRESH_MS } from './chunk-F47JBIAW.js';
6
- import { isLinkedRepository } from './chunk-YDSMROTB.js';
6
+ import { isLinkedRepository } from './chunk-3NSNIIBE.js';
7
7
  import { sanitizeTerminal } from './chunk-WUYTWNMA.js';
8
8
  import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-JXYVA45C.js';
9
9
  import { C } from './chunk-YRYMNBGQ.js';
@@ -13,7 +13,7 @@ import { checkFormerSkillNames } from './chunk-C5Y5ZJJZ.js';
13
13
  import { defaultFetch } from './chunk-YO4PSLVB.js';
14
14
  import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
15
15
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
16
- import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-6JNURGOA.js';
16
+ import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-BWQ66M6N.js';
17
17
  import { deadHooksState, preparePackageManagerCommand, contextExcludesPresent } from './chunk-XCCLFVXM.js';
18
18
  import { findGitDirs } from './chunk-BJ3KTMDH.js';
19
19
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -1084,6 +1084,56 @@ async function credentialChecks(options = {}) {
1084
1084
  const source = env.OUTERLAYER_API_KEY ? "OUTERLAYER_API_KEY" : "~/.outerlayer/config.json";
1085
1085
  return factoryKeyChecks(fetchImpl, resolved.url, resolved.credential, resolved.appId, source, local);
1086
1086
  }
1087
+ function governedDetail(source) {
1088
+ return `governed by ${sanitizeTerminal(source.repository)} (ref ${sanitizeTerminal(source.ref)}, stored commit ${sanitizeTerminal(source.sha.slice(0, 7))})`;
1089
+ }
1090
+ async function governanceChecks(options = {}) {
1091
+ const name = "Governance";
1092
+ const env = options.env ?? process.env;
1093
+ const cwd = options.cwd ?? process.cwd();
1094
+ const resolved = resolveGatewayCredentials({ home: options.home, env, cwd });
1095
+ if (resolved.credential === void 0 || resolved.url === void 0) {
1096
+ return [skippedCheck(name, "there is no credential to ask with", "Run `outerlayer login` to sign in.")];
1097
+ }
1098
+ const local = resolveRepoIdentity(cwd).gitRepo;
1099
+ if (local === void 0) return [skippedCheck(name, "not inside a git repository with a remote")];
1100
+ if (resolved.appId === void 0) return [skippedCheck(name, "no factory is chosen for this repository", CONNECT_FIX)];
1101
+ const fetchImpl = options.fetchImpl ?? defaultFetch;
1102
+ const reply = await askGateway(fetchImpl, resolved.url, `/v1/context/source?${new URLSearchParams({ repo: local.split("/").slice(-2).join("/") }).toString()}`, resolved.credential, resolved.appId);
1103
+ const unanswered = unansweredDetail(reply);
1104
+ if (unanswered !== void 0 && !("failure" in reply) && reply.status === 503) {
1105
+ const message = refusalMessage(reply.body);
1106
+ return [{ name, status: "warn", detail: message === "" ? unanswered : `governed, but ${message}`, fix: "Check that the GitHub App can read the control plane, then run `outerlayer doctor` again." }];
1107
+ }
1108
+ if (unanswered !== void 0) return [{ name, status: "warn", detail: unanswered, fix: NETWORK_FIX }];
1109
+ const { status, body } = reply;
1110
+ if (status === 401 || status === 403) {
1111
+ return [{ name, status: "warn", detail: `the gateway refused to say what governs ${sanitizeTerminal(local)} (HTTP ${status})`, fix: LOGIN_FIX }];
1112
+ }
1113
+ if (status < 200 || status >= 300) {
1114
+ return [{ name, status: "warn", detail: `the gateway did not answer which control plane governs ${sanitizeTerminal(local)} (HTTP ${status})`, fix: UPDATE_FIX }];
1115
+ }
1116
+ const data = body?.data;
1117
+ const source = data?.source;
1118
+ if (source === void 0) {
1119
+ return [
1120
+ {
1121
+ name,
1122
+ status: "warn",
1123
+ detail: "the gateway is too old to say which control plane governs this repository: its answer has no source",
1124
+ fix: UPDATE_FIX
1125
+ }
1126
+ ];
1127
+ }
1128
+ if (source === null) {
1129
+ return [{ name, status: "pass", detail: `${sanitizeTerminal(local)} is self-governed: it supplies its own context` }];
1130
+ }
1131
+ const named = source;
1132
+ if (typeof named.repository !== "string" || typeof named.ref !== "string" || typeof named.sha !== "string") {
1133
+ return [{ name, status: "warn", detail: "the gateway named a control plane without its repository, ref and commit", fix: UPDATE_FIX }];
1134
+ }
1135
+ return [{ name, status: "pass", detail: governedDetail({ repository: named.repository, ref: named.ref, sha: named.sha }) }];
1136
+ }
1087
1137
  function doctorExitCode(checks) {
1088
1138
  return checks.some((c) => c.status === "fail") ? 1 : 0;
1089
1139
  }
@@ -1095,14 +1145,14 @@ async function gatherDoctorChecks() {
1095
1145
  const checks = runDoctor({ runnerHost: hasRunnerBlock(configPath) });
1096
1146
  const credential = await credentialChecks();
1097
1147
  checks.push(...credential);
1098
- if (credential[0]?.status === "pass") checks.push(...await githubAppChecks());
1148
+ if (credential[0]?.status === "pass") checks.push(...await githubAppChecks(), ...await governanceChecks());
1099
1149
  const runnerVm = runnerVmOf(configPath);
1100
1150
  if (runnerVm !== void 0) {
1101
1151
  const { realLima } = await import('./lima-7NPCNGWT.js');
1102
1152
  const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
1103
1153
  checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
1104
1154
  } else if (hasRunnerBlock(configPath)) {
1105
- const { runnerHostChecks } = await import('./doctor-N6Y7HKK3.js');
1155
+ const { runnerHostChecks } = await import('./doctor-4TAIARIG.js');
1106
1156
  const hooks = (() => {
1107
1157
  try {
1108
1158
  return loadRunnerConfig(configPath).hooks;
@@ -4,7 +4,7 @@ import { runEmit } from './chunk-2MNPHL23.js';
4
4
  import { addStdioMcpEntryIfAbsent, addDocsMcpEntryIfAbsent, DOCS_MCP_SERVER_NAME } from './chunk-XCK2YAY5.js';
5
5
  import { installStarterPack } from './chunk-42ZI52JW.js';
6
6
  import { C } from './chunk-YRYMNBGQ.js';
7
- import { resolveGitCommonDir, defaultGitRunner } from './chunk-JEHRUE3F.js';
7
+ import { resolveGitCommonDir, defaultGitRunner } from './chunk-YZ5F4PIS.js';
8
8
  import { pinExists, readContextManifest } from './chunk-WTE3MQML.js';
9
9
  import { loadTemplateFiles, loadMaintainedFiles, skillDir } from './chunk-POJMEEJJ.js';
10
10
  import { generatedHeaderSource } from './chunk-OHVJA253.js';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isPlaceholderCommand } from './chunk-CA3XMYFN.js';
4
- import { describeCallFailure } from './chunk-EWORLJMO.js';
5
- import { WorkCommandError, getJson } from './chunk-6QRMLNH3.js';
3
+ import { isPlaceholderCommand } from './chunk-VQYBXPI7.js';
4
+ import { describeCallFailure } from './chunk-MAK5LYRF.js';
5
+ import { WorkCommandError, getJson } from './chunk-S3NYLI2P.js';
6
6
  import { builtinKind } from './chunk-22RMZBGW.js';
7
7
  import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-4Q7OMKAT.js';
8
8
  import { sanitizeTerminal } from './chunk-WUYTWNMA.js';
@@ -3,7 +3,7 @@ import { createRequire } from 'node:module';
3
3
  import { createDockerHost, childEnvironment, spawnRun } from './chunk-KMDLFI4P.js';
4
4
  import { execCapture } from './chunk-QKFB4K7X.js';
5
5
  import { GUEST_CID } from './chunk-RSNSZ2LJ.js';
6
- import { WorkCommandError, postJson } from './chunk-6QRMLNH3.js';
6
+ import { WorkCommandError, postJson } from './chunk-S3NYLI2P.js';
7
7
  import { hostAllowed } from './chunk-UXYLWVTQ.js';
8
8
  import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-R7PF5OOU.js';
9
9
  import { RecipeError } from './chunk-QOZKPLVJ.js';
@@ -14,15 +14,15 @@ import { parseDuKilobytes } from './chunk-7RQ73DLO.js';
14
14
  import { repositoriesOf, primaryOf, RELAY_PORT, CHECKOUT_DIR, JOB_MOUNT, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath } from './chunk-4Q7OMKAT.js';
15
15
  import { CLAUDE_CODE_VERSION, firecrackerArch, MICROVM_ARCHES, DEFAULT_BASE_IMAGE, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, FIRECRACKER_VERSION, GUEST_ASSETS_VERSION } from './chunk-CX22S5BA.js';
16
16
  import { setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-JXYVA45C.js';
17
- import { defaultGitRunner, materializeContext } from './chunk-JEHRUE3F.js';
17
+ import { defaultGitRunner, materializeContext } from './chunk-YZ5F4PIS.js';
18
18
  import { readContextManifest, readSourceCache } from './chunk-WTE3MQML.js';
19
19
  import { signingFetchFor } from './chunk-YO4PSLVB.js';
20
20
  import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-OHVJA253.js';
21
21
  import { downconvertSession } from './chunk-J5M7BSJQ.js';
22
22
  import { signerFor } from './chunk-V7NIVOFD.js';
23
23
  import { rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, stagedContextDir, contextHomeDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, RUNNER_DIR_MODE, vmAssetsDir } from './chunk-ZM2IMMYN.js';
24
+ import { fstatSync, readFileSync, existsSync, mkdirSync, chmodSync, truncateSync, rmSync, writeFileSync, accessSync, constants, readdirSync, statSync, rmdirSync, renameSync, lstatSync, unlinkSync, openSync, closeSync, mkdtempSync, createWriteStream, createReadStream } from 'fs';
24
25
  import { relative, join, dirname, basename } from 'path';
25
- import { readFileSync, existsSync, mkdirSync, chmodSync, truncateSync, rmSync, writeFileSync, accessSync, constants, readdirSync, statSync, rmdirSync, renameSync, lstatSync, unlinkSync, openSync, closeSync, mkdtempSync, createWriteStream, createReadStream } from 'fs';
26
26
  import { spawnSync, spawn } from 'child_process';
27
27
  import { availableParallelism, networkInterfaces } from 'os';
28
28
  import { randomBytes, createHash } from 'crypto';
@@ -38,16 +38,25 @@ createRequire(import.meta.url);
38
38
  function logStamp(at) {
39
39
  return at.toISOString().replace(/\.\d{3}Z$/, "Z");
40
40
  }
41
- function createRunnerLog(now = () => /* @__PURE__ */ new Date()) {
41
+ function sameDestination(stat = fstatSync) {
42
+ try {
43
+ const out = stat(1);
44
+ const err = stat(2);
45
+ return out.dev === err.dev && out.ino === err.ino;
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+ function createRunnerLog(now = () => /* @__PURE__ */ new Date(), io = { stdout: process.stdout, stderr: process.stderr, joined: () => sameDestination() }) {
42
51
  const write = (stream, text) => {
43
52
  stream.write(`${logStamp(now())} ${text}
44
53
  `);
45
54
  };
46
55
  return {
47
- line: (text) => write(process.stdout, text),
56
+ line: (text) => write(io.stdout, text),
48
57
  error: (text) => {
49
- write(process.stdout, text);
50
- write(process.stderr, text);
58
+ write(io.stdout, text);
59
+ if (!io.joined()) write(io.stderr, text);
51
60
  }
52
61
  };
53
62
  }
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LiveUploader } from './chunk-U3HXXRTY.js';
3
+ import { LiveUploader } from './chunk-NWQTTSBB.js';
4
4
  import { CaptureDaemon } from './chunk-JXYVA45C.js';
5
5
  import { parseWorkItemEnv } from './chunk-GQD22KKN.js';
6
- import { spoolDir } from './chunk-6JNURGOA.js';
6
+ import { spoolDir } from './chunk-BWQ66M6N.js';
7
7
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
8
8
  import { mkdirSync, writeFileSync, rmSync } from 'fs';
9
9
  import { join } from 'path';
@@ -14,7 +14,7 @@ import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-PLMTLGYH
14
14
  import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-J5M7BSJQ.js';
15
15
  import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-EABW6AJQ.js';
16
16
  import { signerFor, signRunnerRequest } from './chunk-V7NIVOFD.js';
17
- import { writeSyncStatus, spoolDir } from './chunk-6JNURGOA.js';
17
+ import { writeSyncStatus, spoolDir } from './chunk-BWQ66M6N.js';
18
18
  import { removeJournalHooks } from './chunk-XCCLFVXM.js';
19
19
  import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
20
20
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { MIN_ENGINE_MAJOR } from './chunk-EWORLJMO.js';
3
+ import { MIN_ENGINE_MAJOR } from './chunk-MAK5LYRF.js';
4
4
  import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-CX22S5BA.js';
5
5
  import { spawnSync } from 'child_process';
6
6
  import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { autoConnect } from './chunk-NPQWKGUA.js';
3
+ import { autoConnect } from './chunk-6Y5RUTHO.js';
4
4
  import { detectActiveSession } from './chunk-IP7BIBXJ.js';
5
- import { workPageUrl } from './chunk-YDSMROTB.js';
5
+ import { workPageUrl } from './chunk-3NSNIIBE.js';
6
6
  import { sanitizeTerminal } from './chunk-WUYTWNMA.js';
7
7
  import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
8
8
  import { C } from './chunk-YRYMNBGQ.js';
@@ -360,7 +360,7 @@ async function runWorkLinkSession(opts) {
360
360
  return await linkSession(opts);
361
361
  } catch (err) {
362
362
  if (opts.logFailures) {
363
- const { logHookError } = await import('./hook-fast-D7HV4IXG.js');
363
+ const { logHookError } = await import('./hook-fast-R4FVSZ2H.js');
364
364
  const reason = err instanceof Error ? err.message : String(err);
365
365
  logHookError(opts.home ?? homeFromEnv(opts.env ?? process.env), new Error(`work link-session #${opts.number} failed: ${reason}`));
366
366
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-RSPXEVDX.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-EWORLJMO.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-ONKJUM6R.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-MAK5LYRF.js';
5
5
  import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-OZGHL5Y5.js';
6
6
  import { runnerCredentialProblem } from './chunk-22RMZBGW.js';
7
7
  import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
@@ -112,7 +112,7 @@ function prepareRunnerInit(configPath, opts = {}) {
112
112
  function writeRunnerInit(prepared, runnerKey) {
113
113
  const { configPath, config, carried, credential, agent, machine, hooks } = prepared;
114
114
  if (prepared.needsKey && runnerKey === void 0) {
115
- throw new RunnerInitError(`${configPath}: apiKey is missing, and no runner key was created from the login.`);
115
+ throw new RunnerInitError(`${configPath}: apiKey is missing, and no runner key was pasted.`);
116
116
  }
117
117
  if (runnerKey !== void 0) Object.assign(config, { url: runnerKey.url, apiKey: runnerKey.apiKey, appId: runnerKey.appId });
118
118
  mkdirSync(runnerDir(configPath), { recursive: true, mode: RUNNER_DIR_MODE });
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-R4ZQQ7U2.js';
3
+ import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-G5NPRL2K.js';
4
+ import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-RMWLBUCJ.js';
4
5
  import { writePendingUpdate } from './chunk-O765JR4W.js';
5
6
  import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-UGP76IZ5.js';
6
7
  import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
7
8
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-YETTWTAY.js';
8
- import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-RMWLBUCJ.js';
9
9
  import { compareVersions, satisfiesRange } from './chunk-I2UOAV7X.js';
10
10
  import { RUNNER_PROTOCOL } from './chunk-ADJRGVZC.js';
11
- import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-FWX735W7.js';
11
+ import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-LWSJQJC6.js';
12
12
  import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
13
13
  import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, cleanVersions, isInLayout, stagingDir } from './chunk-TI7B7UEO.js';
14
14
  import { RepoFilter } from './chunk-TBT347UY.js';
15
- import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, measureDisk, createRunnerLog, setUpRunnerCgroup, parseCpuList, ensureTunnel, keepGhConfigCurrent, createContainerRuntime, formatClock } from './chunk-EWORLJMO.js';
15
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, measureDisk, createRunnerLog, setUpRunnerCgroup, parseCpuList, ensureTunnel, keepGhConfigCurrent, createContainerRuntime, formatClock } from './chunk-MAK5LYRF.js';
16
16
  import { spawnRun } from './chunk-KMDLFI4P.js';
17
17
  import { checkFit } from './chunk-RLYZLUQ7.js';
18
- import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-6QRMLNH3.js';
18
+ import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-S3NYLI2P.js';
19
19
  import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-22RMZBGW.js';
20
20
  import { startTimeOf, claimPidFile, readPidFile, isSameProcess, releasePidFile } from './chunk-N5FOE5PS.js';
21
21
  import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-4NPZVMJU.js';
@@ -1315,7 +1315,7 @@ var CLAIM_REFUSAL_CODES = new Set(
1315
1315
  "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected branch_claimed_elsewhere".split(" ")
1316
1316
  );
1317
1317
  async function tryClaimAndStart(state, item, queue) {
1318
- const { postJson: postJson2 } = await import('./work-cmd-DJQJEZVB.js');
1318
+ const { postJson: postJson2 } = await import('./work-cmd-Z2WXLZPH.js');
1319
1319
  const log = logOf(state);
1320
1320
  const hostKey = await loadHostKey(state.config.configPath);
1321
1321
  const claim = await retrySend(
@@ -2074,7 +2074,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2074
2074
  const outcome = await onStartUnderMarker({
2075
2075
  configPath,
2076
2076
  own: ownVersionOf(deps),
2077
- check: update.check ? () => update.check(configPath) : async () => (await import('./check-CNTMSGOG.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2077
+ check: update.check ? () => update.check(configPath) : async () => (await import('./check-5XE7XMC4.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2078
2078
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
2079
2079
  log
2080
2080
  });