popeye-cli 1.0.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 (209) hide show
  1. package/.env.example +25 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +320 -0
  4. package/dist/adapters/claude.d.ts +82 -0
  5. package/dist/adapters/claude.d.ts.map +1 -0
  6. package/dist/adapters/claude.js +230 -0
  7. package/dist/adapters/claude.js.map +1 -0
  8. package/dist/adapters/openai.d.ts +48 -0
  9. package/dist/adapters/openai.d.ts.map +1 -0
  10. package/dist/adapters/openai.js +257 -0
  11. package/dist/adapters/openai.js.map +1 -0
  12. package/dist/auth/claude.d.ts +44 -0
  13. package/dist/auth/claude.d.ts.map +1 -0
  14. package/dist/auth/claude.js +139 -0
  15. package/dist/auth/claude.js.map +1 -0
  16. package/dist/auth/index.d.ts +61 -0
  17. package/dist/auth/index.d.ts.map +1 -0
  18. package/dist/auth/index.js +141 -0
  19. package/dist/auth/index.js.map +1 -0
  20. package/dist/auth/keychain.d.ts +66 -0
  21. package/dist/auth/keychain.d.ts.map +1 -0
  22. package/dist/auth/keychain.js +125 -0
  23. package/dist/auth/keychain.js.map +1 -0
  24. package/dist/auth/openai-entry.d.ts +9 -0
  25. package/dist/auth/openai-entry.d.ts.map +1 -0
  26. package/dist/auth/openai-entry.js +410 -0
  27. package/dist/auth/openai-entry.js.map +1 -0
  28. package/dist/auth/openai.d.ts +71 -0
  29. package/dist/auth/openai.d.ts.map +1 -0
  30. package/dist/auth/openai.js +212 -0
  31. package/dist/auth/openai.js.map +1 -0
  32. package/dist/auth/server.d.ts +32 -0
  33. package/dist/auth/server.d.ts.map +1 -0
  34. package/dist/auth/server.js +213 -0
  35. package/dist/auth/server.js.map +1 -0
  36. package/dist/cli/commands/auth.d.ts +10 -0
  37. package/dist/cli/commands/auth.d.ts.map +1 -0
  38. package/dist/cli/commands/auth.js +162 -0
  39. package/dist/cli/commands/auth.js.map +1 -0
  40. package/dist/cli/commands/config.d.ts +10 -0
  41. package/dist/cli/commands/config.d.ts.map +1 -0
  42. package/dist/cli/commands/config.js +215 -0
  43. package/dist/cli/commands/config.js.map +1 -0
  44. package/dist/cli/commands/create.d.ts +10 -0
  45. package/dist/cli/commands/create.d.ts.map +1 -0
  46. package/dist/cli/commands/create.js +240 -0
  47. package/dist/cli/commands/create.js.map +1 -0
  48. package/dist/cli/commands/index.d.ts +10 -0
  49. package/dist/cli/commands/index.d.ts.map +1 -0
  50. package/dist/cli/commands/index.js +10 -0
  51. package/dist/cli/commands/index.js.map +1 -0
  52. package/dist/cli/commands/resume.d.ts +18 -0
  53. package/dist/cli/commands/resume.d.ts.map +1 -0
  54. package/dist/cli/commands/resume.js +241 -0
  55. package/dist/cli/commands/resume.js.map +1 -0
  56. package/dist/cli/commands/status.d.ts +18 -0
  57. package/dist/cli/commands/status.d.ts.map +1 -0
  58. package/dist/cli/commands/status.js +154 -0
  59. package/dist/cli/commands/status.js.map +1 -0
  60. package/dist/cli/index.d.ts +17 -0
  61. package/dist/cli/index.d.ts.map +1 -0
  62. package/dist/cli/index.js +71 -0
  63. package/dist/cli/index.js.map +1 -0
  64. package/dist/cli/interactive.d.ts +9 -0
  65. package/dist/cli/interactive.d.ts.map +1 -0
  66. package/dist/cli/interactive.js +330 -0
  67. package/dist/cli/interactive.js.map +1 -0
  68. package/dist/cli/output.d.ts +182 -0
  69. package/dist/cli/output.d.ts.map +1 -0
  70. package/dist/cli/output.js +355 -0
  71. package/dist/cli/output.js.map +1 -0
  72. package/dist/config/defaults.d.ts +57 -0
  73. package/dist/config/defaults.d.ts.map +1 -0
  74. package/dist/config/defaults.js +103 -0
  75. package/dist/config/defaults.js.map +1 -0
  76. package/dist/config/index.d.ts +138 -0
  77. package/dist/config/index.d.ts.map +1 -0
  78. package/dist/config/index.js +244 -0
  79. package/dist/config/index.js.map +1 -0
  80. package/dist/config/schema.d.ts +220 -0
  81. package/dist/config/schema.d.ts.map +1 -0
  82. package/dist/config/schema.js +141 -0
  83. package/dist/config/schema.js.map +1 -0
  84. package/dist/generators/index.d.ts +101 -0
  85. package/dist/generators/index.d.ts.map +1 -0
  86. package/dist/generators/index.js +200 -0
  87. package/dist/generators/index.js.map +1 -0
  88. package/dist/generators/python.d.ts +48 -0
  89. package/dist/generators/python.d.ts.map +1 -0
  90. package/dist/generators/python.js +262 -0
  91. package/dist/generators/python.js.map +1 -0
  92. package/dist/generators/templates/index.d.ts +6 -0
  93. package/dist/generators/templates/index.d.ts.map +1 -0
  94. package/dist/generators/templates/index.js +6 -0
  95. package/dist/generators/templates/index.js.map +1 -0
  96. package/dist/generators/templates/python.d.ts +53 -0
  97. package/dist/generators/templates/python.d.ts.map +1 -0
  98. package/dist/generators/templates/python.js +454 -0
  99. package/dist/generators/templates/python.js.map +1 -0
  100. package/dist/generators/templates/typescript.d.ts +53 -0
  101. package/dist/generators/templates/typescript.d.ts.map +1 -0
  102. package/dist/generators/templates/typescript.js +394 -0
  103. package/dist/generators/templates/typescript.js.map +1 -0
  104. package/dist/generators/typescript.d.ts +64 -0
  105. package/dist/generators/typescript.d.ts.map +1 -0
  106. package/dist/generators/typescript.js +271 -0
  107. package/dist/generators/typescript.js.map +1 -0
  108. package/dist/index.d.ts +7 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +12 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/state/index.d.ts +168 -0
  113. package/dist/state/index.d.ts.map +1 -0
  114. package/dist/state/index.js +338 -0
  115. package/dist/state/index.js.map +1 -0
  116. package/dist/state/persistence.d.ts +91 -0
  117. package/dist/state/persistence.d.ts.map +1 -0
  118. package/dist/state/persistence.js +201 -0
  119. package/dist/state/persistence.js.map +1 -0
  120. package/dist/types/cli.d.ts +132 -0
  121. package/dist/types/cli.d.ts.map +1 -0
  122. package/dist/types/cli.js +17 -0
  123. package/dist/types/cli.js.map +1 -0
  124. package/dist/types/consensus.d.ts +111 -0
  125. package/dist/types/consensus.d.ts.map +1 -0
  126. package/dist/types/consensus.js +29 -0
  127. package/dist/types/consensus.js.map +1 -0
  128. package/dist/types/index.d.ts +9 -0
  129. package/dist/types/index.d.ts.map +1 -0
  130. package/dist/types/index.js +13 -0
  131. package/dist/types/index.js.map +1 -0
  132. package/dist/types/project.d.ts +73 -0
  133. package/dist/types/project.d.ts.map +1 -0
  134. package/dist/types/project.js +55 -0
  135. package/dist/types/project.js.map +1 -0
  136. package/dist/types/workflow.d.ts +236 -0
  137. package/dist/types/workflow.d.ts.map +1 -0
  138. package/dist/types/workflow.js +74 -0
  139. package/dist/types/workflow.js.map +1 -0
  140. package/dist/workflow/consensus.d.ts +89 -0
  141. package/dist/workflow/consensus.d.ts.map +1 -0
  142. package/dist/workflow/consensus.js +220 -0
  143. package/dist/workflow/consensus.js.map +1 -0
  144. package/dist/workflow/execution-mode.d.ts +82 -0
  145. package/dist/workflow/execution-mode.d.ts.map +1 -0
  146. package/dist/workflow/execution-mode.js +346 -0
  147. package/dist/workflow/execution-mode.js.map +1 -0
  148. package/dist/workflow/index.d.ts +110 -0
  149. package/dist/workflow/index.d.ts.map +1 -0
  150. package/dist/workflow/index.js +283 -0
  151. package/dist/workflow/index.js.map +1 -0
  152. package/dist/workflow/plan-mode.d.ts +83 -0
  153. package/dist/workflow/plan-mode.d.ts.map +1 -0
  154. package/dist/workflow/plan-mode.js +241 -0
  155. package/dist/workflow/plan-mode.js.map +1 -0
  156. package/dist/workflow/test-runner.d.ts +87 -0
  157. package/dist/workflow/test-runner.d.ts.map +1 -0
  158. package/dist/workflow/test-runner.js +273 -0
  159. package/dist/workflow/test-runner.js.map +1 -0
  160. package/eslint.config.js +25 -0
  161. package/package.json +66 -0
  162. package/src/adapters/claude.ts +298 -0
  163. package/src/adapters/openai.ts +300 -0
  164. package/src/auth/claude.ts +166 -0
  165. package/src/auth/index.ts +171 -0
  166. package/src/auth/keychain.ts +138 -0
  167. package/src/auth/openai-entry.ts +410 -0
  168. package/src/auth/openai.ts +260 -0
  169. package/src/auth/server.ts +252 -0
  170. package/src/cli/commands/auth.ts +194 -0
  171. package/src/cli/commands/config.ts +241 -0
  172. package/src/cli/commands/create.ts +308 -0
  173. package/src/cli/commands/index.ts +10 -0
  174. package/src/cli/commands/resume.ts +304 -0
  175. package/src/cli/commands/status.ts +189 -0
  176. package/src/cli/index.ts +90 -0
  177. package/src/cli/interactive.ts +418 -0
  178. package/src/cli/output.ts +410 -0
  179. package/src/config/defaults.ts +114 -0
  180. package/src/config/index.ts +315 -0
  181. package/src/config/schema.ts +164 -0
  182. package/src/generators/index.ts +251 -0
  183. package/src/generators/python.ts +318 -0
  184. package/src/generators/templates/index.ts +6 -0
  185. package/src/generators/templates/python.ts +465 -0
  186. package/src/generators/templates/typescript.ts +417 -0
  187. package/src/generators/typescript.ts +340 -0
  188. package/src/index.ts +13 -0
  189. package/src/state/index.ts +454 -0
  190. package/src/state/persistence.ts +230 -0
  191. package/src/types/cli.ts +146 -0
  192. package/src/types/consensus.ts +116 -0
  193. package/src/types/index.ts +64 -0
  194. package/src/types/project.ts +85 -0
  195. package/src/types/workflow.ts +149 -0
  196. package/src/workflow/consensus.ts +299 -0
  197. package/src/workflow/execution-mode.ts +517 -0
  198. package/src/workflow/index.ts +396 -0
  199. package/src/workflow/plan-mode.ts +356 -0
  200. package/src/workflow/test-runner.ts +345 -0
  201. package/tests/adapters/openai.test.ts +145 -0
  202. package/tests/config/config.test.ts +208 -0
  203. package/tests/generators/generators.test.ts +185 -0
  204. package/tests/types/consensus.test.ts +152 -0
  205. package/tests/types/project.test.ts +134 -0
  206. package/tests/workflow/consensus.test.ts +221 -0
  207. package/tests/workflow/test-runner.test.ts +214 -0
  208. package/tsconfig.json +25 -0
  209. package/vitest.config.ts +22 -0
