@outerlayer/cli 0.34.0-next.20261028010245 → 0.34.0-next.20261028122415

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 (123) hide show
  1. package/dist/{agent-setup-6FPE6EYN.js → agent-setup-LZ7PEM6A.js} +6 -6
  2. package/dist/{bridge-JGIHPGMY.js → bridge-4DFOWIY2.js} +2 -2
  3. package/dist/{build-AAQ4PVP2.js → build-VVZHFSZK.js} +8 -8
  4. package/dist/{build-disk-L7JRQA22.js → build-disk-QV4TO7HZ.js} +6 -6
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-LMLAVVVF.js → builder-6JLFMAGJ.js} +5 -5
  7. package/dist/{check-C7UKLYZQ.js → check-FWRVWOVY.js} +38 -38
  8. package/dist/{chunk-WEQMLC7P.js → chunk-265SXBQ5.js} +3 -3
  9. package/dist/{chunk-AJTGTSNA.js → chunk-2CW2QMSG.js} +1 -1
  10. package/dist/{chunk-AHWMY3MS.js → chunk-2LCNMAWP.js} +4 -4
  11. package/dist/{chunk-SWCOWG2C.js → chunk-3EU4MWCE.js} +3 -3
  12. package/dist/{chunk-L2OARQKP.js → chunk-4N7BQBO4.js} +28 -13
  13. package/dist/{chunk-6OLXDSQ6.js → chunk-5B6DLEVM.js} +1 -1
  14. package/dist/{chunk-QNF7LT7W.js → chunk-5VKSPEST.js} +3 -3
  15. package/dist/{chunk-3X6OSXSB.js → chunk-64LLUVJR.js} +1 -1
  16. package/dist/{chunk-WSVE5QGL.js → chunk-6CQXOTNL.js} +4 -4
  17. package/dist/{chunk-GJYGOFF3.js → chunk-72N7GOLM.js} +6 -6
  18. package/dist/{chunk-4A5OJOCR.js → chunk-7DHESPSV.js} +10 -10
  19. package/dist/{chunk-VB4QD4WN.js → chunk-7JBG43BX.js} +67 -25
  20. package/dist/{chunk-EGJY6MBC.js → chunk-7LKOOGSN.js} +2 -2
  21. package/dist/{chunk-KTVZ7TZY.js → chunk-7XZQTJOD.js} +1 -1
  22. package/dist/{chunk-A6PJSNP6.js → chunk-A2KLVZBU.js} +31 -29
  23. package/dist/{chunk-BQ4C47K2.js → chunk-AGNFPJSP.js} +5 -5
  24. package/dist/{chunk-JXY66VYX.js → chunk-AKQX462F.js} +3 -3
  25. package/dist/{chunk-5LUN7TTR.js → chunk-AVI3MGQO.js} +2 -2
  26. package/dist/{chunk-3XOLOV5A.js → chunk-AXKSVN4U.js} +4 -4
  27. package/dist/{work-proofs-record-LIQGUDWH.js → chunk-BEGMZKMG.js} +176 -497
  28. package/dist/{chunk-QJ2SNBHL.js → chunk-BUVDDPOM.js} +1 -1
  29. package/dist/{chunk-32FAPJFD.js → chunk-C2E4PWEN.js} +6 -6
  30. package/dist/{chunk-57WFXHCB.js → chunk-D7MWJM2G.js} +1 -1
  31. package/dist/{chunk-G4SOMWXL.js → chunk-DKIZDYUX.js} +1 -1
  32. package/dist/{chunk-I4YOWQH7.js → chunk-E3GX4WVJ.js} +1 -1
  33. package/dist/{chunk-F3BGTGQC.js → chunk-EXKOPZQV.js} +1 -1
  34. package/dist/{chunk-BTDBDTUY.js → chunk-GJHOU5V3.js} +3 -3
  35. package/dist/{chunk-D6SH7DWA.js → chunk-H5YUWLIY.js} +3 -3
  36. package/dist/{chunk-PAGB3DCI.js → chunk-IZKUPAXF.js} +1 -1
  37. package/dist/{chunk-GET5HKLM.js → chunk-JDQBJUXQ.js} +1 -1
  38. package/dist/{chunk-23XAA7YD.js → chunk-LEJWPGO7.js} +3 -3
  39. package/dist/{chunk-NBETYM32.js → chunk-N4KQMGEZ.js} +4 -4
  40. package/dist/{chunk-4J5GRWAY.js → chunk-N6V4ZHI7.js} +2 -2
  41. package/dist/{chunk-PHIQHIRJ.js → chunk-NPTEYMBW.js} +1 -1
  42. package/dist/{chunk-3E7QAXUW.js → chunk-OFKM35MX.js} +6 -6
  43. package/dist/{chunk-LBKCYEJT.js → chunk-ORENXMHA.js} +1 -1
  44. package/dist/{chunk-6Q7O4MRI.js → chunk-QGTJ5IJN.js} +1 -1
  45. package/dist/{chunk-5IUC2B6J.js → chunk-QTL7VZVF.js} +2 -2
  46. package/dist/{chunk-GXMMILQ4.js → chunk-QXAPVAPR.js} +3 -3
  47. package/dist/{chunk-6LS62EO4.js → chunk-S37IAT3A.js} +3 -3
  48. package/dist/{chunk-PPQTTJSW.js → chunk-SODV2YMW.js} +5 -5
  49. package/dist/{chunk-SYMBXSAT.js → chunk-SX3LYSWR.js} +3 -3
  50. package/dist/{chunk-77D5ENBA.js → chunk-TZXJSNN4.js} +1 -1
  51. package/dist/{chunk-HFMK2R7O.js → chunk-U3O7MULV.js} +20 -20
  52. package/dist/{chunk-GMEXR6PY.js → chunk-UDMFRKFJ.js} +6 -6
  53. package/dist/{chunk-NCKH3KCM.js → chunk-UKEIJKCH.js} +25 -12
  54. package/dist/{chunk-VKYU4HHW.js → chunk-VJQQVTCS.js} +1 -1
  55. package/dist/{chunk-UEDRRWZ3.js → chunk-XDCD4GD5.js} +3 -3
  56. package/dist/{chunk-PBI4CM4M.js → chunk-YGU43DH4.js} +57 -27
  57. package/dist/{chunk-NOEJGR4X.js → chunk-ZIXLG6EQ.js} +3 -3
  58. package/dist/{claude-launcher-GGZEWVYJ.js → claude-launcher-XX2MLBDW.js} +1 -1
  59. package/dist/{cli-IG52447Q.js → cli-K7AWWU6C.js} +112 -112
  60. package/dist/{command-NSTOWAZ6.js → command-GJKJ5WT4.js} +25 -25
  61. package/dist/{config-YPUOOZB6.js → config-AB5Y73BU.js} +7 -7
  62. package/dist/{connect-cmd-RPEEANNE.js → connect-cmd-FOD7PKVW.js} +6 -6
  63. package/dist/{container-start-OOBTGHWF.js → container-start-XGKAKLUD.js} +32 -32
  64. package/dist/{context-show-cmd-R5WCECOT.js → context-show-cmd-A226Q6K5.js} +7 -7
  65. package/dist/{control-plane-launch-55CJGYBK.js → control-plane-launch-RJSAIFEP.js} +5 -5
  66. package/dist/{demo-record-cmd-SFOWQPL7.js → demo-record-cmd-KM2UPWPL.js} +2 -2
  67. package/dist/{demo-voice-cmd-ZOBRVHOK.js → demo-voice-cmd-W4NYPCVL.js} +12 -12
  68. package/dist/{dist-BUSLJNSZ.js → dist-ZW7I72SD.js} +1 -1
  69. package/dist/{docker-VPJW5LXB.js → docker-OQP6NU7P.js} +5 -5
  70. package/dist/{doctor-O2EJAPZB.js → doctor-OXMOYIKK.js} +25 -25
  71. package/dist/{emit-artifact-cmd-HBFYBXJR.js → emit-artifact-cmd-X2YWXLKQ.js} +11 -11
  72. package/dist/{emit-criteria-cmd-TPUL7M2R.js → emit-criteria-cmd-HYKOTFXG.js} +8 -8
  73. package/dist/{emit-demo-cmd-5CUT7W3R.js → emit-demo-cmd-DTARV6RI.js} +12 -12
  74. package/dist/{emit-finding-cmd-IKHGMACP.js → emit-finding-cmd-GSLYQC43.js} +8 -8
  75. package/dist/{emit-result-cmd-F7CI6SNZ.js → emit-result-cmd-PKJH76NG.js} +10 -10
  76. package/dist/{emit-step-cmd-DVEKGHK7.js → emit-step-cmd-IW2Y4N67.js} +8 -8
  77. package/dist/{exec-client-H2JG36OS.js → exec-client-BQIZRROT.js} +3 -3
  78. package/dist/find-unit-2C6EK5YY.js +19 -0
  79. package/dist/{findings-cmd-ODKZ462L.js → findings-cmd-CFF2I3TU.js} +8 -8
  80. package/dist/{fleet-readiness-UHCBNW6A.js → fleet-readiness-ZSG4UDYR.js} +5 -5
  81. package/dist/{governing-source-SRECHKPR.js → governing-source-TUGE7QJY.js} +10 -10
  82. package/dist/{guest-init-6FUC4XZX.js → guest-init-DXXSPKHY.js} +4 -4
  83. package/dist/{hook-fast-WM6YZVBJ.js → hook-fast-5C4MQ5ZS.js} +1 -1
  84. package/dist/{host-checks-FLIHLR35.js → host-checks-L4GX6F3H.js} +30 -30
  85. package/dist/{host-key-OSWPVMIA.js → host-key-5P3ZL5XW.js} +3 -3
  86. package/dist/{image-tag-LF3NEGSL.js → image-tag-3KPTSRB4.js} +3 -3
  87. package/dist/index.js +4 -4
  88. package/dist/{init-LPD75DCX.js → init-NSTWRPRM.js} +22 -22
  89. package/dist/{init-OX677NNB.js → init-WU2S3WRO.js} +22 -22
  90. package/dist/{init-cmd-ZCLVC5RR.js → init-cmd-H4HYM5V3.js} +11 -11
  91. package/dist/{init-update-POKSLQDQ.js → init-update-WOYX2AIO.js} +9 -9
  92. package/dist/{install-cmd-6SQVZEXL.js → install-cmd-6HGNO2HF.js} +5 -5
  93. package/dist/{logs-QHXZTSKZ.js → logs-E2O53NUI.js} +2 -2
  94. package/dist/{loop-ELTO36MN.js → loop-GQLSSBQB.js} +37 -37
  95. package/dist/{machine-7VPFAC6L.js → machine-IRBCGRUO.js} +22 -22
  96. package/dist/{mcp-serve-cmd-J32K42HM.js → mcp-serve-cmd-OFK3CS2T.js} +4 -4
  97. package/dist/{paths-4ZGWWNTG.js → paths-VQ3ALYZ3.js} +2 -2
  98. package/dist/{pending-CRXJKKKI.js → pending-V5FBWIJ4.js} +3 -3
  99. package/dist/{pidfile-VLZPRIBZ.js → pidfile-AVJFRZZT.js} +3 -3
  100. package/dist/{record-4ZJPJTWO.js → record-XE7Z3QGF.js} +3 -3
  101. package/dist/{runner-env-W53VDVOK.js → runner-env-TYGE6BFU.js} +9 -9
  102. package/dist/{runner-identity-BH42S2MU.js → runner-identity-B2MZQFYN.js} +5 -5
  103. package/dist/{runner-key-ESAZRV3A.js → runner-key-NPPEGU6H.js} +22 -22
  104. package/dist/{session-sender-UB45MUKV.js → session-sender-ZS4OIE3M.js} +11 -11
  105. package/dist/{spec-cmd-H5B55O5L.js → spec-cmd-N45YF6UL.js} +9 -9
  106. package/dist/{status-L2OYAZHY.js → status-EP6QSFRY.js} +30 -30
  107. package/dist/{sync-cmd-IWA5ZTI2.js → sync-cmd-VCB4YDCB.js} +10 -10
  108. package/dist/{update-steps-FWQ5ASZ6.js → update-steps-BJB7NL6L.js} +31 -31
  109. package/dist/{watch-NOEBVS6U.js → watch-XU2AUR6Z.js} +10 -10
  110. package/dist/{work-claim-cmd-7P7U3OQ6.js → work-claim-cmd-WEP3OWAU.js} +13 -13
  111. package/dist/{work-cmd-77GUT7LY.js → work-cmd-DWR27TKQ.js} +8 -8
  112. package/dist/{work-comment-cmd-VS3BSPGM.js → work-comment-cmd-HSDVPYWM.js} +9 -9
  113. package/dist/{work-demo-cmd-S3GXBYIA.js → work-demo-cmd-3EQYHRBP.js} +8 -8
  114. package/dist/{work-logs-cmd-6BXIINCM.js → work-logs-cmd-3YACDH7Y.js} +8 -8
  115. package/dist/{work-open-pr-cmd-EPOFWJDC.js → work-open-pr-cmd-MHVTTTLD.js} +9 -9
  116. package/dist/{work-pr-cmd-DYSYOP74.js → work-pr-cmd-XETSFFM2.js} +8 -8
  117. package/dist/{work-proofs-cmd-DS2VX4E4.js → work-proofs-cmd-RYQ7Y6KO.js} +10 -10
  118. package/dist/work-proofs-record-IC3RWDDQ.js +509 -0
  119. package/dist/{work-stop-cmd-HYQTDNUY.js → work-stop-cmd-4BE2B7TY.js} +8 -8
  120. package/package.json +1 -1
  121. package/skill-pack/maintained/outerlayer-build/scripts/criterion-citations.mjs +44 -4
  122. package/dist/chunk-6CK2OC4Q.js +0 -152
  123. package/dist/find-unit-ACTOZVVS.js +0 -19
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { WorkPrCommandError, itemLabel, runWorkPr } from './chunk-SWCOWG2C.js';
3
+ export { WorkPrCommandError, itemLabel, runWorkPr } from './chunk-3EU4MWCE.js';
4
4
  import './chunk-IP7BIBXJ.js';
