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,204 @@
1
+ /**
2
+ * StateMachine Core - Story 4.1
3
+ * Manages workflow state transitions for BYAN v2 orchestrator
4
+ *
5
+ * States: INTERVIEW → ANALYSIS → GENERATION → COMPLETED (+ ERROR from any state)
6
+ */
7
+
8
+ const Logger = require('../observability/logger');
9
+ const ErrorTracker = require('../observability/error-tracker');
10
+
11
+ class StateMachine {
12
+ constructor(options = {}) {
13
+ this.logger = options.logger || new Logger();
14
+ this.errorTracker = options.errorTracker || new ErrorTracker();
15
+
16
+ // AC1: Define five states
17
+ this.STATES = {
18
+ INTERVIEW: 'INTERVIEW',
19
+ ANALYSIS: 'ANALYSIS',
20
+ GENERATION: 'GENERATION',
21
+ COMPLETED: 'COMPLETED',
22
+ ERROR: 'ERROR'
23
+ };
24
+
25
+ // AC2: Valid state transitions
26
+ this.validTransitions = {
27
+ INTERVIEW: ['ANALYSIS', 'ERROR'],
28
+ ANALYSIS: ['GENERATION', 'ERROR'],
29
+ GENERATION: ['COMPLETED', 'ERROR'],
30
+ COMPLETED: [], // Terminal state
31
+ ERROR: [] // Terminal state
32
+ };
33
+
34
+ // State metadata
35
+ this.currentState = this.STATES.INTERVIEW;
36
+ this.stateMetadata = {
37
+ name: this.STATES.INTERVIEW,
38
+ timestamp: Date.now(),
39
+ attempts: 0
40
+ };
41
+
42
+ // AC5: Hooks for state enter/exit
43
+ this.enterHooks = {}; // { stateName: [callbacks] }
44
+ this.exitHooks = {}; // { stateName: [callbacks] }
45
+ }
46
+
47
+ /**
48
+ * AC3: Validate and execute state transition
49
+ * @param {string} newState - Target state
50
+ * @returns {Object} { success, previousState, newState, error? }
51
+ */
52
+ transition(newState) {
53
+ const previousState = this.currentState;
54
+
55
+ // Validate newState exists
56
+ if (!newState || !this.STATES[newState]) {
57
+ const error = new Error(`Unknown state: ${newState}`);
58
+ this.errorTracker.trackError({
59
+ error,
60
+ component: 'StateMachine',
61
+ operation: 'transition',
62
+ currentState: this.currentState,
63
+ attemptedState: newState
64
+ });
65
+ return {
66
+ success: false,
67
+ error: error.message
68
+ };
69
+ }
70
+
71
+ // Validate transition is allowed
72
+ if (!this.validTransitions[this.currentState].includes(newState)) {
73
+ const error = new Error(
74
+ `Invalid transition from ${this.currentState} to ${newState}`
75
+ );
76
+ this.errorTracker.trackError({
77
+ error,
78
+ component: 'StateMachine',
79
+ operation: 'transition',
80
+ currentState: this.currentState,
81
+ attemptedState: newState
82
+ });
83
+ return {
84
+ success: false,
85
+ error: error.message
86
+ };
87
+ }
88
+
89
+ // Execute transition with hooks
90
+ try {
91
+ // AC5: Call exit hooks
92
+ this._executeHooks(this.exitHooks[this.currentState], {
93
+ from: this.currentState,
94
+ to: newState
95
+ });
96
+
97
+ // Update state
98
+ this.currentState = newState;
99
+ this.stateMetadata = {
100
+ name: newState,
101
+ timestamp: Date.now(),
102
+ attempts: 0
103
+ };
104
+
105
+ // AC5: Call enter hooks
106
+ this._executeHooks(this.enterHooks[newState], {
107
+ from: previousState,
108
+ to: newState
109
+ });
110
+
111
+ // Log successful transition
112
+ this.logger.info('State transition', {
113
+ from: previousState,
114
+ to: newState,
115
+ timestamp: this.stateMetadata.timestamp
116
+ });
117
+
118
+ return {
119
+ success: true,
120
+ previousState,
121
+ newState
122
+ };
123
+ } catch (error) {
124
+ // If hooks fail, track but complete transition
125
+ this.errorTracker.trackError({
126
+ error,
127
+ component: 'StateMachine',
128
+ operation: 'transition-hooks',
129
+ state: newState
130
+ });
131
+
132
+ return {
133
+ success: true,
134
+ previousState,
135
+ newState,
136
+ hookError: error.message
137
+ };
138
+ }
139
+ }
140
+
141
+ /**
142
+ * AC4: Get current state with metadata
143
+ * @returns {Object} { name, timestamp, attempts }
144
+ */
145
+ getCurrentState() {
146
+ return { ...this.stateMetadata };
147
+ }
148
+
149
+ /**
150
+ * Increment retry attempts for current state
151
+ */
152
+ incrementAttempts() {
153
+ this.stateMetadata.attempts++;
154
+ }
155
+
156
+ /**
157
+ * AC5: Register state enter hook
158
+ * @param {string} stateName - State to hook into
159
+ * @param {Function} callback - Hook function
160
+ */
161
+ onStateEnter(stateName, callback) {
162
+ if (!this.enterHooks[stateName]) {
163
+ this.enterHooks[stateName] = [];
164
+ }
165
+ this.enterHooks[stateName].push(callback);
166
+ }
167
+
168
+ /**
169
+ * AC5: Register state exit hook
170
+ * @param {string} stateName - State to hook into
171
+ * @param {Function} callback - Hook function
172
+ */
173
+ onStateExit(stateName, callback) {
174
+ if (!this.exitHooks[stateName]) {
175
+ this.exitHooks[stateName] = [];
176
+ }
177
+ this.exitHooks[stateName].push(callback);
178
+ }
179
+
180
+ /**
181
+ * Execute all hooks for a state
182
+ * @private
183
+ */
184
+ _executeHooks(hooks, context) {
185
+ if (!hooks || hooks.length === 0) return;
186
+
187
+ hooks.forEach(hook => {
188
+ try {
189
+ hook(context);
190
+ } catch (error) {
191
+ // Track hook error but don't block transition
192
+ this.errorTracker.trackError({
193
+ error,
194
+ component: 'StateMachine',
195
+ operation: 'hook-execution',
196
+ context
197
+ });
198
+ throw error; // Re-throw to be caught by transition()
199
+ }
200
+ });
201
+ }
202
+ }
203
+
204
+ module.exports = StateMachine;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Simple Cache with TTL support for reducing token consumption
3
+ * Provides in-memory caching with automatic expiration
4
+ *
5
+ * @class SimpleCache
6
+ * @example
7
+ * const cache = new SimpleCache();
8
+ * cache.set('key1', 'value1', 5000); // TTL 5 seconds
9
+ * const value = cache.get('key1');
10
+ */
11
+ class SimpleCache {
12
+ /**
13
+ * Initialize a new SimpleCache instance
14
+ */
15
+ constructor() {
16
+ this.store = new Map();
17
+ }
18
+
19
+ /**
20
+ * Store a value in cache with optional TTL
21
+ * @param {string} key - Cache key
22
+ * @param {*} value - Value to cache
23
+ * @param {number} [ttl] - Time to live in milliseconds (optional)
24
+ * @throws {Error} If key is not a string
25
+ * @returns {void}
26
+ */
27
+ set(key, value, ttl) {
28
+ if (typeof key !== 'string' || !key) {
29
+ throw new Error('Cache key must be a non-empty string');
30
+ }
31
+
32
+ const entry = {
33
+ value,
34
+ timestamp: Date.now(),
35
+ ttl: ttl || null
36
+ };
37
+
38
+ this.store.set(key, entry);
39
+ }
40
+
41
+ /**
42
+ * Retrieve a value from cache
43
+ * @param {string} key - Cache key
44
+ * @returns {*|null} Cached value or null if not found or expired
45
+ */
46
+ get(key) {
47
+ const entry = this.store.get(key);
48
+
49
+ if (!entry) {
50
+ return null;
51
+ }
52
+
53
+ // Check if TTL has expired
54
+ if (entry.ttl && (Date.now() - entry.timestamp) > entry.ttl) {
55
+ this.store.delete(key);
56
+ return null;
57
+ }
58
+
59
+ return entry.value;
60
+ }
61
+
62
+ /**
63
+ * Check if a key exists and is not expired
64
+ * @param {string} key - Cache key
65
+ * @returns {boolean} True if key exists and not expired
66
+ */
67
+ has(key) {
68
+ const value = this.get(key);
69
+ return value !== null;
70
+ }
71
+
72
+ /**
73
+ * Delete a specific cache entry
74
+ * @param {string} key - Cache key to delete
75
+ * @returns {boolean} True if key was deleted, false if not found
76
+ */
77
+ delete(key) {
78
+ return this.store.delete(key);
79
+ }
80
+
81
+ /**
82
+ * Clear all cache entries
83
+ * @returns {void}
84
+ */
85
+ clear() {
86
+ this.store.clear();
87
+ }
88
+
89
+ /**
90
+ * Get the number of entries in cache (includes expired but not cleaned)
91
+ * @returns {number} Number of cache entries
92
+ */
93
+ size() {
94
+ return this.store.size;
95
+ }
96
+
97
+ /**
98
+ * Get all non-expired keys
99
+ * @returns {string[]} Array of valid keys
100
+ */
101
+ keys() {
102
+ const validKeys = [];
103
+ for (const [key] of this.store) {
104
+ if (this.get(key) !== null) {
105
+ validKeys.push(key);
106
+ }
107
+ }
108
+ return validKeys;
109
+ }
110
+
111
+ /**
112
+ * Clean up expired entries
113
+ * @returns {number} Number of entries removed
114
+ */
115
+ cleanup() {
116
+ let removed = 0;
117
+ for (const [key] of this.store) {
118
+ if (this.get(key) === null) {
119
+ removed++;
120
+ }
121
+ }
122
+ return removed;
123
+ }
124
+ }
125
+
126
+ module.exports = SimpleCache;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Context Layer for managing conversational context across agents
3
+ * Provides a hierarchical structure for storing and retrieving context data
4
+ *
5
+ * @class ContextLayer
6
+ * @example
7
+ * const ctx = new ContextLayer();
8
+ * ctx.addLayer('user', { name: 'Yan', role: 'dev' });
9
+ * const userData = ctx.getLayer('user');
10
+ */
11
+ class ContextLayer {
12
+ /**
13
+ * Initialize a new ContextLayer instance
14
+ */
15
+ constructor() {
16
+ this.layers = {};
17
+ }
18
+
19
+ /**
20
+ * Add or update a context layer
21
+ * @param {string} name - Layer name/identifier
22
+ * @param {object} data - Layer data to store
23
+ * @throws {Error} If name is not a string or data is not an object
24
+ * @returns {void}
25
+ */
26
+ addLayer(name, data) {
27
+ if (typeof name !== 'string' || !name) {
28
+ throw new Error('Layer name must be a non-empty string');
29
+ }
30
+ if (typeof data !== 'object' || data === null) {
31
+ throw new Error('Layer data must be an object');
32
+ }
33
+ this.layers[name] = { ...data, _timestamp: Date.now() };
34
+ }
35
+
36
+ /**
37
+ * Retrieve a specific context layer
38
+ * @param {string} name - Layer name to retrieve
39
+ * @returns {object|null} Layer data (deep copy) or null if not found
40
+ */
41
+ getLayer(name) {
42
+ if (!this.layers[name]) {
43
+ return null;
44
+ }
45
+ return JSON.parse(JSON.stringify(this.layers[name]));
46
+ }
47
+
48
+ /**
49
+ * Get all context layers
50
+ * @returns {object} All layers as a key-value object (deep copy)
51
+ */
52
+ getAllLayers() {
53
+ return JSON.parse(JSON.stringify(this.layers));
54
+ }
55
+
56
+ /**
57
+ * Remove a specific context layer
58
+ * @param {string} name - Layer name to remove
59
+ * @returns {boolean} True if layer was removed, false if not found
60
+ */
61
+ clearLayer(name) {
62
+ if (this.layers[name]) {
63
+ delete this.layers[name];
64
+ return true;
65
+ }
66
+ return false;
67
+ }
68
+
69
+ /**
70
+ * Serialize all layers to JSON string
71
+ * @returns {string} JSON representation of all layers
72
+ */
73
+ serialize() {
74
+ return JSON.stringify(this.layers);
75
+ }
76
+
77
+ /**
78
+ * Clear all context layers
79
+ * @returns {void}
80
+ */
81
+ clearAll() {
82
+ this.layers = {};
83
+ }
84
+ }
85
+
86
+ module.exports = ContextLayer;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Economic Dispatcher for routing tasks to appropriate AI models
3
+ * Routes tasks based on complexity keywords to optimize cost/performance
4
+ *
5
+ * @class EconomicDispatcher
6
+ * @example
7
+ * const dispatcher = new EconomicDispatcher();
8
+ * const model = dispatcher.dispatch('explore codebase'); // Returns 'haiku'
9
+ */
10
+ class EconomicDispatcher {
11
+ /**
12
+ * Initialize a new EconomicDispatcher instance
13
+ */
14
+ constructor() {
15
+ // Model classification patterns
16
+ this.patterns = {
17
+ haiku: [
18
+ 'explore', 'simple', 'quick', 'search', 'find', 'list', 'show',
19
+ 'check', 'verify', 'read', 'get', 'view', 'display', 'basic'
20
+ ],
21
+ sonnet: [
22
+ 'implement', 'code', 'complex', 'develop', 'create', 'build',
23
+ 'write', 'fix', 'refactor', 'optimize', 'integrate', 'design'
24
+ ],
25
+ opus: [
26
+ 'architect', 'critical', 'review', 'analyze', 'evaluate', 'plan',
27
+ 'strategy', 'security', 'performance', 'scalability', 'system-design',
28
+ 'architectural', 'mission-critical', 'production'
29
+ ]
30
+ };
31
+
32
+ // Relative costs (Haiku = 1x baseline)
33
+ this.costs = {
34
+ haiku: 1,
35
+ sonnet: 5,
36
+ opus: 15
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Dispatch a task to the appropriate model
42
+ * @param {string} task - Task description
43
+ * @returns {string} Model name ('haiku', 'sonnet', or 'opus')
44
+ * @throws {Error} If task is not a string
45
+ */
46
+ dispatch(task) {
47
+ if (typeof task !== 'string' || !task) {
48
+ throw new Error('Task must be a non-empty string');
49
+ }
50
+
51
+ const taskLower = task.toLowerCase();
52
+
53
+ // Helper to check for whole word match or start of compound words
54
+ const hasKeyword = (patterns) => {
55
+ return patterns.some(pattern => {
56
+ const regex = new RegExp(`\\b${pattern}\\b`, 'i');
57
+ return regex.test(task);
58
+ });
59
+ };
60
+
61
+ // Check Opus patterns first (highest priority for critical tasks)
62
+ if (hasKeyword(this.patterns.opus)) {
63
+ return 'opus';
64
+ }
65
+
66
+ // Check Sonnet patterns (medium complexity)
67
+ if (hasKeyword(this.patterns.sonnet)) {
68
+ return 'sonnet';
69
+ }
70
+
71
+ // Check Haiku patterns (simple tasks)
72
+ if (hasKeyword(this.patterns.haiku)) {
73
+ return 'haiku';
74
+ }
75
+
76
+ // Default to Sonnet for unclassified tasks (balanced choice)
77
+ return 'sonnet';
78
+ }
79
+
80
+ /**
81
+ * Get the relative cost of a model
82
+ * @param {string} model - Model name ('haiku', 'sonnet', or 'opus')
83
+ * @returns {number} Relative cost multiplier
84
+ * @throws {Error} If model is unknown
85
+ */
86
+ getModelCost(model) {
87
+ if (!this.costs[model]) {
88
+ throw new Error(`Unknown model: ${model}`);
89
+ }
90
+ return this.costs[model];
91
+ }
92
+
93
+ /**
94
+ * Get cost comparison between two models
95
+ * @param {string} model1 - First model
96
+ * @param {string} model2 - Second model
97
+ * @returns {number} Cost ratio (model1/model2)
98
+ */
99
+ compareCosts(model1, model2) {
100
+ const cost1 = this.getModelCost(model1);
101
+ const cost2 = this.getModelCost(model2);
102
+ return cost1 / cost2;
103
+ }
104
+
105
+ /**
106
+ * Get all available models with their costs
107
+ * @returns {object} Models and their costs
108
+ */
109
+ getAllModels() {
110
+ return { ...this.costs };
111
+ }
112
+
113
+ /**
114
+ * Estimate cost savings by using recommended model vs default
115
+ * @param {string} task - Task description
116
+ * @param {string} defaultModel - Default model to compare against
117
+ * @returns {object} Savings information
118
+ */
119
+ estimateSavings(task, defaultModel = 'sonnet') {
120
+ const recommended = this.dispatch(task);
121
+ const recommendedCost = this.getModelCost(recommended);
122
+ const defaultCost = this.getModelCost(defaultModel);
123
+ const savings = ((defaultCost - recommendedCost) / defaultCost) * 100;
124
+
125
+ return {
126
+ recommended,
127
+ recommendedCost,
128
+ defaultCost,
129
+ savingsPercent: Math.round(savings),
130
+ shouldSwitch: savings > 0
131
+ };
132
+ }
133
+ }
134
+
135
+ module.exports = EconomicDispatcher;