mcp-agent-foundry 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +477 -0
  3. package/dist/cli/install-skills.d.ts +11 -0
  4. package/dist/cli/install-skills.d.ts.map +1 -0
  5. package/dist/cli/install-skills.js +143 -0
  6. package/dist/cli/install-skills.js.map +1 -0
  7. package/dist/cli/recovery-commands.d.ts +41 -0
  8. package/dist/cli/recovery-commands.d.ts.map +1 -0
  9. package/dist/cli/recovery-commands.js +241 -0
  10. package/dist/cli/recovery-commands.js.map +1 -0
  11. package/dist/cli/setup-wizard.d.ts +25 -0
  12. package/dist/cli/setup-wizard.d.ts.map +1 -0
  13. package/dist/cli/setup-wizard.js +1417 -0
  14. package/dist/cli/setup-wizard.js.map +1 -0
  15. package/dist/cli/test-connection.d.ts +45 -0
  16. package/dist/cli/test-connection.d.ts.map +1 -0
  17. package/dist/cli/test-connection.js +317 -0
  18. package/dist/cli/test-connection.js.map +1 -0
  19. package/dist/cli.d.ts +75 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +704 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/config/defaults.d.ts +57 -0
  24. package/dist/config/defaults.d.ts.map +1 -0
  25. package/dist/config/defaults.js +99 -0
  26. package/dist/config/defaults.js.map +1 -0
  27. package/dist/config/index.d.ts +14 -0
  28. package/dist/config/index.d.ts.map +1 -0
  29. package/dist/config/index.js +22 -0
  30. package/dist/config/index.js.map +1 -0
  31. package/dist/config/manager.d.ts +184 -0
  32. package/dist/config/manager.d.ts.map +1 -0
  33. package/dist/config/manager.js +347 -0
  34. package/dist/config/manager.js.map +1 -0
  35. package/dist/config/merger.d.ts +76 -0
  36. package/dist/config/merger.d.ts.map +1 -0
  37. package/dist/config/merger.js +189 -0
  38. package/dist/config/merger.js.map +1 -0
  39. package/dist/config/schema.d.ts +20 -0
  40. package/dist/config/schema.d.ts.map +1 -0
  41. package/dist/config/schema.js +20 -0
  42. package/dist/config/schema.js.map +1 -0
  43. package/dist/config/validator.d.ts +254 -0
  44. package/dist/config/validator.d.ts.map +1 -0
  45. package/dist/config/validator.js +363 -0
  46. package/dist/config/validator.js.map +1 -0
  47. package/dist/config/worktree-defaults.d.ts +23 -0
  48. package/dist/config/worktree-defaults.d.ts.map +1 -0
  49. package/dist/config/worktree-defaults.js +78 -0
  50. package/dist/config/worktree-defaults.js.map +1 -0
  51. package/dist/index.d.ts +8 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +44 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/mcp/tools/compare-agents.d.ts +25 -0
  56. package/dist/mcp/tools/compare-agents.d.ts.map +1 -0
  57. package/dist/mcp/tools/compare-agents.js +177 -0
  58. package/dist/mcp/tools/compare-agents.js.map +1 -0
  59. package/dist/mcp/tools/critique-plan.d.ts +26 -0
  60. package/dist/mcp/tools/critique-plan.d.ts.map +1 -0
  61. package/dist/mcp/tools/critique-plan.js +162 -0
  62. package/dist/mcp/tools/critique-plan.js.map +1 -0
  63. package/dist/mcp/tools/design-feedback.d.ts +26 -0
  64. package/dist/mcp/tools/design-feedback.d.ts.map +1 -0
  65. package/dist/mcp/tools/design-feedback.js +216 -0
  66. package/dist/mcp/tools/design-feedback.js.map +1 -0
  67. package/dist/mcp/tools/index.d.ts +50 -0
  68. package/dist/mcp/tools/index.d.ts.map +1 -0
  69. package/dist/mcp/tools/index.js +191 -0
  70. package/dist/mcp/tools/index.js.map +1 -0
  71. package/dist/mcp/tools/invoke-agent.d.ts +25 -0
  72. package/dist/mcp/tools/invoke-agent.d.ts.map +1 -0
  73. package/dist/mcp/tools/invoke-agent.js +141 -0
  74. package/dist/mcp/tools/invoke-agent.js.map +1 -0
  75. package/dist/mcp/tools/review-code.d.ts +25 -0
  76. package/dist/mcp/tools/review-code.d.ts.map +1 -0
  77. package/dist/mcp/tools/review-code.js +170 -0
  78. package/dist/mcp/tools/review-code.js.map +1 -0
  79. package/dist/mcp/tools/tasks/claim-next-task.d.ts +22 -0
  80. package/dist/mcp/tools/tasks/claim-next-task.d.ts.map +1 -0
  81. package/dist/mcp/tools/tasks/claim-next-task.js +203 -0
  82. package/dist/mcp/tools/tasks/claim-next-task.js.map +1 -0
  83. package/dist/mcp/tools/tasks/create-routed-task.d.ts +17 -0
  84. package/dist/mcp/tools/tasks/create-routed-task.d.ts.map +1 -0
  85. package/dist/mcp/tools/tasks/create-routed-task.js +178 -0
  86. package/dist/mcp/tools/tasks/create-routed-task.js.map +1 -0
  87. package/dist/mcp/tools/tasks/execute-pipeline.d.ts +22 -0
  88. package/dist/mcp/tools/tasks/execute-pipeline.d.ts.map +1 -0
  89. package/dist/mcp/tools/tasks/execute-pipeline.js +401 -0
  90. package/dist/mcp/tools/tasks/execute-pipeline.js.map +1 -0
  91. package/dist/mcp/tools/tasks/execute-task.d.ts +32 -0
  92. package/dist/mcp/tools/tasks/execute-task.d.ts.map +1 -0
  93. package/dist/mcp/tools/tasks/execute-task.js +284 -0
  94. package/dist/mcp/tools/tasks/execute-task.js.map +1 -0
  95. package/dist/mcp/tools/tasks/get-pipeline-status.d.ts +26 -0
  96. package/dist/mcp/tools/tasks/get-pipeline-status.d.ts.map +1 -0
  97. package/dist/mcp/tools/tasks/get-pipeline-status.js +460 -0
  98. package/dist/mcp/tools/tasks/get-pipeline-status.js.map +1 -0
  99. package/dist/mcp/tools/tasks/index.d.ts +36 -0
  100. package/dist/mcp/tools/tasks/index.d.ts.map +1 -0
  101. package/dist/mcp/tools/tasks/index.js +66 -0
  102. package/dist/mcp/tools/tasks/index.js.map +1 -0
  103. package/dist/mcp/tools/worktree/cleanup-worktrees.d.ts +17 -0
  104. package/dist/mcp/tools/worktree/cleanup-worktrees.d.ts.map +1 -0
  105. package/dist/mcp/tools/worktree/cleanup-worktrees.js +147 -0
  106. package/dist/mcp/tools/worktree/cleanup-worktrees.js.map +1 -0
  107. package/dist/mcp/tools/worktree/get-worktree-status.d.ts +17 -0
  108. package/dist/mcp/tools/worktree/get-worktree-status.d.ts.map +1 -0
  109. package/dist/mcp/tools/worktree/get-worktree-status.js +123 -0
  110. package/dist/mcp/tools/worktree/get-worktree-status.js.map +1 -0
  111. package/dist/mcp/tools/worktree/index.d.ts +41 -0
  112. package/dist/mcp/tools/worktree/index.d.ts.map +1 -0
  113. package/dist/mcp/tools/worktree/index.js +69 -0
  114. package/dist/mcp/tools/worktree/index.js.map +1 -0
  115. package/dist/mcp/tools/worktree/list-worktrees.d.ts +17 -0
  116. package/dist/mcp/tools/worktree/list-worktrees.d.ts.map +1 -0
  117. package/dist/mcp/tools/worktree/list-worktrees.js +136 -0
  118. package/dist/mcp/tools/worktree/list-worktrees.js.map +1 -0
  119. package/dist/mcp/tools/worktree/resolve-conflicts.d.ts +19 -0
  120. package/dist/mcp/tools/worktree/resolve-conflicts.d.ts.map +1 -0
  121. package/dist/mcp/tools/worktree/resolve-conflicts.js +228 -0
  122. package/dist/mcp/tools/worktree/resolve-conflicts.js.map +1 -0
  123. package/dist/mcp/transport/stdio.d.ts +13 -0
  124. package/dist/mcp/transport/stdio.d.ts.map +1 -0
  125. package/dist/mcp/transport/stdio.js +15 -0
  126. package/dist/mcp/transport/stdio.js.map +1 -0
  127. package/dist/observability/logger.d.ts +137 -0
  128. package/dist/observability/logger.d.ts.map +1 -0
  129. package/dist/observability/logger.js +235 -0
  130. package/dist/observability/logger.js.map +1 -0
  131. package/dist/observability/metrics.d.ts +250 -0
  132. package/dist/observability/metrics.d.ts.map +1 -0
  133. package/dist/observability/metrics.js +364 -0
  134. package/dist/observability/metrics.js.map +1 -0
  135. package/dist/persistence/index.d.ts +9 -0
  136. package/dist/persistence/index.d.ts.map +1 -0
  137. package/dist/persistence/index.js +9 -0
  138. package/dist/persistence/index.js.map +1 -0
  139. package/dist/persistence/state-schema.d.ts +116 -0
  140. package/dist/persistence/state-schema.d.ts.map +1 -0
  141. package/dist/persistence/state-schema.js +28 -0
  142. package/dist/persistence/state-schema.js.map +1 -0
  143. package/dist/persistence/state-store.d.ts +111 -0
  144. package/dist/persistence/state-store.d.ts.map +1 -0
  145. package/dist/persistence/state-store.js +291 -0
  146. package/dist/persistence/state-store.js.map +1 -0
  147. package/dist/providers/anthropic.d.ts +164 -0
  148. package/dist/providers/anthropic.d.ts.map +1 -0
  149. package/dist/providers/anthropic.js +500 -0
  150. package/dist/providers/anthropic.js.map +1 -0
  151. package/dist/providers/base.d.ts +151 -0
  152. package/dist/providers/base.d.ts.map +1 -0
  153. package/dist/providers/base.js +227 -0
  154. package/dist/providers/base.js.map +1 -0
  155. package/dist/providers/gemini.d.ts +85 -0
  156. package/dist/providers/gemini.d.ts.map +1 -0
  157. package/dist/providers/gemini.js +414 -0
  158. package/dist/providers/gemini.js.map +1 -0
  159. package/dist/providers/kimi.d.ts +19 -0
  160. package/dist/providers/kimi.d.ts.map +1 -0
  161. package/dist/providers/kimi.js +20 -0
  162. package/dist/providers/kimi.js.map +1 -0
  163. package/dist/providers/manager.d.ts +160 -0
  164. package/dist/providers/manager.d.ts.map +1 -0
  165. package/dist/providers/manager.js +264 -0
  166. package/dist/providers/manager.js.map +1 -0
  167. package/dist/providers/ollama.d.ts +83 -0
  168. package/dist/providers/ollama.d.ts.map +1 -0
  169. package/dist/providers/ollama.js +453 -0
  170. package/dist/providers/ollama.js.map +1 -0
  171. package/dist/providers/openai.d.ts +96 -0
  172. package/dist/providers/openai.d.ts.map +1 -0
  173. package/dist/providers/openai.js +457 -0
  174. package/dist/providers/openai.js.map +1 -0
  175. package/dist/providers/zai.d.ts +19 -0
  176. package/dist/providers/zai.d.ts.map +1 -0
  177. package/dist/providers/zai.js +20 -0
  178. package/dist/providers/zai.js.map +1 -0
  179. package/dist/router/context-manager.d.ts +2 -0
  180. package/dist/router/context-manager.d.ts.map +1 -0
  181. package/dist/router/context-manager.js +3 -0
  182. package/dist/router/context-manager.js.map +1 -0
  183. package/dist/router/engine.d.ts +169 -0
  184. package/dist/router/engine.d.ts.map +1 -0
  185. package/dist/router/engine.js +435 -0
  186. package/dist/router/engine.js.map +1 -0
  187. package/dist/router/pattern-executor.d.ts +317 -0
  188. package/dist/router/pattern-executor.d.ts.map +1 -0
  189. package/dist/router/pattern-executor.js +571 -0
  190. package/dist/router/pattern-executor.js.map +1 -0
  191. package/dist/router/role-resolver.d.ts +59 -0
  192. package/dist/router/role-resolver.d.ts.map +1 -0
  193. package/dist/router/role-resolver.js +95 -0
  194. package/dist/router/role-resolver.js.map +1 -0
  195. package/dist/server.d.ts +32 -0
  196. package/dist/server.d.ts.map +1 -0
  197. package/dist/server.js +223 -0
  198. package/dist/server.js.map +1 -0
  199. package/dist/startup.d.ts +78 -0
  200. package/dist/startup.d.ts.map +1 -0
  201. package/dist/startup.js +107 -0
  202. package/dist/startup.js.map +1 -0
  203. package/dist/tasks/coordinator.d.ts +141 -0
  204. package/dist/tasks/coordinator.d.ts.map +1 -0
  205. package/dist/tasks/coordinator.js +331 -0
  206. package/dist/tasks/coordinator.js.map +1 -0
  207. package/dist/tasks/index.d.ts +13 -0
  208. package/dist/tasks/index.d.ts.map +1 -0
  209. package/dist/tasks/index.js +13 -0
  210. package/dist/tasks/index.js.map +1 -0
  211. package/dist/tasks/persistent-state-coordinator.d.ts +89 -0
  212. package/dist/tasks/persistent-state-coordinator.d.ts.map +1 -0
  213. package/dist/tasks/persistent-state-coordinator.js +371 -0
  214. package/dist/tasks/persistent-state-coordinator.js.map +1 -0
  215. package/dist/tasks/pipeline-manager.d.ts +103 -0
  216. package/dist/tasks/pipeline-manager.d.ts.map +1 -0
  217. package/dist/tasks/pipeline-manager.js +358 -0
  218. package/dist/tasks/pipeline-manager.js.map +1 -0
  219. package/dist/tasks/state-coordinator.d.ts +79 -0
  220. package/dist/tasks/state-coordinator.d.ts.map +1 -0
  221. package/dist/tasks/state-coordinator.js +200 -0
  222. package/dist/tasks/state-coordinator.js.map +1 -0
  223. package/dist/tasks/worker-mode.d.ts +65 -0
  224. package/dist/tasks/worker-mode.d.ts.map +1 -0
  225. package/dist/tasks/worker-mode.js +208 -0
  226. package/dist/tasks/worker-mode.js.map +1 -0
  227. package/dist/translation/errors.d.ts +203 -0
  228. package/dist/translation/errors.d.ts.map +1 -0
  229. package/dist/translation/errors.js +477 -0
  230. package/dist/translation/errors.js.map +1 -0
  231. package/dist/translation/index.d.ts +12 -0
  232. package/dist/translation/index.d.ts.map +1 -0
  233. package/dist/translation/index.js +32 -0
  234. package/dist/translation/index.js.map +1 -0
  235. package/dist/translation/messages.d.ts +295 -0
  236. package/dist/translation/messages.d.ts.map +1 -0
  237. package/dist/translation/messages.js +557 -0
  238. package/dist/translation/messages.js.map +1 -0
  239. package/dist/translation/streaming.d.ts +226 -0
  240. package/dist/translation/streaming.d.ts.map +1 -0
  241. package/dist/translation/streaming.js +520 -0
  242. package/dist/translation/streaming.js.map +1 -0
  243. package/dist/translation/tools.d.ts +209 -0
  244. package/dist/translation/tools.d.ts.map +1 -0
  245. package/dist/translation/tools.js +331 -0
  246. package/dist/translation/tools.js.map +1 -0
  247. package/dist/types.d.ts +747 -0
  248. package/dist/types.d.ts.map +1 -0
  249. package/dist/types.js +86 -0
  250. package/dist/types.js.map +1 -0
  251. package/dist/utils/circuit-breaker.d.ts +175 -0
  252. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  253. package/dist/utils/circuit-breaker.js +315 -0
  254. package/dist/utils/circuit-breaker.js.map +1 -0
  255. package/dist/utils/env.d.ts +2 -0
  256. package/dist/utils/env.d.ts.map +1 -0
  257. package/dist/utils/env.js +3 -0
  258. package/dist/utils/env.js.map +1 -0
  259. package/dist/utils/git.d.ts +58 -0
  260. package/dist/utils/git.d.ts.map +1 -0
  261. package/dist/utils/git.js +197 -0
  262. package/dist/utils/git.js.map +1 -0
  263. package/dist/utils/index.d.ts +9 -0
  264. package/dist/utils/index.d.ts.map +1 -0
  265. package/dist/utils/index.js +9 -0
  266. package/dist/utils/index.js.map +1 -0
  267. package/dist/utils/merge-ordering.d.ts +45 -0
  268. package/dist/utils/merge-ordering.d.ts.map +1 -0
  269. package/dist/utils/merge-ordering.js +128 -0
  270. package/dist/utils/merge-ordering.js.map +1 -0
  271. package/dist/utils/retry.d.ts +106 -0
  272. package/dist/utils/retry.d.ts.map +1 -0
  273. package/dist/utils/retry.js +188 -0
  274. package/dist/utils/retry.js.map +1 -0
  275. package/dist/worktrees/branch-manager.d.ts +55 -0
  276. package/dist/worktrees/branch-manager.d.ts.map +1 -0
  277. package/dist/worktrees/branch-manager.js +129 -0
  278. package/dist/worktrees/branch-manager.js.map +1 -0
  279. package/dist/worktrees/conflict-handler.d.ts +72 -0
  280. package/dist/worktrees/conflict-handler.d.ts.map +1 -0
  281. package/dist/worktrees/conflict-handler.js +287 -0
  282. package/dist/worktrees/conflict-handler.js.map +1 -0
  283. package/dist/worktrees/conflict-parser.d.ts +28 -0
  284. package/dist/worktrees/conflict-parser.d.ts.map +1 -0
  285. package/dist/worktrees/conflict-parser.js +140 -0
  286. package/dist/worktrees/conflict-parser.js.map +1 -0
  287. package/dist/worktrees/index.d.ts +20 -0
  288. package/dist/worktrees/index.d.ts.map +1 -0
  289. package/dist/worktrees/index.js +20 -0
  290. package/dist/worktrees/index.js.map +1 -0
  291. package/dist/worktrees/instructions.d.ts +20 -0
  292. package/dist/worktrees/instructions.d.ts.map +1 -0
  293. package/dist/worktrees/instructions.js +84 -0
  294. package/dist/worktrees/instructions.js.map +1 -0
  295. package/dist/worktrees/manager.d.ts +76 -0
  296. package/dist/worktrees/manager.d.ts.map +1 -0
  297. package/dist/worktrees/manager.js +277 -0
  298. package/dist/worktrees/manager.js.map +1 -0
  299. package/dist/worktrees/pipeline-merge-orchestrator.d.ts +55 -0
  300. package/dist/worktrees/pipeline-merge-orchestrator.d.ts.map +1 -0
  301. package/dist/worktrees/pipeline-merge-orchestrator.js +221 -0
  302. package/dist/worktrees/pipeline-merge-orchestrator.js.map +1 -0
  303. package/dist/worktrees/pool.d.ts +95 -0
  304. package/dist/worktrees/pool.d.ts.map +1 -0
  305. package/dist/worktrees/pool.js +271 -0
  306. package/dist/worktrees/pool.js.map +1 -0
  307. package/dist/worktrees/recovery.d.ts +94 -0
  308. package/dist/worktrees/recovery.d.ts.map +1 -0
  309. package/dist/worktrees/recovery.js +371 -0
  310. package/dist/worktrees/recovery.js.map +1 -0
  311. package/dist/worktrees/resource-manager.d.ts +74 -0
  312. package/dist/worktrees/resource-manager.d.ts.map +1 -0
  313. package/dist/worktrees/resource-manager.js +228 -0
  314. package/dist/worktrees/resource-manager.js.map +1 -0
  315. package/package.json +88 -0
