@outerlayer/cli 0.34.0-next.20261024180339 → 0.34.0-next.20261024231715

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 (94) hide show
  1. package/README.md +5 -5
  2. package/dist/{agent-setup-FBAT5LGX.js → agent-setup-HEJM3D3V.js} +9 -9
  3. package/dist/build-info.json +1 -1
  4. package/dist/{check-HCKDHD2R.js → check-OOUGS65D.js} +20 -20
  5. package/dist/{chunk-SVLFZLTE.js → chunk-272AKVRP.js} +5 -5
  6. package/dist/{chunk-B5MSDF5B.js → chunk-2AIOOU3A.js} +4 -4
  7. package/dist/{chunk-BTHH5H5H.js → chunk-3IH6K7KG.js} +2 -2
  8. package/dist/{chunk-XFAJQZN2.js → chunk-4P6QGMPN.js} +2 -2
  9. package/dist/{chunk-43ZOV4OR.js → chunk-4Y54SQXH.js} +10 -10
  10. package/dist/{chunk-MHGIN2X6.js → chunk-5HZGLLNW.js} +2 -2
  11. package/dist/{chunk-74Q24R3B.js → chunk-5QBUX5YZ.js} +7 -7
  12. package/dist/{chunk-6AQLRSYU.js → chunk-62LXQM7U.js} +2 -2
  13. package/dist/{chunk-SHIGGHZO.js → chunk-65AKMFBH.js} +2 -2
  14. package/dist/{chunk-OHJDH5GV.js → chunk-6NUPXDAA.js} +1 -1
  15. package/dist/{chunk-ZADIXMKT.js → chunk-7WM7K2DY.js} +1 -1
  16. package/dist/{chunk-XLJHFZRL.js → chunk-ACRRO3MB.js} +7 -7
  17. package/dist/{chunk-OLCIPTST.js → chunk-AP2K4LPI.js} +4 -4
  18. package/dist/{chunk-YPCDDQFU.js → chunk-DQ6YO7FH.js} +1 -1
  19. package/dist/{chunk-5HLA7KPK.js → chunk-E4ASIOVL.js} +1 -1
  20. package/dist/{chunk-NVDPSH72.js → chunk-EE2ZZGQV.js} +1 -1
  21. package/dist/{chunk-GWF3ZRUX.js → chunk-EN3YWO7Q.js} +1 -1
  22. package/dist/{chunk-CQRPR4WZ.js → chunk-FGXT5OXS.js} +56 -126
  23. package/dist/{chunk-3KT2IWV3.js → chunk-FVKH3PMV.js} +49 -9
  24. package/dist/{chunk-UF2FU3CM.js → chunk-JWNH4ZTF.js} +2 -2
  25. package/dist/{chunk-2G7PJAJZ.js → chunk-K5Q6T7SE.js} +1 -1
  26. package/dist/{chunk-TIRHZC2M.js → chunk-NKOM4JKY.js} +2 -2
  27. package/dist/{chunk-B44BFR2Q.js → chunk-O6DYCIVW.js} +3 -3
  28. package/dist/{chunk-YREGBU3O.js → chunk-QDVGOMSC.js} +1 -1
  29. package/dist/{chunk-5XZ6BUPH.js → chunk-QMWUPRYQ.js} +1 -1
  30. package/dist/{chunk-HMCBX3PL.js → chunk-RCRE42V6.js} +1 -1
  31. package/dist/{chunk-R2CLQJA2.js → chunk-TDAQHYM4.js} +1 -1
  32. package/dist/{chunk-SMAZA7DM.js → chunk-XFFUXXI4.js} +2 -2
  33. package/dist/{chunk-TFKROYY2.js → chunk-YEVPRO7L.js} +3 -3
  34. package/dist/{chunk-HBVHRC3A.js → chunk-YGSY2NWU.js} +2 -2
  35. package/dist/{chunk-PBIYM2Z6.js → chunk-YIBFGAYI.js} +2 -2
  36. package/dist/{chunk-HIGP4WOC.js → chunk-Z4KWHSO4.js} +3 -3
  37. package/dist/{chunk-ZGB4ZJ5E.js → chunk-ZQSANKS4.js} +1 -1
  38. package/dist/{chunk-5WCBFLES.js → chunk-ZW6L275N.js} +7 -7
  39. package/dist/{claude-launcher-YXRS4EZE.js → claude-launcher-MORG66PJ.js} +4 -4
  40. package/dist/{cli-ADIMCYPF.js → cli-XI7RUSC5.js} +90 -94
  41. package/dist/{command-YQBQDIAM.js → command-BJSHY6OB.js} +10 -10
  42. package/dist/{connect-cmd-42JHZKWN.js → connect-cmd-YAUOCX4X.js} +4 -4
  43. package/dist/{container-start-W4VEGRL5.js → container-start-QADK3YGL.js} +17 -17
  44. package/dist/{context-cleanup-YGWYIFFV.js → context-cleanup-LUBEZB3L.js} +2 -2
  45. package/dist/{context-show-cmd-LIWHRWVT.js → context-show-cmd-VHY3OBIA.js} +5 -5
  46. package/dist/{control-plane-launch-AXBWT5CC.js → control-plane-launch-QSBWTA2V.js} +5 -5
  47. package/dist/{doctor-AZZJBJYO.js → doctor-UR76MCGI.js} +11 -11
  48. package/dist/{emit-artifact-cmd-NU5JURAA.js → emit-artifact-cmd-DP2EQ54N.js} +9 -9
  49. package/dist/{emit-cmd-A4CB7BEC.js → emit-cmd-7NMNKDK7.js} +5 -5
  50. package/dist/{emit-criteria-cmd-RAU3PDEK.js → emit-criteria-cmd-TTFBN6RK.js} +6 -6
  51. package/dist/{emit-demo-cmd-524A54D5.js → emit-demo-cmd-Z7YGLEBJ.js} +10 -10
  52. package/dist/{emit-finding-cmd-LE3HFQWL.js → emit-finding-cmd-IQRD3J2X.js} +6 -6
  53. package/dist/{emit-result-cmd-XT2VEPAJ.js → emit-result-cmd-GIWB6UHH.js} +8 -8
  54. package/dist/{emit-step-cmd-LXOKBFQE.js → emit-step-cmd-PU5TTU6C.js} +6 -6
  55. package/dist/{findings-cmd-O5HUK26I.js → findings-cmd-7J5SHCUO.js} +6 -6
  56. package/dist/{fleet-readiness-VAKMSSWI.js → fleet-readiness-G63D76EX.js} +6 -6
  57. package/dist/{governing-source-FNSH4V4A.js → governing-source-DLESDP6T.js} +9 -9
  58. package/dist/{hook-fast-WENTLDMA.js → hook-fast-VQXRDS6E.js} +1 -1
  59. package/dist/index.js +4 -4
  60. package/dist/{init-RUIWHKLE.js → init-67R7LO4C.js} +10 -10
  61. package/dist/{init-LQDKX2XL.js → init-KSXU4PA7.js} +10 -10
  62. package/dist/{init-cmd-2OTTULTI.js → init-cmd-MNOVMADM.js} +14 -14
  63. package/dist/{init-update-TN2W4EN6.js → init-update-6KEXRCJH.js} +13 -13
  64. package/dist/{layout-NAPG4SX2.js → layout-7B3O3FT3.js} +3 -3
  65. package/dist/{loop-X3ANDLQU.js → loop-KUEOPBKX.js} +20 -20
  66. package/dist/{machine-IEYKRHRK.js → machine-EQEAPT76.js} +10 -10
  67. package/dist/{machine-skills-2TT3RXMJ.js → machine-skills-3FEGR376.js} +3 -3
  68. package/dist/{runner-key-QKZZTKLY.js → runner-key-ML7R33HF.js} +10 -10
  69. package/dist/{session-sender-IH44FURK.js → session-sender-A43GZQ7T.js} +9 -9
  70. package/dist/{spec-cmd-2LRTOTAO.js → spec-cmd-VVUJZSG2.js} +7 -7
  71. package/dist/{starter-pack-5D4BANFU.js → starter-pack-LEL3Q2DB.js} +4 -4
  72. package/dist/{status-6ISCZDBX.js → status-4G6K7I2C.js} +15 -15
  73. package/dist/{sync-cmd-MIID2ANV.js → sync-cmd-ZEC65ABJ.js} +8 -8
  74. package/dist/{update-steps-4M2GIB4A.js → update-steps-XLO7734I.js} +16 -16
  75. package/dist/{watch-K5UUKCPB.js → watch-QB4AMWR3.js} +8 -8
  76. package/dist/{work-claim-cmd-2LD2JQKI.js → work-claim-cmd-6W3GBHRS.js} +8 -8
  77. package/dist/{work-cmd-NR53YCXJ.js → work-cmd-LTZXOPPN.js} +6 -6
  78. package/dist/{work-comment-cmd-PC4HNM45.js → work-comment-cmd-LDZBUO6M.js} +7 -7
  79. package/dist/{work-demo-cmd-S5EJXBVH.js → work-demo-cmd-77LISWQ3.js} +6 -6
  80. package/dist/{work-logs-cmd-5F6MDBLQ.js → work-logs-cmd-FK7HE7PC.js} +6 -6
  81. package/dist/{work-open-pr-cmd-SWVFDSMY.js → work-open-pr-cmd-WVONEHZL.js} +7 -7
  82. package/dist/{work-pr-cmd-DXW4RXG4.js → work-pr-cmd-6IPXWJEH.js} +6 -6
  83. package/dist/{work-proofs-cmd-UVTSPFLL.js → work-proofs-cmd-TGIAP5IO.js} +7 -7
  84. package/dist/work-proofs-record-XPAU7N57.js +2382 -0
  85. package/dist/{work-stop-cmd-HL6FZL5X.js → work-stop-cmd-UJ45EV3A.js} +6 -6
  86. package/package.json +2 -1
  87. package/skill-pack/maintained/outerlayer-amend/SKILL.md +1 -2
  88. package/skill-pack/maintained/outerlayer-build/SKILL.md +4 -3
  89. package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +33 -28
  90. package/skill-pack/maintained/outerlayer-build/references/evidence.md +22 -20
  91. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +1 -1
  92. package/dist/chunk-RT6VNM3S.js +0 -148
  93. package/dist/work-proofs-init-GNGI7PZU.js +0 -35
  94. package/dist/work-proofs-record-HTWSMEDG.js +0 -402
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveCredentials, postJson, WorkCommandError } from './chunk-HIGP4WOC.js';
3
+ import { resolveCredentials, postJson, WorkCommandError } from './chunk-Z4KWHSO4.js';
4
4
  import './chunk-IP7BIBXJ.js';
