@quinteroac/agents-coding-toolkit 0.1.0-preview

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.
Files changed (85) hide show
  1. package/AGENTS.md +7 -0
  2. package/README.md +127 -0
  3. package/package.json +34 -0
  4. package/scaffold/.agents/flow/archived/tmpl_.gitkeep +0 -0
  5. package/scaffold/.agents/flow/tmpl_README.md +7 -0
  6. package/scaffold/.agents/flow/tmpl_iteration_close_checklist.example.md +11 -0
  7. package/scaffold/.agents/skills/automated-fix/tmpl_SKILL.md +67 -0
  8. package/scaffold/.agents/skills/create-issue/tmpl_SKILL.md +68 -0
  9. package/scaffold/.agents/skills/create-pr-document/tmpl_SKILL.md +125 -0
  10. package/scaffold/.agents/skills/create-project-context/tmpl_SKILL.md +168 -0
  11. package/scaffold/.agents/skills/create-test-plan/tmpl_SKILL.md +86 -0
  12. package/scaffold/.agents/skills/debug/tmpl_SKILL.md +19 -0
  13. package/scaffold/.agents/skills/evaluate/tmpl_SKILL.md +19 -0
  14. package/scaffold/.agents/skills/execute-test-batch/tmpl_SKILL.md +49 -0
  15. package/scaffold/.agents/skills/execute-test-case/tmpl_SKILL.md +47 -0
  16. package/scaffold/.agents/skills/implement-user-story/tmpl_SKILL.md +68 -0
  17. package/scaffold/.agents/skills/plan-refactor/tmpl_SKILL.md +19 -0
  18. package/scaffold/.agents/skills/refactor-prd/tmpl_SKILL.md +19 -0
  19. package/scaffold/.agents/skills/refine-pr-document/tmpl_SKILL.md +108 -0
  20. package/scaffold/.agents/skills/refine-project-context/tmpl_SKILL.md +157 -0
  21. package/scaffold/.agents/skills/refine-test-plan/tmpl_SKILL.md +76 -0
  22. package/scaffold/.agents/tmpl_PROJECT_CONTEXT.md +3 -0
  23. package/scaffold/.agents/tmpl_state.example.json +26 -0
  24. package/scaffold/.agents/tmpl_state_rules.md +29 -0
  25. package/scaffold/docs/nvst-flow/templates/tmpl_CHANGELOG.md +18 -0
  26. package/scaffold/docs/nvst-flow/templates/tmpl_TECHNICAL_DEBT.md +11 -0
  27. package/scaffold/docs/nvst-flow/templates/tmpl_it_000001_evaluation-report.md +19 -0
  28. package/scaffold/docs/nvst-flow/templates/tmpl_it_000001_product-requirement-document.md +19 -0
  29. package/scaffold/docs/nvst-flow/templates/tmpl_it_000001_refactor_plan.md +19 -0
  30. package/scaffold/docs/nvst-flow/templates/tmpl_it_000001_test-plan.md +19 -0
  31. package/scaffold/docs/nvst-flow/tmpl_COMMANDS.md +0 -0
  32. package/scaffold/docs/nvst-flow/tmpl_QUICK_USE.md +0 -0
  33. package/scaffold/docs/tmpl_PLACEHOLDER.md +0 -0
  34. package/scaffold/schemas/node-shims.d.ts +15 -0
  35. package/scaffold/schemas/tmpl_issues.ts +19 -0
  36. package/scaffold/schemas/tmpl_prd.ts +26 -0
  37. package/scaffold/schemas/tmpl_progress.ts +39 -0
  38. package/scaffold/schemas/tmpl_state.ts +81 -0
  39. package/scaffold/schemas/tmpl_test-plan.ts +20 -0
  40. package/scaffold/schemas/tmpl_validate-progress.ts +13 -0
  41. package/scaffold/schemas/tmpl_validate-state.ts +13 -0
  42. package/scaffold/tmpl_AGENTS.md +7 -0
  43. package/schemas/prd.ts +26 -0
  44. package/schemas/progress.ts +39 -0
  45. package/schemas/state.ts +81 -0
  46. package/schemas/test-plan.test.ts +53 -0
  47. package/schemas/test-plan.ts +20 -0
  48. package/schemas/validate-progress.ts +13 -0
  49. package/schemas/validate-state.ts +13 -0
  50. package/src/agent.test.ts +37 -0
  51. package/src/agent.ts +225 -0
  52. package/src/cli-path.ts +4 -0
  53. package/src/cli.ts +578 -0
  54. package/src/commands/approve-project-context.ts +37 -0
  55. package/src/commands/approve-requirement.ts +217 -0
  56. package/src/commands/approve-test-plan.test.ts +193 -0
  57. package/src/commands/approve-test-plan.ts +202 -0
  58. package/src/commands/create-issue.test.ts +484 -0
  59. package/src/commands/create-issue.ts +371 -0
  60. package/src/commands/create-project-context.ts +96 -0
  61. package/src/commands/create-prototype.test.ts +153 -0
  62. package/src/commands/create-prototype.ts +425 -0
  63. package/src/commands/create-test-plan.test.ts +381 -0
  64. package/src/commands/create-test-plan.ts +248 -0
  65. package/src/commands/define-requirement.ts +47 -0
  66. package/src/commands/destroy.ts +113 -0
  67. package/src/commands/execute-automated-fix.test.ts +580 -0
  68. package/src/commands/execute-automated-fix.ts +363 -0
  69. package/src/commands/execute-manual-fix.test.ts +343 -0
  70. package/src/commands/execute-manual-fix.ts +203 -0
  71. package/src/commands/execute-test-plan.test.ts +1891 -0
  72. package/src/commands/execute-test-plan.ts +722 -0
  73. package/src/commands/init.ts +85 -0
  74. package/src/commands/refine-project-context.ts +74 -0
  75. package/src/commands/refine-requirement.ts +60 -0
  76. package/src/commands/refine-test-plan.test.ts +200 -0
  77. package/src/commands/refine-test-plan.ts +93 -0
  78. package/src/commands/start-iteration.test.ts +144 -0
  79. package/src/commands/start-iteration.ts +101 -0
  80. package/src/commands/write-json.ts +136 -0
  81. package/src/install.test.ts +124 -0
  82. package/src/pack.test.ts +103 -0
  83. package/src/state.test.ts +66 -0
  84. package/src/state.ts +52 -0
  85. package/tsconfig.json +15 -0
