aios-core 3.6.0 → 3.8.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 (62) hide show
  1. package/.aios-core/core/session/context-detector.js +3 -0
  2. package/.aios-core/core/session/context-loader.js +154 -0
  3. package/.aios-core/data/learned-patterns.yaml +3 -0
  4. package/.aios-core/data/workflow-patterns.yaml +347 -3
  5. package/.aios-core/development/agents/dev.md +13 -0
  6. package/.aios-core/development/agents/squad-creator.md +30 -0
  7. package/.aios-core/development/scripts/squad/squad-analyzer.js +638 -0
  8. package/.aios-core/development/scripts/squad/squad-extender.js +871 -0
  9. package/.aios-core/development/scripts/squad/squad-generator.js +107 -19
  10. package/.aios-core/development/scripts/squad/squad-migrator.js +3 -5
  11. package/.aios-core/development/scripts/squad/squad-validator.js +98 -0
  12. package/.aios-core/development/tasks/create-service.md +391 -0
  13. package/.aios-core/development/tasks/next.md +294 -0
  14. package/.aios-core/development/tasks/patterns.md +334 -0
  15. package/.aios-core/development/tasks/squad-creator-analyze.md +315 -0
  16. package/.aios-core/development/tasks/squad-creator-create.md +26 -3
  17. package/.aios-core/development/tasks/squad-creator-extend.md +411 -0
  18. package/.aios-core/development/tasks/squad-creator-validate.md +9 -1
  19. package/.aios-core/development/tasks/waves.md +205 -0
  20. package/.aios-core/development/templates/service-template/README.md.hbs +158 -0
  21. package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -0
  22. package/.aios-core/development/templates/service-template/client.ts.hbs +403 -0
  23. package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -0
  24. package/.aios-core/development/templates/service-template/index.ts.hbs +120 -0
  25. package/.aios-core/development/templates/service-template/jest.config.js +89 -0
  26. package/.aios-core/development/templates/service-template/package.json.hbs +87 -0
  27. package/.aios-core/development/templates/service-template/tsconfig.json +45 -0
  28. package/.aios-core/development/templates/service-template/types.ts.hbs +145 -0
  29. package/.aios-core/development/templates/squad/agent-template.md +69 -0
  30. package/.aios-core/development/templates/squad/checklist-template.md +82 -0
  31. package/.aios-core/development/templates/squad/data-template.yaml +105 -0
  32. package/.aios-core/development/templates/squad/script-template.js +179 -0
  33. package/.aios-core/development/templates/squad/task-template.md +125 -0
  34. package/.aios-core/development/templates/squad/template-template.md +97 -0
  35. package/.aios-core/development/templates/squad/tool-template.js +103 -0
  36. package/.aios-core/development/templates/squad/workflow-template.yaml +108 -0
  37. package/.aios-core/infrastructure/scripts/ide-sync/agent-parser.js +45 -1
  38. package/.aios-core/infrastructure/scripts/ide-sync/transformers/antigravity.js +6 -6
  39. package/.aios-core/infrastructure/scripts/ide-sync/transformers/cursor.js +5 -4
  40. package/.aios-core/infrastructure/scripts/ide-sync/transformers/trae.js +3 -3
  41. package/.aios-core/infrastructure/scripts/ide-sync/transformers/windsurf.js +3 -3
  42. package/.aios-core/install-manifest.yaml +139 -35
  43. package/.aios-core/quality/metrics-collector.js +27 -0
  44. package/.aios-core/scripts/session-context-loader.js +13 -254
  45. package/.aios-core/utils/aios-validator.js +25 -0
  46. package/.aios-core/workflow-intelligence/__tests__/confidence-scorer.test.js +334 -0
  47. package/.aios-core/workflow-intelligence/__tests__/integration.test.js +337 -0
  48. package/.aios-core/workflow-intelligence/__tests__/suggestion-engine.test.js +431 -0
  49. package/.aios-core/workflow-intelligence/__tests__/wave-analyzer.test.js +458 -0
  50. package/.aios-core/workflow-intelligence/__tests__/workflow-registry.test.js +302 -0
  51. package/.aios-core/workflow-intelligence/engine/confidence-scorer.js +305 -0
  52. package/.aios-core/workflow-intelligence/engine/output-formatter.js +285 -0
  53. package/.aios-core/workflow-intelligence/engine/suggestion-engine.js +603 -0
  54. package/.aios-core/workflow-intelligence/engine/wave-analyzer.js +676 -0
  55. package/.aios-core/workflow-intelligence/index.js +327 -0
  56. package/.aios-core/workflow-intelligence/learning/capture-hook.js +147 -0
  57. package/.aios-core/workflow-intelligence/learning/index.js +230 -0
  58. package/.aios-core/workflow-intelligence/learning/pattern-capture.js +340 -0
  59. package/.aios-core/workflow-intelligence/learning/pattern-store.js +498 -0
  60. package/.aios-core/workflow-intelligence/learning/pattern-validator.js +309 -0
  61. package/.aios-core/workflow-intelligence/registry/workflow-registry.js +358 -0
  62. package/package.json +1 -1