5
- import './chunk-BTDBDTUY.js';
6
- import './chunk-4J5GRWAY.js';
5
+ import './chunk-GJHOU5V3.js';
6
+ import './chunk-N6V4ZHI7.js';
7
7
  import './chunk-NWHU5G6R.js';
8
8
  import './chunk-G2JWZDFA.js';
9
9
  import './chunk-ANPNT6PM.js';
10
10
  import './chunk-IXPH4EXK.js';
11
11
  import './chunk-LYCJQOO2.js';
12
- import './chunk-PAGB3DCI.js';
12
+ import './chunk-IZKUPAXF.js';
13
13
  import './chunk-PJDQPF5N.js';
14
- import './chunk-VKYU4HHW.js';
14
+ import './chunk-VJQQVTCS.js';
15
15
  import './chunk-BJ3KTMDH.js';
16
16
  import './chunk-OVNF4LLC.js';
17
- import './chunk-A6PJSNP6.js';
17
+ import './chunk-A2KLVZBU.js';
18
18
  import './chunk-5BHIBJDA.js';
19
19
  import './chunk-CDDED64E.js';
20
20
  import './chunk-RA3O54FC.js';
@@ -24,8 +24,8 @@ import './chunk-CRB3POP4.js';
24
24
  import './chunk-XFJ7YOPD.js';
