create-byan-agent 2.0.1 → 2.1.1

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 (240) hide show
  1. package/API-BYAN-V2.md +741 -0
  2. package/BMAD-QUICK-REFERENCE.md +370 -0
  3. package/CHANGELOG-v2.1.0.md +371 -0
  4. package/LICENSE +1 -1
  5. package/MIGRATION-v2.0-to-v2.1.md +430 -0
  6. package/README-BYAN-V2.md +446 -0
  7. package/README.md +264 -201
  8. package/install/.eslintrc.js +20 -0
  9. package/install/.prettierrc +7 -0
  10. package/install/BUGFIX-CHALK.md +173 -0
  11. package/install/BUGFIX-DOCUMENTATION-INDEX.md +299 -0
  12. package/install/BUGFIX-PATH-RESOLUTION.md +293 -0
  13. package/install/BUGFIX-QUICKSTART.md +184 -0
  14. package/install/BUGFIX-SUMMARY.txt +91 -0
  15. package/install/BUGFIX-VISUAL-SUMMARY.md +253 -0
  16. package/install/DEPLOYMENT-GUIDE-V2.md +431 -0
  17. package/install/DOCS-INDEX.md +261 -0
  18. package/install/GUIDE-INSTALLATION-BYAN-SIMPLE.md +1083 -0
  19. package/install/INSTALLER-V2-CHANGES.md +472 -0
  20. package/install/LICENSE +21 -0
  21. package/install/PUBLICATION-CHECKLIST.md +265 -0
  22. package/install/PUBLISH-GUIDE.md +190 -0
  23. package/install/QUICKSTART.md +311 -0
  24. package/install/README-NPM-PUBLISH.md +298 -0
  25. package/install/README-NPM-SHORT.md +298 -0
  26. package/install/README-NPM.md +433 -0
  27. package/install/README-RACHID.md +302 -0
  28. package/install/README-V2-INDEX.md +306 -0
  29. package/install/README.md +298 -0
  30. package/install/RESUME-EXECUTIF-YAN.md +408 -0
  31. package/install/UPDATE-SUMMARY.md +205 -0
  32. package/install/__tests__/integration/detection-flow.test.js +154 -0
  33. package/install/__tests__/platforms/claude-code.test.js +175 -0
  34. package/install/__tests__/platforms/codex.test.js +80 -0
  35. package/install/__tests__/platforms/copilot-cli.test.js +118 -0
  36. package/install/__tests__/platforms/vscode.test.js +67 -0
  37. package/install/__tests__/utils/file-utils.test.js +87 -0
  38. package/install/__tests__/utils/git-detector.test.js +80 -0
  39. package/install/__tests__/utils/logger.test.js +83 -0
  40. package/install/__tests__/utils/node-detector.test.js +71 -0
  41. package/install/__tests__/utils/os-detector.test.js +63 -0
  42. package/install/__tests__/utils/yaml-utils.test.js +85 -0
  43. package/install/__tests__/yanstaller/detector.test.js +210 -0
  44. package/install/coverage/clover.xml +219 -0
  45. package/install/coverage/coverage-final.json +13 -0
  46. package/install/coverage/lcov-report/base.css +224 -0
  47. package/install/coverage/lcov-report/block-navigation.js +87 -0
  48. package/install/coverage/lcov-report/favicon.png +0 -0
  49. package/install/coverage/lcov-report/index.html +146 -0
  50. package/install/coverage/lcov-report/lib/errors.js.html +268 -0
  51. package/install/coverage/lcov-report/lib/exit-codes.js.html +247 -0
  52. package/install/coverage/lcov-report/lib/index.html +131 -0
  53. package/install/coverage/lcov-report/lib/platforms/claude-code.js.html +343 -0
  54. package/install/coverage/lcov-report/lib/platforms/codex.js.html +361 -0
  55. package/install/coverage/lcov-report/lib/platforms/copilot-cli.js.html +454 -0
  56. package/install/coverage/lcov-report/lib/platforms/index.html +176 -0
  57. package/install/coverage/lcov-report/lib/platforms/index.js.html +127 -0
  58. package/install/coverage/lcov-report/lib/platforms/vscode.js.html +238 -0
  59. package/install/coverage/lcov-report/lib/utils/config-loader.js.html +322 -0
  60. package/install/coverage/lcov-report/lib/utils/file-utils.js.html +397 -0
  61. package/install/coverage/lcov-report/lib/utils/git-detector.js.html +190 -0
  62. package/install/coverage/lcov-report/lib/utils/index.html +206 -0
  63. package/install/coverage/lcov-report/lib/utils/logger.js.html +277 -0
  64. package/install/coverage/lcov-report/lib/utils/node-detector.js.html +259 -0
  65. package/install/coverage/lcov-report/lib/utils/os-detector.js.html +307 -0
  66. package/install/coverage/lcov-report/lib/utils/yaml-utils.js.html +346 -0
  67. package/install/coverage/lcov-report/lib/yanstaller/backuper.js.html +409 -0
  68. package/install/coverage/lcov-report/lib/yanstaller/detector.js.html +508 -0
  69. package/install/coverage/lcov-report/lib/yanstaller/index.html +236 -0
  70. package/install/coverage/lcov-report/lib/yanstaller/index.js.html +364 -0
  71. package/install/coverage/lcov-report/lib/yanstaller/installer.js.html +505 -0
  72. package/install/coverage/lcov-report/lib/yanstaller/interviewer.js.html +349 -0
  73. package/install/coverage/lcov-report/lib/yanstaller/recommender.js.html +379 -0
  74. package/install/coverage/lcov-report/lib/yanstaller/troubleshooter.js.html +352 -0
  75. package/install/coverage/lcov-report/lib/yanstaller/validator.js.html +679 -0
  76. package/install/coverage/lcov-report/lib/yanstaller/wizard.js.html +412 -0
  77. package/install/coverage/lcov-report/platforms/claude-code.js.html +343 -0
  78. package/install/coverage/lcov-report/platforms/codex.js.html +361 -0
  79. package/install/coverage/lcov-report/platforms/copilot-cli.js.html +454 -0
  80. package/install/coverage/lcov-report/platforms/index.html +176 -0
  81. package/install/coverage/lcov-report/platforms/index.js.html +127 -0
  82. package/install/coverage/lcov-report/platforms/vscode.js.html +238 -0
  83. package/install/coverage/lcov-report/prettify.css +1 -0
  84. package/install/coverage/lcov-report/prettify.js +2 -0
  85. package/install/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  86. package/install/coverage/lcov-report/sorter.js +210 -0
  87. package/install/coverage/lcov-report/utils/file-utils.js.html +397 -0
  88. package/install/coverage/lcov-report/utils/git-detector.js.html +190 -0
  89. package/install/coverage/lcov-report/utils/index.html +191 -0
  90. package/install/coverage/lcov-report/utils/logger.js.html +277 -0
  91. package/install/coverage/lcov-report/utils/node-detector.js.html +259 -0
  92. package/install/coverage/lcov-report/utils/os-detector.js.html +307 -0
  93. package/install/coverage/lcov-report/utils/yaml-utils.js.html +346 -0
  94. package/install/coverage/lcov-report/yanstaller/detector.js.html +508 -0
  95. package/install/coverage/lcov-report/yanstaller/index.html +116 -0
  96. package/install/coverage/lcov.info +414 -0
  97. package/install/install.sh +239 -0
  98. package/install/jest.config.js +33 -0
  99. package/install/lib/errors.js +61 -0
  100. package/install/lib/exit-codes.js +54 -0
  101. package/install/lib/platforms/claude-code.js +86 -0
  102. package/install/lib/platforms/codex.js +92 -0
  103. package/install/lib/platforms/copilot-cli.js +123 -0
  104. package/install/lib/platforms/index.js +14 -0
  105. package/install/lib/platforms/vscode.js +51 -0
  106. package/install/lib/utils/config-loader.js +79 -0
  107. package/install/lib/utils/file-utils.js +104 -0
  108. package/install/lib/utils/git-detector.js +35 -0
  109. package/install/lib/utils/logger.js +64 -0
  110. package/install/lib/utils/node-detector.js +58 -0
  111. package/install/lib/utils/os-detector.js +74 -0
  112. package/install/lib/utils/yaml-utils.js +87 -0
  113. package/install/lib/yanstaller/backuper.js +108 -0
  114. package/install/lib/yanstaller/detector.js +141 -0
  115. package/install/lib/yanstaller/index.js +93 -0
  116. package/install/lib/yanstaller/installer.js +140 -0
  117. package/install/lib/yanstaller/interviewer.js +88 -0
  118. package/install/lib/yanstaller/recommender.js +98 -0
  119. package/install/lib/yanstaller/troubleshooter.js +89 -0
  120. package/install/lib/yanstaller/validator.js +198 -0
  121. package/install/lib/yanstaller/wizard.js +109 -0
  122. package/install/package-npm.json +55 -0
  123. package/install/package.json +63 -0
  124. package/install/src/byan-v2/context/copilot-context.js +79 -0
  125. package/install/src/byan-v2/context/session-state.js +98 -0
  126. package/install/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  127. package/install/src/byan-v2/dispatcher/local-executor.js +221 -0
  128. package/install/src/byan-v2/dispatcher/task-router.js +122 -0
  129. package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  130. package/install/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  131. package/install/src/byan-v2/generation/agent-profile-validator.js +113 -0
  132. package/install/src/byan-v2/generation/profile-template.js +113 -0
  133. package/install/src/byan-v2/generation/templates/default-agent.md +49 -0
  134. package/install/src/byan-v2/generation/templates/test-template.md +1 -0
  135. package/install/src/byan-v2/index.js +199 -0
  136. package/install/src/byan-v2/observability/error-tracker.js +105 -0
  137. package/install/src/byan-v2/observability/logger.js +154 -0
  138. package/install/src/byan-v2/observability/metrics-collector.js +194 -0
  139. package/install/src/byan-v2/orchestrator/analysis-state.js +268 -0
  140. package/install/src/byan-v2/orchestrator/generation-state.js +340 -0
  141. package/install/src/byan-v2/orchestrator/interview-state.js +271 -0
  142. package/install/src/byan-v2/orchestrator/state-machine.js +204 -0
  143. package/install/src/core/cache/cache.js +126 -0
  144. package/install/src/core/context/context.js +86 -0
  145. package/install/src/core/dispatcher/dispatcher.js +135 -0
  146. package/install/src/core/worker-pool/worker-pool.js +194 -0
  147. package/install/src/core/workflow/workflow-executor.js +220 -0
  148. package/install/src/index.js +139 -0
  149. package/install/src/observability/dashboard/dashboard.js +191 -0
  150. package/install/src/observability/logger/structured-logger.js +254 -0
  151. package/install/src/observability/metrics/metrics-collector.js +325 -0
  152. package/install/switch-to-v2.sh +126 -0
  153. package/install/test-chalk-fix.sh +210 -0
  154. package/install/test-installer-v2.sh +204 -0
  155. package/install/test-path-resolution.sh +200 -0
  156. package/package.json +53 -33
  157. package/src/byan-v2/context/copilot-context.js +79 -0
  158. package/src/byan-v2/context/session-state.js +98 -0
  159. package/src/byan-v2/data/mantras.json +852 -0
  160. package/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  161. package/src/byan-v2/dispatcher/five-whys-analyzer.js +310 -0
  162. package/src/byan-v2/dispatcher/local-executor.js +221 -0
  163. package/src/byan-v2/dispatcher/task-router.js +122 -0
  164. package/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  165. package/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  166. package/src/byan-v2/generation/agent-profile-validator.js +113 -0
  167. package/src/byan-v2/generation/mantra-validator.js +416 -0
  168. package/src/byan-v2/generation/profile-template.js +113 -0
  169. package/src/byan-v2/generation/templates/default-agent.md +49 -0
  170. package/src/byan-v2/generation/templates/test-template.md +1 -0
  171. package/src/byan-v2/index.js +652 -0
  172. package/src/byan-v2/integration/voice-integration.js +295 -0
  173. package/src/byan-v2/observability/error-tracker.js +105 -0
  174. package/src/byan-v2/observability/logger.js +154 -0
  175. package/src/byan-v2/observability/metrics-collector.js +194 -0
  176. package/src/byan-v2/orchestrator/active-listener.js +541 -0
  177. package/src/byan-v2/orchestrator/analysis-state.js +268 -0
  178. package/src/byan-v2/orchestrator/generation-state.js +340 -0
  179. package/src/byan-v2/orchestrator/glossary-builder.js +431 -0
  180. package/src/byan-v2/orchestrator/interview-state.js +353 -0
  181. package/src/byan-v2/orchestrator/state-machine.js +253 -0
  182. package/src/core/cache/cache.js +126 -0
  183. package/src/core/context/context.js +86 -0
  184. package/src/core/dispatcher/dispatcher.js +135 -0
  185. package/src/core/worker-pool/worker-pool.js +194 -0
  186. package/src/core/workflow/workflow-executor.js +220 -0
  187. package/src/index.js +139 -0
  188. package/src/observability/dashboard/dashboard.js +191 -0
  189. package/src/observability/logger/structured-logger.js +254 -0
  190. package/src/observability/metrics/metrics-collector.js +325 -0
  191. package/templates/.github/agents/bmad-agent-test-dynamic.md +0 -21
  192. package/templates/.github/agents/franck.md +0 -379
  193. /package/{CHANGELOG.md → install/CHANGELOG.md} +0 -0
  194. /package/{bin → install/bin}/create-byan-agent-backup.js +0 -0
  195. /package/{bin → install/bin}/create-byan-agent-fixed.js +0 -0
  196. /package/{bin → install/bin}/create-byan-agent-v2.js +0 -0
  197. /package/{bin → install/bin}/create-byan-agent.js +0 -0
  198. /package/{templates → install/templates}/.github/agents/bmad-agent-bmad-master.md +0 -0
  199. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-agent-builder.md +0 -0
  200. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-module-builder.md +0 -0
  201. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -0
  202. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-analyst.md +0 -0
  203. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-architect.md +0 -0
  204. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-dev.md +0 -0
  205. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-pm.md +0 -0
  206. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -0
  207. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quinn.md +0 -0
  208. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-sm.md +0 -0
  209. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-tech-writer.md +0 -0
  210. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-ux-designer.md +0 -0
  211. /package/{templates → install/templates}/.github/agents/bmad-agent-byan-test.md +0 -0
  212. /package/{templates → install/templates}/.github/agents/bmad-agent-byan.md +0 -0
  213. /package/{templates → install/templates}/.github/agents/bmad-agent-carmack.md +0 -0
  214. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -0
  215. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -0
  216. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -0
  217. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -0
  218. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-presentation-master.md +0 -0
  219. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-storyteller.md +0 -0
  220. /package/{templates → install/templates}/.github/agents/bmad-agent-marc.md +0 -0
  221. /package/{templates → install/templates}/.github/agents/bmad-agent-patnote.md +0 -0
  222. /package/{templates → install/templates}/.github/agents/bmad-agent-rachid.md +0 -0
  223. /package/{templates → install/templates}/.github/agents/bmad-agent-tea-tea.md +0 -0
  224. /package/{templates → install/templates}/_bmad/bmb/agents/agent-builder.md +0 -0
  225. /package/{templates → install/templates}/_bmad/bmb/agents/byan-test.md +0 -0
  226. /package/{templates → install/templates}/_bmad/bmb/agents/byan.md +0 -0
  227. /package/{templates → install/templates}/_bmad/bmb/agents/marc.md +0 -0
  228. /package/{templates → install/templates}/_bmad/bmb/agents/module-builder.md +0 -0
  229. /package/{templates → install/templates}/_bmad/bmb/agents/patnote.md +0 -0
  230. /package/{templates → install/templates}/_bmad/bmb/agents/rachid.md +0 -0
  231. /package/{templates → install/templates}/_bmad/bmb/agents/workflow-builder.md +0 -0
  232. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -0
  233. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/templates.yaml +0 -0
  234. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -0
  235. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -0
  236. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/interview-workflow.md +0 -0
  237. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -0
  238. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -0
  239. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -0
  240. /package/{templates → install/templates}/_bmad/core/agents/carmack.md +0 -0
