claude-flow 3.0.0-alpha.1 → 3.0.0-alpha.10

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 (243) hide show
  1. package/README.md +1151 -41
  2. package/bin/cli.js +8 -30
  3. package/dist/src/commands/agent.d.ts +8 -0
  4. package/dist/src/commands/agent.d.ts.map +1 -0
  5. package/dist/src/commands/agent.js +819 -0
  6. package/dist/src/commands/agent.js.map +1 -0
  7. package/dist/src/commands/config.d.ts +8 -0
  8. package/dist/src/commands/config.d.ts.map +1 -0
  9. package/dist/src/commands/config.js +406 -0
  10. package/dist/src/commands/config.js.map +1 -0
  11. package/dist/src/commands/daemon.d.ts +8 -0
  12. package/dist/src/commands/daemon.d.ts.map +1 -0
  13. package/dist/src/commands/daemon.js +545 -0
  14. package/dist/src/commands/daemon.js.map +1 -0
  15. package/dist/src/commands/hive-mind.d.ts +8 -0
  16. package/dist/src/commands/hive-mind.d.ts.map +1 -0
  17. package/dist/src/commands/hive-mind.js +844 -0
  18. package/dist/src/commands/hive-mind.js.map +1 -0
  19. package/dist/src/commands/hooks.d.ts +8 -0
  20. package/dist/src/commands/hooks.d.ts.map +1 -0
  21. package/dist/src/commands/hooks.js +2098 -0
  22. package/dist/src/commands/hooks.js.map +1 -0
  23. package/dist/src/commands/index.d.ts +52 -0
  24. package/dist/src/commands/index.d.ts.map +1 -0
  25. package/dist/src/commands/index.js +108 -0
  26. package/dist/src/commands/index.js.map +1 -0
  27. package/dist/src/commands/init.d.ts +8 -0
  28. package/dist/src/commands/init.d.ts.map +1 -0
  29. package/dist/src/commands/init.js +532 -0
  30. package/dist/src/commands/init.js.map +1 -0
  31. package/dist/src/commands/mcp.d.ts +11 -0
  32. package/dist/src/commands/mcp.d.ts.map +1 -0
  33. package/dist/src/commands/mcp.js +662 -0
  34. package/dist/src/commands/mcp.js.map +1 -0
  35. package/dist/src/commands/memory.d.ts +8 -0
  36. package/dist/src/commands/memory.d.ts.map +1 -0
  37. package/dist/src/commands/memory.js +977 -0
  38. package/dist/src/commands/memory.js.map +1 -0
  39. package/dist/src/commands/migrate.d.ts +8 -0
  40. package/dist/src/commands/migrate.d.ts.map +1 -0
  41. package/dist/src/commands/migrate.js +398 -0
  42. package/dist/src/commands/migrate.js.map +1 -0
  43. package/dist/src/commands/process.d.ts +10 -0
  44. package/dist/src/commands/process.d.ts.map +1 -0
  45. package/dist/src/commands/process.js +641 -0
  46. package/dist/src/commands/process.js.map +1 -0
  47. package/dist/src/commands/session.d.ts +8 -0
  48. package/dist/src/commands/session.d.ts.map +1 -0
  49. package/dist/src/commands/session.js +750 -0
  50. package/dist/src/commands/session.js.map +1 -0
  51. package/dist/src/commands/start.d.ts +8 -0
  52. package/dist/src/commands/start.d.ts.map +1 -0
  53. package/dist/src/commands/start.js +398 -0
  54. package/dist/src/commands/start.js.map +1 -0
  55. package/dist/src/commands/status.d.ts +8 -0
  56. package/dist/src/commands/status.d.ts.map +1 -0
  57. package/dist/src/commands/status.js +584 -0
  58. package/dist/src/commands/status.js.map +1 -0
  59. package/dist/src/commands/swarm.d.ts +8 -0
  60. package/dist/src/commands/swarm.d.ts.map +1 -0
  61. package/dist/src/commands/swarm.js +573 -0
  62. package/dist/src/commands/swarm.js.map +1 -0
  63. package/dist/src/commands/task.d.ts +8 -0
  64. package/dist/src/commands/task.d.ts.map +1 -0
  65. package/dist/src/commands/task.js +671 -0
  66. package/dist/src/commands/task.js.map +1 -0
  67. package/dist/src/commands/workflow.d.ts +8 -0
  68. package/dist/src/commands/workflow.d.ts.map +1 -0
  69. package/dist/src/commands/workflow.js +617 -0
  70. package/dist/src/commands/workflow.js.map +1 -0
  71. package/dist/src/config-adapter.d.ts +15 -0
  72. package/dist/src/config-adapter.d.ts.map +1 -0
  73. package/dist/src/config-adapter.js +185 -0
  74. package/dist/src/config-adapter.js.map +1 -0
  75. package/dist/src/index.d.ts +55 -0
  76. package/dist/src/index.d.ts.map +1 -0
  77. package/dist/src/index.js +353 -0
  78. package/dist/src/index.js.map +1 -0
  79. package/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
  80. package/dist/src/infrastructure/in-memory-repositories.d.ts.map +1 -0
  81. package/dist/src/infrastructure/in-memory-repositories.js +264 -0
  82. package/dist/src/infrastructure/in-memory-repositories.js.map +1 -0
  83. package/dist/src/init/claudemd-generator.d.ts +15 -0
  84. package/dist/src/init/claudemd-generator.d.ts.map +1 -0
  85. package/dist/src/init/claudemd-generator.js +626 -0
  86. package/dist/src/init/claudemd-generator.js.map +1 -0
  87. package/dist/src/init/executor.d.ts +11 -0
  88. package/dist/src/init/executor.d.ts.map +1 -0
  89. package/dist/src/init/executor.js +652 -0
  90. package/dist/src/init/executor.js.map +1 -0
  91. package/dist/src/init/helpers-generator.d.ts +42 -0
  92. package/dist/src/init/helpers-generator.d.ts.map +1 -0
  93. package/dist/src/init/helpers-generator.js +613 -0
  94. package/dist/src/init/helpers-generator.js.map +1 -0
  95. package/dist/src/init/index.d.ts +12 -0
  96. package/dist/src/init/index.d.ts.map +1 -0
  97. package/dist/src/init/index.js +15 -0
  98. package/dist/src/init/index.js.map +1 -0
  99. package/dist/src/init/mcp-generator.d.ts +18 -0
  100. package/dist/src/init/mcp-generator.d.ts.map +1 -0
  101. package/dist/src/init/mcp-generator.js +71 -0
  102. package/dist/src/init/mcp-generator.js.map +1 -0
  103. package/dist/src/init/settings-generator.d.ts +14 -0
  104. package/dist/src/init/settings-generator.d.ts.map +1 -0
  105. package/dist/src/init/settings-generator.js +267 -0
  106. package/dist/src/init/settings-generator.js.map +1 -0
  107. package/dist/src/init/statusline-generator.d.ts +14 -0
  108. package/dist/src/init/statusline-generator.d.ts.map +1 -0
  109. package/dist/src/init/statusline-generator.js +206 -0
  110. package/dist/src/init/statusline-generator.js.map +1 -0
  111. package/dist/src/init/types.d.ts +240 -0
  112. package/dist/src/init/types.d.ts.map +1 -0
  113. package/dist/src/init/types.js +210 -0
  114. package/dist/src/init/types.js.map +1 -0
  115. package/dist/src/mcp-client.d.ts +92 -0
  116. package/dist/src/mcp-client.d.ts.map +1 -0
  117. package/dist/src/mcp-client.js +203 -0
  118. package/dist/src/mcp-client.js.map +1 -0
  119. package/dist/src/mcp-server.d.ts +153 -0
  120. package/dist/src/mcp-server.d.ts.map +1 -0
  121. package/dist/src/mcp-server.js +453 -0
  122. package/dist/src/mcp-server.js.map +1 -0
  123. package/dist/src/mcp-tools/agent-tools.d.ts +8 -0
  124. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -0
  125. package/dist/src/mcp-tools/agent-tools.js +426 -0
  126. package/dist/src/mcp-tools/agent-tools.js.map +1 -0
  127. package/dist/src/mcp-tools/config-tools.d.ts +8 -0
  128. package/dist/src/mcp-tools/config-tools.d.ts.map +1 -0
  129. package/dist/src/mcp-tools/config-tools.js +333 -0
  130. package/dist/src/mcp-tools/config-tools.js.map +1 -0
  131. package/dist/src/mcp-tools/hive-mind-tools.d.ts +8 -0
  132. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -0
  133. package/dist/src/mcp-tools/hive-mind-tools.js +447 -0
  134. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -0
  135. package/dist/src/mcp-tools/hooks-tools.d.ts +41 -0
  136. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -0
  137. package/dist/src/mcp-tools/hooks-tools.js +1711 -0
  138. package/dist/src/mcp-tools/hooks-tools.js.map +1 -0
  139. package/dist/src/mcp-tools/index.d.ts +16 -0
  140. package/dist/src/mcp-tools/index.d.ts.map +1 -0
  141. package/dist/src/mcp-tools/index.js +15 -0
  142. package/dist/src/mcp-tools/index.js.map +1 -0
  143. package/dist/src/mcp-tools/memory-tools.d.ts +8 -0
  144. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -0
  145. package/dist/src/mcp-tools/memory-tools.js +235 -0
  146. package/dist/src/mcp-tools/memory-tools.js.map +1 -0
  147. package/dist/src/mcp-tools/session-tools.d.ts +8 -0
  148. package/dist/src/mcp-tools/session-tools.d.ts.map +1 -0
  149. package/dist/src/mcp-tools/session-tools.js +315 -0
  150. package/dist/src/mcp-tools/session-tools.js.map +1 -0
  151. package/dist/src/mcp-tools/swarm-tools.d.ts +8 -0
  152. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -0
  153. package/dist/src/mcp-tools/swarm-tools.js +102 -0
  154. package/dist/src/mcp-tools/swarm-tools.js.map +1 -0
  155. package/dist/src/mcp-tools/task-tools.d.ts +8 -0
  156. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -0
  157. package/dist/src/mcp-tools/task-tools.js +302 -0
  158. package/dist/src/mcp-tools/task-tools.js.map +1 -0
  159. package/dist/src/mcp-tools/types.d.ts +31 -0
  160. package/dist/src/mcp-tools/types.d.ts.map +1 -0
  161. package/dist/src/mcp-tools/types.js +7 -0
  162. package/dist/src/mcp-tools/types.js.map +1 -0
  163. package/dist/src/mcp-tools/workflow-tools.d.ts +8 -0
  164. package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -0
  165. package/dist/src/mcp-tools/workflow-tools.js +481 -0
  166. package/dist/src/mcp-tools/workflow-tools.js.map +1 -0
  167. package/dist/src/output.d.ts +133 -0
  168. package/dist/src/output.d.ts.map +1 -0
  169. package/dist/src/output.js +513 -0
  170. package/dist/src/output.js.map +1 -0
  171. package/dist/src/parser.d.ts +41 -0
  172. package/dist/src/parser.d.ts.map +1 -0
  173. package/dist/src/parser.js +353 -0
  174. package/dist/src/parser.js.map +1 -0
  175. package/dist/src/prompt.d.ts +44 -0
  176. package/dist/src/prompt.d.ts.map +1 -0
  177. package/dist/src/prompt.js +501 -0
  178. package/dist/src/prompt.js.map +1 -0
  179. package/dist/src/services/index.d.ts +7 -0
  180. package/dist/src/services/index.d.ts.map +1 -0
  181. package/dist/src/services/index.js +6 -0
  182. package/dist/src/services/index.js.map +1 -0
  183. package/dist/src/services/worker-daemon.d.ts +153 -0
  184. package/dist/src/services/worker-daemon.d.ts.map +1 -0
  185. package/dist/src/services/worker-daemon.js +567 -0
  186. package/dist/src/services/worker-daemon.js.map +1 -0
  187. package/dist/src/types.d.ts +198 -0
  188. package/dist/src/types.d.ts.map +1 -0
  189. package/dist/src/types.js +38 -0
  190. package/dist/src/types.js.map +1 -0
  191. package/dist/tsconfig.tsbuildinfo +1 -0
  192. package/package.json +12 -52
  193. package/src/commands/agent.ts +955 -0
  194. package/src/commands/config.ts +452 -0
  195. package/src/commands/daemon.ts +621 -0
  196. package/src/commands/hive-mind.ts +928 -0
  197. package/src/commands/hooks.ts +2603 -0
  198. package/src/commands/index.ts +118 -0
  199. package/src/commands/init.ts +597 -0
  200. package/src/commands/mcp.ts +753 -0
  201. package/src/commands/memory.ts +1161 -0
  202. package/src/commands/migrate.ts +447 -0
  203. package/src/commands/process.ts +695 -0
  204. package/src/commands/session.ts +891 -0
  205. package/src/commands/start.ts +457 -0
  206. package/src/commands/status.ts +736 -0
  207. package/src/commands/swarm.ts +648 -0
  208. package/src/commands/task.ts +792 -0
  209. package/src/commands/workflow.ts +742 -0
  210. package/src/config-adapter.ts +210 -0
  211. package/src/index.ts +427 -0
  212. package/src/infrastructure/in-memory-repositories.ts +310 -0
  213. package/src/init/claudemd-generator.ts +631 -0
  214. package/src/init/executor.ts +762 -0
  215. package/src/init/helpers-generator.ts +628 -0
  216. package/src/init/index.ts +60 -0
  217. package/src/init/mcp-generator.ts +83 -0
  218. package/src/init/settings-generator.ts +284 -0
  219. package/src/init/statusline-generator.ts +211 -0
  220. package/src/init/types.ts +447 -0
  221. package/src/mcp-client.ts +241 -0
  222. package/src/mcp-server.ts +577 -0
  223. package/src/mcp-tools/agent-tools.ts +466 -0
  224. package/src/mcp-tools/config-tools.ts +370 -0
  225. package/src/mcp-tools/hive-mind-tools.ts +521 -0
  226. package/src/mcp-tools/hooks-tools.ts +1888 -0
  227. package/src/mcp-tools/index.ts +16 -0
  228. package/src/mcp-tools/memory-tools.ts +270 -0
  229. package/src/mcp-tools/session-tools.ts +359 -0
  230. package/src/mcp-tools/swarm-tools.ts +105 -0
  231. package/src/mcp-tools/task-tools.ts +347 -0
  232. package/src/mcp-tools/types.ts +33 -0
  233. package/src/mcp-tools/workflow-tools.ts +573 -0
  234. package/src/output.ts +639 -0
  235. package/src/parser.ts +417 -0
  236. package/src/prompt.ts +619 -0
  237. package/src/services/index.ts +15 -0
  238. package/src/services/worker-daemon.ts +726 -0
  239. package/src/types.ts +287 -0
  240. package/dist/index.d.ts +0 -30
  241. package/dist/index.d.ts.map +0 -1
  242. package/dist/index.js +0 -30
  243. package/dist/index.js.map +0 -1
