wogiflow 2.4.2 → 2.4.4

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 (210) hide show
  1. package/.claude/commands/wogi-start.md +124 -0
  2. package/.claude/docs/claude-code-compatibility.md +51 -0
  3. package/.claude/docs/explore-agents.md +11 -0
  4. package/.claude/settings.json +12 -1
  5. package/.workflow/models/registry.json +1 -1
  6. package/bin/flow +11 -1
  7. package/lib/workspace-contracts.js +599 -0
  8. package/lib/workspace-intelligence.js +600 -0
  9. package/lib/workspace-messages.js +441 -0
  10. package/lib/workspace-routing.js +485 -0
  11. package/lib/workspace-sync.js +339 -0
  12. package/lib/workspace.js +1073 -0
  13. package/package.json +4 -4
  14. package/scripts/MEMORY-ARCHITECTURE.md +1 -1
  15. package/scripts/base-workflow-step.js +136 -0
  16. package/scripts/flow-adaptive-learning.js +8 -9
  17. package/scripts/flow-aggregate.js +11 -6
  18. package/scripts/flow-api-index.js +4 -6
  19. package/scripts/flow-assumption-detector.js +0 -2
  20. package/scripts/flow-audit.js +15 -2
  21. package/scripts/flow-auto-context.js +8 -12
  22. package/scripts/flow-auto-learn.js +49 -49
  23. package/scripts/flow-background.js +5 -6
  24. package/scripts/flow-bridge-state.js +8 -10
  25. package/scripts/flow-bulk-loop.js +1 -3
  26. package/scripts/flow-bulk-orchestrator.js +1 -3
  27. package/scripts/flow-cascade-completion.js +0 -2
  28. package/scripts/flow-cascade.js +4 -4
  29. package/scripts/flow-checkpoint.js +10 -13
  30. package/scripts/flow-code-intelligence.js +10 -12
  31. package/scripts/flow-community-sync.js +4 -4
  32. package/scripts/flow-community.js +12 -20
  33. package/scripts/flow-config-defaults.js +28 -2
  34. package/scripts/flow-config-interactive.js +9 -5
  35. package/scripts/flow-config-loader.js +49 -92
  36. package/scripts/flow-config-substitution.js +0 -2
  37. package/scripts/flow-context-estimator.js +4 -4
  38. package/scripts/flow-context-init.js +10 -12
  39. package/scripts/flow-context-manager.js +0 -2
  40. package/scripts/flow-context-scoring.js +2 -2
  41. package/scripts/flow-contract-scan.js +6 -9
  42. package/scripts/flow-correct.js +29 -27
  43. package/scripts/flow-correction-detector.js +5 -1
  44. package/scripts/flow-damage-control.js +47 -54
  45. package/scripts/flow-decisions-merge.js +4 -14
  46. package/scripts/flow-diff.js +5 -8
  47. package/scripts/flow-done-gates.js +786 -0
  48. package/scripts/flow-done-report.js +123 -0
  49. package/scripts/flow-done.js +71 -717
  50. package/scripts/flow-entropy-monitor.js +1 -3
  51. package/scripts/flow-eval-calibration.js +257 -0
  52. package/scripts/flow-eval-judge.js +10 -1
  53. package/scripts/flow-eval.js +14 -5
  54. package/scripts/flow-extraction-review.js +1 -0
  55. package/scripts/flow-failure-categories.js +0 -2
  56. package/scripts/flow-figma-confirm.js +5 -9
  57. package/scripts/flow-figma-generate.js +8 -10
  58. package/scripts/flow-figma-index.js +8 -10
  59. package/scripts/flow-figma-match.js +3 -5
  60. package/scripts/flow-figma-mcp-server.js +2 -4
  61. package/scripts/flow-figma-orchestrator.js +2 -3
  62. package/scripts/flow-figma-registry.js +2 -3
  63. package/scripts/flow-framework-resolver.js +0 -2
  64. package/scripts/flow-function-index.js +4 -6
  65. package/scripts/flow-gate-confidence.js +2 -2
  66. package/scripts/flow-gitignore.js +0 -2
  67. package/scripts/flow-guided-edit.js +5 -6
  68. package/scripts/flow-health.js +5 -6
  69. package/scripts/flow-hook-errors.js +6 -0
  70. package/scripts/flow-hook-status.js +263 -0
  71. package/scripts/flow-hooks.js +17 -29
  72. package/scripts/flow-http-client.js +9 -8
  73. package/scripts/flow-hybrid-interactive.js +7 -12
  74. package/scripts/flow-hybrid-test.js +12 -13
  75. package/scripts/flow-instruction-richness.js +1 -1
  76. package/scripts/flow-io.js +21 -4
  77. package/scripts/flow-knowledge-router.js +9 -3
  78. package/scripts/flow-learning-orchestrator.js +318 -13
  79. package/scripts/flow-links.js +5 -7
  80. package/scripts/flow-long-input-association.js +275 -0
  81. package/scripts/flow-long-input-chunking.js +1 -0
  82. package/scripts/flow-long-input-cli.js +0 -2
  83. package/scripts/flow-long-input-complexity.js +0 -2
  84. package/scripts/flow-long-input-constants.js +0 -2
  85. package/scripts/flow-long-input-contradictions.js +351 -0
  86. package/scripts/flow-long-input-detection.js +0 -2
  87. package/scripts/flow-long-input-passes.js +885 -0
  88. package/scripts/flow-long-input-stories.js +1 -1
  89. package/scripts/flow-long-input-voice.js +0 -2
  90. package/scripts/flow-long-input.js +425 -3005
  91. package/scripts/flow-loop-retry-learning.js +2 -3
  92. package/scripts/flow-lsp.js +3 -3
  93. package/scripts/flow-mcp-docs.js +3 -4
  94. package/scripts/flow-memory-db.js +6 -8
  95. package/scripts/flow-memory-sync.js +18 -11
  96. package/scripts/flow-metrics.js +1 -2
  97. package/scripts/flow-model-adapter.js +2 -3
  98. package/scripts/flow-model-config.js +72 -104
  99. package/scripts/flow-model-router.js +2 -2
  100. package/scripts/flow-model-types.js +0 -2
  101. package/scripts/flow-multi-approach.js +5 -6
  102. package/scripts/flow-orchestrate-context.js +3 -7
  103. package/scripts/flow-orchestrate-rollback.js +3 -8
  104. package/scripts/flow-orchestrate-state.js +8 -14
  105. package/scripts/flow-orchestrate-templates.js +2 -6
  106. package/scripts/flow-orchestrate-validator.js +5 -9
  107. package/scripts/flow-orchestrate.js +126 -103
  108. package/scripts/flow-output.js +0 -2
  109. package/scripts/flow-parallel.js +1 -1
  110. package/scripts/flow-paths.js +23 -2
  111. package/scripts/flow-pattern-enforcer.js +30 -28
  112. package/scripts/flow-pattern-extractor.js +3 -4
  113. package/scripts/flow-pending.js +0 -2
  114. package/scripts/flow-permissions.js +2 -3
  115. package/scripts/flow-plugin-registry.js +10 -12
  116. package/scripts/flow-prd-manager.js +1 -1
  117. package/scripts/flow-progress.js +7 -9
  118. package/scripts/flow-prompt-composer.js +3 -3
  119. package/scripts/flow-prompt-template.js +2 -2
  120. package/scripts/flow-providers.js +7 -4
  121. package/scripts/flow-registry-manager.js +7 -12
  122. package/scripts/flow-regression.js +9 -11
  123. package/scripts/flow-roadmap.js +2 -2
  124. package/scripts/flow-run-trace.js +16 -15
  125. package/scripts/flow-safety.js +2 -5
  126. package/scripts/flow-scanner-base.js +5 -7
  127. package/scripts/flow-scenario-engine.js +1 -5
  128. package/scripts/flow-security.js +29 -0
  129. package/scripts/flow-session-end.js +32 -41
  130. package/scripts/flow-session-learning.js +53 -49
  131. package/scripts/flow-setup-hooks.js +2 -3
  132. package/scripts/flow-skill-create.js +7 -12
  133. package/scripts/flow-skill-generator.js +12 -16
  134. package/scripts/flow-skill-learn.js +17 -8
  135. package/scripts/flow-skill-matcher.js +1 -2
  136. package/scripts/flow-spec-generator.js +2 -4
  137. package/scripts/flow-stack-wizard.js +5 -7
  138. package/scripts/flow-standards-learner.js +35 -16
  139. package/scripts/flow-start.js +2 -0
  140. package/scripts/flow-stats-collector.js +2 -2
  141. package/scripts/flow-status.js +10 -10
  142. package/scripts/flow-statusline-setup.js +2 -2
  143. package/scripts/flow-step-changelog.js +2 -3
  144. package/scripts/flow-step-comments.js +66 -81
  145. package/scripts/flow-step-complexity.js +50 -70
  146. package/scripts/flow-step-coverage.js +3 -5
  147. package/scripts/flow-step-knowledge.js +2 -3
  148. package/scripts/flow-step-pr-tests.js +64 -74
  149. package/scripts/flow-step-regression.js +3 -5
  150. package/scripts/flow-step-review.js +86 -103
  151. package/scripts/flow-step-security.js +111 -121
  152. package/scripts/flow-step-silent-failures.js +56 -83
  153. package/scripts/flow-step-simplifier.js +52 -70
  154. package/scripts/flow-story.js +4 -7
  155. package/scripts/flow-strict-adherence.js +3 -4
  156. package/scripts/flow-task-checkpoint.js +36 -5
  157. package/scripts/flow-task-enforcer.js +2 -24
  158. package/scripts/flow-tech-debt.js +1 -1
  159. package/scripts/flow-template-extractor.js +1 -0
  160. package/scripts/flow-templates.js +11 -13
  161. package/scripts/flow-test-api.js +9 -13
  162. package/scripts/flow-test-discovery.js +1 -1
  163. package/scripts/flow-test-generate.js +5 -9
  164. package/scripts/flow-test-integrity.js +3 -7
  165. package/scripts/flow-test-ui.js +5 -9
  166. package/scripts/flow-testing-deps.js +1 -3
  167. package/scripts/flow-tiered-learning.js +4 -4
  168. package/scripts/flow-todowrite-sync.js +1 -1
  169. package/scripts/flow-tokens.js +0 -2
  170. package/scripts/flow-verification-profile.js +6 -10
  171. package/scripts/flow-verify.js +12 -16
  172. package/scripts/flow-version-check.js +4 -12
  173. package/scripts/flow-webmcp-generator.js +3 -5
  174. package/scripts/flow-workflow-steps.js +0 -2
  175. package/scripts/flow-workflow.js +9 -11
  176. package/scripts/hooks/adapters/claude-code.js +31 -0
  177. package/scripts/hooks/core/config-change.js +1 -0
  178. package/scripts/hooks/core/extension-registry.js +0 -2
  179. package/scripts/hooks/core/instructions-loaded.js +1 -1
  180. package/scripts/hooks/core/observation-capture.js +5 -5
  181. package/scripts/hooks/core/phase-gate.js +5 -0
  182. package/scripts/hooks/core/post-compact.js +1 -12
  183. package/scripts/hooks/core/research-gate.js +2 -12
  184. package/scripts/hooks/core/routing-gate.js +6 -0
  185. package/scripts/hooks/core/task-completed.js +12 -0
  186. package/scripts/hooks/core/task-created.js +83 -0
  187. package/scripts/hooks/core/worktree-lifecycle.js +1 -1
  188. package/scripts/hooks/entry/claude-code/config-change.js +6 -29
  189. package/scripts/hooks/entry/claude-code/instructions-loaded.js +5 -30
  190. package/scripts/hooks/entry/claude-code/post-compact.js +4 -31
  191. package/scripts/hooks/entry/claude-code/post-tool-use.js +121 -172
  192. package/scripts/hooks/entry/claude-code/pre-tool-use.js +260 -361
  193. package/scripts/hooks/entry/claude-code/session-end.js +4 -28
  194. package/scripts/hooks/entry/claude-code/session-start.js +205 -243
  195. package/scripts/hooks/entry/claude-code/setup.js +8 -49
  196. package/scripts/hooks/entry/claude-code/stop.js +40 -72
  197. package/scripts/hooks/entry/claude-code/task-completed.js +4 -28
  198. package/scripts/hooks/entry/claude-code/task-created.js +15 -0
  199. package/scripts/hooks/entry/claude-code/user-prompt-submit.js +113 -195
  200. package/scripts/hooks/entry/claude-code/worktree-create.js +6 -25
  201. package/scripts/hooks/entry/claude-code/worktree-remove.js +6 -25
  202. package/scripts/hooks/entry/shared/hook-runner.js +99 -0
  203. package/scripts/hooks/entry/shared/read-stdin.js +0 -2
  204. package/scripts/postinstall.js +2 -0
  205. package/scripts/registries/api-registry.js +0 -2
  206. package/scripts/registries/component-registry.js +5 -9
  207. package/scripts/registries/contract-scanner.js +2 -9
  208. package/scripts/registries/function-registry.js +0 -2
  209. package/scripts/registries/schema-registry.js +14 -18
  210. package/scripts/registries/service-registry.js +23 -27