25
25
  import './chunk-DINRXUQA.js';
26
26
  import './chunk-VNVZDWO3.js';
27
- import './chunk-AJTGTSNA.js';
28
- import './chunk-L2OARQKP.js';
27
+ import './chunk-2CW2QMSG.js';
28
+ import './chunk-4N7BQBO4.js';
29
29
  import './chunk-MESOOLF4.js';
30
30
  import './chunk-Z5GEFMRW.js';
31
31
 
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-NCKH3KCM.js';
4
- import './chunk-6CK2OC4Q.js';
5
- import './chunk-GJYGOFF3.js';
3
+ export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-UKEIJKCH.js';
4
+ import './chunk-BEGMZKMG.js';
5
+ import './chunk-72N7GOLM.js';
6
6
  import './chunk-IP7BIBXJ.js';
7
- import './chunk-BTDBDTUY.js';
8
- import './chunk-4J5GRWAY.js';
7
+ import './chunk-GJHOU5V3.js';
8
+ import './chunk-N6V4ZHI7.js';
9
9
  import './chunk-NWHU5G6R.js';
10
10
  import './chunk-G2JWZDFA.js';
11
11
  import './chunk-ANPNT6PM.js';
12
12
  import './chunk-IXPH4EXK.js';
13
13
  import './chunk-LYCJQOO2.js';
14
- import './chunk-PAGB3DCI.js';
14
+ import './chunk-IZKUPAXF.js';
15
15
  import './chunk-PJDQPF5N.js';
16
- import './chunk-VKYU4HHW.js';
16
+ import './chunk-VJQQVTCS.js';
17
17
  import './chunk-BJ3KTMDH.js';
18
18
  import './chunk-OVNF4LLC.js';
19
- import './chunk-A6PJSNP6.js';
19
+ import './chunk-A2KLVZBU.js';
20
20
  import './chunk-5BHIBJDA.js';
21
21
  import './chunk-CDDED64E.js';
22
22
  import './chunk-RA3O54FC.js';
@@ -27,8 +27,8 @@ import './chunk-YQR6E6OV.js';
27
27
  import './chunk-XFJ7YOPD.js';
28
28
  import './chunk-DINRXUQA.js';
29
29
  import './chunk-VNVZDWO3.js';
30
- import './chunk-AJTGTSNA.js';
31
- import './chunk-L2OARQKP.js';
30
+ import './chunk-2CW2QMSG.js';
31
+ import './chunk-4N7BQBO4.js';
32
32
  import './chunk-MESOOLF4.js';
