@peterxiaoyang/superspec 0.1.38 → 0.1.39
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/cli.js +19 -2
- package/dist/code_review.d.ts +17 -2
- package/dist/code_review.js +471 -80
- package/dist/format.d.ts +46 -4
- package/dist/format.js +311 -26
- package/dist/git_state.d.ts +36 -0
- package/dist/git_state.js +174 -0
- package/dist/job_validity.d.ts +1 -0
- package/dist/job_validity.js +11 -8
- package/dist/next.js +46 -314
- package/dist/phase_plan.d.ts +97 -0
- package/dist/phase_plan.js +582 -0
- package/dist/record.js +56 -7
- package/dist/review.d.ts +3 -2
- package/dist/review.js +64 -32
- package/dist/review_job_gates.js +1 -0
- package/dist/store.d.ts +10 -0
- package/dist/store.js +53 -3
- package/dist/sync.js +5 -5
- package/dist/task.js +87 -9
- package/dist/task_evidence.js +80 -0
- package/dist/transition.d.ts +1 -1
- package/dist/transition.js +301 -210
- package/dist/types.d.ts +77 -1
- package/package.json +1 -1
- package/templates/workflow/prompts/architect.md +17 -27
- package/templates/workflow/prompts/code-reviewer.md +13 -2
- package/templates/workflow/prompts/critic.md +62 -61
- package/templates/workflow/prompts/executor.md +1 -1
- package/templates/workflow/prompts/explore.md +38 -26
- package/templates/workflow/prompts/test-engineer.md +18 -32
- package/templates/workflow/prompts/verifier.md +5 -3
- package/templates/workflow/skills/superspec-apply/SKILL.md +34 -11
- package/templates/workflow/skills/superspec-explore/SKILL.md +65 -64
- package/templates/workflow/skills/superspec-propose/SKILL.md +64 -43
- package/templates/workflow/skills/superspec-review/SKILL.md +1 -1
package/dist/task_evidence.js
CHANGED
|
@@ -3,6 +3,9 @@ import { join } from "node:path";
|
|
|
3
3
|
import { parseTasksMd } from "./format.js";
|
|
4
4
|
import { readEvents, sha256Text } from "./store.js";
|
|
5
5
|
export function taskEvidenceReadiness(projectRoot, change, changeRoot, attempt) {
|
|
6
|
+
if (attempt.contract_mode === true) {
|
|
7
|
+
return contractTaskEvidenceReadiness(projectRoot, change, attempt);
|
|
8
|
+
}
|
|
6
9
|
const tasksContent = readFileSync(join(changeRoot, "tasks.md"), "utf8");
|
|
7
10
|
const tasks = parseTasksMd(tasksContent);
|
|
8
11
|
const taskInfo = tasks.find(task => task.taskId === attempt.task_id);
|
|
@@ -44,3 +47,80 @@ export function taskEvidenceReadiness(projectRoot, change, changeRoot, attempt)
|
|
|
44
47
|
? { ready: true, missing: [] }
|
|
45
48
|
: { ready: false, missing, reason: missing.join("、") };
|
|
46
49
|
}
|
|
50
|
+
function contractTaskEvidenceReadiness(projectRoot, change, attempt) {
|
|
51
|
+
const missing = [];
|
|
52
|
+
const tddRequired = attempt.tdd_required !== false;
|
|
53
|
+
const characterization = attempt.tdd_required === false && attempt.no_tdd_reason === "characterization";
|
|
54
|
+
const declaredTests = attempt.contract?.tests ?? [];
|
|
55
|
+
if (!tddRequired && !attempt.no_tdd_reason) {
|
|
56
|
+
missing.push("no_tdd_reason");
|
|
57
|
+
}
|
|
58
|
+
if (declaredTests.length === 0) {
|
|
59
|
+
if (tddRequired) {
|
|
60
|
+
const hasAttemptEvidence = attemptLevelRedGreenEvidence(projectRoot, change, attempt.attempt_id);
|
|
61
|
+
if (!hasAttemptEvidence.hasRed)
|
|
62
|
+
missing.push("RED 证据");
|
|
63
|
+
if (!hasAttemptEvidence.hasGreen)
|
|
64
|
+
missing.push("GREEN 证据");
|
|
65
|
+
}
|
|
66
|
+
return missing.length === 0
|
|
67
|
+
? { ready: true, missing: [] }
|
|
68
|
+
: { ready: false, missing, reason: missing.join("、") };
|
|
69
|
+
}
|
|
70
|
+
const perTest = new Map();
|
|
71
|
+
for (const testId of declaredTests) {
|
|
72
|
+
perTest.set(testId, { sawRed: false, sawGreen: false, paired: false });
|
|
73
|
+
}
|
|
74
|
+
for (const ev of readEvents(projectRoot, change)) {
|
|
75
|
+
if (ev.event_type !== "test_run_recorded")
|
|
76
|
+
continue;
|
|
77
|
+
const tr = ev.payload;
|
|
78
|
+
if (tr.attempt_id !== attempt.attempt_id)
|
|
79
|
+
continue;
|
|
80
|
+
if (typeof tr.test_id !== "string")
|
|
81
|
+
continue;
|
|
82
|
+
const state = perTest.get(tr.test_id);
|
|
83
|
+
if (!state)
|
|
84
|
+
continue;
|
|
85
|
+
if (tr.semantic_status === "expected_failure" && typeof tr.exit_code === "number" && tr.exit_code !== 0) {
|
|
86
|
+
state.sawRed = true;
|
|
87
|
+
}
|
|
88
|
+
const isExpectedSuccess = tr.semantic_status === "expected_success" && tr.exit_code === 0;
|
|
89
|
+
const isCharacterizationPass = characterization && tr.semantic_status === "characterization_pass" && tr.exit_code === 0;
|
|
90
|
+
if (isExpectedSuccess || isCharacterizationPass) {
|
|
91
|
+
if (state.sawRed)
|
|
92
|
+
state.paired = true;
|
|
93
|
+
state.sawGreen = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const [testId, state] of perTest) {
|
|
97
|
+
if (!state.sawGreen)
|
|
98
|
+
missing.push(`${testId} GREEN 证据`);
|
|
99
|
+
}
|
|
100
|
+
if (tddRequired) {
|
|
101
|
+
const hasPairedTest = [...perTest.values()].some(state => state.paired);
|
|
102
|
+
if (!hasPairedTest)
|
|
103
|
+
missing.push("同一 TEST 的 RED/GREEN 配对");
|
|
104
|
+
}
|
|
105
|
+
return missing.length === 0
|
|
106
|
+
? { ready: true, missing: [] }
|
|
107
|
+
: { ready: false, missing, reason: missing.join("、") };
|
|
108
|
+
}
|
|
109
|
+
function attemptLevelRedGreenEvidence(projectRoot, change, attemptId) {
|
|
110
|
+
let hasRed = false;
|
|
111
|
+
let hasGreen = false;
|
|
112
|
+
for (const ev of readEvents(projectRoot, change)) {
|
|
113
|
+
if (ev.event_type !== "test_run_recorded")
|
|
114
|
+
continue;
|
|
115
|
+
const tr = ev.payload;
|
|
116
|
+
if (tr.attempt_id !== attemptId)
|
|
117
|
+
continue;
|
|
118
|
+
if (tr.semantic_status === "expected_failure" && typeof tr.exit_code === "number" && tr.exit_code !== 0) {
|
|
119
|
+
hasRed = true;
|
|
120
|
+
}
|
|
121
|
+
if (tr.semantic_status === "expected_success" && tr.exit_code === 0) {
|
|
122
|
+
hasGreen = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { hasRed, hasGreen };
|
|
126
|
+
}
|
package/dist/transition.d.ts
CHANGED
|
@@ -43,5 +43,5 @@ export declare function reopen(projectRoot: string, change: string, changeRoot:
|
|
|
43
43
|
export declare function reviewReady(projectRoot: string, change: string, changeRoot: string, risk?: "minimal" | "normal" | "strict"): TransitionResult;
|
|
44
44
|
export declare function accept(projectRoot: string, change: string, changeRoot: string): TransitionResult;
|
|
45
45
|
export declare function archive(projectRoot: string, change: string, changeRoot: string): TransitionResult;
|
|
46
|
-
export declare function taskComplete(projectRoot: string, change: string, changeRoot: string, taskId: string): TransitionResult;
|
|
46
|
+
export declare function taskComplete(projectRoot: string, change: string, changeRoot: string, taskId: string, inputContent?: string | null): TransitionResult;
|
|
47
47
|
export {};
|