@@ -0,0 +1,466 @@
1
+ /**
2
+ * Agent MCP Tools for CLI
3
+ *
4
+ * Tool definitions for agent lifecycle management with file persistence.
5
+ */
6
+
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import type { MCPTool } from './types.js';
10
+
11
+ // Storage paths
12
+ const STORAGE_DIR = '.claude-flow';
13
+ const AGENT_DIR = 'agents';
14
+ const AGENT_FILE = 'store.json';
15
+
16
+ interface AgentRecord {
17
+ agentId: string;
18
+ agentType: string;
19
+ status: 'idle' | 'busy' | 'terminated';
20
+ health: number;
21
+ taskCount: number;
22
+ config: Record<string, unknown>;
23
+ createdAt: string;
24
+ domain?: string;
25
+ }
26
+
27
+ interface AgentStore {
28
+ agents: Record<string, AgentRecord>;
29
+ version: string;
30
+ }
31
+
32
+ function getAgentDir(): string {
33
+ return join(process.cwd(), STORAGE_DIR, AGENT_DIR);
34
+ }
35
+
36
+ function getAgentPath(): string {
37
+ return join(getAgentDir(), AGENT_FILE);
38
+ }
39
+
40
+ function ensureAgentDir(): void {
41
+ const dir = getAgentDir();
42
+ if (!existsSync(dir)) {
43
+ mkdirSync(dir, { recursive: true });
44
+ }
45
+ }
46
+
47
+ function loadAgentStore(): AgentStore {
48
+ try {
49
+ const path = getAgentPath();
50
+ if (existsSync(path)) {
51
+ const data = readFileSync(path, 'utf-8');
52
+ return JSON.parse(data);
53
+ }
54
+ } catch {
55
+ // Return empty store on error
56
+ }
57
+ return { agents: {}, version: '3.0.0' };
58
+ }
59
+
60
+ function saveAgentStore(store: AgentStore): void {
61
+ ensureAgentDir();
62
+ writeFileSync(getAgentPath(), JSON.stringify(store, null, 2), 'utf-8');
63
+ }
64
+
65
+ export const agentTools: MCPTool[] = [
66
+ {
67
+ name: 'agent/spawn',
68
+ description: 'Spawn a new agent',
69
+ category: 'agent',
70
+ inputSchema: {
71
+ type: 'object',
72
+ properties: {
73
+ agentType: { type: 'string', description: 'Type of agent to spawn' },
74
+ agentId: { type: 'string', description: 'Optional custom agent ID' },
75
+ config: { type: 'object', description: 'Agent configuration' },
76
+ domain: { type: 'string', description: 'Agent domain' },
77
+ },
78
+ required: ['agentType'],
79
+ },
80
+ handler: async (input) => {
81
+ const store = loadAgentStore();
82
+ const agentId = (input.agentId as string) || `agent-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
83
+
84
+ const agent: AgentRecord = {
85
+ agentId,
86
+ agentType: input.agentType as string,
87
+ status: 'idle',
88
+ health: 1.0,
89
+ taskCount: 0,
90
+ config: (input.config as Record<string, unknown>) || {},
91
+ createdAt: new Date().toISOString(),
92
+ domain: input.domain as string,
93
+ };
94
+
95
+ store.agents[agentId] = agent;
96
+ saveAgentStore(store);
97
+
98
+ return {
99
+ success: true,
100
+ agentId,
101
+ agentType: agent.agentType,
102
+ status: 'spawned',
103
+ createdAt: agent.createdAt,
104
+ };
105
+ },
106
+ },
107
+ {
108
+ name: 'agent/terminate',
109
+ description: 'Terminate an agent',
110
+ category: 'agent',
111
+ inputSchema: {
112
+ type: 'object',
113
+ properties: {
114
+ agentId: { type: 'string', description: 'ID of agent to terminate' },
115
+ force: { type: 'boolean', description: 'Force immediate termination' },
116
+ },
117
+ required: ['agentId'],
118
+ },
119
+ handler: async (input) => {
120
+ const store = loadAgentStore();
121
+ const agentId = input.agentId as string;
122
+
123
+ if (store.agents[agentId]) {
124
+ store.agents[agentId].status = 'terminated';
125
+ saveAgentStore(store);
126
+ return {
127
+ success: true,
128
+ agentId,
129
+ terminated: true,
130
+ terminatedAt: new Date().toISOString(),
131
+ };
132
+ }
133
+
134
+ return {
135
+ success: false,
136
+ agentId,
137
+ error: 'Agent not found',
138
+ };
139
+ },
140
+ },
141
+ {
142
+ name: 'agent/status',
143
+ description: 'Get agent status',
144
+ category: 'agent',
145
+ inputSchema: {
146
+ type: 'object',
147
+ properties: {
148
+ agentId: { type: 'string', description: 'ID of agent' },
149
+ },
150
+ required: ['agentId'],
151
+ },
152
+ handler: async (input) => {
153
+ const store = loadAgentStore();
154
+ const agentId = input.agentId as string;
155
+ const agent = store.agents[agentId];
156
+
157
+ if (agent) {
158
+ return {
159
+ agentId: agent.agentId,
160
+ agentType: agent.agentType,
161
+ status: agent.status,
162
+ health: agent.health,
163
+ taskCount: agent.taskCount,
164
+ createdAt: agent.createdAt,
165
+ domain: agent.domain,
166
+ };
167
+ }
168
+
169
+ return {
170
+ agentId,
171
+ status: 'not_found',
172
+ error: 'Agent not found',
173
+ };
174
+ },
175
+ },
176
+ {
177
+ name: 'agent/list',
178
+ description: 'List all agents',
179
+ category: 'agent',
180
+ inputSchema: {
181
+ type: 'object',
182
+ properties: {
183
+ status: { type: 'string', description: 'Filter by status' },
184
+ domain: { type: 'string', description: 'Filter by domain' },
185
+ includeTerminated: { type: 'boolean', description: 'Include terminated agents' },
186
+ },
187
+ },
188
+ handler: async (input) => {
189
+ const store = loadAgentStore();
190
+ let agents = Object.values(store.agents);
191
+
192
+ // Filter by status
193
+ if (input.status) {
194
+ agents = agents.filter(a => a.status === input.status);
195
+ } else if (!input.includeTerminated) {
196
+ agents = agents.filter(a => a.status !== 'terminated');
197
+ }
198
+
199
+ // Filter by domain
200
+ if (input.domain) {
201
+ agents = agents.filter(a => a.domain === input.domain);
202
+ }
203
+
204
+ return {
205
+ agents: agents.map(a => ({
206
+ agentId: a.agentId,
207
+ agentType: a.agentType,
208
+ status: a.status,
209
+ health: a.health,
210
+ taskCount: a.taskCount,
211
+ createdAt: a.createdAt,
212
+ domain: a.domain,
213
+ })),
214
+ total: agents.length,
215
+ filters: {
216
+ status: input.status,
217
+ domain: input.domain,
218
+ includeTerminated: input.includeTerminated,
219
+ },
220
+ };
221
+ },
222
+ },
223
+ {
224
+ name: 'agent/pool',
225
+ description: 'Manage agent pool',
226
+ category: 'agent',
227
+ inputSchema: {
228
+ type: 'object',
229
+ properties: {
230
+ action: { type: 'string', enum: ['status', 'scale', 'drain', 'fill'], description: 'Pool action' },
231
+ targetSize: { type: 'number', description: 'Target pool size (for scale action)' },
232
+ agentType: { type: 'string', description: 'Agent type filter' },
233
+ },
234
+ required: ['action'],
235
+ },
236
+ handler: async (input) => {
237
+ const store = loadAgentStore();
238
+ const agents = Object.values(store.agents).filter(a => a.status !== 'terminated');
239
+ const action = (input.action as string) || 'status'; // Default to status
240
+
241
+ if (action === 'status') {
242
+ const byType: Record<string, number> = {};
243
+ const byStatus: Record<string, number> = {};
244
+ for (const agent of agents) {
245
+ byType[agent.agentType] = (byType[agent.agentType] || 0) + 1;
246
+ byStatus[agent.status] = (byStatus[agent.status] || 0) + 1;
247
+ }
248
+ const idleAgents = agents.filter(a => a.status === 'idle').length;
249
+ const busyAgents = agents.filter(a => a.status === 'busy').length;
250
+ const utilization = agents.length > 0 ? busyAgents / agents.length : 0;
251
+ return {
252
+ action,
253
+ // CLI expected fields
254
+ poolId: 'agent-pool-default',
255
+ currentSize: agents.length,
256
+ minSize: (input.min as number) || 0,
257
+ maxSize: (input.max as number) || 100,
258
+ autoScale: (input.autoScale as boolean) ?? false,
259
+ utilization,
260
+ agents: agents.map(a => ({
261
+ id: a.agentId,
262
+ type: a.agentType,
263
+ status: a.status,
264
+ })),
265
+ // Additional fields
266
+ id: 'agent-pool-default',
267
+ size: agents.length,
268
+ totalAgents: agents.length,
269
+ byType,
270
+ byStatus,
271
+ avgHealth: agents.length > 0 ? agents.reduce((sum, a) => sum + a.health, 0) / agents.length : 0,
272
+ };
273
+ }
274
+
275
+ if (action === 'scale') {
276
+ const targetSize = (input.targetSize as number) || 5;
277
+ const agentType = (input.agentType as string) || 'worker';
278
+ const currentSize = agents.filter(a => a.agentType === agentType).length;
279
+ const delta = targetSize - currentSize;
280
+ const added: string[] = [];
281
+ const removed: string[] = [];
282
+
283
+ if (delta > 0) {
284
+ for (let i = 0; i < delta; i++) {
285
+ const agentId = `agent-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
286
+ store.agents[agentId] = {
287
+ agentId,
288
+ agentType,
289
+ status: 'idle',
290
+ health: 1.0,
291
+ taskCount: 0,
292
+ config: {},
293
+ createdAt: new Date().toISOString(),
294
+ };
295
+ added.push(agentId);
296
+ }
297
+ } else if (delta < 0) {
298
+ const toRemove = agents.filter(a => a.agentType === agentType && a.status === 'idle').slice(0, -delta);
299
+ for (const agent of toRemove) {
300
+ store.agents[agent.agentId].status = 'terminated';
301
+ removed.push(agent.agentId);
302
+ }
303
+ }
304
+
305
+ saveAgentStore(store);
306
+ return {
307
+ action,
308
+ agentType,
309
+ previousSize: currentSize,
310
+ targetSize,
311
+ newSize: currentSize + delta,
312
+ added,
313
+ removed,
314
+ };
315
+ }
316
+
317
+ if (action === 'drain') {
318
+ const agentType = input.agentType as string;
319
+ let drained = 0;
320
+ for (const agent of agents) {
321
+ if (!agentType || agent.agentType === agentType) {
322
+ if (agent.status === 'idle') {
323
+ store.agents[agent.agentId].status = 'terminated';
324
+ drained++;
325
+ }
326
+ }
327
+ }
328
+ saveAgentStore(store);
329
+ return {
330
+ action,
331
+ agentType: agentType || 'all',
332
+ drained,
333
+ remaining: agents.length - drained,
334
+ };
335
+ }
336
+
337
+ return { action, error: 'Unknown action' };
338
+ },
339
+ },
340
+ {
341
+ name: 'agent/health',
342
+ description: 'Check agent health',
343
+ category: 'agent',
344
+ inputSchema: {
345
+ type: 'object',
346
+ properties: {
347
+ agentId: { type: 'string', description: 'Specific agent ID (optional)' },
348
+ threshold: { type: 'number', description: 'Health threshold (0-1)' },
349
+ },
350
+ },
351
+ handler: async (input) => {
352
+ const store = loadAgentStore();
353
+ const agents = Object.values(store.agents).filter(a => a.status !== 'terminated');
354
+ const threshold = (input.threshold as number) || 0.5;
355
+
356
+ if (input.agentId) {
357
+ const agent = store.agents[input.agentId as string];
358
+ if (agent) {
359
+ return {
360
+ agentId: agent.agentId,
361
+ health: agent.health,
362
+ status: agent.status,
363
+ healthy: agent.health >= threshold,
364
+ taskCount: agent.taskCount,
365
+ uptime: Date.now() - new Date(agent.createdAt).getTime(),
366
+ };
367
+ }
368
+ return { agentId: input.agentId, error: 'Agent not found' };
369
+ }
370
+
371
+ const healthyAgents = agents.filter(a => a.health >= threshold);
372
+ const degradedAgents = agents.filter(a => a.health >= 0.3 && a.health < threshold);
373
+ const unhealthyAgents = agents.filter(a => a.health < 0.3);
374
+ const avgHealth = agents.length > 0 ? agents.reduce((sum, a) => sum + a.health, 0) / agents.length : 1;
375
+ const avgCpu = agents.length > 0 ? 35 + Math.random() * 30 : 0; // Simulated CPU
376
+ const avgMemory = avgHealth * 0.6; // Correlated with health
377
+
378
+ return {
379
+ // CLI expected fields
380
+ agents: agents.map(a => {
381
+ const uptime = Date.now() - new Date(a.createdAt).getTime();
382
+ return {
383
+ id: a.agentId,
384
+ type: a.agentType,
385
+ health: a.health >= threshold ? 'healthy' : (a.health >= 0.3 ? 'degraded' : 'unhealthy'),
386
+ uptime,
387
+ memory: { used: Math.floor(256 * (1 - a.health * 0.3)), limit: 512 },
388
+ cpu: 20 + Math.floor(a.health * 40),
389
+ tasks: { active: a.taskCount > 0 ? 1 : 0, queued: 0, completed: a.taskCount, failed: 0 },
390
+ latency: { avg: 50 + Math.floor((1 - a.health) * 100), p99: 150 + Math.floor((1 - a.health) * 200) },
391
+ errors: { count: a.health < threshold ? 1 : 0 },
392
+ };
393
+ }),
394
+ overall: {
395
+ healthy: healthyAgents.length,
396
+ degraded: degradedAgents.length,
397
+ unhealthy: unhealthyAgents.length,
398
+ avgCpu,
399
+ avgMemory,
400
+ score: Math.round(avgHealth * 100),
401
+ issues: unhealthyAgents.length,
402
+ },
403
+ // Additional fields
404
+ total: agents.length,
405
+ healthyCount: healthyAgents.length,
406
+ unhealthyCount: unhealthyAgents.length,
407
+ threshold,
408
+ avgHealth,
409
+ unhealthyAgents: unhealthyAgents.map(a => ({
410
+ agentId: a.agentId,
411
+ health: a.health,
412
+ status: a.status,
413
+ })),
414
+ };
415
+ },
416
+ },
417
+ {
418
+ name: 'agent/update',
419
+ description: 'Update agent status or config',
420
+ category: 'agent',
421
+ inputSchema: {
422
+ type: 'object',
423
+ properties: {
424
+ agentId: { type: 'string', description: 'ID of agent' },
425
+ status: { type: 'string', description: 'New status' },
426
+ health: { type: 'number', description: 'Health value (0-1)' },
427
+ taskCount: { type: 'number', description: 'Task count' },
428
+ config: { type: 'object', description: 'Config updates' },
429
+ },
430
+ required: ['agentId'],
431
+ },
432
+ handler: async (input) => {
433
+ const store = loadAgentStore();
434
+ const agentId = input.agentId as string;
435
+ const agent = store.agents[agentId];
436
+
437
+ if (agent) {
438
+ if (input.status) agent.status = input.status as AgentRecord['status'];
439
+ if (typeof input.health === 'number') agent.health = input.health as number;
440
+ if (typeof input.taskCount === 'number') agent.taskCount = input.taskCount as number;
441
+ if (input.config) {
442
+ agent.config = { ...agent.config, ...(input.config as Record<string, unknown>) };
443
+ }
444
+ saveAgentStore(store);
445
+
446
+ return {
447
+ success: true,
448
+ agentId,
449
+ updated: true,
450
+ agent: {
451
+ agentId: agent.agentId,
452
+ status: agent.status,
453
+ health: agent.health,
454
+ taskCount: agent.taskCount,
455
+ },
456
+ };
457
+ }
458
+
459
+ return {
460
+ success: false,
461
+ agentId,
462
+ error: 'Agent not found',
463
+ };
464
+ },
465
+ },
466
+ ];