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,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;
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Worker for executing tasks asynchronously
3
+ * Represents a single worker in the pool
4
+ *
5
+ * @class Worker
6
+ */
7
+ class Worker {
8
+ /**
9
+ * Create a new Worker
10
+ * @param {number} id - Unique worker identifier
11
+ */
12
+ constructor(id) {
13
+ this.id = id;
14
+ this.status = 'idle'; // idle, busy, error
15
+ this.currentTask = null;
16
+ }
17
+
18
+ /**
19
+ * Execute a task
20
+ * @param {Function|object} task - Task to execute (function or object with execute method)
21
+ * @returns {Promise<*>} Task result
22
+ */
23
+ async execute(task) {
24
+ this.status = 'busy';
25
+ this.currentTask = task;
26
+
27
+ try {
28
+ let result;
29
+
30
+ if (typeof task === 'function') {
31
+ result = await task();
32
+ } else if (task && typeof task.execute === 'function') {
33
+ result = await task.execute();
34
+ } else {
35
+ throw new Error('Task must be a function or have an execute method');
36
+ }
37
+
38
+ this.status = 'idle';
39
+ this.currentTask = null;
40
+ return result;
41
+ } catch (error) {
42
+ this.status = 'error';
43
+ this.currentTask = null;
44
+ throw error;
45
+ }
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Worker Pool for managing parallel task execution
51
+ * Provides a pool of workers with automatic task queuing
52
+ *
53
+ * @class WorkerPool
54
+ * @example
55
+ * const pool = new WorkerPool(3);
56
+ * const result = await pool.submitTask(async () => { return 'done'; });
57
+ */
58
+ class WorkerPool {
59
+ /**
60
+ * Create a new WorkerPool
61
+ * @param {number} maxWorkers - Maximum number of concurrent workers
62
+ * @throws {Error} If maxWorkers is not a positive number
63
+ */
64
+ constructor(maxWorkers = 4) {
65
+ if (typeof maxWorkers !== 'number' || maxWorkers < 1) {
66
+ throw new Error('maxWorkers must be a positive number');
67
+ }
68
+
69
+ this.maxWorkers = maxWorkers;
70
+ this.workers = [];
71
+ this.taskQueue = [];
72
+ this.activeTasks = 0;
73
+ this.isShutdown = false;
74
+
75
+ // Initialize workers
76
+ for (let i = 0; i < maxWorkers; i++) {
77
+ this.workers.push(new Worker(i));
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Submit a task to the pool
83
+ * @param {Function|object} task - Task to execute
84
+ * @returns {Promise<*>} Promise that resolves with task result
85
+ */
86
+ submitTask(task) {
87
+ if (this.isShutdown) {
88
+ return Promise.reject(new Error('Worker pool is shutdown'));
89
+ }
90
+
91
+ return new Promise((resolve, reject) => {
92
+ this.taskQueue.push({ task, resolve, reject });
93
+ this._processQueue();
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Process the task queue
99
+ * @private
100
+ */
101
+ async _processQueue() {
102
+ // Find an idle worker
103
+ const idleWorker = this.workers.find(w => w.status === 'idle');
104
+
105
+ if (!idleWorker || this.taskQueue.length === 0) {
106
+ return;
107
+ }
108
+
109
+ const { task, resolve, reject } = this.taskQueue.shift();
110
+ this.activeTasks++;
111
+
112
+ try {
113
+ const result = await idleWorker.execute(task);
114
+ this.activeTasks--;
115
+ resolve(result);
116
+
117
+ // Process next task if any
118
+ if (this.taskQueue.length > 0) {
119
+ this._processQueue();
120
+ }
121
+ } catch (error) {
122
+ this.activeTasks--;
123
+ reject(error);
124
+
125
+ // Reset worker to idle on error
126
+ idleWorker.status = 'idle';
127
+
128
+ // Continue processing queue
129
+ if (this.taskQueue.length > 0) {
130
+ this._processQueue();
131
+ }
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Get number of active workers
137
+ * @returns {number} Number of busy workers
138
+ */
139
+ getActiveWorkers() {
140
+ return this.workers.filter(w => w.status === 'busy').length;
141
+ }
142
+
143
+ /**
144
+ * Get number of idle workers
145
+ * @returns {number} Number of idle workers
146
+ */
147
+ getIdleWorkers() {
148
+ return this.workers.filter(w => w.status === 'idle').length;
149
+ }
150
+
151
+ /**
152
+ * Get current queue size
153
+ * @returns {number} Number of queued tasks
154
+ */
155
+ getQueueSize() {
156
+ return this.taskQueue.length;
157
+ }
158
+
159
+ /**
160
+ * Get pool statistics
161
+ * @returns {object} Pool statistics
162
+ */
163
+ getStats() {
164
+ return {
165
+ totalWorkers: this.workers.length,
166
+ activeWorkers: this.getActiveWorkers(),
167
+ idleWorkers: this.getIdleWorkers(),
168
+ queueSize: this.getQueueSize(),
169
+ activeTasks: this.activeTasks
170
+ };
171
+ }
172
+
173
+ /**
174
+ * Shutdown the pool gracefully
175
+ * Waits for active tasks to complete
176
+ * @returns {Promise<void>}
177
+ */
178
+ async shutdown() {
179
+ this.isShutdown = true;
180
+
181
+ // Wait for all active tasks to complete
182
+ while (this.activeTasks > 0) {
183
+ await new Promise(resolve => setTimeout(resolve, 10));
184
+ }
185
+
186
+ // Clear queue and reject pending tasks
187
+ while (this.taskQueue.length > 0) {
188
+ const { reject } = this.taskQueue.shift();
189
+ reject(new Error('Worker pool shutdown'));
190
+ }
191
+ }
192
+ }
193
+
194
+ module.exports = { WorkerPool, Worker };