@mjasnikovs/pi-task 0.40.50 → 0.41.0
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/README.md +7 -4
- package/dist/config/config.d.ts +61 -18
- package/dist/config/config.js +50 -6
- package/dist/config/register.js +18 -5
- package/dist/shared/content-tokens.d.ts +16 -0
- package/dist/shared/content-tokens.js +137 -0
- package/dist/task/accept-debt.d.ts +15 -1
- package/dist/task/accept-debt.js +4 -0
- package/dist/task/artifact-closure.js +7 -1
- package/dist/task/auto-io.d.ts +59 -7
- package/dist/task/auto-io.js +140 -47
- package/dist/task/auto-orchestrator.d.ts +22 -19
- package/dist/task/auto-orchestrator.js +126 -112
- package/dist/task/child-runner.d.ts +18 -0
- package/dist/task/child-runner.js +7 -8
- package/dist/task/command-run.d.ts +4 -0
- package/dist/task/command-run.js +4 -2
- package/dist/task/constraint-policy.d.ts +52 -0
- package/dist/task/constraint-policy.js +66 -0
- package/dist/task/context-silence.d.ts +5 -4
- package/dist/task/context-silence.js +13 -5
- package/dist/task/coverage-loop.d.ts +7 -4
- package/dist/task/coverage-loop.js +16 -138
- package/dist/task/debug-log.d.ts +25 -2
- package/dist/task/debug-log.js +64 -10
- package/dist/task/decompose-fidelity.d.ts +17 -4
- package/dist/task/decompose-fidelity.js +95 -55
- package/dist/task/decompose-granularity.d.ts +7 -7
- package/dist/task/decompose-granularity.js +8 -8
- package/dist/task/env-notes.d.ts +65 -19
- package/dist/task/env-notes.js +152 -50
- package/dist/task/external-context.js +25 -5
- package/dist/task/fix-context.d.ts +39 -0
- package/dist/task/fix-context.js +58 -0
- package/dist/task/gate-deps.d.ts +49 -0
- package/dist/task/gate-deps.js +199 -38
- package/dist/task/gate-evidence.d.ts +51 -0
- package/dist/task/gate-evidence.js +90 -0
- package/dist/task/gate-resolution.d.ts +119 -0
- package/dist/task/gate-resolution.js +120 -0
- package/dist/task/git-state-guard.js +3 -26
- package/dist/task/handoff.d.ts +35 -0
- package/dist/task/handoff.js +100 -0
- package/dist/task/health-baseline.d.ts +87 -0
- package/dist/task/health-baseline.js +158 -0
- package/dist/task/ledger.d.ts +10 -0
- package/dist/task/ledger.js +22 -11
- package/dist/task/lint-fix.d.ts +11 -0
- package/dist/task/lint-fix.js +14 -8
- package/dist/task/loop-detector.d.ts +52 -3
- package/dist/task/loop-detector.js +81 -5
- package/dist/task/mentions.d.ts +17 -0
- package/dist/task/mentions.js +86 -0
- package/dist/task/orchestrator.d.ts +53 -9
- package/dist/task/orchestrator.js +104 -28
- package/dist/task/orientation.d.ts +135 -29
- package/dist/task/orientation.js +259 -67
- package/dist/task/owned-freeze-reassign.d.ts +7 -3
- package/dist/task/owned-freeze-reassign.js +13 -5
- package/dist/task/parsers.d.ts +6 -1
- package/dist/task/parsers.js +21 -4
- package/dist/task/phases.d.ts +1 -1
- package/dist/task/phases.js +125 -153
- package/dist/task/plan-orchestrator.js +5 -6
- package/dist/task/plan-rounds.d.ts +1 -0
- package/dist/task/plan-rounds.js +8 -1
- package/dist/task/prohibition-probe.d.ts +6 -1
- package/dist/task/prohibition-probe.js +26 -6
- package/dist/task/prompts.js +13 -2
- package/dist/task/qa-transcript.d.ts +17 -0
- package/dist/task/qa-transcript.js +28 -0
- package/dist/task/question-source.d.ts +16 -2
- package/dist/task/question-source.js +21 -8
- package/dist/task/repo-health-check.d.ts +27 -0
- package/dist/task/repo-health-check.js +39 -5
- package/dist/task/requirements.d.ts +67 -13
- package/dist/task/requirements.js +129 -67
- package/dist/task/research-worker.d.ts +43 -2
- package/dist/task/research-worker.js +103 -8
- package/dist/task/run-bracket.d.ts +9 -4
- package/dist/task/run-bracket.js +9 -0
- package/dist/task/run-context.d.ts +152 -0
- package/dist/task/run-context.js +277 -0
- package/dist/task/spec-doc.d.ts +78 -0
- package/dist/task/spec-doc.js +205 -0
- package/dist/task/spec-model.d.ts +70 -0
- package/dist/task/spec-model.js +139 -0
- package/dist/task/stall-detector.d.ts +1 -1
- package/dist/task/stall-detector.js +9 -5
- package/dist/task/state-dir.d.ts +29 -0
- package/dist/task/state-dir.js +80 -0
- package/dist/task/suppression-probe.d.ts +67 -0
- package/dist/task/suppression-probe.js +78 -0
- package/dist/task/task-gates.d.ts +39 -57
- package/dist/task/task-gates.js +115 -195
- package/dist/task/task-io.d.ts +10 -0
- package/dist/task/task-io.js +69 -18
- package/dist/task/task-parsers.js +6 -6
- package/dist/task/task-types.d.ts +7 -0
- package/dist/task/timings.d.ts +11 -0
- package/dist/task/timings.js +21 -0
- package/dist/task/tree-hash.d.ts +8 -0
- package/dist/task/tree-hash.js +55 -0
- package/dist/task/verify-reconcile.d.ts +4 -3
- package/dist/task/verify-reconcile.js +7 -8
- package/dist/task/verify-resolution.d.ts +28 -5
- package/dist/task/verify-resolution.js +70 -13
- package/dist/task/verify-work.d.ts +98 -35
- package/dist/task/verify-work.js +227 -60
- package/dist/task/yolo.d.ts +0 -13
- package/dist/task/yolo.js +9 -21
- package/dist/workers/pi-worker-core.d.ts +20 -0
- package/dist/workers/pi-worker-core.js +16 -11
- package/dist/workers/pi-worker-docs.d.ts +6 -5
- package/dist/workers/pi-worker-docs.js +8 -7
- package/dist/workers/pi-worker-fetch.d.ts +3 -2
- package/dist/workers/pi-worker-fetch.js +5 -4
- package/dist/workers/pi-worker-search.js +5 -4
- package/dist/workers/research-cache.d.ts +23 -1
- package/dist/workers/research-cache.js +63 -3
- package/dist/workers/shared.d.ts +18 -0
- package/dist/workers/shared.js +38 -22
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped rows. Each `re` is a LINE test, so a pattern that appears inside a
|
|
3
|
+
* string literal or a comment still counts — the point is the suppression's
|
|
4
|
+
* presence in the shipped file, and deciding what is "really" a suppression would
|
|
5
|
+
* need a parser per language to answer worse.
|
|
6
|
+
*/
|
|
7
|
+
export const SUPPRESSION_PATTERNS = [
|
|
8
|
+
{ id: '@ts-expect-error', re: /@ts-expect-error/, ecosystems: ['npm'] },
|
|
9
|
+
{ id: '@ts-ignore', re: /@ts-ignore/, ecosystems: ['npm'] },
|
|
10
|
+
{ id: 'eslint-disable', re: /eslint-disable/, ecosystems: ['npm'] },
|
|
11
|
+
{ id: 'as unknown as', re: /\bas\s+unknown\s+as\b/, ecosystems: ['npm'] },
|
|
12
|
+
{ id: '#[allow(', re: /#\[allow\(/, ecosystems: ['cargo'] },
|
|
13
|
+
{ id: '# noqa', re: /#\s*noqa\b/i },
|
|
14
|
+
{ id: '# type: ignore', re: /#\s*type:\s*ignore\b/ },
|
|
15
|
+
{ id: '//nolint', re: /\/\/\s*nolint\b/, ecosystems: ['go'] },
|
|
16
|
+
{ id: '@SuppressWarnings', re: /@SuppressWarnings\b/ },
|
|
17
|
+
{ id: '#pragma warning disable', re: /#pragma\s+warning\s+disable\b/ }
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Compile the extra patterns a project configures. An unparseable source is
|
|
21
|
+
* dropped rather than thrown: a hand-edited config may not break the gate, and a
|
|
22
|
+
* pattern nobody can compile finds nothing either way.
|
|
23
|
+
*/
|
|
24
|
+
export function compileSuppressionPatterns(sources) {
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const source of sources) {
|
|
27
|
+
try {
|
|
28
|
+
out.push({ id: source, re: new RegExp(source) });
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// an invalid regex is a config defect, not a gate failure
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
/** The rows in force for a project: the shipped ones its ecosystems claim, plus
|
|
37
|
+
* every configured one (a user pattern is never ecosystem-gated — they wrote it
|
|
38
|
+
* for this repo). */
|
|
39
|
+
export function suppressionPatternsFor(ecosystems, extra = []) {
|
|
40
|
+
const shipped = SUPPRESSION_PATTERNS.filter(p => !p.ecosystems
|
|
41
|
+
|| ecosystems.length === 0
|
|
42
|
+
|| p.ecosystems.some(e => ecosystems.includes(e)));
|
|
43
|
+
return [...shipped, ...extra];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Net-new suppressions per file and pattern, in a stable order (file, then
|
|
47
|
+
* registry order) so two runs over the same diff produce the same findings.
|
|
48
|
+
*/
|
|
49
|
+
export function findSuppressionWidening(lines, patterns = SUPPRESSION_PATTERNS) {
|
|
50
|
+
// Keyed by path then pattern rather than by a joined string: any separator
|
|
51
|
+
// would have to be a character no path can contain, and `\0` — the honest
|
|
52
|
+
// choice — is a byte prettier rewrites and plain grep cannot see.
|
|
53
|
+
const byPath = new Map();
|
|
54
|
+
const hits = [];
|
|
55
|
+
for (const line of lines) {
|
|
56
|
+
for (const pattern of patterns) {
|
|
57
|
+
if (!pattern.re.test(line.text))
|
|
58
|
+
continue;
|
|
59
|
+
let byPattern = byPath.get(line.path);
|
|
60
|
+
if (!byPattern) {
|
|
61
|
+
byPattern = new Map();
|
|
62
|
+
byPath.set(line.path, byPattern);
|
|
63
|
+
}
|
|
64
|
+
let hit = byPattern.get(pattern.id);
|
|
65
|
+
if (!hit) {
|
|
66
|
+
hit = { path: line.path, patternId: pattern.id, net: 0 };
|
|
67
|
+
byPattern.set(pattern.id, hit);
|
|
68
|
+
hits.push(hit);
|
|
69
|
+
}
|
|
70
|
+
hit.net += line.added ? 1 : -1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return hits.filter(h => h.net > 0).sort((a, b) => a.path.localeCompare(b.path));
|
|
74
|
+
}
|
|
75
|
+
/** The verify prompt's finding lines for the suppression-widening row. */
|
|
76
|
+
export function suppressionVerifyFindings(hits) {
|
|
77
|
+
return hits.map(h => `${h.path} — ${h.net} net-new \`${h.patternId}\` line${h.net === 1 ? '' : 's'} added by this task`);
|
|
78
|
+
}
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* just-finished work:
|
|
7
7
|
*
|
|
8
8
|
* 1. VERIFY — RUN the composed spec's VERIFY block in the real workspace and
|
|
9
|
-
* judge a PASS/FAIL.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* judge a PASS/FAIL. A FAIL goes to gate-resolution.ts's decision table,
|
|
10
|
+
* which returns one of three actions: re-run the implementation turn
|
|
11
|
+
* UNATTENDED and loop back, accept the artifact and write the defect to the
|
|
12
|
+
* debt ledger, or show the user the boxed picker. This module owns none of
|
|
13
|
+
* that policy — it only carries the actions out.
|
|
14
14
|
* 2. ENFORCE — hold the committed work to the project's AGENTS.md / CLAUDE.md
|
|
15
15
|
* rules. Runs in `edit` mode (fix in place) only when the verify gate produced
|
|
16
16
|
* a genuine clean pass to guard the edits against; otherwise `flag` mode
|
|
@@ -34,8 +34,11 @@ import type { CommitResult } from './auto-commit.js';
|
|
|
34
34
|
import { type VerifyOutcome } from './verify-work.js';
|
|
35
35
|
import type { EnforceOutcome } from './enforce-guidelines.js';
|
|
36
36
|
import { type ResolutionOutcome, type ResolutionChoice } from './verify-resolution.js';
|
|
37
|
+
import { type HealthBaseline, type HealthSignal } from './health-baseline.js';
|
|
38
|
+
import type { LintFixResult } from './lint-fix.js';
|
|
37
39
|
import { type RepairCandidate } from './root-cause-repair.js';
|
|
38
40
|
import { type DebtOrigin } from './accept-debt.js';
|
|
41
|
+
import type { FixContext } from './fix-context.js';
|
|
39
42
|
/**
|
|
40
43
|
* The deps the gate sequence drives. A superset of these is built once per command
|
|
41
44
|
* by buildGateDeps; AutoDeps extends this with the planning-only `runChild`. Every
|
|
@@ -53,7 +56,9 @@ export interface GateDeps {
|
|
|
53
56
|
resumeId?: string;
|
|
54
57
|
onStart?: (taskId: string) => void | Promise<void>;
|
|
55
58
|
planContext?: string;
|
|
56
|
-
|
|
59
|
+
planKey?: string;
|
|
60
|
+
fixContext?: FixContext;
|
|
61
|
+
healthBaseline?: (ctx: ExtensionCommandContext) => Promise<HealthBaseline | null>;
|
|
57
62
|
}) => Promise<RunSingleTaskResult>;
|
|
58
63
|
/** Snapshot the working tree into one commit after a task passes. */
|
|
59
64
|
commit: (cwd: string, message: string) => Promise<CommitResult>;
|
|
@@ -80,9 +85,10 @@ export interface GateDeps {
|
|
|
80
85
|
*/
|
|
81
86
|
enforce?: (ctx: ExtensionCommandContext, cwd: string, taskTitle: string, mode: 'edit' | 'flag') => Promise<EnforceOutcome>;
|
|
82
87
|
/**
|
|
83
|
-
* After a verify FAIL, research whether
|
|
84
|
-
*
|
|
85
|
-
*
|
|
88
|
+
* After a verify FAIL, research whether the work is genuinely wrong (AUTOFIX),
|
|
89
|
+
* good as-is (ACCEPT), or blocked by a contradiction in its own spec. One input
|
|
90
|
+
* to the decision table, which alone decides what happens next. Absent → the
|
|
91
|
+
* table sees the conservative AUTOFIX default.
|
|
86
92
|
*/
|
|
87
93
|
recommend?: (ctx: ExtensionCommandContext, cwd: string, taskTitle: string, taskId: string, failReason: string) => Promise<ResolutionOutcome>;
|
|
88
94
|
/**
|
|
@@ -96,13 +102,11 @@ export interface GateDeps {
|
|
|
96
102
|
* exactly the static findings (revert-guarded — see lint-fix.ts), instead of the
|
|
97
103
|
* full implementation re-run AUTOFIX reaches for. Smallest tool first: a static
|
|
98
104
|
* finding does not need the whole turn re-run to fix it. Runs at most once per
|
|
99
|
-
* gate sequence;
|
|
100
|
-
*
|
|
105
|
+
* gate sequence; a `frozen-path` result mints the SpecContradiction that ends
|
|
106
|
+
* the loop, anything else falls through to the decision table unchanged. Absent
|
|
107
|
+
* → the loop goes straight to the judge and the table.
|
|
101
108
|
*/
|
|
102
|
-
lintFix?: (ctx: ExtensionCommandContext, cwd: string, taskTitle: string, taskId: string, failReason: string) => Promise<
|
|
103
|
-
ok: boolean;
|
|
104
|
-
reason?: string;
|
|
105
|
-
}>;
|
|
109
|
+
lintFix?: (ctx: ExtensionCommandContext, cwd: string, taskTitle: string, taskId: string, failReason: string) => Promise<LintFixResult>;
|
|
106
110
|
/**
|
|
107
111
|
* Deterministic whole-repo static check (repo-health), used as the PRE-COMMIT
|
|
108
112
|
* gate on an edit-mode enforce pass: an enforce edit that breaks the project's
|
|
@@ -118,7 +122,16 @@ export interface GateDeps {
|
|
|
118
122
|
ok: boolean;
|
|
119
123
|
reason: string;
|
|
120
124
|
output?: string;
|
|
121
|
-
}>;
|
|
125
|
+
} & HealthSignal>;
|
|
126
|
+
/**
|
|
127
|
+
* Record what the same static checks say about the tree RIGHT NOW, as the
|
|
128
|
+
* baseline a later verify differential attributes against (health-baseline.ts).
|
|
129
|
+
* Called where the tree is committed and the task has not started — the
|
|
130
|
+
* `/task-auto` pre-task checkpoint, and `/task`'s own start. Null when the
|
|
131
|
+
* capture could not run; absent in tests → no baseline is written and the
|
|
132
|
+
* verify gate establishes one lazily.
|
|
133
|
+
*/
|
|
134
|
+
captureHealthBaseline?: (ctx: ExtensionCommandContext, cwd: string, label: string) => Promise<HealthBaseline | null>;
|
|
122
135
|
/** Does the working tree hold changes (excluding .pi-tasks)? Lets the pre-commit
|
|
123
136
|
* health check run only when the enforce pass actually edited something. */
|
|
124
137
|
dirty?: (cwd: string) => Promise<boolean>;
|
|
@@ -140,12 +153,13 @@ export interface GateDeps {
|
|
|
140
153
|
* see accept-debt.ts), stamped with the DebtOrigin that says how it was reached.
|
|
141
154
|
* The final integration gate re-checks every recorded debt at run end and surfaces
|
|
142
155
|
* the ones still open, so a defect the gate found is never lost by whatever the
|
|
143
|
-
* loop then did with the WORK — accepted by a human ('accepted'),
|
|
144
|
-
* unattended by yolo mode ('yolo-accepted'),
|
|
145
|
-
* ('enforce-revert'), kept because the enforce
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* pre-existing bug this one merely
|
|
156
|
+
* loop then did with the WORK — accepted by a human ('accepted'), dismissed at
|
|
157
|
+
* the picker ('dismissed'), accepted unattended by yolo mode ('yolo-accepted'),
|
|
158
|
+
* reverted with the enforce commit ('enforce-revert'), kept because the enforce
|
|
159
|
+
* diff could not have caused it ('enforce-kept'), unreachable under the task's
|
|
160
|
+
* own spec ('spec-contradiction'), a sibling's deliverable deleted and accepted
|
|
161
|
+
* ('cross-task-deletion'), or another task's pre-existing bug this one merely
|
|
162
|
+
* tripped over ('root-cause').
|
|
149
163
|
*
|
|
150
164
|
* The ORIGIN is load-bearing, not a label: the final gate reports by class, and
|
|
151
165
|
* an unattended auto-pick may never be recorded as the 'accepted' class, which
|
|
@@ -261,38 +275,6 @@ export type GateResult = {
|
|
|
261
275
|
ctx: ExtensionCommandContext;
|
|
262
276
|
reason?: string;
|
|
263
277
|
};
|
|
264
|
-
/**
|
|
265
|
-
* How many times a verify FAIL may be auto-fixed UNATTENDED (the research
|
|
266
|
-
* recommended AUTOFIX, so pi re-runs the impl turn without prompting) before the
|
|
267
|
-
* loop falls back to the human picker. Each AUTOFIX is a full implementation
|
|
268
|
-
* re-run, so a non-converging loop must not run forever with nobody able to break
|
|
269
|
-
* it — after this many consecutive auto attempts that still FAIL, the picker is
|
|
270
|
-
* shown so a person can decide. A recommendation to ACCEPT always shows the picker
|
|
271
|
-
* regardless of this count (blessing an artifact as-is is a human's call).
|
|
272
|
-
*/
|
|
273
|
-
export declare const MAX_AUTO_AUTOFIX = 3;
|
|
274
|
-
/** Which of the four disjoint branches sent a FAIL to the terminal YOLO ACCEPT. */
|
|
275
|
-
export interface YoloAcceptContext {
|
|
276
|
-
/** Rule 5c: the spec-required check could not run (tooling absent). */
|
|
277
|
-
isUnobserved: boolean;
|
|
278
|
-
/** Cross-task contradiction: the repo-health fix needs a spec-frozen path. */
|
|
279
|
-
isFrozenBlocked: boolean;
|
|
280
|
-
/** What the resolution research recommended, when it was consulted at all. */
|
|
281
|
-
recommend: ResolutionOutcome['recommend'];
|
|
282
|
-
/** Unattended AUTOFIX attempts already spent on this task. */
|
|
283
|
-
autoFixCount: number;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* The reason an auto-ACCEPT is being written — NAMED, not assumed.
|
|
287
|
-
*
|
|
288
|
-
* Four disjoint branches reach the terminal auto-ACCEPT, and only ONE of them has
|
|
289
|
-
* spent the autofix budget. An UNOBSERVED FAIL never consults the research; a
|
|
290
|
-
* frozen-blocked one is a contradiction no re-run can resolve; an ACCEPT
|
|
291
|
-
* recommendation can arrive with the budget untouched. A single "autofix budget
|
|
292
|
-
* spent" line would be false on three of the four, and a durable trail that
|
|
293
|
-
* misstates why a defect shipped reads as an exhausted fixer that never tried.
|
|
294
|
-
*/
|
|
295
|
-
export declare function yoloAcceptReason(c: YoloAcceptContext): string;
|
|
296
278
|
/**
|
|
297
279
|
* Show the boxed two-choice picker after a verify FAIL and return what the user
|
|
298
280
|
* decided. The model-recommended card is placed first so the renderer tints it
|
|
@@ -340,9 +322,9 @@ type VerifyGateStep = {
|
|
|
340
322
|
};
|
|
341
323
|
/**
|
|
342
324
|
* The VERIFY resolution loop: run the task's verification against the finished
|
|
343
|
-
* work, and
|
|
344
|
-
*
|
|
345
|
-
* or terminates.
|
|
325
|
+
* work, and carry out what gate-resolution.ts's decision table says to do with a
|
|
326
|
+
* FAIL (bounded lint fix first, then the table's autofix / accept / ask) until it
|
|
327
|
+
* verifies, is accepted, or terminates.
|
|
346
328
|
*
|
|
347
329
|
* Split from `runGatesForTask` at the single boolean that crosses to the ENFORCE
|
|
348
330
|
* half (`cleanPass`). This loop has four terminal exits and carries the whole
|