aios-core 3.7.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 (47) 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 +6 -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/next.md +294 -0
  13. package/.aios-core/development/tasks/patterns.md +334 -0
  14. package/.aios-core/development/tasks/squad-creator-analyze.md +315 -0
  15. package/.aios-core/development/tasks/squad-creator-create.md +26 -3
  16. package/.aios-core/development/tasks/squad-creator-extend.md +411 -0
  17. package/.aios-core/development/tasks/squad-creator-validate.md +9 -1
  18. package/.aios-core/development/tasks/waves.md +205 -0
  19. package/.aios-core/development/templates/squad/agent-template.md +69 -0
  20. package/.aios-core/development/templates/squad/checklist-template.md +82 -0
  21. package/.aios-core/development/templates/squad/data-template.yaml +105 -0
  22. package/.aios-core/development/templates/squad/script-template.js +179 -0
  23. package/.aios-core/development/templates/squad/task-template.md +125 -0
  24. package/.aios-core/development/templates/squad/template-template.md +97 -0
  25. package/.aios-core/development/templates/squad/tool-template.js +103 -0
  26. package/.aios-core/development/templates/squad/workflow-template.yaml +108 -0
  27. package/.aios-core/install-manifest.yaml +89 -25
  28. package/.aios-core/quality/metrics-collector.js +27 -0
  29. package/.aios-core/scripts/session-context-loader.js +13 -254
  30. package/.aios-core/utils/aios-validator.js +25 -0
  31. package/.aios-core/workflow-intelligence/__tests__/confidence-scorer.test.js +334 -0
  32. package/.aios-core/workflow-intelligence/__tests__/integration.test.js +337 -0
  33. package/.aios-core/workflow-intelligence/__tests__/suggestion-engine.test.js +431 -0
  34. package/.aios-core/workflow-intelligence/__tests__/wave-analyzer.test.js +458 -0
  35. package/.aios-core/workflow-intelligence/__tests__/workflow-registry.test.js +302 -0
  36. package/.aios-core/workflow-intelligence/engine/confidence-scorer.js +305 -0
  37. package/.aios-core/workflow-intelligence/engine/output-formatter.js +285 -0
  38. package/.aios-core/workflow-intelligence/engine/suggestion-engine.js +603 -0
  39. package/.aios-core/workflow-intelligence/engine/wave-analyzer.js +676 -0
  40. package/.aios-core/workflow-intelligence/index.js +327 -0
  41. package/.aios-core/workflow-intelligence/learning/capture-hook.js +147 -0
  42. package/.aios-core/workflow-intelligence/learning/index.js +230 -0
  43. package/.aios-core/workflow-intelligence/learning/pattern-capture.js +340 -0
  44. package/.aios-core/workflow-intelligence/learning/pattern-store.js +498 -0
  45. package/.aios-core/workflow-intelligence/learning/pattern-validator.js +309 -0
  46. package/.aios-core/workflow-intelligence/registry/workflow-registry.js +358 -0
  47. package/package.json +1 -1
