@mjasnikovs/pi-task 0.38.15 → 0.38.17

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.
Files changed (86) hide show
  1. package/dist/config/config.d.ts +26 -0
  2. package/dist/config/config.js +68 -17
  3. package/dist/shared/child-process.js +9 -16
  4. package/dist/task/accept-debt.d.ts +7 -5
  5. package/dist/task/accept-debt.js +18 -14
  6. package/dist/task/artifact-closure.js +18 -63
  7. package/dist/task/auto-orchestrator.js +211 -218
  8. package/dist/task/autofix-ledger.d.ts +113 -0
  9. package/dist/task/autofix-ledger.js +152 -0
  10. package/dist/task/boot-probe.d.ts +109 -1
  11. package/dist/task/boot-probe.js +139 -23
  12. package/dist/task/child-runner.d.ts +50 -6
  13. package/dist/task/child-runner.js +48 -69
  14. package/dist/task/command-run.d.ts +49 -6
  15. package/dist/task/command-run.js +154 -18
  16. package/dist/task/coverage-loop.d.ts +11 -0
  17. package/dist/task/coverage-loop.js +16 -0
  18. package/dist/task/external-context.d.ts +9 -12
  19. package/dist/task/external-context.js +5 -5
  20. package/dist/task/failure-classifier.d.ts +9 -1
  21. package/dist/task/failure-classifier.js +9 -0
  22. package/dist/task/final-gate-fix.d.ts +22 -26
  23. package/dist/task/final-gate-fix.js +16 -31
  24. package/dist/task/final-gate.d.ts +10 -2
  25. package/dist/task/final-gate.js +55 -89
  26. package/dist/task/fix-child.d.ts +64 -0
  27. package/dist/task/fix-child.js +66 -0
  28. package/dist/task/gate-deps.js +20 -13
  29. package/dist/task/lint-fix.d.ts +7 -0
  30. package/dist/task/lint-fix.js +45 -9
  31. package/dist/task/orchestrator.d.ts +33 -24
  32. package/dist/task/orchestrator.js +75 -46
  33. package/dist/task/phases.d.ts +120 -34
  34. package/dist/task/phases.js +221 -134
  35. package/dist/task/plan-orchestrator.js +2 -2
  36. package/dist/task/plan-rounds.d.ts +86 -0
  37. package/dist/task/plan-rounds.js +105 -0
  38. package/dist/task/plan-session.d.ts +31 -21
  39. package/dist/task/plan-session.js +97 -120
  40. package/dist/task/qa-transcript.d.ts +100 -0
  41. package/dist/task/qa-transcript.js +99 -0
  42. package/dist/task/question-source.d.ts +117 -0
  43. package/dist/task/question-source.js +174 -0
  44. package/dist/task/repo-health-check.d.ts +21 -21
  45. package/dist/task/repo-health-check.js +43 -112
  46. package/dist/task/run-end.d.ts +77 -0
  47. package/dist/task/run-end.js +37 -0
  48. package/dist/task/run-final-gate.js +71 -79
  49. package/dist/task/serve-entry.js +6 -57
  50. package/dist/task/shipped-source.d.ts +67 -0
  51. package/dist/task/shipped-source.js +144 -0
  52. package/dist/task/task-gates.d.ts +9 -1
  53. package/dist/task/task-gates.js +27 -6
  54. package/dist/task/terminal-outcome.d.ts +1 -1
  55. package/dist/task/terminal-outcome.js +12 -0
  56. package/dist/task/verify-work.d.ts +46 -0
  57. package/dist/task/verify-work.js +51 -3
  58. package/dist/workers/brave-search.d.ts +7 -0
  59. package/dist/workers/brave-search.js +36 -55
  60. package/dist/workers/ddg-search.d.ts +1 -1
  61. package/dist/workers/ddg-search.js +27 -47
  62. package/dist/workers/docs-core.d.ts +71 -1
  63. package/dist/workers/docs-core.js +131 -71
  64. package/dist/workers/exa-search.d.ts +2 -2
  65. package/dist/workers/exa-search.js +53 -68
  66. package/dist/workers/html-clean.js +67 -88
  67. package/dist/workers/http-request.d.ts +74 -0
  68. package/dist/workers/http-request.js +103 -0
  69. package/dist/workers/npm-version.js +37 -42
  70. package/dist/workers/pi-worker-core.d.ts +13 -2
  71. package/dist/workers/pi-worker-core.js +35 -25
  72. package/dist/workers/pi-worker-docs.d.ts +1 -1
  73. package/dist/workers/pi-worker-docs.js +49 -68
  74. package/dist/workers/pi-worker-fetch.d.ts +1 -1
  75. package/dist/workers/pi-worker-fetch.js +20 -21
  76. package/dist/workers/pi-worker-search.js +6 -4
  77. package/dist/workers/pi-worker.js +5 -4
  78. package/dist/workers/search-core.d.ts +1 -1
  79. package/dist/workers/search-core.js +36 -42
  80. package/dist/workers/search-types.d.ts +13 -0
  81. package/dist/workers/search-types.js +27 -0
  82. package/dist/workers/shared.d.ts +51 -11
  83. package/dist/workers/shared.js +0 -0
  84. package/dist/workers/worker-channels.d.ts +60 -0
  85. package/dist/workers/worker-channels.js +98 -0
  86. package/package.json +1 -1
