@outerlayer/cli 0.34.0-next.20261026161241 → 0.34.0-next.20261026182624

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.
@@ -4936,7 +4936,8 @@ A proof is current when it was recorded at this checkout's HEAD, or at the head
4936
4936
  linked pull request that is open or merged. Run \`outerlayer sync\` first, so the
4937
4937
  gateway has the artifacts you just emitted. Test proofs are not listed.
4938
4938
  Exits 0 when every listed proof is current, 1 when any is out of date or missing,
4939
- and 2 when it cannot tell.
4939
+ and 2 when it cannot tell. It also lists each criterion the criteria judge fails without
4940
+ reading a test, as uncited or failed. In a runner build those rows give exit 1.
4940
4941
 
4941
4942
  --record reads .outerlayer-proofs.yaml from the HEAD commit and finds the test files at HEAD
4942
4943
  that hold the id of each proof that is not current. It runs setup, then each runner once with
@@ -4958,7 +4959,7 @@ differs from HEAD.
4958
4959
  fail(trackerNumberError("--pr", opts.pr));
4959
4960
  return;
4960
4961
  }
4961
- const { runWorkProofsCommand } = await import('./work-proofs-cmd-YMLIJDJZ.js');
4962
+ const { runWorkProofsCommand } = await import('./work-proofs-cmd-YMMDAA6W.js');
4962
4963
  await runWorkProofsCommand({ ...opts, ...pr === void 0 ? {} : { pr } });
4963
4964
  });
4964
4965
  workCmd.command("list").description("List live work items for this factory").option("--stage <spec|build|review>", "filter by stage").option("--section <attention|waiting|flowing>", "filter by Queue section").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--unclaimed", "only items with no live lease").option("--claimed", "only items with a live lease, held by a host or a local session").option("--startable", "only items a host can start: a build request, no open PR, no live lease").option("--needs <amend>", "only items with a thread waiting on an agent").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
@@ -5105,7 +5106,7 @@ function registerRunnerCommands(program2) {
5105
5106
  const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
5106
5107
  runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
5107
5108
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-WSZIWPP4.js');
5108
- const { start, RunnerStartError } = await import('./loop-A4CB4IFF.js');
5109
+ const { start, RunnerStartError } = await import('./loop-NGFNQF3Y.js');
5109
5110
  const { RunnerAlreadyRunningError } = await import('./pidfile-PCG2H5T4.js');
5110
5111
  const configPath = opts.config ?? defaultRunnerConfigPath();
5111
5112
  try {
@@ -5124,8 +5125,8 @@ function registerRunnerCommands(program2) {
5124
5125
  "\nReads OUTERLAYER_URL, OUTERLAYER_APP_ID, OUTERLAYER_API_KEY, OUTERLAYER_RUNNER_NAME and one Claude credential\n(CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY) from the environment. OUTERLAYER_AGENT\nis optional and defaults to claude. On a later start it refuses variables that disagree with the config in the volume.\nThe image sets OUTERLAYER_RUNNER_IMAGE; outside the image, use `runner start`.\n"
5125
5126
  ).action(async () => {
5126
5127
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-WSZIWPP4.js');
5127
- const { containerStart } = await import('./container-start-IL74XEC5.js');
5128
- const { start, RunnerStartError } = await import('./loop-A4CB4IFF.js');
5128
+ const { containerStart } = await import('./container-start-XRR4VC5Z.js');
5129
+ const { start, RunnerStartError } = await import('./loop-NGFNQF3Y.js');
5129
5130
  const { RunnerAlreadyRunningError } = await import('./pidfile-PCG2H5T4.js');
5130
5131
  try {
5131
5132
  const result = await containerStart({
@@ -5149,14 +5150,14 @@ function registerRunnerCommands(program2) {
5149
5150
  ).action(async (opts) => {
5150
5151
  const { defaultRunnerConfigPath } = await import('./config-WSZIWPP4.js');
5151
5152
  const { runnerDir } = await import('./paths-AQ47ZRHK.js');
5152
- const { runUpdateSteps } = await import('./update-steps-CSC2QVJF.js');
5153
+ const { runUpdateSteps } = await import('./update-steps-IQVAL64Y.js');
5153
5154
  const text = await runUpdateSteps({ runnerDirPath: runnerDir(opts.config ?? defaultRunnerConfigPath()) });
5154
5155
  process.stdout.write(`${text}
