wogiflow 1.9.9 → 2.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 (277) hide show
  1. package/.claude/settings.json +45 -12
  2. package/.workflow/lib/assumption-detector.js +4 -481
  3. package/.workflow/lib/config-substitution.js +4 -389
  4. package/.workflow/lib/failure-categories.js +4 -478
  5. package/lib/commands/login.js +6 -6
  6. package/lib/commands/logout.js +1 -1
  7. package/lib/commands/team-connection.js +8 -8
  8. package/lib/installer.js +19 -20
  9. package/lib/release-channel.js +2 -2
  10. package/lib/skill-registry.js +4 -4
  11. package/lib/upgrader.js +4 -3
  12. package/lib/utils.js +4 -4
  13. package/package.json +8 -1
  14. package/scripts/flow +3 -0
  15. package/scripts/flow-adaptive-learning.js +19 -36
  16. package/scripts/flow-aggregate.js +5 -5
  17. package/scripts/flow-api-index.js +3 -3
  18. package/scripts/flow-assumption-detector.js +483 -0
  19. package/scripts/flow-audit.js +6 -6
  20. package/scripts/flow-auto-context.js +18 -17
  21. package/scripts/flow-auto-learn.js +5 -5
  22. package/scripts/flow-background.js +6 -7
  23. package/scripts/flow-best-of-n.js +1 -1
  24. package/scripts/flow-bridge-state.js +7 -7
  25. package/scripts/flow-bridge.js +8 -7
  26. package/scripts/flow-bug.js +3 -3
  27. package/scripts/flow-bulk-loop.js +21 -24
  28. package/scripts/flow-bulk-orchestrator.js +28 -28
  29. package/scripts/flow-capture.js +8 -8
  30. package/scripts/flow-cascade-completion.js +512 -0
  31. package/scripts/flow-cascade.js +2 -2
  32. package/scripts/flow-checkpoint.js +13 -12
  33. package/scripts/flow-clarifying-questions.js +4 -4
  34. package/scripts/flow-cli.js +9 -8
  35. package/scripts/flow-code-intelligence.js +11 -17
  36. package/scripts/flow-community-sync.js +2 -2
  37. package/scripts/flow-community.js +36 -36
  38. package/scripts/flow-config-defaults.js +14 -6
  39. package/scripts/flow-config-interactive.js +3 -3
  40. package/scripts/flow-config-loader.js +30 -61
  41. package/scripts/flow-config-set.js +2 -2
  42. package/scripts/flow-config-substitution.js +392 -0
  43. package/scripts/flow-conflict-resolver.js +7 -68
  44. package/scripts/flow-consistency-check.js +2 -2
  45. package/scripts/flow-constants.js +34 -30
  46. package/scripts/flow-context-compact/expander.js +3 -3
  47. package/scripts/flow-context-compact/index.js +4 -4
  48. package/scripts/flow-context-compact/section-extractor.js +1 -1
  49. package/scripts/flow-context-compact/summary-tree.js +6 -6
  50. package/scripts/flow-context-estimator.js +33 -2
  51. package/scripts/flow-context-gatherer.js +2 -2
  52. package/scripts/flow-context-generator.js +3 -3
  53. package/scripts/flow-context-init.js +11 -9
  54. package/scripts/flow-context-monitor.js +5 -5
  55. package/scripts/flow-context-orchestrator.js +1 -1
  56. package/scripts/flow-context-scoring.js +8 -8
  57. package/scripts/flow-correct.js +6 -6
  58. package/scripts/flow-correction-detector.js +3 -3
  59. package/scripts/flow-damage-control.js +14 -3
  60. package/scripts/flow-decision-tracker.js +2 -2
  61. package/scripts/flow-decisions-merge.js +4 -4
  62. package/scripts/flow-diff.js +16 -11
  63. package/scripts/flow-done.js +135 -558
  64. package/scripts/flow-durable-session.js +7 -6
  65. package/scripts/flow-entropy-monitor.js +4 -3
  66. package/scripts/flow-epics.js +4 -5
  67. package/scripts/flow-error-recovery.js +2 -2
  68. package/scripts/flow-eval-judge.js +3 -3
  69. package/scripts/flow-eval.js +8 -8
  70. package/scripts/flow-export-profile +3 -3
  71. package/scripts/flow-export-scanner.js +7 -7
  72. package/scripts/flow-extraction-review.js +3 -12
  73. package/scripts/flow-failure-categories.js +480 -0
  74. package/scripts/flow-failure-learning.js +3 -3
  75. package/scripts/flow-feature.js +3 -3
  76. package/scripts/flow-figma-confirm.js +11 -7
  77. package/scripts/flow-figma-extract.js +3 -3
  78. package/scripts/flow-figma-generate.js +17 -13
  79. package/scripts/flow-figma-index.js +18 -23
  80. package/scripts/flow-figma-match.js +6 -5
  81. package/scripts/flow-figma-mcp-server.js +6 -13
  82. package/scripts/flow-figma-orchestrator.js +2 -2
  83. package/scripts/flow-figma-registry.js +2 -2
  84. package/scripts/flow-function-index.js +3 -3
  85. package/scripts/flow-gate-confidence.js +2 -2
  86. package/scripts/flow-gitignore.js +3 -3
  87. package/scripts/flow-guided-edit.js +13 -21
  88. package/scripts/flow-health.js +111 -100
  89. package/scripts/flow-hooks-install.js +3 -3
  90. package/scripts/flow-hooks.js +25 -27
  91. package/scripts/flow-http-client.js +2 -2
  92. package/scripts/flow-hybrid-detect.js +2 -2
  93. package/scripts/flow-hybrid-interactive.js +7 -6
  94. package/scripts/flow-hybrid-test.js +6 -6
  95. package/scripts/flow-hypothesis-generator.js +14 -13
  96. package/scripts/flow-import-profile +1 -1
  97. package/scripts/flow-instruction-richness.js +8 -8
  98. package/scripts/flow-io.js +16 -16
  99. package/scripts/flow-knowledge-router.js +12 -11
  100. package/scripts/flow-knowledge-sync.js +14 -20
  101. package/scripts/flow-links.js +13 -20
  102. package/scripts/flow-log-manager.js +5 -5
  103. package/scripts/flow-long-input-chunking.js +32 -56
  104. package/scripts/flow-long-input-cli.js +3066 -0
  105. package/scripts/flow-long-input-complexity.js +422 -0
  106. package/scripts/flow-long-input-constants.js +445 -0
  107. package/scripts/flow-long-input-detection.js +757 -0
  108. package/scripts/flow-long-input-stories.js +2 -2
  109. package/scripts/flow-long-input-voice.js +390 -0
  110. package/scripts/flow-long-input.js +117 -4845
  111. package/scripts/flow-loop-retry-learning.js +54 -66
  112. package/scripts/flow-lsp.js +3 -3
  113. package/scripts/flow-mcp-docs.js +8 -10
  114. package/scripts/flow-memory-blocks.js +3 -3
  115. package/scripts/flow-memory-compactor.js +4 -10
  116. package/scripts/flow-memory-db.js +6 -5
  117. package/scripts/flow-memory-sync.js +5 -14
  118. package/scripts/flow-metrics.js +8 -12
  119. package/scripts/flow-migrate.js +11 -17
  120. package/scripts/flow-model-adapter.js +8 -16
  121. package/scripts/flow-model-caller.js +1 -1
  122. package/scripts/flow-model-config.js +9 -9
  123. package/scripts/flow-model-profile.js +3 -3
  124. package/scripts/flow-model-router.js +1 -1
  125. package/scripts/flow-model-types.js +2 -2
  126. package/scripts/flow-models.js +2 -2
  127. package/scripts/flow-morning.js +10 -10
  128. package/scripts/flow-multi-approach.js +8 -7
  129. package/scripts/flow-orchestrate-context.js +793 -0
  130. package/scripts/flow-orchestrate-llm.js +2 -2
  131. package/scripts/flow-orchestrate-rollback.js +108 -0
  132. package/scripts/flow-orchestrate-state.js +323 -0
  133. package/scripts/flow-orchestrate-templates.js +253 -0
  134. package/scripts/flow-orchestrate-validation.js +3 -3
  135. package/scripts/flow-orchestrate-validator.js +176 -0
  136. package/scripts/flow-orchestrate.js +323 -1848
  137. package/scripts/flow-output.js +9 -0
  138. package/scripts/flow-parallel.js +6 -6
  139. package/scripts/flow-paths.js +26 -9
  140. package/scripts/flow-pattern-enforcer.js +4 -4
  141. package/scripts/flow-pattern-extractor.js +23 -34
  142. package/scripts/flow-peer-review.js +4 -4
  143. package/scripts/flow-permissions.js +8 -10
  144. package/scripts/flow-phased-task.js +2 -2
  145. package/scripts/flow-plan.js +3 -3
  146. package/scripts/flow-plugin-registry.js +2 -2
  147. package/scripts/flow-prd-manager.js +2 -2
  148. package/scripts/flow-proactive-compact.js +1 -1
  149. package/scripts/flow-product-scanner.js +2 -2
  150. package/scripts/flow-progress.js +1 -1
  151. package/scripts/flow-project-analyzer.js +10 -10
  152. package/scripts/flow-prompt-capture.js +3 -3
  153. package/scripts/flow-prompt-composer.js +4 -4
  154. package/scripts/flow-prompt-template.js +3 -3
  155. package/scripts/flow-providers.js +23 -22
  156. package/scripts/flow-queue.js +10 -10
  157. package/scripts/flow-ready.js +4 -7
  158. package/scripts/flow-registry-manager.js +3 -3
  159. package/scripts/flow-regression.js +15 -14
  160. package/scripts/flow-research-protocol.js +2 -2
  161. package/scripts/flow-response-parser.js +4 -4
  162. package/scripts/flow-resume.js +6 -6
  163. package/scripts/flow-review-passes/index.js +11 -8
  164. package/scripts/flow-review-passes/integration.js +1 -1
  165. package/scripts/flow-review-passes/logic.js +1 -1
  166. package/scripts/flow-review-passes/security.js +11 -32
  167. package/scripts/flow-review-passes/structure.js +2 -2
  168. package/scripts/flow-review.js +10 -13
  169. package/scripts/flow-revision-tracker.js +2 -2
  170. package/scripts/flow-roadmap.js +24 -23
  171. package/scripts/flow-rules-sync.js +2 -2
  172. package/scripts/flow-run-trace.js +24 -38
  173. package/scripts/flow-safety.js +7 -6
  174. package/scripts/flow-scanner-base.js +3 -3
  175. package/scripts/flow-scenario-engine.js +55 -54
  176. package/scripts/flow-script-resolver.js +8 -22
  177. package/scripts/flow-section-index.js +5 -5
  178. package/scripts/flow-security.js +148 -4
  179. package/scripts/flow-semantic-match.js +2 -2
  180. package/scripts/flow-session-end.js +22 -22
  181. package/scripts/flow-session-learning.js +3 -3
  182. package/scripts/flow-session-state.js +2 -2
  183. package/scripts/flow-setup-hooks.js +13 -16
  184. package/scripts/flow-skill-create.js +11 -8
  185. package/scripts/flow-skill-freshness.js +3 -3
  186. package/scripts/flow-skill-generator.js +27 -24
  187. package/scripts/flow-skill-learn.js +4 -4
  188. package/scripts/flow-skill-matcher.js +4 -3
  189. package/scripts/flow-solution-optimizer.js +5 -11
  190. package/scripts/flow-spec-generator.js +19 -22
  191. package/scripts/flow-spec-verifier.js +5 -5
  192. package/scripts/flow-stack-wizard.js +12 -21
  193. package/scripts/flow-standards-checker.js +3 -3
  194. package/scripts/flow-standards-gate.js +2 -2
  195. package/scripts/flow-standards-learner.js +4 -4
  196. package/scripts/flow-start.js +14 -13
  197. package/scripts/flow-state-cleanup.js +2 -2
  198. package/scripts/flow-stats-collector.js +2 -2
  199. package/scripts/flow-status.js +5 -6
  200. package/scripts/flow-statusline-setup.js +13 -11
  201. package/scripts/flow-step-changelog.js +2 -2
  202. package/scripts/flow-step-comments.js +2 -2
  203. package/scripts/flow-step-complexity.js +2 -2
  204. package/scripts/flow-step-coverage.js +9 -7
  205. package/scripts/flow-step-knowledge.js +2 -2
  206. package/scripts/flow-step-pr-tests.js +4 -8
  207. package/scripts/flow-step-regression.js +2 -2
  208. package/scripts/flow-step-review.js +2 -2
  209. package/scripts/flow-step-security.js +9 -14
  210. package/scripts/flow-step-silent-failures.js +2 -2
  211. package/scripts/flow-step-simplifier.js +2 -2
  212. package/scripts/flow-story.js +12 -11
  213. package/scripts/flow-strict-adherence.js +2 -2
  214. package/scripts/flow-suspend.js +2 -2
  215. package/scripts/flow-sync-anonymizer.js +1 -1
  216. package/scripts/flow-task-analyzer.js +2 -2
  217. package/scripts/flow-task-checkpoint.js +9 -10
  218. package/scripts/flow-task-classifier.js +2 -2
  219. package/scripts/flow-task-completion-summary.js +18 -18
  220. package/scripts/flow-task-enforcer.js +6 -6
  221. package/scripts/flow-tech-debt.js +7 -6
  222. package/scripts/flow-template-extractor.js +10 -18
  223. package/scripts/flow-templates.js +7 -12
  224. package/scripts/flow-test-api.js +3 -3
  225. package/scripts/flow-test-discovery.js +6 -7
  226. package/scripts/flow-test-generate.js +2 -2
  227. package/scripts/flow-test-integrity.js +2 -2
  228. package/scripts/flow-test-ui.js +5 -5
  229. package/scripts/flow-testing-deps.js +3 -3
  230. package/scripts/flow-tiered-learning.js +2 -2
  231. package/scripts/flow-todowrite-sync.js +2 -2
  232. package/scripts/flow-utils.js +32 -473
  233. package/scripts/flow-verification-profile.js +32 -35
  234. package/scripts/flow-verify.js +39 -50
  235. package/scripts/flow-version-check.js +17 -27
  236. package/scripts/flow-webmcp-generator.js +11 -6
  237. package/scripts/flow-wiring-verifier.js +3 -3
  238. package/scripts/flow-workflow-steps.js +2 -2
  239. package/scripts/flow-workflow.js +13 -11
  240. package/scripts/flow-worktree.js +11 -11
  241. package/scripts/hooks/adapters/claude-code.js +37 -5
  242. package/scripts/hooks/core/component-check.js +5 -6
  243. package/scripts/hooks/core/config-change.js +4 -4
  244. package/scripts/hooks/core/instructions-loaded.js +9 -9
  245. package/scripts/hooks/core/loop-check.js +6 -6
  246. package/scripts/hooks/core/observation-capture.js +2 -2
  247. package/scripts/hooks/core/phase-gate.js +2 -2
  248. package/scripts/hooks/core/post-compact.js +143 -0
  249. package/scripts/hooks/core/research-gate.js +2 -2
  250. package/scripts/hooks/core/routing-gate.js +7 -7
  251. package/scripts/hooks/core/scope-gate.js +2 -17
  252. package/scripts/hooks/core/session-context.js +16 -16
  253. package/scripts/hooks/core/session-end.js +2 -2
  254. package/scripts/hooks/core/setup-check.js +2 -2
  255. package/scripts/hooks/core/task-completed.js +8 -8
  256. package/scripts/hooks/core/task-gate.js +5 -5
  257. package/scripts/hooks/core/validation.js +5 -5
  258. package/scripts/hooks/core/worktree-lifecycle.js +3 -3
  259. package/scripts/hooks/entry/claude-code/config-change.js +3 -8
  260. package/scripts/hooks/entry/claude-code/instructions-loaded.js +3 -12
  261. package/scripts/hooks/entry/claude-code/post-compact.js +45 -0
  262. package/scripts/hooks/entry/claude-code/post-tool-use.js +1 -1
  263. package/scripts/hooks/entry/claude-code/pre-tool-use.js +65 -1
  264. package/scripts/hooks/entry/claude-code/session-end.js +3 -7
  265. package/scripts/hooks/entry/claude-code/session-start.js +8 -4
  266. package/scripts/hooks/entry/claude-code/setup.js +3 -7
  267. package/scripts/hooks/entry/claude-code/stop.js +3 -17
  268. package/scripts/hooks/entry/claude-code/task-completed.js +3 -8
  269. package/scripts/hooks/entry/claude-code/user-prompt-submit.js +6 -19
  270. package/scripts/hooks/entry/claude-code/worktree-create.js +3 -7
  271. package/scripts/hooks/entry/claude-code/worktree-remove.js +3 -7
  272. package/scripts/hooks/git/post-commit.js +5 -4
  273. package/scripts/postinstall.js +7 -3
  274. package/scripts/preuninstall.js +2 -2
  275. package/scripts/registries/component-registry.js +4 -3
  276. package/scripts/registries/schema-registry.js +5 -5
  277. package/scripts/registries/service-registry.js +6 -6
