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,254 @@
1
+ /**
2
+ * Structured Logger for BYAN v2.0
3
+ * Provides structured logging with JSON format, log levels, and metadata
4
+ *
5
+ * @module observability/logger/structured-logger
6
+ * @version 2.0.0-HYPER-MVP
7
+ */
8
+
9
+ /**
10
+ * Log levels supported by the logger
11
+ */
12
+ const LOG_LEVELS = {
13
+ DEBUG: 'debug',
14
+ INFO: 'info',
15
+ WARN: 'warn',
16
+ ERROR: 'error',
17
+ };
18
+
19
+ /**
20
+ * Numeric priorities for log levels
21
+ */
22
+ const LOG_PRIORITIES = {
23
+ debug: 0,
24
+ info: 1,
25
+ warn: 2,
26
+ error: 3,
27
+ };
28
+
29
+ /**
30
+ * Structured Logger - Provides JSON-formatted logging with metadata
31
+ *
32
+ * @class StructuredLogger
33
+ * @example
34
+ * const logger = new StructuredLogger();
35
+ * logger.info('User logged in', { userId: '123', ip: '192.168.1.1' });
36
+ */
37
+ class StructuredLogger {
38
+ constructor(options = {}) {
39
+ this.level = options.level || LOG_LEVELS.INFO;
40
+ this.logs = []; // In-memory storage for tests
41
+ this.enableConsole = options.enableConsole !== false;
42
+ }
43
+
44
+ /**
45
+ * Set the minimum log level
46
+ *
47
+ * @param {string} level - Log level (debug, info, warn, error)
48
+ * @returns {void}
49
+ *
50
+ * @example
51
+ * logger.setLevel('debug'); // Show all logs
52
+ * logger.setLevel('error'); // Show only errors
53
+ */
54
+ setLevel(level) {
55
+ if (!LOG_PRIORITIES.hasOwnProperty(level)) {
56
+ throw new Error(
57
+ `Invalid log level: ${level}. Must be one of: debug, info, warn, error`
58
+ );
59
+ }
60
+ this.level = level;
61
+ }
62
+
63
+ /**
64
+ * Log debug message
65
+ *
66
+ * @param {string} message - Log message
67
+ * @param {Object} [meta={}] - Additional metadata
68
+ * @returns {void}
69
+ *
70
+ * @example
71
+ * logger.debug('Cache hit', { key: 'user:123', ttl: 3600 });
72
+ */
73
+ debug(message, meta = {}) {
74
+ this._log(LOG_LEVELS.DEBUG, message, meta);
75
+ }
76
+
77
+ /**
78
+ * Log info message
79
+ *
80
+ * @param {string} message - Log message
81
+ * @param {Object} [meta={}] - Additional metadata
82
+ * @returns {void}
83
+ *
84
+ * @example
85
+ * logger.info('Task started', { taskId: '123', agent: 'dev' });
86
+ */
87
+ info(message, meta = {}) {
88
+ this._log(LOG_LEVELS.INFO, message, meta);
89
+ }
90
+
91
+ /**
92
+ * Log warning message
93
+ *
94
+ * @param {string} message - Log message
95
+ * @param {Object} [meta={}] - Additional metadata
96
+ * @returns {void}
97
+ *
98
+ * @example
99
+ * logger.warn('Rate limit approaching', { limit: 1000, used: 950 });
100
+ */
101
+ warn(message, meta = {}) {
102
+ this._log(LOG_LEVELS.WARN, message, meta);
103
+ }
104
+
105
+ /**
106
+ * Log error message
107
+ *
108
+ * @param {string} message - Log message
109
+ * @param {Object} [meta={}] - Additional metadata
110
+ * @returns {void}
111
+ *
112
+ * @example
113
+ * logger.error('Task failed', { taskId: '123', error: 'Timeout' });
114
+ */
115
+ error(message, meta = {}) {
116
+ this._log(LOG_LEVELS.ERROR, message, meta);
117
+ }
118
+
119
+ /**
120
+ * Internal log method
121
+ *
122
+ * @private
123
+ * @param {string} level - Log level
124
+ * @param {string} message - Log message
125
+ * @param {Object} meta - Metadata
126
+ * @returns {void}
127
+ */
128
+ _log(level, message, meta) {
129
+ // Check if this log should be recorded based on level
130
+ if (LOG_PRIORITIES[level] < LOG_PRIORITIES[this.level]) {
131
+ return;
132
+ }
133
+
134
+ const logEntry = {
135
+ timestamp: new Date().toISOString(),
136
+ level,
137
+ message,
138
+ meta: { ...meta },
139
+ };
140
+
141
+ // Store in memory
142
+ this.logs.push(logEntry);
143
+
144
+ // Output to console if enabled
145
+ if (this.enableConsole) {
146
+ this._outputToConsole(logEntry);
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Output log entry to console
152
+ *
153
+ * @private
154
+ * @param {Object} logEntry - Log entry
155
+ * @returns {void}
156
+ */
157
+ _outputToConsole(logEntry) {
158
+ const output = JSON.stringify(logEntry);
159
+
160
+ switch (logEntry.level) {
161
+ case LOG_LEVELS.DEBUG:
162
+ console.debug(output);
163
+ break;
164
+ case LOG_LEVELS.INFO:
165
+ console.info(output);
166
+ break;
167
+ case LOG_LEVELS.WARN:
168
+ console.warn(output);
169
+ break;
170
+ case LOG_LEVELS.ERROR:
171
+ console.error(output);
172
+ break;
173
+ default:
174
+ console.log(output);
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Get all logs
180
+ *
181
+ * @returns {Array<Object>} Array of log entries
182
+ *
183
+ * @example
184
+ * const logs = logger.getLogs();
185
+ * logs.forEach(log => {
186
+ * console.log(`[${log.level}] ${log.message}`);
187
+ * });
188
+ */
189
+ getLogs() {
190
+ return [...this.logs];
191
+ }
192
+
193
+ /**
194
+ * Get logs filtered by level
195
+ *
196
+ * @param {string} level - Log level to filter by
197
+ * @returns {Array<Object>} Filtered log entries
198
+ *
199
+ * @example
200
+ * const errors = logger.getLogsByLevel('error');
201
+ */
202
+ getLogsByLevel(level) {
203
+ return this.logs.filter((log) => log.level === level);
204
+ }
205
+
206
+ /**
207
+ * Clear all logs
208
+ *
209
+ * @returns {void}
210
+ *
211
+ * @example
212
+ * logger.clear(); // Remove all logs from memory
213
+ */
214
+ clear() {
215
+ this.logs = [];
216
+ }
217
+
218
+ /**
219
+ * Get log count
220
+ *
221
+ * @returns {number} Number of logs
222
+ */
223
+ count() {
224
+ return this.logs.length;
225
+ }
226
+
227
+ /**
228
+ * Get log count by level
229
+ *
230
+ * @returns {Object} Count of logs per level
231
+ *
232
+ * @example
233
+ * const stats = logger.getStats();
234
+ * // { debug: 10, info: 25, warn: 3, error: 1 }
235
+ */
236
+ getStats() {
237
+ const stats = {
238
+ debug: 0,
239
+ info: 0,
240
+ warn: 0,
241
+ error: 0,
242
+ };
243
+
244
+ this.logs.forEach((log) => {
245
+ if (stats.hasOwnProperty(log.level)) {
246
+ stats[log.level]++;
247
+ }
248
+ });
249
+
250
+ return stats;
251
+ }
252
+ }
253
+
254
+ module.exports = { StructuredLogger, LOG_LEVELS };
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Metrics Collector for BYAN v2.0
3
+ * Collects and manages system metrics (counters, gauges, timings)
4
+ *
5
+ * @module observability/metrics/metrics-collector
6
+ * @version 2.0.0-HYPER-MVP
7
+ */
8
+
9
+ /**
10
+ * Metrics Collector - Records and tracks system metrics
11
+ *
12
+ * @class MetricsCollector
13
+ * @example
14
+ * const metrics = new MetricsCollector();
15
+ * metrics.increment('api.calls', { endpoint: '/chat' });
16
+ * metrics.recordDuration('request.duration', 150);
17
+ */
18
+ class MetricsCollector {
19
+ constructor() {
20
+ this.metrics = new Map();
21
+ }
22
+
23
+ /**
24
+ * Record a metric with a specific value
25
+ *
26
+ * @param {string} name - Metric name
27
+ * @param {number} value - Metric value
28
+ * @param {Object} [tags={}] - Optional tags for filtering
29
+ * @returns {void}
30
+ *
31
+ * @example
32
+ * metrics.recordMetric('memory.usage', 1024, { unit: 'MB', service: 'api' });
33
+ */
34
+ recordMetric(name, value, tags = {}) {
35
+ if (!name || typeof name !== 'string') {
36
+ throw new Error('Metric name must be a non-empty string');
37
+ }
38
+
39
+ if (typeof value !== 'number') {
40
+ throw new Error('Metric value must be a number');
41
+ }
42
+
43
+ if (isNaN(value)) {
44
+ throw new Error('Metric value cannot be NaN');
45
+ }
46
+
47
+ const key = this._generateKey(name, tags);
48
+
49
+ this.metrics.set(key, {
50
+ name,
51
+ value,
52
+ tags: { ...tags },
53
+ timestamp: new Date().toISOString(),
54
+ type: 'gauge',
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Increment a counter metric
60
+ *
61
+ * @param {string} name - Metric name
62
+ * @param {Object} [tags={}] - Optional tags
63
+ * @param {number} [delta=1] - Increment amount
64
+ * @returns {void}
65
+ *
66
+ * @example
67
+ * metrics.increment('api.calls', { endpoint: '/chat' });
68
+ * metrics.increment('cache.hits', {}, 5); // Increment by 5
69
+ */
70
+ increment(name, tags = {}, delta = 1) {
71
+ if (!name || typeof name !== 'string') {
72
+ throw new Error('Metric name must be a non-empty string');
73
+ }
74
+
75
+ if (typeof delta !== 'number') {
76
+ throw new Error('Delta must be a number');
77
+ }
78
+
79
+ const key = this._generateKey(name, tags);
80
+ const existing = this.metrics.get(key);
81
+
82
+ if (existing) {
83
+ this.metrics.set(key, {
84
+ ...existing,
85
+ value: existing.value + delta,
86
+ timestamp: new Date().toISOString(),
87
+ });
88
+ } else {
89
+ this.metrics.set(key, {
90
+ name,
91
+ value: delta,
92
+ tags: { ...tags },
93
+ timestamp: new Date().toISOString(),
94
+ type: 'counter',
95
+ });
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Decrement a counter metric
101
+ *
102
+ * @param {string} name - Metric name
103
+ * @param {Object} [tags={}] - Optional tags
104
+ * @param {number} [delta=1] - Decrement amount
105
+ * @returns {void}
106
+ *
107
+ * @example
108
+ * metrics.decrement('active.connections', { server: 'main' });
109
+ */
110
+ decrement(name, tags = {}, delta = 1) {
111
+ this.increment(name, tags, -delta);
112
+ }
113
+
114
+ /**
115
+ * Record a duration/timing metric
116
+ *
117
+ * @param {string} name - Metric name
118
+ * @param {number} durationMs - Duration in milliseconds
119
+ * @param {Object} [tags={}] - Optional tags
120
+ * @returns {void}
121
+ *
122
+ * @example
123
+ * metrics.recordDuration('request.duration', 150, { status: '200' });
124
+ */
125
+ recordDuration(name, durationMs, tags = {}) {
126
+ if (!name || typeof name !== 'string') {
127
+ throw new Error('Metric name must be a non-empty string');
128
+ }
129
+
130
+ if (typeof durationMs !== 'number') {
131
+ throw new Error('Duration must be a number');
132
+ }
133
+
134
+ if (durationMs < 0) {
135
+ throw new Error('Duration cannot be negative');
136
+ }
137
+
138
+ const key = this._generateKey(name, tags);
139
+
140
+ this.metrics.set(key, {
141
+ name,
142
+ value: durationMs,
143
+ tags: { ...tags },
144
+ timestamp: new Date().toISOString(),
145
+ type: 'timing',
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Generate unique key for metric with tags
151
+ *
152
+ * @private
153
+ * @param {string} name - Metric name
154
+ * @param {Object} tags - Tags
155
+ * @returns {string} Unique key
156
+ */
157
+ _generateKey(name, tags) {
158
+ if (Object.keys(tags).length === 0) {
159
+ return name;
160
+ }
161
+
162
+ const sortedTags = Object.keys(tags)
163
+ .sort()
164
+ .map((key) => `${key}:${tags[key]}`)
165
+ .join(',');
166
+
167
+ return `${name}[${sortedTags}]`;
168
+ }
169
+
170
+ /**
171
+ * Get all metrics
172
+ *
173
+ * @returns {Object} All metrics as key-value pairs
174
+ *
175
+ * @example
176
+ * const allMetrics = metrics.getMetrics();
177
+ * Object.entries(allMetrics).forEach(([key, metric]) => {
178
+ * console.log(`${key}: ${metric.value}`);
179
+ * });
180
+ */
181
+ getMetrics() {
182
+ const result = {};
183
+
184
+ for (const [key, value] of this.metrics.entries()) {
185
+ result[key] = { ...value };
186
+ }
187
+
188
+ return result;
189
+ }
190
+
191
+ /**
192
+ * Get a specific metric
193
+ *
194
+ * @param {string} name - Metric name
195
+ * @param {Object} [tags={}] - Optional tags
196
+ * @returns {Object|null} Metric or null if not found
197
+ *
198
+ * @example
199
+ * const apiCalls = metrics.getMetric('api.calls', { endpoint: '/chat' });
200
+ * console.log(`API calls: ${apiCalls.value}`);
201
+ */
202
+ getMetric(name, tags = {}) {
203
+ const key = this._generateKey(name, tags);
204
+ const metric = this.metrics.get(key);
205
+
206
+ return metric ? { ...metric } : null;
207
+ }
208
+
209
+ /**
210
+ * Get metrics filtered by name prefix
211
+ *
212
+ * @param {string} prefix - Name prefix
213
+ * @returns {Object} Filtered metrics
214
+ *
215
+ * @example
216
+ * const apiMetrics = metrics.getMetricsByPrefix('api.');
217
+ * // Returns all metrics starting with 'api.'
218
+ */
219
+ getMetricsByPrefix(prefix) {
220
+ const result = {};
221
+
222
+ for (const [key, value] of this.metrics.entries()) {
223
+ if (value.name.startsWith(prefix)) {
224
+ result[key] = { ...value };
225
+ }
226
+ }
227
+
228
+ return result;
229
+ }
230
+
231
+ /**
232
+ * Get metrics filtered by type
233
+ *
234
+ * @param {string} type - Metric type (gauge, counter, timing)
235
+ * @returns {Object} Filtered metrics
236
+ *
237
+ * @example
238
+ * const counters = metrics.getMetricsByType('counter');
239
+ */
240
+ getMetricsByType(type) {
241
+ const result = {};
242
+
243
+ for (const [key, value] of this.metrics.entries()) {
244
+ if (value.type === type) {
245
+ result[key] = { ...value };
246
+ }
247
+ }
248
+
249
+ return result;
250
+ }
251
+
252
+ /**
253
+ * Clear all metrics
254
+ *
255
+ * @returns {void}
256
+ *
257
+ * @example
258
+ * metrics.clear(); // Remove all metrics
259
+ */
260
+ clear() {
261
+ this.metrics.clear();
262
+ }
263
+
264
+ /**
265
+ * Get metrics count
266
+ *
267
+ * @returns {number} Number of metrics
268
+ */
269
+ count() {
270
+ return this.metrics.size;
271
+ }
272
+
273
+ /**
274
+ * Reset a specific metric to zero
275
+ *
276
+ * @param {string} name - Metric name
277
+ * @param {Object} [tags={}] - Optional tags
278
+ * @returns {boolean} True if metric was reset, false if not found
279
+ *
280
+ * @example
281
+ * metrics.resetMetric('api.calls', { endpoint: '/chat' });
282
+ */
283
+ resetMetric(name, tags = {}) {
284
+ const key = this._generateKey(name, tags);
285
+ const existing = this.metrics.get(key);
286
+
287
+ if (existing) {
288
+ this.metrics.set(key, {
289
+ ...existing,
290
+ value: 0,
291
+ timestamp: new Date().toISOString(),
292
+ });
293
+ return true;
294
+ }
295
+
296
+ return false;
297
+ }
298
+
299
+ /**
300
+ * Get summary statistics
301
+ *
302
+ * @returns {Object} Summary stats
303
+ *
304
+ * @example
305
+ * const stats = metrics.getStats();
306
+ * // { total: 10, byType: { counter: 5, gauge: 3, timing: 2 } }
307
+ */
308
+ getStats() {
309
+ const byType = {};
310
+
311
+ for (const metric of this.metrics.values()) {
312
+ if (!byType[metric.type]) {
313
+ byType[metric.type] = 0;
314
+ }
315
+ byType[metric.type]++;
316
+ }
317
+
318
+ return {
319
+ total: this.metrics.size,
320
+ byType,
321
+ };
322
+ }
323
+ }
324
+
325
+ module.exports = { MetricsCollector };
@@ -1,21 +0,0 @@
1
- ---
2
- name: 'test-dynamic'
3
- description: 'Test Dynamic Loading - Phase B Validation'
4
- ---
5
-
6
- <agent-activation CRITICAL="TRUE">
7
- 1. LOAD the FULL agent file from {project-root}/_bmad/core/agents/test-dynamic.md
8
- 2. READ its entire contents
9
- 3. FOLLOW activation steps precisely
10
- 4. WAIT for user input
11
- </agent-activation>
12
-
13
- ```xml
14
- <agent id="test-dynamic" name="TEST-DYNAMIC" title="Dynamic Loading Test" icon="🧪">
15
- <activation>
16
- <step n="1">Load from {project-root}/_bmad/core/agents/test-dynamic.md</step>
17
- <step n="2">Test inheritance from base agent</step>
18
- <step n="3">Display menu</step>
19
- </activation>
20
- </agent>
21
- ```