5
- import './chunk-OHJDH5GV.js';
6
- import './chunk-NVDPSH72.js';
5
+ import './chunk-6NUPXDAA.js';
6
+ import './chunk-EE2ZZGQV.js';
7
7
  import './chunk-MECW77XP.js';
8
8
  import './chunk-6ZFY2L2T.js';
9
- import './chunk-TIRHZC2M.js';
9
+ import './chunk-NKOM4JKY.js';
10
10
  import './chunk-Y5YCX6AL.js';
11
11
  import './chunk-G2JWZDFA.js';
12
12
  import './chunk-ANPNT6PM.js';
@@ -16,13 +16,13 @@ import './chunk-SOI6K5DY.js';
16
16
  import './chunk-PA6CK6WQ.js';
17
17
  import './chunk-BALIE3BA.js';
18
18
  import './chunk-BJ3KTMDH.js';
19
- import './chunk-ZGB4ZJ5E.js';
19
+ import './chunk-ZQSANKS4.js';
20
20
  import './chunk-5BHIBJDA.js';
21
21
  import './chunk-CDDED64E.js';
22
22
  import './chunk-RA3O54FC.js';
23
23
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
24
24
  import './chunk-CRB3POP4.js';
25
- import './chunk-CQRPR4WZ.js';
25
+ import './chunk-FGXT5OXS.js';
26
26
  import './chunk-EOTMDIYC.js';
