wogiflow 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 (221) hide show
  1. package/.workflow/agents/reviewer.md +81 -0
  2. package/.workflow/agents/security.md +94 -0
  3. package/.workflow/agents/story-writer.md +58 -0
  4. package/.workflow/bridges/base-bridge.js +395 -0
  5. package/.workflow/bridges/claude-bridge.js +434 -0
  6. package/.workflow/bridges/index.js +130 -0
  7. package/.workflow/lib/assumption-detector.js +481 -0
  8. package/.workflow/lib/config-substitution.js +371 -0
  9. package/.workflow/lib/failure-categories.js +478 -0
  10. package/.workflow/state/app-map.md.template +15 -0
  11. package/.workflow/state/architecture.md.template +24 -0
  12. package/.workflow/state/component-index.json.template +5 -0
  13. package/.workflow/state/decisions.md.template +15 -0
  14. package/.workflow/state/feedback-patterns.md.template +9 -0
  15. package/.workflow/state/knowledge-sync.json.template +6 -0
  16. package/.workflow/state/progress.md.template +14 -0
  17. package/.workflow/state/ready.json.template +7 -0
  18. package/.workflow/state/request-log.md.template +14 -0
  19. package/.workflow/state/session-state.json.template +11 -0
  20. package/.workflow/state/stack.md.template +33 -0
  21. package/.workflow/state/testing.md.template +36 -0
  22. package/.workflow/templates/claude-md.hbs +257 -0
  23. package/.workflow/templates/correction-report.md +67 -0
  24. package/.workflow/templates/gemini-md.hbs +52 -0
  25. package/README.md +1802 -0
  26. package/bin/flow +205 -0
  27. package/lib/index.js +33 -0
  28. package/lib/installer.js +467 -0
  29. package/lib/release-channel.js +269 -0
  30. package/lib/skill-registry.js +526 -0
  31. package/lib/upgrader.js +401 -0
  32. package/lib/utils.js +305 -0
  33. package/package.json +64 -0
  34. package/scripts/flow +985 -0
  35. package/scripts/flow-adaptive-learning.js +1259 -0
  36. package/scripts/flow-aggregate.js +488 -0
  37. package/scripts/flow-archive +133 -0
  38. package/scripts/flow-auto-context.js +1015 -0
  39. package/scripts/flow-auto-learn.js +615 -0
  40. package/scripts/flow-bridge.js +223 -0
  41. package/scripts/flow-browser-suggest.js +316 -0
  42. package/scripts/flow-bug.js +247 -0
  43. package/scripts/flow-cascade.js +711 -0
  44. package/scripts/flow-changelog +85 -0
  45. package/scripts/flow-checkpoint.js +483 -0
  46. package/scripts/flow-cli.js +403 -0
  47. package/scripts/flow-code-intelligence.js +760 -0
  48. package/scripts/flow-complexity.js +502 -0
  49. package/scripts/flow-config-set.js +152 -0
  50. package/scripts/flow-constants.js +157 -0
  51. package/scripts/flow-context +152 -0
  52. package/scripts/flow-context-init.js +482 -0
  53. package/scripts/flow-context-monitor.js +384 -0
  54. package/scripts/flow-context-scoring.js +886 -0
  55. package/scripts/flow-correct.js +458 -0
  56. package/scripts/flow-damage-control.js +985 -0
  57. package/scripts/flow-deps +101 -0
  58. package/scripts/flow-diff.js +700 -0
  59. package/scripts/flow-done +151 -0
  60. package/scripts/flow-done.js +489 -0
  61. package/scripts/flow-durable-session.js +1541 -0
  62. package/scripts/flow-entropy-monitor.js +345 -0
  63. package/scripts/flow-export-profile +349 -0
  64. package/scripts/flow-export-scanner.js +1046 -0
  65. package/scripts/flow-figma-confirm.js +400 -0
  66. package/scripts/flow-figma-extract.js +496 -0
  67. package/scripts/flow-figma-generate.js +683 -0
  68. package/scripts/flow-figma-index.js +909 -0
  69. package/scripts/flow-figma-match.js +617 -0
  70. package/scripts/flow-figma-mcp-server.js +518 -0
  71. package/scripts/flow-figma-pipeline.js +414 -0
  72. package/scripts/flow-file-ops.js +301 -0
  73. package/scripts/flow-gate-confidence.js +825 -0
  74. package/scripts/flow-guided-edit.js +659 -0
  75. package/scripts/flow-health +185 -0
  76. package/scripts/flow-health.js +413 -0
  77. package/scripts/flow-hooks.js +556 -0
  78. package/scripts/flow-http-client.js +249 -0
  79. package/scripts/flow-hybrid-detect.js +167 -0
  80. package/scripts/flow-hybrid-interactive.js +591 -0
  81. package/scripts/flow-hybrid-test.js +152 -0
  82. package/scripts/flow-import-profile +439 -0
  83. package/scripts/flow-init +253 -0
  84. package/scripts/flow-instruction-richness.js +827 -0
  85. package/scripts/flow-jira-integration.js +579 -0
  86. package/scripts/flow-knowledge-router.js +522 -0
  87. package/scripts/flow-knowledge-sync.js +589 -0
  88. package/scripts/flow-linear-integration.js +631 -0
  89. package/scripts/flow-links.js +774 -0
  90. package/scripts/flow-log-manager.js +559 -0
  91. package/scripts/flow-loop-enforcer.js +1246 -0
  92. package/scripts/flow-loop-retry-learning.js +630 -0
  93. package/scripts/flow-lsp.js +923 -0
  94. package/scripts/flow-map-index +348 -0
  95. package/scripts/flow-map-sync +201 -0
  96. package/scripts/flow-memory-blocks.js +668 -0
  97. package/scripts/flow-memory-compactor.js +350 -0
  98. package/scripts/flow-memory-db.js +1110 -0
  99. package/scripts/flow-memory-sync.js +484 -0
  100. package/scripts/flow-metrics.js +353 -0
  101. package/scripts/flow-migrate-ids.js +370 -0
  102. package/scripts/flow-model-adapter.js +802 -0
  103. package/scripts/flow-model-router.js +884 -0
  104. package/scripts/flow-models.js +1231 -0
  105. package/scripts/flow-morning.js +517 -0
  106. package/scripts/flow-multi-approach.js +660 -0
  107. package/scripts/flow-new-feature +86 -0
  108. package/scripts/flow-onboard +1042 -0
  109. package/scripts/flow-orchestrate-llm.js +459 -0
  110. package/scripts/flow-orchestrate.js +3592 -0
  111. package/scripts/flow-output.js +123 -0
  112. package/scripts/flow-parallel-detector.js +399 -0
  113. package/scripts/flow-parallel-dispatch.js +987 -0
  114. package/scripts/flow-parallel.js +428 -0
  115. package/scripts/flow-pattern-enforcer.js +600 -0
  116. package/scripts/flow-prd-manager.js +282 -0
  117. package/scripts/flow-progress.js +323 -0
  118. package/scripts/flow-project-analyzer.js +975 -0
  119. package/scripts/flow-prompt-composer.js +487 -0
  120. package/scripts/flow-providers.js +1381 -0
  121. package/scripts/flow-queue.js +308 -0
  122. package/scripts/flow-ready +82 -0
  123. package/scripts/flow-ready.js +189 -0
  124. package/scripts/flow-regression.js +396 -0
  125. package/scripts/flow-response-parser.js +450 -0
  126. package/scripts/flow-resume.js +284 -0
  127. package/scripts/flow-rules-sync.js +439 -0
  128. package/scripts/flow-run-trace.js +718 -0
  129. package/scripts/flow-safety.js +587 -0
  130. package/scripts/flow-search +104 -0
  131. package/scripts/flow-security.js +481 -0
  132. package/scripts/flow-session-end +106 -0
  133. package/scripts/flow-session-end.js +437 -0
  134. package/scripts/flow-session-state.js +671 -0
  135. package/scripts/flow-setup-hooks +216 -0
  136. package/scripts/flow-setup-hooks.js +377 -0
  137. package/scripts/flow-skill-create.js +329 -0
  138. package/scripts/flow-skill-creator.js +572 -0
  139. package/scripts/flow-skill-generator.js +1046 -0
  140. package/scripts/flow-skill-learn.js +880 -0
  141. package/scripts/flow-skill-matcher.js +578 -0
  142. package/scripts/flow-spec-generator.js +820 -0
  143. package/scripts/flow-stack-wizard.js +895 -0
  144. package/scripts/flow-standup +162 -0
  145. package/scripts/flow-start +74 -0
  146. package/scripts/flow-start.js +235 -0
  147. package/scripts/flow-status +110 -0
  148. package/scripts/flow-status.js +301 -0
  149. package/scripts/flow-step-browser.js +83 -0
  150. package/scripts/flow-step-changelog.js +217 -0
  151. package/scripts/flow-step-comments.js +306 -0
  152. package/scripts/flow-step-complexity.js +234 -0
  153. package/scripts/flow-step-coverage.js +218 -0
  154. package/scripts/flow-step-knowledge.js +193 -0
  155. package/scripts/flow-step-pr-tests.js +364 -0
  156. package/scripts/flow-step-regression.js +89 -0
  157. package/scripts/flow-step-review.js +516 -0
  158. package/scripts/flow-step-security.js +162 -0
  159. package/scripts/flow-step-silent-failures.js +290 -0
  160. package/scripts/flow-step-simplifier.js +346 -0
  161. package/scripts/flow-story +105 -0
  162. package/scripts/flow-story.js +500 -0
  163. package/scripts/flow-suspend.js +252 -0
  164. package/scripts/flow-sync-daemon.js +654 -0
  165. package/scripts/flow-task-analyzer.js +606 -0
  166. package/scripts/flow-team-dashboard.js +748 -0
  167. package/scripts/flow-team-sync.js +752 -0
  168. package/scripts/flow-team.js +977 -0
  169. package/scripts/flow-tech-options.js +528 -0
  170. package/scripts/flow-templates.js +812 -0
  171. package/scripts/flow-tiered-learning.js +728 -0
  172. package/scripts/flow-trace +204 -0
  173. package/scripts/flow-transcript-chunking.js +1106 -0
  174. package/scripts/flow-transcript-digest.js +7918 -0
  175. package/scripts/flow-transcript-language.js +465 -0
  176. package/scripts/flow-transcript-parsing.js +1085 -0
  177. package/scripts/flow-transcript-stories.js +2194 -0
  178. package/scripts/flow-update-map +224 -0
  179. package/scripts/flow-utils.js +2242 -0
  180. package/scripts/flow-verification.js +644 -0
  181. package/scripts/flow-verify.js +1177 -0
  182. package/scripts/flow-voice-input.js +638 -0
  183. package/scripts/flow-watch +168 -0
  184. package/scripts/flow-workflow-steps.js +521 -0
  185. package/scripts/flow-workflow.js +1029 -0
  186. package/scripts/flow-worktree.js +489 -0
  187. package/scripts/hooks/adapters/base-adapter.js +102 -0
  188. package/scripts/hooks/adapters/claude-code.js +359 -0
  189. package/scripts/hooks/adapters/index.js +79 -0
  190. package/scripts/hooks/core/component-check.js +341 -0
  191. package/scripts/hooks/core/index.js +35 -0
  192. package/scripts/hooks/core/loop-check.js +241 -0
  193. package/scripts/hooks/core/session-context.js +294 -0
  194. package/scripts/hooks/core/task-gate.js +177 -0
  195. package/scripts/hooks/core/validation.js +230 -0
  196. package/scripts/hooks/entry/claude-code/post-tool-use.js +65 -0
  197. package/scripts/hooks/entry/claude-code/pre-tool-use.js +89 -0
  198. package/scripts/hooks/entry/claude-code/session-end.js +87 -0
  199. package/scripts/hooks/entry/claude-code/session-start.js +46 -0
  200. package/scripts/hooks/entry/claude-code/stop.js +43 -0
  201. package/scripts/postinstall.js +139 -0
  202. package/templates/browser-test-flow.json +56 -0
  203. package/templates/bug-report.md +43 -0
  204. package/templates/component-detail.md +42 -0
  205. package/templates/component.stories.tsx +49 -0
  206. package/templates/context/constraints.md +83 -0
  207. package/templates/context/conventions.md +177 -0
  208. package/templates/context/stack.md +60 -0
  209. package/templates/correction-report.md +90 -0
  210. package/templates/feature-proposal.md +35 -0
  211. package/templates/hybrid/_base.md +254 -0
  212. package/templates/hybrid/_patterns.md +45 -0
  213. package/templates/hybrid/create-component.md +127 -0
  214. package/templates/hybrid/create-file.md +56 -0
  215. package/templates/hybrid/create-hook.md +145 -0
  216. package/templates/hybrid/create-service.md +70 -0
  217. package/templates/hybrid/fix-bug.md +33 -0
  218. package/templates/hybrid/modify-file.md +55 -0
  219. package/templates/story.md +68 -0
  220. package/templates/task.json +56 -0
  221. package/templates/trace.md +69 -0
