@claude-flow/cli 3.0.0-alpha.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 (229) hide show
  1. package/.agentic-flow/intelligence.json +16 -0
  2. package/.claude-flow/metrics/agent-metrics.json +1 -0
  3. package/.claude-flow/metrics/performance.json +87 -0
  4. package/.claude-flow/metrics/task-metrics.json +10 -0
  5. package/README.md +1186 -0
  6. package/__tests__/README.md +140 -0
  7. package/__tests__/TEST_SUMMARY.md +144 -0
  8. package/__tests__/cli.test.ts +558 -0
  9. package/__tests__/commands.test.ts +726 -0
  10. package/__tests__/config-adapter.test.ts +362 -0
  11. package/__tests__/config-loading.test.ts +106 -0
  12. package/__tests__/coverage/.tmp/coverage-0.json +1 -0
  13. package/__tests__/coverage/.tmp/coverage-1.json +1 -0
  14. package/__tests__/coverage/.tmp/coverage-2.json +1 -0
  15. package/__tests__/coverage/.tmp/coverage-3.json +1 -0
  16. package/__tests__/coverage/.tmp/coverage-4.json +1 -0
  17. package/__tests__/coverage/.tmp/coverage-5.json +1 -0
  18. package/__tests__/mcp-client.test.ts +480 -0
  19. package/__tests__/p1-commands.test.ts +1064 -0
  20. package/bin/cli.js +14 -0
  21. package/dist/src/commands/agent.d.ts +8 -0
  22. package/dist/src/commands/agent.d.ts.map +1 -0
  23. package/dist/src/commands/agent.js +803 -0
  24. package/dist/src/commands/agent.js.map +1 -0
  25. package/dist/src/commands/config.d.ts +8 -0
  26. package/dist/src/commands/config.d.ts.map +1 -0
  27. package/dist/src/commands/config.js +406 -0
  28. package/dist/src/commands/config.js.map +1 -0
  29. package/dist/src/commands/hive-mind.d.ts +8 -0
  30. package/dist/src/commands/hive-mind.d.ts.map +1 -0
  31. package/dist/src/commands/hive-mind.js +627 -0
  32. package/dist/src/commands/hive-mind.js.map +1 -0
  33. package/dist/src/commands/hooks.d.ts +8 -0
  34. package/dist/src/commands/hooks.d.ts.map +1 -0
  35. package/dist/src/commands/hooks.js +2098 -0
  36. package/dist/src/commands/hooks.js.map +1 -0
  37. package/dist/src/commands/index.d.ts +51 -0
  38. package/dist/src/commands/index.d.ts.map +1 -0
  39. package/dist/src/commands/index.js +105 -0
  40. package/dist/src/commands/index.js.map +1 -0
  41. package/dist/src/commands/init.d.ts +8 -0
  42. package/dist/src/commands/init.d.ts.map +1 -0
  43. package/dist/src/commands/init.js +532 -0
  44. package/dist/src/commands/init.js.map +1 -0
  45. package/dist/src/commands/mcp.d.ts +11 -0
  46. package/dist/src/commands/mcp.d.ts.map +1 -0
  47. package/dist/src/commands/mcp.js +662 -0
  48. package/dist/src/commands/mcp.js.map +1 -0
  49. package/dist/src/commands/memory.d.ts +8 -0
  50. package/dist/src/commands/memory.d.ts.map +1 -0
  51. package/dist/src/commands/memory.js +911 -0
  52. package/dist/src/commands/memory.js.map +1 -0
  53. package/dist/src/commands/migrate.d.ts +8 -0
  54. package/dist/src/commands/migrate.d.ts.map +1 -0
  55. package/dist/src/commands/migrate.js +398 -0
  56. package/dist/src/commands/migrate.js.map +1 -0
  57. package/dist/src/commands/process.d.ts +10 -0
  58. package/dist/src/commands/process.d.ts.map +1 -0
  59. package/dist/src/commands/process.js +566 -0
  60. package/dist/src/commands/process.js.map +1 -0
  61. package/dist/src/commands/session.d.ts +8 -0
  62. package/dist/src/commands/session.d.ts.map +1 -0
  63. package/dist/src/commands/session.js +750 -0
  64. package/dist/src/commands/session.js.map +1 -0
  65. package/dist/src/commands/start.d.ts +8 -0
  66. package/dist/src/commands/start.d.ts.map +1 -0
  67. package/dist/src/commands/start.js +398 -0
  68. package/dist/src/commands/start.js.map +1 -0
  69. package/dist/src/commands/status.d.ts +8 -0
  70. package/dist/src/commands/status.d.ts.map +1 -0
  71. package/dist/src/commands/status.js +560 -0
  72. package/dist/src/commands/status.js.map +1 -0
  73. package/dist/src/commands/swarm.d.ts +8 -0
  74. package/dist/src/commands/swarm.d.ts.map +1 -0
  75. package/dist/src/commands/swarm.js +573 -0
  76. package/dist/src/commands/swarm.js.map +1 -0
  77. package/dist/src/commands/task.d.ts +8 -0
  78. package/dist/src/commands/task.d.ts.map +1 -0
  79. package/dist/src/commands/task.js +671 -0
  80. package/dist/src/commands/task.js.map +1 -0
  81. package/dist/src/commands/workflow.d.ts +8 -0
  82. package/dist/src/commands/workflow.d.ts.map +1 -0
  83. package/dist/src/commands/workflow.js +617 -0
  84. package/dist/src/commands/workflow.js.map +1 -0
  85. package/dist/src/config-adapter.d.ts +15 -0
  86. package/dist/src/config-adapter.d.ts.map +1 -0
  87. package/dist/src/config-adapter.js +185 -0
  88. package/dist/src/config-adapter.js.map +1 -0
  89. package/dist/src/index.d.ts +55 -0
  90. package/dist/src/index.d.ts.map +1 -0
  91. package/dist/src/index.js +312 -0
  92. package/dist/src/index.js.map +1 -0
  93. package/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
  94. package/dist/src/infrastructure/in-memory-repositories.d.ts.map +1 -0
  95. package/dist/src/infrastructure/in-memory-repositories.js +264 -0
  96. package/dist/src/infrastructure/in-memory-repositories.js.map +1 -0
  97. package/dist/src/init/claudemd-generator.d.ts +15 -0
  98. package/dist/src/init/claudemd-generator.d.ts.map +1 -0
  99. package/dist/src/init/claudemd-generator.js +626 -0
  100. package/dist/src/init/claudemd-generator.js.map +1 -0
  101. package/dist/src/init/executor.d.ts +11 -0
  102. package/dist/src/init/executor.d.ts.map +1 -0
  103. package/dist/src/init/executor.js +647 -0
  104. package/dist/src/init/executor.js.map +1 -0
  105. package/dist/src/init/helpers-generator.d.ts +42 -0
  106. package/dist/src/init/helpers-generator.d.ts.map +1 -0
  107. package/dist/src/init/helpers-generator.js +613 -0
  108. package/dist/src/init/helpers-generator.js.map +1 -0
  109. package/dist/src/init/index.d.ts +12 -0
  110. package/dist/src/init/index.d.ts.map +1 -0
  111. package/dist/src/init/index.js +15 -0
  112. package/dist/src/init/index.js.map +1 -0
  113. package/dist/src/init/mcp-generator.d.ts +18 -0
  114. package/dist/src/init/mcp-generator.d.ts.map +1 -0
  115. package/dist/src/init/mcp-generator.js +71 -0
  116. package/dist/src/init/mcp-generator.js.map +1 -0
  117. package/dist/src/init/settings-generator.d.ts +14 -0
  118. package/dist/src/init/settings-generator.d.ts.map +1 -0
  119. package/dist/src/init/settings-generator.js +257 -0
  120. package/dist/src/init/settings-generator.js.map +1 -0
  121. package/dist/src/init/statusline-generator.d.ts +14 -0
  122. package/dist/src/init/statusline-generator.d.ts.map +1 -0
  123. package/dist/src/init/statusline-generator.js +206 -0
  124. package/dist/src/init/statusline-generator.js.map +1 -0
  125. package/dist/src/init/types.d.ts +240 -0
  126. package/dist/src/init/types.d.ts.map +1 -0
  127. package/dist/src/init/types.js +210 -0
  128. package/dist/src/init/types.js.map +1 -0
  129. package/dist/src/mcp-client.d.ts +92 -0
  130. package/dist/src/mcp-client.d.ts.map +1 -0
  131. package/dist/src/mcp-client.js +189 -0
  132. package/dist/src/mcp-client.js.map +1 -0
  133. package/dist/src/mcp-server.d.ts +153 -0
  134. package/dist/src/mcp-server.d.ts.map +1 -0
  135. package/dist/src/mcp-server.js +448 -0
  136. package/dist/src/mcp-server.js.map +1 -0
  137. package/dist/src/mcp-tools/agent-tools.d.ts +8 -0
  138. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -0
  139. package/dist/src/mcp-tools/agent-tools.js +90 -0
  140. package/dist/src/mcp-tools/agent-tools.js.map +1 -0
  141. package/dist/src/mcp-tools/config-tools.d.ts +8 -0
  142. package/dist/src/mcp-tools/config-tools.d.ts.map +1 -0
  143. package/dist/src/mcp-tools/config-tools.js +86 -0
  144. package/dist/src/mcp-tools/config-tools.js.map +1 -0
  145. package/dist/src/mcp-tools/hooks-tools.d.ts +41 -0
  146. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -0
  147. package/dist/src/mcp-tools/hooks-tools.js +1646 -0
  148. package/dist/src/mcp-tools/hooks-tools.js.map +1 -0
  149. package/dist/src/mcp-tools/index.d.ts +12 -0
  150. package/dist/src/mcp-tools/index.d.ts.map +1 -0
  151. package/dist/src/mcp-tools/index.js +11 -0
  152. package/dist/src/mcp-tools/index.js.map +1 -0
  153. package/dist/src/mcp-tools/memory-tools.d.ts +8 -0
  154. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -0
  155. package/dist/src/mcp-tools/memory-tools.js +87 -0
  156. package/dist/src/mcp-tools/memory-tools.js.map +1 -0
  157. package/dist/src/mcp-tools/swarm-tools.d.ts +8 -0
  158. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -0
  159. package/dist/src/mcp-tools/swarm-tools.js +67 -0
  160. package/dist/src/mcp-tools/swarm-tools.js.map +1 -0
  161. package/dist/src/mcp-tools/types.d.ts +31 -0
  162. package/dist/src/mcp-tools/types.d.ts.map +1 -0
  163. package/dist/src/mcp-tools/types.js +7 -0
  164. package/dist/src/mcp-tools/types.js.map +1 -0
  165. package/dist/src/output.d.ts +117 -0
  166. package/dist/src/output.d.ts.map +1 -0
  167. package/dist/src/output.js +471 -0
  168. package/dist/src/output.js.map +1 -0
  169. package/dist/src/parser.d.ts +41 -0
  170. package/dist/src/parser.d.ts.map +1 -0
  171. package/dist/src/parser.js +353 -0
  172. package/dist/src/parser.js.map +1 -0
  173. package/dist/src/prompt.d.ts +44 -0
  174. package/dist/src/prompt.d.ts.map +1 -0
  175. package/dist/src/prompt.js +501 -0
  176. package/dist/src/prompt.js.map +1 -0
  177. package/dist/src/types.d.ts +198 -0
  178. package/dist/src/types.d.ts.map +1 -0
  179. package/dist/src/types.js +38 -0
  180. package/dist/src/types.js.map +1 -0
  181. package/dist/tsconfig.tsbuildinfo +1 -0
  182. package/docs/CONFIG_LOADING.md +236 -0
  183. package/docs/IMPLEMENTATION_COMPLETE.md +421 -0
  184. package/docs/MCP_CLIENT_GUIDE.md +620 -0
  185. package/docs/REFACTORING_SUMMARY.md +247 -0
  186. package/package.json +29 -0
  187. package/src/commands/agent.ts +941 -0
  188. package/src/commands/config.ts +452 -0
  189. package/src/commands/hive-mind.ts +762 -0
  190. package/src/commands/hooks.ts +2603 -0
  191. package/src/commands/index.ts +115 -0
  192. package/src/commands/init.ts +597 -0
  193. package/src/commands/mcp.ts +753 -0
  194. package/src/commands/memory.ts +1063 -0
  195. package/src/commands/migrate.ts +447 -0
  196. package/src/commands/process.ts +617 -0
  197. package/src/commands/session.ts +891 -0
  198. package/src/commands/start.ts +457 -0
  199. package/src/commands/status.ts +705 -0
  200. package/src/commands/swarm.ts +648 -0
  201. package/src/commands/task.ts +792 -0
  202. package/src/commands/workflow.ts +742 -0
  203. package/src/config-adapter.ts +210 -0
  204. package/src/index.ts +383 -0
  205. package/src/infrastructure/in-memory-repositories.ts +310 -0
  206. package/src/init/claudemd-generator.ts +631 -0
  207. package/src/init/executor.ts +756 -0
  208. package/src/init/helpers-generator.ts +628 -0
  209. package/src/init/index.ts +60 -0
  210. package/src/init/mcp-generator.ts +83 -0
  211. package/src/init/settings-generator.ts +274 -0
  212. package/src/init/statusline-generator.ts +211 -0
  213. package/src/init/types.ts +447 -0
  214. package/src/mcp-client.ts +227 -0
  215. package/src/mcp-server.ts +571 -0
  216. package/src/mcp-tools/agent-tools.ts +92 -0
  217. package/src/mcp-tools/config-tools.ts +88 -0
  218. package/src/mcp-tools/hooks-tools.ts +1819 -0
  219. package/src/mcp-tools/index.ts +12 -0
  220. package/src/mcp-tools/memory-tools.ts +89 -0
  221. package/src/mcp-tools/swarm-tools.ts +69 -0
  222. package/src/mcp-tools/types.ts +33 -0
  223. package/src/output.ts +593 -0
  224. package/src/parser.ts +417 -0
  225. package/src/prompt.ts +619 -0
  226. package/src/types.ts +287 -0
  227. package/tsconfig.json +16 -0
  228. package/tsconfig.tsbuildinfo +1 -0
  229. package/vitest.config.ts +13 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * In-Memory Repositories - CLI Infrastructure
