infinity-harness 2.8.9 → 2.8.11
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/CHANGELOG.md +18 -0
- package/dist/extensions/infinity-harness/index.js +3614 -0
- package/dist/extensions/infinity-harness/index.js.map +1 -0
- package/dist/src/approval.js +154 -0
- package/dist/src/approval.js.map +1 -0
- package/dist/src/core/brief.js +309 -0
- package/dist/src/core/brief.js.map +1 -0
- package/dist/src/core/config.js +539 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/exec.js +106 -0
- package/dist/src/core/exec.js.map +1 -0
- package/dist/src/core/featureList.js +365 -0
- package/dist/src/core/featureList.js.map +1 -0
- package/dist/src/core/fsx.js +123 -0
- package/dist/src/core/fsx.js.map +1 -0
- package/dist/src/core/gates.js +490 -0
- package/dist/src/core/gates.js.map +1 -0
- package/dist/src/core/init.js +480 -0
- package/dist/src/core/init.js.map +1 -0
- package/dist/src/core/lock.js +183 -0
- package/dist/src/core/lock.js.map +1 -0
- package/dist/src/core/modelRouter.js +185 -0
- package/dist/src/core/modelRouter.js.map +1 -0
- package/dist/src/core/paths.js +129 -0
- package/dist/src/core/paths.js.map +1 -0
- package/dist/src/core/phases.js +254 -0
- package/dist/src/core/phases.js.map +1 -0
- package/dist/src/core/plan.js +15 -0
- package/dist/src/core/plan.js.map +1 -0
- package/dist/src/core/runState.js +126 -0
- package/dist/src/core/runState.js.map +1 -0
- package/dist/src/core/settings.js +877 -0
- package/dist/src/core/settings.js.map +1 -0
- package/dist/src/core/skills.js +319 -0
- package/dist/src/core/skills.js.map +1 -0
- package/dist/src/core/skillsAudit.js +194 -0
- package/dist/src/core/skillsAudit.js.map +1 -0
- package/dist/src/core/types.js +77 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/daemon/budget.js +85 -0
- package/dist/src/daemon/budget.js.map +1 -0
- package/dist/src/daemon/guard.js +122 -0
- package/dist/src/daemon/guard.js.map +1 -0
- package/dist/src/daemon/index.js +461 -0
- package/dist/src/daemon/index.js.map +1 -0
- package/dist/src/daemon/isolation.js +84 -0
- package/dist/src/daemon/isolation.js.map +1 -0
- package/dist/src/daemon/preflight.js +131 -0
- package/dist/src/daemon/preflight.js.map +1 -0
- package/dist/src/daemon/server.js +174 -0
- package/dist/src/daemon/server.js.map +1 -0
- package/dist/src/daemon/supervisorState.js +42 -0
- package/dist/src/daemon/supervisorState.js.map +1 -0
- package/dist/src/daemon/worker.js +239 -0
- package/dist/src/daemon/worker.js.map +1 -0
- package/dist/src/daemon/worktree.js +102 -0
- package/dist/src/daemon/worktree.js.map +1 -0
- package/dist/src/escalate.js +312 -0
- package/dist/src/escalate.js.map +1 -0
- package/dist/src/exec/piWorker.js +630 -0
- package/dist/src/exec/piWorker.js.map +1 -0
- package/dist/src/goal.js +317 -0
- package/dist/src/goal.js.map +1 -0
- package/dist/src/goalLoop.js +374 -0
- package/dist/src/goalLoop.js.map +1 -0
- package/dist/src/goalSpec.js +397 -0
- package/dist/src/goalSpec.js.map +1 -0
- package/dist/src/goalState.js +255 -0
- package/dist/src/goalState.js.map +1 -0
- package/dist/src/handoff.js +205 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/intake.js +203 -0
- package/dist/src/intake.js.map +1 -0
- package/dist/src/loop.js +592 -0
- package/dist/src/loop.js.map +1 -0
- package/dist/src/modelRouter.js +216 -0
- package/dist/src/modelRouter.js.map +1 -0
- package/dist/src/remote.js +246 -0
- package/dist/src/remote.js.map +1 -0
- package/dist/src/replan.js +262 -0
- package/dist/src/replan.js.map +1 -0
- package/dist/src/review.js +54 -0
- package/dist/src/review.js.map +1 -0
- package/dist/src/rework.js +241 -0
- package/dist/src/rework.js.map +1 -0
- package/dist/src/runState.js +4 -0
- package/dist/src/runState.js.map +1 -0
- package/dist/src/scheduler.js +270 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/supervisor.js +787 -0
- package/dist/src/supervisor.js.map +1 -0
- package/dist/src/taskList.js +430 -0
- package/dist/src/taskList.js.map +1 -0
- package/dist/src/ui/config.js +268 -0
- package/dist/src/ui/config.js.map +1 -0
- package/dist/src/ui/dashboard.js +1288 -0
- package/dist/src/ui/dashboard.js.map +1 -0
- package/dist/src/ui/display.js +229 -0
- package/dist/src/ui/display.js.map +1 -0
- package/dist/src/ui/planTree.js +219 -0
- package/dist/src/ui/planTree.js.map +1 -0
- package/dist/src/ui/theme.js +298 -0
- package/dist/src/ui/theme.js.map +1 -0
- package/dist/src/ui/viewState.js +65 -0
- package/dist/src/ui/viewState.js.map +1 -0
- package/dist/src/ui/widget.js +721 -0
- package/dist/src/ui/widget.js.map +1 -0
- package/dist/src/ui/wizard.js +540 -0
- package/dist/src/ui/wizard.js.map +1 -0
- package/dist/src/unstuck.js +210 -0
- package/dist/src/unstuck.js.map +1 -0
- package/dist/src/worker.js +267 -0
- package/dist/src/worker.js.map +1 -0
- package/dist/src/workflow.js +250 -0
- package/dist/src/workflow.js.map +1 -0
- package/dist/tests/approval.test.js +144 -0
- package/dist/tests/approval.test.js.map +1 -0
- package/dist/tests/brief.test.js +271 -0
- package/dist/tests/brief.test.js.map +1 -0
- package/dist/tests/config.test.js +320 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/dashboard.test.js +277 -0
- package/dist/tests/dashboard.test.js.map +1 -0
- package/dist/tests/display.test.js +229 -0
- package/dist/tests/display.test.js.map +1 -0
- package/dist/tests/escalate.test.js +272 -0
- package/dist/tests/escalate.test.js.map +1 -0
- package/dist/tests/featureList.test.js +429 -0
- package/dist/tests/featureList.test.js.map +1 -0
- package/dist/tests/gates.test.js +333 -0
- package/dist/tests/gates.test.js.map +1 -0
- package/dist/tests/goal.test.js +229 -0
- package/dist/tests/goal.test.js.map +1 -0
- package/dist/tests/goalLoop.test.js +170 -0
- package/dist/tests/goalLoop.test.js.map +1 -0
- package/dist/tests/goalSpec.test.js +146 -0
- package/dist/tests/goalSpec.test.js.map +1 -0
- package/dist/tests/goalState.test.js +202 -0
- package/dist/tests/goalState.test.js.map +1 -0
- package/dist/tests/handoff.test.js +127 -0
- package/dist/tests/handoff.test.js.map +1 -0
- package/dist/tests/init.test.js +264 -0
- package/dist/tests/init.test.js.map +1 -0
- package/dist/tests/intake.test.js +288 -0
- package/dist/tests/intake.test.js.map +1 -0
- package/dist/tests/loop.test.js +453 -0
- package/dist/tests/loop.test.js.map +1 -0
- package/dist/tests/modelRouter.test.js +131 -0
- package/dist/tests/modelRouter.test.js.map +1 -0
- package/dist/tests/phases.test.js +244 -0
- package/dist/tests/phases.test.js.map +1 -0
- package/dist/tests/planTree.test.js +190 -0
- package/dist/tests/planTree.test.js.map +1 -0
- package/dist/tests/remote.test.js +380 -0
- package/dist/tests/remote.test.js.map +1 -0
- package/dist/tests/replan.test.js +113 -0
- package/dist/tests/replan.test.js.map +1 -0
- package/dist/tests/review.test.js +77 -0
- package/dist/tests/review.test.js.map +1 -0
- package/dist/tests/rework.test.js +109 -0
- package/dist/tests/rework.test.js.map +1 -0
- package/dist/tests/routing-live.test.js +121 -0
- package/dist/tests/routing-live.test.js.map +1 -0
- package/dist/tests/runState.test.js +73 -0
- package/dist/tests/runState.test.js.map +1 -0
- package/dist/tests/settings.test.js +311 -0
- package/dist/tests/settings.test.js.map +1 -0
- package/dist/tests/skills.test.js +387 -0
- package/dist/tests/skills.test.js.map +1 -0
- package/dist/tests/supervisor.test.js +437 -0
- package/dist/tests/supervisor.test.js.map +1 -0
- package/dist/tests/surface.test.js +203 -0
- package/dist/tests/surface.test.js.map +1 -0
- package/dist/tests/taskList.test.js +376 -0
- package/dist/tests/taskList.test.js.map +1 -0
- package/dist/tests/theme.test.js +149 -0
- package/dist/tests/theme.test.js.map +1 -0
- package/dist/tests/unstuck.test.js +268 -0
- package/dist/tests/unstuck.test.js.map +1 -0
- package/dist/tests/widget.test.js +424 -0
- package/dist/tests/widget.test.js.map +1 -0
- package/dist/tests/worker.test.js +306 -0
- package/dist/tests/worker.test.js.map +1 -0
- package/dist/tests/workflow.test.js +187 -0
- package/dist/tests/workflow.test.js.map +1 -0
- package/extensions/infinity-harness/index.ts +39 -12
- package/package.json +5 -2
- package/src/core/modelRouter.ts +23 -1
- package/src/daemon/index.ts +3 -3
- package/src/daemon/worker.ts +28 -5
- package/src/ui/config.ts +25 -1
- package/src/ui/wizard.ts +10 -5
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — the phase state machine.
|
|
3
|
+
*
|
|
4
|
+
* Transitions are forward-only and one step at a time. That constraint is the
|
|
5
|
+
* whole point of the harness: an agent cannot decide it is done with BUILD and
|
|
6
|
+
* jump to SHIP. The only backward movement is an explicit rework (src/rework.ts),
|
|
7
|
+
* which records why it happened.
|
|
8
|
+
*/
|
|
9
|
+
import { PHASE_ORDER, DEFAULT_ENABLED_PHASES } from "./types.js";
|
|
10
|
+
import { loadConfig, saveConfig, recordGate, currentRoleFor } from "./config.js";
|
|
11
|
+
import { gitBranch, gitIsClean, gitHasUpstream, gitLastCommitMessage } from "./exec.js";
|
|
12
|
+
import { loadFeatureList, saveFeatureList, tasksForPhase } from "./featureList.js";
|
|
13
|
+
export { PHASE_ORDER };
|
|
14
|
+
export function isPhase(v) {
|
|
15
|
+
return typeof v === "string" && PHASE_ORDER.includes(v);
|
|
16
|
+
}
|
|
17
|
+
/** The enabled pipeline, in canonical order. Unknown entries are ignored. */
|
|
18
|
+
export function getPhaseOrder(enabled) {
|
|
19
|
+
if (!Array.isArray(enabled))
|
|
20
|
+
return [...DEFAULT_ENABLED_PHASES];
|
|
21
|
+
const set = new Set(enabled);
|
|
22
|
+
const order = PHASE_ORDER.filter((p) => set.has(p));
|
|
23
|
+
return order.length ? [...order] : [...DEFAULT_ENABLED_PHASES];
|
|
24
|
+
}
|
|
25
|
+
export function isValidTransition(fromPhase, toPhase, enabled) {
|
|
26
|
+
const order = getPhaseOrder(enabled);
|
|
27
|
+
if (!order.includes(toPhase))
|
|
28
|
+
return false;
|
|
29
|
+
if (fromPhase === null)
|
|
30
|
+
return order[0] === toPhase;
|
|
31
|
+
if (fromPhase === toPhase)
|
|
32
|
+
return true; // re-running a phase is always legal
|
|
33
|
+
return order.indexOf(toPhase) === order.indexOf(fromPhase) + 1;
|
|
34
|
+
}
|
|
35
|
+
export function nextPhase(fromPhase, enabled) {
|
|
36
|
+
const order = getPhaseOrder(enabled);
|
|
37
|
+
if (fromPhase === null)
|
|
38
|
+
return order[0] ?? null;
|
|
39
|
+
const i = order.indexOf(fromPhase);
|
|
40
|
+
if (i === -1)
|
|
41
|
+
return order[0] ?? null;
|
|
42
|
+
return order[i + 1] ?? null;
|
|
43
|
+
}
|
|
44
|
+
export function isFinalPhase(phase, enabled) {
|
|
45
|
+
const order = getPhaseOrder(enabled);
|
|
46
|
+
return phase !== null && order[order.length - 1] === phase;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Advance to `toPhase`, refreshing git metadata and resetting the right
|
|
50
|
+
* retry counters. Re-entering the same phase counts as a retry; moving to a
|
|
51
|
+
* new phase clears the phase budget but leaves task/feature budgets alone
|
|
52
|
+
* (those are cleared by whoever completes the task/feature).
|
|
53
|
+
*/
|
|
54
|
+
export async function transitionPhase(targetDir, toPhase) {
|
|
55
|
+
const { config, ok, error } = loadConfig(targetDir);
|
|
56
|
+
if (!ok) {
|
|
57
|
+
return { ok: false, error: error ?? "cannot load config", config: null, from: null, to: null };
|
|
58
|
+
}
|
|
59
|
+
const from = config.currentPhase;
|
|
60
|
+
const enabled = config.phases?.enabled;
|
|
61
|
+
if (!isValidTransition(from, toPhase, enabled)) {
|
|
62
|
+
const order = getPhaseOrder(enabled).join(" → ");
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: `invalid transition ${from ?? "start"} → ${toPhase}. Pipeline is: ${order}`,
|
|
66
|
+
config: null,
|
|
67
|
+
from,
|
|
68
|
+
to: toPhase,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const isNewPhase = from !== toPhase;
|
|
72
|
+
if (from && isNewPhase)
|
|
73
|
+
recordGate(config, from, "pass");
|
|
74
|
+
if (isNewPhase) {
|
|
75
|
+
config.retryCount = 0;
|
|
76
|
+
config.phaseRetryCount = 0;
|
|
77
|
+
config.pipelineIteration = (config.pipelineIteration ?? 0) + 1;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
config.retryCount = (config.retryCount ?? 0) + 1;
|
|
81
|
+
config.phaseRetryCount = (config.phaseRetryCount ?? 0) + 1;
|
|
82
|
+
}
|
|
83
|
+
config.currentPhase = toPhase;
|
|
84
|
+
config.currentRole = currentRoleFor(toPhase);
|
|
85
|
+
config.paused = false;
|
|
86
|
+
// Git metadata is best-effort context for the brief, never a blocker.
|
|
87
|
+
try {
|
|
88
|
+
config.git = config.git ?? {
|
|
89
|
+
autoCommit: false,
|
|
90
|
+
autoTag: false,
|
|
91
|
+
branch: null,
|
|
92
|
+
clean: true,
|
|
93
|
+
hasUpstream: false,
|
|
94
|
+
lastCommitMessage: null,
|
|
95
|
+
};
|
|
96
|
+
config.git.branch = await gitBranch(targetDir);
|
|
97
|
+
config.git.clean = await gitIsClean(targetDir);
|
|
98
|
+
config.git.hasUpstream = await gitHasUpstream(targetDir);
|
|
99
|
+
config.git.lastCommitMessage = await gitLastCommitMessage(targetDir);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
/* leave prior git metadata in place */
|
|
103
|
+
}
|
|
104
|
+
const saved = saveConfig(targetDir, config);
|
|
105
|
+
if (!saved.ok) {
|
|
106
|
+
return { ok: false, error: saved.error, config: null, from, to: toPhase };
|
|
107
|
+
}
|
|
108
|
+
return { ok: true, error: null, config, from, to: toPhase };
|
|
109
|
+
}
|
|
110
|
+
export const STARTER_TASKS_BY_DEPTH = {
|
|
111
|
+
standard: [
|
|
112
|
+
{ id: "research/r1", description: "Collect prior art — 3 primary sources with URLs, what exists, where it stops", difficulty: "moderate", subtasks: ["source 1 + URL + summary", "source 2 + URL + summary", "source 3 + URL + summary"] },
|
|
113
|
+
{ id: "research/r2", description: "Name constraints (given vs inferred) and lay out 2+ options with costs", difficulty: "moderate", subtasks: ["constraints given vs inferred table", "option A cost/benefit", "option B cost/benefit"] },
|
|
114
|
+
{ id: "research/r3", description: "Recommend one option, falsification condition, and open questions for DEFINE", difficulty: "moderate", subtasks: ["recommendation + falsification", "open questions list (≥5)"] },
|
|
115
|
+
],
|
|
116
|
+
deep: [
|
|
117
|
+
{ id: "research/r1", description: "Prior art: ≥5 primary sources with URLs (docs/specs/repos), what each gets right and where it stops", difficulty: "moderate", subtasks: ["sources 1-3 + URLs + summaries", "sources 4-5 + URLs + gap analysis", "comparison table: feature × prior art"] },
|
|
118
|
+
{ id: "research/r2", description: "Constraints & domain model: given vs inferred, glossary terms, actors & data", difficulty: "moderate", subtasks: ["constraints given vs inferred (table)", "domain glossary + actors", "data & platform constraints"] },
|
|
119
|
+
{ id: "research/r3", description: "Options: ≥3 genuine alternatives with architecture, cost, risk and trade-offs", difficulty: "difficult", subtasks: ["option A: arch + cost + risk", "option B: arch + cost + risk", "option C / hybrid + trade-off matrix"] },
|
|
120
|
+
{ id: "research/r4", description: "Recommendation with falsification: what must be true, what would prove it wrong", difficulty: "moderate", subtasks: ["recommendation + rationale", "falsification condition + experiment"] },
|
|
121
|
+
{ id: "research/r5", description: "Open questions for DEFINE: ranked questions only a human can answer", difficulty: "easy", subtasks: ["open questions (≥8) ranked", "DEFINE interview agenda"] },
|
|
122
|
+
],
|
|
123
|
+
comprehensive: [
|
|
124
|
+
{ id: "research/r1", description: "Literature sweep: ≥15 primary sources — papers, RFCs, repos, postmortems — annotated", difficulty: "difficult", subtasks: ["sources 1-5 annotated", "sources 6-10 annotated", "sources 11-15 annotated", "citation map + gaps in literature"] },
|
|
125
|
+
{ id: "research/r2", description: "Domain & constraints synthesis: glossary, actors, data, regulatory & platform limits", difficulty: "difficult", subtasks: ["constraints given vs inferred (full table)", "domain glossary + bounded contexts", "actors, data flows & invariants"] },
|
|
126
|
+
{ id: "research/r3", description: "Benchmark prior work: reproduce or reason about 3+ approaches on a toy case", difficulty: "difficult", subtasks: ["approach A benchmark", "approach B benchmark", "approach C benchmark + comparison matrix"] },
|
|
127
|
+
{ id: "research/r4", description: "Architecture options: ≥3 with diagrams, cost model, risk register, team & time", difficulty: "difficult", subtasks: ["option A: diagram + cost + risk", "option B: diagram + cost + risk", "option C: diagram + cost + risk", "trade-off matrix + decision criteria"] },
|
|
128
|
+
{ id: "research/r5", description: "Recommendation as a decision record + what falsifies it", difficulty: "moderate", subtasks: ["ADR: recommendation + alternatives rejected", "falsification condition + experiment design"] },
|
|
129
|
+
{ id: "research/r6", description: "Risk & unknowns register: known unknowns, unknown unknowns, mitigations", difficulty: "moderate", subtasks: ["risk register", "mitigations + owners", "open unknowns vs knowns"] },
|
|
130
|
+
{ id: "research/r7", description: "DEFINE handoff: ranked open questions (≥12) + interview agenda + glossary delta", difficulty: "easy", subtasks: ["open questions (≥12) ranked", "DEFINE interview agenda", "glossary delta for DOMAIN.md"] },
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
// Back-compat: default deep
|
|
134
|
+
const DEFAULT_RESEARCH_DEPTH = "deep";
|
|
135
|
+
export const STARTER_TASKS = {
|
|
136
|
+
get research() { return STARTER_TASKS_BY_DEPTH[DEFAULT_RESEARCH_DEPTH]; },
|
|
137
|
+
set research(v) { STARTER_TASKS_BY_DEPTH[DEFAULT_RESEARCH_DEPTH] = v; },
|
|
138
|
+
define: [
|
|
139
|
+
{
|
|
140
|
+
id: "define/d1",
|
|
141
|
+
description: "Interview scope and write bounded PRD + acceptance criteria",
|
|
142
|
+
difficulty: "moderate",
|
|
143
|
+
subtasks: ["scope interview", "PRD draft", "acceptance criteria per feature"],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: "define/d2",
|
|
147
|
+
description: "Record sprint contract and branch (not main)",
|
|
148
|
+
difficulty: "easy",
|
|
149
|
+
subtasks: ["sprint contract", "feature branch"],
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
plan: [
|
|
153
|
+
{
|
|
154
|
+
id: "plan/p1",
|
|
155
|
+
description: "Break each feature into ordered, dependency-aware tasks",
|
|
156
|
+
difficulty: "moderate",
|
|
157
|
+
subtasks: ["vertical slices", "dependency graph", "difficulty + subtasks"],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: "plan/p2",
|
|
161
|
+
description: "Commit plan (feature-list) and validate",
|
|
162
|
+
difficulty: "easy",
|
|
163
|
+
subtasks: ["feature-list.json commit", "validate gate"],
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
export function isPhaseDone(dir, phase) {
|
|
168
|
+
const { list } = loadFeatureList(dir);
|
|
169
|
+
const tasks = tasksForPhase(list, phase);
|
|
170
|
+
return tasks.length > 0 && tasks.every((t) => t.status === "complete");
|
|
171
|
+
}
|
|
172
|
+
function startersForPhase(dir, phase) {
|
|
173
|
+
if (phase !== "research")
|
|
174
|
+
return STARTER_TASKS[phase] ?? [];
|
|
175
|
+
try {
|
|
176
|
+
const { config } = loadConfig(dir);
|
|
177
|
+
const depth = config.researchDepth;
|
|
178
|
+
if (depth && STARTER_TASKS_BY_DEPTH[depth])
|
|
179
|
+
return STARTER_TASKS_BY_DEPTH[depth];
|
|
180
|
+
}
|
|
181
|
+
catch { }
|
|
182
|
+
return STARTER_TASKS_BY_DEPTH[DEFAULT_RESEARCH_DEPTH] ?? [];
|
|
183
|
+
}
|
|
184
|
+
export function ensurePhaseSeeded(dir, phase) {
|
|
185
|
+
try {
|
|
186
|
+
const { list } = loadFeatureList(dir);
|
|
187
|
+
if (tasksForPhase(list, phase).length > 0)
|
|
188
|
+
return false;
|
|
189
|
+
const r = seedPhaseIfEmpty(dir, phase);
|
|
190
|
+
return r.seeded;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export function seedPhaseIfEmpty(dir, phase) {
|
|
197
|
+
const seeded = startersForPhase(dir, phase);
|
|
198
|
+
if (seeded.length === 0)
|
|
199
|
+
return { seeded: false, error: null };
|
|
200
|
+
try {
|
|
201
|
+
const { list } = loadFeatureList(dir);
|
|
202
|
+
const existing = tasksForPhase(list, phase);
|
|
203
|
+
if (existing.length > 0)
|
|
204
|
+
return { seeded: false, error: null };
|
|
205
|
+
// Each phase gets its own feature (phase-<name>) so per-phase tabs/groups isolate correctly.
|
|
206
|
+
// Never append a "define" task to a "research" feature — the feature.phase is the grouping key.
|
|
207
|
+
const match = list.features.find((f) => f.phase === phase);
|
|
208
|
+
const feature = match ?? { id: `phase-${phase}`, name: phase.toUpperCase(), tasks: [] };
|
|
209
|
+
if (!list.features.includes(feature)) {
|
|
210
|
+
feature.phase = phase;
|
|
211
|
+
list.features.push(feature);
|
|
212
|
+
}
|
|
213
|
+
for (const t of seeded) {
|
|
214
|
+
if (feature.tasks.some((x) => x.id === t.id))
|
|
215
|
+
continue;
|
|
216
|
+
feature.tasks.push({
|
|
217
|
+
id: t.id,
|
|
218
|
+
description: t.description,
|
|
219
|
+
status: "pending",
|
|
220
|
+
phase,
|
|
221
|
+
difficulty: t.difficulty,
|
|
222
|
+
subtasks: (t.subtasks ?? []).map((title) => ({ title, status: "pending" })),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
// Newly created phase-features default to criteria so DEFINE gate doesn't fail on 'phase-define missing criteria'.
|
|
226
|
+
if (Array.isArray(feature.criteria) && feature.criteria.length === 0) {
|
|
227
|
+
feature.criteria = [`${phase} ready for review`];
|
|
228
|
+
}
|
|
229
|
+
list.baseRevision = (list.baseRevision ?? 0) + 1;
|
|
230
|
+
saveFeatureList(dir, list);
|
|
231
|
+
return { seeded: true, error: null };
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
return { seeded: false, error: e instanceof Error ? e.message : String(e) };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** Advance one step along the enabled pipeline. */
|
|
238
|
+
export async function advancePhase(targetDir) {
|
|
239
|
+
const { config, ok, error } = loadConfig(targetDir);
|
|
240
|
+
if (!ok)
|
|
241
|
+
return { ok: false, error: error ?? "cannot load config", config: null, from: null, to: null };
|
|
242
|
+
const to = nextPhase(config.currentPhase, config.phases?.enabled);
|
|
243
|
+
if (to === null) {
|
|
244
|
+
return {
|
|
245
|
+
ok: false,
|
|
246
|
+
error: "pipeline complete — no phase after " + (config.currentPhase ?? "start"),
|
|
247
|
+
config,
|
|
248
|
+
from: config.currentPhase,
|
|
249
|
+
to: null,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return transitionPhase(targetDir, to);
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=phases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phases.js","sourceRoot":"","sources":["../../../src/core/phases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — plan.ts (canonical) — re-export / wrapper around featureList.ts.
|
|
3
|
+
*
|
|
4
|
+
* v3 canonical path is `harness/plan.json`. The module `featureList.ts` already
|
|
5
|
+
* implements the canonical load/save with legacy fallback and stub handling;
|
|
6
|
+
* this file is the name the architecture calls "plan.ts" — one file, one name,
|
|
7
|
+
* matching the 5-level hierarchy.
|
|
8
|
+
*
|
|
9
|
+
* Keeping `featureList.ts` as the real implementation avoids churning every
|
|
10
|
+
* import in one commit; this shim means `import { loadPlan } from "./plan.ts"`
|
|
11
|
+
* and `import { loadFeatureList } from "./featureList.ts"` both work and
|
|
12
|
+
* point at the same truth.
|
|
13
|
+
*/
|
|
14
|
+
export { emptyFeatureList, validateKey, normalizeStatus, normalizeSubtaskStatus, isDone, resolvePlanFile, loadFeatureList, loadFeatureList as loadPlan, saveFeatureList, saveFeatureList as savePlan, flattenTasks, findTask, findFeature, tasksForPhase, featuresForPhase, computeProgress, nextActionableTask, detectCycle, MAX_TASKS, MAX_DEPENDS_ON, MAX_SUBJECT_LEN, MAX_DESCRIPTION_LEN, } from "./featureList.js";
|
|
15
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/core/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,MAAM,EACN,eAAe,EACf,eAAe,EACf,eAAe,IAAI,QAAQ,EAC3B,eAAe,EACf,eAAe,IAAI,QAAQ,EAC3B,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — core/runState.ts (Core owns type + path, Daemon owns writes).
|
|
3
|
+
*
|
|
4
|
+
* v2.7's `src/runState.ts` had { armed, runId, startedAt, sessions, stoppedAt, stopReason }.
|
|
5
|
+
* v3 extends it with: baseModel, tiers (preflight results), budget (byTier UsageTotals + caps).
|
|
6
|
+
* Existing fields are kept; the file stays `harness/run.json`.
|
|
7
|
+
*
|
|
8
|
+
* Core owns the type, the path spelling, and the read helpers used by Interfaces.
|
|
9
|
+
* Daemon owns the writes (arm, heartbeat, budget, preflight) — but the types
|
|
10
|
+
* are here so Interfaces and Core can read the same truth without importing
|
|
11
|
+
* the Daemon.
|
|
12
|
+
*/
|
|
13
|
+
import { runStatePath } from "./paths.js";
|
|
14
|
+
import { readJsonSafe, writeJsonAtomic, removeFile } from "./fsx.js";
|
|
15
|
+
export function createUsageTotals() {
|
|
16
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, calls: 0 };
|
|
17
|
+
}
|
|
18
|
+
export function newRunState(runId, now = new Date()) {
|
|
19
|
+
return {
|
|
20
|
+
armed: true,
|
|
21
|
+
runId,
|
|
22
|
+
startedAt: now.toISOString(),
|
|
23
|
+
sessions: 1,
|
|
24
|
+
stoppedAt: null,
|
|
25
|
+
stopReason: null,
|
|
26
|
+
baseModel: null,
|
|
27
|
+
tiers: {},
|
|
28
|
+
budget: { byTier: {}, cap: {}, stopOnExhaustion: true },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function loadRunState(targetDir) {
|
|
32
|
+
const raw = readJsonSafe(runStatePath(targetDir), null);
|
|
33
|
+
if (!raw || typeof raw.runId !== "string" || !raw.runId)
|
|
34
|
+
return null;
|
|
35
|
+
const sessions = typeof raw.sessions === "number" && raw.sessions > 0 ? raw.sessions : 1;
|
|
36
|
+
// Back-compat: older file had no baseModel/tiers/budget — treat as null/empty.
|
|
37
|
+
const baseModel = (() => {
|
|
38
|
+
const bm = raw.baseModel;
|
|
39
|
+
if (!bm || typeof bm !== "object" || Array.isArray(bm))
|
|
40
|
+
return null;
|
|
41
|
+
const b = bm;
|
|
42
|
+
if (typeof b.provider === "string" && typeof b.id === "string")
|
|
43
|
+
return { provider: String(b.provider), id: String(b.id), ...(typeof b.thinkingLevel === "string" ? { thinkingLevel: b.thinkingLevel } : {}) };
|
|
44
|
+
// legacy: baseModel was a string "provider/id"
|
|
45
|
+
if (typeof raw.baseModel === "string" && String(raw.baseModel).trim()) {
|
|
46
|
+
const s = String(raw.baseModel).trim();
|
|
47
|
+
const parts = s.split("/");
|
|
48
|
+
if (parts.length >= 2)
|
|
49
|
+
return { provider: parts[0], id: parts.slice(1).join("/") };
|
|
50
|
+
return { provider: "anthropic", id: s };
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
})();
|
|
54
|
+
const tiersRaw = raw.tiers;
|
|
55
|
+
const tiers = (tiersRaw && typeof tiersRaw === "object" && !Array.isArray(tiersRaw) ? tiersRaw : {});
|
|
56
|
+
const budgetRaw = raw.budget;
|
|
57
|
+
const budget = (budgetRaw && typeof budgetRaw === "object" && !Array.isArray(budgetRaw)
|
|
58
|
+
? budgetRaw
|
|
59
|
+
: { byTier: {}, cap: {}, stopOnExhaustion: true });
|
|
60
|
+
if (!budget.byTier || typeof budget.byTier !== "object")
|
|
61
|
+
budget.byTier = {};
|
|
62
|
+
if (!budget.cap || typeof budget.cap !== "object")
|
|
63
|
+
budget.cap = {};
|
|
64
|
+
return {
|
|
65
|
+
armed: raw.armed === true,
|
|
66
|
+
runId: raw.runId,
|
|
67
|
+
startedAt: typeof raw.startedAt === "string" ? raw.startedAt : new Date(0).toISOString(),
|
|
68
|
+
sessions,
|
|
69
|
+
stoppedAt: typeof raw.stoppedAt === "string" ? raw.stoppedAt : null,
|
|
70
|
+
stopReason: typeof raw.stopReason === "string" ? raw.stopReason : null,
|
|
71
|
+
baseModel,
|
|
72
|
+
tiers,
|
|
73
|
+
budget,
|
|
74
|
+
...(typeof raw.wallClockMs === "number" ? { wallClockMs: raw.wallClockMs } : {}),
|
|
75
|
+
...(typeof raw.escalation === "object" ? { escalation: raw.escalation } : {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function saveRunState(targetDir, state) {
|
|
79
|
+
try {
|
|
80
|
+
writeJsonAtomic(runStatePath(targetDir), state);
|
|
81
|
+
}
|
|
82
|
+
catch { /* run bookkeeping must not kill the session */ }
|
|
83
|
+
}
|
|
84
|
+
export function armRun(targetDir, runId, now = new Date()) {
|
|
85
|
+
const existing = loadRunState(targetDir);
|
|
86
|
+
const state = existing && existing.armed ? { ...existing, stoppedAt: null, stopReason: null } : newRunState(runId, now);
|
|
87
|
+
saveRunState(targetDir, state);
|
|
88
|
+
return state;
|
|
89
|
+
}
|
|
90
|
+
export function disarmRun(targetDir, reason, now = new Date()) {
|
|
91
|
+
const existing = loadRunState(targetDir);
|
|
92
|
+
if (!existing)
|
|
93
|
+
return null;
|
|
94
|
+
const state = { ...existing, armed: false, stoppedAt: now.toISOString(), stopReason: reason };
|
|
95
|
+
saveRunState(targetDir, state);
|
|
96
|
+
return state;
|
|
97
|
+
}
|
|
98
|
+
export function countSession(targetDir) {
|
|
99
|
+
const existing = loadRunState(targetDir);
|
|
100
|
+
if (!existing)
|
|
101
|
+
return null;
|
|
102
|
+
const state = { ...existing, sessions: existing.sessions + 1 };
|
|
103
|
+
saveRunState(targetDir, state);
|
|
104
|
+
return state;
|
|
105
|
+
}
|
|
106
|
+
export function clearRunState(targetDir) {
|
|
107
|
+
try {
|
|
108
|
+
removeFile(runStatePath(targetDir));
|
|
109
|
+
}
|
|
110
|
+
catch { /* nothing to clear */ }
|
|
111
|
+
}
|
|
112
|
+
export function runIdFor(targetDir, fallback) {
|
|
113
|
+
const state = loadRunState(targetDir);
|
|
114
|
+
return state && state.armed ? state.runId : fallback;
|
|
115
|
+
}
|
|
116
|
+
/** Parse a legacy baseModel string "provider/id" into a ProviderModel. */
|
|
117
|
+
export function parseBaseModelString(s) {
|
|
118
|
+
if (!s || !String(s).trim())
|
|
119
|
+
return null;
|
|
120
|
+
const str = String(s).trim();
|
|
121
|
+
const parts = str.split("/");
|
|
122
|
+
if (parts.length >= 2)
|
|
123
|
+
return { provider: parts[0], id: parts.slice(1).join("/") };
|
|
124
|
+
return { provider: "anthropic", id: str };
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=runState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runState.js","sourceRoot":"","sources":["../../../src/core/runState.ts"],"names":[],"mappings":"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"}
|