@@ -0,0 +1,185 @@
1
+ #!/bin/bash
2
+
3
+ # Wogi Flow - Health Check
4
+ # Verifies workflow files are in sync and properly configured
5
+
6
+ set -e
7
+
8
+ WORKFLOW_DIR=".workflow"
9
+
10
+ # Colors
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ CYAN='\033[0;36m'
15
+ NC='\033[0m'
16
+
17
+ echo -e "${CYAN}Wogi Flow Health Check${NC}"
18
+ echo "========================"
19
+ echo ""
20
+
21
+ issues=0
22
+ warnings=0
23
+
24
+ # Check required files exist
25
+ echo -e "${CYAN}Checking required files...${NC}"
26
+
27
+ required_files=(
28
+ "$WORKFLOW_DIR/config.json"
29
+ "$WORKFLOW_DIR/state/ready.json"
30
+ "$WORKFLOW_DIR/state/request-log.md"
31
+ "$WORKFLOW_DIR/state/app-map.md"
32
+ "$WORKFLOW_DIR/state/decisions.md"
33
+ "$WORKFLOW_DIR/state/progress.md"
34
+ "CLAUDE.md"
35
+ )
36
+
37
+ for file in "${required_files[@]}"; do
38
+ if [ -f "$file" ]; then
39
+ echo -e " ${GREEN}✓${NC} $file"
40
+ else
41
+ echo -e " ${RED}✗${NC} $file - MISSING"
42
+ issues=$((issues + 1))
43
+ fi
44
+ done
45
+
46
+ # Check required directories
47
+ echo ""
48
+ echo -e "${CYAN}Checking directories...${NC}"
49
+
50
+ required_dirs=(
51
+ "$WORKFLOW_DIR/state/components"
52
+ "$WORKFLOW_DIR/specs"
53
+ "$WORKFLOW_DIR/changes"
54
+ "$WORKFLOW_DIR/bugs"
55
+ "$WORKFLOW_DIR/archive"
56
+ "agents"
57
+ "scripts"
58
+ )
59
+
60
+ for dir in "${required_dirs[@]}"; do
61
+ if [ -d "$dir" ]; then
62
+ echo -e " ${GREEN}✓${NC} $dir/"
63
+ else
64
+ echo -e " ${RED}✗${NC} $dir/ - MISSING"
65
+ issues=$((issues + 1))
66
+ fi
67
+ done
68
+
69
+ # Check config.json is valid JSON
70
+ echo ""
71
+ echo -e "${CYAN}Validating config.json...${NC}"
72
+
73
+ if [ -f "$WORKFLOW_DIR/config.json" ]; then
74
+ if python3 -c "import json, sys; json.load(open(sys.argv[1]))" "$WORKFLOW_DIR/config.json" 2>/dev/null; then
75
+ echo -e " ${GREEN}✓${NC} Valid JSON"
76
+ else
77
+ echo -e " ${RED}✗${NC} Invalid JSON syntax"
78
+ issues=$((issues + 1))
79
+ fi
80
+ fi
81
+
82
+ # Check ready.json is valid JSON
83
+ echo ""
84
+ echo -e "${CYAN}Validating ready.json...${NC}"
85
+
86
+ if [ -f "$WORKFLOW_DIR/state/ready.json" ]; then
87
+ if python3 -c "import json, sys; json.load(open(sys.argv[1]))" "$WORKFLOW_DIR/state/ready.json" 2>/dev/null; then
88
+ echo -e " ${GREEN}✓${NC} Valid JSON"
89
+ else
90
+ echo -e " ${RED}✗${NC} Invalid JSON syntax"
91
+ issues=$((issues + 1))
92
+ fi
93
+ fi
94
+
95
+ # Check app-map vs actual components
96
+ echo ""
97
+ echo -e "${CYAN}Checking app-map sync...${NC}"
98
+
99
+ if [ -d "src/components" ]; then
100
+ component_count=$(find src/components -name "*.tsx" -o -name "*.jsx" 2>/dev/null | wc -l)
101
+ mapped_count=$(grep -c "^|" "$WORKFLOW_DIR/state/app-map.md" 2>/dev/null || echo 0)
102
+ mapped_count=$((mapped_count - 3)) # Subtract header rows
103
+
104
+ if [ $mapped_count -lt 0 ]; then mapped_count=0; fi
105
+
106
+ echo -e " Components in src/: $component_count"
107
+ echo -e " Components in app-map: $mapped_count"
108
+
109
+ if [ $component_count -gt $((mapped_count + 5)) ]; then
110
+ echo -e " ${YELLOW}⚠${NC} App-map may be out of sync"
111
+ echo -e " Run: ./scripts/flow update-map scan src/components"
112
+ warnings=$((warnings + 1))
113
+ else
114
+ echo -e " ${GREEN}✓${NC} App-map appears in sync"
115
+ fi
116
+ else
117
+ echo -e " ${YELLOW}⚠${NC} src/components/ not found (may be OK for new projects)"
118
+ fi
119
+
120
+ # Check git status
121
+ echo ""
122
+ echo -e "${CYAN}Checking git status...${NC}"
123
+
124
+ if [ -d ".git" ]; then
125
+ uncommitted=$(git status --porcelain 2>/dev/null | wc -l)
126
+ if [ $uncommitted -eq 0 ]; then
127
+ echo -e " ${GREEN}✓${NC} Working directory clean"
128
+ else
129
+ echo -e " ${YELLOW}⚠${NC} $uncommitted uncommitted changes"
130
+ warnings=$((warnings + 1))
131
+ fi
132
+ else
133
+ echo -e " ${YELLOW}⚠${NC} Not a git repository"
134
+ warnings=$((warnings + 1))
135
+ fi
136
+
137
+ # Check request-log recent activity
138
+ echo ""
139
+ echo -e "${CYAN}Checking request-log...${NC}"
140
+
141
+ if [ -f "$WORKFLOW_DIR/state/request-log.md" ]; then
142
+ entry_count=$(grep -c "^### R-" "$WORKFLOW_DIR/state/request-log.md" 2>/dev/null || echo 0)
143
+ echo -e " Total entries: $entry_count"
144
+
145
+ if [ $entry_count -gt 0 ]; then
146
+ last_entry=$(grep "^### R-" "$WORKFLOW_DIR/state/request-log.md" | tail -1)
147
+ echo -e " Last entry: $last_entry"
148
+ fi
149
+ fi
150
+
151
+ # Check agents exist
152
+ echo ""
153
+ echo -e "${CYAN}Checking agents...${NC}"
154
+
155
+ core_agents=("orchestrator" "developer" "reviewer" "tester")
156
+ optional_agents=("accessibility" "security" "performance" "docs" "design-system" "onboarding")
157
+
158
+ for agent in "${core_agents[@]}"; do
159
+ if [ -f "agents/$agent.md" ]; then
160
+ echo -e " ${GREEN}✓${NC} $agent.md"
161
+ else
162
+ echo -e " ${RED}✗${NC} $agent.md - MISSING (core agent)"
163
+ issues=$((issues + 1))
164
+ fi
165
+ done
166
+
167
+ for agent in "${optional_agents[@]}"; do
168
+ if [ -f "agents/$agent.md" ]; then
169
+ echo -e " ${GREEN}✓${NC} $agent.md (optional)"
170
+ fi
171
+ done
172
+
173
+ # Summary
174
+ echo ""
175
+ echo "========================"
176
+
177
+ if [ $issues -eq 0 ] && [ $warnings -eq 0 ]; then
178
+ echo -e "${GREEN}✓ Workflow is healthy!${NC}"
179
+ elif [ $issues -eq 0 ]; then
180
+ echo -e "${YELLOW}⚠ $warnings warning(s), but no critical issues${NC}"
181
+ else
182
+ echo -e "${RED}✗ $issues issue(s), $warnings warning(s)${NC}"
183
+ echo ""
184
+ echo "Run './scripts/flow init' to fix missing files"
185
+ fi
@@ -0,0 +1,413 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Health Check
5
+ *
6
+ * Verifies workflow files are in sync and properly configured.
7
+ */
8
+
9
+ const path = require('path');
10
+ const {
11
+ PATHS,
12
+ PROJECT_ROOT,
13
+ fileExists,
14
+ dirExists,
15
+ validateJson,
16
+ countAppMapComponents,
17
+ countRequestLogEntries,
18
+ getLastRequestLogEntry,
19
+ getGitStatus,
20
+ countFiles,
21
+ color,
22
+ printSection,
23
+ success,
24
+ warn,
25
+ error,
26
+ validatePermissions
27
+ } = require('./flow-utils');
28
+
29
+ function main() {
30
+ console.log(color('cyan', 'Wogi Flow Health Check'));
31
+ console.log('========================');
32
+ console.log('');
33
+
34
+ let issues = 0;
35
+ let warnings = 0;
36
+
37
+ // Check required files
38
+ printSection('Checking required files...');
39
+
40
+ const requiredFiles = [
41
+ { path: PATHS.config, name: '.workflow/config.json' },
42
+ { path: PATHS.ready, name: '.workflow/state/ready.json' },
43
+ { path: PATHS.requestLog, name: '.workflow/state/request-log.md' },
44
+ { path: PATHS.appMap, name: '.workflow/state/app-map.md' },
45
+ { path: PATHS.decisions, name: '.workflow/state/decisions.md' },
46
+ { path: PATHS.progress, name: '.workflow/state/progress.md' },
47
+ ];
48
+
49
+ for (const file of requiredFiles) {
50
+ if (fileExists(file.path)) {
51
+ console.log(` ${color('green', '✓')} ${file.name}`);
52
+ } else {
53
+ console.log(` ${color('red', '✗')} ${file.name} - MISSING`);
54
+ issues++;
55
+ }
56
+ }
57
+
58
+ // Check CLI-specific rules file
59
+ let cliType = 'claude-code'; // default
60
+ if (fileExists(PATHS.config)) {
61
+ try {
62
+ const config = require(PATHS.config);
63
+ cliType = config.cli?.type || 'claude-code';
64
+ } catch {}
65
+ }
66
+
67
+ const rulesFiles = {
68
+ 'claude-code': { path: path.join(PROJECT_ROOT, 'CLAUDE.md'), name: 'CLAUDE.md' },
69
+ 'gemini-cli': { path: path.join(PROJECT_ROOT, 'GEMINI.md'), name: 'GEMINI.md' },
70
+ 'opencode': { path: path.join(PROJECT_ROOT, '.opencode', 'config.json'), name: '.opencode/config.json' }
71
+ };
72
+
73
+ const rulesFile = rulesFiles[cliType] || rulesFiles['claude-code'];
74
+ if (fileExists(rulesFile.path)) {
75
+ console.log(` ${color('green', '✓')} ${rulesFile.name} (${cliType})`);
76
+ } else {
77
+ console.log(` ${color('red', '✗')} ${rulesFile.name} - MISSING (${cliType})`);
78
+ issues++;
79
+ }
80
+
81
+ // Check required directories
82
+ console.log('');
83
+ printSection('Checking directories...');
84
+
85
+ const requiredDirs = [
86
+ { path: PATHS.components, name: '.workflow/state/components' },
87
+ { path: PATHS.specs, name: '.workflow/specs' },
88
+ { path: PATHS.changes, name: '.workflow/changes' },
89
+ { path: PATHS.bugs, name: '.workflow/bugs' },
90
+ { path: PATHS.archive, name: '.workflow/archive' },
91
+ { path: path.join(PROJECT_ROOT, 'agents'), name: 'agents' },
92
+ { path: path.join(PROJECT_ROOT, 'scripts'), name: 'scripts' },
93
+ ];
94
+
95
+ for (const dir of requiredDirs) {
96
+ if (dirExists(dir.path)) {
97
+ console.log(` ${color('green', '✓')} ${dir.name}/`);
98
+ } else {
99
+ console.log(` ${color('red', '✗')} ${dir.name}/ - MISSING`);
100
+ issues++;
101
+ }
102
+ }
103
+
104
+ // Check universal structure directories (optional but recommended)
105
+ console.log('');
106
+ printSection('Checking universal structure...');
107
+
108
+ const universalDirs = [
109
+ { path: path.join(PROJECT_ROOT, '.workflow', 'models'), name: '.workflow/models' },
110
+ { path: path.join(PROJECT_ROOT, '.workflow', 'bridges'), name: '.workflow/bridges' },
111
+ { path: path.join(PROJECT_ROOT, '.workflow', 'templates'), name: '.workflow/templates' },
112
+ ];
113
+
114
+ for (const dir of universalDirs) {
115
+ if (dirExists(dir.path)) {
116
+ console.log(` ${color('green', '✓')} ${dir.name}/`);
117
+ } else {
118
+ console.log(` ${color('yellow', '○')} ${dir.name}/ - not found (run 'flow migrate' to add)`);
119
+ warnings++;
120
+ }
121
+ }
122
+
123
+ // Check model registry
124
+ const registryPath = path.join(PROJECT_ROOT, '.workflow', 'models', 'registry.json');
125
+ if (fileExists(registryPath)) {
126
+ const result = validateJson(registryPath);
127
+ if (result.valid) {
128
+ console.log(` ${color('green', '✓')} Model registry valid`);
129
+ } else {
130
+ console.log(` ${color('red', '✗')} Model registry invalid JSON`);
131
+ issues++;
132
+ }
133
+ }
134
+
135
+ // Check knowledge files (optional - generated by onboard)
136
+ console.log('');
137
+ printSection('Checking knowledge files...');
138
+
139
+ // Use paths from PATHS constant (defined in flow-utils.js)
140
+ const knowledgeFiles = [
141
+ { path: PATHS.stackMd, name: 'stack.md', category: 'stack' },
142
+ { path: PATHS.architectureMd, name: 'architecture.md', category: 'architecture' },
143
+ { path: PATHS.testingMd, name: 'testing.md', category: 'testing' },
144
+ ];
145
+
146
+ // Try to load drift detection
147
+ let driftStatus = null;
148
+ try {
149
+ const { checkAllDrift } = require('./flow-knowledge-sync');
150
+ driftStatus = checkAllDrift();
151
+ } catch {
152
+ // Knowledge sync not available
153
+ }
154
+
155
+ for (const file of knowledgeFiles) {
156
+ if (fileExists(file.path)) {
157
+ // Check sync status if available
158
+ const categoryStatus = driftStatus?.categories?.[file.category];
159
+ if (categoryStatus?.status === 'drifted') {
160
+ console.log(` ${color('yellow', '⚠')} ${file.name} - out of sync (${categoryStatus.reason})`);
161
+ warnings++;
162
+ } else {
163
+ console.log(` ${color('green', '✓')} ${file.name}`);
164
+ }
165
+ } else {
166
+ console.log(` ${color('yellow', '○')} ${file.name} - not found (run 'flow onboard' to generate)`);
167
+ warnings++;
168
+ }
169
+ }
170
+
171
+ // Show sync recommendation if drift detected
172
+ if (driftStatus?.anyDrift) {
173
+ console.log('');
174
+ console.log(` ${color('dim', "Run 'flow knowledge-sync regenerate' to update")}`);
175
+ }
176
+
177
+ // Validate config.json
178
+ console.log('');
179
+ printSection('Validating config.json...');
180
+
181
+ if (fileExists(PATHS.config)) {
182
+ const result = validateJson(PATHS.config);
183
+ if (result.valid) {
184
+ console.log(` ${color('green', '✓')} Valid JSON`);
185
+ } else {
186
+ console.log(` ${color('red', '✗')} Invalid JSON syntax`);
187
+ issues++;
188
+ }
189
+ }
190
+
191
+ // Validate ready.json
192
+ console.log('');
193
+ printSection('Validating ready.json...');
194
+
195
+ if (fileExists(PATHS.ready)) {
196
+ const result = validateJson(PATHS.ready);
197
+ if (result.valid) {
198
+ console.log(` ${color('green', '✓')} Valid JSON`);
199
+ } else {
200
+ console.log(` ${color('red', '✗')} Invalid JSON syntax`);
201
+ issues++;
202
+ }
203
+ }
204
+
205
+ // Check enforcement settings
206
+ console.log('');
207
+ printSection('Checking enforcement...');
208
+
209
+ const claudeMdPath = path.join(PROJECT_ROOT, 'CLAUDE.md');
210
+ if (fileExists(claudeMdPath)) {
211
+ const fs = require('fs');
212
+ const claudeMdContent = fs.readFileSync(claudeMdPath, 'utf-8');
213
+ const claudeMdSize = fs.statSync(claudeMdPath).size;
214
+ const sizeKb = Math.round(claudeMdSize / 1024);
215
+
216
+ // Check CLAUDE.md size (should be under 20KB for reliable loading)
217
+ if (sizeKb <= 20) {
218
+ console.log(` ${color('green', '✓')} CLAUDE.md size: ${sizeKb}KB (under 20KB limit)`);
219
+ } else {
220
+ console.log(` ${color('yellow', '⚠')} CLAUDE.md size: ${sizeKb}KB (over 20KB - may get truncated)`);
221
+ warnings++;
222
+ }
223
+
224
+ // Check if enforcement section is at top (within first 100 lines)
225
+ const lines = claudeMdContent.split('\n').slice(0, 100);
226
+ const hasEnforcementAtTop = lines.some(line =>
227
+ line.includes('MANDATORY') && line.includes('Task Gating')
228
+ );
229
+
230
+ if (hasEnforcementAtTop) {
231
+ console.log(` ${color('green', '✓')} Enforcement section: FOUND at top of CLAUDE.md`);
232
+ } else {
233
+ console.log(` ${color('yellow', '⚠')} Enforcement section not found at top of CLAUDE.md`);
234
+ warnings++;
235
+ }
236
+ }
237
+
238
+ // Check strict mode in config
239
+ if (fileExists(PATHS.config)) {
240
+ const configResult = validateJson(PATHS.config);
241
+ if (configResult.valid) {
242
+ try {
243
+ const config = JSON.parse(require('fs').readFileSync(PATHS.config, 'utf-8'));
244
+ if (config.enforcement?.strictMode === true) {
245
+ console.log(` ${color('green', '✓')} Strict mode: ENABLED`);
246
+ } else if (config.enforcement?.strictMode === false) {
247
+ console.log(` ${color('yellow', '⚠')} Strict mode: DISABLED (Claude may skip task creation)`);
248
+ warnings++;
249
+ } else {
250
+ console.log(` ${color('yellow', '⚠')} Strict mode: NOT CONFIGURED (add enforcement section to config.json)`);
251
+ warnings++;
252
+ }
253
+ } catch (err) {
254
+ console.log(` ${color('yellow', '⚠')} Could not parse config.json for strict mode check`);
255
+ warnings++;
256
+ }
257
+ }
258
+ }
259
+
260
+ // Check app-map sync
261
+ console.log('');
262
+ printSection('Checking app-map sync...');
263
+
264
+ const srcComponents = path.join(PROJECT_ROOT, 'src', 'components');
265
+ if (dirExists(srcComponents)) {
266
+ const componentCount = countFiles(srcComponents, ['.tsx', '.jsx']);
267
+ const mappedCount = countAppMapComponents();
268
+
269
+ console.log(` Components in src/: ${componentCount}`);
270
+ console.log(` Components in app-map: ${mappedCount}`);
271
+
272
+ if (componentCount > mappedCount + 5) {
273
+ console.log(` ${color('yellow', '⚠')} App-map may be out of sync`);
274
+ console.log(' Run: ./scripts/flow update-map scan src/components');
275
+ warnings++;
276
+ } else {
277
+ console.log(` ${color('green', '✓')} App-map appears in sync`);
278
+ }
279
+ } else {
280
+ console.log(` ${color('yellow', '⚠')} src/components/ not found (may be OK for new projects)`);
281
+ }
282
+
283
+ // Check permission rules (Claude Code specific)
284
+ console.log('');
285
+ printSection('Checking permission rules...');
286
+
287
+ const settingsPath = path.join(PROJECT_ROOT, '.claude', 'settings.local.json');
288
+ if (fileExists(settingsPath)) {
289
+ try {
290
+ const settings = JSON.parse(require('fs').readFileSync(settingsPath, 'utf-8'));
291
+ const permissions = settings.permissions?.allow || [];
292
+
293
+ // Use shared validation function
294
+ const validation = validatePermissions(permissions);
295
+
296
+ console.log(` Total rules: ${validation.analysis.total}`);
297
+
298
+ // Show duplicates (warning)
299
+ if (validation.analysis.duplicates.length > 0) {
300
+ console.log(` ${color('yellow', '⚠')} ${validation.analysis.duplicates.length} duplicate rule(s) found`);
301
+ for (const dup of validation.analysis.duplicates.slice(0, 3)) {
302
+ console.log(` - ${dup}`);
303
+ }
304
+ warnings++;
305
+ } else {
306
+ console.log(` ${color('green', '✓')} No duplicate rules`);
307
+ }
308
+
309
+ // Show overly broad rules (issue)
310
+ if (validation.analysis.overbroad.length > 0) {
311
+ console.log(` ${color('yellow', '⚠')} ${validation.analysis.overbroad.length} overly broad rule(s)`);
312
+ for (const ob of validation.analysis.overbroad) {
313
+ console.log(` - ${ob}`);
314
+ }
315
+ warnings++;
316
+ }
317
+
318
+ // Show shadowed rules (info only)
319
+ if (validation.analysis.shadowed.length > 0) {
320
+ console.log(` ${color('dim', 'ℹ')} ${validation.analysis.shadowed.length} rule(s) shadowed by wildcards (OK but redundant)`);
321
+ }
322
+
323
+ // Check for respectGitignore
324
+ if (settings.respectGitignore === true) {
325
+ console.log(` ${color('green', '✓')} respectGitignore: enabled`);
326
+ } else {
327
+ console.log(` ${color('yellow', '○')} respectGitignore: not set`);
328
+ }
329
+
330
+ } catch (err) {
331
+ console.log(` ${color('yellow', '⚠')} Could not parse settings.local.json`);
332
+ warnings++;
333
+ }
334
+ } else {
335
+ console.log(` ${color('yellow', '○')} .claude/settings.local.json not found (run 'flow bridge sync')`);
336
+ }
337
+
338
+ // Check git status
339
+ console.log('');
340
+ printSection('Checking git status...');
341
+
342
+ const git = getGitStatus();
343
+ if (git.isRepo) {
344
+ if (git.clean) {
345
+ console.log(` ${color('green', '✓')} Working directory clean`);
346
+ } else {
347
+ console.log(` ${color('yellow', '⚠')} ${git.uncommitted} uncommitted changes`);
348
+ warnings++;
349
+ }
350
+ } else {
351
+ console.log(` ${color('yellow', '⚠')} Not a git repository`);
352
+ warnings++;
353
+ }
354
+
355
+ // Check request-log
356
+ console.log('');
357
+ printSection('Checking request-log...');
358
+
359
+ if (fileExists(PATHS.requestLog)) {
360
+ const entryCount = countRequestLogEntries();
361
+ console.log(` Total entries: ${entryCount}`);
362
+
363
+ if (entryCount > 0) {
364
+ const lastEntry = getLastRequestLogEntry();
365
+ if (lastEntry) {
366
+ console.log(` Last entry: ${lastEntry}`);
367
+ }
368
+ }
369
+ }
370
+
371
+ // Check agents
372
+ console.log('');
373
+ printSection('Checking agents...');
374
+
375
+ const agentsDir = path.join(PROJECT_ROOT, 'agents');
376
+ const coreAgents = ['orchestrator', 'developer', 'reviewer', 'tester'];
377
+ const optionalAgents = ['accessibility', 'security', 'performance', 'docs', 'design-system', 'onboarding'];
378
+
379
+ for (const agent of coreAgents) {
380
+ const agentPath = path.join(agentsDir, `${agent}.md`);
381
+ if (fileExists(agentPath)) {
382
+ console.log(` ${color('green', '✓')} ${agent}.md`);
383
+ } else {
384
+ console.log(` ${color('red', '✗')} ${agent}.md - MISSING (core agent)`);
385
+ issues++;
386
+ }
387
+ }
388
+
389
+ for (const agent of optionalAgents) {
390
+ const agentPath = path.join(agentsDir, `${agent}.md`);
391
+ if (fileExists(agentPath)) {
392
+ console.log(` ${color('green', '✓')} ${agent}.md (optional)`);
393
+ }
394
+ }
395
+
396
+ // Summary
397
+ console.log('');
398
+ console.log('========================');
399
+
400
+ if (issues === 0 && warnings === 0) {
401
+ console.log(color('green', '✓ Workflow is healthy!'));
402
+ } else if (issues === 0) {
403
+ console.log(color('yellow', `⚠ ${warnings} warning(s), but no critical issues`));
404
+ } else {
405
+ console.log(color('red', `✗ ${issues} issue(s), ${warnings} warning(s)`));
406
+ console.log('');
407
+ console.log("Run './scripts/flow init' to fix missing files");
408
+ }
409
+
410
+ process.exit(issues > 0 ? 1 : 0);
411
+ }
412
+
413
+ main();