@@ -0,0 +1,327 @@
1
+ /**
2
+ * @module workflow-intelligence
3
+ * @description Workflow Intelligence System (WIS) public API
4
+ * @story WIS-2 - Workflow Registry Enhancement
5
+ * @story WIS-4 - Wave Analysis Engine
6
+ * @version 1.1.0
7
+ *
8
+ * @example
9
+ * const wis = require('./.aios-core/workflow-intelligence');
10
+ *
11
+ * // Get workflow suggestions
12
+ * const suggestions = wis.getSuggestions({
13
+ * lastCommand: 'create-story',
14
+ * lastCommands: ['create-epic', 'create-story'],
15
+ * agentId: '@sm'
16
+ * });
17
+ *
18
+ * // Find matching workflow
19
+ * const workflow = wis.matchWorkflow(['create-epic', 'create-story']);
20
+ *
21
+ * // Get next steps for a state
22
+ * const nextSteps = wis.getNextSteps('epic_creation', 'stories_created');
23
+ *
24
+ * // Analyze waves for parallel execution (WIS-4)
25
+ * const waves = wis.analyzeWaves('story_development');
26
+ * console.log(waves.waves); // Wave groupings
27
+ * console.log(waves.criticalPath); // Critical path
28
+ */
29
+
30
+ 'use strict';
31
+
32
+ const {
33
+ WorkflowRegistry,
34
+ createWorkflowRegistry,
35
+ DEFAULT_CACHE_TTL,
36
+ DEFAULT_PATTERNS_PATH
37
+ } = require('./registry/workflow-registry');
38
+
39
+ const {
40
+ ConfidenceScorer,
41
+ createConfidenceScorer,
42
+ SCORING_WEIGHTS
43
+ } = require('./engine/confidence-scorer');
44
+
45
+ const {
46
+ SuggestionEngine,
47
+ createSuggestionEngine,
48
+ SUGGESTION_CACHE_TTL,
49
+ LOW_CONFIDENCE_THRESHOLD
50
+ } = require('./engine/suggestion-engine');
51
+
52
+ const {
53
+ WaveAnalyzer,
54
+ CircularDependencyError,
55
+ createWaveAnalyzer,
56
+ analyzeWaves,
57
+ DEFAULT_TASK_DURATIONS
58
+ } = require('./engine/wave-analyzer');
59
+
60
+ const outputFormatter = require('./engine/output-formatter');
61
+
62
+ // Learning module (WIS-5)
63
+ let learningModule = null;
64
+ try {
65
+ learningModule = require('./learning');
66
+ } catch (error) {
67
+ // Learning module not yet available
68
+ learningModule = null;
69
+ }
70
+
71
+ /**
72
+ * Singleton instances for default usage
73
+ */
74
+ let defaultRegistry = null;
75
+ let defaultScorer = null;
76
+
77
+ /**
78
+ * Get or create the default registry instance
79
+ * @returns {WorkflowRegistry} Default registry instance
80
+ */
81
+ function getDefaultRegistry() {
82
+ if (!defaultRegistry) {
83
+ defaultRegistry = createWorkflowRegistry();
84
+ }
85
+ return defaultRegistry;
86
+ }
87
+
88
+ /**
89
+ * Get or create the default scorer instance
90
+ * @returns {ConfidenceScorer} Default scorer instance
91
+ */
92
+ function getDefaultScorer() {
93
+ if (!defaultScorer) {
94
+ defaultScorer = createConfidenceScorer();
95
+ }
96
+ return defaultScorer;
97
+ }
98
+
99
+ /**
100
+ * Get workflow suggestions with confidence scores
101
+ * @param {Object} context - Current session context
102
+ * @param {string} context.lastCommand - Last executed command
103
+ * @param {string[]} context.lastCommands - Recent command history
104
+ * @param {string} context.agentId - Current active agent
105
+ * @param {Object} context.projectState - Current project state
106
+ * @returns {Object[]} Ranked suggestions with scores
107
+ */
108
+ function getSuggestions(context) {
109
+ if (!context) {
110
+ return [];
111
+ }
112
+
113
+ const registry = getDefaultRegistry();
114
+ const scorer = getDefaultScorer();
115
+
116
+ // Find matching workflow
117
+ const commands = context.lastCommands || (context.lastCommand ? [context.lastCommand] : []);
118
+ const match = registry.matchWorkflow(commands);
119
+
120
+ if (!match) {
121
+ return [];
122
+ }
123
+
124
+ // Find current state
125
+ const currentState = registry.findCurrentState(match.name, context.lastCommand);
126
+
127
+ if (!currentState) {
128
+ // Return first state's suggestions if we can't determine current state
129
+ const transitions = registry.getAllTransitions(match.name);
130
+ const firstState = Object.keys(transitions)[0];
131
+
132
+ if (!firstState) {
133
+ return [];
134
+ }
135
+
136
+ return formatSuggestions(
137
+ registry.getNextSteps(match.name, firstState),
138
+ match,
139
+ firstState,
140
+ scorer,
141
+ context
142
+ );
143
+ }
144
+
145
+ // Get next steps for current state
146
+ const nextSteps = registry.getNextSteps(match.name, currentState);
147
+
148
+ return formatSuggestions(nextSteps, match, currentState, scorer, context);
149
+ }
150
+
151
+ /**
152
+ * Format and score suggestions
153
+ * @param {Object[]} nextSteps - Raw next steps from registry
154
+ * @param {Object} match - Workflow match info
155
+ * @param {string} state - Current state
156
+ * @param {ConfidenceScorer} scorer - Scorer instance
157
+ * @param {Object} context - Session context
158
+ * @returns {Object[]} Formatted and scored suggestions
159
+ */
160
+ function formatSuggestions(nextSteps, match, state, scorer, context) {
161
+ if (!nextSteps || nextSteps.length === 0) {
162
+ return [];
163
+ }
164
+
165
+ const transition = getDefaultRegistry().getTransitions(match.name, state);
166
+ const baseConfidence = transition?.confidence || 0.5;
167
+
168
+ return nextSteps.map(step => {
169
+ const suggestion = {
170
+ command: step.command,
171
+ args_template: step.args_template,
172
+ description: step.description,
173
+ priority: step.priority,
174
+ workflow: match.name,
175
+ state: state,
176
+ trigger: transition?.trigger,
177
+ agentSequence: match.workflow.agent_sequence,
178
+ keyCommands: match.workflow.key_commands
179
+ };
180
+
181
+ // Calculate confidence score
182
+ const score = scorer.score(suggestion, context);
183
+
184
+ // Blend base confidence with calculated score
185
+ const finalScore = (baseConfidence * 0.4) + (score * 0.6);
186
+
187
+ return {
188
+ ...suggestion,
189
+ confidence: Math.round(finalScore * 100) / 100
190
+ };
191
+ }).sort((a, b) => b.confidence - a.confidence);
192
+ }
193
+
194
+ /**
195
+ * Match command history to a workflow
196
+ * @param {string[]} commands - Command history
197
+ * @returns {Object|null} Matching workflow or null
198
+ */
199
+ function matchWorkflow(commands) {
200
+ return getDefaultRegistry().matchWorkflow(commands);
201
+ }
202
+
203
+ /**
204
+ * Get next steps for a workflow state
205
+ * @param {string} workflowName - Workflow name
206
+ * @param {string} state - Current state
207
+ * @returns {Object[]} Next step suggestions
208
+ */
209
+ function getNextSteps(workflowName, state) {
210
+ return getDefaultRegistry().getNextSteps(workflowName, state);
211
+ }
212
+
213
+ /**
214
+ * Get transitions for a workflow state
215
+ * @param {string} workflowName - Workflow name
216
+ * @param {string} state - Current state
217
+ * @returns {Object|null} Transition or null
218
+ */
219
+ function getTransitions(workflowName, state) {
220
+ return getDefaultRegistry().getTransitions(workflowName, state);
221
+ }
222
+
223
+ /**
224
+ * Get a workflow by name
225
+ * @param {string} name - Workflow name
226
+ * @returns {Object|null} Workflow or null
227
+ */
228
+ function getWorkflow(name) {
229
+ return getDefaultRegistry().getWorkflow(name);
230
+ }
231
+
232
+ /**
233
+ * Get all workflow names
234
+ * @returns {string[]} Workflow names
235
+ */
236
+ function getWorkflowNames() {
237
+ return getDefaultRegistry().getWorkflowNames();
238
+ }
239
+
240
+ /**
241
+ * Get workflows by agent
242
+ * @param {string} agentId - Agent identifier
243
+ * @returns {Object[]} Workflows involving this agent
244
+ */
245
+ function getWorkflowsByAgent(agentId) {
246
+ return getDefaultRegistry().getWorkflowsByAgent(agentId);
247
+ }
248
+
249
+ /**
250
+ * Find current state based on last command
251
+ * @param {string} workflowName - Workflow name
252
+ * @param {string} lastCommand - Last command
253
+ * @returns {string|null} Current state or null
254
+ */
255
+ function findCurrentState(workflowName, lastCommand) {
256
+ return getDefaultRegistry().findCurrentState(workflowName, lastCommand);
257
+ }
258
+
259
+ /**
260
+ * Get registry statistics
261
+ * @returns {Object} Statistics
262
+ */
263
+ function getStats() {
264
+ return getDefaultRegistry().getStats();
265
+ }
266
+
267
+ /**
268
+ * Invalidate registry cache
269
+ */
270
+ function invalidateCache() {
271
+ if (defaultRegistry) {
272
+ defaultRegistry.invalidateCache();
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Reset singleton instances (for testing)
278
+ */
279
+ function reset() {
280
+ defaultRegistry = null;
281
+ defaultScorer = null;
282
+ }
283
+
284
+ module.exports = {
285
+ // High-level API
286
+ getSuggestions,
287
+ matchWorkflow,
288
+ getNextSteps,
289
+ getTransitions,
290
+ getWorkflow,
291
+ getWorkflowNames,
292
+ getWorkflowsByAgent,
293
+ findCurrentState,
294
+ getStats,
295
+ invalidateCache,
296
+ reset,
297
+
298
+ // Wave Analysis API (WIS-4)
299
+ analyzeWaves,
300
+ createWaveAnalyzer,
301
+
302
+ // Pattern Learning API (WIS-5)
303
+ learning: learningModule,
304
+
305
+ // Factory functions
306
+ createWorkflowRegistry,
307
+ createConfidenceScorer,
308
+ createSuggestionEngine,
309
+
310
+ // Classes (for advanced usage)
311
+ WorkflowRegistry,
312
+ ConfidenceScorer,
313
+ SuggestionEngine,
314
+ WaveAnalyzer,
315
+ CircularDependencyError,
316
+
317
+ // Output formatting (for *next task)
318
+ outputFormatter,
319
+
320
+ // Constants
321
+ SCORING_WEIGHTS,
322
+ DEFAULT_CACHE_TTL,
323
+ DEFAULT_PATTERNS_PATH,
324
+ SUGGESTION_CACHE_TTL,
325
+ LOW_CONFIDENCE_THRESHOLD,
326
+ DEFAULT_TASK_DURATIONS
327
+ };
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @module CaptureHook
3
+ * @description Task completion hook for pattern capture
4
+ * @story WIS-5 - Pattern Capture (Internal)
5
+ * @version 1.0.0
6
+ *
7
+ * @example
8
+ * // In task completion flow
9
+ * const { onTaskComplete } = require('./workflow-intelligence/learning/capture-hook');
10
+ * await onTaskComplete('develop', { sessionId: 'abc123', agentId: '@dev' });
11
+ */
12
+
13
+ 'use strict';
14
+
15
+ const { createPatternCapture } = require('./pattern-capture');
16
+ const { createPatternValidator } = require('./pattern-validator');
17
+ const { createPatternStore } = require('./pattern-store');
18
+
19
+ /**
20
+ * Singleton instances
21
+ */
22
+ let capture = null;
23
+ let validator = null;
24
+ let store = null;
25
+
26
+ /**
27
+ * Check if pattern capture is enabled
28
+ * @returns {boolean} True if enabled
29
+ */
30
+ function isEnabled() {
31
+ return process.env.AIOS_PATTERN_CAPTURE !== 'false';
32
+ }
33
+
34
+ /**
35
+ * Get or create singleton instances
36
+ */
37
+ function getInstances() {
38
+ if (!capture) {
39
+ capture = createPatternCapture();
40
+ }
41
+ if (!validator) {
42
+ validator = createPatternValidator();
43
+ }
44
+ if (!store) {
45
+ store = createPatternStore();
46
+ }
47
+ return { capture, validator, store };
48
+ }
49
+
50
+ /**
51
+ * Handle task completion event (non-blocking)
52
+ * @param {string} taskName - Name of completed task
53
+ * @param {Object} context - Task context
54
+ * @returns {Promise<Object>} Capture result
55
+ */
56
+ async function onTaskComplete(taskName, context = {}) {
57
+ if (!isEnabled()) {
58
+ return { success: false, reason: 'disabled' };
59
+ }
60
+
61
+ try {
62
+ const { capture: cap, validator: val, store: st } = getInstances();
63
+ const result = await cap.onTaskComplete(taskName, context);
64
+
65
+ if (result.captured && result.pattern) {
66
+ // Validate and store
67
+ const validation = val.validate(result.pattern);
68
+
69
+ if (validation.valid) {
70
+ st.save(result.pattern);
71
+ return {
72
+ success: true,
73
+ action: 'stored',
74
+ patternId: result.pattern.id
75
+ };
76
+ } else {
77
+ return {
78
+ success: false,
79
+ reason: 'validation_failed',
80
+ errors: validation.errors
81
+ };
82
+ }
83
+ }
84
+
85
+ return {
86
+ success: false,
87
+ reason: result.reason || 'not_captured'
88
+ };
89
+ } catch (error) {
90
+ // Silent failure - capture is non-critical
91
+ if (process.env.AIOS_DEBUG === 'true') {
92
+ console.debug('[PatternCapture] Hook failed:', error.message);
93
+ }
94
+ return {
95
+ success: false,
96
+ reason: 'error',
97
+ error: error.message
98
+ };
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Mark session as failed (for error handling)
104
+ * @param {string} sessionId - Session identifier
105
+ */
106
+ function markSessionFailed(sessionId) {
107
+ if (!isEnabled()) return;
108
+
109
+ try {
110
+ const { capture: cap } = getInstances();
111
+ cap.markSessionFailed(sessionId);
112
+ } catch (error) {
113
+ // Ignore errors
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Clear session buffer
119
+ * @param {string} sessionId - Optional session ID
120
+ */
121
+ function clearSession(sessionId) {
122
+ if (!isEnabled()) return;
123
+
124
+ try {
125
+ const { capture: cap } = getInstances();
126
+ cap.clearSession(sessionId);
127
+ } catch (error) {
128
+ // Ignore errors
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Reset singleton instances (for testing)
134
+ */
135
+ function reset() {
136
+ capture = null;
137
+ validator = null;
138
+ store = null;
139
+ }
140
+
141
+ module.exports = {
142
+ onTaskComplete,
143
+ markSessionFailed,
144
+ clearSession,
145
+ isEnabled,
146
+ reset
147
+ };
@@ -0,0 +1,230 @@
1
+ /**
2
+ * @module learning
3
+ * @description Pattern Learning module for Workflow Intelligence System
4
+ * @story WIS-5 - Pattern Capture (Internal)
5
+ * @version 1.0.0
6
+ *
7
+ * @example
8
+ * const learning = require('./.aios-core/workflow-intelligence/learning');
9
+ *
10
+ * // Capture a session pattern
11
+ * const capture = learning.createPatternCapture();
12
+ * const result = capture.captureSession({
13
+ * commands: ['validate-story-draft', 'develop', 'review-qa'],
14
+ * agentSequence: ['po', 'dev', 'qa'],
15
+ * success: true,
16
+ * timestamp: Date.now()
17
+ * });
18
+ *
19
+ * // Validate the pattern
20
+ * const validator = learning.createPatternValidator();
21
+ * const validation = validator.validate(result.pattern);
22
+ *
23
+ * // Store if valid
24
+ * if (validation.valid) {
25
+ * const store = learning.createPatternStore();
26
+ * store.save(result.pattern);
27
+ * }
28
+ */
29
+
30
+ 'use strict';
31
+
32
+ const {
33
+ PatternCapture,
34
+ createPatternCapture,
35
+ DEFAULT_MIN_SEQUENCE_LENGTH,
36
+ KEY_WORKFLOW_COMMANDS
37
+ } = require('./pattern-capture');
38
+
39
+ const {
40
+ PatternValidator,
41
+ createPatternValidator,
42
+ DEFAULT_VALIDATION_RULES,
43
+ KNOWN_COMMANDS
44
+ } = require('./pattern-validator');
45
+
46
+ const {
47
+ PatternStore,
48
+ createPatternStore,
49
+ DEFAULT_STORAGE_PATH,
50
+ DEFAULT_MAX_PATTERNS,
51
+ DEFAULT_PRUNE_THRESHOLD,
52
+ PATTERN_STATUS
53
+ } = require('./pattern-store');
54
+
55
+ /**
56
+ * Singleton instances for default usage
57
+ */
58
+ let defaultCapture = null;
59
+ let defaultValidator = null;
60
+ let defaultStore = null;
61
+
62
+ /**
63
+ * Get or create the default PatternCapture instance
64
+ * @returns {PatternCapture} Default capture instance
65
+ */
66
+ function getDefaultCapture() {
67
+ if (!defaultCapture) {
68
+ defaultCapture = createPatternCapture();
69
+ }
70
+ return defaultCapture;
71
+ }
72
+
73
+ /**
74
+ * Get or create the default PatternValidator instance
75
+ * @returns {PatternValidator} Default validator instance
76
+ */
77
+ function getDefaultValidator() {
78
+ if (!defaultValidator) {
79
+ defaultValidator = createPatternValidator();
80
+ }
81
+ return defaultValidator;
82
+ }
83
+
84
+ /**
85
+ * Get or create the default PatternStore instance
86
+ * @returns {PatternStore} Default store instance
87
+ */
88
+ function getDefaultStore() {
89
+ if (!defaultStore) {
90
+ defaultStore = createPatternStore();
91
+ }
92
+ return defaultStore;
93
+ }
94
+
95
+ /**
96
+ * Capture and store a pattern in one operation
97
+ * @param {Object} sessionData - Session data
98
+ * @returns {Object} Result with captured and stored status
99
+ */
100
+ function captureAndStore(sessionData) {
101
+ const capture = getDefaultCapture();
102
+ const validator = getDefaultValidator();
103
+ const store = getDefaultStore();
104
+
105
+ // Capture
106
+ const captureResult = capture.captureSession(sessionData);
107
+
108
+ if (!captureResult.valid) {
109
+ return {
110
+ success: false,
111
+ stage: 'capture',
112
+ reason: captureResult.reason
113
+ };
114
+ }
115
+
116
+ // Validate
117
+ const validation = validator.validate(captureResult.pattern);
118
+
119
+ if (!validation.valid) {
120
+ return {
121
+ success: false,
122
+ stage: 'validation',
123
+ reason: validation.reason,
124
+ errors: validation.errors
125
+ };
126
+ }
127
+
128
+ // Check for duplicates
129
+ const existingPatterns = store.load().patterns;
130
+ const duplicateCheck = validator.isDuplicate(captureResult.pattern, existingPatterns);
131
+
132
+ if (duplicateCheck.isDuplicate) {
133
+ // Update existing pattern instead
134
+ const existing = existingPatterns.find(p => p.id === duplicateCheck.duplicateOf);
135
+ if (existing) {
136
+ store.save(existing); // This will increment occurrences
137
+ return {
138
+ success: true,
139
+ action: 'merged',
140
+ patternId: existing.id
141
+ };
142
+ }
143
+ }
144
+
145
+ // Store
146
+ const storeResult = store.save(captureResult.pattern);
147
+
148
+ return {
149
+ success: true,
150
+ action: storeResult.action,
151
+ pattern: storeResult.pattern
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Get learned patterns for suggestions
157
+ * @param {Object} options - Options
158
+ * @param {boolean} options.activeOnly - Only return active/promoted patterns
159
+ * @returns {Object[]} Patterns
160
+ */
161
+ function getLearnedPatterns(options = {}) {
162
+ const store = getDefaultStore();
163
+
164
+ if (options.activeOnly) {
165
+ return store.getActivePatterns();
166
+ }
167
+
168
+ return store.load().patterns;
169
+ }
170
+
171
+ /**
172
+ * Find patterns matching a command sequence
173
+ * @param {string[]} sequence - Command sequence to match
174
+ * @returns {Object[]} Matching patterns
175
+ */
176
+ function findMatchingPatterns(sequence) {
177
+ const store = getDefaultStore();
178
+ return store.findSimilar(sequence);
179
+ }
180
+
181
+ /**
182
+ * Get pattern learning statistics
183
+ * @returns {Object} Statistics
184
+ */
185
+ function getStats() {
186
+ return getDefaultStore().getStats();
187
+ }
188
+
189
+ /**
190
+ * Reset singleton instances (for testing)
191
+ */
192
+ function reset() {
193
+ defaultCapture = null;
194
+ defaultValidator = null;
195
+ defaultStore = null;
196
+ }
197
+
198
+ module.exports = {
199
+ // High-level API
200
+ captureAndStore,
201
+ getLearnedPatterns,
202
+ findMatchingPatterns,
203
+ getStats,
204
+ reset,
205
+
206
+ // Singleton accessors
207
+ getDefaultCapture,
208
+ getDefaultValidator,
209
+ getDefaultStore,
210
+
211
+ // Factory functions
212
+ createPatternCapture,
213
+ createPatternValidator,
214
+ createPatternStore,
215
+
216
+ // Classes (for advanced usage)
217
+ PatternCapture,
218
+ PatternValidator,
219
+ PatternStore,
220
+
221
+ // Constants
222
+ DEFAULT_MIN_SEQUENCE_LENGTH,
223
+ KEY_WORKFLOW_COMMANDS,
224
+ DEFAULT_VALIDATION_RULES,
225
+ KNOWN_COMMANDS,
226
+ DEFAULT_STORAGE_PATH,
227
+ DEFAULT_MAX_PATTERNS,
228
+ DEFAULT_PRUNE_THRESHOLD,
229
+ PATTERN_STATUS
230
+ };