27
27
  import './chunk-VNVZDWO3.js';
28
28
  import './chunk-HACGUL52.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outerlayer/cli",
3
- "version": "0.34.0-next.20261024180339",
3
+ "version": "0.34.0-next.20261024231715",
4
4
  "description": "OuterLayer CLI — commands: init, claude, connect, doctor, login, logout, sync, daemon (alias: watch), emit, findings, work, spec, runner, hooks, mcp, context. Capture and sync coding-agent sessions, and record proof of factory work.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Magu Studios, Inc.",
@@ -56,6 +56,7 @@
56
56
  "@types/pngjs": "^6.0.5",
57
57
  "commander": "^15.0.0",
58
58
  "http-message-sig": "0.3.0",
59
+ "minimatch": "^10.2.3",
59
60
  "pngjs": "^7.0.0",
60
61
  "structured-headers": "2.1.1",
61
62
  "tsup": "^8.5.0",
@@ -113,8 +113,7 @@ repository. Commit and push in each checkout you change, to its own branch only.
113
113
  `outerlayer work comment --item "$OUTERLAYER_WORK" [--criterion <criterion>] --body "<what changed>" --ready`.
114
114
  Omit `--criterion` on the general thread.
115
115
  6. **Record the proofs again** before you watch CI: the evidence check waits
