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,410 @@
1
+ /**
2
+ * CLI output utilities
3
+ * Handles formatted output, spinners, and progress display
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import ora, { type Ora } from 'ora';
8
+ import type { ProjectState, Milestone, Task } from '../types/workflow.js';
9
+ import type { ConsensusResult } from '../types/consensus.js';
10
+ import type { TestResult } from '../workflow/test-runner.js';
11
+
12
+ /**
13
+ * Output theme colors
14
+ */
15
+ export const theme = {
16
+ primary: chalk.cyan,
17
+ secondary: chalk.gray,
18
+ success: chalk.green,
19
+ warning: chalk.yellow,
20
+ error: chalk.red,
21
+ info: chalk.blue,
22
+ highlight: chalk.bold.white,
23
+ dim: chalk.dim,
24
+ };
25
+
26
+ /**
27
+ * Spinner instance for progress display
28
+ */
29
+ let spinner: Ora | null = null;
30
+
31
+ /**
32
+ * Start a spinner with a message
33
+ *
34
+ * @param message - Initial message
35
+ * @returns Spinner instance
36
+ */
37
+ export function startSpinner(message: string): Ora {
38
+ if (spinner) {
39
+ spinner.stop();
40
+ }
41
+ spinner = ora({
42
+ text: message,
43
+ spinner: 'dots',
44
+ }).start();
45
+ return spinner;
46
+ }
47
+
48
+ /**
49
+ * Update spinner message
50
+ *
51
+ * @param message - New message
52
+ */
53
+ export function updateSpinner(message: string): void {
54
+ if (spinner) {
55
+ spinner.text = message;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Stop spinner with success
61
+ *
62
+ * @param message - Success message
63
+ */
64
+ export function succeedSpinner(message?: string): void {
65
+ if (spinner) {
66
+ spinner.succeed(message);
67
+ spinner = null;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Stop spinner with failure
73
+ *
74
+ * @param message - Failure message
75
+ */
76
+ export function failSpinner(message?: string): void {
77
+ if (spinner) {
78
+ spinner.fail(message);
79
+ spinner = null;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Stop spinner without status
85
+ */
86
+ export function stopSpinner(): void {
87
+ if (spinner) {
88
+ spinner.stop();
89
+ spinner = null;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Print a header
95
+ *
96
+ * @param title - Header title
97
+ */
98
+ export function printHeader(title: string): void {
99
+ console.log();
100
+ console.log(theme.primary.bold(`=== ${title} ===`));
101
+ console.log();
102
+ }
103
+
104
+ /**
105
+ * Print a section header
106
+ *
107
+ * @param title - Section title
108
+ */
109
+ export function printSection(title: string): void {
110
+ console.log();
111
+ console.log(theme.highlight(`--- ${title} ---`));
112
+ }
113
+
114
+ /**
115
+ * Print a success message
116
+ *
117
+ * @param message - Success message
118
+ */
119
+ export function printSuccess(message: string): void {
120
+ console.log(theme.success(`[OK] ${message}`));
121
+ }
122
+
123
+ /**
124
+ * Print a warning message
125
+ *
126
+ * @param message - Warning message
127
+ */
128
+ export function printWarning(message: string): void {
129
+ console.log(theme.warning(`[WARN] ${message}`));
130
+ }
131
+
132
+ /**
133
+ * Print an error message
134
+ *
135
+ * @param message - Error message
136
+ */
137
+ export function printError(message: string): void {
138
+ console.log(theme.error(`[ERROR] ${message}`));
139
+ }
140
+
141
+ /**
142
+ * Print an info message
143
+ *
144
+ * @param message - Info message
145
+ */
146
+ export function printInfo(message: string): void {
147
+ console.log(theme.info(`[INFO] ${message}`));
148
+ }
149
+
150
+ /**
151
+ * Print a key-value pair
152
+ *
153
+ * @param key - Key
154
+ * @param value - Value
155
+ */
156
+ export function printKeyValue(key: string, value: string | number | boolean): void {
157
+ console.log(` ${theme.secondary(key + ':')} ${value}`);
158
+ }
159
+
160
+ /**
161
+ * Print a list item
162
+ *
163
+ * @param item - List item
164
+ * @param indent - Indentation level
165
+ */
166
+ export function printListItem(item: string, indent: number = 0): void {
167
+ const prefix = ' '.repeat(indent) + '- ';
168
+ console.log(theme.secondary(prefix) + item);
169
+ }
170
+
171
+ /**
172
+ * Print project state summary
173
+ *
174
+ * @param state - Project state
175
+ */
176
+ export function printProjectState(state: ProjectState): void {
177
+ printHeader(`Project: ${state.name}`);
178
+
179
+ printKeyValue('ID', state.id);
180
+ printKeyValue('Language', state.language);
181
+ printKeyValue('Phase', state.phase);
182
+ printKeyValue('Status', state.status);
183
+ printKeyValue('Created', state.createdAt);
184
+ printKeyValue('Updated', state.updatedAt);
185
+
186
+ if (state.error) {
187
+ printSection('Error');
188
+ printError(state.error);
189
+ }
190
+
191
+ if (state.milestones.length > 0) {
192
+ printSection('Milestones');
193
+ for (const milestone of state.milestones) {
194
+ printMilestone(milestone);
195
+ }
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Print milestone summary
201
+ *
202
+ * @param milestone - Milestone
203
+ */
204
+ export function printMilestone(milestone: Milestone): void {
205
+ const statusIcon = getStatusIcon(milestone.status);
206
+ console.log(`\n ${statusIcon} ${theme.highlight(milestone.name)}`);
207
+
208
+ if (milestone.tasks.length > 0) {
209
+ for (const task of milestone.tasks) {
210
+ printTask(task, 2);
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Print task summary
217
+ *
218
+ * @param task - Task
219
+ * @param indent - Indentation level
220
+ */
221
+ export function printTask(task: Task, indent: number = 0): void {
222
+ const statusIcon = getStatusIcon(task.status);
223
+ const prefix = ' '.repeat(indent);
224
+ console.log(`${prefix}${statusIcon} ${task.name}`);
225
+ }
226
+
227
+ /**
228
+ * Get status icon
229
+ *
230
+ * @param status - Status
231
+ * @returns Status icon
232
+ */
233
+ function getStatusIcon(status: string): string {
234
+ switch (status) {
235
+ case 'complete':
236
+ return theme.success('[OK]');
237
+ case 'in-progress':
238
+ return theme.warning('[..]');
239
+ case 'failed':
240
+ return theme.error('[X]');
241
+ default:
242
+ return theme.dim('[ ]');
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Print consensus result
248
+ *
249
+ * @param result - Consensus result
250
+ */
251
+ export function printConsensusResult(result: ConsensusResult): void {
252
+ const scoreColor = result.score >= 95 ? theme.success :
253
+ result.score >= 80 ? theme.warning : theme.error;
254
+
255
+ printSection('Consensus Review');
256
+ console.log(` Score: ${scoreColor(`${result.score}%`)}`);
257
+ console.log(` Status: ${result.approved ? theme.success('APPROVED') : theme.warning('PENDING')}`);
258
+
259
+ if (result.strengths && result.strengths.length > 0) {
260
+ console.log();
261
+ console.log(theme.success(' Strengths:'));
262
+ for (const strength of result.strengths.slice(0, 3)) {
263
+ printListItem(strength, 2);
264
+ }
265
+ }
266
+
267
+ if (result.concerns && result.concerns.length > 0) {
268
+ console.log();
269
+ console.log(theme.warning(' Concerns:'));
270
+ for (const concern of result.concerns.slice(0, 3)) {
271
+ printListItem(concern, 2);
272
+ }
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Print test result
278
+ *
279
+ * @param result - Test result
280
+ */
281
+ export function printTestResult(result: TestResult): void {
282
+ printSection('Test Results');
283
+
284
+ if (result.error) {
285
+ printError(result.error);
286
+ return;
287
+ }
288
+
289
+ const statusIcon = result.success ? theme.success('[PASS]') : theme.error('[FAIL]');
290
+ console.log(` ${statusIcon} ${result.passed}/${result.total} tests passed`);
291
+
292
+ if (result.failedTests && result.failedTests.length > 0) {
293
+ console.log();
294
+ console.log(theme.error(' Failed tests:'));
295
+ for (const test of result.failedTests.slice(0, 5)) {
296
+ printListItem(test, 2);
297
+ }
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Print progress bar
303
+ *
304
+ * @param current - Current value
305
+ * @param total - Total value
306
+ * @param label - Label
307
+ */
308
+ export function printProgress(current: number, total: number, label?: string): void {
309
+ const percent = total > 0 ? Math.round((current / total) * 100) : 0;
310
+ const barWidth = 30;
311
+ const filled = Math.round((percent / 100) * barWidth);
312
+ const empty = barWidth - filled;
313
+
314
+ const bar = theme.success('#'.repeat(filled)) + theme.dim('-'.repeat(empty));
315
+ const percentStr = `${percent}%`.padStart(4);
316
+
317
+ console.log(` [${bar}] ${percentStr}${label ? ` - ${label}` : ''}`);
318
+ }
319
+
320
+ /**
321
+ * Print authentication status
322
+ *
323
+ * @param status - Authentication status
324
+ */
325
+ export function printAuthStatus(status: {
326
+ claude: { authenticated: boolean; user?: string };
327
+ openai: { authenticated: boolean; keyLastFour?: string };
328
+ }): void {
329
+ printSection('Authentication Status');
330
+
331
+ // Claude status
332
+ const claudeIcon = status.claude.authenticated ? theme.success('[OK]') : theme.error('[X]');
333
+ const claudeInfo = status.claude.user || 'Not authenticated';
334
+ console.log(` ${claudeIcon} Claude CLI: ${claudeInfo}`);
335
+
336
+ // OpenAI status
337
+ const openaiIcon = status.openai.authenticated ? theme.success('[OK]') : theme.error('[X]');
338
+ const openaiInfo = status.openai.keyLastFour
339
+ ? `Authenticated (****${status.openai.keyLastFour})`
340
+ : 'Not authenticated';
341
+ console.log(` ${openaiIcon} OpenAI API: ${openaiInfo}`);
342
+ }
343
+
344
+ /**
345
+ * Print help for a command
346
+ *
347
+ * @param command - Command name
348
+ * @param description - Command description
349
+ * @param usage - Usage string
350
+ * @param options - Command options
351
+ */
352
+ export function printHelp(
353
+ command: string,
354
+ description: string,
355
+ usage: string,
356
+ options?: Array<{ flag: string; description: string }>
357
+ ): void {
358
+ printHeader(command);
359
+ console.log(description);
360
+ console.log();
361
+ console.log(theme.highlight('Usage:'));
362
+ console.log(` ${usage}`);
363
+
364
+ if (options && options.length > 0) {
365
+ console.log();
366
+ console.log(theme.highlight('Options:'));
367
+ for (const opt of options) {
368
+ console.log(` ${theme.primary(opt.flag.padEnd(20))} ${opt.description}`);
369
+ }
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Print a table
375
+ *
376
+ * @param headers - Table headers
377
+ * @param rows - Table rows
378
+ */
379
+ export function printTable(headers: string[], rows: string[][]): void {
380
+ // Calculate column widths
381
+ const widths = headers.map((h, i) => {
382
+ const maxRow = Math.max(...rows.map((r) => (r[i] || '').length));
383
+ return Math.max(h.length, maxRow);
384
+ });
385
+
386
+ // Print header
387
+ const headerLine = headers.map((h, i) => h.padEnd(widths[i])).join(' ');
388
+ console.log(theme.highlight(headerLine));
389
+ console.log(theme.dim('-'.repeat(headerLine.length)));
390
+
391
+ // Print rows
392
+ for (const row of rows) {
393
+ const rowLine = row.map((cell, i) => (cell || '').padEnd(widths[i])).join(' ');
394
+ console.log(rowLine);
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Clear the console
400
+ */
401
+ export function clearConsole(): void {
402
+ console.clear();
403
+ }
404
+
405
+ /**
406
+ * Print a blank line
407
+ */
408
+ export function printBlank(): void {
409
+ console.log();
410
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Default configuration values
3
+ * Matches popeye-cli-spec.md section 9.1 exactly
4
+ */
5
+
6
+ import type { Config } from './schema.js';
7
+
8
+ /**
9
+ * Default configuration object
10
+ */
11
+ export const DEFAULT_CONFIG: Config = {
12
+ consensus: {
13
+ threshold: 95,
14
+ max_disagreements: 5,
15
+ escalation_action: 'pause',
16
+ },
17
+ apis: {
18
+ openai: {
19
+ model: 'gpt-4o',
20
+ temperature: 0.3,
21
+ max_tokens: 4096,
22
+ available_models: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1-preview', 'o1-mini'],
23
+ },
24
+ claude: {
25
+ model: 'claude-sonnet-4-20250514',
26
+ },
27
+ },
28
+ project: {
29
+ default_language: 'python',
30
+ python: {
31
+ package_manager: 'pip',
32
+ test_framework: 'pytest',
33
+ min_version: '3.10',
34
+ },
35
+ typescript: {
36
+ package_manager: 'npm',
37
+ test_framework: 'jest',
38
+ min_version: '18',
39
+ },
40
+ },
41
+ directories: {
42
+ docs: 'docs',
43
+ tests: 'docs/tests',
44
+ plans: 'docs/plans',
45
+ },
46
+ output: {
47
+ format: 'markdown',
48
+ verbose: false,
49
+ timestamps: true,
50
+ show_consensus_dialog: true,
51
+ },
52
+ };
53
+
54
+ /**
55
+ * Configuration file names to search for
56
+ */
57
+ export const CONFIG_FILE_NAMES = [
58
+ 'popeye.config.yaml',
59
+ 'popeye.config.yml',
60
+ '.popeyerc.yaml',
61
+ '.popeyerc.yml',
62
+ '.popeyerc',
63
+ ];
64
+
65
+ /**
66
+ * Global config directory path
67
+ */
68
+ export const GLOBAL_CONFIG_DIR = '.popeye';
69
+
70
+ /**
71
+ * State file name
72
+ */
73
+ export const STATE_FILE_NAME = 'state.json';
74
+
75
+ /**
76
+ * Config file name in .popeye directory
77
+ */
78
+ export const CONFIG_FILE_NAME = 'config.yaml';
79
+
80
+ /**
81
+ * Service name for keychain
82
+ */
83
+ export const SERVICE_NAME = 'popeye-cli';
84
+
85
+ /**
86
+ * Keychain account names
87
+ */
88
+ export const KEYCHAIN_ACCOUNTS = {
89
+ CLAUDE: 'claude-cli',
90
+ OPENAI: 'openai-api',
91
+ } as const;
92
+
93
+ /**
94
+ * Environment variable names
95
+ */
96
+ export const ENV_VARS = {
97
+ OPENAI_KEY: 'POPEYE_OPENAI_KEY',
98
+ ANTHROPIC_KEY: 'POPEYE_ANTHROPIC_KEY',
99
+ DEFAULT_LANGUAGE: 'POPEYE_DEFAULT_LANGUAGE',
100
+ OPENAI_MODEL: 'POPEYE_OPENAI_MODEL',
101
+ CONSENSUS_THRESHOLD: 'POPEYE_CONSENSUS_THRESHOLD',
102
+ MAX_DISAGREEMENTS: 'POPEYE_MAX_DISAGREEMENTS',
103
+ LOG_LEVEL: 'POPEYE_LOG_LEVEL',
104
+ } as const;
105
+
106
+ /**
107
+ * CLI version
108
+ */
109
+ export const CLI_VERSION = '1.0.0';
110
+
111
+ /**
112
+ * State file version
113
+ */
114
+ export const STATE_VERSION = '1.0.0';