@agile-vibe-coding/avc 0.1.1 → 0.3.1

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 (239) hide show
  1. package/cli/agent-loader.js +21 -0
  2. package/cli/agents/agent-selector.md +152 -0
  3. package/cli/agents/architecture-recommender.md +418 -0
  4. package/cli/agents/code-implementer.md +117 -0
  5. package/cli/agents/code-validator.md +80 -0
  6. package/cli/agents/context-reviewer-epic.md +101 -0
  7. package/cli/agents/context-reviewer-story.md +92 -0
  8. package/cli/agents/context-writer-epic.md +145 -0
  9. package/cli/agents/context-writer-story.md +111 -0
  10. package/cli/agents/database-deep-dive.md +470 -0
  11. package/cli/agents/database-recommender.md +634 -0
  12. package/cli/agents/doc-distributor.md +176 -0
  13. package/cli/agents/doc-writer-epic.md +42 -0
  14. package/cli/agents/doc-writer-story.md +43 -0
  15. package/cli/agents/documentation-updater.md +203 -0
  16. package/cli/agents/duplicate-detector.md +110 -0
  17. package/cli/agents/epic-story-decomposer.md +559 -0
  18. package/cli/agents/feature-context-generator.md +91 -0
  19. package/cli/agents/gap-checker-epic.md +52 -0
  20. package/cli/agents/impact-checker-story.md +51 -0
  21. package/cli/agents/migration-guide-generator.md +305 -0
  22. package/cli/agents/mission-scope-generator.md +143 -0
  23. package/cli/agents/mission-scope-validator.md +146 -0
  24. package/cli/agents/project-context-extractor.md +122 -0
  25. package/cli/agents/project-documentation-creator.json +226 -0
  26. package/cli/agents/project-documentation-creator.md +595 -0
  27. package/cli/agents/question-prefiller.md +269 -0
  28. package/cli/agents/refiner-epic.md +39 -0
  29. package/cli/agents/refiner-story.md +42 -0
  30. package/cli/agents/scaffolding-generator.md +99 -0
  31. package/cli/agents/seed-validator.md +71 -0
  32. package/cli/agents/story-doc-enricher.md +133 -0
  33. package/cli/agents/story-scope-reviewer.md +147 -0
  34. package/cli/agents/story-splitter.md +83 -0
  35. package/cli/agents/suggestion-business-analyst.md +88 -0
  36. package/cli/agents/suggestion-deployment-architect.md +263 -0
  37. package/cli/agents/suggestion-product-manager.md +129 -0
  38. package/cli/agents/suggestion-security-specialist.md +156 -0
  39. package/cli/agents/suggestion-technical-architect.md +269 -0
  40. package/cli/agents/suggestion-ux-researcher.md +93 -0
  41. package/cli/agents/task-subtask-decomposer.md +188 -0
  42. package/cli/agents/validator-documentation.json +183 -0
  43. package/cli/agents/validator-documentation.md +455 -0
  44. package/cli/agents/validator-selector.md +211 -0
  45. package/cli/ansi-colors.js +21 -0
  46. package/cli/api-reference-tool.js +368 -0
  47. package/cli/build-docs.js +29 -8
  48. package/cli/ceremony-history.js +369 -0
  49. package/cli/checks/catalog.json +76 -0
  50. package/cli/checks/code/quality.json +26 -0
  51. package/cli/checks/code/testing.json +14 -0
  52. package/cli/checks/code/traceability.json +26 -0
  53. package/cli/checks/cross-refs/epic.json +171 -0
  54. package/cli/checks/cross-refs/story.json +149 -0
  55. package/cli/checks/epic/api.json +114 -0
  56. package/cli/checks/epic/backend.json +126 -0
  57. package/cli/checks/epic/cloud.json +126 -0
  58. package/cli/checks/epic/data.json +102 -0
  59. package/cli/checks/epic/database.json +114 -0
  60. package/cli/checks/epic/developer.json +182 -0
  61. package/cli/checks/epic/devops.json +174 -0
  62. package/cli/checks/epic/frontend.json +162 -0
  63. package/cli/checks/epic/mobile.json +102 -0
  64. package/cli/checks/epic/qa.json +90 -0
  65. package/cli/checks/epic/security.json +184 -0
  66. package/cli/checks/epic/solution-architect.json +192 -0
  67. package/cli/checks/epic/test-architect.json +90 -0
  68. package/cli/checks/epic/ui.json +102 -0
  69. package/cli/checks/epic/ux.json +90 -0
  70. package/cli/checks/fixes/epic-fix-template.md +10 -0
  71. package/cli/checks/fixes/story-fix-template.md +10 -0
  72. package/cli/checks/story/api.json +186 -0
  73. package/cli/checks/story/backend.json +102 -0
  74. package/cli/checks/story/cloud.json +102 -0
  75. package/cli/checks/story/data.json +210 -0
  76. package/cli/checks/story/database.json +102 -0
  77. package/cli/checks/story/developer.json +168 -0
  78. package/cli/checks/story/devops.json +102 -0
  79. package/cli/checks/story/frontend.json +174 -0
  80. package/cli/checks/story/mobile.json +102 -0
  81. package/cli/checks/story/qa.json +210 -0
  82. package/cli/checks/story/security.json +198 -0
  83. package/cli/checks/story/solution-architect.json +230 -0
  84. package/cli/checks/story/test-architect.json +210 -0
  85. package/cli/checks/story/ui.json +102 -0
  86. package/cli/checks/story/ux.json +102 -0
  87. package/cli/coding-order.js +401 -0
  88. package/cli/command-logger.js +49 -12
  89. package/cli/components/static-output.js +63 -0
  90. package/cli/console-output-manager.js +94 -0
  91. package/cli/dependency-checker.js +72 -0
  92. package/cli/docs-sync.js +306 -0
  93. package/cli/epic-story-validator.js +659 -0
  94. package/cli/evaluation-prompts.js +1008 -0
  95. package/cli/execution-context.js +195 -0
  96. package/cli/generate-summary-table.js +340 -0
  97. package/cli/init-model-config.js +704 -0
  98. package/cli/init.js +1737 -278
  99. package/cli/kanban-server-manager.js +227 -0
  100. package/cli/llm-claude.js +150 -1
  101. package/cli/llm-gemini.js +109 -0
  102. package/cli/llm-local.js +493 -0
  103. package/cli/llm-mock.js +233 -0
  104. package/cli/llm-openai.js +454 -0
  105. package/cli/llm-provider.js +379 -3
  106. package/cli/llm-token-limits.js +211 -0
  107. package/cli/llm-verifier.js +662 -0
  108. package/cli/llm-xiaomi.js +143 -0
  109. package/cli/message-constants.js +49 -0
  110. package/cli/message-manager.js +334 -0
  111. package/cli/message-types.js +96 -0
  112. package/cli/messaging-api.js +291 -0
  113. package/cli/micro-check-fixer.js +335 -0
  114. package/cli/micro-check-runner.js +449 -0
  115. package/cli/micro-check-scorer.js +148 -0
  116. package/cli/micro-check-validator.js +538 -0
  117. package/cli/model-pricing.js +192 -0
  118. package/cli/model-query-engine.js +468 -0
  119. package/cli/model-recommendation-analyzer.js +495 -0
  120. package/cli/model-selector.js +270 -0
  121. package/cli/output-buffer.js +107 -0
  122. package/cli/process-manager.js +73 -2
  123. package/cli/prompt-logger.js +57 -0
  124. package/cli/repl-ink.js +4625 -1094
  125. package/cli/repl-old.js +3 -4
  126. package/cli/seed-processor.js +962 -0
  127. package/cli/sprint-planning-processor.js +4162 -0
  128. package/cli/template-processor.js +2149 -105
  129. package/cli/templates/project.md +25 -8
  130. package/cli/templates/vitepress-config.mts.template +5 -4
  131. package/cli/token-tracker.js +547 -0
  132. package/cli/tools/generate-story-validators.js +317 -0
  133. package/cli/tools/generate-validators.js +669 -0
  134. package/cli/update-checker.js +19 -17
  135. package/cli/update-notifier.js +4 -4
  136. package/cli/validation-router.js +667 -0
  137. package/cli/verification-tracker.js +563 -0
  138. package/cli/worktree-runner.js +654 -0
  139. package/kanban/README.md +386 -0
  140. package/kanban/client/README.md +205 -0
  141. package/kanban/client/components.json +20 -0
  142. package/kanban/client/dist/assets/index-D_KC5EQT.css +1 -0
  143. package/kanban/client/dist/assets/index-DjY5zqW7.js +351 -0
  144. package/kanban/client/dist/index.html +16 -0
  145. package/kanban/client/dist/vite.svg +1 -0
  146. package/kanban/client/index.html +15 -0
  147. package/kanban/client/package-lock.json +9442 -0
  148. package/kanban/client/package.json +44 -0
  149. package/kanban/client/postcss.config.js +6 -0
  150. package/kanban/client/public/vite.svg +1 -0
  151. package/kanban/client/src/App.jsx +651 -0
  152. package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
  153. package/kanban/client/src/components/ceremony/AskArchPopup.jsx +420 -0
  154. package/kanban/client/src/components/ceremony/AskModelPopup.jsx +629 -0
  155. package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +1133 -0
  156. package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
  157. package/kanban/client/src/components/ceremony/ProviderSwitcherButton.jsx +290 -0
  158. package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +686 -0
  159. package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +838 -0
  160. package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
  161. package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +136 -0
  162. package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
  163. package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
  164. package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
  165. package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +329 -0
  166. package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +249 -0
  167. package/kanban/client/src/components/kanban/CardDetailModal.jsx +646 -0
  168. package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
  169. package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
  170. package/kanban/client/src/components/kanban/GroupingSelector.jsx +63 -0
  171. package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
  172. package/kanban/client/src/components/kanban/KanbanCard.jsx +147 -0
  173. package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
  174. package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +784 -0
  175. package/kanban/client/src/components/kanban/RunButton.jsx +162 -0
  176. package/kanban/client/src/components/kanban/SeedButton.jsx +176 -0
  177. package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
  178. package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
  179. package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
  180. package/kanban/client/src/components/settings/AgentsTab.jsx +381 -0
  181. package/kanban/client/src/components/settings/ApiKeysTab.jsx +142 -0
  182. package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +105 -0
  183. package/kanban/client/src/components/settings/CheckEditorPopup.jsx +507 -0
  184. package/kanban/client/src/components/settings/CostThresholdsTab.jsx +95 -0
  185. package/kanban/client/src/components/settings/ModelPricingTab.jsx +269 -0
  186. package/kanban/client/src/components/settings/OpenAIAuthSection.jsx +412 -0
  187. package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
  188. package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
  189. package/kanban/client/src/components/stats/CostModal.jsx +384 -0
  190. package/kanban/client/src/components/ui/badge.jsx +27 -0
  191. package/kanban/client/src/components/ui/dialog.jsx +121 -0
  192. package/kanban/client/src/components/ui/tabs.jsx +85 -0
  193. package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
  194. package/kanban/client/src/hooks/useGrouping.js +177 -0
  195. package/kanban/client/src/hooks/useWebSocket.js +120 -0
  196. package/kanban/client/src/lib/__tests__/api.test.js +196 -0
  197. package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
  198. package/kanban/client/src/lib/api.js +515 -0
  199. package/kanban/client/src/lib/status-grouping.js +154 -0
  200. package/kanban/client/src/lib/utils.js +11 -0
  201. package/kanban/client/src/main.jsx +10 -0
  202. package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
  203. package/kanban/client/src/store/ceremonyStore.js +172 -0
  204. package/kanban/client/src/store/filterStore.js +201 -0
  205. package/kanban/client/src/store/kanbanStore.js +123 -0
  206. package/kanban/client/src/store/processStore.js +65 -0
  207. package/kanban/client/src/store/sprintPlanningStore.js +33 -0
  208. package/kanban/client/src/styles/globals.css +59 -0
  209. package/kanban/client/tailwind.config.js +77 -0
  210. package/kanban/client/vite.config.js +28 -0
  211. package/kanban/client/vitest.config.js +28 -0
  212. package/kanban/dev-start.sh +47 -0
  213. package/kanban/package.json +12 -0
  214. package/kanban/server/index.js +537 -0
  215. package/kanban/server/routes/ceremony.js +454 -0
  216. package/kanban/server/routes/costs.js +163 -0
  217. package/kanban/server/routes/openai-oauth.js +366 -0
  218. package/kanban/server/routes/processes.js +50 -0
  219. package/kanban/server/routes/settings.js +736 -0
  220. package/kanban/server/routes/websocket.js +281 -0
  221. package/kanban/server/routes/work-items.js +487 -0
  222. package/kanban/server/services/CeremonyService.js +1441 -0
  223. package/kanban/server/services/FileSystemScanner.js +95 -0
  224. package/kanban/server/services/FileWatcher.js +144 -0
  225. package/kanban/server/services/HierarchyBuilder.js +196 -0
  226. package/kanban/server/services/ProcessRegistry.js +122 -0
  227. package/kanban/server/services/TaskRunnerService.js +261 -0
  228. package/kanban/server/services/WorkItemReader.js +123 -0
  229. package/kanban/server/services/WorkItemRefineService.js +510 -0
  230. package/kanban/server/start.js +49 -0
  231. package/kanban/server/utils/kanban-logger.js +132 -0
  232. package/kanban/server/utils/markdown.js +91 -0
  233. package/kanban/server/utils/status-grouping.js +107 -0
  234. package/kanban/server/workers/run-task-worker.js +121 -0
  235. package/kanban/server/workers/seed-worker.js +94 -0
  236. package/kanban/server/workers/sponsor-call-worker.js +92 -0
  237. package/kanban/server/workers/sprint-planning-worker.js +212 -0
  238. package/package.json +19 -7
  239. package/cli/agents/documentation.md +0 -302
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Execution Context - Tracks command execution lifecycle
3
+ *
4
+ * Prevents ghost messages by associating messages with specific command runs.
5
+ * Each command execution creates a unique context that can be cancelled/completed.
6
+ */
7
+
8
+ import { randomBytes } from 'crypto';
9
+
10
+ /**
11
+ * Execution state enum
12
+ */
13
+ export const ExecutionState = {
14
+ ACTIVE: 'active',
15
+ CANCELLED: 'cancelled',
16
+ COMPLETED: 'completed'
17
+ };
18
+
19
+ /**
20
+ * ExecutionContext class
21
+ * Represents a single command execution lifecycle
22
+ */
23
+ export class ExecutionContext {
24
+ /**
25
+ * @param {string} commandName - Name of the command being executed
26
+ */
27
+ constructor(commandName) {
28
+ this.id = this._generateId();
29
+ this.commandName = commandName;
30
+ this.state = ExecutionState.ACTIVE;
31
+ this.startTime = Date.now();
32
+ this.endTime = null;
33
+ this.messageBuffer = [];
34
+ this.executingMessage = null; // Current progress message
35
+ this.executingSubstep = null; // Current substep message
36
+ }
37
+
38
+ /**
39
+ * Generate unique execution ID
40
+ * @private
41
+ * @returns {string} Unique ID
42
+ */
43
+ _generateId() {
44
+ return `${Date.now()}-${randomBytes(4).toString('hex')}`;
45
+ }
46
+
47
+ /**
48
+ * Check if context is active
49
+ * @returns {boolean} True if active
50
+ */
51
+ isActive() {
52
+ return this.state === ExecutionState.ACTIVE;
53
+ }
54
+
55
+ /**
56
+ * Check if context is cancelled
57
+ * @returns {boolean} True if cancelled
58
+ */
59
+ isCancelled() {
60
+ return this.state === ExecutionState.CANCELLED;
61
+ }
62
+
63
+ /**
64
+ * Check if context is completed
65
+ * @returns {boolean} True if completed
66
+ */
67
+ isCompleted() {
68
+ return this.state === ExecutionState.COMPLETED;
69
+ }
70
+
71
+ /**
72
+ * Cancel this execution context
73
+ * Prevents any further messages from being output
74
+ */
75
+ cancel() {
76
+ if (this.state === ExecutionState.ACTIVE) {
77
+ this.state = ExecutionState.CANCELLED;
78
+ this.endTime = Date.now();
79
+ this.messageBuffer = []; // Clear any pending messages
80
+ this.executingMessage = null;
81
+ this.executingSubstep = null;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Mark this execution context as completed
87
+ */
88
+ complete() {
89
+ if (this.state === ExecutionState.ACTIVE) {
90
+ this.state = ExecutionState.COMPLETED;
91
+ this.endTime = Date.now();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Add message to buffer
97
+ * @param {Object} message - Message object
98
+ */
99
+ addMessage(message) {
100
+ if (this.isActive()) {
101
+ this.messageBuffer.push({
102
+ ...message,
103
+ timestamp: Date.now(),
104
+ contextId: this.id
105
+ });
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Set executing message (progress indicator)
111
+ * @param {string} message - Progress message
112
+ */
113
+ setExecutingMessage(message) {
114
+ if (this.isActive()) {
115
+ this.executingMessage = message;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Set executing substep (detailed progress)
121
+ * @param {string} substep - Substep message
122
+ */
123
+ setExecutingSubstep(substep) {
124
+ if (this.isActive()) {
125
+ this.executingSubstep = substep;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Clear executing message
131
+ */
132
+ clearExecutingMessage() {
133
+ this.executingMessage = null;
134
+ }
135
+
136
+ /**
137
+ * Clear executing substep
138
+ */
139
+ clearExecutingSubstep() {
140
+ this.executingSubstep = null;
141
+ }
142
+
143
+ /**
144
+ * Get all buffered messages
145
+ * @returns {Array} Message array
146
+ */
147
+ getMessages() {
148
+ return [...this.messageBuffer];
149
+ }
150
+
151
+ /**
152
+ * Clear message buffer
153
+ */
154
+ clearMessages() {
155
+ this.messageBuffer = [];
156
+ }
157
+
158
+ /**
159
+ * Get execution duration in milliseconds
160
+ * @returns {number|null} Duration or null if still active
161
+ */
162
+ getDuration() {
163
+ if (this.endTime) {
164
+ return this.endTime - this.startTime;
165
+ }
166
+ return Date.now() - this.startTime;
167
+ }
168
+
169
+ /**
170
+ * Get context summary for debugging
171
+ * @returns {Object} Context summary
172
+ */
173
+ toJSON() {
174
+ return {
175
+ id: this.id,
176
+ commandName: this.commandName,
177
+ state: this.state,
178
+ startTime: this.startTime,
179
+ endTime: this.endTime,
180
+ duration: this.getDuration(),
181
+ messageCount: this.messageBuffer.length,
182
+ executingMessage: this.executingMessage,
183
+ executingSubstep: this.executingSubstep
184
+ };
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Check if an execution state is valid
190
+ * @param {string} state - State to validate
191
+ * @returns {boolean} True if valid
192
+ */
193
+ export function isValidExecutionState(state) {
194
+ return Object.values(ExecutionState).includes(state);
195
+ }
@@ -0,0 +1,340 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Generate Summary Table from Model Evaluation Results
5
+ * Creates a comprehensive table showing stage vs provider recommendations
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import { sendError, sendWarning, sendSuccess, sendInfo, sendOutput, sendIndented, sendSectionHeader } from './messaging-api.js';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+
16
+ /**
17
+ * Load evaluation results from JSON file
18
+ */
19
+ function loadResults() {
20
+ const jsonPath = path.join(process.cwd(), '_temp', 'model-recommendations.json');
21
+
22
+ if (!fs.existsSync(jsonPath)) {
23
+ sendError('model-recommendations.json not found in _temp/');
24
+ sendIndented('Please run "npm run models:evaluate" first.', 1);
25
+ process.exit(1);
26
+ }
27
+
28
+ const data = fs.readFileSync(jsonPath, 'utf-8');
29
+ return JSON.parse(data);
30
+ }
31
+
32
+ /**
33
+ * Truncate text to specified length
34
+ */
35
+ function truncate(text, maxLength = 80) {
36
+ if (!text) return 'N/A';
37
+ if (text.length <= maxLength) return text;
38
+ return text.substring(0, maxLength - 3) + '...';
39
+ }
40
+
41
+ /**
42
+ * Generate markdown summary table
43
+ */
44
+ function generateMarkdownTable(results) {
45
+ const { evaluations } = results;
46
+
47
+ let markdown = '# Model Evaluation Summary Table\n\n';
48
+ markdown += `Generated: ${new Date().toISOString()}\n\n`;
49
+ markdown += '---\n\n';
50
+
51
+ // Group by ceremony
52
+ const byCeremony = {};
53
+ for (const evaluation of evaluations) {
54
+ if (!byCeremony[evaluation.ceremony]) {
55
+ byCeremony[evaluation.ceremony] = [];
56
+ }
57
+ byCeremony[evaluation.ceremony].push(evaluation);
58
+ }
59
+
60
+ // Generate table for each ceremony
61
+ for (const [ceremony, ceremonyEvals] of Object.entries(byCeremony)) {
62
+ markdown += `## ${ceremony.toUpperCase()}\n\n`;
63
+
64
+ // Table header
65
+ markdown += '| Stage | Current Default | Claude | OpenAI | Gemini | Consensus |\n';
66
+ markdown += '|-------|-----------------|--------|--------|--------|----------|\n';
67
+
68
+ for (const evaluation of ceremonyEvals) {
69
+ const { stageName, analysis, recommendations } = evaluation;
70
+
71
+ // Get current default from analysis
72
+ const currentDefault = analysis?.currentDefault || 'Unknown';
73
+
74
+ // Get provider recommendations
75
+ const claudeRec = recommendations.claude?.model || 'Error';
76
+ const openaiRec = recommendations.openai?.model || 'Error';
77
+ const geminiRec = recommendations.gemini?.model || 'Error';
78
+
79
+ // Get consensus
80
+ const consensus = analysis?.consensus?.level || 'unknown';
81
+ const consensusPrefix = consensus === 'full' ? '[OK]' :
82
+ consensus === 'partial' ? '[WARN]' :
83
+ consensus === 'none' ? '[ERR]' : '[?]';
84
+ const consensusText = `${consensusPrefix} ${consensus}`;
85
+
86
+ markdown += `| ${stageName} | ${currentDefault} | ${claudeRec} | ${openaiRec} | ${geminiRec} | ${consensusText} |\n`;
87
+ }
88
+
89
+ markdown += '\n';
90
+ }
91
+
92
+ return markdown;
93
+ }
94
+
95
+ /**
96
+ * Generate detailed table with reasoning
97
+ */
98
+ function generateDetailedTable(results) {
99
+ const { evaluations } = results;
100
+
101
+ let markdown = '# Detailed Model Recommendations\n\n';
102
+ markdown += `Generated: ${new Date().toISOString()}\n\n`;
103
+ markdown += '---\n\n';
104
+
105
+ // Group by ceremony
106
+ const byCeremony = {};
107
+ for (const evaluation of evaluations) {
108
+ if (!byCeremony[evaluation.ceremony]) {
109
+ byCeremony[evaluation.ceremony] = [];
110
+ }
111
+ byCeremony[evaluation.ceremony].push(evaluation);
112
+ }
113
+
114
+ // Generate detailed section for each ceremony
115
+ for (const [ceremony, ceremonyEvals] of Object.entries(byCeremony)) {
116
+ markdown += `## ${ceremony.toUpperCase()}\n\n`;
117
+
118
+ for (const evaluation of ceremonyEvals) {
119
+ const { stageName, analysis, recommendations } = evaluation;
120
+
121
+ markdown += `### ${stageName}\n\n`;
122
+ markdown += `**Current Default:** ${analysis?.currentDefault || 'Unknown'}\n\n`;
123
+ markdown += `**Consensus:** ${analysis?.consensus?.level || 'unknown'} (${analysis?.consensus?.agreement || 'N/A'})\n\n`;
124
+
125
+ // Provider recommendations table
126
+ markdown += '| Provider | Model | Confidence | Reasoning |\n';
127
+ markdown += '|----------|-------|------------|----------|\n';
128
+
129
+ for (const [provider, rec] of Object.entries(recommendations)) {
130
+ if (rec.status === 'error') {
131
+ markdown += `| ${provider} | Error | N/A | ${rec.error} |\n`;
132
+ } else {
133
+ const reasoning = truncate(rec.reasoning, 100);
134
+ markdown += `| ${provider} | ${rec.model} | ${rec.confidence} | ${reasoning} |\n`;
135
+ }
136
+ }
137
+
138
+ markdown += '\n';
139
+
140
+ // Insights
141
+ if (analysis?.insights && analysis.insights.length > 0) {
142
+ markdown += '**Insights:**\n';
143
+ for (const insight of analysis.insights) {
144
+ markdown += `- ${insight}\n`;
145
+ }
146
+ markdown += '\n';
147
+ }
148
+
149
+ markdown += '---\n\n';
150
+ }
151
+ }
152
+
153
+ return markdown;
154
+ }
155
+
156
+ /**
157
+ * Generate CSV export
158
+ */
159
+ function generateCSV(results) {
160
+ const { evaluations } = results;
161
+
162
+ let csv = 'Ceremony,Stage,Current Default,Claude Model,Claude Confidence,OpenAI Model,OpenAI Confidence,Gemini Model,Gemini Confidence,Consensus,Consensus Level\n';
163
+
164
+ for (const evaluation of evaluations) {
165
+ const { ceremony, stageName, analysis, recommendations } = evaluation;
166
+
167
+ const currentDefault = analysis?.currentDefault || 'Unknown';
168
+ const claudeModel = recommendations.claude?.model || 'Error';
169
+ const claudeConf = recommendations.claude?.confidence || 'N/A';
170
+ const openaiModel = recommendations.openai?.model || 'Error';
171
+ const openaiConf = recommendations.openai?.confidence || 'N/A';
172
+ const geminiModel = recommendations.gemini?.model || 'Error';
173
+ const geminiConf = recommendations.gemini?.confidence || 'N/A';
174
+ const consensus = analysis?.consensus?.agreement || 'N/A';
175
+ const consensusLevel = analysis?.consensus?.level || 'unknown';
176
+
177
+ // Escape CSV fields
178
+ const escapeCSV = (str) => `"${str.replace(/"/g, '""')}"`;
179
+
180
+ csv += `${escapeCSV(ceremony)},${escapeCSV(stageName)},${escapeCSV(currentDefault)},`;
181
+ csv += `${escapeCSV(claudeModel)},${escapeCSV(claudeConf)},`;
182
+ csv += `${escapeCSV(openaiModel)},${escapeCSV(openaiConf)},`;
183
+ csv += `${escapeCSV(geminiModel)},${escapeCSV(geminiConf)},`;
184
+ csv += `${escapeCSV(consensus)},${escapeCSV(consensusLevel)}\n`;
185
+ }
186
+
187
+ return csv;
188
+ }
189
+
190
+ /**
191
+ * Generate comparison matrix (Stage vs Provider)
192
+ */
193
+ function generateComparisonMatrix(results) {
194
+ const { evaluations } = results;
195
+
196
+ let markdown = '# Stage vs Provider Recommendation Matrix\n\n';
197
+ markdown += `Generated: ${new Date().toISOString()}\n\n`;
198
+ markdown += 'This matrix shows which model each provider recommends for each stage.\n\n';
199
+ markdown += '---\n\n';
200
+
201
+ // Create matrix
202
+ markdown += '| Stage | Claude | OpenAI | Gemini | Agreement |\n';
203
+ markdown += '|-------|--------|--------|--------|----------|\n';
204
+
205
+ for (const evaluation of evaluations) {
206
+ const { ceremony, stage, stageName, recommendations, analysis } = evaluation;
207
+
208
+ const claudeModel = recommendations.claude?.model || '[ERR]';
209
+ const openaiModel = recommendations.openai?.model || '[ERR]';
210
+ const geminiModel = recommendations.gemini?.model || '[ERR]';
211
+
212
+ // Consensus indicator
213
+ const consensus = analysis?.consensus?.level || 'unknown';
214
+ const agreementText = consensus === 'full' ? '[OK] All agree' :
215
+ consensus === 'partial' ? `[WARN] ${analysis?.consensus?.agreement}` :
216
+ consensus === 'none' ? '[ERR] No consensus' :
217
+ '[?] Unknown';
218
+
219
+ const stageLabel = `${ceremony}/${stage}`;
220
+
221
+ markdown += `| ${stageLabel} | ${claudeModel} | ${openaiModel} | ${geminiModel} | ${agreementText} |\n`;
222
+ }
223
+
224
+ markdown += '\n---\n\n';
225
+
226
+ // Add legend
227
+ markdown += '## Legend\n\n';
228
+ markdown += '- [OK] **Full consensus** - All providers recommend same model tier\n';
229
+ markdown += '- [WARN] **Partial consensus** - Majority agreement (2/3 providers)\n';
230
+ markdown += '- [ERR] **No consensus** - All providers recommend different models\n';
231
+ markdown += '- [ERR] **Error** - Provider query failed\n\n';
232
+
233
+ return markdown;
234
+ }
235
+
236
+ /**
237
+ * Generate statistics summary
238
+ */
239
+ function generateStatistics(results) {
240
+ const { summary, analysis } = results;
241
+
242
+ let markdown = '# Evaluation Statistics\n\n';
243
+ markdown += `Generated: ${new Date().toISOString()}\n\n`;
244
+ markdown += '---\n\n';
245
+
246
+ // Execution stats
247
+ markdown += '## Execution Summary\n\n';
248
+ markdown += `- **Total prompts evaluated:** ${summary.totalPrompts}\n`;
249
+ markdown += `- **Successful queries:** ${summary.successfulQueries}\n`;
250
+ markdown += `- **Failed queries:** ${summary.failedQueries}\n`;
251
+ markdown += `- **Execution time:** ${summary.executionTime}\n\n`;
252
+
253
+ // Cost breakdown
254
+ markdown += '## Cost Breakdown\n\n';
255
+ markdown += '| Provider | Cost |\n';
256
+ markdown += '|----------|------|\n';
257
+ for (const [provider, cost] of Object.entries(summary.totalCost)) {
258
+ if (provider !== 'total') {
259
+ markdown += `| ${provider} | $${cost.toFixed(4)} |\n`;
260
+ }
261
+ }
262
+ markdown += `| **TOTAL** | **$${summary.totalCost.total.toFixed(4)}** |\n\n`;
263
+
264
+ // Consensus statistics
265
+ if (analysis && analysis.statistics) {
266
+ markdown += '## Consensus Statistics\n\n';
267
+ markdown += `- **Full consensus:** ${analysis.statistics.consensus.full} stages (${analysis.statistics.consensusRate.full})\n`;
268
+ markdown += `- **Partial consensus:** ${analysis.statistics.consensus.partial} stages (${analysis.statistics.consensusRate.partial})\n`;
269
+ markdown += `- **No consensus:** ${analysis.statistics.consensus.none} stages (${analysis.statistics.consensusRate.none})\n\n`;
270
+
271
+ markdown += '## Default Alignment\n\n';
272
+ markdown += `- **Perfect alignment:** ${analysis.statistics.defaultAlignment.perfect} stages\n`;
273
+ markdown += `- **Partial alignment:** ${analysis.statistics.defaultAlignment.partial} stages\n`;
274
+ markdown += `- **No alignment:** ${analysis.statistics.defaultAlignment.none} stages\n\n`;
275
+
276
+ markdown += '## Recommendations\n\n';
277
+ markdown += `- **Upgrade suggestions:** ${analysis.statistics.upgradeRecommendations} stages\n`;
278
+ markdown += `- **Downgrade suggestions:** ${analysis.statistics.downgradeRecommendations} stages\n\n`;
279
+ }
280
+
281
+ return markdown;
282
+ }
283
+
284
+ /**
285
+ * Main function
286
+ */
287
+ function main() {
288
+ sendOutput('\n╔══════════════════════════════════════════════════════════════╗');
289
+ sendOutput('║ Generate Summary Tables from Evaluation ║');
290
+ sendOutput('╚══════════════════════════════════════════════════════════════╝');
291
+
292
+ // Load results
293
+ sendInfo('Loading evaluation results...');
294
+ const results = loadResults();
295
+ sendIndented('Results loaded', 1);
296
+
297
+ // Generate outputs
298
+ const tempDir = path.join(process.cwd(), '_temp');
299
+
300
+ sendSectionHeader('Generating summary tables');
301
+
302
+ // 1. Simple summary table
303
+ const summaryTable = generateMarkdownTable(results);
304
+ const summaryPath = path.join(tempDir, 'EVALUATION_SUMMARY_TABLE.md');
305
+ fs.writeFileSync(summaryPath, summaryTable, 'utf-8');
306
+ sendIndented(`Summary table: ${summaryPath}`, 1);
307
+
308
+ // 2. Detailed table with reasoning
309
+ const detailedTable = generateDetailedTable(results);
310
+ const detailedPath = path.join(tempDir, 'EVALUATION_DETAILED_TABLE.md');
311
+ fs.writeFileSync(detailedPath, detailedTable, 'utf-8');
312
+ sendIndented(`Detailed table: ${detailedPath}`, 1);
313
+
314
+ // 3. Comparison matrix
315
+ const comparisonMatrix = generateComparisonMatrix(results);
316
+ const matrixPath = path.join(tempDir, 'EVALUATION_COMPARISON_MATRIX.md');
317
+ fs.writeFileSync(matrixPath, comparisonMatrix, 'utf-8');
318
+ sendIndented(`Comparison matrix: ${matrixPath}`, 1);
319
+
320
+ // 4. Statistics
321
+ const statistics = generateStatistics(results);
322
+ const statsPath = path.join(tempDir, 'EVALUATION_STATISTICS.md');
323
+ fs.writeFileSync(statsPath, statistics, 'utf-8');
324
+ sendIndented(`Statistics: ${statsPath}`, 1);
325
+
326
+ // 5. CSV export
327
+ const csv = generateCSV(results);
328
+ const csvPath = path.join(tempDir, 'evaluation-results.csv');
329
+ fs.writeFileSync(csvPath, csv, 'utf-8');
330
+ sendIndented(`CSV export: ${csvPath}`, 1);
331
+
332
+ sendSuccess('All tables generated successfully!');
333
+ }
334
+
335
+ // Run if executed directly
336
+ if (import.meta.url === `file://${process.argv[1]}`) {
337
+ main();
338
+ }
339
+
340
+ export { generateMarkdownTable, generateDetailedTable, generateComparisonMatrix, generateCSV, generateStatistics };