116
- on them. Push any recipe edit (`.outerlayer/proofs/<item key>.yaml`) first.
117
- Run `outerlayer work proofs --record --comment --pr <prNumber>` in each
116
+ on them. Run `outerlayer work proofs --record --comment --pr <prNumber>` in each
118
117
  checkout you pushed.
119
118
  7. **Watch CI.** Skip this step when you pushed nothing. Run
120
119
  `gh pr checks <prNumber> --repo <repository> --watch` on each pull request
@@ -342,9 +342,10 @@ Run them in order.
342
342
  same time, as release.md's "Watch CI" says: CI never reads the proofs.
343
343
  6. **Evidence.** Run `outerlayer emit step "Evidence" --item "$OUTERLAYER_WORK"`,
344
344
  then apply the team's changes for this phase. Read [references/evidence.md](references/evidence.md)
345
- when the pull request opens, and run it. Write and commit the proof recipe
346
- (`outerlayer work proofs --init`), then capture each proof with
347
- `outerlayer work proofs --record`. Check the proofs with
345
+ when the pull request opens, and run it. Write and commit the demo test and the
346
+ file-proof tests. Each test names the id of the criterion it proves. When the
347
+ repository has no `.outerlayer-proofs.yaml`, write and commit one. Then
348
+ capture each proof with `outerlayer work proofs --record`. Check the proofs with
348
349
  `outerlayer work proofs`, as that file says.
349
350
 
350
351
  Optional steps a team may turn off: the manual test and screenshots in the
@@ -264,36 +264,41 @@ Record each criterion that declares `proof: screenshot` as a chapter of the same
264
264
  demo, with a `demo.screenshot()` call where the result shows. The frame then
265
265
  comes from the committed test, so a later session records it again at the new head.
266
266
 