@@ -0,0 +1,203 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { createInterface } from "node:readline/promises";
4
+
5
+ import {
6
+ invokeAgent,
7
+ type AgentInvokeOptions,
8
+ type AgentProvider,
9
+ type AgentResult,
10
+ } from "../agent";
11
+ import { exists, FLOW_REL_DIR, readState } from "../state";
12
+ import { IssuesSchema, type Issue } from "../../scaffold/schemas/tmpl_issues";
13
+ import type { State } from "../../scaffold/schemas/tmpl_state";
14
+
15
+ export interface ExecuteManualFixOptions {
16
+ provider: AgentProvider;
17
+ }
18
+
19
+ interface ExecuteManualFixDeps {
20
+ existsFn: (path: string) => Promise<boolean>;
21
+ invokeAgentFn: (options: AgentInvokeOptions) => Promise<AgentResult>;
22
+ logFn: (message: string) => void;
23
+ promptIssueOutcomeFn: (question: string) => Promise<IssueOutcomeAction>;
24
+ promptProceedFn: (question: string) => Promise<boolean>;
25
+ readFileFn: typeof readFile;
26
+ readStateFn: (projectRoot: string) => Promise<State>;
27
+ writeFileFn: typeof writeFile;
28
+ }
29
+
30
+ const defaultDeps: ExecuteManualFixDeps = {
31
+ existsFn: exists,
32
+ invokeAgentFn: invokeAgent,
33
+ logFn: console.log,
34
+ promptIssueOutcomeFn: promptForIssueOutcome,
35
+ promptProceedFn: promptForConfirmation,
36
+ readFileFn: readFile,
37
+ readStateFn: readState,
38
+ writeFileFn: writeFile,
39
+ };
40
+
41
+ export type IssueOutcomeAction = "fixed" | "skip" | "exit";
42
+
43
+ export function buildManualFixGuidancePrompt(issue: Issue, iteration: string): string {
44
+ return `You are helping a developer resolve one manual-fix issue.
45
+
46
+ Issue context:
47
+ - Iteration: ${iteration}
48
+ - Issue ID: ${issue.id}
49
+ - Title: ${issue.title}
50
+ - Description:
51
+ ${issue.description}
52
+
53
+ Response requirements:
54
+ 1. Start with a concise summary/analysis of the problem.
55
+ 2. Suggest a concrete reproduction strategy or test case.
56
+ 3. Suggest potential fixes or code changes with rationale.
57
+ 4. After the initial guidance, continue in an interactive chat loop:
58
+ - Answer clarifying questions.
59
+ - Provide code snippets when requested.
60
+ - Keep working on this issue until the user says they are done.
61
+ 5. Do not switch to other issues in this session.`;
62
+ }
63
+
64
+ export async function promptForConfirmation(question: string): Promise<boolean> {
65
+ const readline = createInterface({
66
+ input: process.stdin,
67
+ output: process.stdout,
68
+ });
69
+
70
+ try {
71
+ const answer = (await readline.question(question)).trim();
72
+ return /^y(?:es)?$/i.test(answer);
73
+ } finally {
74
+ readline.close();
75
+ }
76
+ }
77
+
78
+ export async function promptForIssueOutcome(question: string): Promise<IssueOutcomeAction> {
79
+ const readline = createInterface({
80
+ input: process.stdin,
81
+ output: process.stdout,
82
+ });
83
+
84
+ try {
85
+ while (true) {
86
+ const answer = (await readline.question(question)).trim().toLowerCase();
87
+ if (["fixed", "f", "done", "d"].includes(answer)) {
88
+ return "fixed";
89
+ }
90
+ if (["skip", "s", "next", "n"].includes(answer)) {
91
+ return "skip";
92
+ }
93
+ if (["exit", "e", "quit", "q"].includes(answer)) {
94
+ return "exit";
95
+ }
96
+ console.log("Invalid choice. Try (f)ixed, (s)kip, or (e)xit.");
97
+ }
98
+ } finally {
99
+ readline.close();
100
+ }
101
+ }
102
+
103
+ export async function runExecuteManualFix(
104
+ opts: ExecuteManualFixOptions,
105
+ deps: Partial<ExecuteManualFixDeps> = {},
106
+ ): Promise<void> {
107
+ const mergedDeps: ExecuteManualFixDeps = { ...defaultDeps, ...deps };
108
+ const projectRoot = process.cwd();
109
+ const state = await mergedDeps.readStateFn(projectRoot);
110
+
111
+ const iteration = state.current_iteration;
112
+ const fileName = `it_${iteration}_ISSUES.json`;
113
+ const issuesPath = join(projectRoot, FLOW_REL_DIR, fileName);
114
+ const flowRelativePath = join(FLOW_REL_DIR, fileName);
115
+
116
+ if (!(await mergedDeps.existsFn(issuesPath))) {
117
+ throw new Error(
118
+ `Issues file not found: expected ${flowRelativePath}. Run \`bun nvst create issue --agent <provider>\` first.`,
119
+ );
120
+ }
121
+
122
+ let parsedIssuesRaw: unknown;
123
+ try {
124
+ parsedIssuesRaw = JSON.parse(await mergedDeps.readFileFn(issuesPath, "utf8"));
125
+ } catch {
126
+ throw new Error(
127
+ `Deterministic validation error: invalid issues JSON in ${flowRelativePath}.`,
128
+ );
129
+ }
130
+
131
+ const validation = IssuesSchema.safeParse(parsedIssuesRaw);
132
+ if (!validation.success) {
133
+ throw new Error(
134
+ `Deterministic validation error: issues schema mismatch in ${flowRelativePath}.`,
135
+ );
136
+ }
137
+
138
+ const manualFixIssues = validation.data.filter((issue: Issue) => issue.status === "manual-fix");
139
+ mergedDeps.logFn(
140
+ `Found ${manualFixIssues.length} issue(s) with status 'manual-fix' in ${flowRelativePath}.`,
141
+ );
142
+
143
+ const proceed = await mergedDeps.promptProceedFn(
144
+ `Proceed with manual-fix processing for ${manualFixIssues.length} issue(s) using '${opts.provider}'? [y/N] `,
145
+ );
146
+ if (!proceed) {
147
+ mergedDeps.logFn("Manual-fix execution cancelled.");
148
+ return;
149
+ }
150
+
151
+ if (manualFixIssues.length === 0) {
152
+ mergedDeps.logFn("No manual-fix issues to process. Exiting without changes.");
153
+ return;
154
+ }
155
+
156
+ mergedDeps.logFn(`Ready to process ${manualFixIssues.length} manual-fix issue(s).`);
157
+
158
+ for (const [index, issue] of manualFixIssues.entries()) {
159
+ mergedDeps.logFn("\n" + "=".repeat(60));
160
+ mergedDeps.logFn(
161
+ `Issue ${index + 1}/${manualFixIssues.length}: ${issue.id} - ${issue.title}`,
162
+ );
163
+ mergedDeps.logFn("-".repeat(60));
164
+ mergedDeps.logFn(issue.description);
165
+ mergedDeps.logFn("-".repeat(60));
166
+ mergedDeps.logFn(`Starting interactive session with '${opts.provider}'.`);
167
+ mergedDeps.logFn("When finished, exit the agent session (e.g., via '/exit' or Ctrl+D) to return here.");
168
+ mergedDeps.logFn("=".repeat(60) + "\n");
169
+
170
+ const prompt = buildManualFixGuidancePrompt(issue, iteration);
171
+ const result = await mergedDeps.invokeAgentFn({
172
+ provider: opts.provider,
173
+ prompt,
174
+ cwd: projectRoot,
175
+ interactive: true,
176
+ });
177
+
178
+ if (result.exitCode !== 0) {
179
+ throw new Error(
180
+ `Agent invocation failed while guiding issue ${issue.id} with exit code ${result.exitCode}.`,
181
+ );
182
+ }
183
+
184
+ const action = await mergedDeps.promptIssueOutcomeFn(
185
+ "Action? (f)ixed, (s)kip, (e)xit: ",
186
+ );
187
+
188
+ if (action === "fixed") {
189
+ issue.status = "fixed";
190
+ await mergedDeps.writeFileFn(issuesPath, `${JSON.stringify(validation.data, null, 2)}\n`, "utf8");
191
+ mergedDeps.logFn(`${issue.id}: marked as fixed.`);
192
+ continue;
193
+ }
194
+
195
+ if (action === "skip") {
196
+ mergedDeps.logFn(`${issue.id}: skipped. Status remains manual-fix.`);
197
+ continue;
198
+ }
199
+
200
+ mergedDeps.logFn("Exiting manual-fix session by user request.");
201
+ break;
202
+ }
203
+ }