@@ -0,0 +1,340 @@
1
+ /**
2
+ * @module PatternCapture
3
+ * @description Captures workflow patterns from user sessions
4
+ * @story WIS-5 - Pattern Capture (Internal)
5
+ * @version 1.0.0
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ const crypto = require('crypto');
11
+
12
+ /**
13
+ * Default minimum sequence length for pattern capture
14
+ * @type {number}
15
+ */
16
+ const DEFAULT_MIN_SEQUENCE_LENGTH = 3;
17
+
18
+ /**
19
+ * Key workflow commands that trigger pattern capture
20
+ * @type {string[]}
21
+ */
22
+ const KEY_WORKFLOW_COMMANDS = [
23
+ 'develop',
24
+ 'review-qa',
25
+ 'apply-qa-fixes',
26
+ 'validate-story-draft',
27
+ 'create-story',
28
+ 'create-next-story',
29
+ 'run-tests',
30
+ 'create-pr'
31
+ ];
32
+
33
+ /**
34
+ * PatternCapture class for capturing workflow patterns from sessions
35
+ */
36
+ class PatternCapture {
37
+ /**
38
+ * Create a PatternCapture instance
39
+ * @param {Object} options - Configuration options
40
+ * @param {number} options.minSequenceLength - Minimum sequence length (default: 3)
41
+ * @param {string[]} options.keyCommands - Commands that trigger capture
42
+ * @param {boolean} options.enabled - Whether capture is enabled
43
+ */
44
+ constructor(options = {}) {
45
+ this.minSequenceLength = options.minSequenceLength || DEFAULT_MIN_SEQUENCE_LENGTH;
46
+ this.keyCommands = options.keyCommands || KEY_WORKFLOW_COMMANDS;
47
+ this.enabled = options.enabled !== false && process.env.AIOS_PATTERN_CAPTURE !== 'false';
48
+ this.sessionBuffer = new Map(); // Track ongoing sessions
49
+ }
50
+
51
+ /**
52
+ * Capture a completed session as a pattern
53
+ * @param {Object} sessionData - Session data to capture
54
+ * @param {string[]} sessionData.agentSequence - Sequence of agents used
55
+ * @param {string[]} sessionData.commands - Sequence of commands executed
56
+ * @param {boolean} sessionData.success - Whether workflow completed successfully
57
+ * @param {number} sessionData.timestamp - Session timestamp
58
+ * @param {string} sessionData.sessionId - Unique session identifier
59
+ * @returns {Object} Captured pattern with validity info
60
+ */
61
+ captureSession(sessionData) {
62
+ if (!this.enabled) {
63
+ return { valid: false, reason: 'Pattern capture disabled' };
64
+ }
65
+
66
+ if (!sessionData || !sessionData.commands) {
67
+ return { valid: false, reason: 'Invalid session data' };
68
+ }
69
+
70
+ // Only capture successful workflows
71
+ if (!sessionData.success) {
72
+ return { valid: false, reason: 'Workflow not successful' };
73
+ }
74
+
75
+ // Check minimum sequence length
76
+ if (sessionData.commands.length < this.minSequenceLength) {
77
+ return {
78
+ valid: false,
79
+ reason: `Sequence too short (${sessionData.commands.length} < ${this.minSequenceLength})`
80
+ };
81
+ }
82
+
83
+ // Extract normalized command sequence
84
+ const sequence = this._normalizeCommands(sessionData.commands);
85
+ const agents = this._normalizeAgents(sessionData.agentSequence || []);
86
+
87
+ // Build pattern object
88
+ const pattern = {
89
+ id: crypto.randomUUID(),
90
+ sequence: sequence,
91
+ agents: agents,
92
+ occurrences: 1,
93
+ successRate: 1.0,
94
+ firstSeen: new Date(sessionData.timestamp || Date.now()).toISOString(),
95
+ lastSeen: new Date(sessionData.timestamp || Date.now()).toISOString(),
96
+ sessionId: sessionData.sessionId || crypto.randomUUID(),
97
+ workflow: this._detectWorkflow(sequence),
98
+ status: 'pending'
99
+ };
100
+
101
+ return {
102
+ valid: true,
103
+ pattern: pattern,
104
+ sequence: sequence
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Extract pattern candidates from command history
110
+ * @param {string[]} commandHistory - Full command history
111
+ * @returns {Object[]} Array of pattern candidates
112
+ */
113
+ extractPatterns(commandHistory) {
114
+ if (!commandHistory || commandHistory.length < this.minSequenceLength) {
115
+ return [];
116
+ }
117
+
118
+ const patterns = [];
119
+ const normalized = this._normalizeCommands(commandHistory);
120
+
121
+ // Use sliding window to find subsequences
122
+ for (let length = this.minSequenceLength; length <= Math.min(normalized.length, 7); length++) {
123
+ for (let i = 0; i <= normalized.length - length; i++) {
124
+ const subsequence = normalized.slice(i, i + length);
125
+
126
+ // Only include if it contains at least one key command
127
+ if (this._containsKeyCommand(subsequence)) {
128
+ patterns.push({
129
+ sequence: subsequence,
130
+ startIndex: i,
131
+ length: length
132
+ });
133
+ }
134
+ }
135
+ }
136
+
137
+ return patterns;
138
+ }
139
+
140
+ /**
141
+ * Get the minimum sequence length setting
142
+ * @returns {number} Minimum sequence length
143
+ */
144
+ getMinimumSequenceLength() {
145
+ return this.minSequenceLength;
146
+ }
147
+
148
+ /**
149
+ * Handle task completion event
150
+ * @param {string} taskName - Name of completed task
151
+ * @param {Object} context - Task context
152
+ * @returns {Promise<Object>} Capture result
153
+ */
154
+ async onTaskComplete(taskName, context) {
155
+ if (!this.enabled) {
156
+ return { captured: false, reason: 'disabled' };
157
+ }
158
+
159
+ const sessionId = context.sessionId || 'default';
160
+
161
+ // Get or create session buffer
162
+ if (!this.sessionBuffer.has(sessionId)) {
163
+ this.sessionBuffer.set(sessionId, {
164
+ commands: [],
165
+ agents: [],
166
+ startTime: Date.now(),
167
+ success: true
168
+ });
169
+ }
170
+
171
+ const session = this.sessionBuffer.get(sessionId);
172
+
173
+ // Add command to buffer
174
+ const normalizedTask = this._normalizeCommand(taskName);
175
+ session.commands.push(normalizedTask);
176
+
177
+ // Track agent if provided
178
+ if (context.agentId) {
179
+ const normalizedAgent = context.agentId.replace('@', '');
180
+ if (!session.agents.includes(normalizedAgent)) {
181
+ session.agents.push(normalizedAgent);
182
+ }
183
+ }
184
+
185
+ // Check if this is a workflow-ending command
186
+ if (this._isWorkflowEnd(normalizedTask)) {
187
+ const result = this.captureSession({
188
+ commands: session.commands,
189
+ agentSequence: session.agents,
190
+ success: session.success,
191
+ timestamp: Date.now(),
192
+ sessionId: sessionId
193
+ });
194
+
195
+ // Clear session buffer
196
+ this.sessionBuffer.delete(sessionId);
197
+
198
+ return {
199
+ captured: result.valid,
200
+ pattern: result.pattern,
201
+ reason: result.reason
202
+ };
203
+ }
204
+
205
+ return { captured: false, reason: 'workflow_in_progress' };
206
+ }
207
+
208
+ /**
209
+ * Mark current session as failed
210
+ * @param {string} sessionId - Session identifier
211
+ */
212
+ markSessionFailed(sessionId) {
213
+ const session = this.sessionBuffer.get(sessionId || 'default');
214
+ if (session) {
215
+ session.success = false;
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Clear session buffer
221
+ * @param {string} sessionId - Session identifier (optional, clears all if not provided)
222
+ */
223
+ clearSession(sessionId) {
224
+ if (sessionId) {
225
+ this.sessionBuffer.delete(sessionId);
226
+ } else {
227
+ this.sessionBuffer.clear();
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Normalize command name
233
+ * @param {string} command - Command to normalize
234
+ * @returns {string} Normalized command
235
+ * @private
236
+ */
237
+ _normalizeCommand(command) {
238
+ if (!command) return '';
239
+ return command
240
+ .replace(/^\*/, '') // Remove * prefix
241
+ .replace(/-/g, '-') // Keep hyphens
242
+ .toLowerCase()
243
+ .trim();
244
+ }
245
+
246
+ /**
247
+ * Normalize array of commands
248
+ * @param {string[]} commands - Commands to normalize
249
+ * @returns {string[]} Normalized commands
250
+ * @private
251
+ */
252
+ _normalizeCommands(commands) {
253
+ return commands
254
+ .map(cmd => this._normalizeCommand(cmd))
255
+ .filter(cmd => cmd.length > 0);
256
+ }
257
+
258
+ /**
259
+ * Normalize array of agent IDs
260
+ * @param {string[]} agents - Agent IDs to normalize
261
+ * @returns {string[]} Normalized agent IDs
262
+ * @private
263
+ */
264
+ _normalizeAgents(agents) {
265
+ return agents
266
+ .map(agent => agent.replace('@', '').toLowerCase().trim())
267
+ .filter(agent => agent.length > 0);
268
+ }
269
+
270
+ /**
271
+ * Check if sequence contains at least one key workflow command
272
+ * @param {string[]} sequence - Command sequence
273
+ * @returns {boolean} True if contains key command
274
+ * @private
275
+ */
276
+ _containsKeyCommand(sequence) {
277
+ return sequence.some(cmd =>
278
+ this.keyCommands.some(key => cmd.includes(key))
279
+ );
280
+ }
281
+
282
+ /**
283
+ * Detect workflow type from command sequence
284
+ * @param {string[]} sequence - Command sequence
285
+ * @returns {string|null} Detected workflow name or null
286
+ * @private
287
+ */
288
+ _detectWorkflow(sequence) {
289
+ const joined = sequence.join(' ');
290
+
291
+ if (joined.includes('develop') && (joined.includes('review-qa') || joined.includes('qa'))) {
292
+ return 'story_development';
293
+ }
294
+ if (joined.includes('create-story') || joined.includes('validate-story')) {
295
+ return 'story_creation';
296
+ }
297
+ if (joined.includes('create-epic')) {
298
+ return 'epic_creation';
299
+ }
300
+ if (joined.includes('create-pr') || joined.includes('push')) {
301
+ return 'deployment';
302
+ }
303
+
304
+ return null;
305
+ }
306
+
307
+ /**
308
+ * Check if command indicates end of workflow
309
+ * @param {string} command - Command to check
310
+ * @returns {boolean} True if workflow-ending command
311
+ * @private
312
+ */
313
+ _isWorkflowEnd(command) {
314
+ const endCommands = [
315
+ 'create-pr',
316
+ 'push',
317
+ 'deploy',
318
+ 'complete',
319
+ 'done',
320
+ 'finish'
321
+ ];
322
+ return endCommands.some(end => command.includes(end));
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Create a new PatternCapture instance
328
+ * @param {Object} options - Configuration options
329
+ * @returns {PatternCapture} New instance
330
+ */
331
+ function createPatternCapture(options = {}) {
332
+ return new PatternCapture(options);
333
+ }
334
+
335
+ module.exports = {
336
+ PatternCapture,
337
+ createPatternCapture,
338
+ DEFAULT_MIN_SEQUENCE_LENGTH,
339
+ KEY_WORKFLOW_COMMANDS
340
+ };