@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.
- package/README.md +5 -5
- package/dist/{agent-setup-FBAT5LGX.js → agent-setup-HEJM3D3V.js} +9 -9
- package/dist/build-info.json +1 -1
- package/dist/{check-HCKDHD2R.js → check-OOUGS65D.js} +20 -20
- package/dist/{chunk-SVLFZLTE.js → chunk-272AKVRP.js} +5 -5
- package/dist/{chunk-B5MSDF5B.js → chunk-2AIOOU3A.js} +4 -4
- package/dist/{chunk-BTHH5H5H.js → chunk-3IH6K7KG.js} +2 -2
- package/dist/{chunk-XFAJQZN2.js → chunk-4P6QGMPN.js} +2 -2
- package/dist/{chunk-43ZOV4OR.js → chunk-4Y54SQXH.js} +10 -10
- package/dist/{chunk-MHGIN2X6.js → chunk-5HZGLLNW.js} +2 -2
- package/dist/{chunk-74Q24R3B.js → chunk-5QBUX5YZ.js} +7 -7
- package/dist/{chunk-6AQLRSYU.js → chunk-62LXQM7U.js} +2 -2
- package/dist/{chunk-SHIGGHZO.js → chunk-65AKMFBH.js} +2 -2
- package/dist/{chunk-OHJDH5GV.js → chunk-6NUPXDAA.js} +1 -1
- package/dist/{chunk-ZADIXMKT.js → chunk-7WM7K2DY.js} +1 -1
- package/dist/{chunk-XLJHFZRL.js → chunk-ACRRO3MB.js} +7 -7
- package/dist/{chunk-OLCIPTST.js → chunk-AP2K4LPI.js} +4 -4
- package/dist/{chunk-YPCDDQFU.js → chunk-DQ6YO7FH.js} +1 -1
- package/dist/{chunk-5HLA7KPK.js → chunk-E4ASIOVL.js} +1 -1
- package/dist/{chunk-NVDPSH72.js → chunk-EE2ZZGQV.js} +1 -1
- package/dist/{chunk-GWF3ZRUX.js → chunk-EN3YWO7Q.js} +1 -1
- package/dist/{chunk-CQRPR4WZ.js → chunk-FGXT5OXS.js} +56 -126
- package/dist/{chunk-3KT2IWV3.js → chunk-FVKH3PMV.js} +49 -9
- package/dist/{chunk-UF2FU3CM.js → chunk-JWNH4ZTF.js} +2 -2
- package/dist/{chunk-2G7PJAJZ.js → chunk-K5Q6T7SE.js} +1 -1
- package/dist/{chunk-TIRHZC2M.js → chunk-NKOM4JKY.js} +2 -2
- package/dist/{chunk-B44BFR2Q.js → chunk-O6DYCIVW.js} +3 -3
- package/dist/{chunk-YREGBU3O.js → chunk-QDVGOMSC.js} +1 -1
- package/dist/{chunk-5XZ6BUPH.js → chunk-QMWUPRYQ.js} +1 -1
- package/dist/{chunk-HMCBX3PL.js → chunk-RCRE42V6.js} +1 -1
- package/dist/{chunk-R2CLQJA2.js → chunk-TDAQHYM4.js} +1 -1
- package/dist/{chunk-SMAZA7DM.js → chunk-XFFUXXI4.js} +2 -2
- package/dist/{chunk-TFKROYY2.js → chunk-YEVPRO7L.js} +3 -3
- package/dist/{chunk-HBVHRC3A.js → chunk-YGSY2NWU.js} +2 -2
- package/dist/{chunk-PBIYM2Z6.js → chunk-YIBFGAYI.js} +2 -2
- package/dist/{chunk-HIGP4WOC.js → chunk-Z4KWHSO4.js} +3 -3
- package/dist/{chunk-ZGB4ZJ5E.js → chunk-ZQSANKS4.js} +1 -1
- package/dist/{chunk-5WCBFLES.js → chunk-ZW6L275N.js} +7 -7
- package/dist/{claude-launcher-YXRS4EZE.js → claude-launcher-MORG66PJ.js} +4 -4
- package/dist/{cli-ADIMCYPF.js → cli-XI7RUSC5.js} +90 -94
- package/dist/{command-YQBQDIAM.js → command-BJSHY6OB.js} +10 -10
- package/dist/{connect-cmd-42JHZKWN.js → connect-cmd-YAUOCX4X.js} +4 -4
- package/dist/{container-start-W4VEGRL5.js → container-start-QADK3YGL.js} +17 -17
- package/dist/{context-cleanup-YGWYIFFV.js → context-cleanup-LUBEZB3L.js} +2 -2
- package/dist/{context-show-cmd-LIWHRWVT.js → context-show-cmd-VHY3OBIA.js} +5 -5
- package/dist/{control-plane-launch-AXBWT5CC.js → control-plane-launch-QSBWTA2V.js} +5 -5
- package/dist/{doctor-AZZJBJYO.js → doctor-UR76MCGI.js} +11 -11
- package/dist/{emit-artifact-cmd-NU5JURAA.js → emit-artifact-cmd-DP2EQ54N.js} +9 -9
- package/dist/{emit-cmd-A4CB7BEC.js → emit-cmd-7NMNKDK7.js} +5 -5
- package/dist/{emit-criteria-cmd-RAU3PDEK.js → emit-criteria-cmd-TTFBN6RK.js} +6 -6
- package/dist/{emit-demo-cmd-524A54D5.js → emit-demo-cmd-Z7YGLEBJ.js} +10 -10
- package/dist/{emit-finding-cmd-LE3HFQWL.js → emit-finding-cmd-IQRD3J2X.js} +6 -6
- package/dist/{emit-result-cmd-XT2VEPAJ.js → emit-result-cmd-GIWB6UHH.js} +8 -8
- package/dist/{emit-step-cmd-LXOKBFQE.js → emit-step-cmd-PU5TTU6C.js} +6 -6
- package/dist/{findings-cmd-O5HUK26I.js → findings-cmd-7J5SHCUO.js} +6 -6
- package/dist/{fleet-readiness-VAKMSSWI.js → fleet-readiness-G63D76EX.js} +6 -6
- package/dist/{governing-source-FNSH4V4A.js → governing-source-DLESDP6T.js} +9 -9
- package/dist/{hook-fast-WENTLDMA.js → hook-fast-VQXRDS6E.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/{init-RUIWHKLE.js → init-67R7LO4C.js} +10 -10
- package/dist/{init-LQDKX2XL.js → init-KSXU4PA7.js} +10 -10
- package/dist/{init-cmd-2OTTULTI.js → init-cmd-MNOVMADM.js} +14 -14
- package/dist/{init-update-TN2W4EN6.js → init-update-6KEXRCJH.js} +13 -13
- package/dist/{layout-NAPG4SX2.js → layout-7B3O3FT3.js} +3 -3
- package/dist/{loop-X3ANDLQU.js → loop-KUEOPBKX.js} +20 -20
- package/dist/{machine-IEYKRHRK.js → machine-EQEAPT76.js} +10 -10
- package/dist/{machine-skills-2TT3RXMJ.js → machine-skills-3FEGR376.js} +3 -3
- package/dist/{runner-key-QKZZTKLY.js → runner-key-ML7R33HF.js} +10 -10
- package/dist/{session-sender-IH44FURK.js → session-sender-A43GZQ7T.js} +9 -9
- package/dist/{spec-cmd-2LRTOTAO.js → spec-cmd-VVUJZSG2.js} +7 -7
- package/dist/{starter-pack-5D4BANFU.js → starter-pack-LEL3Q2DB.js} +4 -4
- package/dist/{status-6ISCZDBX.js → status-4G6K7I2C.js} +15 -15
- package/dist/{sync-cmd-MIID2ANV.js → sync-cmd-ZEC65ABJ.js} +8 -8
- package/dist/{update-steps-4M2GIB4A.js → update-steps-XLO7734I.js} +16 -16
- package/dist/{watch-K5UUKCPB.js → watch-QB4AMWR3.js} +8 -8
- package/dist/{work-claim-cmd-2LD2JQKI.js → work-claim-cmd-6W3GBHRS.js} +8 -8
- package/dist/{work-cmd-NR53YCXJ.js → work-cmd-LTZXOPPN.js} +6 -6
- package/dist/{work-comment-cmd-PC4HNM45.js → work-comment-cmd-LDZBUO6M.js} +7 -7
- package/dist/{work-demo-cmd-S5EJXBVH.js → work-demo-cmd-77LISWQ3.js} +6 -6
- package/dist/{work-logs-cmd-5F6MDBLQ.js → work-logs-cmd-FK7HE7PC.js} +6 -6
- package/dist/{work-open-pr-cmd-SWVFDSMY.js → work-open-pr-cmd-WVONEHZL.js} +7 -7
- package/dist/{work-pr-cmd-DXW4RXG4.js → work-pr-cmd-6IPXWJEH.js} +6 -6
- package/dist/{work-proofs-cmd-UVTSPFLL.js → work-proofs-cmd-TGIAP5IO.js} +7 -7
- package/dist/work-proofs-record-XPAU7N57.js +2382 -0
- package/dist/{work-stop-cmd-HL6FZL5X.js → work-stop-cmd-UJ45EV3A.js} +6 -6
- package/package.json +2 -1
- package/skill-pack/maintained/outerlayer-amend/SKILL.md +1 -2
- package/skill-pack/maintained/outerlayer-build/SKILL.md +4 -3
- package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +33 -28
- package/skill-pack/maintained/outerlayer-build/references/evidence.md +22 -20
- package/skill-pack/maintained/outerlayer-evidence/SKILL.md +1 -1
- package/dist/chunk-RT6VNM3S.js +0 -148
- package/dist/work-proofs-init-GNGI7PZU.js +0 -35
- 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-
|
|
3
|
+
import { resolveCredentials, postJson, WorkCommandError } from './chunk-Z4KWHSO4.js';
|
|
4
4
|
import './chunk-IP7BIBXJ.js';
|
|
5
|
-
import './chunk-
|
|
6
|
-
import './chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
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
|
|
346
|
-
|
|
347
|
-
|
|
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
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
the
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
|
25
|
-
change
|
|
26
|
-
|
|
27
|
-
capture script outside the
|
|
28
|
-
run it again.
|
|
29
|
-
|
|
30
|
-
After the evidence agent returns,
|
|
31
|
-
`outerlayer
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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:
|
|
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.
|
package/dist/chunk-RT6VNM3S.js
DELETED
|
@@ -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);
|