@ikunin/sprintpilot 2.2.23 → 2.2.24
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.
|
@@ -1461,22 +1461,21 @@ function cmdStart(opts) {
|
|
|
1461
1461
|
);
|
|
1462
1462
|
}
|
|
1463
1463
|
if (profile.lint_enabled) {
|
|
1464
|
-
//
|
|
1465
|
-
//
|
|
1466
|
-
//
|
|
1464
|
+
// v2.2.24: lint_enabled wires verifyDevGreen → post-green-gates.js
|
|
1465
|
+
// (lint-changed + lint-test-pitfalls + ci-parity scan). lint_blocking
|
|
1466
|
+
// governs whether a failed gate halts the autopilot or passes
|
|
1467
|
+
// through with a warning. The v2.2.23 "not wired" warning is gone —
|
|
1468
|
+
// lint runs for real now.
|
|
1467
1469
|
ledger.append(
|
|
1468
1470
|
{
|
|
1469
1471
|
kind: 'state_transition',
|
|
1470
1472
|
detail: {
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
+
lint_enabled: true,
|
|
1474
|
+
lint_blocking: !!profile.lint_blocking,
|
|
1473
1475
|
},
|
|
1474
1476
|
},
|
|
1475
1477
|
{ projectRoot },
|
|
1476
1478
|
);
|
|
1477
|
-
process.stderr.write(
|
|
1478
|
-
'[autopilot] WARN git.lint.enabled=true but no LINT_CHECK phase exists yet (planned for v2.3.0). Bake lint into your test command for now.\n',
|
|
1479
|
-
);
|
|
1480
1479
|
}
|
|
1481
1480
|
|
|
1482
1481
|
// Worktree health check — once per session, after lock acquire so we
|
|
@@ -1647,7 +1646,7 @@ function cmdRecord(opts) {
|
|
|
1647
1646
|
profile.enabled === false && stateMachine.shouldSkipVerifyWhenGitDisabled(runtime.phase);
|
|
1648
1647
|
let verifyResult;
|
|
1649
1648
|
if (signal.status === 'success' && !isGitDisabledPhase) {
|
|
1650
|
-
verifyResult = verifyMod.verify(runtime, signal.output, { projectRoot });
|
|
1649
|
+
verifyResult = verifyMod.verify(runtime, signal.output, { projectRoot, profile });
|
|
1651
1650
|
ledger.append(
|
|
1652
1651
|
{ kind: 'verify_result', phase: runtime.phase, ok: verifyResult.ok, issues: verifyResult.issues || [] },
|
|
1653
1652
|
{ projectRoot },
|
|
@@ -1656,7 +1655,7 @@ function cmdRecord(opts) {
|
|
|
1656
1655
|
verifyResult = verifyMod.verifyWithOverride(
|
|
1657
1656
|
runtime,
|
|
1658
1657
|
signal.output || {},
|
|
1659
|
-
{ projectRoot },
|
|
1658
|
+
{ projectRoot, profile },
|
|
1660
1659
|
signal.evidence || {},
|
|
1661
1660
|
);
|
|
1662
1661
|
ledger.append(
|
|
@@ -164,6 +164,54 @@ function autoDetectTestFiles(ctx, baseBranch) {
|
|
|
164
164
|
return out;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
// Invoke scripts/post-green-gates.js when profile.lint_enabled is true.
|
|
168
|
+
// Returns null when:
|
|
169
|
+
// - profile.lint_enabled is false / absent (feature opt-out)
|
|
170
|
+
// - the script is missing (partial install)
|
|
171
|
+
// - projectRoot is unset
|
|
172
|
+
// Returns { failed: bool, summary?: string } on a real run.
|
|
173
|
+
//
|
|
174
|
+
// The script's contract: exit 0 = all gates pass, exit !=0 = at least
|
|
175
|
+
// one gate failed. JSON report on stdout when invoked with --json (we
|
|
176
|
+
// pass that flag). Failure summary captured for the issue message.
|
|
177
|
+
function runPostGreenGates(ctx) {
|
|
178
|
+
if (!ctx || !ctx.profile || !ctx.profile.lint_enabled) return null;
|
|
179
|
+
if (!ctx.projectRoot) return null;
|
|
180
|
+
const scriptRel = nodePath.join('_Sprintpilot', 'scripts', 'post-green-gates.js');
|
|
181
|
+
const scriptAbs = nodePath.join(ctx.projectRoot, scriptRel);
|
|
182
|
+
let fs;
|
|
183
|
+
try {
|
|
184
|
+
fs = ctx.fs || nodeFs;
|
|
185
|
+
if (!fs.existsSync(scriptAbs)) return null;
|
|
186
|
+
} catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const cp = require('node:child_process');
|
|
190
|
+
try {
|
|
191
|
+
const r = cp.spawnSync(
|
|
192
|
+
'node',
|
|
193
|
+
[scriptAbs, '--json', '--project-root', ctx.projectRoot],
|
|
194
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 120_000 },
|
|
195
|
+
);
|
|
196
|
+
if (r.status === 0) return { failed: false };
|
|
197
|
+
// Try to extract a brief summary from the JSON output. Fall back
|
|
198
|
+
// to the exit code if parsing fails.
|
|
199
|
+
let summary = `exit ${r.status}`;
|
|
200
|
+
try {
|
|
201
|
+
const parsed = JSON.parse(r.stdout || '{}');
|
|
202
|
+
if (parsed && parsed.failed_gate) summary = `failed_gate=${parsed.failed_gate}`;
|
|
203
|
+
if (parsed && parsed.first_issue) summary += `: ${parsed.first_issue}`;
|
|
204
|
+
} catch {
|
|
205
|
+
/* keep exit-code summary */
|
|
206
|
+
}
|
|
207
|
+
return { failed: true, summary };
|
|
208
|
+
} catch (_e) {
|
|
209
|
+
// Script crashed (e.g. ENOENT for node). Treat as non-failing —
|
|
210
|
+
// the lint phase should not gate the autopilot on its own bugs.
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
167
215
|
// Probe the underlying git state to confirm a STORY_DONE signal whose
|
|
168
216
|
// `git_steps_completed` flag was omitted. Returns true iff:
|
|
169
217
|
// - commit_sha resolves locally (git cat-file -e <sha>)
|
|
@@ -227,6 +275,7 @@ function verify(state, signalOutput, context) {
|
|
|
227
275
|
runner: (context && context.runner) || null,
|
|
228
276
|
projectRoot: (context && context.projectRoot) || '.',
|
|
229
277
|
augmented: (context && context.augmented) || null,
|
|
278
|
+
profile: (context && context.profile) || null,
|
|
230
279
|
};
|
|
231
280
|
const out = signalOutput || {};
|
|
232
281
|
// Effective state: fall forward to signal.output for identity fields
|
|
@@ -381,6 +430,20 @@ function verifyDevGreen(state, out, ctx) {
|
|
|
381
430
|
issues.push('tests_run must be a positive number (per AGENTS.md test-result format)');
|
|
382
431
|
}
|
|
383
432
|
}
|
|
433
|
+
// Post-GREEN gates: lint-changed + lint-test-pitfalls + ci-parity scan.
|
|
434
|
+
// Composed pipeline lives in scripts/post-green-gates.js. Only fires
|
|
435
|
+
// when profile.lint_enabled === true. Blocking vs non-blocking
|
|
436
|
+
// governed by profile.lint_blocking. Pre-2.2.24 the script existed
|
|
437
|
+
// and was documented as "called by the orchestrator after GREEN
|
|
438
|
+
// verify" but nothing actually invoked it.
|
|
439
|
+
const lintResult = runPostGreenGates(ctx);
|
|
440
|
+
if (lintResult) {
|
|
441
|
+
if (lintResult.failed && (ctx.profile && ctx.profile.lint_blocking)) {
|
|
442
|
+
issues.push(
|
|
443
|
+
`post-green-gates failed (lint_blocking=true): ${lintResult.summary || 'see ledger detail'}`,
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
384
447
|
return { ok: issues.length === 0, issues };
|
|
385
448
|
}
|
|
386
449
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikunin/sprintpilot",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.24",
|
|
4
4
|
"description": "Sprintpilot — autopilot and multi-agent addon for BMad Method v6: git workflow, parallel agents, autonomous story execution",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|