5155
5156
  `);
5156
5157
  });
5157
5158
  runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
5158
5159
  const { defaultRunnerConfigPath } = await import('./config-WSZIWPP4.js');
5159
- const { runRunnerCheck } = await import('./check-ERYYVAEM.js');
5160
+ const { runRunnerCheck } = await import('./check-G2K76NEM.js');
5160
5161
  const configPath = opts.config ?? defaultRunnerConfigPath();
5161
5162
  const result = await runRunnerCheck(configPath);
5162
5163
  if (!result.ok) {
@@ -5564,7 +5565,7 @@ Next:
5564
5565
  });
5565
5566
  runnerCmd.command("stop").description("Take no more work; finish running jobs, then exit").option("--config <path>", "the cloud config file naming the runner to stop").option("--now", "end running jobs immediately, with outcome stopped").action(async (opts) => {
5566
5567
  const { defaultRunnerConfigPath } = await import('./config-WSZIWPP4.js');
5567
- const { requestStop } = await import('./loop-A4CB4IFF.js');
5568
+ const { requestStop } = await import('./loop-NGFNQF3Y.js');
5568
5569
  const configPath = opts.config ?? defaultRunnerConfigPath();
5569
5570
  const { runnerImageVersion } = await import('./image-tag-BTXKIH73.js');
5570
5571
  await requestStop(configPath, Boolean(opts.now), void 0, { image: runnerImageVersion() !== void 0 });
@@ -5572,8 +5573,8 @@ Next:
5572
5573
  runnerCmd.command("status").description("List running jobs; with --recent, finished ones too").option("--config <path>", "the cloud config file naming the runner to inspect").option("--recent", "also list finished jobs, newest first, capped at 20").option("--json", "machine-readable JSON output").action(async (opts) => {
5573
5574
  const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-WSZIWPP4.js');
5574
5575
  const { jobsDir, runnerDir } = await import('./paths-AQ47ZRHK.js');
5575
- const { listJobFiles, runnerProcessState } = await import('./loop-A4CB4IFF.js');
5576
- const { renderStatus } = await import('./status-6V2S63DS.js');
5576
+ const { listJobFiles, runnerProcessState } = await import('./loop-NGFNQF3Y.js');
5577
+ const { renderStatus } = await import('./status-WQ53MWC3.js');
5577
5578
  const { readHousekeepingRecord } = await import('./record-SVCNFCGQ.js');
5578
5579
  const path2 = await import('path');
5579
5580
  const configPath = opts.config ?? defaultRunnerConfigPath();
@@ -5632,7 +5633,7 @@ Next:
5632
5633
  });
5633
5634
  runnerCmd.command("logs").argument("<item>", "the work item's number in the factory").description("Print the newest attempt's log for one item").option("--config <path>", "the cloud config file naming the runner to inspect").option("-f, --follow", "keep printing as the log grows").action(async (itemArg, opts) => {
5634
5635
  const { defaultRunnerConfigPath } = await import('./config-WSZIWPP4.js');
5635
- const { listJobFiles } = await import('./loop-A4CB4IFF.js');
5636
+ const { listJobFiles } = await import('./loop-NGFNQF3Y.js');
5636
5637
  const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-LEVH6VAI.js');
5637
5638
  const configPath = opts.config ?? defaultRunnerConfigPath();
5638
5639
  const item = parseTrackerNumber(itemArg);
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { reportFailedStart, BUILD_MEMORY_VARIABLE } from './chunk-U6AWVO6L.js';
4
- import { readOwnContainer } from './chunk-VWZHOFBP.js';
5
- import './chunk-4G4IH4A7.js';
3
+ import { reportFailedStart, BUILD_MEMORY_VARIABLE } from './chunk-ERTIEYDG.js';
4
+ import { readOwnContainer } from './chunk-P3CHDKXD.js';
5
+ import './chunk-SZU4YCBH.js';
6
6
  import './chunk-ZVB57WI6.js';
7
+ import './chunk-6D7H5DMZ.js';
7
8
  import './chunk-P3NPTFLF.js';
8
9
  import './chunk-I3LTIAOR.js';
9
10
  import './chunk-LD3BHLK7.js';
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ export { MAX_CHECK_ITEMS_BYTES, checksIn, commandItems, isJudgeCheck, makeRecorder, readDefinitions, runHostChecks, timeoutAfter } from './chunk-SZU4YCBH.js';
4
+ import './chunk-ZVB57WI6.js';
5
+ import './chunk-6D7H5DMZ.js';
6
+ import './chunk-P3NPTFLF.js';
7
+ import './chunk-I3LTIAOR.js';
8
+ import './chunk-LD3BHLK7.js';
9
+ import './chunk-VUQKGBIQ.js';
10
+ import './chunk-XSFR76J7.js';
11
+ import './chunk-ESVW4MJY.js';
12
+ import './chunk-CFFVCI2I.js';
13
+ import './chunk-TBT347UY.js';
14
+ import './chunk-XKJOIQ2Q.js';
15
+ import './chunk-CNZRUVZ5.js';
16
+ import './chunk-2PGI6RDE.js';
17
+ import './chunk-H47VGSCW.js';
18
+ import './chunk-OGFGZQA3.js';
19
+ import './chunk-3VZTNXK5.js';
20
+ import './chunk-6KFJIU73.js';
21
+ import './chunk-EPFFYDNX.js';
22
+ import './chunk-SDELQEG4.js';
23
+ import './chunk-TQMI335S.js';
24
+ import './chunk-HVPW272H.js';
25
+ import './chunk-V2VJYK46.js';
26
+ import './chunk-ZIKZZ4LK.js';
27
+ import './chunk-IWVGALDC.js';
28
+ import './chunk-HVQMIZ22.js';
29
+ import './chunk-4UPET3R7.js';
30
+ import './chunk-LQHCNXPK.js';
31
+ import './chunk-JBJTC3UU.js';
32
+ import './chunk-KT4CN6OU.js';
33
+ import './chunk-4P6QGMPN.js';
34
+ import './chunk-JKNOJKVD.js';
35
+ import './chunk-IP7BIBXJ.js';
36
+ import './chunk-IO2BBKG4.js';
37
+ import './chunk-EUQZAH2W.js';
38
+ import './chunk-Y5YCX6AL.js';
39
+ import './chunk-G2JWZDFA.js';
40
+ import './chunk-ANPNT6PM.js';
41
+ import './chunk-MECW77XP.js';
42
+ import './chunk-NKOM4JKY.js';
43
+ import './chunk-5JGPTYLT.js';
44
+ import './chunk-JWNH4ZTF.js';
45
+ import './chunk-7QAJQDHS.js';
46
+ import './chunk-PJDQPF5N.js';
47
+ import './chunk-L5VHGRQE.js';
48
+ import './chunk-NHEU5CON.js';
49
+ import './chunk-ZJSNLVCE.js';
50
+ import './chunk-2O5KA67H.js';
51
+ import './chunk-BKO6JEZI.js';
52
+ import './chunk-FGF52V4V.js';
53
+ import './chunk-HCVLP7XA.js';
54
+ import './chunk-BJ3KTMDH.js';
55
+ import './chunk-ZQSANKS4.js';
56
+ import './chunk-Z7WMU3RA.js';
57
+ import './chunk-5BHIBJDA.js';
58
+ import './chunk-CDDED64E.js';
59
+ import './chunk-RA3O54FC.js';
60
+ import './chunk-T2Q7ISPE.js';
61
+ import './chunk-WZBHBH3J.js';
62
+ import './chunk-CRB3POP4.js';
63
+ import './chunk-URIZRCRY.js';
64
+ import './chunk-DQ6YO7FH.js';
65
+ import './chunk-YQR6E6OV.js';
66
+ import './chunk-TUSYOL2O.js';
67
+ import './chunk-FGXT5OXS.js';
68
+ import './chunk-EOTMDIYC.js';
69
+ import './chunk-VNVZDWO3.js';
70
+ import './chunk-GJ4KBHBD.js';
71
+ import './chunk-SDAEXUIX.js';
72
+ import './chunk-MESOOLF4.js';
73
+ import './chunk-Z5GEFMRW.js';
74
+
75
+ createRequire(import.meta.url);
package/dist/index.js CHANGED
@@ -26,5 +26,5 @@ if (argv[0] === "claude") {
26
26
  process.exit(await runClaudeLauncher(argv.slice(1)));
27
27
  }
28
28
  (await import('./hook-fast-6EW2MGA2.js')).recordLinkExitFailure(argv);
29
- var { runCli } = await import('./cli-LXKVCFD7.js');
29
+ var { runCli } = await import('./cli-5KY3TE3S.js');
30
30
  await runCli(process.argv);
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { RunnerStartError, leaseTimeLeftFor, listJobFiles, logUnusableHelper, probeBuild, probeCredentials, requestStop, runnerProcessState, runtimeOf, sampleUsage, start, tick, watchTick } from './chunk-E6OVLJTR.js';
4
- import './chunk-U6AWVO6L.js';
5
- import './chunk-HOUFCUMH.js';
6
- import './chunk-VWZHOFBP.js';
7
- import './chunk-4G4IH4A7.js';
8
- import './chunk-ZVB57WI6.js';
9
- import './chunk-TS3EFB7S.js';
3
+ export { RunnerStartError, leaseTimeLeftFor, listJobFiles, logUnusableHelper, probeBuild, probeCredentials, requestStop, runnerProcessState, runtimeOf, sampleUsage, start, tick, watchTick } from './chunk-LTN2YFLR.js';
10
4
  import './chunk-3JVYMD4G.js';
5
+ import './chunk-ERTIEYDG.js';
11
6
  import './chunk-E7R2GIAW.js';
12
7
  import './chunk-MH6QLXUO.js';
8
+ import './chunk-HOUFCUMH.js';
9
+ import './chunk-P3CHDKXD.js';
10
+ import './chunk-TS3EFB7S.js';
11
+ import './chunk-SZU4YCBH.js';
12
+ import './chunk-ZVB57WI6.js';
13
+ import './chunk-6D7H5DMZ.js';
13
14
  import './chunk-P3NPTFLF.js';
14
15
  import './chunk-I3LTIAOR.js';
15
16
  import './chunk-LD3BHLK7.js';
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isReadable, ALREADY_RELEASED, RENEW_INTERVAL_SECONDS } from './chunk-4G4IH4A7.js';
3
+ import { isReadable, ALREADY_RELEASED, RENEW_INTERVAL_SECONDS } from './chunk-SZU4YCBH.js';
4
4
  import { jobStateFormatOf } from './chunk-ZVB57WI6.js';
5
+ import './chunk-6D7H5DMZ.js';
5
6
  import './chunk-P3NPTFLF.js';
6
7
  import './chunk-I3LTIAOR.js';
7
8
  import './chunk-LD3BHLK7.js';
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { readOwnContainer, renderUpdateSteps, runUpdateSteps } from './chunk-VWZHOFBP.js';
4
- import './chunk-4G4IH4A7.js';
3
+ export { readOwnContainer, renderUpdateSteps, runUpdateSteps } from './chunk-P3CHDKXD.js';
4
+ import './chunk-SZU4YCBH.js';
5
5
  import './chunk-ZVB57WI6.js';
6
+ import './chunk-6D7H5DMZ.js';
6
7
  import './chunk-P3NPTFLF.js';
7
8
  import './chunk-I3LTIAOR.js';
8
9
  import './chunk-LD3BHLK7.js';
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-FZ4G6CMK.js';
3
+ export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-GYVMMU3U.js';
4
+ import './chunk-6D7H5DMZ.js';
4
5
  import './chunk-JKNOJKVD.js';
5
6
  import './chunk-IP7BIBXJ.js';
6
7
  import './chunk-IO2BBKG4.js';
@@ -22,6 +23,7 @@ import './chunk-RA3O54FC.js';
22
23
  import './chunk-T2Q7ISPE.js';
23
24
  import './chunk-WZBHBH3J.js';
24
25
  import './chunk-CRB3POP4.js';
26
+ import './chunk-YQR6E6OV.js';
25
27
  import './chunk-FGXT5OXS.js';
26
28
  import './chunk-EOTMDIYC.js';
27
29
  import './chunk-VNVZDWO3.js';
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { runWorkComment } from './chunk-JSZRBQY3.js';
4
- import { resolveProofsItem, ownPullRequest, proofsCommentId, otherPullRequestHeads, classifyProofsAt, kindProblem, proofsCommentBody, runWorkProofs } from './chunk-FZ4G6CMK.js';
4
+ import { resolveProofsItem, ownPullRequest, proofsCommentId, otherPullRequestHeads, classifyProofsAt, kindProblem, proofsCommentBody, runWorkProofs } from './chunk-GYVMMU3U.js';
5
+ import './chunk-6D7H5DMZ.js';
5
6
  import { runEmitDemo } from './chunk-ELO5XEES.js';
6
7
  import { readNewestDemo } from './chunk-ER6KQCVJ.js';
7
8
  import { runEmitArtifact } from './chunk-XL2MPORM.js';
@@ -38,6 +39,7 @@ import './chunk-T2Q7ISPE.js';
38
39
  import './chunk-WZBHBH3J.js';
39
40
  import './chunk-CRB3POP4.js';
40
41
  import './chunk-URIZRCRY.js';
42
+ import './chunk-YQR6E6OV.js';
41
43
  import './chunk-TUSYOL2O.js';
42
44
  import { parseProofsConfig } from './chunk-FGXT5OXS.js';
43
45
  import { ARTIFACT_MAX_CAPTION_LENGTH } from './chunk-EOTMDIYC.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outerlayer/cli",
3
- "version": "0.34.0-next.20261026161241",
3
+ "version": "0.34.0-next.20261026182624",
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.",
@@ -129,7 +129,8 @@ repository. Commit and push in each checkout you change, to its own branch only.
129
129
  thread back to a person.
130
130
  9. **Check nothing is left waiting.** Reread threads. A thread still waiting
131
131
  on an agent has a reply that did not land or was flagged `unchanged`. Fix
132
- or report it. Then run `outerlayer sync` and `outerlayer work proofs`.
132
+ or report it. Run `outerlayer sync` and `outerlayer work proofs`. Fix each
133
+ `uncited` or `failed` row it lists.
133
134
  10. **Report.** Write one line per thread: the criterion (or the general
134
135
  thread), and fixed (with the replacement) or handed off (with the reason).
135
136
  Add a line for a merge conflict (merged with the base sha, or handed off
@@ -360,7 +360,9 @@ Run this last, after the pull request is open and the evidence is emitted, and
360
360
  run no other tool call after it. Before it, run `outerlayer sync` and then
361
361
  `outerlayer work proofs --item "$OUTERLAYER_WORK"`. End the run only when it
362
362
  exits 0, or when `build-reports/evidence.md` names each proof it still lists
363
- and the reason. Exit 2 means it could not decide: fix the reason it prints and
363
+ and the reason. A row marked `uncited` or `failed` has no such excuse: make a
364
+ test cite the criterion, or change a test that cites it, and run the command
365
+ again. Exit 2 means it could not decide: fix the reason it prints and
364
366
  run it again:
365
367
 
366
368
  outerlayer work release --item "$OUTERLAYER_WORK"
@@ -30,7 +30,12 @@ session can run it again.
30
30
  After the evidence agent returns, run `outerlayer sync`, then
31
31
  `outerlayer work proofs --item "$OUTERLAYER_WORK"`. It lists each declared proof
32
32
  as current, out of date or missing at the checkout's head. The command leaves
33
- out criteria that declare a test proof.
33
+ out criteria that declare a test proof. It also lists each criterion that the
34
+ host's criteria judge fails without reading a test. A row marked `uncited` has
35
+ no proof and no test at HEAD that cites it: put the id in a test's title or in a
36
+ comment above it, as in `// proves AC-7-02`, and commit. A row marked `failed`
37
+ names a criterion that the judge failed, whose citing tests have not changed:
38
+ change a test that cites it, and commit.
34
39
 
