@outerlayer/cli 0.32.0 → 0.33.0-next.20261021171625

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 (93) hide show
  1. package/README.md +15 -1
  2. package/dist/{agent-setup-E7CMDUR5.js → agent-setup-NSUX64RU.js} +10 -10
  3. package/dist/{artifact-link-cmd-VY6OM7S5.js → artifact-link-cmd-IGVFGHC2.js} +2 -2
  4. package/dist/{build-7QD3VJ6U.js → build-HU24C46Z.js} +3 -2
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-REQJGZJP.js → builder-QECLC243.js} +5 -4
  7. package/dist/{check-COMHCLXW.js → check-4BL6XRWJ.js} +29 -28
  8. package/dist/{chunk-JH2AMJ4K.js → chunk-2FPEB36J.js} +2 -2
  9. package/dist/{chunk-HSUUTD4E.js → chunk-3H7NZPYG.js} +1 -1
  10. package/dist/{chunk-JFLVUA43.js → chunk-3RS3RNGH.js} +3 -3
  11. package/dist/{chunk-IWFYKNAO.js → chunk-3WW2TL7V.js} +45 -2
  12. package/dist/{chunk-SJZL5F3F.js → chunk-3Z3MPR55.js} +1 -51
  13. package/dist/{chunk-ZWBRHH3L.js → chunk-4LU7MFJO.js} +3 -3
  14. package/dist/{chunk-2JPVI45I.js → chunk-5T2VOSIL.js} +3 -2
  15. package/dist/{chunk-G2RRBBOX.js → chunk-6C3ZVE62.js} +1 -1
  16. package/dist/{chunk-Z7HAIZ6X.js → chunk-BSHUTMXV.js} +54 -5
  17. package/dist/{chunk-NIS2PIS4.js → chunk-D73OLAYE.js} +3 -3
  18. package/dist/{chunk-V6IYYQU3.js → chunk-FE3RTGJN.js} +2 -2
  19. package/dist/{chunk-XB7TRWI2.js → chunk-GI6LOIHS.js} +4 -4
  20. package/dist/{chunk-5TNEVWFJ.js → chunk-GXKWPOK6.js} +2 -2
  21. package/dist/{chunk-4XPAQXJF.js → chunk-H6Y5D6J7.js} +6 -6
  22. package/dist/{chunk-XKZPL3GE.js → chunk-INCKTGMM.js} +4 -4
  23. package/dist/{chunk-7F2VPHP7.js → chunk-JJ4W5LVF.js} +9 -9
  24. package/dist/{chunk-ZUOPFE22.js → chunk-JUXATN46.js} +1 -1
  25. package/dist/{chunk-BCWVTWS7.js → chunk-KURUM765.js} +4 -4
  26. package/dist/{chunk-IGIGNYZK.js → chunk-LESWVXRE.js} +4 -4
  27. package/dist/chunk-LK2S5XZH.js +99 -0
  28. package/dist/{emit-artifact-cmd-NCK3VCDM.js → chunk-LRBOBYQI.js} +8 -36
  29. package/dist/{chunk-VIHQLW4L.js → chunk-MV52FCSG.js} +9 -8
  30. package/dist/{chunk-WRW6QCI6.js → chunk-NHXJU7CM.js} +2 -2
  31. package/dist/{chunk-4I3ZDQFU.js → chunk-OF4TFWKR.js} +2 -2
  32. package/dist/{chunk-XAV6XCI2.js → chunk-OX7CHZTJ.js} +7 -7
  33. package/dist/{chunk-XTKH5VAC.js → chunk-QCDVKCHA.js} +2 -2
  34. package/dist/{chunk-SXJVL7NS.js → chunk-QNVIGO5X.js} +2 -2
  35. package/dist/{chunk-FKNOPMUD.js → chunk-RHBFNZ7J.js} +4 -4
  36. package/dist/{chunk-3PYMMGYO.js → chunk-UJIG5BU7.js} +10 -10
  37. package/dist/{chunk-HJUGOAM7.js → chunk-WXEPMPHK.js} +1 -1
  38. package/dist/{chunk-3DSC2FN3.js → chunk-X2Y3B4JH.js} +2 -2
  39. package/dist/{chunk-U4HMGT3L.js → chunk-X7ML37UF.js} +5 -5
  40. package/dist/{chunk-KCB6V5XH.js → chunk-XFS2TMOB.js} +5 -5
  41. package/dist/{chunk-UAFMC3PL.js → chunk-XRQ7DABQ.js} +1 -1
  42. package/dist/{chunk-V36AOTBP.js → chunk-XT5SOJRC.js} +379 -45
  43. package/dist/{chunk-CVGMB4N7.js → chunk-YGXKXL4Q.js} +13 -13
  44. package/dist/{chunk-AKKVPUGK.js → chunk-YW4PEGLN.js} +1 -1
  45. package/dist/{chunk-QDDPVBIS.js → chunk-ZAJKEHIE.js} +2 -2
  46. package/dist/{claude-launcher-IG7GKYIT.js → claude-launcher-RNMUZZ3Y.js} +5 -5
  47. package/dist/{cli-DLUADCTG.js → cli-PNQX4HRX.js} +144 -89
  48. package/dist/{command-JRWYFDNM.js → command-LA7T5YFX.js} +19 -18
  49. package/dist/{connect-cmd-K73AOVUR.js → connect-cmd-2AXEPDT2.js} +8 -8
  50. package/dist/{container-start-4RJRBPVB.js → container-start-4LIRN2LX.js} +20 -19
  51. package/dist/{context-cleanup-D5EGQHQV.js → context-cleanup-VSDT77BZ.js} +3 -3
  52. package/dist/{control-plane-launch-JCUNTTC3.js → control-plane-launch-DHMD5WBU.js} +6 -6
  53. package/dist/{dist-BE3LYGNH.js → dist-DY2ZNEBS.js} +2 -2
  54. package/dist/{docker-CVRCHNYC.js → docker-EOP32YLH.js} +5 -4
  55. package/dist/{doctor-A3A4X2HJ.js → doctor-FDXHHPDJ.js} +21 -20
  56. package/dist/emit-artifact-cmd-JY5V6WQI.js +43 -0
  57. package/dist/{emit-cmd-PSD7AAKJ.js → emit-cmd-T7NIBSF3.js} +6 -6
  58. package/dist/{emit-criteria-cmd-GTCZWV4B.js → emit-criteria-cmd-XRFBNFN7.js} +9 -9
  59. package/dist/emit-demo-cmd-JOVCVXIS.js +888 -0
  60. package/dist/{emit-finding-cmd-OUG72OQA.js → emit-finding-cmd-5RHKQHE6.js} +10 -10
  61. package/dist/{emit-result-cmd-YQ5DZMMR.js → emit-result-cmd-65KJQ2UM.js} +12 -12
  62. package/dist/{emit-step-cmd-QJXSHSQF.js → emit-step-cmd-YZIN6B6P.js} +10 -10
  63. package/dist/{findings-cmd-DYDEHJFI.js → findings-cmd-Z6CKWAG4.js} +10 -10
  64. package/dist/{fleet-readiness-JEQ5ITV6.js → fleet-readiness-7ROJ54ZF.js} +8 -8
  65. package/dist/{governing-source-JSYW4RCL.js → governing-source-NMGGSA6Q.js} +13 -13
  66. package/dist/{hook-fast-UFHR6EKZ.js → hook-fast-WQQYEXO5.js} +1 -1
  67. package/dist/index.js +4 -4
  68. package/dist/{init-SYNDV44H.js → init-OV6IOD2G.js} +20 -19
  69. package/dist/{init-CSXI3OQH.js → init-UBDZRWNE.js} +20 -19
  70. package/dist/{init-cmd-ALBPEG7I.js → init-cmd-YP4TVN2S.js} +18 -18
  71. package/dist/{init-update-PMDRKPA2.js → init-update-24K7ZZWX.js} +17 -17
  72. package/dist/{layout-3ISIED6A.js → layout-OQ7EJUMH.js} +4 -4
  73. package/dist/{login-browser-NTVVDJF7.js → login-browser-KP7YVYTN.js} +2 -2
  74. package/dist/{loop-XDJYLT4D.js → loop-4FEA6E2S.js} +29 -28
  75. package/dist/{machine-GC4MZB5W.js → machine-3BMBF33L.js} +19 -18
  76. package/dist/{machine-skills-I4DB2CP3.js → machine-skills-XWWYFNOZ.js} +4 -4
  77. package/dist/{runner-identity-D3XUB36T.js → runner-identity-HTQNM5AG.js} +5 -4
  78. package/dist/{runner-key-7QNJNPQ6.js → runner-key-7I5FDQKR.js} +20 -19
  79. package/dist/{session-sender-S6KG6VOM.js → session-sender-MKDKMZJD.js} +13 -13
  80. package/dist/{spec-cmd-4RD3A55B.js → spec-cmd-V7W3UV6X.js} +10 -10
  81. package/dist/{starter-pack-2WFNRGFA.js → starter-pack-6O7F6P7C.js} +5 -5
  82. package/dist/{status-ZR2N44KU.js → status-TJDVDR4H.js} +23 -22
  83. package/dist/{sync-cmd-NISS7HJJ.js → sync-cmd-AI4KTJ56.js} +12 -12
  84. package/dist/{watch-VSTJUIRH.js → watch-C7IS6VNS.js} +12 -12
  85. package/dist/{work-claim-cmd-27OJUZ56.js → work-claim-cmd-GFXIZWMU.js} +12 -12
  86. package/dist/{work-cmd-B7YCAK5M.js → work-cmd-UTD4Y7W3.js} +10 -10
  87. package/dist/{work-comment-cmd-2X55NLNL.js → work-comment-cmd-J3SRBK6A.js} +10 -10
  88. package/dist/{work-logs-cmd-2CE5B2DP.js → work-logs-cmd-SH7MQPA3.js} +10 -10
  89. package/dist/{work-open-pr-cmd-Q3HZJPSD.js → work-open-pr-cmd-FIX5QLK7.js} +11 -11
  90. package/dist/{work-pr-cmd-MT246E2A.js → work-pr-cmd-S4IBR7DE.js} +10 -10
  91. package/dist/{work-stop-cmd-CWNLRQKE.js → work-stop-cmd-NECXJEJN.js} +10 -10
  92. package/package.json +1 -1
  93. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +39 -0