267
- Every proof comes from a recipe that you commit with the change. Run
268
- `outerlayer work proofs --init --pr <number>`. It writes
269
- `.outerlayer/proofs/<item key>.yaml` and, when absent, `.outerlayer/proofs/setup.yaml`.
270
- Fill them in:
271
-
272
- - `setup.yaml` lists the commands that seed and start the app (`setup`) and
273
- stop it (`teardown`). Each setup command must return once the app is ready.
274
- - The one `emit: demo` entry holds the command that runs the demo test. Write
275
- the test with `@outerlayer/playwright`, one chapter for each criterion in the
276
- criteria's order, as the outerlayer-evidence skill's "Record a demo" says. The
277
- test writes its manifest where `OUTERLAYER_PROOF_OUT` names. The entry covers
278
- every screenshot and video criterion that no other entry names.
279
- - Every other proof is a command entry: a `command` that writes one file, the
280
- repository-relative `emit` path of that file, and `for`, the criterion id.
281
- The kind of the file must be the kind the criterion declares. Write the file
282
- to a folder that `.gitignore` ignores, such as `out/`, and add the folder to
283
- `.gitignore` when it is not there. The proof is uploaded, never committed.
284
- - A proof that only a person can capture goes under `manual` with a `reason`.
285
- Name each criterion in one place only.
286
-
287
- Commit the recipe, the setup file and the demo test. Then run
288
- `outerlayer work proofs --record` from the committed checkout. It runs only
289
- what is committed at HEAD, and emits each proof at HEAD. Never emit by hand a
290
- proof that a recipe entry can record, and never keep a capture script outside
291
- the recipe. Always pass `--pr <number>` when the item links more than one pull
292
- request in the repository. Record again after every later commit. It skips an
293
- entry whose proofs are current.
267
+ Every proof comes from a test that you commit with the change. The test names
268
+ the id of the criterion it proves, for example `demo.chapter("AC-7-02", ...)`
269
+ or a comment `// proves AC-7-02`. `outerlayer work proofs --record` finds the
270
+ tests at HEAD that hold the id of each proof that is not current, and runs them.
271
+
272
+ - The repository has one `.outerlayer-proofs.yaml` at its root. When it is
273
+ missing, write it and commit it. `setup` lists the commands that seed and start
274
+ the app. Each setup command must return once the app is ready. `teardown`
275
+ lists the commands that stop it. Each entry in `runners` has a `files` glob of
276
+ test files and a `command` that runs them, with `{files}` where the matched
277
+ files go.
278
+ - A demo test uses `@outerlayer/playwright`, one chapter for each screenshot or
279
+ video criterion in the criteria's order, as the outerlayer-evidence skill's
280
+ "Record a demo" says. The fixture writes the manifest where
281
+ `OUTERLAYER_PROOF_OUT` names.
282
+ - A report, log or file proof is a test, in any language, that writes
283
+ `$OUTERLAYER_PROOF_OUT/<criterion id>.<ext>`. The kind of the file must be the
284
+ kind the criterion declares. The test writes outside the repository, so there is
285
+ nothing to ignore or commit.
286
+ - A proof that no test can make stays without a test. Give the reason in
287
+ `build-reports/evidence.md`.
288
+
289
+ Commit the setup file and every test. Then run
290
+ `outerlayer work proofs --record` from the committed checkout. It stops when a
291
+ tracked file differs from HEAD. It runs only what is committed at HEAD, and
292
+ emits each proof at HEAD. It skips a proof that is current. Never emit by hand
293
+ a proof that a test can make. Always pass `--pr <number>` when the item links
294
+ more than one pull request in the repository.
295
+
296
+ The output names each proof that is still not current, with the reason. Fix
297
+ that test, commit it and record again. Do not record again only because the
298
+ head moved. Each run starts the app again. The orchestrator records once, at
299
+ the run's last head.
294
300
 
295
301
  Run `outerlayer sync`, then `outerlayer work proofs --item "$OUTERLAYER_WORK"`.
296
- For each proof it lists as out of date or missing, fix its entry and record again.
297
302
 
298
303
  Write `build-reports/evidence.md` naming every criterion with its artifact, or
299
304
  with the reason none could be produced. A criterion you could not evidence is
@@ -21,26 +21,28 @@ state no demo test can reach. One that declares `proof: video` needs a video: it
21
21
  item's one demo. A screenshot never satisfies `proof: video`. A criterion with no proof form is proven by its
22
22
  test, and needs no artifact.
23
23
 
24
- The evidence agent captures every proof from a recipe it commits with the
25
- change: `outerlayer work proofs --init` writes it, and
26
- `outerlayer work proofs --record` runs it at HEAD and emits each proof. A
27
- capture script outside the recipe is not allowed, because no later session can
28
- run it again.
29
-
30
- After the evidence agent returns, and after every later commit, run
31
- `outerlayer sync`, then `outerlayer work proofs --item "$OUTERLAYER_WORK"`. It
32
- lists each declared proof as current, out of date or missing at the checkout's
33
- head. Commit the work, then run `outerlayer work proofs --record`: it records
34
- each proof that is not current and skips the rest. Run the list command once
35
- more before the run ends. A criterion still listed goes in
36
- `build-reports/evidence.md` with the reason. The command leaves out criteria
37
- that declare a test proof.
38
-
39
- When a commit lands on the branch after the evidence agent captured, run
40
- `outerlayer work proofs --record` again. It records every proof that is not
41
- current at the new head. The final report names the commit and the proofs it
42
- recorded again. A commit that lands after this call reopens it. Never drive the
43
- browser yourself.
24
+ The evidence agent captures every proof from tests it commits with the
25
+ change. Each test names the id of its criterion. `outerlayer work proofs --record`
26
+ finds those tests at HEAD, runs them through `.outerlayer-proofs.yaml`, and emits
27
+ each proof. A capture script outside the tests is not allowed, because no later
28
+ session can run it again.
29
+
30
+ After the evidence agent returns, run `outerlayer sync`, then
31
+ `outerlayer work proofs --item "$OUTERLAYER_WORK"`. It lists each declared proof
32
+ as current, out of date or missing at the checkout's head. The command leaves
33
+ out criteria that declare a test proof.
34
+
35
+ A commit makes every proof out of date, and each `--record` run starts the app
36
+ again. So record only at the run's last head. First make every commit the run
37
+ still needs, such as a CI fix or a merge of the base branch. Push the last
38
+ commit, then run `outerlayer work proofs --record` once. It records each
39
+ proof that is not current and skips the rest. If a commit lands after that,
40
+ record once more after it. The final report names that head and the proofs
41
+ recorded there.
42
+
43
+ Run the list command once more before the run ends. A criterion still listed
44
+ goes in `build-reports/evidence.md` with the reason. Never drive the browser
45
+ yourself.
44
46
 