35
40
  A commit makes every proof out of date, and each `--record` run starts the app
36
41
  again. So record only at the run's last head. First make every commit the run
@@ -41,8 +46,9 @@ record once more after it. The final report names that head and the proofs
41
46
  recorded there.
42
47
 
43
48
  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.
49
+ as out of date or missing goes in `build-reports/evidence.md` with the reason.
50
+ A written reason never excuses an `uncited` or `failed` row. Fix it first. Never
51
+ drive the browser yourself.
46
52
 
47
53
  Re-read the pull request's evidence comment. Resolve or escalate every row that
48
54
  needs attention. A row is resolved when a re-read shows it, not when the fixing
@@ -1,151 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- import { WorkCommandError, resolveCredentials, getJson } from './chunk-JKNOJKVD.js';
4
- import { C } from './chunk-ANPNT6PM.js';
5
- import { sanitizeTerminal } from './chunk-MECW77XP.js';
6
- import { defaultFetch } from './chunk-7QAJQDHS.js';
7
- import { resolveRepoIdentity } from './chunk-Z7WMU3RA.js';
8
- import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
9
- import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
10
- import { inferArtifactKind, mediaTypeForArtifactPath, WORK_ITEM_COMMENT_MAX_BODY_LENGTH } from './chunk-EOTMDIYC.js';
11
- import { createHash } from 'crypto';
12
-
13
- createRequire(import.meta.url);
14
- function kindProblem(declared, file) {
15
- if (declared === "test") return "a test proof is recorded by CI, not by --record";
16
- const kind = inferArtifactKind(mediaTypeForArtifactPath(file));
17
- return kind === declared ? void 0 : `the kinds differ: the file is a ${kind}, but the criterion declares a ${declared} proof`;
18
- }
19
- function proofsCommentBody(head, lines) {
20
- const header = `These proofs are not current at ${head.slice(0, 7)}:`;
21
- const rows = lines.map((line) => `- ${line.id} (${line.proof}): ${line.reason}`);
22
- const fits = (count2) => {
23
- const left = rows.length - count2;
24
- return [header, ...rows.slice(0, count2), ...left > 0 ? [`and ${left} more.`] : []].join("\n");
25
- };
26
- let count = rows.length;
27
- while (count > 0 && fits(count).length > WORK_ITEM_COMMENT_MAX_BODY_LENGTH) count -= 1;
28
- return fits(count);
29
- }
30
- function proofsCommentId(item, head, lines) {
31
- 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]);
32
- const digest = createHash("sha256").update(JSON.stringify([item, head.toLowerCase(), list])).digest("hex");
33
- return `proofs-${digest.slice(0, 32)}`;
34
- }
35
- function repositoryName(repository) {
36
- return repository.replace(/\.git$/, "").split("/").filter((part) => part !== "").slice(-2).join("/").toLowerCase();
37
- }
38
- function ownPullRequest(pullRequests, requested, checkoutRepository) {
39
- if (requested !== void 0) return { pr: requested };
40
- const here = checkoutRepository === void 0 ? void 0 : repositoryName(checkoutRepository);
41
- const open = pullRequests.filter(
42
- (pr) => pr.state === "open" && typeof pr.prNumber === "number" && (here === void 0 || repositoryName(pr.repository ?? "") === here)
43
- );
44
- if (open.length > 1) return { ambiguous: open.map((pr) => pr.prNumber) };
45
- return { pr: open[0]?.prNumber };
46
- }
47
-
48
- // src/work-proofs-cmd.ts
49
- function liveHead(pr) {
50
- if (pr.state !== "open" && pr.state !== "merged" || typeof pr.headSha !== "string" || pr.headSha === "") return void 0;
51
- return pr.headSha.toLowerCase();
52
- }
53
- function otherPullRequestHeads(pullRequests, ownPr, checkoutRepository) {
54
- const here = checkoutRepository === void 0 ? void 0 : repositoryName(checkoutRepository);
55
- const heads = /* @__PURE__ */ new Set();
56
- for (const pr of pullRequests) {
57
- const head = liveHead(pr);
58
- if (head === void 0) continue;
59
- const isOwn = ownPr !== void 0 && pr.prNumber === ownPr && (here === void 0 || repositoryName(pr.repository ?? "") === here);
60
- if (!isOwn) heads.add(head);
61
- }
62
- return heads;
63
- }
64
- function classifyProofs(data, checkoutHead) {
65
- const heads = /* @__PURE__ */ new Set();
66
- if (checkoutHead !== void 0 && checkoutHead !== "") heads.add(checkoutHead.toLowerCase());
67
- data.pullRequests?.forEach((pr) => {
68
- const head = liveHead(pr);
69
- if (head !== void 0) heads.add(head);
70
- });
71
- return classifyProofsAt(data, heads);
72
- }
73
- function classifyProofsAt(data, heads) {
74
- const entries = [];
75
- for (const criterion of data.criteria?.items ?? []) {
76
- if (criterion.proof === null || criterion.proof === "test") continue;
77
- const newest = criterion.newestProof;
78
- if (newest === null || newest === void 0) {
79
- entries.push({ id: criterion.id, proof: criterion.proof, state: "missing", commit: null });
80
- } else if (newest.commitSha !== null && heads.has(newest.commitSha.toLowerCase())) {
81
- entries.push({ id: criterion.id, proof: criterion.proof, state: "current", commit: newest.commitSha });
82
- } else {
83
- entries.push({ id: criterion.id, proof: criterion.proof, state: "out-of-date", commit: newest.commitSha });
84
- }
85
- }
86
- return entries;
87
- }
88
- var STATE_LABEL = { current: "current", "out-of-date": "out of date", missing: "missing" };
89
- function render(entries, json) {
90
- if (json) return JSON.stringify(entries);
91
- if (entries.length === 0) return "No criterion declares a proof other than test.";
92
- return entries.map((e) => `${sanitizeTerminal(e.id)} ${sanitizeTerminal(e.proof)} ${STATE_LABEL[e.state]} ${sanitizeTerminal(e.commit ?? "no commit")}`).join("\n");
93
- }
94
- function resolveProofsItem(opts) {
95
- const env = opts.env ?? process.env;
96
- let item;
97
- if (opts.item !== void 0) {
98
- item = parseTrackerNumber(opts.item);
99
- if (item === void 0) throw new WorkCommandError(trackerNumberError("--item", opts.item));
100
- } else if (env.OUTERLAYER_WORK !== void 0) {
101
- const parsed = parseWorkItemEnv(env.OUTERLAYER_WORK);
102
- if (!("number" in parsed)) throw new WorkCommandError(parsed.reason);
103
- item = parsed.number;
104
- }
105
- if (item === void 0) {
106
- throw new WorkCommandError("no work item. Pass --item <number>, or set OUTERLAYER_WORK to the item's number.");
107
- }
108
- return item;
109
- }
110
- async function runWorkProofs(opts) {
111
- const item = resolveProofsItem(opts);
112
- const creds = resolveCredentials(opts);
113
- const { data } = await getJson(creds.url, `/v1/work-items/${item}`, creds.apiKey, creds.appId, opts.fetchImpl ?? defaultFetch);
114
- const body = data;
115
- const items = body.criteria?.items ?? [];
116
- if (items.some((c) => c.proof !== null && c.proof !== "test" && !("newestProof" in c))) {
117
- throw new WorkCommandError(
118
- "the gateway does not report each criterion's newest proof. Update the gateway, then run this again."
119
- );
120
- }
121
- const checkoutHead = opts.checkoutHead ?? resolveRepoIdentity(opts.cwd ?? process.cwd()).commitSha;
122
- if (!checkoutHead) {
123
- throw new WorkCommandError("cannot read the checkout's HEAD. Run this inside the git checkout, or pass the head explicitly.");
124
- }
125
- const entries = classifyProofs(body, checkoutHead);
126
- const output = render(entries, opts.json === true);
127
- if (!opts.quiet) process.stdout.write(output + "\n");
128
- return { entries, output, exitCode: entries.every((e) => e.state === "current") ? 0 : 1 };
129
- }
130
- async function runWorkProofsCommand(opts) {
131
- try {
132
- if (opts.record) {
133
- const { runWorkProofsRecord } = await import('./work-proofs-record-NK3ULOUQ.js');
134
- const result2 = await runWorkProofsRecord(opts);
135
- process.exitCode = result2.exitCode;
136
- return;
137
- }
138
- const result = await runWorkProofs(opts);
139
- process.exitCode = result.exitCode;
140
- } catch (err) {
141
- if (err instanceof WorkCommandError) {
142
- process.stderr.write(`${C.red}\u2717${C.reset} ${err.message}
143
- `);
144
- process.exitCode = 2;
145
- return;
146
- }
147
- throw err;
148
- }
149
- }
150
-
151
- export { classifyProofs, classifyProofsAt, kindProblem, otherPullRequestHeads, ownPullRequest, proofsCommentBody, proofsCommentId, resolveProofsItem, runWorkProofs, runWorkProofsCommand };