@staff0rd/assist 0.142.0 → 0.143.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/claude/commands/draft.md +1 -1
- package/dist/index.js +96 -54
- package/package.json +1 -1
package/claude/commands/draft.md
CHANGED
|
@@ -38,7 +38,7 @@ Once you have enough context, propose a complete backlog item. Show it to the us
|
|
|
38
38
|
|
|
39
39
|
Keep phases small (2-4 tasks each). A typical item should have 2-3 phases.
|
|
40
40
|
|
|
41
|
-
Most phases should NOT have manual checks — prefer automated verification via the `verify` field on tasks. Only add `manualChecks` to a phase when the checks are genuinely difficult to automate (e.g. visual appearance, UX flow, hardware interaction).
|
|
41
|
+
Most phases should NOT have manual checks — prefer automated verification via the `verify` field on tasks. Only add `manualChecks` to a phase when the checks are genuinely difficult to automate (e.g. visual appearance, UX flow, hardware interaction). Do not add a final phase just for end-to-end verification — a review phase is auto-appended at runtime.
|
|
42
42
|
|
|
43
43
|
## Step 4: Iterate
|
|
44
44
|
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.143.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -2609,36 +2609,20 @@ import enquirer6 from "enquirer";
|
|
|
2609
2609
|
// src/commands/backlog/run.ts
|
|
2610
2610
|
import chalk35 from "chalk";
|
|
2611
2611
|
|
|
2612
|
-
// src/commands/backlog/
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
return
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
"",
|
|
2627
|
-
"Before marking this phase as done, ask the user to perform these manual checks:",
|
|
2628
|
-
...manualChecks.map((c) => `- ${c}`),
|
|
2629
|
-
"",
|
|
2630
|
-
"Wait for the user to confirm all manual checks pass before proceeding."
|
|
2631
|
-
];
|
|
2632
|
-
}
|
|
2633
|
-
if (isLastPhase) {
|
|
2634
|
-
return [
|
|
2635
|
-
"",
|
|
2636
|
-
"This is the final phase. Before marking it as done, ask the user to manually verify",
|
|
2637
|
-
"that the feature works end-to-end and all acceptance criteria are met.",
|
|
2638
|
-
"Wait for the user to confirm before proceeding."
|
|
2639
|
-
];
|
|
2640
|
-
}
|
|
2641
|
-
return [];
|
|
2612
|
+
// src/commands/backlog/buildAuthoredPhasePrompt.ts
|
|
2613
|
+
function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
2614
|
+
const manualChecks = phase.manualChecks ?? [];
|
|
2615
|
+
const needsConfirmation = manualChecks.length > 0;
|
|
2616
|
+
const confirmSuffix = needsConfirmation ? " and the user confirms" : "";
|
|
2617
|
+
return [
|
|
2618
|
+
...buildContextLines(item, phaseIndex, phase),
|
|
2619
|
+
"",
|
|
2620
|
+
"Focus ONLY on this phase. Do not work on other phases.",
|
|
2621
|
+
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
2622
|
+
...buildManualCheckLines(manualChecks),
|
|
2623
|
+
"",
|
|
2624
|
+
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseIndex}`
|
|
2625
|
+
].filter((line) => line !== void 0).join("\n");
|
|
2642
2626
|
}
|
|
2643
2627
|
function buildContextLines(item, phaseIndex, phase) {
|
|
2644
2628
|
const ac = item.acceptanceCriteria.map((c) => `- ${c}`).join("\n");
|
|
@@ -2655,22 +2639,76 @@ function buildContextLines(item, phaseIndex, phase) {
|
|
|
2655
2639
|
formatTasks(phase)
|
|
2656
2640
|
];
|
|
2657
2641
|
}
|
|
2658
|
-
function
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2642
|
+
function buildManualCheckLines(manualChecks) {
|
|
2643
|
+
if (manualChecks.length > 0) {
|
|
2644
|
+
return [
|
|
2645
|
+
"",
|
|
2646
|
+
"Before marking this phase as done, ask the user to perform these manual checks:",
|
|
2647
|
+
...manualChecks.map((c) => `- ${c}`),
|
|
2648
|
+
"",
|
|
2649
|
+
"Wait for the user to confirm all manual checks pass before proceeding."
|
|
2650
|
+
];
|
|
2651
|
+
}
|
|
2652
|
+
return [];
|
|
2653
|
+
}
|
|
2654
|
+
function formatTasks(phase) {
|
|
2655
|
+
return phase.tasks.map((t) => {
|
|
2656
|
+
let line = `- ${t.task}`;
|
|
2657
|
+
if (t.verify) line += ` (verify: ${t.verify})`;
|
|
2658
|
+
return line;
|
|
2659
|
+
}).join("\n");
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
// src/commands/backlog/buildReviewPrompt.ts
|
|
2663
|
+
function buildReviewPrompt(item, phaseIndex) {
|
|
2664
|
+
const acLines = item.acceptanceCriteria.map((ac, i) => `${i + 1}. ${ac}`).join("\n");
|
|
2663
2665
|
return [
|
|
2664
|
-
|
|
2666
|
+
`You are reviewing backlog item #${item.id}: ${item.name}`,
|
|
2665
2667
|
"",
|
|
2666
|
-
|
|
2667
|
-
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
2668
|
-
...buildManualCheckLines(manualChecks, isLastPhase),
|
|
2668
|
+
item.description ? `Description: ${item.description}` : "",
|
|
2669
2669
|
"",
|
|
2670
|
-
|
|
2670
|
+
"This is the auto-generated review phase. Verify each acceptance criterion against the current implementation.",
|
|
2671
|
+
"For each criterion, inspect the code and report PASS or FAIL with a brief explanation:",
|
|
2672
|
+
"",
|
|
2673
|
+
acLines,
|
|
2674
|
+
"",
|
|
2675
|
+
"If any criterion fails, fix the issue and re-verify before proceeding.",
|
|
2676
|
+
"",
|
|
2677
|
+
"After all criteria pass, ask the user to confirm any manual checks",
|
|
2678
|
+
"(e.g. end-to-end behaviour they need to verify themselves).",
|
|
2679
|
+
"Wait for the user to confirm before proceeding.",
|
|
2680
|
+
"",
|
|
2681
|
+
"Once the user confirms:",
|
|
2682
|
+
`1. Run: assist backlog done ${item.id}`,
|
|
2683
|
+
"2. Run: /commit",
|
|
2684
|
+
`3. Run: assist backlog phase-done ${item.id} ${phaseIndex}`
|
|
2671
2685
|
].filter((line) => line !== void 0).join("\n");
|
|
2672
2686
|
}
|
|
2673
2687
|
|
|
2688
|
+
// src/commands/backlog/buildPhasePrompt.ts
|
|
2689
|
+
var REVIEW_PHASE_NAME = "Review";
|
|
2690
|
+
function buildPhasePrompt(item, phaseIndex, phase) {
|
|
2691
|
+
if (phase.name === REVIEW_PHASE_NAME) {
|
|
2692
|
+
return buildReviewPrompt(item, phaseIndex);
|
|
2693
|
+
}
|
|
2694
|
+
return buildAuthoredPhasePrompt(item, phaseIndex, phase);
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
// src/commands/backlog/buildReviewPhase.ts
|
|
2698
|
+
function buildReviewPhase() {
|
|
2699
|
+
return {
|
|
2700
|
+
name: REVIEW_PHASE_NAME,
|
|
2701
|
+
tasks: [
|
|
2702
|
+
{
|
|
2703
|
+
task: "Verify acceptance criteria, confirm manual checks, mark done, commit, and signal phase-done."
|
|
2704
|
+
}
|
|
2705
|
+
]
|
|
2706
|
+
};
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
// src/commands/backlog/executePhase.ts
|
|
2710
|
+
import chalk34 from "chalk";
|
|
2711
|
+
|
|
2674
2712
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
2675
2713
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
2676
2714
|
import { existsSync as existsSync16, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -2792,7 +2830,7 @@ async function executePhase(item, phaseIndex, phases) {
|
|
|
2792
2830
|
)
|
|
2793
2831
|
);
|
|
2794
2832
|
const { child, done: done2 } = spawnClaude(
|
|
2795
|
-
buildPhasePrompt(item, phaseIndex, phase
|
|
2833
|
+
buildPhasePrompt(item, phaseIndex, phase)
|
|
2796
2834
|
);
|
|
2797
2835
|
watchForMarker(child);
|
|
2798
2836
|
await done2;
|
|
@@ -2802,28 +2840,28 @@ async function executePhase(item, phaseIndex, phases) {
|
|
|
2802
2840
|
}
|
|
2803
2841
|
|
|
2804
2842
|
// src/commands/backlog/run.ts
|
|
2805
|
-
function
|
|
2806
|
-
if (
|
|
2807
|
-
|
|
2808
|
-
chalk35.red("Item has no plan. Use /draft to create one with phases.")
|
|
2809
|
-
);
|
|
2810
|
-
return void 0;
|
|
2843
|
+
function resolvePlan(item) {
|
|
2844
|
+
if (item.plan && item.plan.length > 0) {
|
|
2845
|
+
return item.plan;
|
|
2811
2846
|
}
|
|
2812
|
-
return
|
|
2847
|
+
return [
|
|
2848
|
+
{
|
|
2849
|
+
name: "Implement",
|
|
2850
|
+
tasks: item.acceptanceCriteria.map((ac) => ({ task: ac }))
|
|
2851
|
+
}
|
|
2852
|
+
];
|
|
2813
2853
|
}
|
|
2814
2854
|
async function run2(id) {
|
|
2815
2855
|
const result = loadAndFindItem(id);
|
|
2816
2856
|
if (!result) return;
|
|
2817
2857
|
const { item } = result;
|
|
2818
|
-
const plan2 =
|
|
2819
|
-
if (!plan2) return;
|
|
2858
|
+
const plan2 = resolvePlan(item);
|
|
2820
2859
|
const startPhase = item.currentPhase ?? 0;
|
|
2821
|
-
if (startPhase
|
|
2860
|
+
if (startPhase > plan2.length) {
|
|
2822
2861
|
if (item.status !== "done") setStatus(id, "done");
|
|
2823
2862
|
console.log(
|
|
2824
2863
|
chalk35.green(`All phases already complete for #${id}: ${item.name}`)
|
|
2825
2864
|
);
|
|
2826
|
-
console.log(chalk35.dim("Review the changes, then use /commit when ready."));
|
|
2827
2865
|
return;
|
|
2828
2866
|
}
|
|
2829
2867
|
setStatus(id, "in-progress");
|
|
@@ -2842,10 +2880,14 @@ async function run2(id) {
|
|
|
2842
2880
|
phaseIndex = await executePhase(item, phaseIndex, plan2);
|
|
2843
2881
|
if (phaseIndex < 0) return;
|
|
2844
2882
|
}
|
|
2883
|
+
const reviewPhase = buildReviewPhase();
|
|
2884
|
+
const allPhases = [...plan2, reviewPhase];
|
|
2885
|
+
const reviewIndex = plan2.length;
|
|
2886
|
+
const reviewResult = await executePhase(item, reviewIndex, allPhases);
|
|
2887
|
+
if (reviewResult < 0) return;
|
|
2845
2888
|
setStatus(id, "done");
|
|
2846
2889
|
console.log(chalk35.green(`
|
|
2847
2890
|
All phases complete for #${id}: ${item.name}`));
|
|
2848
|
-
console.log(chalk35.dim("Review the changes, then use /commit when ready."));
|
|
2849
2891
|
}
|
|
2850
2892
|
|
|
2851
2893
|
// src/commands/backlog/next.ts
|