@yagni-app/code-staging 1.2.6-staging.1918.1 → 1.2.6-staging.1932.1

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.
@@ -244,7 +244,9 @@ function pickScript(pkgDir, readFile, pm) {
244
244
  */
245
245
  export function detectVerifyCommands(cwd, opts = {}) {
246
246
  const readFile = opts.readFile ?? ((p) => readFileSync(p, "utf8"));
247
- const override = opts.allowRepoOverride ? tryRead(readFile, join(cwd, ".yagni-code", "verify")) : null;
247
+ const override = opts.allowRepoOverride
248
+ ? tryRead(readFile, join(cwd, ".yagni-code", "verify"))
249
+ : null;
248
250
  if (override) {
249
251
  for (const raw of override.split("\n")) {
250
252
  const line = raw.trim();
@@ -380,13 +382,22 @@ export function classifyVerifyInfraFailure(output, exitCode) {
380
382
  * the failure parsers and, past those, to fail-open UNCERTAIN.
381
383
  */
382
384
  const TEST_INFRA_PATTERNS = [
383
- [/\bECONNREFUSED\b|\bconnection refused\b/i, "connection refused (is the test's DB/service running?)"],
385
+ [
386
+ /\bECONNREFUSED\b|\bconnection refused\b/i,
387
+ "connection refused (is the test's DB/service running?)",
388
+ ],
384
389
  [/\bECONNRESET\b/, "connection reset by the test's DB/service"],
385
390
  [/\bENOTFOUND\b|\bEAI_AGAIN\b/, "DNS/host resolution failed for a test dependency"],
386
391
  [/\bEADDRINUSE\b/, "a port the tests need is already in use"],
387
392
  [/\bETIMEDOUT\b|\bconnect(?:ion)? timed out\b/i, "connection to a test dependency timed out"],
388
- [/\bmissing (?:required )?env(?:ironment)? (?:var(?:iable)?s?)\b/i, "missing environment variable"],
389
- [/\benvironment variable\b[^\n]{0,80}\b(?:is )?(?:not set|missing|required|must be set)\b/i, "missing environment variable"],
393
+ [
394
+ /\bmissing (?:required )?env(?:ironment)? (?:var(?:iable)?s?)\b/i,
395
+ "missing environment variable",
396
+ ],
397
+ [
398
+ /\benvironment variable\b[^\n]{0,80}\b(?:is )?(?:not set|missing|required|must be set)\b/i,
399
+ "missing environment variable",
400
+ ],
390
401
  [/\bprocess\.env\.[A-Z0-9_]+ is (?:undefined|not set)\b/, "missing environment variable"],
391
402
  [/\bSASL\b|\bSCRAM-SERVER\b/, "database auth failed (missing DB credentials?)"],
392
403
  [/\bpassword authentication failed\b/i, "database auth failed"],
@@ -395,6 +406,14 @@ const TEST_INFRA_PATTERNS = [
395
406
  [/\brelation "[^"]*" does not exist\b/i, "database schema missing (migrations not run?)"],
396
407
  [/\bauthentication (?:failed|error)\b/i, "authentication against a test dependency failed"],
397
408
  [/\b401 Unauthorized\b|\b403 Forbidden\b/i, "authorization against a test dependency failed"],
409
+ // A container image that would not come down is the registry, not the
410
+ // change (NMT-71: ghcr.io answered EOF to supabase start).
411
+ [
412
+ /\bfailed to pull (?:docker )?image\b|\bError response from daemon: (?:Get|Head|pull|manifest)\b|\bpull access denied\b|\btoomanyrequests\b/i,
413
+ "a container image could not be pulled (registry unreachable or rate-limited)",
414
+ ],
415
+ [/\bCannot connect to the Docker daemon\b/i, "Docker is not running"],
416
+ [/\bno space left on device\b/i, "the disk is full"],
398
417
  ];
399
418
  /** Strip a trailing `(4 ms)` / `(0.82ms)` duration off a failing-test name. */
400
419
  function stripDuration(name) {
@@ -507,7 +526,11 @@ export function classifyTestFailure(output, exitCode) {
507
526
  return {
508
527
  kind: "failures",
509
528
  findings: failures.map((f) => {
510
- const finding = { severity: "critical", lens: VERIFY_LENS, message: `verify: test failed: ${f.message}` };
529
+ const finding = {
530
+ severity: "critical",
531
+ lens: VERIFY_LENS,
532
+ message: `verify: test failed: ${f.message}`,
533
+ };
511
534
  if (f.file)
512
535
  finding.file = f.file;
513
536
  if (f.line)
@@ -564,7 +587,13 @@ export function parseVerifyFailures(output, exitCode, label) {
564
587
  if (seen.has(key))
565
588
  continue;
566
589
  seen.add(key);
567
- located.push({ severity: "critical", lens: VERIFY_LENS, message: `verify: ${message}`, file, line: lineNo });
590
+ located.push({
591
+ severity: "critical",
592
+ lens: VERIFY_LENS,
593
+ message: `verify: ${message}`,
594
+ file,
595
+ line: lineNo,
596
+ });
568
597
  if (located.length >= MAX_LOCATED_FINDINGS)
569
598
  break;
570
599
  }
@@ -720,7 +749,7 @@ export function newTreeEntries(before, after) {
720
749
  }
721
750
  function runGitQuiet(args, cwd) {
722
751
  return new Promise((resolve, reject) => {
723
- execFile("git", args, { cwd, maxBuffer: 1024 * 1024 }, (err) => (err ? reject(err) : resolve()));
752
+ execFile("git", args, { cwd, maxBuffer: 1024 * 1024 }, (err) => err ? reject(err) : resolve());
724
753
  });
725
754
  }
726
755
  /** Undo what the repository checks wrote: an untracked path is removed, a tracked one restored. */
@@ -797,7 +826,10 @@ const defaultExec = makeDefaultExec();
797
826
  */
798
827
  export function resolveClaimDirs(repoRoot, claims, readFile) {
799
828
  const probes = claims
800
- .map((c) => c.trim().replace(/^\.\/+/, "").replace(/\/+$/, ""))
829
+ .map((c) => c
830
+ .trim()
831
+ .replace(/^\.\/+/, "")
832
+ .replace(/\/+$/, ""))
801
833
  .filter((c) => c.length > 0 && c !== ".")
802
834
  .map((c) => `${c}/.claim`);
803
835
  return resolvePackageDirs(repoRoot, probes, readFile);
@@ -832,8 +864,10 @@ function tagFinding(finding, name) {
832
864
  * and produces no findings.
833
865
  */
834
866
  export function makeWorkstreamCheck(opts = {}) {
835
- const claimDirs = opts.claimDirs ?? ((cwd, claims) => resolveClaimDirs(cwd, claims, (p) => readFileSync(p, "utf8")));
836
- const detect = opts.detect ?? ((cwd, dirs) => detectVerifyCommands(cwd, { changedDirs: dirs }));
867
+ const claimDirs = opts.claimDirs ??
868
+ ((cwd, claims) => resolveClaimDirs(cwd, claims, (p) => readFileSync(p, "utf8")));
869
+ const detect = opts.detect ??
870
+ ((cwd, dirs) => detectVerifyCommands(cwd, { changedDirs: dirs }));
837
871
  const exec = opts.exec ?? defaultExec;
838
872
  const timeoutMs = opts.timeoutMs ?? VERIFY_TIMEOUT_MS;
839
873
  return async function runWorkstreamCheck(cwd, targets, signal) {
@@ -923,7 +957,8 @@ export function makeRunVerify(opts = {}) {
923
957
  allowRepoOverride: process.env.YAGNI_CODE_ALLOW_VERIFY_OVERRIDE === "1",
924
958
  changedDirs,
925
959
  }));
926
- const detectTests = opts.detectTests ?? ((cwd, changedDirs) => detectVerifyTestCommands(cwd, { changedDirs }));
960
+ const detectTests = opts.detectTests ??
961
+ ((cwd, changedDirs) => detectVerifyTestCommands(cwd, { changedDirs }));
927
962
  const changedDirs = opts.changedDirs ??
928
963
  (async (cwd, signal, baselinePaths) => {
929
964
  const snapshot = await snapshotWorkspace(cwd, signal);
@@ -951,7 +986,8 @@ export function makeRunVerify(opts = {}) {
951
986
  const path = process.env.YAGNI_TOOLCHAIN_FILE?.trim();
952
987
  return path ? readToolchainFile(path) : null;
953
988
  });
954
- const treeStatus = opts.treeStatus ?? (async (cwd, signal) => (await snapshotWorkspace(cwd, signal)).status);
989
+ const treeStatus = opts.treeStatus ??
990
+ (async (cwd, signal) => (await snapshotWorkspace(cwd, signal)).status);
955
991
  const undoTreeWrites = opts.undoTreeWrites ?? defaultUndoTreeWrites;
956
992
  // Across the whole build: the half's time spent, and each CI step's failure
957
993
  // keys from the last call it failed in.
@@ -992,19 +1028,29 @@ export function makeRunVerify(opts = {}) {
992
1028
  continue;
993
1029
  failedJobs.set(job, job.steps.length > 0
994
1030
  ? { name: job.failedCheck.name, status: "not_reached" }
995
- : { name: job.failedCheck.name, status: "cannot_run", reason: job.cannotRun[0]?.reason ?? "none of its steps can run in the sandbox" });
1031
+ : {
1032
+ name: job.failedCheck.name,
1033
+ status: "cannot_run",
1034
+ reason: job.cannotRun[0]?.reason ?? "none of its steps can run in the sandbox",
1035
+ });
996
1036
  }
997
1037
  const report = () => {
998
1038
  if (failedJobs.size === 0 && !file.failedChecksCannotRun?.length)
999
1039
  return;
1000
1040
  opts.onFailedChecks?.([
1001
1041
  ...failedJobs.values(),
1002
- ...(file.failedChecksCannotRun ?? []).map((failed) => ({ name: failed.name, status: "cannot_run", reason: failed.reason })),
1042
+ ...(file.failedChecksCannotRun ?? []).map((failed) => ({
1043
+ name: failed.name,
1044
+ status: "cannot_run",
1045
+ reason: failed.reason,
1046
+ })),
1003
1047
  ]);
1004
1048
  };
1005
1049
  if (cannotRun.length > 0) {
1006
1050
  const named = cannotRun.slice(0, MAX_NAMED_CANNOT_RUN).join("; ");
1007
- const more = cannotRun.length > MAX_NAMED_CANNOT_RUN ? `; and ${cannotRun.length - MAX_NAMED_CANNOT_RUN} more` : "";
1051
+ const more = cannotRun.length > MAX_NAMED_CANNOT_RUN
1052
+ ? `; and ${cannotRun.length - MAX_NAMED_CANNOT_RUN} more`
1053
+ : "";
1008
1054
  reasons.push(`could not run in the sandbox: ${named}${more}`);
1009
1055
  }
1010
1056
  const approved = file.checks.filter((check) => check.status !== "cannot_run");
@@ -1091,8 +1137,13 @@ export function makeRunVerify(opts = {}) {
1091
1137
  /** A failure's findings, located from the folder the command ran in and prefixed with what ran. */
1092
1138
  function repoFailureFindings(run, failure, label, prefix, dir) {
1093
1139
  const cls = classifyTestFailure(failure.output, failure.code);
1094
- const parsed = cls.kind === "failures" ? cls.findings : parseVerifyFailures(failure.output, failure.code, label);
1095
- return parsed.map((f) => ({ ...liftFinding(f, run.cwd, dir), message: `${prefix}: ${f.message}` }));
1140
+ const parsed = cls.kind === "failures"
1141
+ ? cls.findings
1142
+ : parseVerifyFailures(failure.output, failure.code, label);
1143
+ return parsed.map((f) => ({
1144
+ ...liftFinding(f, run.cwd, dir),
1145
+ message: `${prefix}: ${f.message}`,
1146
+ }));
1096
1147
  }
1097
1148
  const findingRoom = (run) => Math.max(0, MAX_LOCATED_FINDINGS - run.findings.length);
1098
1149
  /**
@@ -1171,7 +1222,9 @@ export function makeRunVerify(opts = {}) {
1171
1222
  }
1172
1223
  const where = `CI ${job.name}, step "${step.name}"`;
1173
1224
  const key = `${job.workflow}\u0000${job.job}\u0000${step.name}\u0000${step.run}`;
1174
- const dir = step.workingDirectory ? join(run.cwd, step.workingDirectory.replace(/^\.\/+/, "")) : run.cwd;
1225
+ const dir = step.workingDirectory
1226
+ ? join(run.cwd, step.workingDirectory.replace(/^\.\/+/, ""))
1227
+ : run.cwd;
1175
1228
  const verdict = await runRepoCommand(run, step.run, dir, step.env);
1176
1229
  if (verdict.kind === "passed") {
1177
1230
  lastCiFailure.delete(key);
@@ -1211,7 +1264,12 @@ export function makeRunVerify(opts = {}) {
1211
1264
  // choice of how to verify, so an override never takes them out of the loop.
1212
1265
  const repoFile = opts.repoChecks?.() ?? null;
1213
1266
  if (commands.length === 0 && testCommands.length === 0 && !repoFile) {
1214
- return { ran: false, ok: true, reason: "verify skipped: no verify command detected", findings: [] };
1267
+ return {
1268
+ ran: false,
1269
+ ok: true,
1270
+ reason: "verify skipped: no verify command detected",
1271
+ findings: [],
1272
+ };
1215
1273
  }
1216
1274
  const findings = [];
1217
1275
  const reasons = [];
@@ -1306,7 +1364,13 @@ export function makeRunVerify(opts = {}) {
1306
1364
  reasons.push("approved checks and CI steps skipped: the typecheck half failed; a later round runs them");
1307
1365
  }
1308
1366
  else {
1309
- const repo = await runRepoChecks({ file: repoFile, cwd, signal, baselinePaths, callStartedAt });
1367
+ const repo = await runRepoChecks({
1368
+ file: repoFile,
1369
+ cwd,
1370
+ signal,
1371
+ baselinePaths,
1372
+ callStartedAt,
1373
+ });
1310
1374
  reasons.push(...repo.reasons);
1311
1375
  repoLabels.push(...repo.labels);
1312
1376
  if (repo.labels.length > 0)
@@ -1317,9 +1381,19 @@ export function makeRunVerify(opts = {}) {
1317
1381
  // The command labels list only what produced a verdict — on every half —
1318
1382
  // so the FINISH trailer's `passed (<cmds>)` never claims a check that was
1319
1383
  // infra-skipped or threw (invariant §0.1).
1320
- const command = [...new Set(typecheckLabels), ...new Set(testLabels), ...new Set(repoLabels)].join(", ");
1384
+ const command = [
1385
+ ...new Set(typecheckLabels),
1386
+ ...new Set(testLabels),
1387
+ ...new Set(repoLabels),
1388
+ ].join(", ");
1321
1389
  if (!anyRan) {
1322
- return { ran: false, ok: true, command, reason: reasons.join("; ") || "verify skipped", findings: [] };
1390
+ return {
1391
+ ran: false,
1392
+ ok: true,
1393
+ command,
1394
+ reason: reasons.join("; ") || "verify skipped",
1395
+ findings: [],
1396
+ };
1323
1397
  }
1324
1398
  return {
1325
1399
  ran: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yagni-app/code-staging",
3
- "version": "1.2.6-staging.1918.1",
3
+ "version": "1.2.6-staging.1932.1",
4
4
  "description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
@@ -58,5 +58,5 @@
58
58
  "turndown": "^7.2.4",
59
59
  "typebox": "^1.3.15"
60
60
  },
61
- "yagniSourceSha": "569bc8a477a2b04062d6422d40cd28bd5a09f182"
61
+ "yagniSourceSha": "15297691a28134646f9295adea6f7744d70e392f"
62
62
  }