aios-core 4.1.0 → 4.2.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 (145) hide show
  1. package/.aios-core/.session/current-session.json +14 -0
  2. package/.aios-core/core/registry/registry-schema.json +166 -166
  3. package/.aios-core/core/registry/service-registry.json +6585 -6585
  4. package/.aios-core/data/entity-registry.yaml +208 -8
  5. package/.aios-core/data/registry-update-log.jsonl +165 -0
  6. package/.aios-core/development/scripts/approval-workflow.js +642 -642
  7. package/.aios-core/development/scripts/backup-manager.js +606 -606
  8. package/.aios-core/development/scripts/branch-manager.js +389 -389
  9. package/.aios-core/development/scripts/code-quality-improver.js +1311 -1311
  10. package/.aios-core/development/scripts/commit-message-generator.js +849 -849
  11. package/.aios-core/development/scripts/conflict-resolver.js +674 -674
  12. package/.aios-core/development/scripts/dependency-analyzer.js +637 -637
  13. package/.aios-core/development/scripts/diff-generator.js +351 -351
  14. package/.aios-core/development/scripts/elicitation-engine.js +384 -384
  15. package/.aios-core/development/scripts/elicitation-session-manager.js +299 -299
  16. package/.aios-core/development/scripts/git-wrapper.js +461 -461
  17. package/.aios-core/development/scripts/manifest-preview.js +244 -244
  18. package/.aios-core/development/scripts/metrics-tracker.js +775 -775
  19. package/.aios-core/development/scripts/modification-validator.js +554 -554
  20. package/.aios-core/development/scripts/pattern-learner.js +1224 -1224
  21. package/.aios-core/development/scripts/performance-analyzer.js +757 -757
  22. package/.aios-core/development/scripts/refactoring-suggester.js +1138 -1138
  23. package/.aios-core/development/scripts/rollback-handler.js +530 -530
  24. package/.aios-core/development/scripts/security-checker.js +358 -358
  25. package/.aios-core/development/scripts/template-engine.js +239 -239
  26. package/.aios-core/development/scripts/template-validator.js +278 -278
  27. package/.aios-core/development/scripts/test-generator.js +843 -843
  28. package/.aios-core/development/scripts/transaction-manager.js +589 -589
  29. package/.aios-core/development/scripts/usage-tracker.js +673 -673
  30. package/.aios-core/development/scripts/validate-filenames.js +226 -226
  31. package/.aios-core/development/scripts/version-tracker.js +526 -526
  32. package/.aios-core/development/scripts/yaml-validator.js +396 -396
  33. package/.aios-core/development/tasks/validate-next-story.md +99 -2
  34. package/.aios-core/development/templates/service-template/README.md.hbs +158 -158
  35. package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -237
  36. package/.aios-core/development/templates/service-template/client.ts.hbs +403 -403
  37. package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -182
  38. package/.aios-core/development/templates/service-template/index.ts.hbs +120 -120
  39. package/.aios-core/development/templates/service-template/package.json.hbs +87 -87
  40. package/.aios-core/development/templates/service-template/types.ts.hbs +145 -145
  41. package/.aios-core/development/templates/squad-template/LICENSE +21 -21
  42. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +335 -0
  43. package/.aios-core/docs/component-creation-guide.md +458 -0
  44. package/.aios-core/docs/session-update-pattern.md +307 -0
  45. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +1963 -0
  46. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +1190 -0
  47. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +439 -0
  48. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +5398 -0
  49. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +523 -0
  50. package/.aios-core/docs/template-syntax.md +267 -0
  51. package/.aios-core/docs/troubleshooting-guide.md +625 -0
  52. package/.aios-core/infrastructure/templates/aios-sync.yaml.template +193 -193
  53. package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
  54. package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
  55. package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
  56. package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
  57. package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
  58. package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
  59. package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
  60. package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
  61. package/.aios-core/infrastructure/tests/utilities-audit-results.json +501 -0
  62. package/.aios-core/install-manifest.yaml +101 -101
  63. package/.aios-core/local-config.yaml.template +70 -70
  64. package/.aios-core/manifests/agents.csv +29 -0
  65. package/.aios-core/manifests/schema/manifest-schema.json +190 -190
  66. package/.aios-core/manifests/tasks.csv +198 -0
  67. package/.aios-core/manifests/workers.csv +204 -0
  68. package/.aios-core/monitor/hooks/lib/__init__.py +1 -1
  69. package/.aios-core/monitor/hooks/lib/enrich.py +58 -58
  70. package/.aios-core/monitor/hooks/lib/send_event.py +47 -47
  71. package/.aios-core/monitor/hooks/notification.py +29 -29
  72. package/.aios-core/monitor/hooks/post_tool_use.py +45 -45
  73. package/.aios-core/monitor/hooks/pre_compact.py +29 -29
  74. package/.aios-core/monitor/hooks/pre_tool_use.py +40 -40
  75. package/.aios-core/monitor/hooks/stop.py +29 -29
  76. package/.aios-core/monitor/hooks/subagent_stop.py +29 -29
  77. package/.aios-core/monitor/hooks/user_prompt_submit.py +38 -38
  78. package/.aios-core/product/templates/adr.hbs +125 -125
  79. package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
  80. package/.aios-core/product/templates/dbdr.hbs +241 -241
  81. package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
  82. package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
  83. package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
  84. package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
  85. package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
  86. package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
  87. package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
  88. package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
  89. package/.aios-core/product/templates/epic.hbs +212 -212
  90. package/.aios-core/product/templates/eslintrc-security.json +32 -32
  91. package/.aios-core/product/templates/github-actions-cd.yml +212 -212
  92. package/.aios-core/product/templates/github-actions-ci.yml +172 -172
  93. package/.aios-core/product/templates/pmdr.hbs +186 -186
  94. package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
  95. package/.aios-core/product/templates/prd.hbs +201 -201
  96. package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
  97. package/.aios-core/product/templates/story.hbs +263 -263
  98. package/.aios-core/product/templates/task.hbs +170 -170
  99. package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
  100. package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
  101. package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
  102. package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
  103. package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
  104. package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
  105. package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
  106. package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
  107. package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
  108. package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
  109. package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
  110. package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
  111. package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
  112. package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
  113. package/.aios-core/product/templates/tmpl-view.sql +177 -177
  114. package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
  115. package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
  116. package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
  117. package/.aios-core/scripts/pm.sh +0 -0
  118. package/.claude/hooks/enforce-architecture-first.py +196 -196
  119. package/.claude/hooks/mind-clone-governance.py +192 -192
  120. package/.claude/hooks/read-protection.py +151 -151
  121. package/.claude/hooks/slug-validation.py +176 -176
  122. package/.claude/hooks/sql-governance.py +182 -182
  123. package/.claude/hooks/write-path-validation.py +194 -194
  124. package/.claude/rules/agent-authority.md +105 -0
  125. package/.claude/rules/coderabbit-integration.md +93 -0
  126. package/.claude/rules/ids-principles.md +112 -0
  127. package/.claude/rules/story-lifecycle.md +139 -0
  128. package/.claude/rules/workflow-execution.md +150 -0
  129. package/LICENSE +48 -48
  130. package/bin/aios-minimal.js +0 -0
  131. package/bin/aios.js +0 -0
  132. package/package.json +1 -1
  133. package/packages/aios-install/bin/aios-install.js +0 -0
  134. package/packages/aios-install/bin/edmcp.js +0 -0
  135. package/packages/aios-pro-cli/bin/aios-pro.js +0 -0
  136. package/packages/installer/src/wizard/pro-setup.js +433 -49
  137. package/scripts/check-markdown-links.py +352 -352
  138. package/scripts/code-intel-health-check.js +343 -0
  139. package/scripts/dashboard-parallel-dev.sh +0 -0
  140. package/scripts/dashboard-parallel-phase3.sh +0 -0
  141. package/scripts/dashboard-parallel-phase4.sh +0 -0
  142. package/scripts/glue/README.md +355 -0
  143. package/scripts/glue/compose-agent-prompt.cjs +362 -0
  144. package/scripts/install-monitor-hooks.sh +0 -0
  145. package/.aios-core/lib/build.json +0 -1