package/README.md CHANGED
@@ -215,7 +215,9 @@ content:
215
215
  host. Docker pulls base images, features and Claude Code's npm package
216
216
  from registries while the image builds, with the host's own `docker
217
217
  login`. The tools layer also downloads the pinned `gh` and `tini` releases
218
- from GitHub, checking each against a digest. The image build runs outside
218
+ from GitHub, a pinned static `ffmpeg` build from GitHub, and the narration
219
+ voice pack from Hugging Face and the npm registry, checking each against a
220
+ digest. The image build runs outside
219
221
  any work item and sends nothing to your factory. `outerlayer runner start`
220
222
  builds each build's image the same way, before the build starts. That image
221
223
  build uses the host's network: the build's tunnel does not carry it, and
@@ -364,6 +366,17 @@ content:
364
366
  content, not to files you emit. With no recorded
365
367
  session to attach it to, it uploads immediately, anchored to a pull request
366
368
  or to the git checkout.
369
+ - **`outerlayer emit demo <manifest>`** cuts a recorded video into one clip
370
+ for each chapter of its manifest and emits each clip as an artifact, as
371
+ `emit artifact` does, followed by the manifest as the demo record. Before
372
+ that it reads the item's recorded criteria
373
+ (`GET /v1/work-items/{number}`) to check the chapters' criterion ids. It
374
+ runs `ffmpeg` and `espeak-ng` on your machine as separate programs and speaks
375
+ the narration there. Nothing is sent to a speech service. The first narrated
376
+ run downloads the voice pack, about 400 MB, from huggingface.co and
377
+ registry.npmjs.org into `~/.outerlayer/voice/`. It checks each file against a
378
+ pinned sha256 and sends nothing to either host. `--no-narration` downloads
379
+ nothing.
367
380
  - **`outerlayer emit <name>`** sends one check's outcome for a work item.
368
381
  Run from inside a session, it sends only when that session carries a
369
382
  launch record — the session's own content may not leave by a second
@@ -456,6 +469,7 @@ before it gives up.
456
469
  | `outerlayer context emit [--check]` | Compile `.outerlayer/` into each configured target tool's native files (targets come from `.outerlayer/config.json`). `--check` computes outputs and diffs against disk without writing (CI mode). Bare `outerlayer emit` with no name still compiles, with a deprecation warning. |
457
470
  | `outerlayer hooks wrap` / `outerlayer hooks unwrap` | Auto-wrap (or undo wrapping) `PreToolUse`/`PostToolUse` hooks for execution evidence — one spawn per firing. |
458
471
  | `outerlayer emit artifact <file> --caption <text> [--for <criterion-id>] [--pr <n>]` | Upload a proof artifact — screenshot, recording, report, or log — with its caption. Inside a recorded session it spools locally and ships on the next `sync`; otherwise it uploads immediately, anchored to a pull request or the current checkout. `--replaces` retires artifacts an earlier run uploaded. A JUnit XML file bound with `--for` proves a criterion that declares `test` proof; `--test <name[=path:line]>` binds only the named tests. |
472
+ | `outerlayer emit demo <manifest> [--no-narration] [--item <n>] [--pr <n>]` | Turn a recorded video and its manifest (written by `@outerlayer/playwright`) into a narrated demo: one WebM clip for each chapter, emitted as a video artifact. A chapter whose checks all passed is bound to its criterion. The manifest is emitted as the demo record. Needs `ffmpeg` and `ffprobe`, and `espeak-ng` unless `--no-narration`. Exit 1 means a chapter had a failed check. |
459
473
  | `outerlayer emit <name> --result <pass\|fail> [--link <url>] [--body <text>\|--body-file <path>] --item <number>` | Record one named check's outcome on a work item. A check that ran carries the run URL as its proof (`--link`); a judgment you are making yourself carries one sentence (`--body`, or `--body-file` to read it from a file — `-` reads standard input). A `fail` needs at least one of the two; a `pass` needs neither. `--item` names the work item by the number printed when the item was created — always required, in or out of a recorded session; a session records checks on its own item like any other, stored as the session's, but cannot clear a person's fail. Prints the recorded check's id. Who recorded it comes from your API key, never from what you send. |
460
474
  | `outerlayer work comment --item <n> [--criterion <id>] --body <text> [--artifact <id>] [--pass\|--fail\|--attach\|--ready]` | Post one comment on a work item's general thread, or on one acceptance criterion's own thread with `--criterion`. `--pass`/`--fail` need a person's own credential and apply to the whole item, so they work on the general thread only and the gateway refuses them with `--criterion`; `--attach` makes the named artifact that criterion's current proof; `--ready` hands a thread back to a person. The detected session id rides along automatically, only ever narrowing what the comment may do. |
461
475
  | `outerlayer work stop --item <n> [--note <text>]` | Ask the host that holds the item's build to end it. The host reads the request at its next heartbeat and ends the build with outcome `stopped`, so the build may run a little longer. The item is not built again until a new build request. Needs `work.update`. Exits 1 when no host build is running for the item. |
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { keepHandWritten, runAgentSetup } from './chunk-XAV6XCI2.js';
4
- import './chunk-XB7TRWI2.js';
3
+ export { keepHandWritten, runAgentSetup } from './chunk-OX7CHZTJ.js';
4
+ import './chunk-GI6LOIHS.js';
5
5
  import './chunk-KT4CN6OU.js';
6
- import './chunk-XTKH5VAC.js';
7
- import './chunk-QDDPVBIS.js';
6
+ import './chunk-QCDVKCHA.js';
7
+ import './chunk-ZAJKEHIE.js';
8
8
  import './chunk-ANPNT6PM.js';
9
- import './chunk-NIS2PIS4.js';
10
- import './chunk-V6IYYQU3.js';
9
+ import './chunk-D73OLAYE.js';
10
+ import './chunk-FE3RTGJN.js';
11
11
  import './chunk-F3EF56LQ.js';
12
12
  import './chunk-PJDQPF5N.js';
13
13
  import './chunk-APSYTJ6I.js';
@@ -15,16 +15,16 @@ import './chunk-KP6R7CV3.js';
15
15
  import './chunk-HDSDUTX4.js';
16
16
  import './chunk-ZJSNLVCE.js';
17
17
  import './chunk-BJ3KTMDH.js';
18
- import './chunk-AKKVPUGK.js';
18
+ import './chunk-YW4PEGLN.js';
19
19
  import './chunk-5BHIBJDA.js';
20
20
  import './chunk-CDDED64E.js';
21
21
  import './chunk-RA3O54FC.js';
22
22
  import './chunk-CRB3POP4.js';
23
- import './chunk-HJUGOAM7.js';
23
+ import './chunk-WXEPMPHK.js';
24
24
  import './chunk-YQR6E6OV.js';
25
25
  import './chunk-TUSYOL2O.js';
26
- import './chunk-ZUOPFE22.js';
27
- import './chunk-IWFYKNAO.js';
26
+ import './chunk-JUXATN46.js';
27
+ import './chunk-3WW2TL7V.js';
28
28
  import './chunk-VNVZDWO3.js';
29
29
  import './chunk-XD4ZCMA4.js';
30
30
  import './chunk-MESOOLF4.js';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { sanitizeTerminal, readEffectiveArtifactSpoolState } from './chunk-HSUUTD4E.js';
3
+ import { sanitizeTerminal, readEffectiveArtifactSpoolState } from './chunk-3H7NZPYG.js';
4
4
  import { cliInvocation } from './chunk-CRB3POP4.js';
5
- import './chunk-IWFYKNAO.js';
5
+ import './chunk-3WW2TL7V.js';
6
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
7
7
  import './chunk-Z5GEFMRW.js';
8
8
 
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { buildRepositoryImage } from './chunk-Z7HAIZ6X.js';
3
+ export { buildRepositoryImage } from './chunk-BSHUTMXV.js';
4
4
  import './chunk-T5TBGOT6.js';
5
5
  import './chunk-JBJTC3UU.js';
6
- export { RecipeError } from './chunk-SJZL5F3F.js';
6
+ export { RecipeError } from './chunk-3Z3MPR55.js';
7
+ import './chunk-LK2S5XZH.js';
7
8
  import './chunk-KP6R7CV3.js';
8
9
  import './chunk-HDSDUTX4.js';
9
10
  import './chunk-XD4ZCMA4.js';
@@ -1 +1 @@
1
- {"id":"2026-10-21T10:25:56.495Z+814b9ca","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-21T17:29:56.212Z+b42151d","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,13 +1,14 @@
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-2JPVI45I.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-5T2VOSIL.js';
4
4
  import './chunk-YJLHUKYS.js';
5
- import './chunk-SJZL5F3F.js';
6
- import './chunk-V36AOTBP.js';
5
+ import './chunk-3Z3MPR55.js';
6
+ import './chunk-LK2S5XZH.js';
7
+ import './chunk-XT5SOJRC.js';
7
8
  import './chunk-APSYTJ6I.js';
8
9
  import './chunk-KP6R7CV3.js';
9
10
  import './chunk-HDSDUTX4.js';
10
- import './chunk-IWFYKNAO.js';
11
+ import './chunk-3WW2TL7V.js';
11
12
  import './chunk-XD4ZCMA4.js';
12
13
  import './chunk-MESOOLF4.js';
13
14
  import './chunk-Z5GEFMRW.js';
@@ -1,68 +1,69 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-3PYMMGYO.js';
4
- import './chunk-CVGMB4N7.js';
3
+ import { probeCredentials } from './chunk-UJIG5BU7.js';
4
+ import './chunk-YGXKXL4Q.js';
5
+ import './chunk-X7UUIHGH.js';
5
6
  import './chunk-3JVYMD4G.js';
6
- import './chunk-WHSYPR3U.js';
7
7
  import './chunk-E7R2GIAW.js';
8
+ import './chunk-WHSYPR3U.js';
8
9
  import './chunk-YKYCE4HY.js';
9
10
  import './chunk-TZQIEUDE.js';
10
11
  import './chunk-ZVB57WI6.js';
11
- import './chunk-X7UUIHGH.js';
12
12
  import './chunk-RJYKTWUP.js';
13
13
  import './chunk-I3LTIAOR.js';
14
- import './chunk-JFLVUA43.js';
15
- import './chunk-KCB6V5XH.js';
16
- import './chunk-XKZPL3GE.js';
14
+ import './chunk-3RS3RNGH.js';
15
+ import './chunk-XFS2TMOB.js';
16
+ import './chunk-INCKTGMM.js';
17
17
  import './chunk-ESVW4MJY.js';
18
18
  import './chunk-XTNMIV77.js';
19
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, managedProblems, managedFactsOf, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-FKNOPMUD.js';
19
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, managedProblems, managedFactsOf, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-RHBFNZ7J.js';
20
20
  import './chunk-YYYRBYWG.js';
21
21
  import './chunk-ZZSQYOY5.js';
22
22
  import './chunk-TBT347UY.js';
23
- import './chunk-JH2AMJ4K.js';
24
- import './chunk-5TNEVWFJ.js';
25
- import { probeHelper, HELPER_ENV, helperSocketPath } from './chunk-VIHQLW4L.js';
23
+ import './chunk-2FPEB36J.js';
24
+ import './chunk-GXKWPOK6.js';
25
+ import { probeHelper, HELPER_ENV, helperSocketPath } from './chunk-MV52FCSG.js';
26
26
  import './chunk-QQGZ5THT.js';
27
27
  import './chunk-HIGJTX5U.js';
28
- import './chunk-SXJVL7NS.js';
28
+ import './chunk-QNVIGO5X.js';
29
29
  import './chunk-IWYS4ERC.js';
30
30
  import './chunk-TQMI335S.js';
31
31
  import './chunk-NJS7JJYN.js';
32
32
  import { DEFAULT_UNIT_NAME } from './chunk-RQGHHEM7.js';
33
33
  import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-P7BEZAEU.js';
34
34
  import './chunk-UXYLWVTQ.js';
35
- import './chunk-Z7HAIZ6X.js';
35
+ import './chunk-BSHUTMXV.js';
36
36
  import './chunk-T5TBGOT6.js';
37
37
  import './chunk-JBJTC3UU.js';
38
38
  import './chunk-OGFGZQA3.js';
39
- import './chunk-2JPVI45I.js';
39
+ import './chunk-5T2VOSIL.js';
40
40
  import './chunk-YJLHUKYS.js';
41
- import './chunk-SJZL5F3F.js';
42
- import './chunk-U4HMGT3L.js';
43
- import './chunk-3DSC2FN3.js';
44
- import './chunk-IGIGNYZK.js';
45
- import './chunk-HSUUTD4E.js';
46
- import './chunk-V36AOTBP.js';
47
- import './chunk-QDDPVBIS.js';
48
- import './chunk-G2RRBBOX.js';
41
+ import './chunk-3Z3MPR55.js';
42
+ import './chunk-LK2S5XZH.js';
43
+ import './chunk-X7ML37UF.js';
44
+ import './chunk-X2Y3B4JH.js';
45
+ import './chunk-LESWVXRE.js';
46
+ import './chunk-3H7NZPYG.js';
47
+ import './chunk-XT5SOJRC.js';
48
+ import './chunk-ZAJKEHIE.js';
49
+ import './chunk-6C3ZVE62.js';
49
50
  import './chunk-G2JWZDFA.js';
50
51
  import './chunk-ANPNT6PM.js';
51
- import './chunk-NIS2PIS4.js';
52
- import './chunk-V6IYYQU3.js';
52
+ import './chunk-D73OLAYE.js';
53
+ import './chunk-FE3RTGJN.js';
53
54
  import './chunk-F3EF56LQ.js';
54
55
  import './chunk-PJDQPF5N.js';
55
56
  import './chunk-APSYTJ6I.js';
56
57
  import './chunk-KP6R7CV3.js';
57
58
  import { claudeEnvPath } from './chunk-HDSDUTX4.js';
58
- import './chunk-WRW6QCI6.js';
59
+ import './chunk-NHXJU7CM.js';
59
60
  import './chunk-ZJSNLVCE.js';
60
61
  import './chunk-2O5KA67H.js';
61
62
  import './chunk-BKO6JEZI.js';
62
63
  import './chunk-FGF52V4V.js';
63
64
  import './chunk-HCVLP7XA.js';
64
65
  import './chunk-BJ3KTMDH.js';
65
- import './chunk-AKKVPUGK.js';
66
+ import './chunk-YW4PEGLN.js';
66
67
  import './chunk-5BHIBJDA.js';
67
68
  import './chunk-CDDED64E.js';
68
69
  import './chunk-RA3O54FC.js';
@@ -72,8 +73,8 @@ import './chunk-CRB3POP4.js';
72
73
  import './chunk-URIZRCRY.js';
73
74
  import './chunk-YQR6E6OV.js';
74
75
  import './chunk-TUSYOL2O.js';
75
- import './chunk-ZUOPFE22.js';
76
- import './chunk-IWFYKNAO.js';
76
+ import './chunk-JUXATN46.js';
77
+ import './chunk-3WW2TL7V.js';
77
78
  import './chunk-VNVZDWO3.js';
78
79
  import { parseRunnerEnv } from './chunk-XD4ZCMA4.js';
79
80
  import './chunk-MESOOLF4.js';
@@ -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-5TNEVWFJ.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-VIHQLW4L.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-GXKWPOK6.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-MV52FCSG.js';
5
5
  import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-NJS7JJYN.js';
6
6
  import { runnerCredentialProblem } from './chunk-P7BEZAEU.js';
7
7
  import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-KP6R7CV3.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-IWFYKNAO.js';
3
+ import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-3WW2TL7V.js';
4
4
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
5
  import { mkdirSync, appendFileSync, writeFileSync, renameSync, unlinkSync, existsSync, readdirSync, readFileSync, statSync } from 'fs';
6
6
  import { join, dirname } from 'path';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LiveUploader } from './chunk-KCB6V5XH.js';
4
- import { CaptureDaemon } from './chunk-V36AOTBP.js';
5
- import { spoolDir } from './chunk-WRW6QCI6.js';
3
+ import { LiveUploader } from './chunk-XFS2TMOB.js';
4
+ import { CaptureDaemon } from './chunk-XT5SOJRC.js';
5
+ import { spoolDir } from './chunk-NHXJU7CM.js';
6
6
  import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
7
7
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
8
8
  import { mkdirSync, writeFileSync, rmSync } from 'fs';
@@ -22365,7 +22365,7 @@ function itemsAllowResult(result, items) {
22365
22365
  return result === "fail" || !(items != null ? items : []).some((item) => item.result === "fail");
22366
22366
  }
22367
22367
  var EMITTED_RESULTS = ["pass", "fail"];
22368
- var RESERVED_EMIT_NAMES = ["artifact", "criteria", "finding", "findings", "step"];
22368
+ var RESERVED_EMIT_NAMES = ["artifact", "criteria", "demo", "finding", "findings", "step"];
22369
22369
  var EmittedNameSchema = external_exports.string().regex(/^[a-z][a-z0-9._-]{0,63}$/).superRefine((name, ctx) => {
22370
22370
  if (RESERVED_EMIT_NAMES.includes(name)) {
22371
22371
  ctx.addIssue({
@@ -22635,6 +22635,49 @@ var CliLoginRefusalSchema = external_exports.object({
22635
22635
  error: external_exports.string(),
22636
22636
  message: external_exports.string().optional()
22637
22637
  });
22638
+ var DEMO_RECORD_MEDIA_TYPE = "application/vnd.outerlayer.demo+json";
22639
+ var ARTIFACT_MAX_BYTES = 8 * 1024 * 1024;
22640
+ var DEMO_CHAPTERS_MAX = 200;
22641
+ var DEMO_CHECKS_MAX = 100;
22642
+ var DEMO_TITLE_MAX = 200;
22643
+ var DEMO_NARRATION_MAX = 2e3;
22644
+ var DEMO_CHECK_TEXT_MAX = 500;
22645
+ var DemoCheckSchema = external_exports.strictObject({
22646
+ text: external_exports.string().min(1).max(DEMO_CHECK_TEXT_MAX),
22647
+ passed: external_exports.boolean()
22648
+ });
22649
+ var chapterFields = {
22650
+ /** The criterion the chapter shows, or `null` for an opening scene. */
22651
+ criterionId: ArtifactCriterionIdSchema.nullable(),
22652
+ /** Seconds from the start of the video. */
22653
+ start: external_exports.number().finite().min(0),
22654
+ end: external_exports.number().finite().positive(),
22655
+ title: external_exports.string().min(1).max(DEMO_TITLE_MAX),
22656
+ /** The line spoken over the chapter. Empty for a chapter with no speech. */
22657
+ narration: external_exports.string().max(DEMO_NARRATION_MAX),
22658
+ checks: external_exports.array(DemoCheckSchema).max(DEMO_CHECKS_MAX)
22659
+ };
22660
+ var DemoChapterSchema = external_exports.strictObject(chapterFields).refine((chapter) => chapter.end > chapter.start, {
22661
+ message: "a chapter must end after it starts",
22662
+ path: ["end"]
22663
+ });
22664
+ var DemoManifestSchema = external_exports.strictObject({
22665
+ schemaVersion: external_exports.literal(1),
22666
+ /** The recorded video, as a path relative to the manifest's folder. */
22667
+ video: external_exports.string().min(1).max(500),
22668
+ chapters: external_exports.array(DemoChapterSchema).min(1).max(DEMO_CHAPTERS_MAX)
22669
+ });
22670
+ var DemoRecordChapterSchema = external_exports.strictObject({
22671
+ ...chapterFields,
22672
+ /** The `clientArtifactId` of the chapter's clip. */
22673
+ clipArtifactId: external_exports.string().min(1).max(64),
22674
+ /** True when the clip was bound to the chapter's criterion: every check passed. */
22675
+ bound: external_exports.boolean()
22676
+ });
22677
+ external_exports.strictObject({
22678
+ schemaVersion: external_exports.literal(1),
22679
+ chapters: external_exports.array(DemoRecordChapterSchema).min(1).max(DEMO_CHAPTERS_MAX)
22680
+ });
22638
22681
  /*! Bundled license information:
22639
22682
 
22640
22683
  xmlchars/xml/1.0/ed5.js:
@@ -22665,4 +22708,4 @@ xmlchars/xmlns/1.0/ed3.js:
22665
22708
  *)
22666
22709
  */
22667
22710
 
22668
- export { ARTIFACT_KINDS, ARTIFACT_MAX_CAPTION_LENGTH, ARTIFACT_MAX_FILENAME_LENGTH, ARTIFACT_MAX_REPLACES_TARGETS, ArtifactCriterionIdSchema, ArtifactSpoolRecordSchema, ArtifactTombstoneRecordSchema, BUCKET_MODEL_MAX_LENGTH, CAPTURE_TIERS, CHECK_ITEM_REASON_MAX_LENGTH, CLI_LOGIN_KIND, CLI_LOGIN_MACHINE_NAME_MAX, CheckItemsSchema, CliLoginPollResponseSchema, CliLoginRefusalSchema, CliLoginStartedSchema, CriteriaListSchema, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, EMITTED_RESULT_MAX_LINK_LENGTH, EVENT_TYPES, EmittedNameSchema, FindingBatchSchema, FindingsResponseSchema, INPUT_BAND_BOUNDARIES, RESERVED_EMIT_NAMES, SAME_PROBLEM_RULES, SCHEMA_VERSION, SPEED_MAX_LENGTH, StepBodySchema, StepNameSchema, bannedPathsForTier, bindTests, downconvertSession, inferArtifactKind, inputBandOf, isHumanUserTurn, itemsAllowResult, mediaTypeForArtifactPath, parseAgentSession, parseJunit, parseTestSelector, turnCountBound };
22711
+ export { ARTIFACT_KINDS, ARTIFACT_MAX_BYTES, ARTIFACT_MAX_CAPTION_LENGTH, ARTIFACT_MAX_FILENAME_LENGTH, ARTIFACT_MAX_REPLACES_TARGETS, ArtifactCriterionIdSchema, ArtifactSpoolRecordSchema, ArtifactTombstoneRecordSchema, BUCKET_MODEL_MAX_LENGTH, CAPTURE_TIERS, CHECK_ITEM_REASON_MAX_LENGTH, CLI_LOGIN_KIND, CLI_LOGIN_MACHINE_NAME_MAX, CheckItemsSchema, CliLoginPollResponseSchema, CliLoginRefusalSchema, CliLoginStartedSchema, CriteriaListSchema, DEMO_RECORD_MEDIA_TYPE, DemoManifestSchema, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, EMITTED_RESULT_MAX_LINK_LENGTH, EVENT_TYPES, EmittedNameSchema, FindingBatchSchema, FindingsResponseSchema, INPUT_BAND_BOUNDARIES, RESERVED_EMIT_NAMES, SAME_PROBLEM_RULES, SCHEMA_VERSION, SPEED_MAX_LENGTH, StepBodySchema, StepNameSchema, bannedPathsForTier, bindTests, downconvertSession, inferArtifactKind, inputBandOf, isHumanUserTurn, itemsAllowResult, mediaTypeForArtifactPath, parseAgentSession, parseJunit, parseTestSelector, turnCountBound };
@@ -223,54 +223,4 @@ function writeSanitizedRecipe(checkoutDir, location, recipe) {
223
223
  }
224
224
  var SANITIZED_NAME = "outerlayer-recipe.json";
225
225
 
226
- // src/runner/image/pins.ts
227
- var CLAUDE_CODE_VERSION = "2.1.284";
228
- var DEFAULT_BASE_IMAGE = "ubuntu:24.04@sha256:008173c23f95b170204355c12626cb5a965d779a7e1283b09e9cffbb1bf33ca3";
229
- var NODE_IMAGE = "node:22-bookworm-slim@sha256:43ac6c60b8f89723f746e8a92ce91abd5017e627ce1ddfe4238355d3a30b772c";
230
- var BUILDKIT_IMAGE = "moby/buildkit:v0.33.1@sha256:cec9f139f45e93c5c69c60f8b07cfad9f43f4ef6b6a6cd917527fea5ff2e3dea";
231
- var GH_VERSION = "2.101.0";
232
- var GH_SHA256 = {
233
- amd64: "9bca2d1c16825f109907a23307628a2f0698fbf99662b73a5cf0b020293072b8",
234
- arm64: "b57e8063f18862647c9d22727c32e9da1b963f8bf9db648fe123a6975695640f"
235
- };
236
- var TINI_VERSION = "0.19.0";
237
- var TINI_SHA256 = {
238
- amd64: "c5b0666b4cb676901f90dfcb37106783c5fe2077b04590973b885950611b30ee",
239
- arm64: "eae1d3aa50c48fb23b8cbdf4e369d0910dfc538566bfd09df89a774aa84a48b9"
240
- };
241
- var MICROVM_ARCHES = ["x86_64"];
242
- function firecrackerArch(nodeArch) {
243
- return nodeArch === "x64" ? "x86_64" : nodeArch === "arm64" ? "aarch64" : nodeArch;
244
- }
245
- var FIRECRACKER_VERSION = "1.17.0";
246
- var FIRECRACKER_SHA256 = {
247
- x86_64: "06094a1108ae9e82aa4c23a775aa92758f53f1175d422270d9d6162cb9ade558"
248
- };
249
- var FIRECRACKER_BINARY_SHA256 = {
250
- x86_64: "99ad0f5cd0514a88aad0e9ae8cfdb3cc3b4ab9d190e1194602406c786b5de7a5"
251
- };
252
- var GUEST_ASSETS_VERSION = "7";
253
- var GUEST_ASSETS_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${GUEST_ASSETS_VERSION}`;
254
- var GUEST_KERNEL_SHA256 = {
255
- x86_64: "8552fad4bdea1d49f3e7d2aa500ce3f8918fcd2fc66779fd83235949688a39bb"
256
- };
257
- var GUEST_HELPER_SHA256 = {
258
- x86_64: "0ae934d3ad3f2a94abffcc3f044ba633b1a523dc17ff0c2bc322ed7d7fc505ea"
259
- };
260
- function guestAssetsPinned(arch) {
261
- const zero = "0".repeat(64);
262
- return GUEST_KERNEL_SHA256[arch] !== zero && GUEST_HELPER_SHA256[arch] !== zero;
263
- }
264
- var JAILER_BINARY_SHA256 = {
265
- x86_64: "65ef226e96f0ceda55ba643f445801ef2cc0ea667ef67cad8ac4f406c9c8434f"
266
- };
267
- var HOST_HELPER_ASSETS_VERSION = "10";
268
- var HOST_HELPER_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${HOST_HELPER_ASSETS_VERSION}`;
269
- var HOST_HELPER_SHA256 = {
270
- x86_64: "caa06b7206cceae6d8fc569781b269817ca66cb2ccfe177740fda042ed46bfcc"
271
- };
272
- function hostHelperPinned(arch = "x86_64", hashes = HOST_HELPER_SHA256) {
273
- return hashes[arch] !== "0".repeat(64);
274
- }
275
-
276
- export { BUILDKIT_IMAGE, CLAUDE_CODE_VERSION, DEFAULT_BASE_IMAGE, DOCKER_FEATURE, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, FIRECRACKER_VERSION, GH_SHA256, GH_VERSION, GUEST_ASSETS_BASE_URL, GUEST_ASSETS_VERSION, GUEST_HELPER_SHA256, GUEST_KERNEL_SHA256, HOST_HELPER_ASSETS_VERSION, HOST_HELPER_BASE_URL, HOST_HELPER_SHA256, JAILER_BINARY_SHA256, MICROVM_ARCHES, NODE_IMAGE, RecipeError, SANITIZED_NAME, TINI_SHA256, TINI_VERSION, assertBuildable, classifyProperties, firecrackerArch, guestAssetsPinned, hostHelperPinned, locateRecipe, readRecipe, writeSanitizedRecipe };
226
+ export { DOCKER_FEATURE, RecipeError, SANITIZED_NAME, assertBuildable, classifyProperties, locateRecipe, readRecipe, writeSanitizedRecipe };
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { launchRefusalForSession } from './chunk-ESVW4MJY.js';
4
- import { detectActiveSession, autoConnect, transcriptPathForSession } from './chunk-3DSC2FN3.js';
5
- import { resolveRepoIdentity, defaultProjectsDir, findTranscripts, sessionIdFromPath, scrubText } from './chunk-V36AOTBP.js';
4
+ import { detectActiveSession, autoConnect, transcriptPathForSession } from './chunk-X2Y3B4JH.js';
5
+ import { resolveRepoIdentity, defaultProjectsDir, findTranscripts, sessionIdFromPath, scrubText } from './chunk-XT5SOJRC.js';
6
6
  import { C } from './chunk-ANPNT6PM.js';
7
7
  import { resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-F3EF56LQ.js';
8
8
  import { readLatestProvenanceForSession } from './chunk-ZJSNLVCE.js';
9
9
  import { launchedItemForSession } from './chunk-T2Q7ISPE.js';
10
10
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
11
11
  import { cliInvocation } from './chunk-CRB3POP4.js';
12
- import { FindingBatchSchema, FindingsResponseSchema, SAME_PROBLEM_RULES } from './chunk-IWFYKNAO.js';
12
+ import { FindingBatchSchema, FindingsResponseSchema, SAME_PROBLEM_RULES } from './chunk-3WW2TL7V.js';
13
13
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
14
14
  import { readFileSync, existsSync } from 'fs';
15
15
  import { join, dirname, basename } from 'path';
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { parseSize } from './chunk-YJLHUKYS.js';
4
- import { RecipeError, BUILDKIT_IMAGE } from './chunk-SJZL5F3F.js';
5
- import { compareVersions } from './chunk-V36AOTBP.js';
4
+ import { RecipeError } from './chunk-3Z3MPR55.js';
5
+ import { BUILDKIT_IMAGE } from './chunk-LK2S5XZH.js';
6
+ import { compareVersions } from './chunk-XT5SOJRC.js';
6
7
  import { ensureHostKey } from './chunk-APSYTJ6I.js';
7
8
  import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-KP6R7CV3.js';
8
9
  import { CLAUDE_PORT, JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-HDSDUTX4.js';
@@ -5,7 +5,7 @@ import { C } from './chunk-ANPNT6PM.js';
5
5
  import { readCloudConfigStrict, CloudConfigError, readCloudConfig, writeCloudConfig, cloudConfigPath } from './chunk-PJDQPF5N.js';
6
6
  import { findGitDirs } from './chunk-BJ3KTMDH.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
8
- import { CLI_LOGIN_MACHINE_NAME_MAX, CliLoginPollResponseSchema, CLI_LOGIN_KIND, CliLoginRefusalSchema, CliLoginStartedSchema } from './chunk-IWFYKNAO.js';
8
+ import { CLI_LOGIN_MACHINE_NAME_MAX, CliLoginPollResponseSchema, CLI_LOGIN_KIND, CliLoginRefusalSchema, CliLoginStartedSchema } from './chunk-3WW2TL7V.js';
9
9
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
10
10
  import { generateKeyPairSync, privateDecrypt, constants, createPrivateKey } from 'crypto';
11
11
  import { spawn } from 'child_process';
@@ -2,7 +2,8 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { claimPidFile, RunnerAlreadyRunningError, releasePidFile } from './chunk-T5TBGOT6.js';
4
4
  import { startTimeOf } from './chunk-JBJTC3UU.js';
5
- import { CLAUDE_CODE_VERSION, NODE_IMAGE, DEFAULT_BASE_IMAGE, RecipeError, locateRecipe, readRecipe, assertBuildable, TINI_VERSION, GH_VERSION, writeSanitizedRecipe, classifyProperties, GH_SHA256, TINI_SHA256, SANITIZED_NAME } from './chunk-SJZL5F3F.js';
5
+ import { RecipeError, locateRecipe, readRecipe, assertBuildable, writeSanitizedRecipe, classifyProperties, SANITIZED_NAME } from './chunk-3Z3MPR55.js';
6
+ import { CLAUDE_CODE_VERSION, NODE_IMAGE, DEFAULT_BASE_IMAGE, MEDIA_PINS, TINI_VERSION, GH_VERSION, VOICE_PACK_FILES, VOICE_PACK_VERSION, FFMPEG_STATIC, FFMPEG_BUILD_TAG, GH_SHA256, TINI_SHA256 } from './chunk-LK2S5XZH.js';
6
7
  import { RUNNER_DIR_MODE, repoCacheDir, imagesDir, attemptStamp, runnerDir, rootfsPathFor, RUNNER_FILE_MODE } from './chunk-KP6R7CV3.js';
7
8
  import { withGitConfig, tokenHeader, PROXY_WARNING_FLAG } from './chunk-HDSDUTX4.js';
8
9
  import { RELAY_ID, RELAY_USER } from './chunk-MESOOLF4.js';
@@ -150,12 +151,16 @@ function plain(name, value, allowed) {
150
151
  if (!allowed.test(value)) throw new Error(`${name} holds a character a Dockerfile line cannot carry safely: ${JSON.stringify(value)}`);
151
152
  return value;
152
153
  }
154
+ var DEFAULT_PACKAGES = ["git", "ca-certificates", "curl", "build-essential", "python3", "python3-pip", "python3-venv", "unzip", "jq"];
153
155
  function defaultDockerfile(baseImage, nodeImage) {
156
+ return ubuntuWithNode(baseImage, nodeImage, DEFAULT_PACKAGES);
157
+ }
158
+ function ubuntuWithNode(baseImage, nodeImage, packages) {
154
159
  return [
155
160
  `FROM ${baseImage}`,
156
161
  "ENV DEBIAN_FRONTEND=noninteractive",
157
162
  "RUN apt-get update \\",
158
- " && apt-get install -y --no-install-recommends git ca-certificates curl \\",
163
+ ` && apt-get install -y --no-install-recommends ${packages.join(" ")} \\`,
159
164
  " && rm -rf /var/lib/apt/lists/*",
160
165
  `COPY --from=${nodeImage} /usr/local/bin/node /usr/local/bin/node`,
161
166
  `COPY --from=${nodeImage} /usr/local/lib/node_modules /usr/local/lib/node_modules`,
@@ -177,7 +182,40 @@ function toolsDockerfile(parts) {
177
182
  )
178
183
  });
179
184
  const download = `NODE_USE_ENV_PROXY=1 node ${PROXY_WARNING_FLAG} -e 'fetch(process.argv[1]).then((r)=>{if(!r.ok)throw new Error(process.argv[1]+" "+r.status);return r.arrayBuffer()}).then((b)=>require("fs").writeFileSync(process.argv[2],Buffer.from(b)))'`;
185
+ const stream = `NODE_USE_ENV_PROXY=1 node ${PROXY_WARNING_FLAG} -e 'const{pipeline}=require("stream/promises"),{Readable}=require("stream"),fs=require("fs");fetch(process.argv[1]).then((r)=>{if(!r.ok)throw new Error(process.argv[1]+" "+r.status);return pipeline(Readable.fromWeb(r.body),fs.createWriteStream(process.argv[2]))})'`;
186
+ const voiceDir = `/out/opt/outerlayer/voice/${VOICE_PACK_VERSION}`;
187
+ const checks = VOICE_PACK_FILES.map((file) => `echo "${file.sha256} ${voiceDir}/${file.name}" | sha256sum -c -`);
180
188
  return [
189
+ // The voice pack streams to disk, one pinned file at a time, because a 300 MB model must not sit in a build's memory. Its own stage keeps it cached when the CLI changes.
190
+ `FROM ${nodeImage} AS voice`,
191
+ `RUN mkdir -p ${voiceDir} \\`,
192
+ ...VOICE_PACK_FILES.map((file) => ` && ${stream} ${file.url} ${voiceDir}/${file.name} \\`),
193
+ ...checks.map((check) => ` && ${check} \\`),
194
+ " && chmod -R a+rX /out",
195
+ // ffmpeg and ffprobe are static LGPL builds. espeak-ng comes from the stage image's own package, with the libraries and loader it needs, and runs as a separate program.
196
+ `FROM ${nodeImage} AS media`,
197
+ "ARG TARGETARCH",
198
+ "RUN apt-get update \\",
199
+ " && apt-get install -y --no-install-recommends ca-certificates espeak-ng xz-utils \\",
200
+ " && rm -rf /var/lib/apt/lists/*",
201
+ "RUN set -eu \\",
202
+ ` && case "$TARGETARCH" in \\`,
203
+ ` amd64) ffmpeg_file=${FFMPEG_STATIC.amd64.file}; ffmpeg_sha=${FFMPEG_STATIC.amd64.sha256} ;; \\`,
204
+ ` arm64) ffmpeg_file=${FFMPEG_STATIC.arm64.file}; ffmpeg_sha=${FFMPEG_STATIC.arm64.sha256} ;; \\`,
205
+ ` *) echo "no pinned ffmpeg for $TARGETARCH" >&2; exit 1 ;; \\`,
206
+ " esac \\",
207
+ ` && ${download} https://github.com/BtbN/FFmpeg-Builds/releases/download/${FFMPEG_BUILD_TAG}/$ffmpeg_file /tmp/ffmpeg.tar.xz \\`,
208
+ ' && echo "$ffmpeg_sha /tmp/ffmpeg.tar.xz" | sha256sum -c - \\',
209
+ " && tar -xJf /tmp/ffmpeg.tar.xz -C /tmp \\",
210
+ " && mkdir -p /out/usr/local/bin /out/opt/outerlayer/media/lib \\",
211
+ " && install -m 0755 /tmp/ffmpeg-*/bin/ffmpeg /tmp/ffmpeg-*/bin/ffprobe /out/usr/local/bin/ \\",
212
+ " && install -m 0755 /usr/bin/espeak-ng /out/opt/outerlayer/media/espeak-ng \\",
213
+ ` && for lib in $(ldd /usr/bin/espeak-ng | awk '$3 ~ /^\\// {print $3}'); do cp -L "$lib" /out/opt/outerlayer/media/lib/; done \\`,
214
+ " && cp -L $(ldd /usr/bin/espeak-ng | awk '$1 ~ /ld-linux/ {print $1}') /out/opt/outerlayer/media/lib/ld.so \\",
215
+ " && cp -r /usr/lib/*/espeak-ng-data /out/opt/outerlayer/media/espeak-ng-data \\",
216
+ ` && printf '%s\\n' '#!/bin/sh' 'ESPEAK_DATA_PATH=/opt/outerlayer/media' 'export ESPEAK_DATA_PATH' 'exec /opt/outerlayer/media/lib/ld.so --library-path /opt/outerlayer/media/lib /opt/outerlayer/media/espeak-ng "$@"' > /out/usr/local/bin/espeak-ng \\`,
217
+ " && chmod 0755 /out/usr/local/bin/espeak-ng \\",
218
+ " && chmod -R a+rX /out",
181
219
  `FROM ${recipeImage} AS recipe`,