@@ -0,0 +1,340 @@
1
+ /**
2
+ * TypeScript project generator
3
+ * Creates complete TypeScript project scaffolding
4
+ */
5
+
6
+ import { promises as fs } from 'node:fs';
7
+ import path from 'node:path';
8
+ import type { ProjectSpec } from '../types/project.js';
9
+ import {
10
+ generatePackageJson,
11
+ generateTsconfig,
12
+ generateVitestConfig,
13
+ generateEslintConfig,
14
+ generatePrettierrc,
15
+ generateIndexTs,
16
+ generateTestFile,
17
+ generateDockerfile,
18
+ generateDockerCompose,
19
+ generateGitignore,
20
+ generateEnvExample,
21
+ generateReadme,
22
+ } from './templates/typescript.js';
23
+
24
+ /**
25
+ * Project generation result
26
+ */
27
+ export interface GenerationResult {
28
+ success: boolean;
29
+ projectDir: string;
30
+ filesCreated: string[];
31
+ error?: string;
32
+ }
33
+
34
+ /**
35
+ * Create a directory if it doesn't exist
36
+ */
37
+ async function ensureDir(dirPath: string): Promise<void> {
38
+ await fs.mkdir(dirPath, { recursive: true });
39
+ }
40
+
41
+ /**
42
+ * Write a file with content
43
+ */
44
+ async function writeFile(filePath: string, content: string): Promise<void> {
45
+ await fs.writeFile(filePath, content, 'utf-8');
46
+ }
47
+
48
+ /**
49
+ * Generate a complete TypeScript project
50
+ *
51
+ * @param spec - Project specification
52
+ * @param outputDir - Output directory
53
+ * @returns Generation result
54
+ */
55
+ export async function generateTypeScriptProject(
56
+ spec: ProjectSpec,
57
+ outputDir: string
58
+ ): Promise<GenerationResult> {
59
+ const projectName = spec.name || 'my-project';
60
+ const projectDir = path.join(outputDir, projectName);
61
+ const filesCreated: string[] = [];
62
+
63
+ try {
64
+ // Create project directory structure
65
+ await ensureDir(projectDir);
66
+ await ensureDir(path.join(projectDir, 'src'));
67
+ await ensureDir(path.join(projectDir, 'tests'));
68
+ await ensureDir(path.join(projectDir, 'data'));
69
+
70
+ // Generate and write files
71
+ const files: Array<{ path: string; content: string }> = [
72
+ // Root files
73
+ {
74
+ path: path.join(projectDir, 'package.json'),
75
+ content: generatePackageJson(projectName, spec.idea),
76
+ },
77
+ {
78
+ path: path.join(projectDir, 'tsconfig.json'),
79
+ content: generateTsconfig(),
80
+ },
81
+ {
82
+ path: path.join(projectDir, 'vitest.config.ts'),
83
+ content: generateVitestConfig(),
84
+ },
85
+ {
86
+ path: path.join(projectDir, 'eslint.config.js'),
87
+ content: generateEslintConfig(),
88
+ },
89
+ {
90
+ path: path.join(projectDir, '.prettierrc'),
91
+ content: generatePrettierrc(),
92
+ },
93
+ {
94
+ path: path.join(projectDir, '.gitignore'),
95
+ content: generateGitignore(),
96
+ },
97
+ {
98
+ path: path.join(projectDir, '.env.example'),
99
+ content: generateEnvExample(),
100
+ },
101
+ {
102
+ path: path.join(projectDir, 'README.md'),
103
+ content: generateReadme(projectName, spec.idea),
104
+ },
105
+ {
106
+ path: path.join(projectDir, 'Dockerfile'),
107
+ content: generateDockerfile(projectName),
108
+ },
109
+ {
110
+ path: path.join(projectDir, 'docker-compose.yml'),
111
+ content: generateDockerCompose(projectName),
112
+ },
113
+
114
+ // Source files
115
+ {
116
+ path: path.join(projectDir, 'src', 'index.ts'),
117
+ content: generateIndexTs(projectName),
118
+ },
119
+
120
+ // Test files
121
+ {
122
+ path: path.join(projectDir, 'tests', 'index.test.ts'),
123
+ content: generateTestFile(projectName),
124
+ },
125
+
126
+ // Data placeholder
127
+ {
128
+ path: path.join(projectDir, 'data', '.gitkeep'),
129
+ content: '',
130
+ },
131
+ ];
132
+
133
+ // Write all files
134
+ for (const file of files) {
135
+ await writeFile(file.path, file.content);
136
+ filesCreated.push(file.path);
137
+ }
138
+
139
+ return {
140
+ success: true,
141
+ projectDir,
142
+ filesCreated,
143
+ };
144
+ } catch (error) {
145
+ return {
146
+ success: false,
147
+ projectDir,
148
+ filesCreated,
149
+ error: error instanceof Error ? error.message : 'Unknown error',
150
+ };
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Get the list of files that would be generated
156
+ *
157
+ * @param projectName - Project name
158
+ * @returns List of relative file paths
159
+ */
160
+ export function getTypeScriptProjectFiles(_projectName: string): string[] {
161
+ return [
162
+ 'package.json',
163
+ 'tsconfig.json',
164
+ 'vitest.config.ts',
165
+ 'eslint.config.js',
166
+ '.prettierrc',
167
+ '.gitignore',
168
+ '.env.example',
169
+ 'README.md',
170
+ 'Dockerfile',
171
+ 'docker-compose.yml',
172
+ 'src/index.ts',
173
+ 'tests/index.test.ts',
174
+ 'data/.gitkeep',
175
+ ];
176
+ }
177
+
178
+ /**
179
+ * Validate a TypeScript project structure
180
+ *
181
+ * @param projectDir - Project directory
182
+ * @returns Validation result
183
+ */
184
+ export async function validateTypeScriptProject(projectDir: string): Promise<{
185
+ valid: boolean;
186
+ missingFiles: string[];
187
+ }> {
188
+ const missingFiles: string[] = [];
189
+
190
+ const requiredFiles = [
191
+ 'package.json',
192
+ 'tsconfig.json',
193
+ 'README.md',
194
+ 'src',
195
+ 'tests',
196
+ ];
197
+
198
+ for (const file of requiredFiles) {
199
+ const filePath = path.join(projectDir, file);
200
+ try {
201
+ await fs.access(filePath);
202
+ } catch {
203
+ missingFiles.push(file);
204
+ }
205
+ }
206
+
207
+ return {
208
+ valid: missingFiles.length === 0,
209
+ missingFiles,
210
+ };
211
+ }
212
+
213
+ /**
214
+ * Add a new TypeScript module to an existing project
215
+ *
216
+ * @param projectDir - Project directory
217
+ * @param moduleName - Module name
218
+ * @returns Files created
219
+ */
220
+ export async function addTypeScriptModule(
221
+ projectDir: string,
222
+ moduleName: string
223
+ ): Promise<string[]> {
224
+ const filesCreated: string[] = [];
225
+
226
+ const srcDir = path.join(projectDir, 'src');
227
+ const moduleDir = path.join(srcDir, moduleName);
228
+ await ensureDir(moduleDir);
229
+
230
+ // Create module files
231
+ const indexContent = `/**
232
+ * ${moduleName} module
233
+ */
234
+
235
+ export * from './${moduleName}.js';
236
+ `;
237
+ await writeFile(path.join(moduleDir, 'index.ts'), indexContent);
238
+ filesCreated.push(path.join(moduleDir, 'index.ts'));
239
+
240
+ const className = moduleName.charAt(0).toUpperCase() + moduleName.slice(1).replace(/-/g, '');
241
+ const moduleContent = `/**
242
+ * ${moduleName} implementation
243
+ */
244
+
245
+ /**
246
+ * ${className} class
247
+ */
248
+ export class ${className} {
249
+ /**
250
+ * Create a new ${className} instance
251
+ */
252
+ constructor() {
253
+ console.log(\`Initializing \${this.constructor.name}\`);
254
+ }
255
+
256
+ /**
257
+ * Run the ${moduleName} logic
258
+ */
259
+ run(): void {
260
+ throw new Error('Not implemented');
261
+ }
262
+ }
263
+ `;
264
+ await writeFile(path.join(moduleDir, `${moduleName}.ts`), moduleContent);
265
+ filesCreated.push(path.join(moduleDir, `${moduleName}.ts`));
266
+
267
+ // Create test file
268
+ const testDir = path.join(projectDir, 'tests');
269
+ const testContent = `import { describe, it, expect } from 'vitest';
270
+ import { ${className} } from '../src/${moduleName}/index.js';
271
+
272
+ describe('${className}', () => {
273
+ it('should create an instance', () => {
274
+ const instance = new ${className}();
275
+ expect(instance).toBeDefined();
276
+ });
277
+
278
+ it('should throw on run (placeholder)', () => {
279
+ const instance = new ${className}();
280
+ expect(() => instance.run()).toThrow('Not implemented');
281
+ });
282
+ });
283
+ `;
284
+ await writeFile(path.join(testDir, `${moduleName}.test.ts`), testContent);
285
+ filesCreated.push(path.join(testDir, `${moduleName}.test.ts`));
286
+
287
+ return filesCreated;
288
+ }
289
+
290
+ /**
291
+ * Add a dependency to package.json
292
+ *
293
+ * @param projectDir - Project directory
294
+ * @param packageName - Package name
295
+ * @param version - Package version
296
+ * @param dev - Whether it's a dev dependency
297
+ */
298
+ export async function addDependency(
299
+ projectDir: string,
300
+ packageName: string,
301
+ version: string,
302
+ dev: boolean = false
303
+ ): Promise<void> {
304
+ const packageJsonPath = path.join(projectDir, 'package.json');
305
+ const content = await fs.readFile(packageJsonPath, 'utf-8');
306
+ const packageJson = JSON.parse(content);
307
+
308
+ const key = dev ? 'devDependencies' : 'dependencies';
309
+ packageJson[key] = packageJson[key] || {};
310
+ packageJson[key][packageName] = version;
311
+
312
+ // Sort dependencies
313
+ packageJson[key] = Object.fromEntries(
314
+ Object.entries(packageJson[key]).sort(([a], [b]) => a.localeCompare(b))
315
+ );
316
+
317
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
318
+ }
319
+
320
+ /**
321
+ * Update package.json scripts
322
+ *
323
+ * @param projectDir - Project directory
324
+ * @param scripts - Scripts to add/update
325
+ */
326
+ export async function updateScripts(
327
+ projectDir: string,
328
+ scripts: Record<string, string>
329
+ ): Promise<void> {
330
+ const packageJsonPath = path.join(projectDir, 'package.json');
331
+ const content = await fs.readFile(packageJsonPath, 'utf-8');
332
+ const packageJson = JSON.parse(content);
333
+
334
+ packageJson.scripts = {
335
+ ...packageJson.scripts,
336
+ ...scripts,
337
+ };
338
+
339
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
340
+ }
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Popeye CLI
4
+ * Fully autonomous code generation powered by Claude CLI and OpenAI consensus
5
+ */
6
+
7
+ import { runCLI } from './cli/index.js';
8
+
9
+ // Run the CLI
10
+ runCLI().catch((error) => {
11
+ console.error('Fatal error:', error);
12
+ process.exit(1);
13
+ });