@@ -1,638 +1,638 @@
1
- /**
2
- * Dependency Analyzer for AIOS-FULLSTACK
3
- * Analyzes and resolves dependencies between components
4
- * @module dependency-analyzer
5
- */
6
-
7
- const fs = require('fs-extra');
8
- const path = require('path');
9
- const _yaml = require('js-yaml');
10
- const chalk = require('chalk');
11
-
12
- class DependencyAnalyzer {
13
- constructor(options = {}) {
14
- this.rootPath = options.rootPath || process.cwd();
15
- this.manifestPath = path.join(this.rootPath, 'aios-core', 'team-manifest.yaml');
16
-
17
- // Component paths
18
- this.paths = {
19
- agents: path.join(this.rootPath, 'aios-core', 'agents'),
20
- tasks: path.join(this.rootPath, 'aios-core', 'tasks'),
21
- workflows: path.join(this.rootPath, 'aios-core', 'workflows')
22
- };
23
-
24
- // Dependency cache
25
- this.dependencyCache = new Map();
26
- }
27
-
28
- /**
29
- * Analyze dependencies for a component
30
- * @param {string} componentType - Type of component (agent/task/workflow)
31
- * @param {Object} componentData - Component configuration data
32
- * @returns {Promise<Object>} Dependency analysis result
33
- */
34
- async analyzeDependencies(componentType, componentData) {
35
- const dependencies = {
36
- required: [],
37
- optional: [],
38
- missing: [],
39
- circular: false,
40
- graph: new Map()
41
- };
42
-
43
- switch (componentType) {
44
- case 'agent':
45
- await this.analyzeAgentDependencies(componentData, dependencies);
46
- break;
47
- case 'task':
48
- await this.analyzeTaskDependencies(componentData, dependencies);
49
- break;
50
- case 'workflow':
51
- await this.analyzeWorkflowDependencies(componentData, dependencies);
52
- break;
53
- }
54
-
55
- // Check for circular dependencies
56
- dependencies.circular = this.detectCircularDependencies(dependencies.graph);
57
-
58
- return dependencies;
59
- }
60
-
61
- /**
62
- * Analyze agent dependencies
63
- * @private
64
- */
65
- async analyzeAgentDependencies(agentData, dependencies) {
66
- // Check for task dependencies from commands
67
- if (agentData.commands && Array.isArray(agentData.commands)) {
68
- for (const command of agentData.commands) {
69
- const taskId = this.commandToTaskId(command);
70
- const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
71
-
72
- if (await fs.pathExists(taskPath)) {
73
- dependencies.required.push({
74
- type: 'task',
75
- id: taskId,
76
- path: taskPath,
77
- reason: `Command '${command}' requires task`
78
- });
79
- } else {
80
- dependencies.missing.push({
81
- type: 'task',
82
- id: taskId,
83
- reason: `Command '${command}' requires task file`
84
- });
85
- }
86
- }
87
- }
88
-
89
- // Check for workflow dependencies
90
- if (agentData.workflows && Array.isArray(agentData.workflows)) {
91
- for (const workflowId of agentData.workflows) {
92
- const workflowPath = path.join(this.paths.workflows, `${workflowId}.yaml`);
93
-
94
- if (await fs.pathExists(workflowPath)) {
95
- dependencies.optional.push({
96
- type: 'workflow',
97
- id: workflowId,
98
- path: workflowPath,
99
- reason: 'Agent workflow reference'
100
- });
101
- }
102
- }
103
- }
104
-
105
- // Check for agent dependencies
106
- if (agentData.dependencies?.agents) {
107
- for (const agentId of agentData.dependencies.agents) {
108
- const agentPath = path.join(this.paths.agents, `${agentId}.md`);
109
-
110
- if (await fs.pathExists(agentPath)) {
111
- dependencies.required.push({
112
- type: 'agent',
113
- id: agentId,
114
- path: agentPath,
115
- reason: 'Explicit agent dependency'
116
- });
117
- } else {
118
- dependencies.missing.push({
119
- type: 'agent',
120
- id: agentId,
121
- reason: 'Required agent not found'
122
- });
123
- }
124
- }
125
- }
126
- }
127
-
128
- /**
129
- * Analyze task dependencies
130
- * @private
131
- */
132
- async analyzeTaskDependencies(taskData, dependencies) {
133
- // Check for agent dependency
134
- if (taskData.agentName) {
135
- const agentPath = path.join(this.paths.agents, `${taskData.agentName}.md`);
136
-
137
- if (await fs.pathExists(agentPath)) {
138
- dependencies.required.push({
139
- type: 'agent',
140
- id: taskData.agentName,
141
- path: agentPath,
142
- reason: 'Task belongs to agent'
143
- });
144
- } else {
145
- dependencies.missing.push({
146
- type: 'agent',
147
- id: taskData.agentName,
148
- reason: 'Agent not found for task'
149
- });
150
- }
151
- }
152
-
153
- // Check for other task dependencies
154
- if (taskData.dependencies?.tasks) {
155
- for (const taskId of taskData.dependencies.tasks) {
156
- const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
157
-
158
- if (await fs.pathExists(taskPath)) {
159
- dependencies.required.push({
160
- type: 'task',
161
- id: taskId,
162
- path: taskPath,
163
- reason: 'Task dependency'
164
- });
165
- } else {
166
- dependencies.missing.push({
167
- type: 'task',
168
- id: taskId,
169
- reason: 'Required task not found'
170
- });
171
- }
172
- }
173
- }
174
- }
175
-
176
- /**
177
- * Analyze workflow dependencies
178
- * @private
179
- */
180
- async analyzeWorkflowDependencies(workflowData, dependencies) {
181
- // Extract task references from workflow steps
182
- const taskIds = new Set();
183
-
184
- if (workflowData.steps && Array.isArray(workflowData.steps)) {
185
- for (const step of workflowData.steps) {
186
- if (step.type === 'task' && step.taskId) {
187
- taskIds.add(step.taskId);
188
- } else if (step.action?.includes('task:')) {
189
- const taskMatch = step.action.match(/task:([a-z0-9-]+)/);
190
- if (taskMatch) {
191
- taskIds.add(taskMatch[1]);
192
- }
193
- }
194
- }
195
- }
196
-
197
- // Check each task dependency
198
- for (const taskId of taskIds) {
199
- const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
200
-
201
- if (await fs.pathExists(taskPath)) {
202
- dependencies.required.push({
203
- type: 'task',
204
- id: taskId,
205
- path: taskPath,
206
- reason: 'Workflow step requires task'
207
- });
208
-
209
- // Also check the task's agent dependency
210
- const taskContent = await fs.readFile(taskPath, 'utf8');
211
- const agentMatch = taskContent.match(/\*\*Agent:\*\*\s*([a-z0-9-]+)/);
212
- if (agentMatch) {
213
- const agentId = agentMatch[1];
214
- const agentPath = path.join(this.paths.agents, `${agentId}.md`);
215
-
216
- if (await fs.pathExists(agentPath)) {
217
- dependencies.required.push({
218
- type: 'agent',
219
- id: agentId,
220
- path: agentPath,
221
- reason: 'Task requires agent'
222
- });
223
- }
224
- }
225
- } else {
226
- dependencies.missing.push({
227
- type: 'task',
228
- id: taskId,
229
- reason: 'Workflow step requires task'
230
- });
231
- }
232
- }
233
-
234
- // Check for sub-workflow dependencies
235
- if (workflowData.dependencies?.workflows) {
236
- for (const workflowId of workflowData.dependencies.workflows) {
237
- const workflowPath = path.join(this.paths.workflows, `${workflowId}.yaml`);
238
-
239
- if (await fs.pathExists(workflowPath)) {
240
- dependencies.required.push({
241
- type: 'workflow',
242
- id: workflowId,
243
- path: workflowPath,
244
- reason: 'Sub-workflow dependency'
245
- });
246
- } else {
247
- dependencies.missing.push({
248
- type: 'workflow',
249
- id: workflowId,
250
- reason: 'Required workflow not found'
251
- });
252
- }
253
- }
254
- }
255
- }
256
-
257
- /**
258
- * Convert command name to task ID
259
- * @private
260
- */
261
- commandToTaskId(command) {
262
- // Remove asterisk if present
263
- const cleanCommand = command.replace(/^\*/, '');
264
-
265
- // Handle common patterns
266
- if (cleanCommand.startsWith('create-')) {
267
- return cleanCommand;
268
- }
269
-
270
- // Convert to task ID format
271
- return cleanCommand.replace(/([A-Z])/g, '-$1').toLowerCase();
272
- }
273
-
274
- /**
275
- * Detect circular dependencies
276
- * @private
277
- */
278
- detectCircularDependencies(graph) {
279
- const visited = new Set();
280
- const recursionStack = new Set();
281
-
282
- const hasCycle = (node, path = []) => {
283
- if (recursionStack.has(node)) {
284
- console.log(chalk.red(`\n⚠️ Circular dependency detected: ${[...path, node].join(' → ')}`));
285
- return true;
286
- }
287
-
288
- if (visited.has(node)) {
289
- return false;
290
- }
291
-
292
- visited.add(node);
293
- recursionStack.add(node);
294
-
295
- const neighbors = graph.get(node) || [];
296
- for (const neighbor of neighbors) {
297
- if (hasCycle(neighbor, [...path, node])) {
298
- return true;
299
- }
300
- }
301
-
302
- recursionStack.delete(node);
303
- return false;
304
- };
305
-
306
- for (const node of graph.keys()) {
307
- if (hasCycle(node)) {
308
- return true;
309
- }
310
- }
311
-
312
- return false;
313
- }
314
-
315
- /**
316
- * Validate all dependencies exist
317
- * @param {Array} components - Components to validate
318
- * @returns {Promise<Object>} Validation result
319
- */
320
- async validateDependencies(components) {
321
- const results = {
322
- valid: true,
323
- issues: [],
324
- resolutions: []
325
- };
326
-
327
- for (const component of components) {
328
- const deps = await this.analyzeDependencies(component.type, component.config);
329
-
330
- if (deps.missing.length > 0) {
331
- results.valid = false;
332
- results.issues.push({
333
- component: component.config.name || component.config.id,
334
- missing: deps.missing
335
- });
336
-
337
- // Suggest resolutions
338
- for (const missing of deps.missing) {
339
- results.resolutions.push({
340
- action: 'create',
341
- type: missing.type,
342
- id: missing.id,
343
- reason: missing.reason
344
- });
345
- }
346
- }
347
-
348
- if (deps.circular) {
349
- results.valid = false;
350
- results.issues.push({
351
- component: component.config.name || component.config.id,
352
- issue: 'Circular dependency detected'
353
- });
354
- }
355
- }
356
-
357
- return results;
358
- }
359
-
360
- /**
361
- * Get creation order for components based on dependencies
362
- * @param {Array} components - Components to order
363
- * @returns {Promise<Array>} Ordered components
364
- */
365
- async getCreationOrder(components) {
366
- const graph = new Map();
367
- const inDegree = new Map();
368
-
369
- // Initialize graph
370
- for (const component of components) {
371
- const id = this.getComponentId(component);
372
- graph.set(id, []);
373
- inDegree.set(id, 0);
374
- }
375
-
376
- // Build dependency graph
377
- for (const component of components) {
378
- const id = this.getComponentId(component);
379
- const deps = await this.analyzeDependencies(component.type, component.config);
380
-
381
- for (const dep of deps.required) {
382
- const depId = `${dep.type}:${dep.id}`;
383
-
384
- // Only add edge if dependency is in our component list
385
- if (graph.has(depId)) {
386
- graph.get(depId).push(id);
387
- inDegree.set(id, inDegree.get(id) + 1);
388
- }
389
- }
390
- }
391
-
392
- // Topological sort using Kahn's algorithm
393
- const queue = [];
394
- const ordered = [];
395
-
396
- // Find nodes with no dependencies
397
- for (const [id, degree] of inDegree.entries()) {
398
- if (degree === 0) {
399
- queue.push(id);
400
- }
401
- }
402
-
403
- while (queue.length > 0) {
404
- const current = queue.shift();
405
- ordered.push(current);
406
-
407
- // Process neighbors
408
- for (const neighbor of graph.get(current) || []) {
409
- inDegree.set(neighbor, inDegree.get(neighbor) - 1);
410
-
411
- if (inDegree.get(neighbor) === 0) {
412
- queue.push(neighbor);
413
- }
414
- }
415
- }
416
-
417
- // Check for cycles
418
- if (ordered.length !== components.length) {
419
- throw new Error('Circular dependency detected - cannot determine creation order');
420
- }
421
-
422
- // Map back to components
423
- const componentMap = new Map();
424
- for (const component of components) {
425
- const id = this.getComponentId(component);
426
- componentMap.set(id, component);
427
- }
428
-
429
- return ordered.map(id => componentMap.get(id));
430
- }
431
-
432
- /**
433
- * Get component ID for graph
434
- * @private
435
- */
436
- getComponentId(component) {
437
- const name = component.config.agentName ||
438
- component.config.taskId ||
439
- component.config.workflowId ||
440
- component.config.name ||
441
- component.config.id;
442
- return `${component.type}:${name}`;
443
- }
444
-
445
- /**
446
- * Create missing dependencies interactively
447
- * @param {Array} missing - Missing dependencies
448
- * @returns {Promise<Array>} Components to create
449
- */
450
- async promptForMissingDependencies(missing) {
451
- const inquirer = require('inquirer');
452
- const componentsToCreate = [];
453
-
454
- console.log(chalk.yellow('\n⚠️ Missing dependencies detected:'));
455
-
456
- for (const dep of missing) {
457
- console.log(chalk.gray(` - ${dep.type}: ${dep.id} (${dep.reason})`));
458
- }
459
-
460
- const { action } = await inquirer.prompt([{
461
- type: 'list',
462
- name: 'action',
463
- message: 'How would you like to handle missing dependencies?',
464
- choices: [
465
- { name: 'Create all missing dependencies', value: 'create-all' },
466
- { name: 'Select which to create', value: 'select' },
467
- { name: 'Skip dependency creation', value: 'skip' }
468
- ]
469
- }]);
470
-
471
- if (action === 'skip') {
472
- return [];
473
- }
474
-
475
- if (action === 'create-all') {
476
- for (const dep of missing) {
477
- componentsToCreate.push({
478
- type: dep.type,
479
- config: await this.getMinimalConfig(dep.type, dep.id)
480
- });
481
- }
482
- } else {
483
- // Select which to create
484
- const { selected } = await inquirer.prompt([{
485
- type: 'checkbox',
486
- name: 'selected',
487
- message: 'Select dependencies to create:',
488
- choices: missing.map(dep => ({
489
- name: `${dep.type}: ${dep.id}`,
490
- value: dep,
491
- checked: true
492
- }))
493
- }]);
494
-
495
- for (const dep of selected) {
496
- componentsToCreate.push({
497
- type: dep.type,
498
- config: await this.getMinimalConfig(dep.type, dep.id)
499
- });
500
- }
501
- }
502
-
503
- return componentsToCreate;
504
- }
505
-
506
- /**
507
- * Validate workflow dependencies
508
- * @param {Object} workflowData - Workflow configuration
509
- * @returns {Promise<Object>} Validation result
510
- */
511
- async validateWorkflowDependencies(workflowData) {
512
- const result = {
513
- valid: true,
514
- issues: [],
515
- taskDependencies: [],
516
- missingTasks: []
517
- };
518
-
519
- // Extract all task references
520
- const taskRefs = new Set();
521
-
522
- if (workflowData.steps && Array.isArray(workflowData.steps)) {
523
- for (const step of workflowData.steps) {
524
- if (step.type === 'task' && step.taskId) {
525
- taskRefs.add(step.taskId);
526
- } else if (step.action && typeof step.action === 'string') {
527
- // Extract task references from action strings
528
- const taskMatches = step.action.match(/task:([a-z0-9-]+)/g);
529
- if (taskMatches) {
530
- taskMatches.forEach(match => {
531
- const taskId = match.replace('task:', '');
532
- taskRefs.add(taskId);
533
- });
534
- }
535
- }
536
-
537
- // Check step dependencies
538
- if (step.dependencies && Array.isArray(step.dependencies)) {
539
- for (const depId of step.dependencies) {
540
- if (!workflowData.steps.find(s => s.id === depId)) {
541
- result.valid = false;
542
- result.issues.push({
543
- step: step.id || step.name,
544
- issue: `References non-existent step: ${depId}`
545
- });
546
- }
547
- }
548
- }
549
- }
550
- }
551
-
552
- // Validate each task reference
553
- for (const taskId of taskRefs) {
554
- const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
555
-
556
- if (await fs.pathExists(taskPath)) {
557
- result.taskDependencies.push({
558
- taskId,
559
- path: taskPath,
560
- exists: true
561
- });
562
- } else {
563
- result.valid = false;
564
- result.missingTasks.push(taskId);
565
- }
566
- }
567
-
568
- // Check for circular step dependencies
569
- if (workflowData.steps) {
570
- const stepGraph = new Map();
571
-
572
- for (const step of workflowData.steps) {
573
- const stepId = step.id || step.name;
574
- const deps = step.dependencies || [];
575
- stepGraph.set(stepId, deps);
576
- }
577
-
578
- if (this.detectCircularDependencies(stepGraph)) {
579
- result.valid = false;
580
- result.issues.push({
581
- issue: 'Circular dependency detected in workflow steps'
582
- });
583
- }
584
- }
585
-
586
- return result;
587
- }
588
-
589
- /**
590
- * Get minimal config for dependency creation
591
- * @private
592
- */
593
- async getMinimalConfig(type, id) {
594
- const inquirer = require('inquirer');
595
-
596
- switch (type) {
597
- case 'agent':
598
- const { agentTitle } = await inquirer.prompt([{
599
- type: 'input',
600
- name: 'agentTitle',
601
- message: `Title for agent '${id}':`,
602
- default: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')
603
- }]);
604
-
605
- return {
606
- agentName: id,
607
- agentTitle,
608
- whenToUse: `Dependency for ${id}`,
609
- commands: []
610
- };
611
-
612
- case 'task':
613
- const { taskTitle } = await inquirer.prompt([{
614
- type: 'input',
615
- name: 'taskTitle',
616
- message: `Title for task '${id}':`,
617
- default: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')
618
- }]);
619
-
620
- return {
621
- taskId: id,
622
- taskTitle,
623
- taskDescription: `Dependency task for ${id}`,
624
- agentName: 'aios-developer'
625
- };
626
-
627
- case 'workflow':
628
- return {
629
- workflowId: id,
630
- workflowName: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
631
- workflowType: 'standard',
632
- steps: []
633
- };
634
- }
635
- }
636
- }
637
-
1
+ /**
2
+ * Dependency Analyzer for AIOS-FULLSTACK
3
+ * Analyzes and resolves dependencies between components
4
+ * @module dependency-analyzer
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const _yaml = require('js-yaml');
10
+ const chalk = require('chalk');
11
+
12
+ class DependencyAnalyzer {
13
+ constructor(options = {}) {
14
+ this.rootPath = options.rootPath || process.cwd();
15
+ this.manifestPath = path.join(this.rootPath, 'aios-core', 'team-manifest.yaml');
16
+
17
+ // Component paths
18
+ this.paths = {
19
+ agents: path.join(this.rootPath, 'aios-core', 'agents'),
20
+ tasks: path.join(this.rootPath, 'aios-core', 'tasks'),
21
+ workflows: path.join(this.rootPath, 'aios-core', 'workflows')
22
+ };
23
+
24
+ // Dependency cache
25
+ this.dependencyCache = new Map();
26
+ }
27
+
28
+ /**
29
+ * Analyze dependencies for a component
30
+ * @param {string} componentType - Type of component (agent/task/workflow)
31
+ * @param {Object} componentData - Component configuration data
32
+ * @returns {Promise<Object>} Dependency analysis result
33
+ */
34
+ async analyzeDependencies(componentType, componentData) {
35
+ const dependencies = {
36
+ required: [],
37
+ optional: [],
38
+ missing: [],
39
+ circular: false,
40
+ graph: new Map()
41
+ };
42
+
43
+ switch (componentType) {
44
+ case 'agent':
45
+ await this.analyzeAgentDependencies(componentData, dependencies);
46
+ break;
47
+ case 'task':
48
+ await this.analyzeTaskDependencies(componentData, dependencies);
49
+ break;
50
+ case 'workflow':
51
+ await this.analyzeWorkflowDependencies(componentData, dependencies);
52
+ break;
53
+ }
54
+
55
+ // Check for circular dependencies
56
+ dependencies.circular = this.detectCircularDependencies(dependencies.graph);
57
+
58
+ return dependencies;
59
+ }
60
+
61
+ /**
62
+ * Analyze agent dependencies
63
+ * @private
64
+ */
65
+ async analyzeAgentDependencies(agentData, dependencies) {
66
+ // Check for task dependencies from commands
67
+ if (agentData.commands && Array.isArray(agentData.commands)) {
68
+ for (const command of agentData.commands) {
69
+ const taskId = this.commandToTaskId(command);
70
+ const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
71
+
72
+ if (await fs.pathExists(taskPath)) {
73
+ dependencies.required.push({
74
+ type: 'task',
75
+ id: taskId,
76
+ path: taskPath,
77
+ reason: `Command '${command}' requires task`
78
+ });
79
+ } else {
80
+ dependencies.missing.push({
81
+ type: 'task',
82
+ id: taskId,
83
+ reason: `Command '${command}' requires task file`
84
+ });
85
+ }
86
+ }
87
+ }
88
+
89
+ // Check for workflow dependencies
90
+ if (agentData.workflows && Array.isArray(agentData.workflows)) {
91
+ for (const workflowId of agentData.workflows) {
92
+ const workflowPath = path.join(this.paths.workflows, `${workflowId}.yaml`);
93
+
94
+ if (await fs.pathExists(workflowPath)) {
95
+ dependencies.optional.push({
96
+ type: 'workflow',
97
+ id: workflowId,
98
+ path: workflowPath,
99
+ reason: 'Agent workflow reference'
100
+ });
101
+ }
102
+ }
103
+ }
104
+
105
+ // Check for agent dependencies
106
+ if (agentData.dependencies?.agents) {
107
+ for (const agentId of agentData.dependencies.agents) {
108
+ const agentPath = path.join(this.paths.agents, `${agentId}.md`);
109
+
110
+ if (await fs.pathExists(agentPath)) {
111
+ dependencies.required.push({
112
+ type: 'agent',
113
+ id: agentId,
114
+ path: agentPath,
115
+ reason: 'Explicit agent dependency'
116
+ });
117
+ } else {
118
+ dependencies.missing.push({
119
+ type: 'agent',
120
+ id: agentId,
121
+ reason: 'Required agent not found'
122
+ });
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Analyze task dependencies
130
+ * @private
131
+ */
132
+ async analyzeTaskDependencies(taskData, dependencies) {
133
+ // Check for agent dependency
134
+ if (taskData.agentName) {
135
+ const agentPath = path.join(this.paths.agents, `${taskData.agentName}.md`);
136
+
137
+ if (await fs.pathExists(agentPath)) {
138
+ dependencies.required.push({
139
+ type: 'agent',
140
+ id: taskData.agentName,
141
+ path: agentPath,
142
+ reason: 'Task belongs to agent'
143
+ });
144
+ } else {
145
+ dependencies.missing.push({
146
+ type: 'agent',
147
+ id: taskData.agentName,
148
+ reason: 'Agent not found for task'
149
+ });
150
+ }
151
+ }
152
+
153
+ // Check for other task dependencies
154
+ if (taskData.dependencies?.tasks) {
155
+ for (const taskId of taskData.dependencies.tasks) {
156
+ const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
157
+
158
+ if (await fs.pathExists(taskPath)) {
159
+ dependencies.required.push({
160
+ type: 'task',
161
+ id: taskId,
162
+ path: taskPath,
163
+ reason: 'Task dependency'
164
+ });
165
+ } else {
166
+ dependencies.missing.push({
167
+ type: 'task',
168
+ id: taskId,
169
+ reason: 'Required task not found'
170
+ });
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Analyze workflow dependencies
178
+ * @private
179
+ */
180
+ async analyzeWorkflowDependencies(workflowData, dependencies) {
181
+ // Extract task references from workflow steps
182
+ const taskIds = new Set();
183
+
184
+ if (workflowData.steps && Array.isArray(workflowData.steps)) {
185
+ for (const step of workflowData.steps) {
186
+ if (step.type === 'task' && step.taskId) {
187
+ taskIds.add(step.taskId);
188
+ } else if (step.action?.includes('task:')) {
189
+ const taskMatch = step.action.match(/task:([a-z0-9-]+)/);
190
+ if (taskMatch) {
191
+ taskIds.add(taskMatch[1]);
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ // Check each task dependency
198
+ for (const taskId of taskIds) {
199
+ const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
200
+
201
+ if (await fs.pathExists(taskPath)) {
202
+ dependencies.required.push({
203
+ type: 'task',
204
+ id: taskId,
205
+ path: taskPath,
206
+ reason: 'Workflow step requires task'
207
+ });
208
+
209
+ // Also check the task's agent dependency
210
+ const taskContent = await fs.readFile(taskPath, 'utf8');
211
+ const agentMatch = taskContent.match(/\*\*Agent:\*\*\s*([a-z0-9-]+)/);
212
+ if (agentMatch) {
213
+ const agentId = agentMatch[1];
214
+ const agentPath = path.join(this.paths.agents, `${agentId}.md`);
215
+
216
+ if (await fs.pathExists(agentPath)) {
217
+ dependencies.required.push({
218
+ type: 'agent',
219
+ id: agentId,
220
+ path: agentPath,
221
+ reason: 'Task requires agent'
222
+ });
223
+ }
224
+ }
225
+ } else {
226
+ dependencies.missing.push({
227
+ type: 'task',
228
+ id: taskId,
229
+ reason: 'Workflow step requires task'
230
+ });
231
+ }
232
+ }
233
+
234
+ // Check for sub-workflow dependencies
235
+ if (workflowData.dependencies?.workflows) {
236
+ for (const workflowId of workflowData.dependencies.workflows) {
237
+ const workflowPath = path.join(this.paths.workflows, `${workflowId}.yaml`);
238
+
239
+ if (await fs.pathExists(workflowPath)) {
240
+ dependencies.required.push({
241
+ type: 'workflow',
242
+ id: workflowId,
243
+ path: workflowPath,
244
+ reason: 'Sub-workflow dependency'
245
+ });
246
+ } else {
247
+ dependencies.missing.push({
248
+ type: 'workflow',
249
+ id: workflowId,
250
+ reason: 'Required workflow not found'
251
+ });
252
+ }
253
+ }
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Convert command name to task ID
259
+ * @private
260
+ */
261
+ commandToTaskId(command) {
262
+ // Remove asterisk if present
263
+ const cleanCommand = command.replace(/^\*/, '');
264
+
265
+ // Handle common patterns
266
+ if (cleanCommand.startsWith('create-')) {
267
+ return cleanCommand;
268
+ }
269
+
270
+ // Convert to task ID format
271
+ return cleanCommand.replace(/([A-Z])/g, '-$1').toLowerCase();
272
+ }
273
+
274
+ /**
275
+ * Detect circular dependencies
276
+ * @private
277
+ */
278
+ detectCircularDependencies(graph) {
279
+ const visited = new Set();
280
+ const recursionStack = new Set();
281
+
282
+ const hasCycle = (node, path = []) => {
283
+ if (recursionStack.has(node)) {
284
+ console.log(chalk.red(`\n⚠️ Circular dependency detected: ${[...path, node].join(' → ')}`));
285
+ return true;
286
+ }
287
+
288
+ if (visited.has(node)) {
289
+ return false;
290
+ }
291
+
292
+ visited.add(node);
293
+ recursionStack.add(node);
294
+
295
+ const neighbors = graph.get(node) || [];
296
+ for (const neighbor of neighbors) {
297
+ if (hasCycle(neighbor, [...path, node])) {
298
+ return true;
299
+ }
300
+ }
301
+
302
+ recursionStack.delete(node);
303
+ return false;
304
+ };
305
+
306
+ for (const node of graph.keys()) {
307
+ if (hasCycle(node)) {
308
+ return true;
309
+ }
310
+ }
311
+
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * Validate all dependencies exist
317
+ * @param {Array} components - Components to validate
318
+ * @returns {Promise<Object>} Validation result
319
+ */
320
+ async validateDependencies(components) {
321
+ const results = {
322
+ valid: true,
323
+ issues: [],
324
+ resolutions: []
325
+ };
326
+
327
+ for (const component of components) {
328
+ const deps = await this.analyzeDependencies(component.type, component.config);
329
+
330
+ if (deps.missing.length > 0) {
331
+ results.valid = false;
332
+ results.issues.push({
333
+ component: component.config.name || component.config.id,
334
+ missing: deps.missing
335
+ });
336
+
337
+ // Suggest resolutions
338
+ for (const missing of deps.missing) {
339
+ results.resolutions.push({
340
+ action: 'create',
341
+ type: missing.type,
342
+ id: missing.id,
343
+ reason: missing.reason
344
+ });
345
+ }
346
+ }
347
+
348
+ if (deps.circular) {
349
+ results.valid = false;
350
+ results.issues.push({
351
+ component: component.config.name || component.config.id,
352
+ issue: 'Circular dependency detected'
353
+ });
354
+ }
355
+ }
356
+
357
+ return results;
358
+ }
359
+
360
+ /**
361
+ * Get creation order for components based on dependencies
362
+ * @param {Array} components - Components to order
363
+ * @returns {Promise<Array>} Ordered components
364
+ */
365
+ async getCreationOrder(components) {
366
+ const graph = new Map();
367
+ const inDegree = new Map();
368
+
369
+ // Initialize graph
370
+ for (const component of components) {
371
+ const id = this.getComponentId(component);
372
+ graph.set(id, []);
373
+ inDegree.set(id, 0);
374
+ }
375
+
376
+ // Build dependency graph
377
+ for (const component of components) {
378
+ const id = this.getComponentId(component);
379
+ const deps = await this.analyzeDependencies(component.type, component.config);
380
+
381
+ for (const dep of deps.required) {
382
+ const depId = `${dep.type}:${dep.id}`;
383
+
384
+ // Only add edge if dependency is in our component list
385
+ if (graph.has(depId)) {
386
+ graph.get(depId).push(id);
387
+ inDegree.set(id, inDegree.get(id) + 1);
388
+ }
389
+ }
390
+ }
391
+
392
+ // Topological sort using Kahn's algorithm
393
+ const queue = [];
394
+ const ordered = [];
395
+
396
+ // Find nodes with no dependencies
397
+ for (const [id, degree] of inDegree.entries()) {
398
+ if (degree === 0) {
399
+ queue.push(id);
400
+ }
401
+ }
402
+
403
+ while (queue.length > 0) {
404
+ const current = queue.shift();
405
+ ordered.push(current);
406
+
407
+ // Process neighbors
408
+ for (const neighbor of graph.get(current) || []) {
409
+ inDegree.set(neighbor, inDegree.get(neighbor) - 1);
410
+
411
+ if (inDegree.get(neighbor) === 0) {
412
+ queue.push(neighbor);
413
+ }
414
+ }
415
+ }
416
+
417
+ // Check for cycles
418
+ if (ordered.length !== components.length) {
419
+ throw new Error('Circular dependency detected - cannot determine creation order');
420
+ }
421
+
422
+ // Map back to components
423
+ const componentMap = new Map();
424
+ for (const component of components) {
425
+ const id = this.getComponentId(component);
426
+ componentMap.set(id, component);
427
+ }
428
+
429
+ return ordered.map(id => componentMap.get(id));
430
+ }
431
+
432
+ /**
433
+ * Get component ID for graph
434
+ * @private
435
+ */
436
+ getComponentId(component) {
437
+ const name = component.config.agentName ||
438
+ component.config.taskId ||
439
+ component.config.workflowId ||
440
+ component.config.name ||
441
+ component.config.id;
442
+ return `${component.type}:${name}`;
443
+ }
444
+
445
+ /**
446
+ * Create missing dependencies interactively
447
+ * @param {Array} missing - Missing dependencies
448
+ * @returns {Promise<Array>} Components to create
449
+ */
450
+ async promptForMissingDependencies(missing) {
451
+ const inquirer = require('inquirer');
452
+ const componentsToCreate = [];
453
+
454
+ console.log(chalk.yellow('\n⚠️ Missing dependencies detected:'));
455
+
456
+ for (const dep of missing) {
457
+ console.log(chalk.gray(` - ${dep.type}: ${dep.id} (${dep.reason})`));
458
+ }
459
+
460
+ const { action } = await inquirer.prompt([{
461
+ type: 'list',
462
+ name: 'action',
463
+ message: 'How would you like to handle missing dependencies?',
464
+ choices: [
465
+ { name: 'Create all missing dependencies', value: 'create-all' },
466
+ { name: 'Select which to create', value: 'select' },
467
+ { name: 'Skip dependency creation', value: 'skip' }
468
+ ]
469
+ }]);
470
+
471
+ if (action === 'skip') {
472
+ return [];
473
+ }
474
+
475
+ if (action === 'create-all') {
476
+ for (const dep of missing) {
477
+ componentsToCreate.push({
478
+ type: dep.type,
479
+ config: await this.getMinimalConfig(dep.type, dep.id)
480
+ });
481
+ }
482
+ } else {
483
+ // Select which to create
484
+ const { selected } = await inquirer.prompt([{
485
+ type: 'checkbox',
486
+ name: 'selected',
487
+ message: 'Select dependencies to create:',
488
+ choices: missing.map(dep => ({
489
+ name: `${dep.type}: ${dep.id}`,
490
+ value: dep,
491
+ checked: true
492
+ }))
493
+ }]);
494
+
495
+ for (const dep of selected) {
496
+ componentsToCreate.push({
497
+ type: dep.type,
498
+ config: await this.getMinimalConfig(dep.type, dep.id)
499
+ });
500
+ }
501
+ }
502
+
503
+ return componentsToCreate;
504
+ }
505
+
506
+ /**
507
+ * Validate workflow dependencies
508
+ * @param {Object} workflowData - Workflow configuration
509
+ * @returns {Promise<Object>} Validation result
510
+ */
511
+ async validateWorkflowDependencies(workflowData) {
512
+ const result = {
513
+ valid: true,
514
+ issues: [],
515
+ taskDependencies: [],
516
+ missingTasks: []
517
+ };
518
+
519
+ // Extract all task references
520
+ const taskRefs = new Set();
521
+
522
+ if (workflowData.steps && Array.isArray(workflowData.steps)) {
523
+ for (const step of workflowData.steps) {
524
+ if (step.type === 'task' && step.taskId) {
525
+ taskRefs.add(step.taskId);
526
+ } else if (step.action && typeof step.action === 'string') {
527
+ // Extract task references from action strings
528
+ const taskMatches = step.action.match(/task:([a-z0-9-]+)/g);
529
+ if (taskMatches) {
530
+ taskMatches.forEach(match => {
531
+ const taskId = match.replace('task:', '');
532
+ taskRefs.add(taskId);
533
+ });
534
+ }
535
+ }
536
+
537
+ // Check step dependencies
538
+ if (step.dependencies && Array.isArray(step.dependencies)) {
539
+ for (const depId of step.dependencies) {
540
+ if (!workflowData.steps.find(s => s.id === depId)) {
541
+ result.valid = false;
542
+ result.issues.push({
543
+ step: step.id || step.name,
544
+ issue: `References non-existent step: ${depId}`
545
+ });
546
+ }
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ // Validate each task reference
553
+ for (const taskId of taskRefs) {
554
+ const taskPath = path.join(this.paths.tasks, `${taskId}.md`);
555
+
556
+ if (await fs.pathExists(taskPath)) {
557
+ result.taskDependencies.push({
558
+ taskId,
559
+ path: taskPath,
560
+ exists: true
561
+ });
562
+ } else {
563
+ result.valid = false;
564
+ result.missingTasks.push(taskId);
565
+ }
566
+ }
567
+
568
+ // Check for circular step dependencies
569
+ if (workflowData.steps) {
570
+ const stepGraph = new Map();
571
+
572
+ for (const step of workflowData.steps) {
573
+ const stepId = step.id || step.name;
574
+ const deps = step.dependencies || [];
575
+ stepGraph.set(stepId, deps);
576
+ }
577
+
578
+ if (this.detectCircularDependencies(stepGraph)) {
579
+ result.valid = false;
580
+ result.issues.push({
581
+ issue: 'Circular dependency detected in workflow steps'
582
+ });
583
+ }
584
+ }
585
+
586
+ return result;
587
+ }
588
+
589
+ /**
590
+ * Get minimal config for dependency creation
591
+ * @private
592
+ */
593
+ async getMinimalConfig(type, id) {
594
+ const inquirer = require('inquirer');
595
+
596
+ switch (type) {
597
+ case 'agent':
598
+ const { agentTitle } = await inquirer.prompt([{
599
+ type: 'input',
600
+ name: 'agentTitle',
601
+ message: `Title for agent '${id}':`,
602
+ default: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')
603
+ }]);
604
+
605
+ return {
606
+ agentName: id,
607
+ agentTitle,
608
+ whenToUse: `Dependency for ${id}`,
609
+ commands: []
610
+ };
611
+
612
+ case 'task':
613
+ const { taskTitle } = await inquirer.prompt([{
614
+ type: 'input',
615
+ name: 'taskTitle',
616
+ message: `Title for task '${id}':`,
617
+ default: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')
618
+ }]);
619
+
620
+ return {
621
+ taskId: id,
622
+ taskTitle,
623
+ taskDescription: `Dependency task for ${id}`,
624
+ agentName: 'aios-developer'
625
+ };
626
+
627
+ case 'workflow':
628
+ return {
629
+ workflowId: id,
630
+ workflowName: id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
631
+ workflowType: 'standard',
632
+ steps: []
633
+ };
634
+ }
635
+ }
636
+ }
637
+
638
638
  module.exports = DependencyAnalyzer;