@@ -3,12 +3,7 @@
3
3
  * critique) plus the config table that drives the orchestrator loop.
4
4
  */
5
5
  import type { ExtensionCommandContext } from '@earendil-works/pi-coding-agent';
6
- import { docsFocused } from '../workers/docs-core.js';
7
- import { fetchFocused } from '../workers/fetch-core.js';
8
- import { type RunWorkerInput, type RunWorkerResult } from '../workers/pi-worker-core.js';
9
- import type { SearchCoreInput, SearchCoreResult } from '../workers/search-core.js';
10
- import type { SearchProvider } from '../workers/search-types.js';
11
- import { type ExternalContextDeps } from './external-context.js';
6
+ import { type SearchProvider } from '../workers/search-types.js';
12
7
  import { MAX_GRILL_QUESTIONS } from './prompts.js';
13
8
  import { type PhaseName } from './task-types.js';
14
9
  import { type WidgetState } from './widget.js';
@@ -38,7 +33,34 @@ export interface PhaseConfig {
38
33
  name: PhaseName;
39
34
  section: string;
40
35
  field: OutputField;
36
+ /**
37
+ * The pure, idempotent transform this phase performs on `PhaseContext` fields
38
+ * OTHER than its own `field` — the phase's CARRY. Mutates `pc` and returns the
39
+ * trail lines the decision produced; it performs no I/O of its own.
40
+ *
41
+ * A carry runs on BOTH arms of the orchestrator loop: before `run` on the live
42
+ * path, and in place of `run` on the resume path. That is the whole point. A
43
+ * row's `section` is what resume restores from disk, and it restores exactly
44
+ * ONE field — so a phase that settles a second field and does not declare it
45
+ * here silently loses that work on every resume past it. Compose is the case
46
+ * that matters: it drops constraints research REFUTED from `refined`, critique
47
+ * re-reads `refined` as GROUND TRUTH under a prompt that says CONSTRAINTS "MUST
48
+ * be preserved", and `## refined prompt` on disk is deliberately left as refine
49
+ * wrote it. A resume at critique used to hand the refuted constraint straight
50
+ * back — the mx5 run-19 defect, restored by the very machinery that closed it.
51
+ *
52
+ * The trail is returned rather than written so the replay cannot duplicate a
53
+ * gate line the live run already recorded.
54
+ */
55
+ carry?: (deps: PhaseDeps, pc: PhaseContext) => Promise<string[]>;
41
56
  run: (deps: PhaseDeps, pc: PhaseContext) => Promise<string>;
57
+ /**
58
+ * What this phase must do once its output is PERSISTED — after the section
59
+ * write, so a fault here cannot lose the output. A row field rather than a
60
+ * `phase.name !== 'refine'` test inside one function, so the compiler can tell
61
+ * you which rows have a post-commit effect.
62
+ */
63
+ postCommit?: (deps: PhaseDeps, pc: PhaseContext, out: string) => Promise<void>;
42
64
  }
43
65
  /** Extract the TOOLING section commands from a research output string. */
44
66
  export declare function extractToolingCommands(research: string): string[] | null;