45
47
  Re-read the pull request's evidence comment. Resolve or escalate every row that
46
48
  needs attention. A row is resolved when a re-read shows it, not when the fixing
@@ -97,7 +97,7 @@ for each criterion:
97
97
  });
98
98
  });
99
99
 
100
- Commit the test: an amend runs it again.
100
+ Commit the test: `work proofs --record` finds it by its chapter ids.
101
101
 
102
102
  Record each `proof: screenshot` criterion as a chapter too. Call `await
103
103
  demo.screenshot()` inside it, right after the `expect` that shows the result.
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- import { liveHead, resolveProofsItem, classifyProofsAt } from './chunk-3KT2IWV3.js';
4
- import { WorkCommandError, resolveCredentials, getJson } from './chunk-HIGP4WOC.js';
5
- import { resolveRepoIdentity } from './chunk-6ZFY2L2T.js';
6
- import { defaultFetch } from './chunk-6RKD7YZ6.js';
7
- import { renderProofRecipe, renderProofSetup } from './chunk-CQRPR4WZ.js';
8
- import { inferArtifactKind, mediaTypeForArtifactPath, WORK_ITEM_COMMENT_MAX_BODY_LENGTH } from './chunk-EOTMDIYC.js';
9
- import { realpathSync, existsSync, mkdirSync, writeFileSync } from 'fs';
10
- import { join, isAbsolute, resolve, relative } from 'path';
11
- import { createHash } from 'crypto';
12
-
13
- createRequire(import.meta.url);
14
- var DEMO_PROOFS = /* @__PURE__ */ new Set(["screenshot", "video"]);
15
- var KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
16
- function recipeKeyFor(trackerKey) {
17
- const hash = trackerKey.lastIndexOf("#");
18
- const key = hash === -1 ? trackerKey : trackerKey.slice(hash + 1);
19
- return KEY_PATTERN.test(key) ? key : void 0;
20
- }
21
- function buildRecipe(entries) {
22
- const run = [];
23
- if (entries.some((entry) => DEMO_PROOFS.has(entry.proof))) run.push({ command: "", emit: "demo" });
24
- for (const entry of entries) {
25
- if (!DEMO_PROOFS.has(entry.proof)) run.push({ command: "", emit: "", for: entry.id });
26
- }
27
- return { run, manual: [] };
28
- }
29
- function planEntries(recipe, states) {
30
- const stateOf = new Map(states.map((state) => [state.id, state.state]));
31
- const named = /* @__PURE__ */ new Set([...recipe.run.flatMap((entry) => entry.for === void 0 ? [] : [entry.for]), ...recipe.manual.map((entry) => entry.criterion)]);
32
- return recipe.run.map((entry) => {
33
- const criteria = entry.emit === "demo" ? states.filter((state) => DEMO_PROOFS.has(state.proof) && !named.has(state.id)).map((state) => state.id) : [entry.for];
34
- if (criteria.length === 0) return { entry, criteria, skip: "empty" };
35
- const current = criteria.every((id) => stateOf.get(id) === "current");
36
- return { entry, criteria, skip: current ? "current" : null };
37
- });
38
- }
39
- function checkEmitPath(root, emit) {
40
- if (emit === "") return { ok: false, reason: "the entry has no emit path" };
41
- if (isAbsolute(emit)) return { ok: false, reason: `the emit path "${emit}" is outside the repository: it is absolute` };
42
- const path = resolve(root, emit);
43
- const from = relative(root, path);
44
- if (from === "" || from === ".." || from.startsWith("../") || isAbsolute(from)) {
45
- return { ok: false, reason: `the emit path "${emit}" is outside the repository` };
46
- }
47
- return { ok: true, path };
48
- }
49
- function insideRoot(root, path) {
50
- try {
51
- const from = relative(realpathSync(root), realpathSync(path));
52
- return from !== "" && from !== ".." && !from.startsWith("../") && !isAbsolute(from);
53
- } catch {
54
- return false;
55
- }
56
- }
57
- function kindProblem(declared, file) {
58
- if (declared === null) return void 0;
59
- if (declared === "test") return "a test proof is recorded by CI, not by a recipe";
60
- const kind = inferArtifactKind(mediaTypeForArtifactPath(file));
61
- return kind === declared ? void 0 : `the file is a ${kind}, but the criterion declares a ${declared} proof`;
62
- }
63
- function proofsCommentBody(head, lines) {
64
- const header = `These proofs are not current at ${head.slice(0, 7)}:`;
65
- const rows = lines.map((line) => `- ${line.id} (${line.proof}): ${line.reason}`);
66
- const fits = (count2) => {
67
- const left = rows.length - count2;
68
- return [header, ...rows.slice(0, count2), ...left > 0 ? [`and ${left} more.`] : []].join("\n");
69
- };
70
- let count = rows.length;
71
- while (count > 0 && fits(count).length > WORK_ITEM_COMMENT_MAX_BODY_LENGTH) count -= 1;
72
- return fits(count);
73
- }
74
- function proofsCommentId(item, head, lines) {
75
- const list = [...lines].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map((line) => [line.id, line.proof, line.reason]);
76
- const digest = createHash("sha256").update(JSON.stringify([item, head.toLowerCase(), list])).digest("hex");
77
- return `proofs-${digest.slice(0, 32)}`;
78
- }
79
- function repositoryName(repository) {
80
- return repository.replace(/\.git$/, "").split("/").filter((part) => part !== "").slice(-2).join("/").toLowerCase();
81
- }
82
- function ownPullRequest(pullRequests, requested, checkoutRepository) {
83
- if (requested !== void 0) return { pr: requested };
84
- const here = checkoutRepository === void 0 ? void 0 : repositoryName(checkoutRepository);
85
- const open = pullRequests.filter(
86
- (pr) => pr.state === "open" && typeof pr.prNumber === "number" && (here === void 0 || repositoryName(pr.repository ?? "") === here)
87
- );
88
- if (open.length > 1) return { ambiguous: open.map((pr) => pr.prNumber) };
89
- return { pr: open[0]?.prNumber };
90
- }
91
-
92
- // src/work-proofs-init.ts
93
- var PROOFS_DIR = join(".outerlayer", "proofs");
94
- var SETUP_FILE = "setup.yaml";
95
- function repositoryName2(repository) {
96
- return repository.replace(/\.git$/, "").split("/").filter((part) => part !== "").slice(-2).join("/").toLowerCase();
97
- }
98
- function otherPullRequestHeads(pullRequests, ownPr, checkoutRepository) {
99
- const here = checkoutRepository === void 0 ? void 0 : repositoryName2(checkoutRepository);
100
- const heads = /* @__PURE__ */ new Set();
101
- for (const pr of pullRequests) {
102
- const head = liveHead(pr);
103
- if (head === void 0) continue;
104
- const isOwn = ownPr !== void 0 && pr.prNumber === ownPr && (here === void 0 || repositoryName2(pr.repository ?? "") === here);
105
- if (!isOwn) heads.add(head);
106
- }
107
- return heads;
108
- }
109
- function writeOnce(path, text) {
110
- if (existsSync(path)) return false;
111
- mkdirSync(join(path, ".."), { recursive: true });
112
- writeFileSync(path, text, { flag: "wx" });
113
- return true;
114
- }
115
- async function runWorkProofsInit(opts) {
116
- const item = resolveProofsItem(opts);
117
- const cwd = opts.cwd ?? process.cwd();
118
- const identity = resolveRepoIdentity(cwd);
119
- if (identity.repoRoot === void 0) throw new WorkCommandError("this is not a git checkout. Run this inside the repository.");
120
- const root = identity.repoRoot;
121
- const creds = resolveCredentials(opts);
122
- const { data } = await getJson(creds.url, `/v1/work-items/${item}`, creds.apiKey, creds.appId, opts.fetchImpl ?? defaultFetch);
123
- const body = data;
124
- const key = recipeKeyFor(body.trackerKey ?? "");
125
- if (key === void 0) {
126
- throw new WorkCommandError(`the item's tracker key "${body.trackerKey ?? ""}" cannot name a recipe file. Name the file by hand in ${PROOFS_DIR}.`);
127
- }
128
- const pullRequests = body.pullRequests ?? [];
129
- const own = ownPullRequest(pullRequests, opts.pr, identity.gitRepo);
130
- if ("ambiguous" in own) {
131
- throw new WorkCommandError(`the item links several open pull requests (${own.ambiguous.map((n) => `#${n}`).join(", ")}). Pass --pr <number> to name this checkout's.`);
132
- }
133
- const otherHeads = otherPullRequestHeads(pullRequests, own.pr, identity.gitRepo);
134
- const todo = classifyProofsAt(body, otherHeads).filter((entry) => entry.state !== "current");
135
- const recipePath = join(root, PROOFS_DIR, `${key}.yaml`);
136
- const shown = relative(root, recipePath);
137
- const recipeWritten = writeOnce(recipePath, renderProofRecipe(buildRecipe(todo)));
138
- const setupWritten = writeOnce(join(root, PROOFS_DIR, SETUP_FILE), renderProofSetup({ setup: [] }));
139
- const lines = [
140
- recipeWritten ? `Wrote ${shown} with ${todo.length} proof${todo.length === 1 ? "" : "s"} to record. Fill in each command and emit path, then commit it.` : `Kept ${shown}: it exists, so it is unchanged.`,
141
- setupWritten ? `Wrote ${join(PROOFS_DIR, SETUP_FILE)} with an empty setup. Add the commands that start the app, then commit it.` : `Kept ${join(PROOFS_DIR, SETUP_FILE)}: it exists.`
142
- ];
143
- const output = lines.join("\n");
144
- if (!opts.quiet) process.stdout.write(output + "\n");
145
- return { output, recipePath, recipe: recipeWritten ? "written" : "kept", setup: setupWritten ? "written" : "kept" };
146
- }
147
-
148
- export { PROOFS_DIR, SETUP_FILE, checkEmitPath, insideRoot, kindProblem, otherPullRequestHeads, ownPullRequest, planEntries, proofsCommentBody, proofsCommentId, recipeKeyFor, runWorkProofsInit };
@@ -1,35 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- export { PROOFS_DIR, SETUP_FILE, otherPullRequestHeads, runWorkProofsInit } from './chunk-RT6VNM3S.js';
4
- import './chunk-3KT2IWV3.js';
5
- import './chunk-HIGP4WOC.js';
6
- import './chunk-IP7BIBXJ.js';
7
- import './chunk-OHJDH5GV.js';
8
- import './chunk-NVDPSH72.js';
9
- import './chunk-MECW77XP.js';
10
- import './chunk-6ZFY2L2T.js';
11
- import './chunk-TIRHZC2M.js';
12
- import './chunk-Y5YCX6AL.js';
13
- import './chunk-G2JWZDFA.js';
14
- import './chunk-ANPNT6PM.js';
15
- import './chunk-6RKD7YZ6.js';
16
- import './chunk-PJDQPF5N.js';
17
- import './chunk-SOI6K5DY.js';
18
- import './chunk-PA6CK6WQ.js';
19
- import './chunk-BALIE3BA.js';
20
- import './chunk-BJ3KTMDH.js';
21
- import './chunk-ZGB4ZJ5E.js';
22
- import './chunk-5BHIBJDA.js';
23
- import './chunk-CDDED64E.js';
24
- import './chunk-RA3O54FC.js';
25
- import './chunk-T2Q7ISPE.js';
26
- import './chunk-WZBHBH3J.js';
27
- import './chunk-CRB3POP4.js';
28
- import './chunk-CQRPR4WZ.js';
29
- import './chunk-EOTMDIYC.js';
30
- import './chunk-VNVZDWO3.js';
31
- import './chunk-HACGUL52.js';
32
- import './chunk-MESOOLF4.js';
33
- import './chunk-Z5GEFMRW.js';
34
-
35
- createRequire(import.meta.url);