@yagni-app/code-staging 1.2.8-staging.2073.1 → 1.2.9-staging.2082.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.
- package/dist/extension/pipeline/cloud.d.ts +10 -1
- package/dist/extension/pipeline/cloud.js +30 -0
- package/dist/extension/pipeline/continuation.d.ts +16 -5
- package/dist/extension/pipeline/continuation.js +19 -6
- package/dist/extension/pipeline/verify.d.ts +19 -0
- package/dist/extension/pipeline/verify.js +106 -5
- package/package.json +2 -2
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* lives (`packages/shared/src/attempts.ts`): the two meet only at this JSON.
|
|
17
17
|
*/
|
|
18
18
|
import type { ContinuationStage } from "./continuation.js";
|
|
19
|
-
import type
|
|
19
|
+
import { type VerifyCheckRun, type VerifyOutcome } from "./verify.js";
|
|
20
20
|
import type { WorktreeExec } from "./worktree.js";
|
|
21
21
|
import type { Finding, PipelineLane, PipelineResult, StopReason } from "./types.js";
|
|
22
22
|
/** Set on every stage child of a cloud session, so its prompt describes the cloud sandbox. */
|
|
@@ -152,6 +152,15 @@ export declare function ticketOfBranch(branch: string | null): string | undefine
|
|
|
152
152
|
export declare function attemptCommitted(cwd: string, exec: WorktreeExec, attemptId: string): Promise<boolean | null>;
|
|
153
153
|
/** Read the execution's work off git. Never throws: a read that fails is a note. */
|
|
154
154
|
export declare function gitFacts(cwd: string, exec: WorktreeExec, baseSha: string): Promise<GitFacts>;
|
|
155
|
+
/**
|
|
156
|
+
* The checks that gave no verdict because the sandbox could not run them,
|
|
157
|
+
* each with why, as one sentence for the person who reads the result: no
|
|
158
|
+
* change to the code makes them run, so the loop never held the change on
|
|
159
|
+
* them. A check only not run on this tree (its budget spent, the build
|
|
160
|
+
* stopped first, its note {@link CHECK_NOT_RUN_NOTE}) is not one: another run
|
|
161
|
+
* could give it a verdict. Null when no check could not run. Pure.
|
|
162
|
+
*/
|
|
163
|
+
export declare function cannotRunNote(checks: readonly VerifyCheckRun[]): string | null;
|
|
155
164
|
/** What the session's last act needs, gathered once the pipeline has stopped. */
|
|
156
165
|
export interface CloudCompletion {
|
|
157
166
|
identity: CloudIdentity;
|
|
@@ -22,6 +22,7 @@ import { planTitle, runFinish, verifyTrailerValue } from "./finish.js";
|
|
|
22
22
|
import { buildPlanFile, planMarkdown } from "./planOutput.js";
|
|
23
23
|
import { cloudLane } from "./stages.js";
|
|
24
24
|
import { applyStageTiers, parseStageTiers, STAGE_TIERS_ENV } from "./tierCap.js";
|
|
25
|
+
import { CHECK_NOT_RUN_NOTE } from "./verify.js";
|
|
25
26
|
/** Set on every stage child of a cloud session, so its prompt describes the cloud sandbox. */
|
|
26
27
|
export const CLOUD_SESSION_ENV = "YAGNI_GO_CLOUD";
|
|
27
28
|
/** Where the session writes `plan.md`, `plan.json` and `result.json`. */
|
|
@@ -235,6 +236,32 @@ export async function gitFacts(cwd, exec, baseSha) {
|
|
|
235
236
|
notes,
|
|
236
237
|
};
|
|
237
238
|
}
|
|
239
|
+
/** Checks the cannot-run note names before "and N more". */
|
|
240
|
+
const MAX_NAMED_CANNOT_RUN = 5;
|
|
241
|
+
/**
|
|
242
|
+
* The checks that gave no verdict because the sandbox could not run them,
|
|
243
|
+
* each with why, as one sentence for the person who reads the result: no
|
|
244
|
+
* change to the code makes them run, so the loop never held the change on
|
|
245
|
+
* them. A check only not run on this tree (its budget spent, the build
|
|
246
|
+
* stopped first, its note {@link CHECK_NOT_RUN_NOTE}) is not one: another run
|
|
247
|
+
* could give it a verdict. Null when no check could not run. Pure.
|
|
248
|
+
*/
|
|
249
|
+
export function cannotRunNote(checks) {
|
|
250
|
+
const unrun = checks.filter((check) => check.baseline === "cannot_run" &&
|
|
251
|
+
check.exitCode === null &&
|
|
252
|
+
!(check.note ?? "").startsWith(CHECK_NOT_RUN_NOTE));
|
|
253
|
+
if (unrun.length === 0)
|
|
254
|
+
return null;
|
|
255
|
+
const named = unrun.slice(0, MAX_NAMED_CANNOT_RUN).map((check) => {
|
|
256
|
+
const cause = (check.note ?? "")
|
|
257
|
+
.split("; `")[0]
|
|
258
|
+
.replace(/^could not run(?: in the sandbox)?:?\s*/, "")
|
|
259
|
+
.trim();
|
|
260
|
+
return `\`${check.name}\` (${cause || "could not run"})`;
|
|
261
|
+
});
|
|
262
|
+
const more = unrun.length - named.length;
|
|
263
|
+
return `No change to the code can make ${unrun.length === 1 ? "this check" : "these checks"} run here, so ${unrun.length === 1 ? "it was" : "they were"} never a finding to fix and gave no verdict on this change: ${named.join("; ")}${more > 0 ? `; and ${more} more` : ""}.`;
|
|
264
|
+
}
|
|
238
265
|
/** A finding as the result dedupes it: where it is and what it says. */
|
|
239
266
|
function findingKey(finding) {
|
|
240
267
|
return `${finding.file ?? ""}:${finding.line ?? ""}:${finding.message}`;
|
|
@@ -312,6 +339,9 @@ export async function completeCloudSession(c, ran) {
|
|
|
312
339
|
notes.push(`The checks could not run on the final tree: ${err instanceof Error ? err.message : String(err)}`);
|
|
313
340
|
}
|
|
314
341
|
}
|
|
342
|
+
const unrun = cannotRunNote(checks?.checks ?? []);
|
|
343
|
+
if (unrun)
|
|
344
|
+
notes.push(unrun);
|
|
315
345
|
// The loop judged the tree it last verified; what the final scan or checks
|
|
316
346
|
// found blocking in the tree being committed means it did not stop clean.
|
|
317
347
|
if (stop === "clean" && extra.some(isBlockingFinding)) {
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* run's own change (an implement that only confirms finished work is not
|
|
11
11
|
* `no_changes`, and the verify gate scopes to the whole diff against HEAD);
|
|
12
12
|
* - an attempt that stopped in review, fix or verify re-enters the review→fix
|
|
13
|
-
* loop at the next round,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* loop at the next round, but never on the lane's last, so its review is
|
|
14
|
+
* always followed by a fix pass, through the same `resume_loop` seam a
|
|
15
|
+
* resumed interactive run uses. An attempt that stopped in implement (or
|
|
16
|
+
* before) runs implement again on the approved plan.
|
|
16
17
|
*
|
|
17
18
|
* The file is the host's contract, so anything unreadable is refused here and
|
|
18
19
|
* the caller runs a normal mission instead of crashing.
|
|
@@ -58,11 +59,21 @@ export declare function continuesInLoop(continuation: ContinuationInputs): boole
|
|
|
58
59
|
* the same design context.
|
|
59
60
|
*/
|
|
60
61
|
export declare function continuationReviewInput(continuation: ContinuationInputs, mission: MissionInputs | undefined, committed?: boolean): string;
|
|
62
|
+
/**
|
|
63
|
+
* The round a continuation re-enters the loop at: the earlier attempt's count
|
|
64
|
+
* goes on, but never onto the lane's last round, so the review it starts
|
|
65
|
+
* with is always followed by one fix pass before the cap can stop it. A
|
|
66
|
+
* resume onto the cap reviewed, hit the cap and stopped `round_cap` without a
|
|
67
|
+
* fix: COREX-1291's eight fix sessions (continue.json `roundsDone: 4` on the
|
|
68
|
+
* cloud lane's four rounds) each ran one review and changed nothing. A lane of
|
|
69
|
+
* one round has no fix pass to give. Pure.
|
|
70
|
+
*/
|
|
71
|
+
export declare function continuationRound(reviewRoundsDone: number, maxRounds: number): number;
|
|
61
72
|
/**
|
|
62
73
|
* The resume plan that re-enters the review→fix loop for a continuation that
|
|
63
74
|
* stopped in review, fix or verify; undefined when implement must run again.
|
|
64
|
-
*
|
|
65
|
-
*
|
|
75
|
+
* Its round is {@link continuationRound}'s, so a continuation always gets a
|
|
76
|
+
* review and a fix pass for what that review finds. `committed` is the cloud
|
|
66
77
|
* lane's resume, whose earlier work is on the branch.
|
|
67
78
|
*/
|
|
68
79
|
export declare function continuationResumePlan(continuation: ContinuationInputs, ctx: {
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* run's own change (an implement that only confirms finished work is not
|
|
11
11
|
* `no_changes`, and the verify gate scopes to the whole diff against HEAD);
|
|
12
12
|
* - an attempt that stopped in review, fix or verify re-enters the review→fix
|
|
13
|
-
* loop at the next round,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* loop at the next round, but never on the lane's last, so its review is
|
|
14
|
+
* always followed by a fix pass, through the same `resume_loop` seam a
|
|
15
|
+
* resumed interactive run uses. An attempt that stopped in implement (or
|
|
16
|
+
* before) runs implement again on the approved plan.
|
|
16
17
|
*
|
|
17
18
|
* The file is the host's contract, so anything unreadable is refused here and
|
|
18
19
|
* the caller runs a normal mission instead of crashing.
|
|
@@ -95,11 +96,23 @@ export function continuationReviewInput(continuation, mission, committed = false
|
|
|
95
96
|
const design = missionDesignContext(mission);
|
|
96
97
|
return design ? `${summary}\n\n${design}` : summary;
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* The round a continuation re-enters the loop at: the earlier attempt's count
|
|
101
|
+
* goes on, but never onto the lane's last round, so the review it starts
|
|
102
|
+
* with is always followed by one fix pass before the cap can stop it. A
|
|
103
|
+
* resume onto the cap reviewed, hit the cap and stopped `round_cap` without a
|
|
104
|
+
* fix: COREX-1291's eight fix sessions (continue.json `roundsDone: 4` on the
|
|
105
|
+
* cloud lane's four rounds) each ran one review and changed nothing. A lane of
|
|
106
|
+
* one round has no fix pass to give. Pure.
|
|
107
|
+
*/
|
|
108
|
+
export function continuationRound(reviewRoundsDone, maxRounds) {
|
|
109
|
+
return Math.max(1, Math.min(reviewRoundsDone + 1, maxRounds - 1));
|
|
110
|
+
}
|
|
98
111
|
/**
|
|
99
112
|
* The resume plan that re-enters the review→fix loop for a continuation that
|
|
100
113
|
* stopped in review, fix or verify; undefined when implement must run again.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
114
|
+
* Its round is {@link continuationRound}'s, so a continuation always gets a
|
|
115
|
+
* review and a fix pass for what that review finds. `committed` is the cloud
|
|
103
116
|
* lane's resume, whose earlier work is on the branch.
|
|
104
117
|
*/
|
|
105
118
|
export function continuationResumePlan(continuation, ctx, opts = {}) {
|
|
@@ -107,7 +120,7 @@ export function continuationResumePlan(continuation, ctx, opts = {}) {
|
|
|
107
120
|
return undefined;
|
|
108
121
|
return {
|
|
109
122
|
mode: "resume_loop",
|
|
110
|
-
round:
|
|
123
|
+
round: continuationRound(continuation.reviewRoundsDone, opts.maxRounds ?? MAX_REVIEW_ROUNDS),
|
|
111
124
|
reviewInput: continuationReviewInput(continuation, ctx.mission, opts.committed),
|
|
112
125
|
priorRounds: [],
|
|
113
126
|
ticket: ctx.ticket,
|
|
@@ -300,6 +300,25 @@ export declare function detectVerifyTestCommands(cwd: string, opts?: DetectOpts)
|
|
|
300
300
|
* verify failure.
|
|
301
301
|
*/
|
|
302
302
|
export declare function classifyVerifyInfraFailure(output: string, exitCode: number): string | null;
|
|
303
|
+
/**
|
|
304
|
+
* Why a repository check gave no verdict when the paths it reads are not
|
|
305
|
+
* there: `diff` against a log an earlier plan step writes, `grep` in a folder
|
|
306
|
+
* named from the wrong root (COREX-1291: `diff: /tmp/fym-baseline-tsc.log:
|
|
307
|
+
* No such file or directory`, exit 2, eight fix sessions burned on it). The
|
|
308
|
+
* comparison never ran, so the check says nothing of the code, and a fix
|
|
309
|
+
* turn cannot make it run. Null when the output names no such path, when the
|
|
310
|
+
* tool that said so is not one the command runs (a test's own output), when
|
|
311
|
+
* a missing path is one this change touched (a file it deleted, a folder it
|
|
312
|
+
* made): that is the change's to put back, or when the rest of the output
|
|
313
|
+
* carries a located diagnostic (a compound check whose other half failed for
|
|
314
|
+
* real): the missing path is then not the whole story, and the check stays
|
|
315
|
+
* the change's failure. Pure.
|
|
316
|
+
*/
|
|
317
|
+
export declare function classifyMissingInput(command: string, output: string, at: {
|
|
318
|
+
repoRoot: string;
|
|
319
|
+
dir: string;
|
|
320
|
+
changedPaths?: readonly string[];
|
|
321
|
+
}): string | null;
|
|
303
322
|
/**
|
|
304
323
|
* What a run could not start without, when its output says so in a way the
|
|
305
324
|
* gate recognises: a credential or variable the environment lacks, or a
|
|
@@ -541,6 +541,87 @@ export function classifyVerifyInfraFailure(output, exitCode) {
|
|
|
541
541
|
}
|
|
542
542
|
return null;
|
|
543
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Tools whose "No such file or directory" names a path the check reads (or,
|
|
546
|
+
* for `tee`, writes into): the comparison or search never ran.
|
|
547
|
+
*/
|
|
548
|
+
const PATH_READING_TOOLS = new Set("awk cat cmp comm cut diff egrep fgrep find grep head jq ls rg sed sort stat tail tee wc".split(" "));
|
|
549
|
+
/**
|
|
550
|
+
* A tool's own line for a path that is not there, GNU's and BSD's: `diff:
|
|
551
|
+
* /tmp/a.log: No such file or directory`, `ls: cannot access 'x': No such
|
|
552
|
+
* file or directory`, `awk: cannot open x (No such file or directory)`.
|
|
553
|
+
*/
|
|
554
|
+
const MISSING_PATH_LINE = /^(?:\S*\/)?([a-z][\w-]*):\s+(.*?)\s*[:(]?\s*No such file or directory\b/;
|
|
555
|
+
/** What a tool says before the path it could not open. */
|
|
556
|
+
const MISSING_PATH_VERB = /^(?:(?:error|fatal):\s*)?(?:(?:cannot|can't|could not|couldn't|unable to)\s+(?:access|open|read|stat|statx)(?:\s+file)?:?\s+|IO error for operation on\s+)/i;
|
|
557
|
+
/** Missing paths a cause names before "and N more". */
|
|
558
|
+
const MAX_NAMED_MISSING_PATHS = 3;
|
|
559
|
+
/** The path in what a tool said about it, or null when it names none plainly. */
|
|
560
|
+
function missingPathIn(what) {
|
|
561
|
+
const quoted = [...what.matchAll(/[`'"‘]([^`'"’\n]+)[`'"’]/g)].at(-1)?.[1]?.trim();
|
|
562
|
+
if (quoted)
|
|
563
|
+
return quoted;
|
|
564
|
+
for (const segment of what.replace(MISSING_PATH_VERB, "").split(/:\s+/)) {
|
|
565
|
+
const path = segment.replace(/\s+for reading$/, "").trim();
|
|
566
|
+
if (path && !/\s/.test(path))
|
|
567
|
+
return path;
|
|
568
|
+
}
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
/** True when `tool` is a command the shell line runs, not a word in an argument. */
|
|
572
|
+
function commandRuns(command, tool) {
|
|
573
|
+
return new RegExp(`(?:^|[\\s;&|(!{\`])(?:\\S*/)?${tool}(?=[\\s;&|)]|$)`).test(command);
|
|
574
|
+
}
|
|
575
|
+
/** Two repo-relative paths are one, or one holds the other. */
|
|
576
|
+
function pathsOverlap(a, b) {
|
|
577
|
+
const x = a.replace(/\/+$/, "");
|
|
578
|
+
const y = b.replace(/\/+$/, "");
|
|
579
|
+
return x === y || x.startsWith(`${y}/`) || y.startsWith(`${x}/`);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Why a repository check gave no verdict when the paths it reads are not
|
|
583
|
+
* there: `diff` against a log an earlier plan step writes, `grep` in a folder
|
|
584
|
+
* named from the wrong root (COREX-1291: `diff: /tmp/fym-baseline-tsc.log:
|
|
585
|
+
* No such file or directory`, exit 2, eight fix sessions burned on it). The
|
|
586
|
+
* comparison never ran, so the check says nothing of the code, and a fix
|
|
587
|
+
* turn cannot make it run. Null when the output names no such path, when the
|
|
588
|
+
* tool that said so is not one the command runs (a test's own output), when
|
|
589
|
+
* a missing path is one this change touched (a file it deleted, a folder it
|
|
590
|
+
* made): that is the change's to put back, or when the rest of the output
|
|
591
|
+
* carries a located diagnostic (a compound check whose other half failed for
|
|
592
|
+
* real): the missing path is then not the whole story, and the check stays
|
|
593
|
+
* the change's failure. Pure.
|
|
594
|
+
*/
|
|
595
|
+
export function classifyMissingInput(command, output, at) {
|
|
596
|
+
const missing = new Map();
|
|
597
|
+
const rest = [];
|
|
598
|
+
for (const raw of output.split("\n")) {
|
|
599
|
+
const match = MISSING_PATH_LINE.exec(raw.trim());
|
|
600
|
+
const tool = match?.[1];
|
|
601
|
+
if (!match || !tool || !PATH_READING_TOOLS.has(tool) || !commandRuns(command, tool)) {
|
|
602
|
+
rest.push(raw);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
const path = missingPathIn(match[2] ?? "");
|
|
606
|
+
if (!path)
|
|
607
|
+
continue;
|
|
608
|
+
const repoPath = relative(at.repoRoot, isAbsolutePath(path) ? path : join(at.dir, path)) || ".";
|
|
609
|
+
const inRepo = repoPath !== ".." && !repoPath.startsWith("../") && !isAbsolutePath(repoPath);
|
|
610
|
+
if (inRepo && (at.changedPaths ?? []).some((changed) => pathsOverlap(changed, repoPath))) {
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
missing.set(inRepo ? repoPath : path, inRepo);
|
|
614
|
+
}
|
|
615
|
+
if (missing.size === 0)
|
|
616
|
+
return null;
|
|
617
|
+
if (parseVerifyFailures(rest.join("\n"), 1, command).some((finding) => finding.file))
|
|
618
|
+
return null;
|
|
619
|
+
const named = [...missing]
|
|
620
|
+
.slice(0, MAX_NAMED_MISSING_PATHS)
|
|
621
|
+
.map(([path, inRepo]) => (inRepo ? path : `${path} (outside the repository)`));
|
|
622
|
+
const more = missing.size - named.length;
|
|
623
|
+
return `${missing.size === 1 ? "a path it reads does not exist" : "paths it reads do not exist"}: ${named.join(", ")}${more > 0 ? ` and ${more} more` : ""}`;
|
|
624
|
+
}
|
|
544
625
|
/**
|
|
545
626
|
* Test-half infra/environment patterns (spec §3d): failure shapes that mean the
|
|
546
627
|
* ENVIRONMENT could not run the suite — a DB that is not up, a missing env var,
|
|
@@ -1502,7 +1583,8 @@ export function makeRunVerify(opts = {}) {
|
|
|
1502
1583
|
* The repository-checks half: the plan's approved checks, then the pull
|
|
1503
1584
|
* request's CI steps its changed paths trigger. A failure becomes `critical`
|
|
1504
1585
|
* findings the fix turn works on, except where it can never clear: a check
|
|
1505
|
-
* the sandbox cannot start, an infra failure,
|
|
1586
|
+
* the sandbox cannot start, an infra failure, a path the check reads that is
|
|
1587
|
+
* not there ({@link classifyMissingInput}), an approved check that already
|
|
1506
1588
|
* failed on the unchanged code (the host compares it after the build), and a
|
|
1507
1589
|
* CI step that fails exactly as it did before a fix turn (it may fail on the
|
|
1508
1590
|
* base too, and the pull request's CI shows it). Those are notes.
|
|
@@ -1599,6 +1681,7 @@ export function makeRunVerify(opts = {}) {
|
|
|
1599
1681
|
approvedFailed: new Set(),
|
|
1600
1682
|
checks: [],
|
|
1601
1683
|
approvedRuns: new Map(),
|
|
1684
|
+
changedPaths: paths,
|
|
1602
1685
|
};
|
|
1603
1686
|
const before = await treeStatus(cwd, signal).catch((err) => {
|
|
1604
1687
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1688,8 +1771,21 @@ export function makeRunVerify(opts = {}) {
|
|
|
1688
1771
|
}
|
|
1689
1772
|
const output = scrubSecrets(rawOutput);
|
|
1690
1773
|
const cls = classifyTestFailure(output, code, MAX_LOCATED_FINDINGS, env);
|
|
1691
|
-
|
|
1692
|
-
|
|
1774
|
+
// A path the check reads that is not there (a log an earlier plan step
|
|
1775
|
+
// writes, a folder named from the wrong root) gave no verdict either,
|
|
1776
|
+
// unless the check passed on the unchanged code: then the change lost it.
|
|
1777
|
+
// One already failing on the base is a note as it is, its record kept.
|
|
1778
|
+
const cause = cls.kind === "infra" && !(cls.needs && check.passedOnBase)
|
|
1779
|
+
? cls.reason
|
|
1780
|
+
: cls.kind === "uncertain" && check.baseline === "runnable" && !check.passedOnBase
|
|
1781
|
+
? classifyMissingInput(command, output, {
|
|
1782
|
+
repoRoot: run.cwd,
|
|
1783
|
+
dir,
|
|
1784
|
+
changedPaths: run.changedPaths,
|
|
1785
|
+
})
|
|
1786
|
+
: null;
|
|
1787
|
+
if (cause) {
|
|
1788
|
+
const reason = `could not run: ${cause}`;
|
|
1693
1789
|
const entry = record("cannot_run", `${reason}; ${exitSummary(check.name, code, output)}`);
|
|
1694
1790
|
opts.onCheck?.(checkEnded(entry, output));
|
|
1695
1791
|
return { kind: "note", reason };
|
|
@@ -2370,8 +2466,13 @@ export function makeMeasureChecksOnBase(opts = {}) {
|
|
|
2370
2466
|
}
|
|
2371
2467
|
const output = scrubSecrets(rawOutput);
|
|
2372
2468
|
const cls = classifyTestFailure(output, code, Number.POSITIVE_INFINITY, env);
|
|
2373
|
-
|
|
2374
|
-
|
|
2469
|
+
const cause = cls.kind === "infra"
|
|
2470
|
+
? cls.reason
|
|
2471
|
+
: cls.kind === "uncertain"
|
|
2472
|
+
? classifyMissingInput(check.command, output, { repoRoot: cwd, dir: cwd })
|
|
2473
|
+
: null;
|
|
2474
|
+
if (cause) {
|
|
2475
|
+
result.notes.push(`\`${label}\`: could not run: ${cause}`);
|
|
2375
2476
|
continue;
|
|
2376
2477
|
}
|
|
2377
2478
|
const found = repoCommandFindings({ output, code, env }, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagni-app/code-staging",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9-staging.2082.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": "
|
|
61
|
+
"yagniSourceSha": "aa51aeb734fe374a2b12c82a0680729e2bf5c4d1"
|
|
62
62
|
}
|