33
33
  import './chunk-Z5GEFMRW.js';
34
34
 
@@ -0,0 +1,509 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { resolveProofsItem, ownPullRequest, proofsCommentId, otherPullRequestHeads, classifyProofsAt, kindProblem, proofsCommentBody, runWorkProofs } from './chunk-UKEIJKCH.js';
4
+ import { runWorkComment } from './chunk-H5YUWLIY.js';
5
+ import { runnerMatcher } from './chunk-BEGMZKMG.js';
6
+ import { runEmitDemo } from './chunk-6CQXOTNL.js';
7
+ import { readNewestDemo } from './chunk-ER6KQCVJ.js';
8
+ import { runEmitArtifact } from './chunk-AXKSVN4U.js';
9
+ import { runSync } from './chunk-C2E4PWEN.js';
10
+ import './chunk-ZIXLG6EQ.js';
11
+ import './chunk-ESVW4MJY.js';
12
+ import './chunk-TBT347UY.js';
13
+ import './chunk-2PGI6RDE.js';
14
+ import './chunk-D3CT6XQ4.js';
15
+ import { WorkCommandError, resolveCredentials, getJson } from './chunk-72N7GOLM.js';
16
+ import './chunk-IP7BIBXJ.js';
17
+ import './chunk-GJHOU5V3.js';
18
+ import './chunk-N6V4ZHI7.js';
19
+ import './chunk-NWHU5G6R.js';
20
+ import './chunk-G2JWZDFA.js';
21
+ import './chunk-ANPNT6PM.js';
22
+ import './chunk-IXPH4EXK.js';
23
+ import './chunk-LYCJQOO2.js';
24
+ import { defaultFetch } from './chunk-IZKUPAXF.js';
25
+ import './chunk-PJDQPF5N.js';
26
+ import './chunk-VJQQVTCS.js';
27
+ import './chunk-D7MWJM2G.js';
28
+ import './chunk-ZJSNLVCE.js';
29
+ import './chunk-2O5KA67H.js';
30
+ import './chunk-BKO6JEZI.js';
31
+ import './chunk-HCVLP7XA.js';
32
+ import './chunk-BJ3KTMDH.js';
33
+ import './chunk-OVNF4LLC.js';
34
+ import { resolveRepoIdentity } from './chunk-A2KLVZBU.js';
35
+ import './chunk-5BHIBJDA.js';
36
+ import './chunk-CDDED64E.js';
37
+ import './chunk-RA3O54FC.js';
38
+ import './chunk-T2Q7ISPE.js';
39
+ import './chunk-WZBHBH3J.js';
40
+ import './chunk-CRB3POP4.js';
41
+ import './chunk-URIZRCRY.js';
42
+ import './chunk-YQR6E6OV.js';
43
+ import './chunk-TUSYOL2O.js';
44
+ import { parseProofsConfig } from './chunk-XFJ7YOPD.js';
45
+ import { ARTIFACT_MAX_CAPTION_LENGTH } from './chunk-DINRXUQA.js';
46
+ import './chunk-VNVZDWO3.js';
47
+ import './chunk-2CW2QMSG.js';
48
+ import './chunk-4N7BQBO4.js';
49
+ import './chunk-MESOOLF4.js';
50
+ import './chunk-Z5GEFMRW.js';
51
+ import { spawnSync, spawn } from 'child_process';
52
+ import { mkdtempSync, rmSync, openSync, closeSync, readdirSync, readFileSync } from 'fs';
53
+ import { tmpdir } from 'os';
54
+ import { join } from 'path';
55
+
56
+ createRequire(import.meta.url);
57
+ var runShell = (command, params) => {
58
+ const logPath = join(params.logDir, `${params.groups.length}-${Date.now()}.log`);
59
+ const fd = openSync(logPath, "w");
60
+ return new Promise((resolve) => {
61
+ const child = spawn("sh", ["-c", command], { cwd: params.cwd, env: params.env, detached: true, stdio: ["ignore", fd, fd] });
62
+ closeSync(fd);
63
+ if (child.pid !== void 0) params.groups.push(child.pid);
64
+ let timedOut = false;
65
+ const timer = setTimeout(() => {
66
+ timedOut = true;
67
+ try {
68
+ process.kill(-child.pid, "SIGKILL");
69
+ } catch {
70
+ }
71
+ }, params.timeoutMs);
72
+ const finish = (status) => {
73
+ clearTimeout(timer);
74
+ let text = "";
75
+ try {
76
+ text = readFileSync(logPath, "utf8");
77
+ } catch {
78
+ }
79
+ resolve({ status, timedOut, tail: text.trimEnd().split("\n").slice(-8).join("\n") });
80
+ };
81
+ child.on("error", () => finish(null));
82
+ child.on("exit", (status) => finish(status));
83
+ });
84
+ };
85
+ var ID_CHARACTER = "A-Za-z0-9_-";
86
+ function escapeRegExp(text) {
87
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
88
+ }
89
+ function containsId(text, id) {
90
+ return new RegExp(`(?<![${ID_CHARACTER}])${escapeRegExp(id)}(?![${ID_CHARACTER}])`).test(text);
91
+ }
92
+ function planRuns(files, runners) {
93
+ const plan = /* @__PURE__ */ new Map();
94
+ const runnerFor = runnerMatcher(runners);
95
+ for (const file of [...files].sort()) {
96
+ const index = runnerFor(file);
97
+ if (index === void 0) continue;
98
+ plan.set(index, [...plan.get(index) ?? [], file]);
99
+ }
100
+ return new Map([...plan].sort(([a], [b]) => a - b));
101
+ }
102
+ function shellQuote(text) {
103
+ const path = text.startsWith("-") ? `./${text}` : text;
104
+ if (/^[A-Za-z0-9_@%+=:,./-]+$/.test(path)) return path;
105
+ return `'${path.replace(/'/g, `'\\''`)}'`;
106
+ }
107
+ function fillFiles(command, files) {
108
+ const quoted = files.map(shellQuote).join(" ");
109
+ return command.split("{files}").join(quoted);
110
+ }
111
+ function proofFileCriterion(name, declared) {
112
+ const dot = name.lastIndexOf(".");
113
+ if (dot <= 0) return void 0;
114
+ const stem = name.slice(0, dot);
115
+ return declared.has(stem) ? stem : void 0;
116
+ }
117
+ function git(root, args, accepted = [0]) {
118
+ const result = spawnSync("git", args, { cwd: root, encoding: "utf8", maxBuffer: 268435456 });
119
+ if (result.error !== void 0 || !accepted.includes(result.status)) {
120
+ throw new WorkCommandError(`git ${args[0]} failed (${result.error?.message ?? `exit status ${result.status}`}), so the tests that name a proof cannot be found.`);
121
+ }
122
+ return result.stdout;
123
+ }
124
+ function discoverTestFiles(root, ids, runners) {
125
+ const found = /* @__PURE__ */ new Map();
126
+ if (ids.length === 0 || runners.length === 0) return found;
127
+ const grep = git(root, ["grep", "-z", "-l", "-I", "-F", ...ids.flatMap((id) => ["-e", id]), "HEAD", "--"], [0, 1]);
128
+ const runnerFor = runnerMatcher(runners);
129
+ const paths = grep.split("\0").filter((entry) => entry !== "").map((entry) => entry.slice("HEAD:".length)).filter((path) => runnerFor(path) !== void 0).sort();
130
+ for (const path of paths) {
131
+ const shown = git(root, ["show", `HEAD:${path}`]);
132
+ for (const id of ids) {
133
+ if (containsId(shown, id)) found.set(id, [...found.get(id) ?? [], path]);
134
+ }
135
+ }
136
+ return found;
137
+ }
138
+
139
+ // src/work-proofs-record.ts
140
+ var CONFIG_FILE = ".outerlayer-proofs.yaml";
141
+ var DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
142
+ var DEMO_PROOFS = /* @__PURE__ */ new Set(["screenshot", "video"]);
143
+ var NO_TEST = "no test at HEAD names this criterion";
144
+ function changedTrackedFiles(root) {
145
+ const status = spawnSync("git", ["status", "--porcelain=v1", "-z", "--untracked-files=no"], { cwd: root, encoding: "utf8", maxBuffer: 16 * 1024 * 1024 });
146
+ if (status.error !== void 0 || status.status !== 0) {
147
+ throw new WorkCommandError(`git cannot say whether the working copy matches HEAD (${status.error?.message ?? `exit status ${status.status}`}), so nothing was recorded.`);
148
+ }
149
+ const fields = status.stdout.split("\0").filter((field) => field !== "");
150
+ const paths = [];
151
+ for (let i = 0; i < fields.length; i += 1) {
152
+ const field = fields[i];
153
+ paths.push(field.slice(3));
154
+ if (/[RC]/.test(field.slice(0, 2))) i += 1;
155
+ }
156
+ return paths;
157
+ }
158
+ function topLevelFiles(folder) {
159
+ try {
160
+ return readdirSync(folder, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
161
+ } catch {
162
+ return [];
163
+ }
164
+ }
165
+ function chapterCriteria(manifestPath) {
166
+ const ids = /* @__PURE__ */ new Set();
167
+ try {
168
+ const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
169
+ for (const chapter of parsed.chapters ?? []) {
170
+ if (typeof chapter?.criterionId === "string") ids.add(chapter.criterionId);
171
+ }
172
+ } catch {
173
+ }
174
+ return ids;
175
+ }
176
+ function showAtHead(root, path) {
177
+ const shown = spawnSync("git", ["show", `HEAD:${path}`], { cwd: root, encoding: "utf8", maxBuffer: 16 * 1024 * 1024 });
178
+ return shown.status === 0 ? shown.stdout : void 0;
179
+ }
180
+ function findManifests(folder) {
181
+ const found = [];
182
+ let entries = [];
183
+ try {
184
+ entries = readdirSync(folder, { withFileTypes: true });
185
+ } catch {
186
+ }
187
+ for (const entry of entries) {
188
+ const path = join(folder, entry.name);
189
+ if (entry.isDirectory()) found.push(...findManifests(path));
190
+ else if (entry.name === "manifest.json" && folder.split("/").pop() === "demo") found.push(path);
191
+ }
192
+ return found;
193
+ }
194
+ function unstoredUploads(result, spooled) {
195
+ if (typeof result !== "object" || result === null) return [];
196
+ const { artifactsDropped, artifactsHeld, rejected, uploadedArtifacts } = result;
197
+ if (Array.isArray(uploadedArtifacts)) {
198
+ const stored = new Set(uploadedArtifacts.map((a) => a?.artifactId));
199
+ return spooled.filter((id) => !stored.has(id));
200
+ }
201
+ const lost = typeof artifactsDropped === "number" && artifactsDropped > 0 || typeof artifactsHeld === "number" && artifactsHeld > 0 || Array.isArray(rejected) && rejected.length > 0;
202
+ return lost ? "all" : [];
203
+ }
204
+ function shortSha(sha) {
205
+ return sha.slice(0, 7);
206
+ }
207
+ function oneLine(text) {
208
+ return text.replace(/\s+/g, " ").trim();
209
+ }
210
+ async function runWorkProofsRecord(opts) {
211
+ const env = opts.env ?? process.env;
212
+ const item = resolveProofsItem({ item: opts.item, env });
213
+ const cwd = opts.cwd ?? process.cwd();
214
+ const identity = resolveRepoIdentity(cwd);
215
+ if (identity.repoRoot === void 0 || identity.commitSha === void 0) {
216
+ throw new WorkCommandError("this is not a git checkout with a commit. Run this inside the repository, after the tests are committed.");
217
+ }
218
+ const { repoRoot: root, commitSha: head } = identity;
219
+ const changed = changedTrackedFiles(root);
220
+ if (changed.length > 0) {
221
+ throw new WorkCommandError(
222
+ `the working copy differs from HEAD in ${changed.join(", ")}. Only the committed files run, so nothing was recorded. Commit or discard the change, then record again.`
223
+ );
224
+ }
225
+ const fetchImpl = opts.fetchImpl ?? defaultFetch;
226
+ const creds = resolveCredentials({ ...opts, env });
227
+ const home = opts.home;
228
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
229
+ const lines = [];
230
+ const say = (line) => void lines.push(line);
231
+ const { data } = await getJson(creds.url, `/v1/work-items/${item}`, creds.apiKey, creds.appId, fetchImpl);
232
+ const body = data;
233
+ const own = ownPullRequest(body.pullRequests ?? [], opts.pr, identity.gitRepo);
234
+ if ("ambiguous" in own) {
235
+ throw new WorkCommandError(`the item links several open pull requests (${own.ambiguous.map((n) => `#${n}`).join(", ")}). Pass --pr <number> to name this checkout's.`);
236
+ }
237
+ const ownPr = own.pr;
238
+ const postGeneral = async (text, clientCommentId) => {
239
+ try {
240
+ await runWorkComment({ ...creds, item, body: text, clientCommentId, cwd, home, env, fetchImpl, quiet: true });
241
+ } catch (err) {
242
+ if (!(err instanceof WorkCommandError && err.code === "comment_conflict")) {
243
+ say(`The comment on the item's thread was not posted: ${oneLine(String(err instanceof Error ? err.message : err))}`);
244
+ }
245
+ }
246
+ };
247
+ const configText = showAtHead(root, CONFIG_FILE);
248
+ const parsed = configText === void 0 ? void 0 : parseProofsConfig(configText);
249
+ if (parsed === void 0 || !parsed.ok) {
250
+ const problem = parsed === void 0 ? `${CONFIG_FILE} is missing at HEAD. Commit it at the repository root, with the setup, teardown and runners that run the tests.` : `${CONFIG_FILE} cannot be read: ${parsed.problems.join("; ")}`;
251
+ if (opts.comment) {
252
+ const text = `No proof was recorded at ${shortSha(head)}. ${problem}`.slice(0, 2e3);
253
+ await postGeneral(text, proofsCommentId(item, head, [{ id: CONFIG_FILE, proof: "setup file", reason: problem }]));
254
+ }
255
+ throw new WorkCommandError(problem);
256
+ }
257
+ const config = parsed.value;
258
+ const heads = /* @__PURE__ */ new Set([head.toLowerCase(), ...otherPullRequestHeads(body.pullRequests ?? [], ownPr, identity.gitRepo)]);
259
+ const states = classifyProofsAt(body, heads);
260
+ const todo = states.filter((state) => state.state !== "current").map((state) => state.id);
261
+ const declared = new Map((body.criteria?.items ?? []).map((criterion) => [criterion.id, criterion]));
262
+ const proofOf = (id) => declared.get(id).proof;
263
+ const reasons = /* @__PURE__ */ new Map();
264
+ const emitted = /* @__PURE__ */ new Map();
265
+ const found = discoverTestFiles(root, todo, config.runners);
266
+ for (const id of todo) {
267
+ if (!found.has(id)) reasons.set(id, NO_TEST);
268
+ }
269
+ const plan = planRuns([...new Set([...found.values()].flat())], config.runners);
270
+ const logDir = mkdtempSync(join(tmpdir(), "outerlayer-proofs-"));
271
+ const proofOuts = [];
272
+ const groups = [];
273
+ const runCommand = opts.runCommand ?? runShell;
274
+ const baseEnv = { ...process.env, ...env };
275
+ delete baseEnv.OUTERLAYER_PROOF_OUT;
276
+ let spooledCount = 0;
277
+ const spooledCriteria = /* @__PURE__ */ new Set();
278
+ const emitArtifact = async (emitOpts) => {
279
+ const result = await (opts.emitArtifact ?? runEmitArtifact)(emitOpts);
280
+ if (result.spooled) spooledCount += 1;
281
+ return result;
282
+ };
283
+ const common = { url: creds.url, apiKey: creds.apiKey, appId: creds.appId, cwd: root, home, env, fetchImpl, quiet: true };
284
+ const stopGroups = () => {
285
+ for (const pid of groups) {
286
+ try {
287
+ process.kill(-pid, "SIGTERM");
288
+ } catch {
289
+ }
290
+ }
291
+ };
292
+ const cleanUp = () => {
293
+ rmSync(logDir, { recursive: true, force: true });
294
+ for (const folder of proofOuts) rmSync(folder, { recursive: true, force: true });
295
+ };
296
+ const onSignal = (signal) => {
297
+ stopGroups();
298
+ cleanUp();
299
+ process.exit(signal === "SIGINT" ? 130 : 143);
300
+ };
301
+ const onInterrupt = () => onSignal("SIGINT");
302
+ const onTerminate = () => onSignal("SIGTERM");
303
+ process.once("SIGINT", onInterrupt);
304
+ process.once("SIGTERM", onTerminate);
305
+ const runs = [];
306
+ try {
307
+ let setupStarted = false;
308
+ try {
309
+ let setupFailed;
310
+ if (plan.size > 0) {
311
+ setupStarted = true;
312
+ for (const command of config.setup) {
313
+ const result = await runCommand(command, { cwd: root, env: baseEnv, timeoutMs, logDir, groups });
314
+ if (result.status !== 0) {
315
+ setupFailed = `setup failed: "${oneLine(command)}" ${result.timedOut ? `timed out after ${Math.round(timeoutMs / 1e3)} s` : `exited with status ${result.status}`}`;
316
+ say(setupFailed);
317
+ if (result.tail !== "") say(result.tail);
318
+ break;
319
+ }
320
+ }
321
+ }
322
+ for (const [index, files] of plan) {
323
+ const runner = config.runners[index];
324
+ const criteria = todo.filter((id) => found.get(id)?.some((file) => files.includes(file)));
325
+ if (setupFailed !== void 0) {
326
+ for (const id of criteria) reasons.set(id, setupFailed);
327
+ continue;
328
+ }
329
+ const proofOut = mkdtempSync(join(tmpdir(), "outerlayer-proof-out-"));
330
+ proofOuts.push(proofOut);
331
+ const result = await runCommand(fillFiles(runner.command, files), { cwd: root, env: { ...baseEnv, OUTERLAYER_PROOF_OUT: proofOut }, timeoutMs, logDir, groups });
332
+ const failure = result.timedOut ? `the runner for ${runner.files} timed out after ${Math.round(timeoutMs / 1e3)} s` : result.status === 0 ? void 0 : `the runner for ${runner.files} exited with status ${result.status}`;
333
+ if (failure !== void 0) {
334
+ say(failure);
335
+ if (result.tail !== "") say(result.tail);
336
+ }
337
+ runs.push({ glob: runner.files, proofOut, criteria, failure, tail: result.tail });
338
+ }
339
+ } finally {
340
+ if (setupStarted) {
341
+ for (const command of config.teardown) {
342
+ const result = await runCommand(command, { cwd: root, env: baseEnv, timeoutMs, logDir, groups });
343
+ if (result.status !== 0) say(`teardown failed: "${oneLine(command)}" ${result.timedOut ? "timed out" : `exited with status ${result.status}`}`);
344
+ }
345
+ }
346
+ process.off("SIGINT", onInterrupt);
347
+ process.off("SIGTERM", onTerminate);
348
+ stopGroups();
349
+ }
350
+ if (plan.size > 0) {
351
+ let left = [];
352
+ try {
353
+ left = changedTrackedFiles(root);
354
+ } catch {
355
+ }
356
+ if (left.length > 0) {
357
+ say(`The run changed tracked files: ${left.join(", ")}. The next --record records nothing until they match HEAD. Make setup, the tests and teardown leave them unchanged.`);
358
+ }
359
+ }
360
+ await emitProofs();
361
+ } finally {
362
+ cleanUp();
363
+ }
364
+ async function emitProofs() {
365
+ const notCurrent2 = new Set(todo);
366
+ const manifests = runs.flatMap((run) => findManifests(run.proofOut));
367
+ const chapters = /* @__PURE__ */ new Set();
368
+ if (manifests.length > 1) {
369
+ say(`Not recorded, the demo: the runners left ${manifests.length} demo manifests, so it is unclear which to store`);
370
+ } else if (manifests.length === 1) {
371
+ for (const id of chapterCriteria(manifests[0])) chapters.add(id);
372
+ await recordDemo(manifests[0], chapters);
373
+ }
374
+ for (const run of runs) {
375
+ const names = topLevelFiles(run.proofOut);
376
+ for (const name of names) {
377
+ const id = proofFileCriterion(name, new Set(declared.keys()));
378
+ if (id === void 0) {
379
+ say(`Ignored ${name}: its name is not the id of a declared criterion.`);
380
+ continue;
381
+ }
382
+ if (!notCurrent2.has(id)) {
383
+ say(`Ignored ${name}: the proof for ${id} is current, or no proof is declared for it.`);
384
+ continue;
385
+ }
386
+ if (DEMO_PROOFS.has(proofOf(id)) && chapters.has(id)) {
387
+ say(`Ignored ${name}: a demo chapter proves ${id}.`);
388
+ continue;
389
+ }
390
+ if (emitted.has(id)) continue;
391
+ const fail = (reason) => {
392
+ reasons.set(id, reason);
393
+ say(`Not recorded, ${id}: ${reason}`);
394
+ };
395
+ if (run.failure !== void 0) {
396
+ fail(`${run.failure}, so its files are not recorded`);
397
+ continue;
398
+ }
399
+ const problem = kindProblem(proofOf(id), name);
400
+ if (problem !== void 0) {
401
+ fail(problem);
402
+ continue;
403
+ }
404
+ try {
405
+ const caption = (declared.get(id).text ?? `Proof for ${id}`).slice(0, ARTIFACT_MAX_CAPTION_LENGTH);
406
+ const before = spooledCount;
407
+ const result = await emitArtifact({ ...common, file: join(run.proofOut, name), caption, criterionId: id, ...ownPr === void 0 ? {} : { pr: ownPr } });
408
+ const artifactId = result.record?.artifactId ?? result.data?.clientArtifactId;
409
+ if (artifactId === void 0) {
410
+ fail("the upload returned no artifact id");
411
+ continue;
412
+ }
413
+ emitted.set(id, artifactId);
414
+ if (spooledCount > before) spooledCriteria.add(id);
415
+ } catch (err) {
416
+ fail(`the upload failed: ${oneLine(String(err instanceof Error ? err.message : err))}`);
417
+ }
418
+ }
419
+ }
420
+ for (const run of runs) {
421
+ for (const id of run.criteria) {
422
+ if (emitted.has(id) || reasons.has(id)) continue;
423
+ reasons.set(id, run.failure ?? `the tests ran and wrote no ${id}.<ext> file under OUTERLAYER_PROOF_OUT`);
424
+ }
425
+ }
426
+ }
427
+ async function recordDemo(manifest, chapters) {
428
+ const demoCriteria = todo.filter((id) => DEMO_PROOFS.has(proofOf(id)));
429
+ let replaces;
430
+ try {
431
+ replaces = (await readNewestDemo({ url: creds.url, apiKey: creds.apiKey, appId: creds.appId, item, fetchImpl }))?.artifactId;
432
+ } catch (err) {
433
+ replaces = void 0;
434
+ say(`The previous demo could not be read, so the new demo does not replace it: ${oneLine(String(err instanceof Error ? err.message : err))}`);
435
+ }
436
+ const before = spooledCount;
437
+ let result;
438
+ try {
439
+ result = await (opts.emitDemo ?? runEmitDemo)({
440
+ ...common,
441
+ manifest,
442
+ item,
443
+ ...ownPr === void 0 ? {} : { pr: ownPr },
444
+ ...replaces === void 0 ? {} : { replaces },
445
+ emitArtifact
446
+ });
447
+ } catch (err) {
448
+ const reason = `the demo was not stored: ${oneLine(String(err instanceof Error ? err.message : err))}`;
449
+ for (const id of demoCriteria) reasons.set(id, reason);
450
+ say(`Not recorded, the demo: ${reason}`);
451
+ return;
452
+ }
453
+ for (const id of demoCriteria) {
454
+ const artifactId = proofOf(id) === "screenshot" ? result.screenshots.find((shot) => shot.criterionId === id && shot.artifactId !== void 0)?.artifactId : result.clips.find((clip) => clip.criterionId === id && clip.bound)?.clipArtifactId;
455
+ if (artifactId !== void 0) {
456
+ emitted.set(id, artifactId);
457
+ if (spooledCount > before) spooledCriteria.add(id);
458
+ } else if (chapters.has(id)) {
459
+ reasons.set(id, result.failures.length > 0 ? `the demo failed a check: ${oneLine(result.failures[0])}` : "the demo has no passing chapter for it");
460
+ }
461
+ }
462
+ for (const failure of result.failures) say(`Demo check failed: ${oneLine(failure)}`);
463
+ }
464
+ if (spooledCount > 0) {
465
+ try {
466
+ const synced = await (opts.sync ?? (() => runSync({ ...common })))();
467
+ const unstored = unstoredUploads(
468
+ synced,
469
+ [...spooledCriteria].map((id) => emitted.get(id))
470
+ );
471
+ const lostIds = unstored === "all" ? [...spooledCriteria] : [...spooledCriteria].filter((id) => unstored.includes(emitted.get(id)));
472
+ for (const id of lostIds) {
473
+ emitted.delete(id);
474
+ reasons.set(id, "the sync did not store the upload, so the proof is stored only in the session record");
475
+ }
476
+ if (lostIds.length > 0) say("The sync did not store an upload. The proofs that went through the session record are not stored.");
477
+ } catch (err) {
478
+ for (const id of spooledCriteria) {
479
+ emitted.delete(id);
480
+ reasons.set(id, "the sync failed, so the proof is stored only in the session record");
481
+ }
482
+ say(`The sync failed, so the new proofs are stored only in the session record: ${oneLine(String(err instanceof Error ? err.message : err))}`);
483
+ }
484
+ }
485
+ for (const [criterion, artifactId] of emitted) say(`Recorded ${criterion}: ${artifactId}`);
486
+ let finalStates = states;
487
+ try {
488
+ const { data: fresh } = await getJson(creds.url, `/v1/work-items/${item}`, creds.apiKey, creds.appId, fetchImpl);
489
+ finalStates = classifyProofsAt(fresh, heads);
490
+ } catch (err) {
491
+ say(`The item could not be read again, so the list below may be out of date: ${oneLine(String(err instanceof Error ? err.message : err))}`);
492
+ }
493
+ const notCurrent = finalStates.filter((state) => state.state !== "current" && !emitted.has(state.id)).map((state) => ({ id: state.id, proof: state.proof, reason: reasons.get(state.id) ?? "it was not recorded in this run" }));
494
+ if (opts.comment && notCurrent.length > 0) {
495
+ await postGeneral(proofsCommentBody(head, notCurrent), proofsCommentId(item, head, notCurrent));
496
+ }
497
+ for (const proof of notCurrent) say(`Not current, ${proof.id} (${proof.proof}): ${proof.reason}`);
498
+ const closing = await runWorkProofs({ ...opts, item, env, quiet: true, checkoutHead: head, fetchImpl });
499
+ const output = [...lines, closing.output].join("\n");
500
+ if (!opts.quiet) process.stdout.write(output + "\n");
501
+ return {
502
+ exitCode: closing.exitCode,
503
+ output,
504
+ emitted: [...emitted].map(([criterion, artifactId]) => ({ criterion, artifactId })),
505
+ notCurrent
506
+ };
507
+ }
508
+
509
+ export { runWorkProofsRecord };
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveCredentials, postJson, WorkCommandError } from './chunk-GJYGOFF3.js';
3
+ import { resolveCredentials, postJson, WorkCommandError } from './chunk-72N7GOLM.js';
4
4
  import './chunk-IP7BIBXJ.js';