@@ -19,14 +19,12 @@ const path = require('node:path');
19
19
  const memoryDb = require('./flow-memory-db');
20
20
  const { getConfig } = require('./flow-config-loader');
21
21
  const { color } = require('./flow-output');
22
- const { getProjectRoot } = require('./flow-paths');
22
+ const { getProjectRoot, PATHS } = require('./flow-paths');
23
23
 
24
24
  // ============================================================
25
25
  // Configuration
26
26
  // ============================================================
27
27
 
28
- const PROJECT_ROOT = getProjectRoot();
29
-
30
28
  // ============================================================
31
29
  // Output Formatting
32
30
  // ============================================================
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Eval Calibration
5
+ *
6
+ * Stores and retrieves calibrated eval examples for anchoring judge scores.
7
+ * Prevents score drift by providing few-shot examples of what high and low
8
+ * scores look like in practice.
9
+ *
10
+ * Based on Anthropic's harness design research finding that "few-shot examples
11
+ * with detailed score breakdowns calibrated evaluator judgment, reducing score
12
+ * drift across iterations."
13
+ *
14
+ * Usage:
15
+ * node flow-eval-calibration.js save <taskId> <quality> — save as calibration example
16
+ * node flow-eval-calibration.js get — get calibration examples for prompt injection
17
+ * node flow-eval-calibration.js list — list all calibration examples
18
+ */
19
+
20
+ const path = require('node:path');
21
+ const fs = require('node:fs');
22
+ const { PATHS, safeJsonParse, writeJson } = require('./flow-utils');
23
+
24
+ // ============================================================
25
+ // Constants
26
+ // ============================================================
27
+
28
+ const CALIBRATION_PATH = path.join(PATHS.state, 'eval-calibration.json');
29
+ const MAX_EXAMPLES_PER_QUALITY = 3; // Keep 3 high, 3 low
30
+
31
+ // ============================================================
32
+ // Storage
33
+ // ============================================================
34
+
35
+ /**
36
+ * Load calibration data
37
+ * @returns {Object} { high: [], low: [], lastUpdated }
38
+ */
39
+ function loadCalibration() {
40
+ return safeJsonParse(CALIBRATION_PATH, {
41
+ high: [],
42
+ low: [],
43
+ lastUpdated: null
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Save a completed eval as a calibration example.
49
+ * Called after /wogi-eval produces scores.
50
+ *
51
+ * @param {Object} params
52
+ * @param {string} params.taskId — the task that was evaluated
53
+ * @param {string} params.quality — "high" or "low"
54
+ * @param {Object} params.scores — { completeness, accuracy, workflowCompliance, tokenEfficiency, quality }
55
+ * @param {string} params.specSummary — brief spec description (first 500 chars)
56
+ * @param {string} params.diffSummary — brief diff description (file count, line count)
57
+ * @param {string} params.notes — judge's justification notes
58
+ */
59
+ function saveCalibrationExample(params) {
60
+ const { taskId, quality, scores, specSummary, diffSummary, notes } = params;
61
+
62
+ if (quality !== 'high' && quality !== 'low') {
63
+ throw new Error('Quality must be "high" or "low"');
64
+ }
65
+
66
+ const cal = loadCalibration();
67
+ const example = {
68
+ taskId,
69
+ scores,
70
+ specSummary: (specSummary || '').slice(0, 500),
71
+ diffSummary: (diffSummary || '').slice(0, 200),
72
+ notes: (notes || '').slice(0, 500),
73
+ savedAt: new Date().toISOString()
74
+ };
75
+
76
+ cal[quality].unshift(example);
77
+
78
+ // Keep only MAX_EXAMPLES_PER_QUALITY
79
+ if (cal[quality].length > MAX_EXAMPLES_PER_QUALITY) {
80
+ cal[quality] = cal[quality].slice(0, MAX_EXAMPLES_PER_QUALITY);
81
+ }
82
+
83
+ cal.lastUpdated = new Date().toISOString();
84
+ writeJson(CALIBRATION_PATH, cal);
85
+
86
+ return example;
87
+ }
88
+
89
+ /**
90
+ * Auto-classify and save an eval result as calibration.
91
+ * High = average score >= 8. Low = average score <= 4.
92
+ *
93
+ * @param {Object} evalResult — from flow-eval.js
94
+ * @returns {Object|null} saved example or null if score is in the middle range
95
+ */
96
+ function autoSaveFromEval(evalResult) {
97
+ if (!evalResult || !evalResult.scores) return null;
98
+
99
+ const scores = evalResult.scores;
100
+ const values = Object.values(scores).filter(v => typeof v === 'number');
101
+ if (values.length === 0) return null;
102
+
103
+ const avg = values.reduce((sum, v) => sum + v, 0) / values.length;
104
+
105
+ let quality = null;
106
+ if (avg >= 8) quality = 'high';
107
+ else if (avg <= 4) quality = 'low';
108
+ else return null; // Middle range — not a good calibration anchor
109
+
110
+ return saveCalibrationExample({
111
+ taskId: evalResult.taskId,
112
+ quality,
113
+ scores,
114
+ specSummary: evalResult.specSummary || '',
115
+ diffSummary: evalResult.diffSummary || '',
116
+ notes: evalResult.notes || ''
117
+ });
118
+ }
119
+
120
+ // ============================================================
121
+ // Retrieval (for prompt injection)
122
+ // ============================================================
123
+
124
+ /**
125
+ * Get calibration examples formatted for injection into judge/evaluator prompts.
126
+ * Returns 1 high + 1 low example (if available).
127
+ *
128
+ * @returns {string} formatted calibration text, or empty string if no examples
129
+ */
130
+ function getCalibrationPrompt() {
131
+ const cal = loadCalibration();
132
+ const parts = [];
133
+
134
+ if (cal.high.length > 0) {
135
+ const ex = cal.high[0];
136
+ parts.push(`## Calibration Example: HIGH QUALITY (reference)
137
+
138
+ **Task**: ${ex.taskId}
139
+ **Spec**: ${ex.specSummary}
140
+ **Scores**: completeness=${ex.scores.completeness}, accuracy=${ex.scores.accuracy}, workflowCompliance=${ex.scores.workflowCompliance}, tokenEfficiency=${ex.scores.tokenEfficiency}, quality=${ex.scores.quality}
141
+ **Why this scored high**: ${ex.notes}`);
142
+ }
143
+
144
+ if (cal.low.length > 0) {
145
+ const ex = cal.low[0];
146
+ parts.push(`## Calibration Example: LOW QUALITY (reference)
147
+
148
+ **Task**: ${ex.taskId}
149
+ **Spec**: ${ex.specSummary}
150
+ **Scores**: completeness=${ex.scores.completeness}, accuracy=${ex.scores.accuracy}, workflowCompliance=${ex.scores.workflowCompliance}, tokenEfficiency=${ex.scores.tokenEfficiency}, quality=${ex.scores.quality}
151
+ **Why this scored low**: ${ex.notes}`);
152
+ }
153
+
154
+ if (parts.length === 0) return '';
155
+
156
+ return `
157
+ ## Score Calibration (anchoring examples)
158
+
159
+ Use these real examples to calibrate your scoring. They represent the extremes of the scale — most tasks should score between these.
160
+
161
+ ${parts.join('\n\n')}
162
+
163
+ ---
164
+ `;
165
+ }
166
+
167
+ /**
168
+ * Get calibration examples as structured data
169
+ * @returns {{ high: Object|null, low: Object|null }}
170
+ */
171
+ function getCalibrationExamples() {
172
+ const cal = loadCalibration();
173
+ return {
174
+ high: cal.high[0] || null,
175
+ low: cal.low[0] || null
176
+ };
177
+ }
178
+
179
+ // ============================================================
180
+ // CLI
181
+ // ============================================================
182
+
183
+ function main() {
184
+ const args = process.argv.slice(2);
185
+ const command = args[0];
186
+
187
+ switch (command) {
188
+ case 'save': {
189
+ const taskId = args[1];
190
+ const quality = args[2];
191
+ if (!taskId || !quality) {
192
+ console.error('Usage: flow-eval-calibration.js save <taskId> <high|low>');
193
+ process.exit(1);
194
+ }
195
+ // Read scores from stdin or eval results
196
+ const evalsDir = path.join(PATHS.workflow, 'evals');
197
+ const evalFiles = fs.existsSync(evalsDir) ? fs.readdirSync(evalsDir).filter(f => f.includes(taskId)) : [];
198
+ if (evalFiles.length === 0) {
199
+ console.error(`No eval results found for task ${taskId}`);
200
+ process.exit(1);
201
+ }
202
+ const evalResult = safeJsonParse(path.join(evalsDir, evalFiles[0]), null);
203
+ if (evalResult) {
204
+ const saved = saveCalibrationExample({
205
+ taskId,
206
+ quality,
207
+ scores: evalResult.aggregated || evalResult.scores || {},
208
+ specSummary: evalResult.spec?.substring(0, 500) || '',
209
+ diffSummary: `${(evalResult.changedFiles || []).length} files changed`,
210
+ notes: evalResult.notes || evalResult.aggregated?.notes || ''
211
+ });
212
+ console.log(`Saved ${quality} calibration example: ${saved.taskId}`);
213
+ }
214
+ break;
215
+ }
216
+
217
+ case 'get':
218
+ console.log(getCalibrationPrompt() || 'No calibration examples yet.');
219
+ break;
220
+
221
+ case 'list': {
222
+ const cal = loadCalibration();
223
+ console.log(`High examples: ${cal.high.length}`);
224
+ for (const ex of cal.high) {
225
+ const values = Object.values(ex.scores).filter(v => typeof v === 'number');
226
+ const avg = values.length > 0 ? values.reduce((s, v) => s + v, 0) / values.length : 0;
227
+ console.log(` ${ex.taskId} — avg ${avg.toFixed(1)} (${ex.savedAt})`);
228
+ }
229
+ console.log(`Low examples: ${cal.low.length}`);
230
+ for (const ex of cal.low) {
231
+ const values = Object.values(ex.scores).filter(v => typeof v === 'number');
232
+ const avg = values.length > 0 ? values.reduce((s, v) => s + v, 0) / values.length : 0;
233
+ console.log(` ${ex.taskId} — avg ${avg.toFixed(1)} (${ex.savedAt})`);
234
+ }
235
+ break;
236
+ }
237
+
238
+ default:
239
+ console.log('Usage: flow-eval-calibration.js <save|get|list>');
240
+ }
241
+ }
242
+
243
+ // ============================================================
244
+ // Exports
245
+ // ============================================================
246
+
247
+ module.exports = {
248
+ loadCalibration,
249
+ saveCalibrationExample,
250
+ autoSaveFromEval,
251
+ getCalibrationPrompt,
252
+ getCalibrationExamples
253
+ };
254
+
255
+ if (require.main === module) {
256
+ main();
257
+ }
@@ -62,10 +62,19 @@ const DEFAULT_EVAL_CONFIG = {
62
62
  function buildJudgePrompt(params) {
63
63
  const { taskId, specContent, implementationDiff, iterations, tokenEstimate } = params;
64
64
 
65
+ // Inject calibration examples if available (prevents score drift)
66
+ let calibrationBlock = '';
67
+ try {
68
+ const { getCalibrationPrompt } = require('./flow-eval-calibration');
69
+ calibrationBlock = getCalibrationPrompt();
70
+ } catch (_err) {
71
+ // Calibration module not available — continue without it
72
+ }
73
+
65
74
  return `You are an expert code reviewer evaluating AI-generated implementation quality.
66
75
 
67
76
  ## Task: ${taskId}
68
-
77
+ ${calibrationBlock}
69
78
  ## Specification
70
79
  ${specContent}
71
80
 
@@ -35,7 +35,7 @@ const {
35
35
  // Constants
36
36
  // ============================================================
37
37
 
38
- const EVALS_DIR = path.join(PATHS.root, '.workflow', 'evals');
38
+ const EVALS_DIR = PATHS.evals;
39
39
 
40
40
  // ============================================================
41
41
  // Core Functions
@@ -171,13 +171,13 @@ function getTaskDiff(taskId, taskRecord) {
171
171
  function findSpecFile(taskId) {
172
172
  // Check common locations
173
173
  const candidates = [
174
- path.join(PATHS.root, '.workflow', 'specs', `${taskId}.md`),
175
- path.join(PATHS.root, '.workflow', 'changes', `${taskId}.md`)
174
+ path.join(PATHS.specs, `${taskId}.md`),
175
+ path.join(PATHS.changes, `${taskId}.md`)
176
176
  ];
177
177
 
178
178
  // Also search subdirectories of changes/
179
179
  try {
180
- const changesDir = path.join(PATHS.root, '.workflow', 'changes');
180
+ const changesDir = PATHS.changes;
181
181
  if (fs.existsSync(changesDir)) {
182
182
  const entries = fs.readdirSync(changesDir, { withFileTypes: true });
183
183
  for (const entry of entries) {
@@ -202,7 +202,7 @@ function findSpecFile(taskId) {
202
202
 
203
203
  // Check ready.json for specPath
204
204
  try {
205
- const ready = readJson(path.join(PATHS.state, 'ready.json'), {});
205
+ const ready = readJson(PATHS.ready, {});
206
206
  const allTasks = [
207
207
  ...(ready.inProgress || []),
208
208
  ...(ready.ready || []),
@@ -248,6 +248,15 @@ function saveEvalResult(evalResult) {
248
248
 
249
249
  try {
250
250
  writeJson(filePath, evalResult);
251
+
252
+ // Auto-save as calibration example if scores are extreme (high or low)
253
+ try {
254
+ const { autoSaveFromEval } = require('./flow-eval-calibration');
255
+ autoSaveFromEval(evalResult);
256
+ } catch (_err) {
257
+ // Calibration module not available — non-critical
258
+ }
259
+
251
260
  return filePath;
252
261
  } catch (err) {
253
262
  if (process.env.DEBUG) {
@@ -23,6 +23,7 @@ const REVIEW_FILE = path.join(TMP_DIR, 'review-session.json');
23
23
 
24
24
  // Colors
25
25
  const { colors: c } = require('./flow-output');
26
+ const { PATHS } = require('./flow-utils');
26
27
 
27
28
  // =============================================================================
28
29
  // REVIEW SESSION MANAGEMENT
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  * Wogi Flow - Centralized Failure Categories
5
3
  *
@@ -13,12 +13,10 @@
13
13
 
14
14
  const fs = require('node:fs');
15
15
  const path = require('node:path');
16
- const readline = require('node:readline');
17
- const { getProjectRoot, colors: c, readJson } = require('./flow-utils');
16
+ const readline = require('node:readline/promises');
17
+ const { getProjectRoot, colors: c, readJson, PATHS } = require('./flow-utils');
18
18
 
19
- const PROJECT_ROOT = getProjectRoot();
20
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
21
- const DECISIONS_PATH = path.join(WORKFLOW_DIR, 'state', 'figma-decisions.json');
19
+ const DECISIONS_PATH = path.join(PATHS.workflow, 'state', 'figma-decisions.json');
22
20
 
23
21
  const sym = {
24
22
  check: '✅',
@@ -252,9 +250,7 @@ Let's go through each component:
252
250
  }
253
251
 
254
252
  prompt(question) {
255
- return new Promise(resolve => {
256
- this.rl.question(question, resolve);
257
- });
253
+ return this.rl.question(question);
258
254
  }
259
255
 
260
256
  printSummary() {
@@ -295,7 +291,7 @@ ${c.bold}CONFIRMATION SUMMARY${c.reset}
295
291
  decisions: this.decisions
296
292
  }, null, 2));
297
293
 
298
- console.log(`${c.dim}Decisions saved to: ${path.relative(PROJECT_ROOT, DECISIONS_PATH)}${c.reset}`);
294
+ console.log(`${c.dim}Decisions saved to: ${path.relative(PATHS.root, DECISIONS_PATH)}${c.reset}`);
299
295
  }
300
296
  }
301
297
 
@@ -25,14 +25,12 @@ const { getProjectRoot,
25
25
  getConfig,
26
26
  addRequestLogEntry,
27
27
  addAppMapComponent,
28
- readJson
28
+ readJson, PATHS
29
29
  } = require('./flow-utils')
30
30
  const { error, info } = require('./flow-output');;
31
31
 
32
- const PROJECT_ROOT = getProjectRoot();
33
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
34
- const DECISIONS_PATH = path.join(WORKFLOW_DIR, 'state', 'figma-decisions.json');
35
- const REGISTRY_PATH = path.join(WORKFLOW_DIR, 'state', 'component-registry.json');
32
+ const DECISIONS_PATH = path.join(PATHS.workflow, 'state', 'figma-decisions.json');
33
+ const REGISTRY_PATH = path.join(PATHS.workflow, 'state', 'component-registry.json');
36
34
 
37
35
  // ============================================================
38
36
  // Framework-Specific Templates
@@ -231,7 +229,7 @@ export class {{name}}Component {
231
229
  class CodeGenerator {
232
230
  constructor(decisions, options = {}) {
233
231
  this.decisions = Array.isArray(decisions) ? decisions : decisions.decisions || [];
234
- this.framework = options.framework || detectFramework(PROJECT_ROOT);
232
+ this.framework = options.framework || detectFramework(PATHS.root);
235
233
  this.templates = FRAMEWORK_TEMPLATES[this.framework] || FRAMEWORK_TEMPLATES.react;
236
234
  this.registry = this.loadRegistry();
237
235
 
@@ -497,7 +495,7 @@ ${this.formatCSSPropertiesForPrompt(figma.css)}
497
495
 
498
496
  _detectSourceRoot() {
499
497
  for (const dir of ['src', 'app', 'lib']) {
500
- if (fs.existsSync(path.join(PROJECT_ROOT, dir))) return dir;
498
+ if (fs.existsSync(path.join(PATHS.root, dir))) return dir;
501
499
  }
502
500
  return '.';
503
501
  }
@@ -633,9 +631,9 @@ Framework: ${output.framework}
633
631
  }
634
632
 
635
633
  // Save output
636
- const outputPath = path.join(WORKFLOW_DIR, 'state', 'figma-output.json');
634
+ const outputPath = path.join(PATHS.workflow, 'state', 'figma-output.json');
637
635
  fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
638
- info(`� Full output saved to: ${path.relative(PROJECT_ROOT, outputPath)}`);
636
+ info(`� Full output saved to: ${path.relative(PATHS.root, outputPath)}`);
639
637
 
640
638
  // Print prompts for new components
641
639
  if (output.prompts.length > 0) {
@@ -668,7 +666,7 @@ ${'─'.repeat(70)}
668
666
  tags: ['#figma', ...componentNames.slice(0, 3).map(n => `#component:${n}`)],
669
667
  request: 'Figma design analysis and code generation',
670
668
  result: `Generated: ${summary.join(', ')}`,
671
- files: [path.relative(PROJECT_ROOT, outputPath)]
669
+ files: [path.relative(PATHS.root, outputPath)]
672
670
  });
673
671
 
674
672
  console.log('\n📝 Logged to request-log.md');
@@ -16,12 +16,10 @@
16
16
 
17
17
  const fs = require('node:fs');
18
18
  const path = require('node:path');
19
- const { getProjectRoot, readJson } = require('./flow-utils');
19
+ const { getProjectRoot, readJson, PATHS } = require('./flow-utils');
20
20
  const { success: printSuccess, error: printError, info: printInfo } = require('./flow-output');
21
21
 
22
- const PROJECT_ROOT = getProjectRoot();
23
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
24
- const REGISTRY_PATH = path.join(WORKFLOW_DIR, 'state', 'component-registry.json');
22
+ const REGISTRY_PATH = path.join(PATHS.workflow, 'state', 'component-registry.json');
25
23
 
26
24
  // ============================================================
27
25
  // Configuration
@@ -97,11 +95,11 @@ function detectFramework(projectRoot) {
97
95
  class ComponentScanner {
98
96
  constructor(config = {}) {
99
97
  this.config = { ...DEFAULT_CONFIG, ...config };
100
- this.framework = detectFramework(PROJECT_ROOT);
98
+ this.framework = detectFramework(PATHS.root);
101
99
  this.registry = {
102
100
  version: '1.0.0',
103
101
  scannedAt: null,
104
- projectRoot: PROJECT_ROOT,
102
+ projectRoot: PATHS.root,
105
103
  framework: this.framework,
106
104
  components: [],
107
105
  tokens: {
@@ -136,7 +134,7 @@ class ComponentScanner {
136
134
  return null;
137
135
  }
138
136
 
139
- console.log(` Component directory: ${path.relative(PROJECT_ROOT, componentDir)}`);
137
+ console.log(` Component directory: ${path.relative(PATHS.root, componentDir)}`);
140
138
  console.log(` Parser: ${this.parser ? 'Babel AST' : 'Regex-based'}`);
141
139
 
142
140
  // Scan for tokens first
@@ -154,14 +152,14 @@ class ComponentScanner {
154
152
  this.saveRegistry();
155
153
 
156
154
  printSuccess(`Found ${this.registry.components.length} components`);
157
- console.log(`📄 Registry saved to: ${path.relative(PROJECT_ROOT, REGISTRY_PATH)}`);
155
+ console.log(`📄 Registry saved to: ${path.relative(PATHS.root, REGISTRY_PATH)}`);
158
156
 
159
157
  return this.registry;
160
158
  }
161
159
 
162
160
  findComponentDir() {
163
161
  for (const dir of this.config.componentDirs) {
164
- const fullPath = path.join(PROJECT_ROOT, dir);
162
+ const fullPath = path.join(PATHS.root, dir);
165
163
  if (fs.existsSync(fullPath)) {
166
164
  return fullPath;
167
165
  }
@@ -173,7 +171,7 @@ class ComponentScanner {
173
171
  console.log('\n📊 Scanning design tokens...');
174
172
 
175
173
  for (const tokenSource of this.config.tokenSources) {
176
- const fullPath = path.join(PROJECT_ROOT, tokenSource);
174
+ const fullPath = path.join(PATHS.root, tokenSource);
177
175
  if (fs.existsSync(fullPath)) {
178
176
  console.log(` Found: ${tokenSource}`);
179
177
  await this.parseTokenFile(fullPath);
@@ -14,12 +14,10 @@
14
14
 
15
15
  const fs = require('node:fs');
16
16
  const path = require('node:path');
17
- const { getProjectRoot, safeJsonParse, safeJsonParseString } = require('./flow-utils')
17
+ const { getProjectRoot, safeJsonParse, safeJsonParseString, PATHS } = require('./flow-utils')
18
18
  const { error } = require('./flow-output');;
19
19
 
20
- const PROJECT_ROOT = getProjectRoot();
21
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
22
- const REGISTRY_PATH = path.join(WORKFLOW_DIR, 'state', 'component-registry.json');
20
+ const REGISTRY_PATH = path.join(PATHS.workflow, 'state', 'component-registry.json');
23
21
 
24
22
  // ============================================================
25
23
  // Matching Configuration
@@ -553,7 +551,7 @@ async function main() {
553
551
 
554
552
  if (figmaRegistryIndex !== -1) {
555
553
  // Use the Figma-sourced multi-page registry
556
- const figmaRegistryPath = path.join(WORKFLOW_DIR, 'state', 'figma-component-registry.json');
554
+ const figmaRegistryPath = path.join(PATHS.workflow, 'state', 'figma-component-registry.json');
557
555
  if (!fs.existsSync(figmaRegistryPath)) {
558
556
  error('Figma component registry not found.');
559
557
  console.error(' Run the multi-page scan first.');
@@ -31,11 +31,9 @@ const { ComponentScanner } = require('./flow-figma-index');
31
31
  const { FigmaExtractor } = require('./flow-figma-extract');
32
32
  const { SimilarityMatcher, MATCH_CONFIG } = require('./flow-figma-match');
33
33
  const { CodeGenerator } = require('./flow-figma-generate');
34
- const { getProjectRoot, readJson } = require('./flow-utils');
34
+ const { getProjectRoot, readJson, PATHS } = require('./flow-utils');
35
35
 
36
- const PROJECT_ROOT = getProjectRoot();
37
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
38
- const REGISTRY_PATH = path.join(WORKFLOW_DIR, 'state', 'component-registry.json');
36
+ const REGISTRY_PATH = path.join(PATHS.workflow, 'state', 'component-registry.json');
39
37
 
40
38
  // ============================================================
41
39
  // Tool Definitions
@@ -20,13 +20,12 @@
20
20
 
21
21
  const fs = require('node:fs');
22
22
  const path = require('node:path');
23
- const { getProjectRoot, writeJson, readJson } = require('./flow-utils');
23
+ const { getProjectRoot, writeJson, readJson, PATHS } = require('./flow-utils');
24
24
  const { FigmaExtractor } = require('./flow-figma-extract');
25
25
  const { FigmaComponentRegistry } = require('./flow-figma-registry');
26
26
  const { FigmaStateAnalyzer } = require('./flow-figma-state-analyzer');
27
27
 
28
- const PROJECT_ROOT = getProjectRoot();
29
- const ORCHESTRATOR_STATE_PATH = path.join(PROJECT_ROOT, '.workflow', 'state', 'figma-orchestrator-state.json');
28
+ const ORCHESTRATOR_STATE_PATH = path.join(PATHS.state, 'figma-orchestrator-state.json');
30
29
 
31
30
  // ============================================================
32
31
  // Orchestrator
@@ -15,11 +15,10 @@
15
15
 
16
16
  const fs = require('node:fs');
17
17
  const path = require('node:path');
18
- const { getProjectRoot, readJson, writeJson } = require('./flow-utils');
18
+ const { getProjectRoot, readJson, writeJson, PATHS } = require('./flow-utils');
19
19
  const { SimilarityMatcher, MATCH_CONFIG } = require('./flow-figma-match');
20
20
 
21
- const PROJECT_ROOT = getProjectRoot();
22
- const REGISTRY_PATH = path.join(PROJECT_ROOT, '.workflow', 'state', 'figma-component-registry.json');
21
+ const REGISTRY_PATH = path.join(PATHS.state, 'figma-component-registry.json');
23
22
 
24
23
  // ============================================================
25
24
  // Registry Data Structure
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  * flow-framework-resolver.js
5
3
  *
@@ -15,7 +15,7 @@
15
15
 
16
16
  const fs = require('node:fs');
17
17
  const path = require('node:path');
18
- const { getProjectRoot, getConfig, color, success, warn, error, safeJsonParse } = require('./flow-utils');
18
+ const { getProjectRoot, getConfig, color, success, warn, error, safeJsonParse, PATHS } = require('./flow-utils');
19
19
  const {
20
20
  findSimilarItems,
21
21
  generateAIDecisionPrompt,
@@ -24,10 +24,8 @@ const {
24
24
  } = require('./flow-semantic-match');
25
25
  const { BaseScanner, PROJECT_ROOT } = require('./flow-scanner-base');
26
26
 
27
- const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
28
- const STATE_DIR = path.join(WORKFLOW_DIR, 'state');
29
- const INDEX_PATH = path.join(STATE_DIR, 'function-index.json');
30
- const MAP_PATH = path.join(STATE_DIR, 'function-map.md');
27
+ const INDEX_PATH = path.join(PATHS.state, 'function-index.json');
28
+ const MAP_PATH = path.join(PATHS.state, 'function-map.md');
31
29
 
32
30
  // ============================================================
33
31
  // Configuration
@@ -344,7 +342,7 @@ class FunctionScanner extends BaseScanner {
344
342
  */
345
343
  save() {
346
344
  this.prune();
347
- fs.mkdirSync(STATE_DIR, { recursive: true });
345
+ fs.mkdirSync(PATHS.state, { recursive: true });
348
346
  fs.writeFileSync(INDEX_PATH, JSON.stringify(this.registry, null, 2));
349
347
  success(`Saved to ${path.relative(PROJECT_ROOT, INDEX_PATH)}`);
350
348
  }
@@ -36,7 +36,7 @@ const {
36
36
  outputJson,
37
37
  printHeader,
38
38
  printSection,
39
- safeJsonParse
39
+ safeJsonParse, PATHS
40
40
  } = require('./flow-utils');
41
41
 
42
42
  // ============================================================
@@ -178,7 +178,7 @@ const DEFAULT_GATE_CONFIG = {
178
178
  // State
179
179
  // ============================================================
180
180
 
181
- const STATE_PATH = path.join(PROJECT_ROOT, '.workflow', 'state', 'gate-confidence.json');
181
+ const STATE_PATH = path.join(PATHS.state, 'gate-confidence.json');
182
182
 
183
183
  /**
184
184
  * Get default confidence state.
@@ -14,8 +14,6 @@
14
14
  * - Declarative: RUNTIME_ARTIFACT_MAP defines all mappings
15
15
  */
16
16
 
17
- 'use strict';
18
-
19
17
  const fs = require('node:fs');
20
18
  const path = require('node:path');
21
19
  const { getConfig } = require('./flow-config-loader');