@@ -1,389 +1,4 @@
1
- /**
2
- * Wogi Flow - Config Substitution
3
- *
4
- * Enables dynamic values in config files using substitution patterns:
5
- * - {env:VAR_NAME} - Environment variable substitution
6
- * - {file:path/to/file} - File content substitution
7
- *
8
- * Features:
9
- * - Tilde expansion (~/.secrets → /home/user/.secrets)
10
- * - Nested object/array processing
11
- * - Graceful handling of missing values
12
- * - Warning logging for unresolved placeholders
13
- *
14
- * Usage:
15
- * const { substituteConfig } = require('./.workflow/lib/config-substitution');
16
- * const resolvedConfig = substituteConfig(rawConfig);
17
- */
18
-
19
- const fs = require('fs');
20
- const path = require('path');
21
- const os = require('os');
22
-
23
- // ============================================================
24
- // Patterns
25
- // ============================================================
26
-
27
- /**
28
- * Substitution patterns
29
- */
30
- const PATTERNS = {
31
- env: /\{env:([^}]+)\}/g, // {env:VAR_NAME}
32
- file: /\{file:([^}]+)\}/g // {file:path/to/file}
33
- };
34
-
35
- /**
36
- * Check if a value contains substitution patterns
37
- * @param {string} value - Value to check
38
- * @returns {boolean}
39
- */
40
- function hasSubstitutionPattern(value) {
41
- if (typeof value !== 'string') return false;
42
- return PATTERNS.env.test(value) || PATTERNS.file.test(value);
43
- }
44
-
45
- // ============================================================
46
- // Path Utilities
47
- // ============================================================
48
-
49
- /**
50
- * Expand tilde (~) to user's home directory
51
- * @param {string} filePath - Path that may contain ~
52
- * @returns {string} Expanded path
53
- */
54
- function expandTilde(filePath) {
55
- if (!filePath || typeof filePath !== 'string') return filePath;
56
-
57
- if (filePath.startsWith('~/')) {
58
- return path.join(os.homedir(), filePath.slice(2));
59
- }
60
- if (filePath === '~') {
61
- return os.homedir();
62
- }
63
- return filePath;
64
- }
65
-
66
- /**
67
- * Resolve a file path (handles tilde and relative paths)
68
- * @param {string} filePath - Path to resolve
69
- * @param {string} basePath - Base path for relative paths
70
- * @returns {string} Resolved absolute path
71
- */
72
- function resolvePath(filePath, basePath = process.cwd()) {
73
- const expanded = expandTilde(filePath);
74
- if (path.isAbsolute(expanded)) {
75
- return expanded;
76
- }
77
- return path.resolve(basePath, expanded);
78
- }
79
-
80
- // ============================================================
81
- // Substitution Functions
82
- // ============================================================
83
-
84
- /**
85
- * Substitute environment variable pattern
86
- * @param {string} value - String containing {env:VAR} patterns
87
- * @param {Object} options - Options
88
- * @returns {Object} Result with value and warnings
89
- */
90
- function substituteEnvVars(value, options = {}) {
91
- const { logWarnings = true } = options;
92
- const warnings = [];
93
-
94
- // Reset regex lastIndex
95
- PATTERNS.env.lastIndex = 0;
96
-
97
- const result = value.replace(PATTERNS.env, (match, varName) => {
98
- const envValue = process.env[varName];
99
-
100
- if (envValue !== undefined) {
101
- return envValue;
102
- }
103
-
104
- // Env var not set - keep placeholder and warn
105
- if (logWarnings) {
106
- warnings.push({
107
- type: 'env',
108
- pattern: match,
109
- variable: varName,
110
- message: `Environment variable '${varName}' is not set`
111
- });
112
- }
113
- return match; // Keep original placeholder
114
- });
115
-
116
- return { value: result, warnings };
117
- }
118
-
119
- /**
120
- * Substitute file content pattern
121
- * @param {string} value - String containing {file:path} patterns
122
- * @param {Object} options - Options
123
- * @returns {Object} Result with value and warnings
124
- */
125
- function substituteFileContents(value, options = {}) {
126
- const { logWarnings = true, basePath = process.cwd() } = options;
127
- const warnings = [];
128
-
129
- // Reset regex lastIndex
130
- PATTERNS.file.lastIndex = 0;
131
-
132
- const result = value.replace(PATTERNS.file, (match, filePath) => {
133
- const resolvedPath = resolvePath(filePath.trim(), basePath);
134
-
135
- // Security: validate path is within project or user's home directory
136
- const homeDir = os.homedir();
137
- const absResolved = path.resolve(resolvedPath);
138
- const isWithinBase = absResolved.startsWith(path.resolve(basePath) + path.sep) || absResolved === path.resolve(basePath);
139
- const isWithinHome = homeDir && absResolved.startsWith(homeDir + path.sep);
140
- if (!isWithinBase && !isWithinHome) {
141
- if (logWarnings) {
142
- warnings.push({
143
- type: 'file',
144
- pattern: match,
145
- path: filePath,
146
- resolvedPath,
147
- message: `File path outside allowed locations blocked: ${resolvedPath}`
148
- });
149
- }
150
- return match; // Keep original placeholder
151
- }
152
-
153
- try {
154
- if (fs.existsSync(resolvedPath)) {
155
- const content = fs.readFileSync(resolvedPath, 'utf-8');
156
- return content.trim(); // Trim whitespace from file contents
157
- }
158
-
159
- // File doesn't exist - keep placeholder and warn
160
- if (logWarnings) {
161
- warnings.push({
162
- type: 'file',
163
- pattern: match,
164
- path: filePath,
165
- resolvedPath,
166
- message: `File not found: ${resolvedPath}`
167
- });
168
- }
169
- return match; // Keep original placeholder
170
- } catch (err) {
171
- if (logWarnings) {
172
- warnings.push({
173
- type: 'file',
174
- pattern: match,
175
- path: filePath,
176
- resolvedPath,
177
- message: `Error reading file: ${err.message}`
178
- });
179
- }
180
- return match;
181
- }
182
- });
183
-
184
- return { value: result, warnings };
185
- }
186
-
187
- /**
188
- * Substitute all patterns in a string value
189
- * @param {string} value - String to process
190
- * @param {Object} options - Options
191
- * @returns {Object} Result with value and warnings
192
- */
193
- function substituteString(value, options = {}) {
194
- if (typeof value !== 'string') {
195
- return { value, warnings: [] };
196
- }
197
-
198
- const allWarnings = [];
199
-
200
- // First pass: environment variables
201
- let result = value;
202
- const envResult = substituteEnvVars(result, options);
203
- result = envResult.value;
204
- allWarnings.push(...envResult.warnings);
205
-
206
- // Second pass: file contents
207
- const fileResult = substituteFileContents(result, options);
208
- result = fileResult.value;
209
- allWarnings.push(...fileResult.warnings);
210
-
211
- return { value: result, warnings: allWarnings };
212
- }
213
-
214
- // ============================================================
215
- // Deep Substitution
216
- // ============================================================
217
-
218
- /**
219
- * Recursively substitute patterns in an object/array
220
- * @param {*} obj - Object, array, or value to process
221
- * @param {Object} options - Options
222
- * @param {string} path - Current path in object (for debugging)
223
- * @returns {Object} Result with value and warnings
224
- */
225
- function substituteDeep(obj, options = {}, currentPath = '') {
226
- const allWarnings = [];
227
-
228
- if (obj === null || obj === undefined) {
229
- return { value: obj, warnings: [] };
230
- }
231
-
232
- // Handle arrays
233
- if (Array.isArray(obj)) {
234
- const result = obj.map((item, index) => {
235
- const itemResult = substituteDeep(item, options, `${currentPath}[${index}]`);
236
- allWarnings.push(...itemResult.warnings.map(w => ({
237
- ...w,
238
- path: `${currentPath}[${index}]`
239
- })));
240
- return itemResult.value;
241
- });
242
- return { value: result, warnings: allWarnings };
243
- }
244
-
245
- // Handle objects
246
- if (typeof obj === 'object') {
247
- const result = {};
248
- for (const [key, value] of Object.entries(obj)) {
249
- const keyPath = currentPath ? `${currentPath}.${key}` : key;
250
- const itemResult = substituteDeep(value, options, keyPath);
251
- allWarnings.push(...itemResult.warnings.map(w => ({
252
- ...w,
253
- path: keyPath
254
- })));
255
- result[key] = itemResult.value;
256
- }
257
- return { value: result, warnings: allWarnings };
258
- }
259
-
260
- // Handle strings
261
- if (typeof obj === 'string') {
262
- const strResult = substituteString(obj, options);
263
- return {
264
- value: strResult.value,
265
- warnings: strResult.warnings.map(w => ({
266
- ...w,
267
- path: currentPath
268
- }))
269
- };
270
- }
271
-
272
- // Other primitives - return as-is
273
- return { value: obj, warnings: [] };
274
- }
275
-
276
- // ============================================================
277
- // Main API
278
- // ============================================================
279
-
280
- /**
281
- * Substitute all patterns in a config object
282
- * @param {Object} config - Config object to process
283
- * @param {Object} options - Options
284
- * @param {boolean} options.logWarnings - Whether to log warnings (default: true)
285
- * @param {boolean} options.printWarnings - Whether to print warnings to console (default: false)
286
- * @param {string} options.basePath - Base path for relative file paths
287
- * @returns {Object} Result with value and warnings array
288
- */
289
- function substituteConfig(config, options = {}) {
290
- const { printWarnings = false, logWarnings = true, basePath } = options;
291
-
292
- const result = substituteDeep(config, { logWarnings, basePath });
293
-
294
- // Print warnings to console if requested
295
- if (printWarnings && result.warnings.length > 0) {
296
- console.warn('\n⚠️ Config substitution warnings:');
297
- for (const warning of result.warnings) {
298
- const pathInfo = warning.path ? ` at '${warning.path}'` : '';
299
- console.warn(` - ${warning.message}${pathInfo}`);
300
- }
301
- console.warn('');
302
- }
303
-
304
- return result;
305
- }
306
-
307
- /**
308
- * Check if a config has unresolved substitution patterns
309
- * @param {Object} config - Config object to check
310
- * @returns {Object} Result with hasUnresolved boolean and patterns array
311
- */
312
- function checkUnresolvedPatterns(config) {
313
- const configStr = JSON.stringify(config);
314
- const unresolvedEnv = [];
315
- const unresolvedFile = [];
316
-
317
- // Check for env patterns
318
- PATTERNS.env.lastIndex = 0;
319
- let match;
320
- while ((match = PATTERNS.env.exec(configStr)) !== null) {
321
- unresolvedEnv.push({ pattern: match[0], variable: match[1] });
322
- }
323
-
324
- // Check for file patterns
325
- PATTERNS.file.lastIndex = 0;
326
- while ((match = PATTERNS.file.exec(configStr)) !== null) {
327
- unresolvedFile.push({ pattern: match[0], path: match[1] });
328
- }
329
-
330
- return {
331
- hasUnresolved: unresolvedEnv.length > 0 || unresolvedFile.length > 0,
332
- env: unresolvedEnv,
333
- file: unresolvedFile
334
- };
335
- }
336
-
337
- /**
338
- * Get a list of all substitution patterns used in a config
339
- * @param {Object} config - Config object to scan
340
- * @returns {Object} Object with env and file pattern lists
341
- */
342
- function getUsedPatterns(config) {
343
- const configStr = JSON.stringify(config);
344
- const envPatterns = new Set();
345
- const filePatterns = new Set();
346
-
347
- // Find env patterns
348
- PATTERNS.env.lastIndex = 0;
349
- let match;
350
- while ((match = PATTERNS.env.exec(configStr)) !== null) {
351
- envPatterns.add(match[1]);
352
- }
353
-
354
- // Find file patterns
355
- PATTERNS.file.lastIndex = 0;
356
- while ((match = PATTERNS.file.exec(configStr)) !== null) {
357
- filePatterns.add(match[1]);
358
- }
359
-
360
- return {
361
- env: Array.from(envPatterns),
362
- file: Array.from(filePatterns)
363
- };
364
- }
365
-
366
- // ============================================================
367
- // Exports
368
- // ============================================================
369
-
370
- module.exports = {
371
- // Main API
372
- substituteConfig,
373
- checkUnresolvedPatterns,
374
- getUsedPatterns,
375
-
376
- // Lower-level functions
377
- substituteString,
378
- substituteEnvVars,
379
- substituteFileContents,
380
- substituteDeep,
381
-
382
- // Utilities
383
- expandTilde,
384
- resolvePath,
385
- hasSubstitutionPattern,
386
-
387
- // Constants
388
- PATTERNS
389
- };
1
+ // DEPRECATED: This file has been moved to scripts/flow-config-substitution.js
2
+ // This copy is kept for backward compatibility with existing installations.
3
+ // It re-exports from the new location.
4
+ module.exports = require('../../scripts/flow-config-substitution');