182
220
  `FROM ${nodeImage} AS stage`,
183
221
  "ARG TARGETARCH",
@@ -231,8 +269,15 @@ function toolsDockerfile(parts) {
231
269
  " && chmod -R a+rX /out",
232
270
  `FROM ${recipeImage}`,
233
271
  "COPY --from=stage /out/ /",
272
+ "COPY --from=voice /out/ /",
273
+ "COPY --from=media /out/ /",
234
274
  "ENV DISABLE_AUTOUPDATER=1",
235
- "RUN outerlayer --version && claude --version && gh --version",
275
+ // espeak-ng's audio library makes a private pulse-* folder for the user who runs it, in the temp folder unless XDG_RUNTIME_DIR names another.
276
+ // Made here, as root, it would ship in the image where the build user cannot read it, and the runner's disk check fails on it.
277
+ "RUN check=$(mktemp -d /tmp/ol-check.XXXXXX) \\",
278
+ " && outerlayer --version && claude --version && gh --version && ffmpeg -version && ffprobe -version \\",
279
+ ' && XDG_RUNTIME_DIR="$check" espeak-ng --version \\',
280
+ ' && rm -rf "$check"',
236
281
  ""
237
282
  ].join("\n");
238
283
  }
@@ -269,7 +314,11 @@ function recipeKey(checkoutDir, location, defaultDockerfile2) {
269
314
  }