package/dist/cli.js ADDED
@@ -0,0 +1,704 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AgentRouter CLI
4
+ *
5
+ * Command-line interface for the AgentRouter MCP server.
6
+ * Provides commands for starting the server, initializing configuration,
7
+ * listing roles, and validating configuration.
8
+ */
9
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
10
+ import { dirname } from "path";
11
+ import { stringify as stringifyYAML } from "yaml";
12
+ import { DEFAULT_CONFIG, getUserConfigPath } from "./config/defaults.js";
13
+ import { ConfigManager } from "./config/manager.js";
14
+ import { createServer, startServer } from "./server.js";
15
+ import { runSetupWizard, addProvider, testProvider, listProviders, } from "./cli/setup-wizard.js";
16
+ import { installSkills } from "./cli/install-skills.js";
17
+ import { statusCommand, orphansListCommand, orphansCleanupCommand, recoverCommand, stateExportCommand, stateImportCommand, } from "./cli/recovery-commands.js";
18
+ export const VERSION = "3.0.2";
19
+ // ============================================================================
20
+ // Constants
21
+ // ============================================================================
22
+ const HELP_TEXT = `
23
+ AgentRouter - MCP server for multi-agent orchestration
24
+
25
+ Usage:
26
+ agent-router [command] [options]
27
+
28
+ Commands:
29
+ setup Interactive setup wizard (recommended for first run)
30
+ start Start the MCP server (default)
31
+ init Create default config file
32
+ list-roles List available agent roles
33
+ validate Validate configuration
34
+ provider Manage providers (add, test, list)
35
+ install-skills Install AgentRouter skills to ~/.claude/skills/
36
+ status Show current state and recovery status
37
+ recover Run full recovery process
38
+ orphans Manage orphaned resources (list, cleanup)
39
+ state Export/import persisted state
40
+ version Show version
41
+ help Show this help message
42
+
43
+ Provider Subcommands:
44
+ provider add [name] Add a new provider interactively
45
+ provider test [name] Test provider connection(s)
46
+ provider list List configured providers
47
+
48
+ Recovery Subcommands:
49
+ orphans list List orphaned worktrees, tasks, and branches
50
+ orphans cleanup Clean up orphaned resources
51
+ state export <path> Export state to a JSON file
52
+ state import <path> Import state from a JSON file
53
+
54
+ Options:
55
+ --config, -c Path to config file
56
+ --profile, -p Profile name (default, development, production)
57
+ --verbose, -v Enable verbose logging
58
+ --dry-run Preview changes without applying them
59
+ --force, -f Skip confirmation prompts
60
+ --auto-cleanup Automatically clean up orphans during recovery
61
+ --help, -h Show help
62
+
63
+ Examples:
64
+ agent-router setup # Run interactive setup wizard
65
+ agent-router # Start server with default config
66
+ agent-router start -c config.yaml # Start with custom config
67
+ agent-router provider add openai # Add OpenAI provider
68
+ agent-router provider test # Test all providers
69
+ agent-router validate # Validate configuration
70
+ agent-router status # Check recovery status
71
+ agent-router recover --dry-run # Preview recovery actions
72
+ agent-router orphans list # List orphaned resources
73
+ agent-router orphans cleanup # Clean up orphans
74
+ agent-router state export backup.json # Export state
75
+
76
+ Getting Started:
77
+ New users should run 'agent-router setup' to configure providers
78
+ and API keys interactively.
79
+
80
+ Configuration:
81
+ Config files are searched in this order (highest priority first):
82
+ 1. --config flag value
83
+ 2. .agent-router.yaml in current directory
84
+ 3. ~/.config/agent-router/config.yaml (Linux/macOS)
85
+ 4. %APPDATA%/agent-router/config.yaml (Windows)
86
+
87
+ Environment variables can be interpolated using \${VAR_NAME} syntax.
88
+
89
+ For more information, visit: https://github.com/hive-dev/agent-router
90
+ `.trim();
91
+ // ============================================================================
92
+ // Argument Parsing
93
+ // ============================================================================
94
+ /**
95
+ * Parse command line arguments into CLIOptions.
96
+ *
97
+ * @param argv - Array of command line arguments (process.argv.slice(2))
98
+ * @returns Parsed CLI options
99
+ */
100
+ export function parseArgs(argv) {
101
+ const options = {
102
+ command: "start",
103
+ verbose: false,
104
+ help: false,
105
+ };
106
+ let i = 0;
107
+ while (i < argv.length) {
108
+ const arg = argv[i];
109
+ // Handle flags
110
+ if (arg === "--help" || arg === "-h") {
111
+ options.help = true;
112
+ i++;
113
+ continue;
114
+ }
115
+ if (arg === "--verbose" || arg === "-v") {
116
+ options.verbose = true;
117
+ i++;
118
+ continue;
119
+ }
120
+ if (arg === "--config" || arg === "-c") {
121
+ const nextArg = argv[i + 1];
122
+ if (!nextArg || nextArg.startsWith("-")) {
123
+ console.error("Error: --config requires a path argument");
124
+ process.exit(1);
125
+ }
126
+ options.configPath = nextArg;
127
+ i += 2;
128
+ continue;
129
+ }
130
+ if (arg === "--profile" || arg === "-p") {
131
+ const nextArg = argv[i + 1];
132
+ if (!nextArg || nextArg.startsWith("-")) {
133
+ console.error("Error: --profile requires a name argument");
134
+ process.exit(1);
135
+ }
136
+ options.profile = nextArg;
137
+ i += 2;
138
+ continue;
139
+ }
140
+ if (arg === "--dry-run") {
141
+ options.dryRun = true;
142
+ i++;
143
+ continue;
144
+ }
145
+ if (arg === "--force" || arg === "-f") {
146
+ options.force = true;
147
+ i++;
148
+ continue;
149
+ }
150
+ if (arg === "--auto-cleanup") {
151
+ options.autoCleanup = true;
152
+ i++;
153
+ continue;
154
+ }
155
+ // Handle combined short flags (e.g., -vh)
156
+ if (arg !== undefined && arg.startsWith("-") && !arg.startsWith("--") && arg.length > 2) {
157
+ const flags = arg.slice(1).split("");
158
+ for (const flag of flags) {
159
+ if (flag === "h")
160
+ options.help = true;
161
+ else if (flag === "v")
162
+ options.verbose = true;
163
+ else if (flag === "f")
164
+ options.force = true;
165
+ else {
166
+ console.error(`Error: Unknown flag: -${flag}`);
167
+ process.exit(1);
168
+ }
169
+ }
170
+ i++;
171
+ continue;
172
+ }
173
+ // Handle unknown flags
174
+ if (arg !== undefined && arg.startsWith("-")) {
175
+ console.error(`Error: Unknown option: ${arg}`);
176
+ console.error('Run "agent-router --help" for usage information.');
177
+ process.exit(1);
178
+ }
179
+ // Handle commands
180
+ const command = (arg ?? "").toLowerCase();
181
+ if (isValidCommand(command)) {
182
+ options.command = command;
183
+ // Handle provider subcommands
184
+ if (command === "provider") {
185
+ const subcommand = argv[i + 1];
186
+ if (subcommand && !subcommand.startsWith("-")) {
187
+ if (isValidProviderSubcommand(subcommand)) {
188
+ options.providerSubcommand = subcommand;
189
+ i++;
190
+ // Check for optional provider name argument (for 'add' and 'test')
191
+ if (subcommand === "add" || subcommand === "test") {
192
+ const providerName = argv[i + 1];
193
+ if (providerName && !providerName.startsWith("-")) {
194
+ options.providerName = providerName;
195
+ i++;
196
+ }
197
+ }
198
+ }
199
+ else {
200
+ console.error(`Error: Unknown provider subcommand: ${subcommand}`);
201
+ console.error("Available subcommands: add, test, list");
202
+ process.exit(1);
203
+ }
204
+ }
205
+ else {
206
+ // No subcommand provided, show provider help
207
+ console.error("Error: provider command requires a subcommand");
208
+ console.error("Usage: agent-router provider <add|test|list> [name]");
209
+ process.exit(1);
210
+ }
211
+ }
212
+ // Handle orphans subcommands
213
+ if (command === "orphans") {
214
+ const subcommand = argv[i + 1];
215
+ if (subcommand && !subcommand.startsWith("-")) {
216
+ if (isValidOrphansSubcommand(subcommand)) {
217
+ options.orphansSubcommand = subcommand;
218
+ i++;
219
+ }
220
+ else {
221
+ console.error(`Error: Unknown orphans subcommand: ${subcommand}`);
222
+ console.error("Available subcommands: list, cleanup");
223
+ process.exit(1);
224
+ }
225
+ }
226
+ else {
227
+ // Default to list if no subcommand
228
+ options.orphansSubcommand = "list";
229
+ }
230
+ }
231
+ // Handle state subcommands
232
+ if (command === "state") {
233
+ const subcommand = argv[i + 1];
234
+ if (subcommand && !subcommand.startsWith("-")) {
235
+ if (isValidStateSubcommand(subcommand)) {
236
+ options.stateSubcommand = subcommand;
237
+ i++;
238
+ // Get required path argument
239
+ const pathArg = argv[i + 1];
240
+ if (pathArg && !pathArg.startsWith("-")) {
241
+ options.statePath = pathArg;
242
+ i++;
243
+ }
244
+ else {
245
+ console.error(`Error: state ${subcommand} requires a path argument`);
246
+ console.error(`Usage: agent-router state ${subcommand} <path>`);
247
+ process.exit(1);
248
+ }
249
+ }
250
+ else {
251
+ console.error(`Error: Unknown state subcommand: ${subcommand}`);
252
+ console.error("Available subcommands: export, import");
253
+ process.exit(1);
254
+ }
255
+ }
256
+ else {
257
+ console.error("Error: state command requires a subcommand");
258
+ console.error("Usage: agent-router state <export|import> <path>");
259
+ process.exit(1);
260
+ }
261
+ }
262
+ }
263
+ else {
264
+ console.error(`Error: Unknown command: ${arg}`);
265
+ console.error('Run "agent-router --help" for usage information.');
266
+ process.exit(1);
267
+ }
268
+ i++;
269
+ }
270
+ // If help flag is set, override command to help
271
+ if (options.help) {
272
+ options.command = "help";
273
+ }
274
+ return options;
275
+ }
276
+ /**
277
+ * Check if a string is a valid command.
278
+ */
279
+ function isValidCommand(cmd) {
280
+ return [
281
+ "setup", "start", "init", "list-roles", "validate", "version", "help",
282
+ "provider", "install-skills", "status", "recover", "orphans", "state"
283
+ ].includes(cmd);
284
+ }
285
+ /**
286
+ * Check if a string is a valid provider subcommand.
287
+ */
288
+ function isValidProviderSubcommand(cmd) {
289
+ return ["add", "test", "list"].includes(cmd);
290
+ }
291
+ /**
292
+ * Check if a string is a valid orphans subcommand.
293
+ */
294
+ function isValidOrphansSubcommand(cmd) {
295
+ return ["list", "cleanup"].includes(cmd);
296
+ }
297
+ /**
298
+ * Check if a string is a valid state subcommand.
299
+ */
300
+ function isValidStateSubcommand(cmd) {
301
+ return ["export", "import"].includes(cmd);
302
+ }
303
+ // ============================================================================
304
+ // Command Implementations
305
+ // ============================================================================
306
+ /**
307
+ * Run the setup wizard.
308
+ */
309
+ async function cmdSetup(_options) {
310
+ await runSetupWizard();
311
+ }
312
+ /**
313
+ * Handle provider subcommands.
314
+ */
315
+ async function cmdProvider(options) {
316
+ switch (options.providerSubcommand) {
317
+ case "add":
318
+ await addProvider(options.providerName);
319
+ break;
320
+ case "test":
321
+ await testProvider(options.providerName);
322
+ break;
323
+ case "list":
324
+ await listProviders();
325
+ break;
326
+ default:
327
+ console.error("Error: provider command requires a subcommand");
328
+ console.error("Usage: agent-router provider <add|test|list> [name]");
329
+ process.exit(1);
330
+ }
331
+ }
332
+ /**
333
+ * Handle status command.
334
+ */
335
+ async function cmdStatus(options) {
336
+ await statusCommand({
337
+ repoPath: process.cwd(),
338
+ dryRun: options.dryRun,
339
+ });
340
+ }
341
+ /**
342
+ * Handle recover command.
343
+ */
344
+ async function cmdRecover(options) {
345
+ await recoverCommand({
346
+ repoPath: process.cwd(),
347
+ dryRun: options.dryRun,
348
+ autoCleanup: options.autoCleanup,
349
+ force: options.force,
350
+ });
351
+ }
352
+ /**
353
+ * Handle orphans subcommands.
354
+ */
355
+ async function cmdOrphans(options) {
356
+ switch (options.orphansSubcommand) {
357
+ case "list":
358
+ await orphansListCommand({
359
+ repoPath: process.cwd(),
360
+ });
361
+ break;
362
+ case "cleanup":
363
+ await orphansCleanupCommand({
364
+ repoPath: process.cwd(),
365
+ dryRun: options.dryRun,
366
+ force: options.force,
367
+ });
368
+ break;
369
+ default:
370
+ await orphansListCommand({
371
+ repoPath: process.cwd(),
372
+ });
373
+ }
374
+ }
375
+ /**
376
+ * Handle state subcommands.
377
+ */
378
+ async function cmdState(options) {
379
+ if (!options.statePath) {
380
+ console.error("Error: state command requires a path argument");
381
+ console.error("Usage: agent-router state <export|import> <path>");
382
+ process.exit(1);
383
+ }
384
+ switch (options.stateSubcommand) {
385
+ case "export":
386
+ await stateExportCommand({
387
+ repoPath: process.cwd(),
388
+ outputPath: options.statePath,
389
+ });
390
+ break;
391
+ case "import":
392
+ await stateImportCommand({
393
+ repoPath: process.cwd(),
394
+ inputPath: options.statePath,
395
+ force: options.force,
396
+ });
397
+ break;
398
+ default:
399
+ console.error("Error: state command requires a subcommand");
400
+ console.error("Usage: agent-router state <export|import> <path>");
401
+ process.exit(1);
402
+ }
403
+ }
404
+ /**
405
+ * Start the MCP server.
406
+ */
407
+ async function cmdStart(options) {
408
+ // Check if config exists, suggest setup if not
409
+ const configPath = options.configPath || getUserConfigPath();
410
+ if (!existsSync(configPath) && !options.configPath) {
411
+ console.error("[AgentRouter] No configuration file found.");
412
+ console.error("");
413
+ console.error(" Run 'agent-router setup' to configure AgentRouter interactively.");
414
+ console.error(" Or run 'agent-router init' to create a default config file.");
415
+ console.error("");
416
+ process.exit(1);
417
+ }
418
+ if (options.verbose) {
419
+ console.error("[AgentRouter] Starting MCP server...");
420
+ if (options.configPath) {
421
+ console.error(`[AgentRouter] Using config: ${options.configPath}`);
422
+ }
423
+ if (options.profile) {
424
+ console.error(`[AgentRouter] Profile: ${options.profile}`);
425
+ }
426
+ }
427
+ // Set environment variable for config path if provided
428
+ if (options.configPath) {
429
+ process.env["AGENT_ROUTER_CONFIG"] = options.configPath;
430
+ }
431
+ const server = await createServer();
432
+ await startServer(server);
433
+ }
434
+ /**
435
+ * Initialize configuration file.
436
+ */
437
+ async function cmdInit(options) {
438
+ const configPath = options.configPath ?? getUserConfigPath();
439
+ const configDir = dirname(configPath);
440
+ // Check if config already exists
441
+ if (existsSync(configPath)) {
442
+ console.error(`Configuration file already exists: ${configPath}`);
443
+ console.error("Use --config to specify a different path, or delete the existing file.");
444
+ process.exit(1);
445
+ }
446
+ // Create directory if needed
447
+ if (!existsSync(configDir)) {
448
+ if (options.verbose) {
449
+ console.error(`Creating directory: ${configDir}`);
450
+ }
451
+ mkdirSync(configDir, { recursive: true });
452
+ }
453
+ // Generate default config as YAML
454
+ const configYAML = stringifyYAML(DEFAULT_CONFIG, {
455
+ indent: 2,
456
+ lineWidth: 100,
457
+ });
458
+ // Add header comment
459
+ const header = `# AgentRouter Configuration
460
+ # Generated by: agent-router init
461
+ # Documentation: https://github.com/hive-dev/agent-router
462
+ #
463
+ # Environment variables can be interpolated using \${VAR_NAME} syntax.
464
+ # Example: api_key: \${ANTHROPIC_API_KEY}
465
+
466
+ `;
467
+ writeFileSync(configPath, header + configYAML, "utf-8");
468
+ console.log(`Configuration file created: ${configPath}`);
469
+ console.log("");
470
+ console.log("Next steps:");
471
+ console.log(" 1. Edit the config file to set your API keys");
472
+ console.log(" 2. Customize roles and providers as needed");
473
+ console.log(' 3. Run "agent-router validate" to check your configuration');
474
+ console.log(' 4. Run "agent-router start" to start the MCP server');
475
+ }
476
+ /**
477
+ * List available agent roles.
478
+ */
479
+ async function cmdListRoles(options) {
480
+ try {
481
+ const managerOptions = {
482
+ watch: false,
483
+ allowMissingEnv: true,
484
+ ...(options.configPath ? { configPath: options.configPath } : {}),
485
+ };
486
+ const manager = await ConfigManager.load(managerOptions);
487
+ const config = manager.get();
488
+ const roles = Object.entries(config.roles);
489
+ if (roles.length === 0) {
490
+ console.log("No roles configured.");
491
+ return;
492
+ }
493
+ console.log("Available agent roles:");
494
+ console.log("");
495
+ for (const [roleName, roleConfig] of roles) {
496
+ const fallbackInfo = roleConfig.fallback
497
+ ? ` (fallback: ${roleConfig.fallback.provider}/${roleConfig.fallback.model})`
498
+ : "";
499
+ console.log(` ${roleName}`);
500
+ console.log(` Provider: ${roleConfig.provider}`);
501
+ console.log(` Model: ${roleConfig.model}${fallbackInfo}`);
502
+ if (options.verbose && roleConfig.system_prompt) {
503
+ // Show first 100 chars of system prompt
504
+ const preview = roleConfig.system_prompt.slice(0, 100).replace(/\n/g, " ");
505
+ const truncated = roleConfig.system_prompt.length > 100 ? "..." : "";
506
+ console.log(` Prompt: ${preview}${truncated}`);
507
+ }
508
+ console.log("");
509
+ }
510
+ console.log(`Total: ${roles.length} role(s)`);
511
+ // Also show loaded config paths in verbose mode
512
+ if (options.verbose) {
513
+ const loadedPaths = manager.getLoadedPaths();
514
+ if (loadedPaths.length > 0) {
515
+ console.log("");
516
+ console.log("Loaded from:");
517
+ for (const path of loadedPaths) {
518
+ console.log(` - ${path}`);
519
+ }
520
+ }
521
+ }
522
+ manager.close();
523
+ }
524
+ catch (error) {
525
+ const message = error instanceof Error ? error.message : String(error);
526
+ console.error(`Error loading configuration: ${message}`);
527
+ process.exit(1);
528
+ }
529
+ }
530
+ /**
531
+ * Validate configuration.
532
+ */
533
+ async function cmdValidate(options) {
534
+ console.log("Validating configuration...");
535
+ console.log("");
536
+ try {
537
+ const validateOptions = {
538
+ watch: false,
539
+ allowMissingEnv: true, // Don't fail on missing env vars during validation
540
+ ...(options.configPath ? { configPath: options.configPath } : {}),
541
+ };
542
+ const manager = await ConfigManager.load(validateOptions);
543
+ const config = manager.get();
544
+ const loadedPaths = manager.getLoadedPaths();
545
+ // Report loaded files
546
+ if (loadedPaths.length === 0) {
547
+ console.log("No configuration files found. Using default configuration.");
548
+ }
549
+ else {
550
+ console.log("Configuration files loaded:");
551
+ for (const path of loadedPaths) {
552
+ console.log(` - ${path}`);
553
+ }
554
+ }
555
+ console.log("");
556
+ // Report configuration summary
557
+ console.log("Configuration summary:");
558
+ console.log(` Version: ${config.version}`);
559
+ console.log(` Roles: ${Object.keys(config.roles).length}`);
560
+ console.log(` Providers: ${Object.keys(config.providers).length}`);
561
+ console.log("");
562
+ // Check for potential issues
563
+ const warnings = [];
564
+ // Check if any roles reference non-existent providers
565
+ for (const [roleName, roleConfig] of Object.entries(config.roles)) {
566
+ if (!config.providers[roleConfig.provider]) {
567
+ warnings.push(`Role "${roleName}" references unknown provider "${roleConfig.provider}"`);
568
+ }
569
+ if (roleConfig.fallback && !config.providers[roleConfig.fallback.provider]) {
570
+ warnings.push(`Role "${roleName}" fallback references unknown provider "${roleConfig.fallback.provider}"`);
571
+ }
572
+ }
573
+ // Check for missing API keys
574
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
575
+ if (providerConfig.api_key?.includes("${")) {
576
+ warnings.push(`Provider "${providerName}" has unresolved environment variable in api_key`);
577
+ }
578
+ }
579
+ if (warnings.length > 0) {
580
+ console.log("Warnings:");
581
+ for (const warning of warnings) {
582
+ console.log(` - ${warning}`);
583
+ }
584
+ console.log("");
585
+ }
586
+ console.log("Configuration is valid.");
587
+ manager.close();
588
+ }
589
+ catch (error) {
590
+ const message = error instanceof Error ? error.message : String(error);
591
+ console.error(`Configuration validation failed: ${message}`);
592
+ console.error("");
593
+ console.error("Tip: Run 'agent-router setup' to configure AgentRouter interactively.");
594
+ process.exit(1);
595
+ }
596
+ }
597
+ /**
598
+ * Show version.
599
+ */
600
+ function cmdVersion() {
601
+ console.log(`agent-router ${VERSION}`);
602
+ }
603
+ /**
604
+ * Show help.
605
+ */
606
+ function cmdHelp() {
607
+ console.log(HELP_TEXT);
608
+ }
609
+ // ============================================================================
610
+ // Main Entry Point
611
+ // ============================================================================
612
+ /**
613
+ * Run the CLI with the given options.
614
+ *
615
+ * @param options - Parsed CLI options
616
+ */
617
+ export async function runCLI(options) {
618
+ switch (options.command) {
619
+ case "setup":
620
+ await cmdSetup(options);
621
+ break;
622
+ case "start":
623
+ await cmdStart(options);
624
+ break;
625
+ case "init":
626
+ await cmdInit(options);
627
+ break;
628
+ case "list-roles":
629
+ await cmdListRoles(options);
630
+ break;
631
+ case "validate":
632
+ await cmdValidate(options);
633
+ break;
634
+ case "provider":
635
+ await cmdProvider(options);
636
+ break;
637
+ case "install-skills":
638
+ await installSkills();
639
+ break;
640
+ case "status":
641
+ await statusCommand({ repoPath: process.cwd(), ...options });
642
+ break;
643
+ case "recover":
644
+ await recoverCommand({ repoPath: process.cwd(), ...options });
645
+ break;
646
+ case "orphans":
647
+ if (options.orphansSubcommand === "cleanup") {
648
+ await orphansCleanupCommand({ repoPath: process.cwd(), ...options });
649
+ }
650
+ else {
651
+ await orphansListCommand({ repoPath: process.cwd(), ...options });
652
+ }
653
+ break;
654
+ case "state":
655
+ if (options.stateSubcommand === "import") {
656
+ await stateImportCommand({ repoPath: process.cwd(), inputPath: options.statePath || 'state-export.json', ...options });
657
+ }
658
+ else {
659
+ await stateExportCommand({ repoPath: process.cwd(), outputPath: options.statePath || 'state-export.json', ...options });
660
+ }
661
+ break;
662
+ case "version":
663
+ cmdVersion();
664
+ break;
665
+ case "help":
666
+ cmdHelp();
667
+ break;
668
+ default: {
669
+ // Type guard for exhaustiveness check
670
+ const _exhaustive = options.command;
671
+ console.error(`Unknown command: ${_exhaustive}`);
672
+ process.exit(1);
673
+ }
674
+ }
675
+ }
676
+ /**
677
+ * Main entry point for the CLI.
678
+ * Parses arguments and executes the appropriate command.
679
+ */
680
+ export function main() {
681
+ const options = parseArgs(process.argv.slice(2));
682
+ runCLI(options).catch((error) => {
683
+ const message = error instanceof Error ? error.message : String(error);
684
+ console.error(`Error: ${message}`);
685
+ process.exit(1);
686
+ });
687
+ }
688
+ // Graceful shutdown handling
689
+ function setupShutdownHandlers() {
690
+ const shutdown = (signal) => {
691
+ console.error(`\nReceived ${signal}, shutting down gracefully...`);
692
+ process.exit(0);
693
+ };
694
+ process.on("SIGINT", () => {
695
+ shutdown("SIGINT");
696
+ });
697
+ process.on("SIGTERM", () => {
698
+ shutdown("SIGTERM");
699
+ });
700
+ }
701
+ // Run if executed directly
702
+ setupShutdownHandlers();
703
+ main();
704
+ //# sourceMappingURL=cli.js.map