@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.
@@ -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). The last phase should always have at least one manual check to confirm the feature works end-to-end.
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.142.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/executePhase.ts
2613
- import chalk34 from "chalk";
2614
-
2615
- // src/commands/backlog/buildPhasePrompt.ts
2616
- function formatTasks(phase) {
2617
- return phase.tasks.map((t) => {
2618
- let line = `- ${t.task}`;
2619
- if (t.verify) line += ` (verify: ${t.verify})`;
2620
- return line;
2621
- }).join("\n");
2622
- }
2623
- function buildManualCheckLines(manualChecks, isLastPhase) {
2624
- if (manualChecks.length > 0) {
2625
- return [
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 buildPhasePrompt(item, phaseIndex, phase, totalPhases) {
2659
- const isLastPhase = phaseIndex === totalPhases - 1;
2660
- const manualChecks = phase.manualChecks ?? [];
2661
- const needsConfirmation = manualChecks.length > 0 || isLastPhase;
2662
- const confirmSuffix = needsConfirmation ? " and the user confirms" : "";
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
- ...buildContextLines(item, phaseIndex, phase),
2666
+ `You are reviewing backlog item #${item.id}: ${item.name}`,
2665
2667
  "",
2666
- "Focus ONLY on this phase. Do not work on other phases.",
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
- `Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseIndex}`
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, phases.length)
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 validatePlan(item) {
2806
- if (!item.plan || item.plan.length === 0) {
2807
- console.log(
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 item.plan;
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 = validatePlan(item);
2819
- if (!plan2) return;
2858
+ const plan2 = resolvePlan(item);
2820
2859
  const startPhase = item.currentPhase ?? 0;
2821
- if (startPhase >= plan2.length) {
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.142.0",
3
+ "version": "0.143.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {