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,482 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Project Context Initializer
5
+ *
6
+ * Creates and manages project context files:
7
+ * - stack.md - Technology stack (auto-detected + human verified)
8
+ * - constraints.md - Immutable rules (human controlled)
9
+ * - conventions.md - Coding patterns (AI can propose updates)
10
+ *
11
+ * Usage:
12
+ * flow context-init # Initialize context files
13
+ * flow context-init --rescan # Rescan and update stack.md
14
+ * flow context show # Show all context
15
+ * flow context stack # Show stack.md
16
+ * flow context constraints # Show constraints.md
17
+ * flow context conventions # Show conventions.md
18
+ */
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const { getProjectRoot, colors: c } = require('./flow-utils');
23
+
24
+ const PROJECT_ROOT = getProjectRoot();
25
+ const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
26
+ const CONTEXT_DIR = path.join(WORKFLOW_DIR, 'context');
27
+ const TEMPLATES_DIR = path.join(__dirname, '..', 'templates', 'context');
28
+
29
+ /**
30
+ * Detect technology stack from project files
31
+ */
32
+ function detectStack() {
33
+ const stack = {
34
+ language: null,
35
+ languageVersion: null,
36
+ runtime: null,
37
+ packageManager: null,
38
+ frameworks: {
39
+ frontend: null,
40
+ backend: null,
41
+ fullStack: null
42
+ },
43
+ testing: null,
44
+ linting: null,
45
+ formatting: null,
46
+ typeChecking: null,
47
+ bundler: null,
48
+ database: null,
49
+ orm: null,
50
+ dependencies: {}
51
+ };
52
+
53
+ // Check package.json for Node.js projects
54
+ const packageJsonPath = path.join(PROJECT_ROOT, 'package.json');
55
+ if (fs.existsSync(packageJsonPath)) {
56
+ try {
57
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
58
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
59
+
60
+ stack.runtime = 'Node.js';
61
+
62
+ // Detect language
63
+ if (deps.typescript) {
64
+ stack.language = 'TypeScript';
65
+ stack.languageVersion = deps.typescript.replace(/[\^~]/g, '');
66
+ stack.typeChecking = 'TypeScript';
67
+ } else {
68
+ stack.language = 'JavaScript';
69
+ }
70
+
71
+ // Detect frameworks
72
+ if (deps.next) {
73
+ stack.frameworks.fullStack = `Next.js ${deps.next.replace(/[\^~]/g, '')}`;
74
+ } else if (deps.nuxt) {
75
+ stack.frameworks.fullStack = `Nuxt ${deps.nuxt.replace(/[\^~]/g, '')}`;
76
+ } else if (deps['@sveltejs/kit']) {
77
+ stack.frameworks.fullStack = 'SvelteKit';
78
+ }
79
+
80
+ if (deps.react) {
81
+ stack.frameworks.frontend = `React ${deps.react.replace(/[\^~]/g, '')}`;
82
+ } else if (deps.vue) {
83
+ stack.frameworks.frontend = `Vue ${deps.vue.replace(/[\^~]/g, '')}`;
84
+ } else if (deps.svelte) {
85
+ stack.frameworks.frontend = `Svelte ${deps.svelte.replace(/[\^~]/g, '')}`;
86
+ } else if (deps['@angular/core']) {
87
+ stack.frameworks.frontend = `Angular ${deps['@angular/core'].replace(/[\^~]/g, '')}`;
88
+ }
89
+
90
+ if (deps.express) {
91
+ stack.frameworks.backend = `Express ${deps.express.replace(/[\^~]/g, '')}`;
92
+ } else if (deps.fastify) {
93
+ stack.frameworks.backend = `Fastify ${deps.fastify.replace(/[\^~]/g, '')}`;
94
+ } else if (deps['@nestjs/core']) {
95
+ stack.frameworks.backend = 'NestJS';
96
+ } else if (deps.hono) {
97
+ stack.frameworks.backend = `Hono ${deps.hono.replace(/[\^~]/g, '')}`;
98
+ }
99
+
100
+ // Detect testing
101
+ if (deps.vitest) {
102
+ stack.testing = 'Vitest';
103
+ } else if (deps.jest) {
104
+ stack.testing = 'Jest';
105
+ } else if (deps.mocha) {
106
+ stack.testing = 'Mocha';
107
+ } else if (deps['@playwright/test']) {
108
+ stack.testing = 'Playwright';
109
+ }
110
+
111
+ // Detect linting
112
+ if (deps['@biomejs/biome'] || deps.biome) {
113
+ stack.linting = 'Biome';
114
+ stack.formatting = 'Biome';
115
+ } else if (deps.eslint) {
116
+ stack.linting = 'ESLint';
117
+ }
118
+
119
+ // Detect formatting
120
+ if (!stack.formatting && deps.prettier) {
121
+ stack.formatting = 'Prettier';
122
+ }
123
+
124
+ // Detect bundler
125
+ if (deps.vite) {
126
+ stack.bundler = 'Vite';
127
+ } else if (deps.webpack) {
128
+ stack.bundler = 'Webpack';
129
+ } else if (deps.esbuild) {
130
+ stack.bundler = 'esbuild';
131
+ } else if (deps.rollup) {
132
+ stack.bundler = 'Rollup';
133
+ } else if (deps.parcel) {
134
+ stack.bundler = 'Parcel';
135
+ }
136
+
137
+ // Detect database/ORM
138
+ if (deps.prisma || deps['@prisma/client']) {
139
+ stack.orm = 'Prisma';
140
+ } else if (deps.drizzle || deps['drizzle-orm']) {
141
+ stack.orm = 'Drizzle';
142
+ } else if (deps.typeorm) {
143
+ stack.orm = 'TypeORM';
144
+ } else if (deps.sequelize) {
145
+ stack.orm = 'Sequelize';
146
+ } else if (deps.mongoose) {
147
+ stack.orm = 'Mongoose';
148
+ stack.database = 'MongoDB';
149
+ }
150
+
151
+ if (deps.pg || deps.postgres) {
152
+ stack.database = 'PostgreSQL';
153
+ } else if (deps.mysql2 || deps.mysql) {
154
+ stack.database = 'MySQL';
155
+ } else if (deps['better-sqlite3'] || deps.sqlite3) {
156
+ stack.database = 'SQLite';
157
+ }
158
+
159
+ // Store key dependencies
160
+ const keyDeps = ['react', 'vue', 'svelte', 'next', 'express', 'fastify',
161
+ 'prisma', 'typescript', 'vite', 'tailwindcss', 'zod', 'trpc'];
162
+ for (const dep of keyDeps) {
163
+ if (deps[dep]) {
164
+ stack.dependencies[dep] = deps[dep].replace(/[\^~]/g, '');
165
+ }
166
+ }
167
+ } catch (err) {
168
+ console.error(`${c.yellow}Warning: Could not parse package.json${c.reset}`);
169
+ }
170
+ }
171
+
172
+ // Detect package manager
173
+ if (fs.existsSync(path.join(PROJECT_ROOT, 'pnpm-lock.yaml'))) {
174
+ stack.packageManager = 'pnpm';
175
+ } else if (fs.existsSync(path.join(PROJECT_ROOT, 'yarn.lock'))) {
176
+ stack.packageManager = 'yarn';
177
+ } else if (fs.existsSync(path.join(PROJECT_ROOT, 'bun.lockb'))) {
178
+ stack.packageManager = 'bun';
179
+ stack.runtime = 'Bun';
180
+ } else if (fs.existsSync(path.join(PROJECT_ROOT, 'package-lock.json'))) {
181
+ stack.packageManager = 'npm';
182
+ }
183
+
184
+ // Check for Python projects
185
+ const requirementsPath = path.join(PROJECT_ROOT, 'requirements.txt');
186
+ const pyprojectPath = path.join(PROJECT_ROOT, 'pyproject.toml');
187
+ if (fs.existsSync(requirementsPath) || fs.existsSync(pyprojectPath)) {
188
+ stack.language = 'Python';
189
+ stack.runtime = 'Python';
190
+
191
+ if (fs.existsSync(path.join(PROJECT_ROOT, 'poetry.lock'))) {
192
+ stack.packageManager = 'Poetry';
193
+ } else if (fs.existsSync(path.join(PROJECT_ROOT, 'Pipfile.lock'))) {
194
+ stack.packageManager = 'Pipenv';
195
+ } else {
196
+ stack.packageManager = 'pip';
197
+ }
198
+
199
+ // Try to detect Python frameworks
200
+ const requirements = fs.existsSync(requirementsPath)
201
+ ? fs.readFileSync(requirementsPath, 'utf-8')
202
+ : '';
203
+
204
+ if (requirements.includes('fastapi') || requirements.includes('FastAPI')) {
205
+ stack.frameworks.backend = 'FastAPI';
206
+ } else if (requirements.includes('django') || requirements.includes('Django')) {
207
+ stack.frameworks.backend = 'Django';
208
+ } else if (requirements.includes('flask') || requirements.includes('Flask')) {
209
+ stack.frameworks.backend = 'Flask';
210
+ }
211
+
212
+ if (requirements.includes('pytest')) {
213
+ stack.testing = 'pytest';
214
+ }
215
+ }
216
+
217
+ // Check for Rust projects
218
+ const cargoPath = path.join(PROJECT_ROOT, 'Cargo.toml');
219
+ if (fs.existsSync(cargoPath)) {
220
+ stack.language = 'Rust';
221
+ stack.runtime = 'Rust';
222
+ stack.packageManager = 'Cargo';
223
+ }
224
+
225
+ // Check for Go projects
226
+ const goModPath = path.join(PROJECT_ROOT, 'go.mod');
227
+ if (fs.existsSync(goModPath)) {
228
+ stack.language = 'Go';
229
+ stack.runtime = 'Go';
230
+ stack.packageManager = 'Go Modules';
231
+ }
232
+
233
+ return stack;
234
+ }
235
+
236
+ /**
237
+ * Generate stack.md content from detected stack
238
+ */
239
+ function generateStackContent(stack) {
240
+ const timestamp = new Date().toISOString().slice(0, 10);
241
+
242
+ let content = `# Technology Stack
243
+
244
+ Auto-detected on ${timestamp}. Please verify and update as needed.
245
+
246
+ ---
247
+
248
+ ## Runtime
249
+ - **Language**: ${stack.language || 'Not detected'}${stack.languageVersion ? ` ${stack.languageVersion}` : ''}
250
+ - **Runtime**: ${stack.runtime || 'Not detected'}
251
+ - **Package Manager**: ${stack.packageManager || 'Not detected'}
252
+
253
+ ## Frameworks
254
+ - **Frontend**: ${stack.frameworks.frontend || 'None'}
255
+ - **Backend**: ${stack.frameworks.backend || 'None'}
256
+ - **Full-Stack**: ${stack.frameworks.fullStack || 'None'}
257
+
258
+ ## Build & Tooling
259
+ - **Bundler**: ${stack.bundler || 'Not detected'}
260
+ - **Testing**: ${stack.testing || 'Not detected'}
261
+ - **Linting**: ${stack.linting || 'Not detected'}
262
+ - **Formatting**: ${stack.formatting || 'Not detected'}
263
+ - **Type Checking**: ${stack.typeChecking || 'None'}
264
+
265
+ ## Infrastructure
266
+ - **Database**: ${stack.database || 'Not detected'}
267
+ - **ORM/ODM**: ${stack.orm || 'Not detected'}
268
+
269
+ `;
270
+
271
+ // Add key dependencies
272
+ const depEntries = Object.entries(stack.dependencies);
273
+ if (depEntries.length > 0) {
274
+ content += `## Key Dependencies
275
+
276
+ | Dependency | Version |
277
+ |------------|---------|
278
+ `;
279
+ for (const [name, version] of depEntries) {
280
+ content += `| ${name} | ${version} |\n`;
281
+ }
282
+ content += '\n';
283
+ }
284
+
285
+ content += `---
286
+
287
+ *Last updated: ${timestamp}*
288
+ *Updated by: auto-detect*
289
+ `;
290
+
291
+ return content;
292
+ }
293
+
294
+ /**
295
+ * Initialize context files
296
+ */
297
+ function initContext(options = {}) {
298
+ // Create context directory
299
+ if (!fs.existsSync(CONTEXT_DIR)) {
300
+ fs.mkdirSync(CONTEXT_DIR, { recursive: true });
301
+ }
302
+
303
+ const results = {
304
+ stack: false,
305
+ constraints: false,
306
+ conventions: false
307
+ };
308
+
309
+ // Generate stack.md
310
+ const stackPath = path.join(CONTEXT_DIR, 'stack.md');
311
+ if (!fs.existsSync(stackPath) || options.rescan) {
312
+ const stack = detectStack();
313
+ const content = generateStackContent(stack);
314
+ fs.writeFileSync(stackPath, content);
315
+ results.stack = true;
316
+ console.log(`${c.green}✅ ${options.rescan ? 'Updated' : 'Created'} stack.md${c.reset}`);
317
+ } else {
318
+ console.log(`${c.dim} stack.md already exists (use --rescan to update)${c.reset}`);
319
+ }
320
+
321
+ // Copy constraints.md template
322
+ const constraintsPath = path.join(CONTEXT_DIR, 'constraints.md');
323
+ if (!fs.existsSync(constraintsPath)) {
324
+ const templatePath = path.join(TEMPLATES_DIR, 'constraints.md');
325
+ if (fs.existsSync(templatePath)) {
326
+ let content = fs.readFileSync(templatePath, 'utf-8');
327
+ content = content.replace(/\{\{date\}\}/g, new Date().toISOString().slice(0, 10));
328
+ fs.writeFileSync(constraintsPath, content);
329
+ results.constraints = true;
330
+ console.log(`${c.green}✅ Created constraints.md${c.reset}`);
331
+ }
332
+ } else {
333
+ console.log(`${c.dim} constraints.md already exists${c.reset}`);
334
+ }
335
+
336
+ // Copy conventions.md template
337
+ const conventionsPath = path.join(CONTEXT_DIR, 'conventions.md');
338
+ if (!fs.existsSync(conventionsPath)) {
339
+ const templatePath = path.join(TEMPLATES_DIR, 'conventions.md');
340
+ if (fs.existsSync(templatePath)) {
341
+ fs.copyFileSync(templatePath, conventionsPath);
342
+ results.conventions = true;
343
+ console.log(`${c.green}✅ Created conventions.md${c.reset}`);
344
+ }
345
+ } else {
346
+ console.log(`${c.dim} conventions.md already exists${c.reset}`);
347
+ }
348
+
349
+ return results;
350
+ }
351
+
352
+ /**
353
+ * Show context file contents
354
+ */
355
+ function showContext(file = null) {
356
+ const files = file
357
+ ? [file]
358
+ : ['stack.md', 'constraints.md', 'conventions.md'];
359
+
360
+ for (const f of files) {
361
+ const filePath = path.join(CONTEXT_DIR, f.endsWith('.md') ? f : `${f}.md`);
362
+ if (fs.existsSync(filePath)) {
363
+ console.log(`\n${c.cyan}${c.bold}=== ${f} ===${c.reset}\n`);
364
+ console.log(fs.readFileSync(filePath, 'utf-8'));
365
+ } else {
366
+ console.log(`${c.yellow}File not found: ${f}${c.reset}`);
367
+ console.log(`${c.dim}Run "flow context-init" to create context files${c.reset}`);
368
+ }
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Load all context for LLM prompts
374
+ */
375
+ function loadProjectContext() {
376
+ const context = {};
377
+ const files = ['stack.md', 'constraints.md', 'conventions.md'];
378
+
379
+ for (const file of files) {
380
+ const filePath = path.join(CONTEXT_DIR, file);
381
+ if (fs.existsSync(filePath)) {
382
+ const key = file.replace('.md', '');
383
+ context[key] = fs.readFileSync(filePath, 'utf-8');
384
+ }
385
+ }
386
+
387
+ return context;
388
+ }
389
+
390
+ /**
391
+ * Get context summary for prompts
392
+ */
393
+ function getContextSummary() {
394
+ const context = loadProjectContext();
395
+ let summary = '';
396
+
397
+ if (context.stack) {
398
+ summary += '## Technology Stack\n' + context.stack + '\n\n';
399
+ }
400
+
401
+ if (context.constraints) {
402
+ summary += '## Project Constraints (MUST FOLLOW)\n' + context.constraints + '\n\n';
403
+ }
404
+
405
+ if (context.conventions) {
406
+ summary += '## Coding Conventions\n' + context.conventions + '\n\n';
407
+ }
408
+
409
+ return summary;
410
+ }
411
+
412
+ // Module exports
413
+ module.exports = {
414
+ detectStack,
415
+ initContext,
416
+ showContext,
417
+ loadProjectContext,
418
+ getContextSummary
419
+ };
420
+
421
+ // CLI Handler
422
+ if (require.main === module) {
423
+ const args = process.argv.slice(2);
424
+ const command = args[0];
425
+
426
+ switch (command) {
427
+ case 'init':
428
+ case undefined: {
429
+ const rescan = args.includes('--rescan');
430
+ console.log(`${c.cyan}${c.bold}Initializing Project Context${c.reset}\n`);
431
+ initContext({ rescan });
432
+ console.log(`\n${c.dim}Context files created in .workflow/context/${c.reset}`);
433
+ break;
434
+ }
435
+
436
+ case 'show': {
437
+ const file = args[1];
438
+ showContext(file);
439
+ break;
440
+ }
441
+
442
+ case 'stack':
443
+ case 'constraints':
444
+ case 'conventions': {
445
+ showContext(command);
446
+ break;
447
+ }
448
+
449
+ case 'detect': {
450
+ const stack = detectStack();
451
+ console.log(JSON.stringify(stack, null, 2));
452
+ break;
453
+ }
454
+
455
+ case '--help':
456
+ case '-h': {
457
+ console.log(`
458
+ ${c.cyan}Wogi Flow - Project Context Manager${c.reset}
459
+
460
+ ${c.bold}Usage:${c.reset}
461
+ flow context-init Initialize context files
462
+ flow context-init --rescan Rescan and update stack.md
463
+ flow context show [file] Show context file(s)
464
+ flow context stack Show stack.md
465
+ flow context constraints Show constraints.md
466
+ flow context conventions Show conventions.md
467
+ flow context detect Detect stack (JSON output)
468
+
469
+ ${c.bold}Files:${c.reset}
470
+ stack.md Technology stack (auto-detected)
471
+ constraints.md Immutable rules (human-controlled)
472
+ conventions.md Coding patterns (AI can propose updates)
473
+ `);
474
+ break;
475
+ }
476
+
477
+ default:
478
+ console.log(`${c.red}Unknown command: ${command}${c.reset}`);
479
+ console.log(`${c.dim}Run "flow context-init --help" for usage${c.reset}`);
480
+ process.exit(1);
481
+ }
482
+ }