@@ -101,29 +123,9 @@ export declare function resolveOwnedFreezeForThisTask(deps: PhaseDeps, spec: str
101
123
  export declare function claimOwnedFreezeForThisTask(deps: PhaseDeps, refined: string): Promise<void>;
102
124
  export declare const phaseRefine: (deps: PhaseDeps, raw: string, planContext?: string) => Promise<string>;
103
125
  export declare function phaseVerifyTooling(deps: PhaseDeps, research: string): Promise<string>;
104
- export interface PhaseResearchDeps extends ExternalContextDeps {
105
- getFileInventory?: (cwd: string, signal?: AbortSignal) => Promise<string>;
106
- /**
107
- * Run ONE research worker. Absent (production) → the real `runWorker`.
108
- *
109
- * The seam exists for the same reason `getFileInventory` does: every decision
110
- * `runSpec` makes — the three Research retry gates, the fatal/runaway/empty
111
- * classification, the marker choice, `postProcess` — is a pure function of the
112
- * returned `RunWorkerResult`, but reaching any of them used to require driving
113
- * a fake process that emits JSON events. Substituting the result lets a gate be
114
- * tested by the fields it actually reads.
115
- *
116
- * `label` is the worker's name — the same one `recordWorker` trails. It is
117
- * passed because a substitute must answer differently per worker, and the only
118
- * alternative is matching a marker sentence inside the prompt, which makes
119
- * prompt copy load-bearing test infrastructure. Same reason
120
- * `PhaseDeps.runChild` takes a name.
121
- */
122
- runWorker?: (label: string, input: RunWorkerInput) => Promise<RunWorkerResult>;
123
- }
124
126
  /**
125
127
  * Is live web search configured for this process? The keyless providers (exa,
126
- * ddg) always are; only brave needs its API key — mirrors search-core's lookup.
128
+ * ddg) always are; only brave needs its API key.
127
129
  */
128
130
  export declare function searchConfigured(getEnv?: (k: string) => string | undefined, provider?: SearchProvider): boolean;
129
131
  /** Extra prompt block for the APIS worker when search is available — trigger-framed
@@ -177,13 +179,8 @@ export declare function degradedSectionBody(name: string, reason: string, partia
177
179
  */
178
180
  export declare function emptySectionBody(name: string): string;
179
181
  export declare function isBareNoneAnswer(text: string): boolean;
180
- export declare function phaseResearch(deps: PhaseDeps, refined: string, researchDeps?: PhaseResearchDeps): Promise<string>;
181
- export interface PhaseAutoAnswerDeps {
182
- docsFocused?: typeof docsFocused;
183
- fetchFocused?: typeof fetchFocused;
184
- searchFn?: (input: SearchCoreInput) => Promise<SearchCoreResult>;
185
- }
186
- export declare function phaseAutoAnswer(deps: PhaseDeps, refined: string, research: string, question: string, autoDeps?: PhaseAutoAnswerDeps): Promise<AutoAnswer>;
182
+ export declare function phaseResearch(deps: PhaseDeps, refined: string): Promise<string>;
183
+ export declare function phaseAutoAnswer(deps: PhaseDeps, refined: string, research: string, question: string): Promise<AutoAnswer>;
187
184
  export declare function phaseGrill(deps: PhaseDeps, ctx: ExtensionCommandContext, widgetState: WidgetState, refined: string, research: string): Promise<string>;
188
185
  /**
189
186
  * A refutation is a DELETION. Where the run's own research explicitly says a
@@ -206,6 +203,17 @@ export declare function phaseGrill(deps: PhaseDeps, ctx: ExtensionCommandContext
206
203
  * STEP 0 `scripts/refuted-constraint-baserate.ts`; A/B-1 `…-ab.ts` (PASS).
207
204
  */
208
205
  export declare function dropRefutedConstraints(deps: PhaseDeps, refined: string, research: string): Promise<string>;
206
+ /**
207
+ * COMPOSE's carry: the refutation drop, as a `PhaseConfig.carry`.
208
+ *
209
+ * Same transform as `dropRefutedConstraints` over the same pure core, minus the
210
+ * recording — the caller decides whether this application is the live one or a
211
+ * resume replay. `dropRefutedConstraints` stays exported and unchanged for the
212
+ * harnesses under `scripts/` that drive the drop directly.
213
+ */
214
+ export declare function composeCarry(_deps: PhaseDeps, pc: PhaseContext): Promise<string[]>;
215
+ /** Write a carry's trail to the debug log and the task file's `## gates` section. */
216
+ export declare function recordPhaseTrail(deps: PhaseDeps, phaseName: string, trail: string[]): Promise<void>;
209
217
  export declare function phaseCompose(deps: PhaseDeps, refined: string, research: string, qa: string): Promise<string>;
210
218
  export declare function phaseCritique(deps: PhaseDeps, spec: string, refined: string, qa: string, planContext?: string, research?: string,
211
219
  /**
@@ -220,5 +228,83 @@ export declare function phaseCritique(deps: PhaseDeps, spec: string, refined: st
220
228
  */
221
229
  extraDefects?: string | null): Promise<string>;
222
230
  export declare function critiqueWithFallback(d: PhaseDeps, p: PhaseContext): Promise<string>;
231
+ /**
232
+ * REFINE — restate the raw prompt as a bounded 4-section spec, then subtractively
233
+ * strike any phantom runtime specifier (`bun:sql`) it carried up verbatim from the
234
+ * spec doc, BEFORE it flows to research/grill/compose. An appended correction alone
235
+ * loses: the affirmative survives into the composed GOAL and on to the implementer
236
+ * (proven: compose re-leaks it 4/4). Rewriting the source so compose has nothing to
237
+ * contradict is the fix. Silent + no-op when nothing is wrong or the runtime's types
238
+ * aren't installed.
239
+ */
240
+ export declare function refinePhase(d: PhaseDeps, p: PhaseContext): Promise<string>;
241
+ /**
242
+ * RESEARCH — the four workers, then the TOOLING verification pass, then a
243
+ * deterministic check of every runtime builtin specifier the refined task names
244
+ * (`bun:sql`, `node:…`) against the installed types. A doc can confidently name a
245
+ * module that does not exist; left unchecked it rides through every phase and the
246
+ * implementer fabricates a `declare module` shim to compile it. The corrections are
247
+ * APPENDED so compose folds them into CONSTRAINTS. No LLM cost, silent when clean.
248
+ */
249
+ export declare function researchPhase(d: PhaseDeps, p: PhaseContext): Promise<string>;
250
+ /** GRILL — the adaptive question loop, and the only phase that talks to the user. */
251
+ export declare function grillPhase(d: PhaseDeps, p: PhaseContext): Promise<string>;
252
+ /**
253
+ * COMPOSE — compose the spec from the refined task, the research and the Q&A.
254
+ *
255
+ * The refutation drop that must happen first is compose's declared `carry`
256
+ * (`composeCarry`), not a line at the top of this function. It settles `p.refined`,
257
+ * which is not compose's own `field`, so the orchestrator has to replay it on the
258
+ * resume path too — and a `run` body cannot be replayed.
259
+ */
260
+ export declare function composePhase(d: PhaseDeps, p: PhaseContext): Promise<string>;
261
+ /**
262
+ * CRITIQUE — the last spec-producing step, and the two host-side corrections that
263
+ * must run after it in THIS ORDER.
264
+ *
265
+ * BRACES (mx5 run 16): append any owned design obligation the spec still omits as a
266
+ * CONSTRAINTS bullet. The belt block upstream is obeyed ~25% (measured); a host-side
267
+ * append is obeyed by construction. Idempotent — quotes the spec already carries
268
+ * (belt-obeying reps) are skipped.
269
+ *
270
+ * Then DETACH: an owned obligation whose only file this spec also FREEZES is
271
+ * unsatisfiable here, so it moves to the pending task that writes that file rather
272
+ * than shipping a requirement no one can meet. It MUST run after the append, because
273
+ * the append is what writes the stamp the detach reads — a critique-time probe
274
+ * measured 0/40 because the stamp did not exist yet.
275
+ */
276
+ export declare function critiquePhase(d: PhaseDeps, p: PhaseContext): Promise<string>;
277
+ /**
278
+ * The pipeline, as a table with no bodies.
279
+ *
280
+ * Every row's `run` is a named exported function, so the COMPOSITION inside a
281
+ * step — which is where this codebase's recorded phase defects have lived, not in
282
+ * the parts — is drivable directly instead of only through a whole TaskRunner run.
283
+ * The parts stay exported and separately covered; what changed is that the ORDER
284
+ * they run in is now asserted by driving the row rather than retyped in a test.
285
+ */
223
286
  export declare const PHASES: PhaseConfig[];
287
+ /**
288
+ * Run one phase row the way the orchestrator does: carry, then run.
289
+ *
290
+ * The row is the interface, so this is the surface a row-driving test crosses —
291
+ * calling `row.run` alone tests past it and would not have caught a carry that the
292
+ * resume path drops. The orchestrator adds only persistence, timings and the
293
+ * checkpoint around this.
294
+ */
295
+ export declare function runPhaseRow(row: PhaseConfig, deps: PhaseDeps, pc: PhaseContext): Promise<string>;
296
+ /**
297
+ * Re-apply one phase row's carry on the RESUME path, where `run` is skipped.
298
+ *
299
+ * The trail is discarded: the live run that produced this phase's output already
300
+ * recorded it on `## gates`, and a replay must not append a second copy.
301
+ */
302
+ export declare function replayPhaseCarry(row: PhaseConfig, deps: PhaseDeps, pc: PhaseContext): Promise<void>;
303
+ /** Dispatch a row's declared post-commit effect. Rows with none do nothing. */
224
304
  export declare function postCommitPhase(phase: PhaseConfig, deps: PhaseDeps, pc: PhaseContext, out: string): Promise<void>;
305
+ /**
306
+ * REFINE's post-commit: derive the task title from the refined prompt, then a short
307
+ * display label. Runs after the section write, so a fault here cannot lose the
308
+ * output it reads.
309
+ */
310
+ export declare function refinePostCommit(deps: PhaseDeps, pc: PhaseContext, out: string): Promise<void>;