5
- import './chunk-BTDBDTUY.js';
6
- import './chunk-4J5GRWAY.js';
5
+ import './chunk-GJHOU5V3.js';
6
+ import './chunk-N6V4ZHI7.js';
7
7
  import './chunk-NWHU5G6R.js';
8
8
  import './chunk-G2JWZDFA.js';
9
9
  import './chunk-ANPNT6PM.js';
10
10
  import './chunk-IXPH4EXK.js';
11
11
  import './chunk-LYCJQOO2.js';
12
- import { defaultFetch } from './chunk-PAGB3DCI.js';
12
+ import { defaultFetch } from './chunk-IZKUPAXF.js';
13
13
  import './chunk-PJDQPF5N.js';
14
- import './chunk-VKYU4HHW.js';
14
+ import './chunk-VJQQVTCS.js';
15
15
  import './chunk-BJ3KTMDH.js';
16
16
  import './chunk-OVNF4LLC.js';
17
- import './chunk-A6PJSNP6.js';
17
+ import './chunk-A2KLVZBU.js';
18
18
  import './chunk-5BHIBJDA.js';
19
19
  import './chunk-CDDED64E.js';
20
20
  import './chunk-RA3O54FC.js';
@@ -23,8 +23,8 @@ import './chunk-CRB3POP4.js';
23
23
  import './chunk-XFJ7YOPD.js';
24
24
  import './chunk-DINRXUQA.js';
25
25
  import './chunk-VNVZDWO3.js';
26
- import './chunk-AJTGTSNA.js';
27
- import './chunk-L2OARQKP.js';
26
+ import './chunk-2CW2QMSG.js';
27
+ import './chunk-4N7BQBO4.js';
28
28
  import './chunk-MESOOLF4.js';
29
29
  import './chunk-Z5GEFMRW.js';
30
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outerlayer/cli",
3
- "version": "0.34.0-next.20261028010245",
3
+ "version": "0.34.0-next.20261028122415",
4
4
  "description": "OuterLayer CLI — commands: init, claude, connect, doctor, login, logout, sync, daemon (alias: watch), emit, demo, 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.",