@@ -0,0 +1,194 @@
1
+ /**
2
+ * MetricsCollector - Track task execution metrics
3
+ *
4
+ * Tracks:
5
+ * - tasksRouted, taskToolCalls, localExecutions
6
+ * - totalTokens, totalDuration
7
+ * - successfulTasks, failedTasks
8
+ * - Averages (duration, tokens)
9
+ *
10
+ * Methods:
11
+ * - recordTaskRouting(routingData)
12
+ * - recordTaskExecution(executionData)
13
+ * - getMetrics()
14
+ * - reset()
15
+ */
16
+
17
+ class MetricsCollector {
18
+ constructor() {
19
+ this.metrics = {
20
+ tasksRouted: 0,
21
+ taskToolCalls: 0,
22
+ localExecutions: 0,
23
+ totalTokens: 0,
24
+ totalDuration: 0,
25
+ successfulTasks: 0,
26
+ failedTasks: 0
27
+ };
28
+
29
+ this.counters = {
30
+ sessionsStarted: 0,
31
+ questionsAsked: 0,
32
+ analysesCompleted: 0,
33
+ profilesGenerated: 0,
34
+ errors: 0
35
+ };
36
+
37
+ this.taskHistory = [];
38
+ }
39
+
40
+ /**
41
+ * Increment a counter by name
42
+ * @param {string} counterName - Name of counter to increment
43
+ * @param {number} amount - Amount to increment by (default 1)
44
+ */
45
+ increment(counterName, amount = 1) {
46
+ if (this.counters.hasOwnProperty(counterName)) {
47
+ this.counters[counterName] += amount;
48
+ } else if (this.metrics.hasOwnProperty(counterName)) {
49
+ this.metrics[counterName] += amount;
50
+ } else {
51
+ this.counters[counterName] = amount;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Get summary of all metrics
57
+ * @returns {Object} Metrics summary
58
+ */
59
+ getSummary() {
60
+ const totalTasks = this.metrics.successfulTasks + this.metrics.failedTasks;
61
+
62
+ return {
63
+ totalSessions: this.counters.sessionsStarted,
64
+ avgQuestionsPerSession: this.counters.sessionsStarted > 0
65
+ ? Math.round(this.counters.questionsAsked / this.counters.sessionsStarted)
66
+ : 0,
67
+ successRate: totalTasks > 0
68
+ ? Math.round((this.metrics.successfulTasks / totalTasks) * 100)
69
+ : 0,
70
+ delegationRate: this.metrics.tasksRouted > 0
71
+ ? Math.round((this.metrics.taskToolCalls / this.metrics.tasksRouted) * 100)
72
+ : 0,
73
+ ...this.counters,
74
+ ...this.metrics
75
+ };
76
+ }
77
+
78
+
79
+ /**
80
+ * Record task routing decision
81
+ * @param {Object} routingData - Routing decision data
82
+ */
83
+ recordTaskRouting(routingData) {
84
+ if (!routingData) return;
85
+
86
+ const { executor, complexity, task } = routingData;
87
+
88
+ // Increment counters
89
+ this.metrics.tasksRouted++;
90
+
91
+ if (executor === 'task-tool') {
92
+ this.metrics.taskToolCalls++;
93
+ } else if (executor === 'local') {
94
+ this.metrics.localExecutions++;
95
+ }
96
+
97
+ // Store in history
98
+ this.taskHistory.push({
99
+ type: 'routing',
100
+ timestamp: new Date().toISOString(),
101
+ executor,
102
+ complexity,
103
+ task
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Record task execution result
109
+ * @param {Object} executionData - Execution result data
110
+ */
111
+ recordTaskExecution(executionData) {
112
+ if (!executionData) return;
113
+
114
+ const { duration, success, tokens, error } = executionData;
115
+
116
+ // Validate and record duration (reject negative)
117
+ if (duration !== undefined && duration >= 0) {
118
+ this.metrics.totalDuration += duration;
119
+ }
120
+
121
+ // Validate and record tokens (reject negative)
122
+ if (tokens !== undefined && tokens >= 0) {
123
+ this.metrics.totalTokens += tokens;
124
+ }
125
+
126
+ // Record success/failure
127
+ if (success === true) {
128
+ this.metrics.successfulTasks++;
129
+ } else if (success === false) {
130
+ this.metrics.failedTasks++;
131
+ }
132
+
133
+ // Store in history
134
+ this.taskHistory.push({
135
+ type: 'execution',
136
+ timestamp: new Date().toISOString(),
137
+ duration,
138
+ success,
139
+ tokens,
140
+ error
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Get current metrics snapshot
146
+ * @returns {Object} Current metrics
147
+ */
148
+ getMetrics() {
149
+ const totalTasks = this.metrics.successfulTasks + this.metrics.failedTasks;
150
+
151
+ return {
152
+ tasksRouted: this.metrics.tasksRouted,
153
+ taskToolCalls: this.metrics.taskToolCalls,
154
+ localExecutions: this.metrics.localExecutions,
155
+ totalTokens: this.metrics.totalTokens,
156
+ totalDuration: this.metrics.totalDuration,
157
+ successfulTasks: this.metrics.successfulTasks,
158
+ failedTasks: this.metrics.failedTasks,
159
+ averageDuration: totalTasks > 0
160
+ ? Math.round(this.metrics.totalDuration / totalTasks)
161
+ : 0,
162
+ averageTokens: totalTasks > 0
163
+ ? Math.round(this.metrics.totalTokens / totalTasks)
164
+ : 0
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Reset all metrics and history
170
+ */
171
+ reset() {
172
+ this.metrics = {
173
+ tasksRouted: 0,
174
+ taskToolCalls: 0,
175
+ localExecutions: 0,
176
+ totalTokens: 0,
177
+ totalDuration: 0,
178
+ successfulTasks: 0,
179
+ failedTasks: 0
180
+ };
181
+
182
+ this.counters = {
183
+ sessionsStarted: 0,
184
+ questionsAsked: 0,
185
+ analysesCompleted: 0,
186
+ profilesGenerated: 0,
187
+ errors: 0
188
+ };
189
+
190
+ this.taskHistory = [];
191
+ }
192
+ }
193
+
194
+ module.exports = MetricsCollector;
@@ -0,0 +1,268 @@
1
+ /**
2
+ * AnalysisState - Story 4.3
3
+ * Analyzes interview responses to extract structured requirements
4
+ *
5
+ * Integrates:
6
+ * - TaskRouter: Route tasks based on complexity
7
+ * - LocalExecutor: Execute high-complexity analysis
8
+ * - Logger: Log analysis steps
9
+ * - SessionState: Store analysis results
10
+ */
11
+
12
+ const TaskRouter = require('../dispatcher/task-router');
13
+ const LocalExecutor = require('../dispatcher/local-executor');
14
+ const Logger = require('../observability/logger');
15
+
16
+ class AnalysisState {
17
+ constructor(sessionState) {
18
+ this.sessionState = sessionState;
19
+ this.taskRouter = new TaskRouter();
20
+ this.localExecutor = new LocalExecutor();
21
+ this.logger = new Logger();
22
+
23
+ this.analysisComplete = false;
24
+ this.requirements = null;
25
+ this.patterns = null;
26
+ }
27
+
28
+ /**
29
+ * AC2: Extract requirements from user responses
30
+ * Identifies: purpose, capabilities, knowledgeAreas, constraints
31
+ *
32
+ * @returns {Promise<Object>} Extracted requirements
33
+ */
34
+ async extractRequirements() {
35
+ this.logger.info('Analysis started: extracting requirements', {
36
+ responseCount: this.sessionState.userResponses.length
37
+ });
38
+
39
+ // Prepare analysis task
40
+ const responsesText = this.sessionState.userResponses
41
+ .map((r, i) => `Response ${i + 1}: ${r.response}`)
42
+ .join('\n');
43
+
44
+ const analysisTask = {
45
+ type: 'analysis',
46
+ prompt: `Extract structured requirements from these user responses:
47
+
48
+ ${responsesText}
49
+
50
+ Extract and return JSON with:
51
+ - purpose: Main goal/purpose of the agent
52
+ - capabilities: Array of specific capabilities needed
53
+ - knowledgeAreas: Array of knowledge domains required
54
+ - constraints: Array of constraints or limitations`,
55
+ metadata: {
56
+ requiresReasoning: true,
57
+ requiresMultipleSteps: true,
58
+ estimatedDuration: 'medium'
59
+ }
60
+ };
61
+
62
+ // AC6: Route through TaskRouter (complexity-based delegation)
63
+ const routing = this.taskRouter.routeTask(analysisTask);
64
+
65
+ this.logger.info('Task routed', {
66
+ executor: routing.executor,
67
+ complexity: routing.complexity
68
+ });
69
+
70
+ // Execute analysis (typically routed to LocalExecutor due to high complexity)
71
+ let result;
72
+ if (routing.executor === 'local') {
73
+ result = await this.localExecutor.execute(analysisTask);
74
+ } else {
75
+ // Fallback to local if task-tool routing (shouldn't happen for analysis)
76
+ result = await this.localExecutor.execute(analysisTask);
77
+ }
78
+
79
+ // Parse requirements
80
+ try {
81
+ this.requirements = JSON.parse(result.output);
82
+ } catch (error) {
83
+ this.logger.error('Failed to parse analysis output', { error: error.message });
84
+ throw new Error('Invalid analysis output format');
85
+ }
86
+
87
+ // Store in SessionState
88
+ this.sessionState.setAnalysisResults({
89
+ requirements: this.requirements,
90
+ timestamp: Date.now(),
91
+ tokens: result.tokens,
92
+ duration: result.duration
93
+ });
94
+
95
+ this.logger.info('Requirements extraction complete', {
96
+ purpose: this.requirements.purpose,
97
+ capabilitiesCount: this.requirements.capabilities?.length || 0,
98
+ knowledgeAreasCount: this.requirements.knowledgeAreas?.length || 0
99
+ });
100
+
101
+ return this.requirements;
102
+ }
103
+
104
+ /**
105
+ * AC3: Identify patterns and common themes across responses
106
+ * @returns {Promise<Array>} Patterns found
107
+ */
108
+ async identifyPatterns() {
109
+ this.logger.info('Identifying patterns across responses');
110
+
111
+ if (!this.sessionState.userResponses || this.sessionState.userResponses.length === 0) {
112
+ this.logger.warn('No responses to analyze for patterns');
113
+ this.patterns = [];
114
+ return this.patterns;
115
+ }
116
+
117
+ // Simple pattern detection based on keyword frequency
118
+ const keywordCounts = {};
119
+ const responses = this.sessionState.userResponses
120
+ .map(r => (r.response || '').toLowerCase())
121
+ .join(' ');
122
+
123
+ // Extract words (simple tokenization)
124
+ const words = responses.split(/\s+/).filter(w => w.length > 3);
125
+
126
+ // Count occurrences
127
+ words.forEach(word => {
128
+ keywordCounts[word] = (keywordCounts[word] || 0) + 1;
129
+ });
130
+
131
+ // Find patterns (words appearing >= 2 times)
132
+ this.patterns = Object.entries(keywordCounts)
133
+ .filter(([word, count]) => count >= 2)
134
+ .map(([word, count]) => ({
135
+ theme: word,
136
+ occurrences: count,
137
+ relevance: count / words.length
138
+ }))
139
+ .sort((a, b) => b.occurrences - a.occurrences)
140
+ .slice(0, 10); // Top 10 patterns
141
+
142
+ // Update SessionState
143
+ if (this.sessionState.analysisResults) {
144
+ this.sessionState.analysisResults.patterns = this.patterns;
145
+ } else {
146
+ this.sessionState.setAnalysisResults({ patterns: this.patterns });
147
+ }
148
+
149
+ this.logger.info('Pattern identification complete', {
150
+ patternsFound: this.patterns.length
151
+ });
152
+
153
+ return this.patterns;
154
+ }
155
+
156
+ /**
157
+ * AC4: Validate that all required fields are present and complete
158
+ * @param {Object} requirements - Requirements object to validate
159
+ * @returns {boolean} True if complete
160
+ */
161
+ validateCompleteness(requirements) {
162
+ if (!requirements || typeof requirements !== 'object') {
163
+ this.logger.warn('Requirements validation failed: invalid input');
164
+ return false;
165
+ }
166
+
167
+ // Check required fields exist
168
+ const requiredFields = ['purpose', 'capabilities', 'knowledgeAreas', 'constraints'];
169
+
170
+ for (const field of requiredFields) {
171
+ if (!requirements[field]) {
172
+ this.logger.warn(`Requirements validation failed: missing ${field}`);
173
+ return false;
174
+ }
175
+ }
176
+
177
+ // Validate purpose is not empty
178
+ if (typeof requirements.purpose !== 'string' || requirements.purpose.trim().length === 0) {
179
+ this.logger.warn('Requirements validation failed: empty purpose');
180
+ return false;
181
+ }
182
+
183
+ // Validate arrays are not empty
184
+ const arrayFields = ['capabilities', 'knowledgeAreas'];
185
+
186
+ for (const field of arrayFields) {
187
+ if (!Array.isArray(requirements[field]) || requirements[field].length === 0) {
188
+ this.logger.warn(`Requirements validation failed: empty ${field}`);
189
+ return false;
190
+ }
191
+ }
192
+
193
+ // Constraints can be empty array (optional)
194
+ if (!Array.isArray(requirements.constraints)) {
195
+ this.logger.warn('Requirements validation failed: constraints must be array');
196
+ return false;
197
+ }
198
+
199
+ this.logger.info('Requirements validation passed', {
200
+ purpose: requirements.purpose.substring(0, 50),
201
+ capabilitiesCount: requirements.capabilities.length,
202
+ knowledgeAreasCount: requirements.knowledgeAreas.length
203
+ });
204
+
205
+ return true;
206
+ }
207
+
208
+ /**
209
+ * AC5: Check if analysis is complete and can transition to GENERATION
210
+ * @returns {boolean} True if ready to transition
211
+ */
212
+ canTransitionToGeneration() {
213
+ // Check if requirements have been extracted
214
+ if (!this.requirements) {
215
+ this.logger.warn('Cannot transition: requirements not extracted');
216
+ return false;
217
+ }
218
+
219
+ // Validate completeness
220
+ if (!this.validateCompleteness(this.requirements)) {
221
+ this.logger.warn('Cannot transition: requirements incomplete');
222
+ return false;
223
+ }
224
+
225
+ // Check SessionState has analysis results
226
+ if (!this.sessionState.analysisResults ||
227
+ !this.sessionState.analysisResults.requirements) {
228
+ this.logger.warn('Cannot transition: SessionState missing analysis results');
229
+ return false;
230
+ }
231
+
232
+ this.logger.info('Analysis complete - ready to transition to GENERATION');
233
+ this.analysisComplete = true;
234
+ return true;
235
+ }
236
+
237
+ /**
238
+ * Get current analysis results
239
+ * @returns {Object} Analysis results
240
+ */
241
+ getAnalysisResults() {
242
+ return {
243
+ requirements: this.requirements,
244
+ patterns: this.patterns,
245
+ complete: this.analysisComplete
246
+ };
247
+ }
248
+
249
+ /**
250
+ * Get requirements summary
251
+ * @returns {Object} Requirements summary
252
+ */
253
+ getRequirementsSummary() {
254
+ if (!this.requirements) {
255
+ return { summary: 'No requirements extracted yet' };
256
+ }
257
+
258
+ return {
259
+ purpose: this.requirements.purpose,
260
+ capabilitiesCount: this.requirements.capabilities?.length || 0,
261
+ knowledgeAreasCount: this.requirements.knowledgeAreas?.length || 0,
262
+ constraintsCount: this.requirements.constraints?.length || 0,
263
+ isComplete: this.validateCompleteness(this.requirements)
264
+ };
265
+ }
266
+ }
267
+
268
+ module.exports = AnalysisState;