procedure-cli 0.1.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.
Files changed (104) hide show
  1. package/.claude/settings.local.json +23 -0
  2. package/.env.example +2 -0
  3. package/AGENTS.md +113 -0
  4. package/CLAUDE.md +136 -0
  5. package/CODE-FIXED.md +124 -0
  6. package/CODE-REVIEW.md +253 -0
  7. package/README.md +130 -0
  8. package/config/defaults.json +8 -0
  9. package/config/powerline-config.json +52 -0
  10. package/config/stacks/typescript-node.json +15 -0
  11. package/dist/app.d.ts +1 -0
  12. package/dist/app.js +131 -0
  13. package/dist/app.js.map +1 -0
  14. package/dist/cli.d.ts +2 -0
  15. package/dist/cli.js +6 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/components/banner.d.ts +1 -0
  18. package/dist/components/banner.js +11 -0
  19. package/dist/components/banner.js.map +1 -0
  20. package/dist/components/gutter-line.d.ts +5 -0
  21. package/dist/components/gutter-line.js +9 -0
  22. package/dist/components/gutter-line.js.map +1 -0
  23. package/dist/components/guttered-select.d.ts +25 -0
  24. package/dist/components/guttered-select.js +68 -0
  25. package/dist/components/guttered-select.js.map +1 -0
  26. package/dist/components/step-indicator.d.ts +7 -0
  27. package/dist/components/step-indicator.js +12 -0
  28. package/dist/components/step-indicator.js.map +1 -0
  29. package/dist/components/timeline.d.ts +13 -0
  30. package/dist/components/timeline.js +26 -0
  31. package/dist/components/timeline.js.map +1 -0
  32. package/dist/lib/fs.d.ts +3 -0
  33. package/dist/lib/fs.js +15 -0
  34. package/dist/lib/fs.js.map +1 -0
  35. package/dist/lib/git.d.ts +4 -0
  36. package/dist/lib/git.js +37 -0
  37. package/dist/lib/git.js.map +1 -0
  38. package/dist/lib/powerline.d.ts +1 -0
  39. package/dist/lib/powerline.js +30 -0
  40. package/dist/lib/powerline.js.map +1 -0
  41. package/dist/lib/template.d.ts +9 -0
  42. package/dist/lib/template.js +46 -0
  43. package/dist/lib/template.js.map +1 -0
  44. package/dist/lib/types.d.ts +44 -0
  45. package/dist/lib/types.js +2 -0
  46. package/dist/lib/types.js.map +1 -0
  47. package/dist/providers/openai.d.ts +1 -0
  48. package/dist/providers/openai.js +5 -0
  49. package/dist/providers/openai.js.map +1 -0
  50. package/dist/providers/zai.d.ts +1 -0
  51. package/dist/providers/zai.js +7 -0
  52. package/dist/providers/zai.js.map +1 -0
  53. package/dist/steps/architecture.d.ts +6 -0
  54. package/dist/steps/architecture.js +39 -0
  55. package/dist/steps/architecture.js.map +1 -0
  56. package/dist/steps/build-test.d.ts +7 -0
  57. package/dist/steps/build-test.js +38 -0
  58. package/dist/steps/build-test.js.map +1 -0
  59. package/dist/steps/generation.d.ts +7 -0
  60. package/dist/steps/generation.js +60 -0
  61. package/dist/steps/generation.js.map +1 -0
  62. package/dist/steps/powerline.d.ts +7 -0
  63. package/dist/steps/powerline.js +62 -0
  64. package/dist/steps/powerline.js.map +1 -0
  65. package/dist/steps/product-context.d.ts +7 -0
  66. package/dist/steps/product-context.js +90 -0
  67. package/dist/steps/product-context.js.map +1 -0
  68. package/dist/steps/project-info.d.ts +6 -0
  69. package/dist/steps/project-info.js +61 -0
  70. package/dist/steps/project-info.js.map +1 -0
  71. package/dist/steps/stack-style.d.ts +6 -0
  72. package/dist/steps/stack-style.js +67 -0
  73. package/dist/steps/stack-style.js.map +1 -0
  74. package/docs/GIAI-THICH-CLAUDE-MD.md +206 -0
  75. package/docs/PRD.md +130 -0
  76. package/docs/USER-STORIES.md +181 -0
  77. package/package.json +38 -0
  78. package/src/app.tsx +201 -0
  79. package/src/cli.tsx +6 -0
  80. package/src/components/banner.tsx +23 -0
  81. package/src/components/gutter-line.tsx +10 -0
  82. package/src/components/guttered-select.tsx +137 -0
  83. package/src/components/step-indicator.tsx +19 -0
  84. package/src/components/timeline.tsx +49 -0
  85. package/src/lib/fs.ts +18 -0
  86. package/src/lib/git.ts +41 -0
  87. package/src/lib/powerline.ts +48 -0
  88. package/src/lib/template.ts +59 -0
  89. package/src/lib/types.ts +68 -0
  90. package/src/providers/openai.ts +5 -0
  91. package/src/providers/zai.ts +7 -0
  92. package/src/steps/architecture.tsx +71 -0
  93. package/src/steps/build-test.tsx +78 -0
  94. package/src/steps/generation.tsx +146 -0
  95. package/src/steps/powerline.tsx +149 -0
  96. package/src/steps/product-context.tsx +182 -0
  97. package/src/steps/project-info.tsx +135 -0
  98. package/src/steps/stack-style.tsx +117 -0
  99. package/templates/.env.example.hbs +6 -0
  100. package/templates/CLAUDE.md.hbs +105 -0
  101. package/templates/README.md.hbs +26 -0
  102. package/templates/docs/PRD.md.hbs +29 -0
  103. package/templates/docs/USER-STORIES.md.hbs +46 -0
  104. package/tsconfig.json +17 -0
