wiggum-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 (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +341 -0
  3. package/bin/ralph.js +8 -0
  4. package/dist/ai/enhancer.d.ts +100 -0
  5. package/dist/ai/enhancer.d.ts.map +1 -0
  6. package/dist/ai/enhancer.js +233 -0
  7. package/dist/ai/enhancer.js.map +1 -0
  8. package/dist/ai/index.d.ts +8 -0
  9. package/dist/ai/index.d.ts.map +1 -0
  10. package/dist/ai/index.js +11 -0
  11. package/dist/ai/index.js.map +1 -0
  12. package/dist/ai/prompts.d.ts +26 -0
  13. package/dist/ai/prompts.d.ts.map +1 -0
  14. package/dist/ai/prompts.js +201 -0
  15. package/dist/ai/prompts.js.map +1 -0
  16. package/dist/ai/providers.d.ts +35 -0
  17. package/dist/ai/providers.d.ts.map +1 -0
  18. package/dist/ai/providers.js +104 -0
  19. package/dist/ai/providers.js.map +1 -0
  20. package/dist/cli.d.ts +6 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +196 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/commands/init.d.ts +16 -0
  25. package/dist/commands/init.d.ts.map +1 -0
  26. package/dist/commands/init.js +124 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/monitor.d.ts +17 -0
  29. package/dist/commands/monitor.d.ts.map +1 -0
  30. package/dist/commands/monitor.js +342 -0
  31. package/dist/commands/monitor.js.map +1 -0
  32. package/dist/commands/new.d.ts +19 -0
  33. package/dist/commands/new.d.ts.map +1 -0
  34. package/dist/commands/new.js +272 -0
  35. package/dist/commands/new.js.map +1 -0
  36. package/dist/commands/run.d.ts +16 -0
  37. package/dist/commands/run.d.ts.map +1 -0
  38. package/dist/commands/run.js +175 -0
  39. package/dist/commands/run.js.map +1 -0
  40. package/dist/generator/config.d.ts +59 -0
  41. package/dist/generator/config.d.ts.map +1 -0
  42. package/dist/generator/config.js +68 -0
  43. package/dist/generator/config.js.map +1 -0
  44. package/dist/generator/index.d.ts +64 -0
  45. package/dist/generator/index.d.ts.map +1 -0
  46. package/dist/generator/index.js +147 -0
  47. package/dist/generator/index.js.map +1 -0
  48. package/dist/generator/templates.d.ts +70 -0
  49. package/dist/generator/templates.d.ts.map +1 -0
  50. package/dist/generator/templates.js +296 -0
  51. package/dist/generator/templates.js.map +1 -0
  52. package/dist/generator/writer.d.ts +93 -0
  53. package/dist/generator/writer.d.ts.map +1 -0
  54. package/dist/generator/writer.js +213 -0
  55. package/dist/generator/writer.js.map +1 -0
  56. package/dist/index.d.ts +12 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +17 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/scanner/detectors/core/framework.d.ts +11 -0
  61. package/dist/scanner/detectors/core/framework.d.ts.map +1 -0
  62. package/dist/scanner/detectors/core/framework.js +275 -0
  63. package/dist/scanner/detectors/core/framework.js.map +1 -0
  64. package/dist/scanner/detectors/core/packageManager.d.ts +11 -0
  65. package/dist/scanner/detectors/core/packageManager.d.ts.map +1 -0
  66. package/dist/scanner/detectors/core/packageManager.js +74 -0
  67. package/dist/scanner/detectors/core/packageManager.js.map +1 -0
  68. package/dist/scanner/detectors/core/styling.d.ts +12 -0
  69. package/dist/scanner/detectors/core/styling.d.ts.map +1 -0
  70. package/dist/scanner/detectors/core/styling.js +230 -0
  71. package/dist/scanner/detectors/core/styling.js.map +1 -0
  72. package/dist/scanner/detectors/core/testing.d.ts +12 -0
  73. package/dist/scanner/detectors/core/testing.d.ts.map +1 -0
  74. package/dist/scanner/detectors/core/testing.js +190 -0
  75. package/dist/scanner/detectors/core/testing.js.map +1 -0
  76. package/dist/scanner/detectors/data/api.d.ts +12 -0
  77. package/dist/scanner/detectors/data/api.d.ts.map +1 -0
  78. package/dist/scanner/detectors/data/api.js +261 -0
  79. package/dist/scanner/detectors/data/api.js.map +1 -0
  80. package/dist/scanner/detectors/data/database.d.ts +12 -0
  81. package/dist/scanner/detectors/data/database.d.ts.map +1 -0
  82. package/dist/scanner/detectors/data/database.js +213 -0
  83. package/dist/scanner/detectors/data/database.js.map +1 -0
  84. package/dist/scanner/detectors/data/orm.d.ts +12 -0
  85. package/dist/scanner/detectors/data/orm.d.ts.map +1 -0
  86. package/dist/scanner/detectors/data/orm.js +160 -0
  87. package/dist/scanner/detectors/data/orm.js.map +1 -0
  88. package/dist/scanner/detectors/frontend/formHandling.d.ts +12 -0
  89. package/dist/scanner/detectors/frontend/formHandling.d.ts.map +1 -0
  90. package/dist/scanner/detectors/frontend/formHandling.js +211 -0
  91. package/dist/scanner/detectors/frontend/formHandling.js.map +1 -0
  92. package/dist/scanner/detectors/frontend/stateManagement.d.ts +12 -0
  93. package/dist/scanner/detectors/frontend/stateManagement.d.ts.map +1 -0
  94. package/dist/scanner/detectors/frontend/stateManagement.js +221 -0
  95. package/dist/scanner/detectors/frontend/stateManagement.js.map +1 -0
  96. package/dist/scanner/detectors/frontend/uiComponents.d.ts +12 -0
  97. package/dist/scanner/detectors/frontend/uiComponents.d.ts.map +1 -0
  98. package/dist/scanner/detectors/frontend/uiComponents.js +285 -0
  99. package/dist/scanner/detectors/frontend/uiComponents.js.map +1 -0
  100. package/dist/scanner/detectors/infra/deployment.d.ts +12 -0
  101. package/dist/scanner/detectors/infra/deployment.d.ts.map +1 -0
  102. package/dist/scanner/detectors/infra/deployment.js +301 -0
  103. package/dist/scanner/detectors/infra/deployment.js.map +1 -0
  104. package/dist/scanner/detectors/infra/monorepo.d.ts +12 -0
  105. package/dist/scanner/detectors/infra/monorepo.d.ts.map +1 -0
  106. package/dist/scanner/detectors/infra/monorepo.js +219 -0
  107. package/dist/scanner/detectors/infra/monorepo.js.map +1 -0
  108. package/dist/scanner/detectors/mcp/mcpProject.d.ts +12 -0
  109. package/dist/scanner/detectors/mcp/mcpProject.d.ts.map +1 -0
  110. package/dist/scanner/detectors/mcp/mcpProject.js +154 -0
  111. package/dist/scanner/detectors/mcp/mcpProject.js.map +1 -0
  112. package/dist/scanner/detectors/mcp/mcpServers.d.ts +17 -0
  113. package/dist/scanner/detectors/mcp/mcpServers.d.ts.map +1 -0
  114. package/dist/scanner/detectors/mcp/mcpServers.js +193 -0
  115. package/dist/scanner/detectors/mcp/mcpServers.js.map +1 -0
  116. package/dist/scanner/detectors/services/analytics.d.ts +12 -0
  117. package/dist/scanner/detectors/services/analytics.d.ts.map +1 -0
  118. package/dist/scanner/detectors/services/analytics.js +236 -0
  119. package/dist/scanner/detectors/services/analytics.js.map +1 -0
  120. package/dist/scanner/detectors/services/auth.d.ts +12 -0
  121. package/dist/scanner/detectors/services/auth.d.ts.map +1 -0
  122. package/dist/scanner/detectors/services/auth.js +217 -0
  123. package/dist/scanner/detectors/services/auth.js.map +1 -0
  124. package/dist/scanner/detectors/services/email.d.ts +12 -0
  125. package/dist/scanner/detectors/services/email.d.ts.map +1 -0
  126. package/dist/scanner/detectors/services/email.js +211 -0
  127. package/dist/scanner/detectors/services/email.js.map +1 -0
  128. package/dist/scanner/detectors/services/payments.d.ts +12 -0
  129. package/dist/scanner/detectors/services/payments.d.ts.map +1 -0
  130. package/dist/scanner/detectors/services/payments.js +185 -0
  131. package/dist/scanner/detectors/services/payments.js.map +1 -0
  132. package/dist/scanner/detectors/utils.d.ts +160 -0
  133. package/dist/scanner/detectors/utils.d.ts.map +1 -0
  134. package/dist/scanner/detectors/utils.js +222 -0
  135. package/dist/scanner/detectors/utils.js.map +1 -0
  136. package/dist/scanner/index.d.ts +42 -0
  137. package/dist/scanner/index.d.ts.map +1 -0
  138. package/dist/scanner/index.js +282 -0
  139. package/dist/scanner/index.js.map +1 -0
  140. package/dist/scanner/registry.d.ts +43 -0
  141. package/dist/scanner/registry.d.ts.map +1 -0
  142. package/dist/scanner/registry.js +243 -0
  143. package/dist/scanner/registry.js.map +1 -0
  144. package/dist/scanner/types.d.ts +112 -0
  145. package/dist/scanner/types.d.ts.map +1 -0
  146. package/dist/scanner/types.js +6 -0
  147. package/dist/scanner/types.js.map +1 -0
  148. package/dist/templates/config/ralph.config.js.tmpl +38 -0
  149. package/dist/templates/guides/AGENTS.md.tmpl +100 -0
  150. package/dist/templates/guides/FRONTEND.md.tmpl +523 -0
  151. package/dist/templates/guides/PERFORMANCE.md.tmpl +264 -0
  152. package/dist/templates/guides/SECURITY.md.tmpl +100 -0
  153. package/dist/templates/prompts/PROMPT.md.tmpl +77 -0
  154. package/dist/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
  155. package/dist/templates/prompts/PROMPT_feature.md.tmpl +83 -0
  156. package/dist/templates/prompts/PROMPT_review.md.tmpl +167 -0
  157. package/dist/templates/prompts/PROMPT_verify.md.tmpl +72 -0
  158. package/dist/templates/root/.gitignore.tmpl +5 -0
  159. package/dist/templates/root/LEARNINGS.md.tmpl +24 -0
  160. package/dist/templates/root/README.md.tmpl +61 -0
  161. package/dist/templates/scripts/feature-loop.sh.tmpl +267 -0
  162. package/dist/templates/scripts/loop.sh.tmpl +59 -0
  163. package/dist/templates/scripts/ralph-monitor.sh.tmpl +244 -0
  164. package/dist/templates/specs/README.md.tmpl +57 -0
  165. package/dist/templates/specs/_example.md.tmpl +71 -0
  166. package/dist/utils/config.d.ts +95 -0
  167. package/dist/utils/config.d.ts.map +1 -0
  168. package/dist/utils/config.js +148 -0
  169. package/dist/utils/config.js.map +1 -0
  170. package/dist/utils/header.d.ts +5 -0
  171. package/dist/utils/header.d.ts.map +1 -0
  172. package/dist/utils/header.js +15 -0
  173. package/dist/utils/header.js.map +1 -0
  174. package/dist/utils/logger.d.ts +11 -0
  175. package/dist/utils/logger.d.ts.map +1 -0
  176. package/dist/utils/logger.js +24 -0
  177. package/dist/utils/logger.js.map +1 -0
  178. package/package.json +44 -0
  179. package/src/ai/enhancer.ts +350 -0
  180. package/src/ai/index.ts +38 -0
  181. package/src/ai/prompts.ts +217 -0
  182. package/src/ai/providers.ts +136 -0
  183. package/src/cli.ts +255 -0
  184. package/src/commands/init.ts +149 -0
  185. package/src/commands/monitor.ts +412 -0
  186. package/src/commands/new.ts +312 -0
  187. package/src/commands/run.ts +214 -0
  188. package/src/generator/config.ts +116 -0
  189. package/src/generator/index.ts +227 -0
  190. package/src/generator/templates.ts +412 -0
  191. package/src/generator/writer.ts +293 -0
  192. package/src/index.ts +41 -0
  193. package/src/scanner/detectors/core/framework.ts +332 -0
  194. package/src/scanner/detectors/core/packageManager.ts +91 -0
  195. package/src/scanner/detectors/core/styling.ts +261 -0
  196. package/src/scanner/detectors/core/testing.ts +221 -0
  197. package/src/scanner/detectors/data/api.ts +303 -0
  198. package/src/scanner/detectors/data/database.ts +245 -0
  199. package/src/scanner/detectors/data/orm.ts +180 -0
  200. package/src/scanner/detectors/frontend/formHandling.ts +244 -0
  201. package/src/scanner/detectors/frontend/stateManagement.ts +261 -0
  202. package/src/scanner/detectors/frontend/uiComponents.ts +328 -0
  203. package/src/scanner/detectors/infra/deployment.ts +343 -0
  204. package/src/scanner/detectors/infra/monorepo.ts +251 -0
  205. package/src/scanner/detectors/mcp/mcpProject.ts +176 -0
  206. package/src/scanner/detectors/mcp/mcpServers.ts +237 -0
  207. package/src/scanner/detectors/services/analytics.ts +273 -0
  208. package/src/scanner/detectors/services/auth.ts +254 -0
  209. package/src/scanner/detectors/services/email.ts +244 -0
  210. package/src/scanner/detectors/services/payments.ts +213 -0
  211. package/src/scanner/detectors/utils.ts +251 -0
  212. package/src/scanner/index.ts +354 -0
  213. package/src/scanner/registry.ts +301 -0
  214. package/src/scanner/types.ts +152 -0
  215. package/src/templates/config/ralph.config.js.tmpl +38 -0
  216. package/src/templates/guides/AGENTS.md.tmpl +100 -0
  217. package/src/templates/guides/FRONTEND.md.tmpl +523 -0
  218. package/src/templates/guides/PERFORMANCE.md.tmpl +264 -0
  219. package/src/templates/guides/SECURITY.md.tmpl +100 -0
  220. package/src/templates/prompts/PROMPT.md.tmpl +77 -0
  221. package/src/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
  222. package/src/templates/prompts/PROMPT_feature.md.tmpl +83 -0
  223. package/src/templates/prompts/PROMPT_review.md.tmpl +167 -0
  224. package/src/templates/prompts/PROMPT_verify.md.tmpl +72 -0
  225. package/src/templates/root/.gitignore.tmpl +5 -0
  226. package/src/templates/root/LEARNINGS.md.tmpl +24 -0
  227. package/src/templates/root/README.md.tmpl +61 -0
  228. package/src/templates/scripts/feature-loop.sh.tmpl +267 -0
  229. package/src/templates/scripts/loop.sh.tmpl +59 -0
  230. package/src/templates/scripts/ralph-monitor.sh.tmpl +244 -0
  231. package/src/templates/specs/README.md.tmpl +57 -0
  232. package/src/templates/specs/_example.md.tmpl +71 -0
  233. package/src/utils/config.ts +221 -0
  234. package/src/utils/header.ts +15 -0
  235. package/src/utils/logger.ts +28 -0
  236. package/tsconfig.json +19 -0
@@ -0,0 +1,272 @@
1
+ /**
2
+ * New Command
3
+ * Create a new feature specification from template
4
+ */
5
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
6
+ import { join, dirname } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { spawn } from 'node:child_process';
9
+ import { logger } from '../utils/logger.js';
10
+ import { loadConfigWithDefaults, hasConfig } from '../utils/config.js';
11
+ import pc from 'picocolors';
12
+ import * as prompts from '@clack/prompts';
13
+ /**
14
+ * Default spec template content
15
+ */
16
+ const DEFAULT_SPEC_TEMPLATE = `# {{feature}} Feature Specification
17
+
18
+ **Status:** Planned
19
+ **Version:** 1.0
20
+ **Last Updated:** {{date}}
21
+
22
+ ## Purpose
23
+
24
+ Describe what this feature does and why it's needed.
25
+
26
+ ## User Stories
27
+
28
+ - As a user, I want [action] so that [benefit]
29
+ - As an admin, I want [action] so that [benefit]
30
+
31
+ ## Requirements
32
+
33
+ ### Functional Requirements
34
+ - [ ] Requirement 1 - Description of what the system must do
35
+ - [ ] Requirement 2 - Another functional requirement
36
+
37
+ ### Non-Functional Requirements
38
+ - [ ] Performance: [target metrics]
39
+ - [ ] Security: [security considerations]
40
+ - [ ] Accessibility: [WCAG level]
41
+
42
+ ## Technical Notes
43
+
44
+ - **Uses:** Existing patterns or components to leverage
45
+ - **Location:** Where the code should live
46
+ - **Dependencies:** External libraries or APIs needed
47
+ - **Database:** Schema changes required (if any)
48
+
49
+ ## Visual Requirements
50
+
51
+ (For UI features - delete this section if backend-only)
52
+
53
+ - **Layout:** Describe the layout structure and responsive behavior
54
+ - **Components:** List the UI components needed
55
+ - **States:**
56
+ - Empty: What to show when there's no data
57
+ - Loading: Skeleton or spinner pattern
58
+ - Error: How to display errors
59
+ - **Mobile:** How the layout adapts on small screens
60
+
61
+ ## API Endpoints
62
+
63
+ (If applicable)
64
+
65
+ | Method | Endpoint | Description |
66
+ |--------|----------|-------------|
67
+ | GET | \`/api/{{feature}}\` | Fetch data |
68
+ | POST | \`/api/{{feature}}\` | Create new |
69
+
70
+ ## Acceptance Criteria
71
+
72
+ - [ ] Criteria 1 - Specific, testable condition
73
+ - [ ] Criteria 2 - Another acceptance criterion
74
+ - [ ] Criteria 3 - E2E testable scenario
75
+
76
+ ## Out of Scope
77
+
78
+ - Feature X (planned for future iteration)
79
+ - Integration Y (separate spec)
80
+
81
+ ## Open Questions
82
+
83
+ - [ ] Question 1 - Decision needed
84
+ - [ ] Question 2 - Clarification required
85
+ `;
86
+ /**
87
+ * Find the _example.md template
88
+ */
89
+ async function findExampleTemplate(projectRoot) {
90
+ const config = await loadConfigWithDefaults(projectRoot);
91
+ const specsDir = config.paths.specs;
92
+ // Check multiple locations
93
+ const possiblePaths = [
94
+ join(projectRoot, specsDir, '_example.md'),
95
+ join(projectRoot, '.ralph', 'specs', '_example.md'),
96
+ join(projectRoot, 'specs', '_example.md'),
97
+ ];
98
+ for (const templatePath of possiblePaths) {
99
+ if (existsSync(templatePath)) {
100
+ return templatePath;
101
+ }
102
+ }
103
+ return null;
104
+ }
105
+ /**
106
+ * Get template directory from the package
107
+ */
108
+ function getPackageTemplateDir() {
109
+ const __filename = fileURLToPath(import.meta.url);
110
+ const __dirname = dirname(__filename);
111
+ // Go up from commands/ to src/ or dist/, then to templates/
112
+ return join(__dirname, '..', 'templates', 'specs');
113
+ }
114
+ /**
115
+ * Process template variables
116
+ */
117
+ function processTemplate(template, feature) {
118
+ const date = new Date().toISOString().split('T')[0];
119
+ const featureTitle = feature
120
+ .split('-')
121
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
122
+ .join(' ');
123
+ return template
124
+ .replace(/\{\{feature\}\}/g, feature)
125
+ .replace(/\{\{featureTitle\}\}/g, featureTitle)
126
+ .replace(/\{\{date\}\}/g, date)
127
+ .replace(/YYYY-MM-DD/g, date);
128
+ }
129
+ /**
130
+ * Open file in editor
131
+ */
132
+ function openInEditor(filePath, editor) {
133
+ const editorCmd = editor || process.env.EDITOR || 'code';
134
+ logger.info(`Opening in editor: ${editorCmd}`);
135
+ const child = spawn(editorCmd, [filePath], {
136
+ detached: true,
137
+ stdio: 'ignore',
138
+ });
139
+ child.unref();
140
+ }
141
+ /**
142
+ * Create a new feature specification
143
+ */
144
+ export async function newCommand(feature, options = {}) {
145
+ const projectRoot = process.cwd();
146
+ // Validate feature name
147
+ if (!feature || typeof feature !== 'string') {
148
+ logger.error('Feature name is required');
149
+ process.exit(1);
150
+ }
151
+ // Sanitize feature name (allow alphanumeric, hyphens, underscores)
152
+ if (!/^[a-zA-Z0-9_-]+$/.test(feature)) {
153
+ logger.error('Feature name must contain only letters, numbers, hyphens, and underscores');
154
+ logger.info('Example: ralph new my-feature or ralph new user_auth');
155
+ process.exit(1);
156
+ }
157
+ // Check for reserved names
158
+ const reservedNames = ['_example', '_template', 'config', 'ralph'];
159
+ if (reservedNames.includes(feature.toLowerCase())) {
160
+ logger.error(`"${feature}" is a reserved name. Please choose a different feature name.`);
161
+ process.exit(1);
162
+ }
163
+ logger.info(`Creating new feature spec: ${pc.bold(feature)}`);
164
+ console.log('');
165
+ // Check for config
166
+ if (!hasConfig(projectRoot)) {
167
+ logger.warn('No ralph.config.js found. Run "ralph init" first to configure your project.');
168
+ logger.info('Using default paths...');
169
+ console.log('');
170
+ }
171
+ // Load config
172
+ const config = await loadConfigWithDefaults(projectRoot);
173
+ const specsDir = join(projectRoot, config.paths.specs);
174
+ // Create specs directory if it doesn't exist
175
+ if (!existsSync(specsDir)) {
176
+ logger.info(`Creating specs directory: ${specsDir}`);
177
+ mkdirSync(specsDir, { recursive: true });
178
+ }
179
+ // Check if spec already exists
180
+ const specPath = join(specsDir, `${feature}.md`);
181
+ if (existsSync(specPath)) {
182
+ if (!options.force) {
183
+ logger.error(`Spec file already exists: ${specPath}`);
184
+ if (!options.yes) {
185
+ const shouldOverwrite = await prompts.confirm({
186
+ message: 'Do you want to overwrite the existing spec?',
187
+ initialValue: false,
188
+ });
189
+ if (prompts.isCancel(shouldOverwrite) || !shouldOverwrite) {
190
+ logger.info('Cancelled');
191
+ return;
192
+ }
193
+ }
194
+ else {
195
+ logger.info('Use --force to overwrite');
196
+ return;
197
+ }
198
+ }
199
+ logger.warn('Overwriting existing spec file');
200
+ }
201
+ // Find or use default template
202
+ let templateContent;
203
+ // Try to find _example.md template
204
+ const exampleTemplate = await findExampleTemplate(projectRoot);
205
+ if (exampleTemplate) {
206
+ logger.info(`Using template: ${exampleTemplate}`);
207
+ templateContent = readFileSync(exampleTemplate, 'utf-8');
208
+ }
209
+ else {
210
+ // Try package template
211
+ const packageTemplateDir = getPackageTemplateDir();
212
+ const packageTemplate = join(packageTemplateDir, '_example.md.tmpl');
213
+ if (existsSync(packageTemplate)) {
214
+ logger.info(`Using package template`);
215
+ templateContent = readFileSync(packageTemplate, 'utf-8');
216
+ }
217
+ else {
218
+ // Use default template
219
+ logger.info('Using default template');
220
+ templateContent = DEFAULT_SPEC_TEMPLATE;
221
+ }
222
+ }
223
+ // Process template
224
+ const specContent = processTemplate(templateContent, feature);
225
+ // Confirm with user (unless --yes)
226
+ if (!options.yes) {
227
+ console.log('');
228
+ console.log(pc.cyan('--- Spec Preview ---'));
229
+ console.log(`File: ${specPath}`);
230
+ console.log('');
231
+ // Show first few lines of the processed template
232
+ const previewLines = specContent.split('\n').slice(0, 15);
233
+ console.log(pc.dim(previewLines.join('\n')));
234
+ if (specContent.split('\n').length > 15) {
235
+ console.log(pc.dim('...'));
236
+ }
237
+ console.log('');
238
+ const shouldCreate = await prompts.confirm({
239
+ message: 'Create this spec file?',
240
+ initialValue: true,
241
+ });
242
+ if (prompts.isCancel(shouldCreate) || !shouldCreate) {
243
+ logger.info('Cancelled');
244
+ return;
245
+ }
246
+ }
247
+ // Write the spec file
248
+ try {
249
+ writeFileSync(specPath, specContent, 'utf-8');
250
+ logger.success(`Created spec: ${specPath}`);
251
+ }
252
+ catch (error) {
253
+ logger.error(`Failed to create spec: ${error instanceof Error ? error.message : String(error)}`);
254
+ process.exit(1);
255
+ }
256
+ // Open in editor if requested
257
+ if (options.edit) {
258
+ try {
259
+ openInEditor(specPath, options.editor);
260
+ }
261
+ catch (error) {
262
+ logger.warn(`Could not open editor: ${error instanceof Error ? error.message : String(error)}`);
263
+ logger.info(`Manually open: ${specPath}`);
264
+ }
265
+ }
266
+ // Display next steps
267
+ console.log('');
268
+ console.log('Next steps:');
269
+ console.log(` 1. Edit the spec: ${pc.cyan(`$EDITOR ${specPath}`)}`);
270
+ console.log(` 2. When ready, run: ${pc.cyan(`ralph run ${feature}`)}`);
271
+ }
272
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Run Command
3
+ * Executes the feature development loop for a specific feature
4
+ */
5
+ export interface RunOptions {
6
+ worktree?: boolean;
7
+ resume?: boolean;
8
+ model?: string;
9
+ maxIterations?: number;
10
+ maxE2eAttempts?: number;
11
+ }
12
+ /**
13
+ * Run the feature development loop for a specific feature
14
+ */
15
+ export declare function runCommand(feature: string, options?: RunOptions): Promise<void>;
16
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAmDD;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyIzF"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Run Command
3
+ * Executes the feature development loop for a specific feature
4
+ */
5
+ import { spawn } from 'node:child_process';
6
+ import { existsSync } from 'node:fs';
7
+ import { join, dirname } from 'node:path';
8
+ import { logger } from '../utils/logger.js';
9
+ import { loadConfigWithDefaults, hasConfig, } from '../utils/config.js';
10
+ import pc from 'picocolors';
11
+ /**
12
+ * Find the feature-loop.sh script
13
+ * Checks: 1) .ralph/scripts/ 2) ralph/ (parent ralph repo)
14
+ */
15
+ function findFeatureLoopScript(projectRoot) {
16
+ // Check .ralph/scripts first
17
+ const localScript = join(projectRoot, '.ralph', 'scripts', 'feature-loop.sh');
18
+ if (existsSync(localScript)) {
19
+ return localScript;
20
+ }
21
+ // Check for ralph directory as sibling (development setup)
22
+ const siblingRalph = join(projectRoot, '..', 'ralph', 'feature-loop.sh');
23
+ if (existsSync(siblingRalph)) {
24
+ return siblingRalph;
25
+ }
26
+ // Check for ralph directory as parent (when running from within ralph-cli)
27
+ const parentRalph = join(projectRoot, 'feature-loop.sh');
28
+ if (existsSync(parentRalph)) {
29
+ return parentRalph;
30
+ }
31
+ return null;
32
+ }
33
+ /**
34
+ * Validate that the spec file exists
35
+ */
36
+ async function validateSpecFile(projectRoot, feature) {
37
+ const config = await loadConfigWithDefaults(projectRoot);
38
+ const specsDir = config.paths.specs;
39
+ // Check various possible spec locations
40
+ const possiblePaths = [
41
+ join(projectRoot, specsDir, `${feature}.md`),
42
+ join(projectRoot, '.ralph', 'specs', `${feature}.md`),
43
+ join(projectRoot, 'specs', `${feature}.md`),
44
+ ];
45
+ for (const specPath of possiblePaths) {
46
+ if (existsSync(specPath)) {
47
+ return specPath;
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ /**
53
+ * Run the feature development loop for a specific feature
54
+ */
55
+ export async function runCommand(feature, options = {}) {
56
+ const projectRoot = process.cwd();
57
+ // Validate feature name
58
+ if (!feature || typeof feature !== 'string') {
59
+ logger.error('Feature name is required');
60
+ process.exit(1);
61
+ }
62
+ // Sanitize feature name (allow alphanumeric, hyphens, underscores)
63
+ if (!/^[a-zA-Z0-9_-]+$/.test(feature)) {
64
+ logger.error('Feature name must contain only letters, numbers, hyphens, and underscores');
65
+ process.exit(1);
66
+ }
67
+ logger.info(`Running feature loop for: ${pc.bold(feature)}`);
68
+ console.log('');
69
+ // Check for config
70
+ if (!hasConfig(projectRoot)) {
71
+ logger.warn('No ralph.config.js found. Run "ralph init" first to configure your project.');
72
+ logger.info('Attempting to run with default settings...');
73
+ console.log('');
74
+ }
75
+ // Load config
76
+ const config = await loadConfigWithDefaults(projectRoot);
77
+ // Validate spec file exists
78
+ const specFile = await validateSpecFile(projectRoot, feature);
79
+ if (!specFile) {
80
+ logger.error(`Spec file not found: ${feature}.md`);
81
+ logger.info(`Create the spec first: ralph new ${feature}`);
82
+ logger.info(`Expected location: ${join(projectRoot, config.paths.specs, `${feature}.md`)}`);
83
+ process.exit(1);
84
+ }
85
+ logger.info(`Found spec: ${specFile}`);
86
+ // Find the feature-loop.sh script
87
+ const scriptPath = findFeatureLoopScript(projectRoot);
88
+ if (!scriptPath) {
89
+ logger.error('feature-loop.sh script not found');
90
+ logger.info('The script should be in .ralph/scripts/ or the ralph/ directory');
91
+ logger.info('Run "ralph init" to generate the necessary scripts');
92
+ process.exit(1);
93
+ }
94
+ logger.info(`Using script: ${scriptPath}`);
95
+ console.log('');
96
+ // Build command arguments
97
+ const args = [feature];
98
+ // Add max iterations
99
+ const maxIterations = options.maxIterations ?? config.loop.maxIterations;
100
+ args.push(String(maxIterations));
101
+ // Add max E2E attempts
102
+ const maxE2eAttempts = options.maxE2eAttempts ?? config.loop.maxE2eAttempts;
103
+ args.push(String(maxE2eAttempts));
104
+ // Add flags
105
+ if (options.worktree) {
106
+ args.push('--worktree');
107
+ }
108
+ if (options.resume) {
109
+ args.push('--resume');
110
+ }
111
+ if (options.model) {
112
+ args.push('--model', options.model);
113
+ }
114
+ // Display configuration
115
+ console.log(pc.cyan('--- Run Configuration ---'));
116
+ console.log(` Feature: ${pc.bold(feature)}`);
117
+ console.log(` Spec: ${specFile}`);
118
+ console.log(` Max Iterations: ${maxIterations}`);
119
+ console.log(` Max E2E Attempts: ${maxE2eAttempts}`);
120
+ console.log(` Model: ${options.model || config.loop.defaultModel}`);
121
+ console.log(` Worktree: ${options.worktree ? 'enabled' : 'disabled'}`);
122
+ console.log(` Resume: ${options.resume ? 'enabled' : 'disabled'}`);
123
+ console.log('');
124
+ // Execute the feature-loop.sh script
125
+ logger.info('Starting feature loop...');
126
+ console.log('');
127
+ const scriptDir = dirname(scriptPath);
128
+ return new Promise((resolve, reject) => {
129
+ try {
130
+ const child = spawn('bash', [scriptPath, ...args], {
131
+ cwd: scriptDir,
132
+ stdio: 'inherit',
133
+ env: {
134
+ ...process.env,
135
+ // Pass config paths to script
136
+ RALPH_CONFIG_ROOT: config.paths.root,
137
+ RALPH_SPEC_DIR: config.paths.specs,
138
+ RALPH_SCRIPTS_DIR: config.paths.scripts,
139
+ },
140
+ });
141
+ child.on('error', (error) => {
142
+ logger.error(`Failed to start feature loop: ${error.message}`);
143
+ if (process.env.DEBUG) {
144
+ console.error(error.stack);
145
+ }
146
+ reject(error);
147
+ });
148
+ child.on('close', (code) => {
149
+ console.log('');
150
+ if (code === 0) {
151
+ logger.success('Feature loop completed successfully!');
152
+ resolve();
153
+ }
154
+ else if (code === 130) {
155
+ // SIGINT (Ctrl+C)
156
+ logger.info('Feature loop interrupted by user');
157
+ resolve();
158
+ }
159
+ else {
160
+ logger.error(`Feature loop exited with code: ${code}`);
161
+ logger.info('Use --resume to continue from where you left off');
162
+ reject(new Error(`Feature loop exited with code: ${code || 1}`));
163
+ }
164
+ });
165
+ }
166
+ catch (error) {
167
+ logger.error(`Unexpected error starting feature loop: ${error instanceof Error ? error.message : String(error)}`);
168
+ if (process.env.DEBUG && error instanceof Error) {
169
+ console.error(error.stack);
170
+ }
171
+ reject(error);
172
+ }
173
+ });
174
+ }
175
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Config Generator
3
+ * Generates ralph.config.js file from scan results
4
+ */
5
+ import type { ScanResult } from '../scanner/types.js';
6
+ /**
7
+ * Ralph configuration structure
8
+ */
9
+ export interface RalphConfig {
10
+ name: string;
11
+ stack: {
12
+ framework: {
13
+ name: string;
14
+ version: string;
15
+ variant: string;
16
+ };
17
+ packageManager: string;
18
+ testing: {
19
+ unit: string;
20
+ e2e: string;
21
+ };
22
+ styling: string;
23
+ };
24
+ commands: {
25
+ dev: string;
26
+ build: string;
27
+ test: string;
28
+ lint: string;
29
+ typecheck: string;
30
+ };
31
+ paths: {
32
+ root: string;
33
+ prompts: string;
34
+ guides: string;
35
+ specs: string;
36
+ scripts: string;
37
+ learnings: string;
38
+ agents: string;
39
+ };
40
+ loop: {
41
+ maxIterations: number;
42
+ maxE2eAttempts: number;
43
+ defaultModel: string;
44
+ planningModel: string;
45
+ };
46
+ }
47
+ /**
48
+ * Generate ralph config object from scan result
49
+ */
50
+ export declare function generateConfig(scanResult: ScanResult, customVars?: Record<string, string>): RalphConfig;
51
+ /**
52
+ * Generate ralph.config.js file content as JavaScript module
53
+ */
54
+ export declare function generateConfigFile(config: RalphConfig): string;
55
+ /**
56
+ * Generate ralph.config.js from scan result
57
+ */
58
+ export declare function generateConfigFileFromScan(scanResult: ScanResult, customVars?: Record<string, string>): string;
59
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/generator/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACL,SAAS,EAAE;YACT,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;QACF,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,WAAW,CAyC3G;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAQ9D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAGlH"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Config Generator
3
+ * Generates ralph.config.js file from scan results
4
+ */
5
+ import { extractVariables } from './templates.js';
6
+ /**
7
+ * Generate ralph config object from scan result
8
+ */
9
+ export function generateConfig(scanResult, customVars = {}) {
10
+ const vars = extractVariables(scanResult, customVars);
11
+ return {
12
+ name: vars.projectName,
13
+ stack: {
14
+ framework: {
15
+ name: vars.framework,
16
+ version: vars.frameworkVersion,
17
+ variant: vars.frameworkVariant,
18
+ },
19
+ packageManager: vars.packageManager,
20
+ testing: {
21
+ unit: vars.unitTest,
22
+ e2e: vars.e2eTest,
23
+ },
24
+ styling: vars.styling,
25
+ },
26
+ commands: {
27
+ dev: vars.devCommand,
28
+ build: vars.buildCommand,
29
+ test: vars.testCommand,
30
+ lint: vars.lintCommand,
31
+ typecheck: vars.typecheckCommand,
32
+ },
33
+ paths: {
34
+ root: '.ralph',
35
+ prompts: '.ralph/prompts',
36
+ guides: '.ralph/guides',
37
+ specs: '.ralph/specs',
38
+ scripts: '.ralph/scripts',
39
+ learnings: '.ralph/LEARNINGS.md',
40
+ agents: '.ralph/AGENTS.md',
41
+ },
42
+ loop: {
43
+ maxIterations: 10,
44
+ maxE2eAttempts: 5,
45
+ defaultModel: 'sonnet',
46
+ planningModel: 'opus',
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * Generate ralph.config.js file content as JavaScript module
52
+ */
53
+ export function generateConfigFile(config) {
54
+ const content = `module.exports = ${JSON.stringify(config, null, 2)};
55
+ `;
56
+ // Fix JSON to valid JS (unquote keys)
57
+ return content
58
+ .replace(/"(\w+)":/g, '$1:')
59
+ .replace(/: "([^"]+)"/g, ": '$1'");
60
+ }
61
+ /**
62
+ * Generate ralph.config.js from scan result
63
+ */
64
+ export function generateConfigFileFromScan(scanResult, customVars = {}) {
65
+ const config = generateConfig(scanResult, customVars);
66
+ return generateConfigFile(config);
67
+ }
68
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/generator/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAA0B,MAAM,gBAAgB,CAAC;AA4C1E;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,UAAsB,EAAE,aAAqC,EAAE;IAC5F,MAAM,IAAI,GAAG,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAEtD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,WAAW;QACtB,KAAK,EAAE;YACL,SAAS,EAAE;gBACT,IAAI,EAAE,IAAI,CAAC,SAAS;gBACpB,OAAO,EAAE,IAAI,CAAC,gBAAgB;gBAC9B,OAAO,EAAE,IAAI,CAAC,gBAAgB;aAC/B;YACD,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE;gBACP,IAAI,EAAE,IAAI,CAAC,QAAQ;gBACnB,GAAG,EAAE,IAAI,CAAC,OAAO;aAClB;YACD,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB;QACD,QAAQ,EAAE;YACR,GAAG,EAAE,IAAI,CAAC,UAAU;YACpB,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,SAAS,EAAE,IAAI,CAAC,gBAAgB;SACjC;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,gBAAgB;YACzB,MAAM,EAAE,eAAe;YACvB,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,qBAAqB;YAChC,MAAM,EAAE,kBAAkB;SAC3B;QACD,IAAI,EAAE;YACJ,aAAa,EAAE,EAAE;YACjB,cAAc,EAAE,CAAC;YACjB,YAAY,EAAE,QAAQ;YACtB,aAAa,EAAE,MAAM;SACtB;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,OAAO,GAAG,oBAAoB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CACpE,CAAC;IAEA,sCAAsC;IACtC,OAAO,OAAO;SACX,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC;SAC3B,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,UAAsB,EAAE,aAAqC,EAAE;IACxG,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtD,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}