270
315
  function toolsKey(parts) {
271
316
  const base = [parts.buildId, "\0", parts.claudeCodeVersion, "\0", parts.nodeImage, "\0", parts.ghVersion, "\0", parts.tiniVersion];
272
- return sha256(...base, ...parts.guestHelperSha256 === void 0 ? [] : ["\0guest-helper\0", parts.guestHelperSha256]);
317
+ return sha256(
318
+ ...base,
319
+ ...parts.guestHelperSha256 === void 0 ? [] : ["\0guest-helper\0", parts.guestHelperSha256],
320
+ ...parts.mediaPins === void 0 ? [] : ["\0media\0", parts.mediaPins]
321
+ );
273
322
  }
274
323
 
275
324
  // src/runner/image/prune.ts
@@ -370,7 +419,7 @@ async function buildRepositoryImage(opts, ports) {
370
419
  assertBuildable(checkout.dir, location, recipe);
371
420
  const defaultText = defaultDockerfile(baseImage, nodeImage);
372
421
  const rKey = recipeKey(checkout.dir, location, defaultText);
373
- const tKey = toolsKey({ buildId: opts.cli.buildId, claudeCodeVersion, nodeImage, ghVersion: GH_VERSION, tiniVersion: TINI_VERSION, guestHelperSha256: opts.guestHelper?.sha256 });
422
+ const tKey = toolsKey({ buildId: opts.cli.buildId, claudeCodeVersion, nodeImage, ghVersion: GH_VERSION, tiniVersion: TINI_VERSION, guestHelperSha256: opts.guestHelper?.sha256, mediaPins: MEDIA_PINS });
374
423
  const recordDir = join(repoRecords, `${rKey.slice(0, KEY_PREFIX)}-${tKey.slice(0, KEY_PREFIX)}`);
375
424
  const buildTag = `${TAG_HOST}/build/${repository}:${rKey.slice(0, KEY_PREFIX)}-${tKey.slice(0, KEY_PREFIX)}`;
376
425
  const recipeTag = `${TAG_HOST}/recipe/${repository}:${rKey.slice(0, KEY_PREFIX)}`;
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { removeRetiredSkills } from './chunk-V6IYYQU3.js';
3
+ import { removeRetiredSkills } from './chunk-FE3RTGJN.js';
4
4
  import { defaultFetch, resolveGatewayCredentials } from './chunk-F3EF56LQ.js';
5
5
  import { withTokenHeader } from './chunk-HDSDUTX4.js';
6
6
  import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
7
- import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-AKKVPUGK.js';
7
+ import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-YW4PEGLN.js';
8
8
  import { cliInvocation } from './chunk-CRB3POP4.js';
9
9
  import { writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, writeContextManifest, SOURCE_CACHE_TTL_SUCCESS_MS, readSourceCache, isSourceCacheFresh, clearDegraded } from './chunk-YQR6E6OV.js';
10
- import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-ZUOPFE22.js';
10
+ import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-JUXATN46.js';
11
11
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
12
12
  import { execFileSync } from 'child_process';
13
13
  import { existsSync, mkdirSync, writeFileSync, chmodSync, lstatSync, readFileSync, copyFileSync } from 'fs';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { skillDir, FORMER_MAINTAINED_NAMES, isMaintainedCopy } from './chunk-AKKVPUGK.js';
3
+ import { skillDir, FORMER_MAINTAINED_NAMES, isMaintainedCopy } from './chunk-YW4PEGLN.js';
4
4
  import { cliInvocation } from './chunk-CRB3POP4.js';
5
- import { emitTree, ALL_TARGET_IDS, classifyTree } from './chunk-ZUOPFE22.js';
5
+ import { emitTree, ALL_TARGET_IDS, classifyTree } from './chunk-JUXATN46.js';
6
6
  import { readFileSync, existsSync, unlinkSync, rmdirSync, readdirSync } from 'fs';
7
7
  import { join, dirname, relative, sep } from 'path';
8
8
 
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-QDDPVBIS.js';
3
+ import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-ZAJKEHIE.js';
4
4
  import { C } from './chunk-ANPNT6PM.js';
5
- import { retiredSkillPaths, removeRetiredSkills } from './chunk-V6IYYQU3.js';
6
- import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-AKKVPUGK.js';
5
+ import { retiredSkillPaths, removeRetiredSkills } from './chunk-FE3RTGJN.js';
6
+ import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-YW4PEGLN.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
8
- import { emitTree, generatedHeaderSource, parseOuterlayerConfig, classifyTree } from './chunk-ZUOPFE22.js';
8
+ import { emitTree, generatedHeaderSource, parseOuterlayerConfig, classifyTree } from './chunk-JUXATN46.js';
9
9
  import { existsSync, readFileSync, mkdirSync, writeFileSync, copyFileSync, unlinkSync, rmdirSync, readdirSync } from 'fs';
10
10
  import { join, dirname } from 'path';
11
11
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { MIN_ENGINE_MAJOR } from './chunk-VIHQLW4L.js';
3
+ import { MIN_ENGINE_MAJOR } from './chunk-MV52FCSG.js';
4
4
  import { runnerImageVersion } from './chunk-IWYS4ERC.js';
5
- import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-SJZL5F3F.js';
5
+ import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-LK2S5XZH.js';
6
6
  import { spawnSync } from 'child_process';
7
7
  import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
8
8