3
+ *
4
+ * Lightweight in-memory implementations for CLI use.
5
+ *
6
+ * @module v3/cli/infrastructure
7
+ */
8
+
9
+ import { Agent, AgentStatus, AgentRole } from '../../../swarm/src/domain/entities/agent.js';
10
+ import { Task, TaskStatus, TaskPriority } from '../../../swarm/src/domain/entities/task.js';
11
+ import {
12
+ IAgentRepository,
13
+ AgentQueryOptions,
14
+ AgentStatistics,
15
+ } from '../../../swarm/src/domain/repositories/agent-repository.interface.js';
16
+ import {
17
+ ITaskRepository,
18
+ TaskQueryOptions,
19
+ TaskStatistics,
20
+ } from '../../../swarm/src/domain/repositories/task-repository.interface.js';
21
+
22
+ /**
23
+ * In-Memory Agent Repository
24
+ */
25
+ export class InMemoryAgentRepository implements IAgentRepository {
26
+ private agents: Map<string, Agent> = new Map();
27
+ private initialized = false;
28
+
29
+ async initialize(): Promise<void> {
30
+ this.initialized = true;
31
+ }
32
+
33
+ async shutdown(): Promise<void> {
34
+ this.agents.clear();
35
+ this.initialized = false;
36
+ }
37
+
38
+ async clear(): Promise<void> {
39
+ this.agents.clear();
40
+ }
41
+
42
+ async save(agent: Agent): Promise<void> {
43
+ this.agents.set(agent.id, agent);
44
+ }
45
+
46
+ async findById(id: string): Promise<Agent | null> {
47
+ return this.agents.get(id) ?? null;
48
+ }
49
+
50
+ async findByName(name: string): Promise<Agent | null> {
51
+ for (const agent of this.agents.values()) {
52
+ if (agent.name === name) return agent;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ async delete(id: string): Promise<boolean> {
58
+ return this.agents.delete(id);
59
+ }
60
+
61
+ async exists(id: string): Promise<boolean> {
62
+ return this.agents.has(id);
63
+ }
64
+
65
+ async saveMany(agents: Agent[]): Promise<void> {
66
+ for (const agent of agents) {
67
+ this.agents.set(agent.id, agent);
68
+ }
69
+ }
70
+
71
+ async findByIds(ids: string[]): Promise<Agent[]> {
72
+ return ids.map((id) => this.agents.get(id)).filter((a): a is Agent => a !== undefined);
73
+ }
74
+
75
+ async deleteMany(ids: string[]): Promise<number> {
76
+ let deleted = 0;
77
+ for (const id of ids) {
78
+ if (this.agents.delete(id)) deleted++;
79
+ }
80
+ return deleted;
81
+ }
82
+
83
+ async findAll(options?: AgentQueryOptions): Promise<Agent[]> {
84
+ let result = Array.from(this.agents.values());
85
+ if (options?.status) result = result.filter((a) => a.status === options.status);
86
+ if (options?.role) result = result.filter((a) => a.role === options.role);
87
+ if (options?.domain) result = result.filter((a) => a.domain === options.domain);
88
+ if (options?.limit) result = result.slice(0, options.limit);
89
+ return result;
90
+ }
91
+
92
+ async findByStatus(status: AgentStatus): Promise<Agent[]> {
93
+ return this.findAll({ status });
94
+ }
95
+
96
+ async findByRole(role: AgentRole): Promise<Agent[]> {
97
+ return this.findAll({ role });
98
+ }
99
+
100
+ async findByDomain(domain: string): Promise<Agent[]> {
101
+ return this.findAll({ domain });
102
+ }
103
+
104
+ async findByParent(parentId: string): Promise<Agent[]> {
105
+ return Array.from(this.agents.values()).filter((a) => a.parentId === parentId);
106
+ }
107
+
108
+ async findByCapability(capability: string): Promise<Agent[]> {
109
+ return Array.from(this.agents.values()).filter((a) => a.hasCapability(capability));
110
+ }
111
+
112
+ async findAvailable(): Promise<Agent[]> {
113
+ return Array.from(this.agents.values()).filter((a) => a.isAvailable());
114
+ }
115
+
116
+ async getStatistics(): Promise<AgentStatistics> {
117
+ const agents = Array.from(this.agents.values());
118
+ const byStatus: Record<AgentStatus, number> = {
119
+ idle: 0,
120
+ active: 0,
121
+ busy: 0,
122
+ paused: 0,
123
+ terminated: 0,
124
+ error: 0,
125
+ };
126
+ const byRole: Record<string, number> = {};
127
+ const byDomain: Record<string, number> = {};
128
+ let totalCompleted = 0;
129
+ let totalUtilization = 0;
130
+
131
+ for (const agent of agents) {
132
+ byStatus[agent.status]++;
133
+ byRole[agent.role] = (byRole[agent.role] ?? 0) + 1;
134
+ byDomain[agent.domain] = (byDomain[agent.domain] ?? 0) + 1;
135
+ totalCompleted += agent.completedTaskCount;
136
+ totalUtilization += agent.getUtilization();
137
+ }
138
+
139
+ return {
140
+ total: agents.length,
141
+ byStatus,
142
+ byRole,
143
+ byDomain,
144
+ totalTasksCompleted: totalCompleted,
145
+ averageUtilization: agents.length > 0 ? totalUtilization / agents.length : 0,
146
+ };
147
+ }
148
+
149
+ async count(options?: AgentQueryOptions): Promise<number> {
150
+ return (await this.findAll(options)).length;
151
+ }
152
+ }
153
+
154
+ /**
155
+ * In-Memory Task Repository
156
+ */
157
+ export class InMemoryTaskRepository implements ITaskRepository {
158
+ private tasks: Map<string, Task> = new Map();
159
+ private initialized = false;
160
+
161
+ async initialize(): Promise<void> {
162
+ this.initialized = true;
163
+ }
164
+
165
+ async shutdown(): Promise<void> {
166
+ this.tasks.clear();
167
+ this.initialized = false;
168
+ }
169
+
170
+ async clear(): Promise<void> {
171
+ this.tasks.clear();
172
+ }
173
+
174
+ async save(task: Task): Promise<void> {
175
+ this.tasks.set(task.id, task);
176
+ }
177
+
178
+ async findById(id: string): Promise<Task | null> {
179
+ return this.tasks.get(id) ?? null;
180
+ }
181
+
182
+ async delete(id: string): Promise<boolean> {
183
+ return this.tasks.delete(id);
184
+ }
185
+
186
+ async exists(id: string): Promise<boolean> {
187
+ return this.tasks.has(id);
188
+ }
189
+
190
+ async saveMany(tasks: Task[]): Promise<void> {
191
+ for (const task of tasks) {
192
+ this.tasks.set(task.id, task);
193
+ }
194
+ }
195
+
196
+ async findByIds(ids: string[]): Promise<Task[]> {
197
+ return ids.map((id) => this.tasks.get(id)).filter((t): t is Task => t !== undefined);
198
+ }
199
+
200
+ async deleteMany(ids: string[]): Promise<number> {
201
+ let deleted = 0;
202
+ for (const id of ids) {
203
+ if (this.tasks.delete(id)) deleted++;
204
+ }
205
+ return deleted;
206
+ }
207
+
208
+ async findAll(options?: TaskQueryOptions): Promise<Task[]> {
209
+ let result = Array.from(this.tasks.values());
210
+ if (options?.status) result = result.filter((t) => t.status === options.status);
211
+ if (options?.priority) result = result.filter((t) => t.priority === options.priority);
212
+ if (options?.type) result = result.filter((t) => t.type === options.type);
213
+ if (options?.assignedAgentId) result = result.filter((t) => t.assignedAgentId === options.assignedAgentId);
214
+ if (options?.limit) result = result.slice(0, options.limit);
215
+ return result;
216
+ }
217
+
218
+ async findByStatus(status: TaskStatus): Promise<Task[]> {
219
+ return this.findAll({ status });
220
+ }
221
+
222
+ async findByPriority(priority: TaskPriority): Promise<Task[]> {
223
+ return this.findAll({ priority });
224
+ }
225
+
226
+ async findByAgent(agentId: string): Promise<Task[]> {
227
+ return this.findAll({ assignedAgentId: agentId });
228
+ }
229
+
230
+ async findPending(): Promise<Task[]> {
231
+ return this.findByStatus('pending');
232
+ }
233
+
234
+ async findQueued(): Promise<Task[]> {
235
+ return this.findByStatus('queued');
236
+ }
237
+
238
+ async findRunning(): Promise<Task[]> {
239
+ return this.findByStatus('running');
240
+ }
241
+
242
+ async findTimedOut(): Promise<Task[]> {
243
+ return Array.from(this.tasks.values()).filter((t) => t.isTimedOut());
244
+ }
245
+
246
+ async getNextTask(agentCapabilities?: string[]): Promise<Task | null> {
247
+ const queued = await this.findQueued();
248
+ if (queued.length === 0) return null;
249
+ queued.sort((a, b) => a.comparePriority(b));
250
+ return queued[0];
251
+ }
252
+
253
+ async getTaskQueue(limit = 10): Promise<Task[]> {
254
+ const queued = await this.findQueued();
255
+ queued.sort((a, b) => a.comparePriority(b));
256
+ return queued.slice(0, limit);
257
+ }
258
+
259
+ async getStatistics(): Promise<TaskStatistics> {
260
+ const tasks = Array.from(this.tasks.values());
261
+ const byStatus: Record<TaskStatus, number> = {
262
+ pending: 0,
263
+ queued: 0,
264
+ assigned: 0,
265
+ running: 0,
266
+ completed: 0,
267
+ failed: 0,
268
+ cancelled: 0,
269
+ };
270
+ const byPriority: Record<TaskPriority, number> = {
271
+ critical: 0,
272
+ high: 0,
273
+ normal: 0,
274
+ low: 0,
275
+ };
276
+ const byType: Record<string, number> = {};
277
+ let totalDuration = 0;
278
+ let completedCount = 0;
279
+ let failedCount = 0;
280
+ let retryTotal = 0;
281
+
282
+ for (const task of tasks) {
283
+ byStatus[task.status]++;
284
+ byPriority[task.priority]++;
285
+ byType[task.type] = (byType[task.type] ?? 0) + 1;
286
+
287
+ if (task.status === 'completed') {
288
+ completedCount++;
289
+ const duration = task.getExecutionDuration();
290
+ if (duration) totalDuration += duration;
291
+ }
292
+ if (task.status === 'failed') failedCount++;
293
+ retryTotal += task.retryCount;
294
+ }
295
+
296
+ return {
297
+ total: tasks.length,
298
+ byStatus,
299
+ byPriority,
300
+ byType,
301
+ averageExecutionTime: completedCount > 0 ? totalDuration / completedCount : 0,
302
+ successRate: tasks.length > 0 ? completedCount / tasks.length : 0,
303
+ retryRate: tasks.length > 0 ? retryTotal / tasks.length : 0,
304
+ };
305
+ }
306
+
307
+ async count(options?: TaskQueryOptions): Promise<number> {
308
+ return (await this.findAll(options)).length;
309
+ }
310
+ }