@@ -0,0 +1,182 @@
1
+ import React, { useState } from "react";
2
+ import { Text } from "ink";
3
+ import { TextInput } from "@inkjs/ui";
4
+ import { GutterLine } from "../components/gutter-line.js";
5
+ import { GutteredMultiSelect } from "../components/guttered-select.js";
6
+ import type { WizardAnswers } from "../lib/types.js";
7
+
8
+ interface Props {
9
+ initialValues?: Partial<WizardAnswers>;
10
+ onComplete: (answers: Partial<WizardAnswers>) => void;
11
+ }
12
+
13
+ type Phase = "problem" | "users" | "techStack" | "coreFeatures" | "nonGoals";
14
+
15
+ const TECH_STACK_OPTIONS = [
16
+ { label: "React", value: "React", description: "UI component library" },
17
+ { label: "Next.js", value: "Next.js", description: "Full-stack React framework" },
18
+ { label: "Vue", value: "Vue", description: "Progressive UI framework" },
19
+ { label: "Svelte", value: "Svelte", description: "Compile-time UI framework" },
20
+ { label: "Node.js", value: "Node.js", description: "Server-side JavaScript runtime" },
21
+ { label: "Express", value: "Express", description: "Minimal Node.js web framework" },
22
+ { label: "Fastify", value: "Fastify", description: "High-performance Node.js framework" },
23
+ { label: "PostgreSQL", value: "PostgreSQL", description: "Relational database" },
24
+ { label: "MongoDB", value: "MongoDB", description: "Document database" },
25
+ { label: "Redis", value: "Redis", description: "In-memory data store / cache" },
26
+ { label: "Supabase", value: "Supabase", description: "Open-source Firebase alternative" },
27
+ { label: "Prisma", value: "Prisma", description: "TypeScript ORM" },
28
+ { label: "Docker", value: "Docker", description: "Container platform" },
29
+ { label: "Tailwind CSS", value: "Tailwind CSS", description: "Utility-first CSS framework" },
30
+ { label: "TypeScript", value: "TypeScript", description: "Typed JavaScript superset" },
31
+ { label: "Python", value: "Python", description: "General-purpose language" },
32
+ { label: "Go", value: "Go", description: "Systems programming language" },
33
+ { label: "Rust", value: "Rust", description: "Memory-safe systems language" },
34
+ ];
35
+
36
+ const PHASE_ORDER: Phase[] = ["problem", "users", "techStack", "coreFeatures", "nonGoals"];
37
+
38
+ export default function ProductContext({ initialValues, onComplete }: Props) {
39
+ const [phaseIndex, setPhaseIndex] = useState(0);
40
+ const [answers, setAnswers] = useState<Record<string, string>>({});
41
+ const [error, setError] = useState("");
42
+
43
+ // Prefill tech stack from Stack & Style selections (language + framework)
44
+ const prefillTechStack: string[] = [];
45
+ if (initialValues?.language) {
46
+ const match = TECH_STACK_OPTIONS.find(
47
+ (o) => o.value.toLowerCase() === initialValues.language!.toLowerCase()
48
+ );
49
+ if (match) prefillTechStack.push(match.value);
50
+ }
51
+ if (initialValues?.framework) {
52
+ const match = TECH_STACK_OPTIONS.find(
53
+ (o) => o.value.toLowerCase() === initialValues.framework!.toLowerCase()
54
+ );
55
+ if (match) prefillTechStack.push(match.value);
56
+ }
57
+
58
+ const currentPhase = PHASE_ORDER[phaseIndex]!;
59
+
60
+ function advanceToNext(key: string, value: string) {
61
+ const next = { ...answers, [key]: value };
62
+ setAnswers(next);
63
+ setError("");
64
+
65
+ if (phaseIndex < PHASE_ORDER.length - 1) {
66
+ setPhaseIndex(phaseIndex + 1);
67
+ } else {
68
+ onComplete({
69
+ problem: next.problem,
70
+ users: next.users,
71
+ techStack: next.techStack,
72
+ coreFeatures: (next.coreFeatures || "")
73
+ .split(",")
74
+ .map((s) => s.trim())
75
+ .filter(Boolean),
76
+ nonGoals: (next.nonGoals || "")
77
+ .split(",")
78
+ .map((s) => s.trim())
79
+ .filter(Boolean),
80
+ userStories: [],
81
+ envVars: [],
82
+ });
83
+ }
84
+ }
85
+
86
+ function handleTextSubmit(key: string, required: boolean) {
87
+ return (value: string) => {
88
+ const val = value.trim();
89
+ if (required && !val) {
90
+ setError(`This field is required`);
91
+ return;
92
+ }
93
+ advanceToNext(key, val);
94
+ };
95
+ }
96
+
97
+ function handleTechStackSubmit(values: string[]) {
98
+ advanceToNext("techStack", values.join(", "));
99
+ }
100
+
101
+ // Build completed fields display
102
+ const completedFields = PHASE_ORDER.slice(0, phaseIndex).map((key) => (
103
+ <GutterLine key={key}>
104
+ <Text dimColor>
105
+ {key === "problem" && `Problem: ${answers[key]}`}
106
+ {key === "users" && `Users: ${answers[key]}`}
107
+ {key === "techStack" && `Tech stack: ${answers[key]}`}
108
+ {key === "coreFeatures" && `Core features: ${answers[key]}`}
109
+ {key === "nonGoals" && `Non-goals: ${answers[key]}`}
110
+ </Text>
111
+ </GutterLine>
112
+ ));
113
+
114
+ const usersPlaceholder = answers["problem"]
115
+ ? `People affected by: ${answers["problem"]}`
116
+ : "e.g. Developers, PMs, designers...";
117
+
118
+ return (
119
+ <>
120
+ {completedFields}
121
+
122
+ {currentPhase === "problem" && (
123
+ <GutterLine>
124
+ <Text bold>What problem does this solve? </Text>
125
+ <TextInput
126
+ placeholder="Describe the core problem..."
127
+ onSubmit={handleTextSubmit("problem", true)}
128
+ />
129
+ </GutterLine>
130
+ )}
131
+
132
+ {currentPhase === "users" && (
133
+ <GutterLine>
134
+ <Text bold>Who are the users? </Text>
135
+ <TextInput
136
+ placeholder={usersPlaceholder}
137
+ onSubmit={handleTextSubmit("users", true)}
138
+ />
139
+ </GutterLine>
140
+ )}
141
+
142
+ {currentPhase === "techStack" && (
143
+ <>
144
+ <GutterLine>
145
+ <Text bold>Tech stack:</Text>
146
+ </GutterLine>
147
+ <GutteredMultiSelect
148
+ options={TECH_STACK_OPTIONS}
149
+ initialSelected={prefillTechStack}
150
+ onSubmit={handleTechStackSubmit}
151
+ />
152
+ </>
153
+ )}
154
+
155
+ {currentPhase === "coreFeatures" && (
156
+ <GutterLine>
157
+ <Text bold>Core features (comma-separated): </Text>
158
+ <TextInput
159
+ placeholder="e.g. Auth, Dashboard, API..."
160
+ onSubmit={handleTextSubmit("coreFeatures", true)}
161
+ />
162
+ </GutterLine>
163
+ )}
164
+
165
+ {currentPhase === "nonGoals" && (
166
+ <GutterLine>
167
+ <Text bold>Non-goals (comma-separated): </Text>
168
+ <TextInput
169
+ placeholder="e.g. Mobile app, Real-time sync..."
170
+ onSubmit={handleTextSubmit("nonGoals", false)}
171
+ />
172
+ </GutterLine>
173
+ )}
174
+
175
+ {error && (
176
+ <GutterLine>
177
+ <Text color="red">{error}</Text>
178
+ </GutterLine>
179
+ )}
180
+ </>
181
+ );
182
+ }
@@ -0,0 +1,135 @@
1
+ import React, { useState } from "react";
2
+ import { Text } from "ink";
3
+ import { TextInput } from "@inkjs/ui";
4
+ import { GutterLine } from "../components/gutter-line.js";
5
+ import { GutteredSelect } from "../components/guttered-select.js";
6
+ import type { WizardAnswers } from "../lib/types.js";
7
+
8
+ interface Props {
9
+ onComplete: (answers: Partial<WizardAnswers>) => void;
10
+ }
11
+
12
+ type Step = "projectName" | "description" | "packageManager" | "license";
13
+
14
+ const STEP_ORDER: Step[] = [
15
+ "projectName",
16
+ "description",
17
+ "packageManager",
18
+ "license",
19
+ ];
20
+
21
+ const PACKAGE_MANAGER_OPTIONS = [
22
+ { label: "npm", value: "npm" },
23
+ { label: "pnpm", value: "pnpm" },
24
+ { label: "bun", value: "bun" },
25
+ { label: "yarn", value: "yarn" },
26
+ ];
27
+
28
+ const LICENSE_OPTIONS = [
29
+ { label: "MIT — Permissive, allows commercial use", value: "MIT" },
30
+ { label: "ISC — Simplified MIT, minimal restrictions", value: "ISC" },
31
+ { label: "Apache-2.0 — Permissive with patent protection", value: "Apache-2.0" },
32
+ { label: "GPL-3.0 — Copyleft, requires source disclosure", value: "GPL-3.0" },
33
+ { label: "Unlicense — Public domain, no restrictions", value: "Unlicense" },
34
+ ];
35
+
36
+ export default function ProjectInfo({ onComplete }: Props) {
37
+ const [stepIndex, setStepIndex] = useState(0);
38
+ const [answers, setAnswers] = useState<Record<string, string>>({});
39
+ const [error, setError] = useState("");
40
+
41
+ const currentStep = STEP_ORDER[stepIndex]!;
42
+
43
+ function advance(key: string, value: string) {
44
+ const next = { ...answers, [key]: value };
45
+ setAnswers(next);
46
+ setError("");
47
+
48
+ if (stepIndex < STEP_ORDER.length - 1) {
49
+ setStepIndex(stepIndex + 1);
50
+ } else {
51
+ onComplete(next as unknown as Partial<WizardAnswers>);
52
+ }
53
+ }
54
+
55
+ function handleTextSubmit(value: string) {
56
+ const val = value.trim();
57
+ if (!val) {
58
+ setError(
59
+ currentStep === "projectName"
60
+ ? "Project name is required"
61
+ : "Description is required"
62
+ );
63
+ return;
64
+ }
65
+ advance(currentStep, val);
66
+ }
67
+
68
+ function handleSelectChange(key: string) {
69
+ return (value: string) => {
70
+ advance(key, value);
71
+ };
72
+ }
73
+
74
+ // Render completed fields
75
+ const completed = STEP_ORDER.slice(0, stepIndex).map((key) => (
76
+ <GutterLine key={key}>
77
+ <Text dimColor>
78
+ {key === "projectName" && `Project name: ${answers[key]}`}
79
+ {key === "description" && `Description: ${answers[key]}`}
80
+ {key === "packageManager" && `Package manager: ${answers[key]}`}
81
+ {key === "license" && `License: ${answers[key]}`}
82
+ </Text>
83
+ </GutterLine>
84
+ ));
85
+
86
+ return (
87
+ <>
88
+ {completed}
89
+
90
+ {currentStep === "projectName" && (
91
+ <GutterLine>
92
+ <Text bold>Project name: </Text>
93
+ <TextInput placeholder="..." onSubmit={handleTextSubmit} />
94
+ </GutterLine>
95
+ )}
96
+
97
+ {currentStep === "description" && (
98
+ <GutterLine>
99
+ <Text bold>One-line description: </Text>
100
+ <TextInput placeholder="..." onSubmit={handleTextSubmit} />
101
+ </GutterLine>
102
+ )}
103
+
104
+ {currentStep === "packageManager" && (
105
+ <>
106
+ <GutterLine>
107
+ <Text bold>Package manager:</Text>
108
+ </GutterLine>
109
+ <GutteredSelect
110
+ options={PACKAGE_MANAGER_OPTIONS}
111
+ onChange={handleSelectChange("packageManager")}
112
+ />
113
+ </>
114
+ )}
115
+
116
+ {currentStep === "license" && (
117
+ <>
118
+ <GutterLine>
119
+ <Text bold>License:</Text>
120
+ </GutterLine>
121
+ <GutteredSelect
122
+ options={LICENSE_OPTIONS}
123
+ onChange={handleSelectChange("license")}
124
+ />
125
+ </>
126
+ )}
127
+
128
+ {error && (
129
+ <GutterLine>
130
+ <Text color="red">{error}</Text>
131
+ </GutterLine>
132
+ )}
133
+ </>
134
+ );
135
+ }
@@ -0,0 +1,117 @@
1
+ import React, { useState } from "react";
2
+ import { Text } from "ink";
3
+ import { TextInput } from "@inkjs/ui";
4
+ import { GutterLine } from "../components/gutter-line.js";
5
+ import { GutteredSelect } from "../components/guttered-select.js";
6
+ import type { WizardAnswers } from "../lib/types.js";
7
+
8
+ interface Props {
9
+ onComplete: (answers: Partial<WizardAnswers>) => void;
10
+ }
11
+
12
+ type Mode = "choosing" | "quickstart" | "advanced";
13
+ type AdvancedField = "language" | "framework" | "codeStyle";
14
+
15
+ const PRESET_OPTIONS = [
16
+ { label: "TypeScript + Node.js", value: "typescript-node" },
17
+ ];
18
+
19
+ const ADVANCED_FIELDS: { key: AdvancedField; label: string }[] = [
20
+ { key: "language", label: "Language" },
21
+ { key: "framework", label: "Framework" },
22
+ { key: "codeStyle", label: "Code style conventions (comma-separated)" },
23
+ ];
24
+
25
+ const PRESETS: Record<string, Partial<WizardAnswers>> = {
26
+ "typescript-node": {
27
+ language: "TypeScript",
28
+ framework: "Node.js",
29
+ codeStyle: [
30
+ "TypeScript strict mode, ESM imports",
31
+ "camelCase for variables, PascalCase for types",
32
+ "stdlib -> external -> internal import ordering",
33
+ "Return errors, don't throw",
34
+ ],
35
+ buildCommand: "npm run build",
36
+ testCommand: "npm run test",
37
+ typecheckCommand: "npm run typecheck",
38
+ lintCommand: "npm run lint",
39
+ },
40
+ };
41
+
42
+ export default function StackStyle({ onComplete }: Props) {
43
+ const [mode, setMode] = useState<Mode>("choosing");
44
+ const [advancedIndex, setAdvancedIndex] = useState(0);
45
+ const [answers, setAnswers] = useState<Record<string, string>>({});
46
+
47
+ if (mode === "choosing") {
48
+ return (
49
+ <>
50
+ <GutterLine>
51
+ <Text bold>Setup mode:</Text>
52
+ </GutterLine>
53
+ <GutteredSelect
54
+ options={[
55
+ { label: "QuickStart (use a preset)", value: "quickstart" },
56
+ { label: "Advanced (manual config)", value: "advanced" },
57
+ ]}
58
+ onChange={(val) => setMode(val as Mode)}
59
+ />
60
+ </>
61
+ );
62
+ }
63
+
64
+ if (mode === "quickstart") {
65
+ return (
66
+ <>
67
+ <GutterLine>
68
+ <Text bold>Select a stack preset:</Text>
69
+ </GutterLine>
70
+ <GutteredSelect
71
+ options={PRESET_OPTIONS}
72
+ onChange={(val) => {
73
+ const preset = PRESETS[val];
74
+ if (preset) {
75
+ onComplete(preset);
76
+ }
77
+ }}
78
+ />
79
+ </>
80
+ );
81
+ }
82
+
83
+ // Advanced mode
84
+ const current = ADVANCED_FIELDS[advancedIndex];
85
+
86
+ function handleSubmit(value: string) {
87
+ const next = { ...answers, [current!.key]: value };
88
+ setAnswers(next);
89
+
90
+ if (advancedIndex < ADVANCED_FIELDS.length - 1) {
91
+ setAdvancedIndex(advancedIndex + 1);
92
+ } else {
93
+ onComplete({
94
+ language: next.language,
95
+ framework: next.framework,
96
+ codeStyle: (next.codeStyle || "").split(",").map((s) => s.trim()),
97
+ });
98
+ }
99
+ }
100
+
101
+ return (
102
+ <>
103
+ {ADVANCED_FIELDS.slice(0, advancedIndex).map((f) => (
104
+ <GutterLine key={f.key}>
105
+ <Text dimColor>
106
+ {f.label}: {answers[f.key]}
107
+ </Text>
108
+ </GutterLine>
109
+ ))}
110
+
111
+ <GutterLine>
112
+ <Text bold>{current!.label}: </Text>
113
+ <TextInput placeholder="..." onSubmit={handleSubmit} />
114
+ </GutterLine>
115
+ </>
116
+ );
117
+ }
@@ -0,0 +1,6 @@
1
+ # Environment Variables
2
+ {{#each envVars}}
3
+
4
+ # {{this.comment}}
5
+ {{this.key}}=
6
+ {{/each}}
@@ -0,0 +1,105 @@
1
+ # {{projectName}}
2
+
3
+ {{description}}
4
+
5
+ See docs/PRD.md for product requirements and docs/USER-STORIES.md for user stories with acceptance criteria.
6
+
7
+ ## Build & Test
8
+
9
+ ```bash
10
+ {{buildCommand}} # Build
11
+ {{typecheckCommand}} # Typecheck (fast — run first)
12
+ {{testCommand}} -- -t "name" # Test (specific)
13
+ {{testCommand}} # Test (full suite)
14
+ {{lintCommand}} # Lint
15
+ {{prCommand}} # Before creating a PR
16
+ ```
17
+
18
+ ## Code Style
19
+
20
+ {{#each codeStyle}}
21
+ - {{{this}}}
22
+ {{/each}}
23
+
24
+ ## Architecture
25
+
26
+ {{{architecture}}}
27
+
28
+ ## Workflow
29
+
30
+ ### Planning
31
+ - Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions)
32
+ - If something goes sideways, STOP and re-plan — don't keep pushing
33
+ - A good plan lets you one-shot the implementation
34
+
35
+ ### Verification
36
+ - Never mark a task complete without proving it works
37
+ - Run tests, check logs, demonstrate correctness
38
+ - Ask yourself: "Would a staff engineer approve this?"
39
+
40
+ ### Self-Improvement
41
+ - After ANY correction from the user: update the Lessons section below
42
+ - Write rules that prevent the same mistake from recurring
43
+
44
+ ### Bug Fixing
45
+ - Given a bug report: just fix it. Don't ask for hand-holding
46
+ - Point at logs, errors, failing tests — then resolve them
47
+
48
+ ### Elegance
49
+ - For non-trivial changes: pause and ask "is there a more elegant way?"
50
+ - If a fix feels hacky, step back and implement the clean solution
51
+ - Skip this for simple, obvious fixes — don't over-engineer
52
+
53
+ ## Task Management
54
+
55
+ ### Solo Work
56
+ 1. Plan first (plan mode for complex tasks)
57
+ 2. Track progress with TaskCreate/TaskUpdate for multi-step work
58
+ 3. Verify before claiming done
59
+ 4. Update Lessons after corrections
60
+
61
+ ### Agent Teams
62
+ 1. Plan-then-team: design approach BEFORE spawning a team
63
+ 2. Each task = one clear deliverable with verification steps
64
+ 3. File ownership: each teammate owns specific files — NEVER have two edit the same file
65
+ 4. Include file paths and constraints in task descriptions — teammates don't inherit context
66
+ 5. DMs by default, broadcast only for critical blocking issues
67
+ 6. 3-5 teammates max
68
+
69
+ ## Code Review & Fix Logging
70
+
71
+ Two tracking files live at the project root. Both are append-only logs — never delete or rewrite past entries.
72
+
73
+ ### CODE-REVIEW.md — review findings
74
+ - Created/appended during code review sessions.
75
+ - Entry ID format: `CR-YYYYMMDD-###` (zero-padded sequence per day).
76
+ - Findings ordered by severity (`High`, `Medium`, `Low`).
77
+ - Every finding includes `file:line` evidence, a clear recommendation, and `Status` (`New`, `Still Open`, `Fixed`, `Regressed`, `Not Reproducible`).
78
+
79
+ ### CODE-FIXED.md — fix results
80
+ - Created/appended when fixing findings from CODE-REVIEW.md.
81
+ - Entry ID format: `CF-YYYYMMDD-###`.
82
+ - Each entry references its source review by `CR-` Entry ID — do NOT re-describe findings, only document actions taken.
83
+ - Fixed findings include `file:line` for every change made.
84
+ - Deferred findings include rationale and a revisit trigger.
85
+ - Verification section must confirm `{{typecheckCommand}}` + `{{buildCommand}}` status after fixes.
86
+
87
+ ### Procedure
88
+ 1. **Reviewing**:
89
+ - **First**: Read CODE-REVIEW.md → Read CODE-FIXED.md → understand current state of findings and fixes.
90
+ - **Then**: Read codebase → append findings to CODE-REVIEW.md with a new `CR-` entry (write to CODE-REVIEW.md only, never modify CODE-FIXED.md).
91
+ - **Never** fix code during a reviewing process.
92
+ 2. **Fixing**:
93
+ - **First**: Read CODE-REVIEW.md → Read CODE-FIXED.md → identify unfixed findings.
94
+ - **Then**: Fix only unfixed findings → append a new `CF-` entry to CODE-FIXED.md (write to CODE-FIXED.md only, never modify CODE-REVIEW.md).
95
+ - **Never** perform a code review during a fixing process.
96
+
97
+ ## Core Principles
98
+
99
+ - **Simplicity First**: Make every change as simple as possible. Minimal code impact.
100
+ - **No Laziness**: Find root causes. No temporary fixes. Senior developer standards.
101
+ - **Minimal Impact**: Changes should only touch what's necessary.
102
+
103
+ ## Lessons
104
+
105
+ <!-- After ANY correction, add a rule here. This section compounds over time. -->
@@ -0,0 +1,26 @@
1
+ # {{projectName}}
2
+
3
+ {{description}}
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ {{packageManager}} install
9
+ {{buildCommand}}
10
+ ```
11
+
12
+ ## Development
13
+
14
+ ```bash
15
+ {{lintCommand}} # Lint
16
+ {{testCommand}} # Run tests
17
+ {{lintCommand}} && {{testCommand}} # Before creating a PR
18
+ ```
19
+
20
+ ## Architecture
21
+
22
+ {{{architectureNotes}}}
23
+
24
+ ## License
25
+
26
+ {{license}}
@@ -0,0 +1,29 @@
1
+ # {{projectName}} — Product Requirements
2
+
3
+ ## Vision
4
+
5
+ {{description}}
6
+
7
+ ## Problem
8
+
9
+ {{problem}}
10
+
11
+ ## Users
12
+
13
+ {{users}}
14
+
15
+ ## Core Features
16
+
17
+ {{#each coreFeatures}}
18
+ - {{{this}}}
19
+ {{/each}}
20
+
21
+ ## Non-Goals
22
+
23
+ {{#each nonGoals}}
24
+ - {{{this}}}
25
+ {{/each}}
26
+
27
+ ## Tech Stack
28
+
29
+ {{techStack}}
@@ -0,0 +1,46 @@
1
+ # {{projectName}} — User Stories
2
+
3
+ {{#if userStories.length}}
4
+ {{#each userStories}}
5
+ ## {{title}}
6
+
7
+ **As a** {{asA}}
8
+ **I want** {{iWant}}
9
+ **So that** {{soThat}}
10
+
11
+ ### Feature: {{feature}}
12
+
13
+ {{#each scenarios}}
14
+ ```gherkin
15
+ Scenario: {{this.name}}
16
+ Given {{this.given}}
17
+ When {{this.when}}
18
+ Then {{this.then}}
19
+ ```
20
+
21
+ {{/each}}
22
+ {{/each}}
23
+ {{else}}
24
+ <!-- TODO: Add user stories for {{projectName}} -->
25
+ <!-- Use the format below to define acceptance criteria in Gherkin style. -->
26
+
27
+ ## Example: User can perform core action
28
+
29
+ **As a** user
30
+ **I want** to perform a core action
31
+ **So that** I can achieve my goal
32
+
33
+ ### Feature: Core Action
34
+
35
+ ```gherkin
36
+ Scenario: Successful core action
37
+ Given the user is authenticated
38
+ When the user performs the core action
39
+ Then the system processes the request
40
+ ```
41
+
42
+ ---
43
+
44
+ > Replace this example with real user stories for your project.
45
+ > Each story should follow the **As a / I want / So that** format with Gherkin scenarios.
46
+ {{/if}}
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "dist",
10
+ "rootDir": "src",
11
+ "jsx": "react-jsx",
12
+ "declaration": true,
13
+ "sourceMap": true
14
+ },
15
+ "include": ["src"],
16
+ "exclude": ["node_modules", "dist"]
17
+ }