@quinteroac/agents-coding-toolkit 0.1.0-preview → 0.1.1-preview.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/README.md +1 -1
- package/package.json +13 -4
- package/scaffold/.agents/skills/execute-refactor-item/tmpl_SKILL.md +59 -0
- package/scaffold/.agents/skills/plan-refactor/tmpl_SKILL.md +89 -9
- package/scaffold/.agents/skills/refine-refactor-plan/tmpl_SKILL.md +30 -0
- package/scaffold/.agents/tmpl_state_rules.md +0 -1
- package/scaffold/schemas/tmpl_refactor-execution-progress.ts +16 -0
- package/scaffold/schemas/tmpl_refactor-prd.ts +14 -0
- package/scaffold/schemas/tmpl_state.ts +1 -0
- package/schemas/refactor-execution-progress.ts +16 -0
- package/schemas/refactor-prd.ts +14 -0
- package/schemas/state.test.ts +58 -0
- package/schemas/state.ts +1 -0
- package/schemas/test-plan.test.ts +1 -1
- package/src/cli.test.ts +57 -0
- package/src/cli.ts +180 -56
- package/src/commands/approve-project-context.ts +13 -6
- package/src/commands/approve-refactor-plan.test.ts +254 -0
- package/src/commands/approve-refactor-plan.ts +200 -0
- package/src/commands/approve-requirement.test.ts +224 -0
- package/src/commands/approve-requirement.ts +75 -16
- package/src/commands/approve-test-plan.test.ts +2 -2
- package/src/commands/approve-test-plan.ts +21 -7
- package/src/commands/create-issue.test.ts +2 -2
- package/src/commands/create-project-context.ts +31 -25
- package/src/commands/create-prototype.test.ts +31 -13
- package/src/commands/create-prototype.ts +17 -7
- package/src/commands/create-test-plan.ts +8 -6
- package/src/commands/define-refactor-plan.test.ts +208 -0
- package/src/commands/define-refactor-plan.ts +96 -0
- package/src/commands/define-requirement.ts +15 -9
- package/src/commands/execute-refactor.test.ts +954 -0
- package/src/commands/execute-refactor.ts +336 -0
- package/src/commands/execute-test-plan.test.ts +9 -2
- package/src/commands/execute-test-plan.ts +13 -6
- package/src/commands/refine-project-context.ts +9 -7
- package/src/commands/refine-refactor-plan.test.ts +210 -0
- package/src/commands/refine-refactor-plan.ts +95 -0
- package/src/commands/refine-requirement.ts +9 -6
- package/src/commands/refine-test-plan.test.ts +2 -2
- package/src/commands/refine-test-plan.ts +9 -6
- package/src/commands/write-json.ts +102 -97
- package/src/force-flag.test.ts +144 -0
- package/src/guardrail.test.ts +411 -0
- package/src/guardrail.ts +104 -0
- package/src/install.test.ts +7 -5
- package/src/pack.test.ts +2 -1
- package/scaffold/.agents/flow/tmpl_README.md +0 -7
- package/scaffold/.agents/flow/tmpl_iteration_close_checklist.example.md +0 -11
- package/schemas/test-plan.ts +0 -20
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ nerds-vst is a package that provides:
|
|
|
73
73
|
|-------|----------|
|
|
74
74
|
| **Iteration** | `bun nvst start iteration` — Start or advance to the next iteration (archives current, resets state). |
|
|
75
75
|
| **Define** | `bun nvst define requirement` → `bun nvst refine requirement` (optional) → `bun nvst approve requirement` → `bun nvst create prd` |
|
|
76
|
-
| **Prototype** | `bun nvst create project-context` → `bun nvst approve project-context` → `bun nvst create prototype` → `bun nvst define test-plan` → `bun nvst approve test-plan` → `bun nvst execute test-plan` → `bun nvst execute automated-fix` / `bun nvst execute manual-fix` →
|
|
76
|
+
| **Prototype** | `bun nvst create project-context` → `bun nvst approve project-context` → `bun nvst create prototype` → `bun nvst define test-plan` → `bun nvst approve test-plan` → `bun nvst execute test-plan` → `bun nvst execute automated-fix` / `bun nvst execute manual-fix` → when all tests pass, prototype is done and Refactor can begin |
|
|
77
77
|
| **Refactor** | `bun nvst define refactor-plan` → `bun nvst approve refactor-plan` → `bun nvst create prd --refactor` → `bun nvst execute refactor` → update PROJECT_CONTEXT, CHANGELOG → then `bun nvst start iteration` for next iteration |
|
|
78
78
|
|
|
79
79
|
|
package/package.json
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
"registry": "https://registry.npmjs.org",
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.1.
|
|
7
|
+
"version": "0.1.1-preview.0",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/quinteroac/nerds-vibecoding-survivor-toolkit.git"
|
|
10
|
+
"url": "git+https://github.com/quinteroac/nerds-vibecoding-survivor-toolkit.git"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"nvst": "src/cli.ts"
|
|
11
14
|
},
|
|
12
|
-
"bin": { "nvst": "src/cli.ts" },
|
|
13
15
|
"files": [
|
|
14
16
|
"src",
|
|
15
17
|
"scaffold",
|
|
@@ -19,9 +21,16 @@
|
|
|
19
21
|
"tsconfig.json"
|
|
20
22
|
],
|
|
21
23
|
"scripts": {
|
|
24
|
+
"test": "bun test src tests schemas",
|
|
22
25
|
"package": "npm pack",
|
|
26
|
+
"bump": "npm version",
|
|
27
|
+
"bump:patch": "npm version patch",
|
|
28
|
+
"bump:minor": "npm version minor",
|
|
29
|
+
"bump:major": "npm version major",
|
|
30
|
+
"bump:preview": "npm version prerelease",
|
|
23
31
|
"validate:state": "bun run scaffold/schemas/tmpl_validate-state.ts",
|
|
24
|
-
"validate:progress": "bun run scaffold/schemas/tmpl_validate-progress.ts"
|
|
32
|
+
"validate:progress": "bun run scaffold/schemas/tmpl_validate-progress.ts",
|
|
33
|
+
"sync-check": "bun run scripts/sync-check.ts"
|
|
25
34
|
},
|
|
26
35
|
"dependencies": {
|
|
27
36
|
"zod": "^3.23.8"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: execute-refactor-item
|
|
3
|
+
description: "Applies a single approved refactor item (RI-NNN) to the codebase. Invoked by: bun nvst execute refactor."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Execute Refactor Item
|
|
8
|
+
|
|
9
|
+
Apply the provided refactor item to the codebase, following the project's conventions and architecture.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## The Job
|
|
14
|
+
|
|
15
|
+
1. Read the **refactor item** (`id`, `title`, `description`, `rationale`) carefully.
|
|
16
|
+
2. Review the **project context** to understand conventions, tech stack, and module structure.
|
|
17
|
+
3. Plan the change: identify which files to create or modify and how the change fits into the existing architecture.
|
|
18
|
+
4. Apply the refactor:
|
|
19
|
+
- Make the changes described in the item's `description`.
|
|
20
|
+
- Ensure the code compiles / type-checks without errors after the change.
|
|
21
|
+
- Run any quality checks defined in the project context and fix failures before finishing.
|
|
22
|
+
5. Do **not** commit — the calling command manages git operations.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Inputs
|
|
27
|
+
|
|
28
|
+
| Source | Used for |
|
|
29
|
+
|--------|----------|
|
|
30
|
+
| `refactor_item_id` (context variable) | The refactor item identifier (e.g. `RI-001`) |
|
|
31
|
+
| `refactor_item_title` (context variable) | Short title of the refactor item |
|
|
32
|
+
| `refactor_item_description` (context variable) | Detailed description of the change to apply |
|
|
33
|
+
| `refactor_item_rationale` (context variable) | Why this refactor is needed |
|
|
34
|
+
| `iteration` (context variable) | Current iteration number for context |
|
|
35
|
+
| `.agents/PROJECT_CONTEXT.md` | Documented conventions, architecture, and standards to follow |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
- **One item at a time.** Apply only the refactor item provided — do not make unrelated changes.
|
|
42
|
+
- **Follow conventions exactly.** Use the naming, formatting, error handling, and module organisation patterns from the project context.
|
|
43
|
+
- **No new dependencies** unless the refactor item explicitly requires them.
|
|
44
|
+
- **Do not modify state files.** Do not touch `.agents/state.json` or progress files — the calling command manages those.
|
|
45
|
+
- **Do not commit.** The calling command handles git operations.
|
|
46
|
+
- **Keep changes minimal.** Only modify files necessary to apply the refactor item.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Checklist
|
|
51
|
+
|
|
52
|
+
Before finishing:
|
|
53
|
+
|
|
54
|
+
- [ ] Refactor item changes are applied as described
|
|
55
|
+
- [ ] Code compiles / type-checks without errors
|
|
56
|
+
- [ ] Quality checks pass
|
|
57
|
+
- [ ] No unrelated changes were made
|
|
58
|
+
- [ ] No state files were modified
|
|
59
|
+
- [ ] No git commits were made
|
|
@@ -1,19 +1,99 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: plan-refactor
|
|
3
|
+
description: "Evaluates the prototype and produces an ordered refactor plan. Triggered by: bun nvst define refactor-plan."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
# Evaluate and Plan Refactor
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
This skill runs in two parts within a single session. **Do NOT implement code.** Only produce documents.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
## Part 1: Evaluate the Prototype
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
Evaluate the current prototype before planning refactorings.
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
### Evaluation Inputs
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
| Source | Used for |
|
|
18
|
+
|--------|----------|
|
|
19
|
+
| `.agents/PROJECT_CONTEXT.md` | Documented conventions, architecture, and standards to validate against |
|
|
20
|
+
| `.agents/TECHNICAL_DEBT.md` | Existing technical debt (if present) |
|
|
21
|
+
| `.agents/flow/it_{current_iteration}_PRD.json` | Implemented scope for this iteration |
|
|
22
|
+
| Prototype codebase | Actual structure, patterns, and quality |
|
|
14
23
|
|
|
15
|
-
|
|
24
|
+
### Evaluation Output
|
|
25
|
+
|
|
26
|
+
Write `it_{current_iteration}_evaluation-report.md` to `.agents/flow/` with this structure:
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
# Evaluation Report — Iteration {current_iteration}
|
|
30
|
+
|
|
31
|
+
## Strengths
|
|
32
|
+
- What works well in the current prototype
|
|
33
|
+
|
|
34
|
+
## Technical Debt
|
|
35
|
+
- Known debt items, with brief impact/effort notes
|
|
36
|
+
|
|
37
|
+
## Violations of PROJECT_CONTEXT.md
|
|
38
|
+
- Conventions, architecture, or standards not followed
|
|
39
|
+
|
|
40
|
+
## Recommendations
|
|
41
|
+
Each item: description, impact, urgency, effort, scope. Optional numeric score for ordering.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Complete Part 1 before starting Part 2. The evaluation report is the input for the refactor plan.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Part 2: Define the Refactor Plan
|
|
49
|
+
|
|
50
|
+
From the evaluation report you just produced, define an ordered refactor plan.
|
|
51
|
+
|
|
52
|
+
### Plan Inputs
|
|
53
|
+
|
|
54
|
+
| Source | Used for |
|
|
55
|
+
|--------|----------|
|
|
56
|
+
| `it_{current_iteration}_evaluation-report.md` | Issues, technical debt, and recommendations to prioritise |
|
|
57
|
+
| User (interactive) | Decisions on trade-offs or approaches that need clarification |
|
|
58
|
+
|
|
59
|
+
### Plan Output
|
|
60
|
+
|
|
61
|
+
Write `it_{current_iteration}_refactor-plan.md` to `.agents/flow/` with this structure:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
# Refactor Plan — Iteration {current_iteration}
|
|
65
|
+
|
|
66
|
+
## Refactor Items
|
|
67
|
+
|
|
68
|
+
### RI-001: <Title>
|
|
69
|
+
|
|
70
|
+
**Description:** One or two sentences describing what needs to change and why it is a problem.
|
|
71
|
+
|
|
72
|
+
**Rationale:** Why this item is prioritised at this position — impact, urgency, or risk reduction.
|
|
73
|
+
|
|
74
|
+
### RI-002: <Title>
|
|
75
|
+
|
|
76
|
+
**Description:** ...
|
|
77
|
+
|
|
78
|
+
**Rationale:** ...
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Plan Instructions
|
|
82
|
+
|
|
83
|
+
1. Read the evaluation report in full before writing the refactor plan.
|
|
84
|
+
2. Identify quick wins (low effort, high impact) and critical refactorings (high urgency or high risk).
|
|
85
|
+
3. For items that require a user decision (e.g. trade-offs between approaches), ask the user before committing to an entry.
|
|
86
|
+
4. Order items by priority: critical blockers first, quick wins second, long-term improvements last.
|
|
87
|
+
5. Assign each item a unique id in `RI-NNN` format (e.g. `RI-001`, `RI-002`).
|
|
88
|
+
6. Write the refactor plan file.
|
|
89
|
+
|
|
90
|
+
---
|
|
16
91
|
|
|
17
92
|
## Checklist
|
|
18
93
|
|
|
19
|
-
|
|
94
|
+
- [ ] Output is in English
|
|
95
|
+
- [ ] Part 1: `it_{current_iteration}_evaluation-report.md` written to `.agents/flow/`
|
|
96
|
+
- [ ] Part 2: `it_{current_iteration}_refactor-plan.md` written to `.agents/flow/`
|
|
97
|
+
- [ ] Each refactor item has a unique `RI-NNN` id, `**Description:**`, and `**Rationale:**`
|
|
98
|
+
- [ ] Refactor items are ordered by priority
|
|
99
|
+
- [ ] State files are not modified by this skill
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refine-refactor-plan
|
|
3
|
+
description: "Refines an existing refactor plan based on user feedback or adversarial challenge mode. Triggered by: bun nvst refine refactor-plan."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Refine Refactor Plan
|
|
8
|
+
|
|
9
|
+
Update `it_{current_iteration}_refactor-plan.md` in place. The file already exists and is provided in context.
|
|
10
|
+
|
|
11
|
+
**Do NOT implement code. Only revise the refactor plan document.**
|
|
12
|
+
|
|
13
|
+
> **Two modes available — determined by the `mode` context variable:**
|
|
14
|
+
> - **Editor mode** (default): apply user-requested updates to the plan.
|
|
15
|
+
> - **Challenger mode** (`mode = "challenger"`): challenge sequencing, risk handling, and testability before applying edits.
|
|
16
|
+
|
|
17
|
+
## Inputs
|
|
18
|
+
|
|
19
|
+
| Source | Used for |
|
|
20
|
+
|--------|----------|
|
|
21
|
+
| `refactor_plan_file` | Current plan file name |
|
|
22
|
+
| `refactor_plan_content` | Existing plan content |
|
|
23
|
+
| User responses | Clarifications and approval of proposed edits |
|
|
24
|
+
|
|
25
|
+
## Checklist
|
|
26
|
+
|
|
27
|
+
- [ ] Output remains in English
|
|
28
|
+
- [ ] Accepted changes are applied to the existing refactor plan file
|
|
29
|
+
- [ ] Same output file path is preserved (refine in place, do not write a new file)
|
|
30
|
+
- [ ] State files are not modified by this skill
|
|
@@ -20,7 +20,6 @@ Each command must validate the relevant fields of `state.json` before running. I
|
|
|
20
20
|
| `bun execute test-plan` | TBD | TBD |
|
|
21
21
|
| `bun execute automated-fix` | TBD | TBD |
|
|
22
22
|
| `bun execute manual-fix` | TBD | TBD |
|
|
23
|
-
| `bun approve prototype` | TBD | TBD |
|
|
24
23
|
| `bun define refactor-plan` | TBD | TBD |
|
|
25
24
|
| `bun refine refactor-plan` | TBD | TBD |
|
|
26
25
|
| `bun approve refactor-plan` | TBD | TBD |
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const RefactorExecutionEntrySchema = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
title: z.string(),
|
|
6
|
+
status: z.enum(["pending", "in_progress", "completed", "failed"]),
|
|
7
|
+
attempt_count: z.number().int(),
|
|
8
|
+
last_agent_exit_code: z.number().int().nullable(),
|
|
9
|
+
updated_at: z.string(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const RefactorExecutionProgressSchema = z.object({
|
|
13
|
+
entries: z.array(RefactorExecutionEntrySchema),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type RefactorExecutionProgress = z.infer<typeof RefactorExecutionProgressSchema>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const RefactorItemSchema = z.object({
|
|
4
|
+
id: z.string().regex(/^RI-\d{3}$/),
|
|
5
|
+
title: z.string().min(1),
|
|
6
|
+
description: z.string().min(1),
|
|
7
|
+
rationale: z.string().min(1),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export const RefactorPrdSchema = z.object({
|
|
11
|
+
refactorItems: z.array(RefactorItemSchema).min(1),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type RefactorPrd = z.infer<typeof RefactorPrdSchema>;
|
|
@@ -68,6 +68,7 @@ const historyEntry = z.object({
|
|
|
68
68
|
export const StateSchema = z.object({
|
|
69
69
|
current_iteration: iterationId,
|
|
70
70
|
current_phase: phase,
|
|
71
|
+
flow_guardrail: z.enum(["strict", "relaxed"]).optional(),
|
|
71
72
|
phases: z.object({
|
|
72
73
|
define: definePhase,
|
|
73
74
|
prototype: prototypePhase,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const RefactorExecutionEntrySchema = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
title: z.string(),
|
|
6
|
+
status: z.enum(["pending", "in_progress", "completed", "failed"]),
|
|
7
|
+
attempt_count: z.number().int(),
|
|
8
|
+
last_agent_exit_code: z.number().int().nullable(),
|
|
9
|
+
updated_at: z.string(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const RefactorExecutionProgressSchema = z.object({
|
|
13
|
+
entries: z.array(RefactorExecutionEntrySchema),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type RefactorExecutionProgress = z.infer<typeof RefactorExecutionProgressSchema>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const RefactorItemSchema = z.object({
|
|
4
|
+
id: z.string().regex(/^RI-\d{3}$/),
|
|
5
|
+
title: z.string().min(1),
|
|
6
|
+
description: z.string().min(1),
|
|
7
|
+
rationale: z.string().min(1),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export const RefactorPrdSchema = z.object({
|
|
11
|
+
refactorItems: z.array(RefactorItemSchema).min(1),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type RefactorPrd = z.infer<typeof RefactorPrdSchema>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { StateSchema as ScaffoldStateSchema } from "../scaffold/schemas/tmpl_state";
|
|
4
|
+
import { StateSchema as WorkingCopyStateSchema } from "./state";
|
|
5
|
+
|
|
6
|
+
function makeValidState(): Record<string, unknown> {
|
|
7
|
+
return {
|
|
8
|
+
current_iteration: "000001",
|
|
9
|
+
current_phase: "define",
|
|
10
|
+
phases: {
|
|
11
|
+
define: {
|
|
12
|
+
requirement_definition: { status: "pending", file: null },
|
|
13
|
+
prd_generation: { status: "pending", file: null },
|
|
14
|
+
},
|
|
15
|
+
prototype: {
|
|
16
|
+
project_context: { status: "pending", file: null },
|
|
17
|
+
test_plan: { status: "pending", file: null },
|
|
18
|
+
tp_generation: { status: "pending", file: null },
|
|
19
|
+
prototype_build: { status: "pending", file: null },
|
|
20
|
+
test_execution: { status: "pending", file: null },
|
|
21
|
+
prototype_approved: false,
|
|
22
|
+
},
|
|
23
|
+
refactor: {
|
|
24
|
+
evaluation_report: { status: "pending", file: null },
|
|
25
|
+
refactor_plan: { status: "pending", file: null },
|
|
26
|
+
refactor_execution: { status: "pending", file: null },
|
|
27
|
+
changelog: { status: "pending", file: null },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
last_updated: "2026-01-01T00:00:00.000Z",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("US-003 state schema parity", () => {
|
|
35
|
+
test("US-003-AC01/AC02/AC05: both schemas accept state without flow_guardrail", () => {
|
|
36
|
+
const input = makeValidState();
|
|
37
|
+
|
|
38
|
+
expect(ScaffoldStateSchema.safeParse(input).success).toBe(true);
|
|
39
|
+
expect(WorkingCopyStateSchema.safeParse(input).success).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("US-003-AC01/AC02: both schemas accept flow_guardrail='strict' and 'relaxed'", () => {
|
|
43
|
+
const strictInput = { ...makeValidState(), flow_guardrail: "strict" };
|
|
44
|
+
const relaxedInput = { ...makeValidState(), flow_guardrail: "relaxed" };
|
|
45
|
+
|
|
46
|
+
expect(ScaffoldStateSchema.safeParse(strictInput).success).toBe(true);
|
|
47
|
+
expect(ScaffoldStateSchema.safeParse(relaxedInput).success).toBe(true);
|
|
48
|
+
expect(WorkingCopyStateSchema.safeParse(strictInput).success).toBe(true);
|
|
49
|
+
expect(WorkingCopyStateSchema.safeParse(relaxedInput).success).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("US-003-AC01/AC02: both schemas reject non-enum flow_guardrail", () => {
|
|
53
|
+
const invalidInput = { ...makeValidState(), flow_guardrail: "lenient" };
|
|
54
|
+
|
|
55
|
+
expect(ScaffoldStateSchema.safeParse(invalidInput).success).toBe(false);
|
|
56
|
+
expect(WorkingCopyStateSchema.safeParse(invalidInput).success).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
});
|
package/schemas/state.ts
CHANGED
|
@@ -68,6 +68,7 @@ const historyEntry = z.object({
|
|
|
68
68
|
export const StateSchema = z.object({
|
|
69
69
|
current_iteration: iterationId,
|
|
70
70
|
current_phase: phase,
|
|
71
|
+
flow_guardrail: z.enum(["strict", "relaxed"]).optional(),
|
|
71
72
|
phases: z.object({
|
|
72
73
|
define: definePhase,
|
|
73
74
|
prototype: prototypePhase,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import { TestPlanSchema } from "
|
|
3
|
+
import { TestPlanSchema } from "../scaffold/schemas/tmpl_test-plan";
|
|
4
4
|
|
|
5
5
|
describe("TestPlanSchema", () => {
|
|
6
6
|
test("accepts enhanced test plan metadata structure", () => {
|
package/src/cli.test.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
describe("US-005: execute refactor CLI routing and help text", () => {
|
|
6
|
+
// AC01: cli.ts routes `execute refactor` to runExecuteRefactor handler
|
|
7
|
+
test("cli.ts routes execute refactor subcommand to runExecuteRefactor", async () => {
|
|
8
|
+
const source = await readFile(join(import.meta.dir, "cli.ts"), "utf8");
|
|
9
|
+
expect(source).toContain('import { runExecuteRefactor } from "./commands/execute-refactor"');
|
|
10
|
+
expect(source).toContain('if (subcommand === "refactor")');
|
|
11
|
+
expect(source).toContain("await runExecuteRefactor({ provider, force })");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// AC02: printUsage includes `execute refactor --agent <provider>` with a one-line description
|
|
15
|
+
test("printUsage includes execute refactor --agent <provider> with one-line description", async () => {
|
|
16
|
+
const source = await readFile(join(import.meta.dir, "cli.ts"), "utf8");
|
|
17
|
+
expect(source).toContain("execute refactor --agent <provider>");
|
|
18
|
+
expect(source).toContain("Execute approved refactor items via agent in order");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// AC03: Unknown options after --agent <provider> cause clear error and exit code 1
|
|
22
|
+
test("unknown options after --agent <provider> cause clear error message and exit code 1", async () => {
|
|
23
|
+
const cliPath = join(import.meta.dir, "cli.ts");
|
|
24
|
+
const proc = Bun.spawn(
|
|
25
|
+
["bun", cliPath, "execute", "refactor", "--agent", "claude", "--unknown-flag"],
|
|
26
|
+
{
|
|
27
|
+
stdout: "pipe",
|
|
28
|
+
stderr: "pipe",
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
const exitCode = await proc.exited;
|
|
32
|
+
const stderrText = await new Response(proc.stderr).text();
|
|
33
|
+
|
|
34
|
+
expect(exitCode).toBe(1);
|
|
35
|
+
expect(stderrText).toContain("Unknown option(s) for execute refactor");
|
|
36
|
+
expect(stderrText).toContain("--unknown-flag");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// AC03: Multiple unknown options after --agent <provider> are all reported
|
|
40
|
+
test("multiple unknown options after --agent <provider> are all listed in error message", async () => {
|
|
41
|
+
const cliPath = join(import.meta.dir, "cli.ts");
|
|
42
|
+
const proc = Bun.spawn(
|
|
43
|
+
["bun", cliPath, "execute", "refactor", "--agent", "claude", "--foo", "--bar"],
|
|
44
|
+
{
|
|
45
|
+
stdout: "pipe",
|
|
46
|
+
stderr: "pipe",
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
const exitCode = await proc.exited;
|
|
50
|
+
const stderrText = await new Response(proc.stderr).text();
|
|
51
|
+
|
|
52
|
+
expect(exitCode).toBe(1);
|
|
53
|
+
expect(stderrText).toContain("Unknown option(s) for execute refactor");
|
|
54
|
+
expect(stderrText).toContain("--foo");
|
|
55
|
+
expect(stderrText).toContain("--bar");
|
|
56
|
+
});
|
|
57
|
+
});
|