@claude-flow/cli 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (263) hide show
  1. package/README.md +172 -6
  2. package/bin/cli.js +0 -0
  3. package/dist/src/commands/agent.d.ts.map +1 -1
  4. package/dist/src/commands/agent.js +43 -27
  5. package/dist/src/commands/agent.js.map +1 -1
  6. package/dist/src/commands/analyze.d.ts +19 -0
  7. package/dist/src/commands/analyze.d.ts.map +1 -0
  8. package/dist/src/commands/analyze.js +1823 -0
  9. package/dist/src/commands/analyze.js.map +1 -0
  10. package/dist/src/commands/claims.d.ts +10 -0
  11. package/dist/src/commands/claims.d.ts.map +1 -0
  12. package/dist/src/commands/claims.js +288 -0
  13. package/dist/src/commands/claims.js.map +1 -0
  14. package/dist/src/commands/completions.d.ts +10 -0
  15. package/dist/src/commands/completions.d.ts.map +1 -0
  16. package/dist/src/commands/completions.js +539 -0
  17. package/dist/src/commands/completions.js.map +1 -0
  18. package/dist/src/commands/config.js +2 -2
  19. package/dist/src/commands/config.js.map +1 -1
  20. package/dist/src/commands/daemon.d.ts +8 -0
  21. package/dist/src/commands/daemon.d.ts.map +1 -0
  22. package/dist/src/commands/daemon.js +545 -0
  23. package/dist/src/commands/daemon.js.map +1 -0
  24. package/dist/src/commands/deployment.d.ts +10 -0
  25. package/dist/src/commands/deployment.d.ts.map +1 -0
  26. package/dist/src/commands/deployment.js +289 -0
  27. package/dist/src/commands/deployment.js.map +1 -0
  28. package/dist/src/commands/doctor.d.ts +10 -0
  29. package/dist/src/commands/doctor.d.ts.map +1 -0
  30. package/dist/src/commands/doctor.js +429 -0
  31. package/dist/src/commands/doctor.js.map +1 -0
  32. package/dist/src/commands/embeddings.d.ts +18 -0
  33. package/dist/src/commands/embeddings.d.ts.map +1 -0
  34. package/dist/src/commands/embeddings.js +616 -0
  35. package/dist/src/commands/embeddings.js.map +1 -0
  36. package/dist/src/commands/hive-mind.d.ts.map +1 -1
  37. package/dist/src/commands/hive-mind.js +252 -35
  38. package/dist/src/commands/hive-mind.js.map +1 -1
  39. package/dist/src/commands/hooks.d.ts.map +1 -1
  40. package/dist/src/commands/hooks.js +326 -2
  41. package/dist/src/commands/hooks.js.map +1 -1
  42. package/dist/src/commands/index.d.ts +13 -0
  43. package/dist/src/commands/index.d.ts.map +1 -1
  44. package/dist/src/commands/index.js +52 -1
  45. package/dist/src/commands/index.js.map +1 -1
  46. package/dist/src/commands/mcp.js +4 -4
  47. package/dist/src/commands/mcp.js.map +1 -1
  48. package/dist/src/commands/memory.d.ts.map +1 -1
  49. package/dist/src/commands/memory.js +236 -170
  50. package/dist/src/commands/memory.js.map +1 -1
  51. package/dist/src/commands/migrate.js +1 -1
  52. package/dist/src/commands/migrate.js.map +1 -1
  53. package/dist/src/commands/neural.d.ts +10 -0
  54. package/dist/src/commands/neural.d.ts.map +1 -0
  55. package/dist/src/commands/neural.js +224 -0
  56. package/dist/src/commands/neural.js.map +1 -0
  57. package/dist/src/commands/performance.d.ts +10 -0
  58. package/dist/src/commands/performance.d.ts.map +1 -0
  59. package/dist/src/commands/performance.js +262 -0
  60. package/dist/src/commands/performance.js.map +1 -0
  61. package/dist/src/commands/plugins.d.ts +10 -0
  62. package/dist/src/commands/plugins.d.ts.map +1 -0
  63. package/dist/src/commands/plugins.js +280 -0
  64. package/dist/src/commands/plugins.js.map +1 -0
  65. package/dist/src/commands/process.d.ts.map +1 -1
  66. package/dist/src/commands/process.js +95 -20
  67. package/dist/src/commands/process.js.map +1 -1
  68. package/dist/src/commands/providers.d.ts +10 -0
  69. package/dist/src/commands/providers.d.ts.map +1 -0
  70. package/dist/src/commands/providers.js +232 -0
  71. package/dist/src/commands/providers.js.map +1 -0
  72. package/dist/src/commands/route.d.ts +16 -0
  73. package/dist/src/commands/route.d.ts.map +1 -0
  74. package/dist/src/commands/route.js +603 -0
  75. package/dist/src/commands/route.js.map +1 -0
  76. package/dist/src/commands/security.d.ts +10 -0
  77. package/dist/src/commands/security.d.ts.map +1 -0
  78. package/dist/src/commands/security.js +261 -0
  79. package/dist/src/commands/security.js.map +1 -0
  80. package/dist/src/commands/start.js +2 -2
  81. package/dist/src/commands/start.js.map +1 -1
  82. package/dist/src/commands/status.d.ts.map +1 -1
  83. package/dist/src/commands/status.js +26 -2
  84. package/dist/src/commands/status.js.map +1 -1
  85. package/dist/src/commands/swarm.js +6 -6
  86. package/dist/src/commands/swarm.js.map +1 -1
  87. package/dist/src/index.d.ts +4 -2
  88. package/dist/src/index.d.ts.map +1 -1
  89. package/dist/src/index.js +63 -5
  90. package/dist/src/index.js.map +1 -1
  91. package/dist/src/init/claudemd-generator.d.ts.map +1 -1
  92. package/dist/src/init/claudemd-generator.js +218 -362
  93. package/dist/src/init/claudemd-generator.js.map +1 -1
  94. package/dist/src/init/executor.d.ts.map +1 -1
  95. package/dist/src/init/executor.js +5 -0
  96. package/dist/src/init/executor.js.map +1 -1
  97. package/dist/src/init/settings-generator.d.ts.map +1 -1
  98. package/dist/src/init/settings-generator.js +22 -12
  99. package/dist/src/init/settings-generator.js.map +1 -1
  100. package/dist/src/mcp-client.d.ts.map +1 -1
  101. package/dist/src/mcp-client.js +17 -1
  102. package/dist/src/mcp-client.js.map +1 -1
  103. package/dist/src/mcp-server.d.ts.map +1 -1
  104. package/dist/src/mcp-server.js +5 -0
  105. package/dist/src/mcp-server.js.map +1 -1
  106. package/dist/src/mcp-tools/agent-tools.d.ts +1 -1
  107. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  108. package/dist/src/mcp-tools/agent-tools.js +350 -14
  109. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  110. package/dist/src/mcp-tools/analyze-tools.d.ts +38 -0
  111. package/dist/src/mcp-tools/analyze-tools.d.ts.map +1 -0
  112. package/dist/src/mcp-tools/analyze-tools.js +317 -0
  113. package/dist/src/mcp-tools/analyze-tools.js.map +1 -0
  114. package/dist/src/mcp-tools/config-tools.d.ts +1 -1
  115. package/dist/src/mcp-tools/config-tools.d.ts.map +1 -1
  116. package/dist/src/mcp-tools/config-tools.js +262 -15
  117. package/dist/src/mcp-tools/config-tools.js.map +1 -1
  118. package/dist/src/mcp-tools/hive-mind-tools.d.ts +8 -0
  119. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -0
  120. package/dist/src/mcp-tools/hive-mind-tools.js +447 -0
  121. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -0
  122. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  123. package/dist/src/mcp-tools/hooks-tools.js +80 -15
  124. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  125. package/dist/src/mcp-tools/index.d.ts +6 -0
  126. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  127. package/dist/src/mcp-tools/index.js +6 -0
  128. package/dist/src/mcp-tools/index.js.map +1 -1
  129. package/dist/src/mcp-tools/memory-tools.d.ts +1 -1
  130. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  131. package/dist/src/mcp-tools/memory-tools.js +157 -9
  132. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  133. package/dist/src/mcp-tools/session-tools.d.ts +8 -0
  134. package/dist/src/mcp-tools/session-tools.d.ts.map +1 -0
  135. package/dist/src/mcp-tools/session-tools.js +315 -0
  136. package/dist/src/mcp-tools/session-tools.js.map +1 -0
  137. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  138. package/dist/src/mcp-tools/swarm-tools.js +37 -2
  139. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  140. package/dist/src/mcp-tools/task-tools.d.ts +8 -0
  141. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -0
  142. package/dist/src/mcp-tools/task-tools.js +302 -0
  143. package/dist/src/mcp-tools/task-tools.js.map +1 -0
  144. package/dist/src/mcp-tools/workflow-tools.d.ts +8 -0
  145. package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -0
  146. package/dist/src/mcp-tools/workflow-tools.js +481 -0
  147. package/dist/src/mcp-tools/workflow-tools.js.map +1 -0
  148. package/dist/src/output.d.ts +16 -0
  149. package/dist/src/output.d.ts.map +1 -1
  150. package/dist/src/output.js +42 -0
  151. package/dist/src/output.js.map +1 -1
  152. package/dist/src/ruvector/ast-analyzer.d.ts +67 -0
  153. package/dist/src/ruvector/ast-analyzer.d.ts.map +1 -0
  154. package/dist/src/ruvector/ast-analyzer.js +277 -0
  155. package/dist/src/ruvector/ast-analyzer.js.map +1 -0
  156. package/dist/src/ruvector/coverage-router.d.ts +145 -0
  157. package/dist/src/ruvector/coverage-router.d.ts.map +1 -0
  158. package/dist/src/ruvector/coverage-router.js +451 -0
  159. package/dist/src/ruvector/coverage-router.js.map +1 -0
  160. package/dist/src/ruvector/coverage-tools.d.ts +33 -0
  161. package/dist/src/ruvector/coverage-tools.d.ts.map +1 -0
  162. package/dist/src/ruvector/coverage-tools.js +157 -0
  163. package/dist/src/ruvector/coverage-tools.js.map +1 -0
  164. package/dist/src/ruvector/diff-classifier.d.ts +175 -0
  165. package/dist/src/ruvector/diff-classifier.d.ts.map +1 -0
  166. package/dist/src/ruvector/diff-classifier.js +662 -0
  167. package/dist/src/ruvector/diff-classifier.js.map +1 -0
  168. package/dist/src/ruvector/graph-analyzer.d.ts +174 -0
  169. package/dist/src/ruvector/graph-analyzer.d.ts.map +1 -0
  170. package/dist/src/ruvector/graph-analyzer.js +878 -0
  171. package/dist/src/ruvector/graph-analyzer.js.map +1 -0
  172. package/dist/src/ruvector/index.d.ts +27 -0
  173. package/dist/src/ruvector/index.d.ts.map +1 -0
  174. package/dist/src/ruvector/index.js +49 -0
  175. package/dist/src/ruvector/index.js.map +1 -0
  176. package/dist/src/ruvector/q-learning-router.d.ts +211 -0
  177. package/dist/src/ruvector/q-learning-router.d.ts.map +1 -0
  178. package/dist/src/ruvector/q-learning-router.js +681 -0
  179. package/dist/src/ruvector/q-learning-router.js.map +1 -0
  180. package/dist/src/ruvector/vector-db.d.ts +69 -0
  181. package/dist/src/ruvector/vector-db.d.ts.map +1 -0
  182. package/dist/src/ruvector/vector-db.js +243 -0
  183. package/dist/src/ruvector/vector-db.js.map +1 -0
  184. package/dist/src/services/index.d.ts +7 -0
  185. package/dist/src/services/index.d.ts.map +1 -0
  186. package/dist/src/services/index.js +6 -0
  187. package/dist/src/services/index.js.map +1 -0
  188. package/dist/src/services/worker-daemon.d.ts +153 -0
  189. package/dist/src/services/worker-daemon.d.ts.map +1 -0
  190. package/dist/src/services/worker-daemon.js +567 -0
  191. package/dist/src/services/worker-daemon.js.map +1 -0
  192. package/dist/src/suggest.d.ts +53 -0
  193. package/dist/src/suggest.d.ts.map +1 -0
  194. package/dist/src/suggest.js +200 -0
  195. package/dist/src/suggest.js.map +1 -0
  196. package/dist/tsconfig.tsbuildinfo +1 -1
  197. package/package.json +28 -6
  198. package/.agentic-flow/intelligence.json +0 -16
  199. package/.claude-flow/metrics/agent-metrics.json +0 -1
  200. package/.claude-flow/metrics/performance.json +0 -87
  201. package/.claude-flow/metrics/task-metrics.json +0 -10
  202. package/__tests__/README.md +0 -140
  203. package/__tests__/TEST_SUMMARY.md +0 -144
  204. package/__tests__/cli.test.ts +0 -558
  205. package/__tests__/commands.test.ts +0 -726
  206. package/__tests__/config-adapter.test.ts +0 -362
  207. package/__tests__/config-loading.test.ts +0 -106
  208. package/__tests__/coverage/.tmp/coverage-0.json +0 -1
  209. package/__tests__/coverage/.tmp/coverage-1.json +0 -1
  210. package/__tests__/coverage/.tmp/coverage-2.json +0 -1
  211. package/__tests__/coverage/.tmp/coverage-3.json +0 -1
  212. package/__tests__/coverage/.tmp/coverage-4.json +0 -1
  213. package/__tests__/coverage/.tmp/coverage-5.json +0 -1
  214. package/__tests__/mcp-client.test.ts +0 -480
  215. package/__tests__/p1-commands.test.ts +0 -1064
  216. package/docs/CONFIG_LOADING.md +0 -236
  217. package/docs/IMPLEMENTATION_COMPLETE.md +0 -421
  218. package/docs/MCP_CLIENT_GUIDE.md +0 -620
  219. package/docs/REFACTORING_SUMMARY.md +0 -247
  220. package/src/commands/agent.ts +0 -941
  221. package/src/commands/config.ts +0 -452
  222. package/src/commands/hive-mind.ts +0 -762
  223. package/src/commands/hooks.ts +0 -2603
  224. package/src/commands/index.ts +0 -115
  225. package/src/commands/init.ts +0 -597
  226. package/src/commands/mcp.ts +0 -753
  227. package/src/commands/memory.ts +0 -1063
  228. package/src/commands/migrate.ts +0 -447
  229. package/src/commands/process.ts +0 -617
  230. package/src/commands/session.ts +0 -891
  231. package/src/commands/start.ts +0 -457
  232. package/src/commands/status.ts +0 -705
  233. package/src/commands/swarm.ts +0 -648
  234. package/src/commands/task.ts +0 -792
  235. package/src/commands/workflow.ts +0 -742
  236. package/src/config-adapter.ts +0 -210
  237. package/src/index.ts +0 -383
  238. package/src/infrastructure/in-memory-repositories.ts +0 -310
  239. package/src/init/claudemd-generator.ts +0 -631
  240. package/src/init/executor.ts +0 -756
  241. package/src/init/helpers-generator.ts +0 -628
  242. package/src/init/index.ts +0 -60
  243. package/src/init/mcp-generator.ts +0 -83
  244. package/src/init/settings-generator.ts +0 -274
  245. package/src/init/statusline-generator.ts +0 -211
  246. package/src/init/types.ts +0 -447
  247. package/src/mcp-client.ts +0 -227
  248. package/src/mcp-server.ts +0 -571
  249. package/src/mcp-tools/agent-tools.ts +0 -92
  250. package/src/mcp-tools/config-tools.ts +0 -88
  251. package/src/mcp-tools/hooks-tools.ts +0 -1819
  252. package/src/mcp-tools/index.ts +0 -12
  253. package/src/mcp-tools/memory-tools.ts +0 -89
  254. package/src/mcp-tools/swarm-tools.ts +0 -69
  255. package/src/mcp-tools/types.ts +0 -33
  256. package/src/output.ts +0 -593
  257. package/src/parser.ts +0 -417
  258. package/src/prompt.ts +0 -619
  259. package/src/types.ts +0 -287
  260. package/tmp.json +0 -0
  261. package/tsconfig.json +0 -16
  262. package/tsconfig.tsbuildinfo +0 -1
  263. package/vitest.config.ts +0 -13
@@ -1,891 +0,0 @@
1
- /**
2
- * V3 CLI Session Command
3
- * Session management for Claude Flow
4
- */
5
-
6
- import type { Command, CommandContext, CommandResult } from '../types.js';
7
- import { output } from '../output.js';
8
- import { confirm, input, select } from '../prompt.js';
9
- import { callMCPTool, MCPClientError } from '../mcp-client.js';
10
- import * as fs from 'fs';
11
- import * as path from 'path';
12
-
13
- // Format date for display
14
- function formatDate(dateStr: string): string {
15
- const date = new Date(dateStr);
16
- const now = new Date();
17
- const diff = now.getTime() - date.getTime();
18
-
19
- // Less than 24 hours - show relative time
20
- if (diff < 24 * 60 * 60 * 1000) {
21
- const hours = Math.floor(diff / (60 * 60 * 1000));
22
- const minutes = Math.floor((diff % (60 * 60 * 1000)) / (60 * 1000));
23
-
24
- if (hours > 0) {
25
- return `${hours}h ${minutes}m ago`;
26
- }
27
- return `${minutes}m ago`;
28
- }
29
-
30
- // Otherwise show date
31
- return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
32
- }
33
-
34
- // Format session status
35
- function formatStatus(status: string): string {
36
- switch (status) {
37
- case 'active':
38
- return output.success(status);
39
- case 'saved':
40
- return output.info(status);
41
- case 'archived':
42
- return output.dim(status);
43
- default:
44
- return status;
45
- }
46
- }
47
-
48
- // List subcommand
49
- const listCommand: Command = {
50
- name: 'list',
51
- aliases: ['ls'],
52
- description: 'List all sessions',
53
- options: [
54
- {
55
- name: 'active',
56
- short: 'a',
57
- description: 'Show only active sessions',
58
- type: 'boolean',
59
- default: false
60
- },
61
- {
62
- name: 'all',
63
- description: 'Include archived sessions',
64
- type: 'boolean',
65
- default: false
66
- },
67
- {
68
- name: 'limit',
69
- short: 'l',
70
- description: 'Maximum sessions to show',
71
- type: 'number',
72
- default: 20
73
- }
74
- ],
75
- action: async (ctx: CommandContext): Promise<CommandResult> => {
76
- const activeOnly = ctx.flags.active as boolean;
77
- const includeArchived = ctx.flags.all as boolean;
78
- const limit = ctx.flags.limit as number;
79
-
80
- try {
81
- const result = await callMCPTool<{
82
- sessions: Array<{
83
- id: string;
84
- name?: string;
85
- description?: string;
86
- status: 'active' | 'saved' | 'archived';
87
- createdAt: string;
88
- updatedAt: string;
89
- agentCount: number;
90
- taskCount: number;
91
- memorySize: number;
92
- }>;
93
- total: number;
94
- }>('session/list', {
95
- status: activeOnly ? 'active' : includeArchived ? 'all' : 'active,saved',
96
- limit
97
- });
98
-
99
- if (ctx.flags.format === 'json') {
100
- output.printJson(result);
101
- return { success: true, data: result };
102
- }
103
-
104
- output.writeln();
105
- output.writeln(output.bold('Sessions'));
106
- output.writeln();
107
-
108
- if (result.sessions.length === 0) {
109
- output.printInfo('No sessions found');
110
- output.printInfo('Run "claude-flow session save" to create a session');
111
- return { success: true, data: result };
112
- }
113
-
114
- output.printTable({
115
- columns: [
116
- { key: 'id', header: 'ID', width: 20 },
117
- { key: 'name', header: 'Name', width: 20 },
118
- { key: 'status', header: 'Status', width: 10 },
119
- { key: 'agents', header: 'Agents', width: 8, align: 'right' },
120
- { key: 'tasks', header: 'Tasks', width: 8, align: 'right' },
121
- { key: 'updated', header: 'Last Updated', width: 18 }
122
- ],
123
- data: result.sessions.map(s => ({
124
- id: s.id,
125
- name: s.name || '-',
126
- status: formatStatus(s.status),
127
- agents: s.agentCount,
128
- tasks: s.taskCount,
129
- updated: formatDate(s.updatedAt)
130
- }))
131
- });
132
-
133
- output.writeln();
134
- output.printInfo(`Showing ${result.sessions.length} of ${result.total} sessions`);
135
-
136
- return { success: true, data: result };
137
- } catch (error) {
138
- if (error instanceof MCPClientError) {
139
- output.printError(`Failed to list sessions: ${error.message}`);
140
- } else {
141
- output.printError(`Unexpected error: ${String(error)}`);
142
- }
143
- return { success: false, exitCode: 1 };
144
- }
145
- }
146
- };
147
-
148
- // Save subcommand
149
- const saveCommand: Command = {
150
- name: 'save',
151
- aliases: ['create', 'checkpoint'],
152
- description: 'Save current session state',
153
- options: [
154
- {
155
- name: 'name',
156
- short: 'n',
157
- description: 'Session name',
158
- type: 'string'
159
- },
160
- {
161
- name: 'description',
162
- short: 'd',
163
- description: 'Session description',
164
- type: 'string'
165
- },
166
- {
167
- name: 'include-memory',
168
- description: 'Include memory state in session',
169
- type: 'boolean',
170
- default: true
171
- },
172
- {
173
- name: 'include-agents',
174
- description: 'Include agent state in session',
175
- type: 'boolean',
176
- default: true
177
- },
178
- {
179
- name: 'include-tasks',
180
- description: 'Include task state in session',
181
- type: 'boolean',
182
- default: true
183
- }
184
- ],
185
- action: async (ctx: CommandContext): Promise<CommandResult> => {
186
- let sessionName = ctx.flags.name as string;
187
- let description = ctx.flags.description as string;
188
-
189
- // Interactive mode
190
- if (!sessionName && ctx.interactive) {
191
- sessionName = await input({
192
- message: 'Session name:',
193
- default: `session-${Date.now().toString(36)}`,
194
- validate: (v) => v.length > 0 || 'Name is required'
195
- });
196
- }
197
-
198
- if (!description && ctx.interactive) {
199
- description = await input({
200
- message: 'Session description (optional):',
201
- default: ''
202
- });
203
- }
204
-
205
- const spinner = output.createSpinner({ text: 'Saving session...' });
206
- spinner.start();
207
-
208
- try {
209
- const result = await callMCPTool<{
210
- sessionId: string;
211
- name: string;
212
- description?: string;
213
- savedAt: string;
214
- includes: {
215
- memory: boolean;
216
- agents: boolean;
217
- tasks: boolean;
218
- };
219
- stats: {
220
- agentCount: number;
221
- taskCount: number;
222
- memoryEntries: number;
223
- totalSize: number;
224
- };
225
- }>('session/save', {
226
- name: sessionName,
227
- description,
228
- includeMemory: ctx.flags['include-memory'] !== false,
229
- includeAgents: ctx.flags['include-agents'] !== false,
230
- includeTasks: ctx.flags['include-tasks'] !== false
231
- });
232
-
233
- spinner.succeed('Session saved');
234
- output.writeln();
235
-
236
- output.printTable({
237
- columns: [
238
- { key: 'property', header: 'Property', width: 18 },
239
- { key: 'value', header: 'Value', width: 35 }
240
- ],
241
- data: [
242
- { property: 'Session ID', value: result.sessionId },
243
- { property: 'Name', value: result.name },
244
- { property: 'Description', value: result.description || '-' },
245
- { property: 'Saved At', value: new Date(result.savedAt).toLocaleString() },
246
- { property: 'Agents', value: result.stats.agentCount },
247
- { property: 'Tasks', value: result.stats.taskCount },
248
- { property: 'Memory Entries', value: result.stats.memoryEntries },
249
- { property: 'Total Size', value: formatSize(result.stats.totalSize) }
250
- ]
251
- });
252
-
253
- output.writeln();
254
- output.printSuccess(`Session saved: ${result.sessionId}`);
255
- output.printInfo(`Restore with: claude-flow session restore ${result.sessionId}`);
256
-
257
- if (ctx.flags.format === 'json') {
258
- output.printJson(result);
259
- }
260
-
261
- return { success: true, data: result };
262
- } catch (error) {
263
- spinner.fail('Failed to save session');
264
- if (error instanceof MCPClientError) {
265
- output.printError(`Error: ${error.message}`);
266
- } else {
267
- output.printError(`Unexpected error: ${String(error)}`);
268
- }
269
- return { success: false, exitCode: 1 };
270
- }
271
- }
272
- };
273
-
274
- // Restore subcommand
275
- const restoreCommand: Command = {
276
- name: 'restore',
277
- aliases: ['load'],
278
- description: 'Restore a saved session',
279
- options: [
280
- {
281
- name: 'force',
282
- short: 'f',
283
- description: 'Overwrite current state without confirmation',
284
- type: 'boolean',
285
- default: false
286
- },
287
- {
288
- name: 'memory-only',
289
- description: 'Only restore memory state',
290
- type: 'boolean',
291
- default: false
292
- },
293
- {
294
- name: 'agents-only',
295
- description: 'Only restore agent state',
296
- type: 'boolean',
297
- default: false
298
- },
299
- {
300
- name: 'tasks-only',
301
- description: 'Only restore task state',
302
- type: 'boolean',
303
- default: false
304
- }
305
- ],
306
- action: async (ctx: CommandContext): Promise<CommandResult> => {
307
- let sessionId = ctx.args[0];
308
- const force = ctx.flags.force as boolean;
309
-
310
- if (!sessionId && ctx.interactive) {
311
- // Show list to select from
312
- try {
313
- const sessions = await callMCPTool<{
314
- sessions: Array<{ id: string; name?: string; status: string; updatedAt: string }>;
315
- }>('session/list', { status: 'saved', limit: 20 });
316
-
317
- if (sessions.sessions.length === 0) {
318
- output.printWarning('No saved sessions found');
319
- return { success: false, exitCode: 1 };
320
- }
321
-
322
- sessionId = await select({
323
- message: 'Select session to restore:',
324
- options: sessions.sessions.map(s => ({
325
- value: s.id,
326
- label: s.name || s.id,
327
- hint: formatDate(s.updatedAt)
328
- }))
329
- });
330
- } catch (error) {
331
- if (error instanceof Error && error.message === 'User cancelled') {
332
- output.printInfo('Operation cancelled');
333
- return { success: true };
334
- }
335
- throw error;
336
- }
337
- }
338
-
339
- if (!sessionId) {
340
- output.printError('Session ID is required');
341
- return { success: false, exitCode: 1 };
342
- }
343
-
344
- // Confirm unless forced
345
- if (!force && ctx.interactive) {
346
- const confirmed = await confirm({
347
- message: 'This will overwrite current state. Continue?',
348
- default: false
349
- });
350
-
351
- if (!confirmed) {
352
- output.printInfo('Operation cancelled');
353
- return { success: true };
354
- }
355
- }
356
-
357
- const spinner = output.createSpinner({ text: 'Restoring session...' });
358
- spinner.start();
359
-
360
- try {
361
- // Determine what to restore
362
- const restoreMemory = !ctx.flags['agents-only'] && !ctx.flags['tasks-only'];
363
- const restoreAgents = !ctx.flags['memory-only'] && !ctx.flags['tasks-only'];
364
- const restoreTasks = !ctx.flags['memory-only'] && !ctx.flags['agents-only'];
365
-
366
- const result = await callMCPTool<{
367
- sessionId: string;
368
- restoredAt: string;
369
- restored: {
370
- memory: boolean;
371
- agents: boolean;
372
- tasks: boolean;
373
- };
374
- stats: {
375
- agentsRestored: number;
376
- tasksRestored: number;
377
- memoryEntriesRestored: number;
378
- };
379
- }>('session/restore', {
380
- sessionId,
381
- restoreMemory,
382
- restoreAgents,
383
- restoreTasks
384
- });
385
-
386
- spinner.succeed('Session restored');
387
- output.writeln();
388
-
389
- output.printTable({
390
- columns: [
391
- { key: 'component', header: 'Component', width: 20 },
392
- { key: 'status', header: 'Status', width: 15 },
393
- { key: 'count', header: 'Items', width: 10, align: 'right' }
394
- ],
395
- data: [
396
- {
397
- component: 'Memory',
398
- status: result.restored.memory ? output.success('Restored') : output.dim('Skipped'),
399
- count: result.stats.memoryEntriesRestored
400
- },
401
- {
402
- component: 'Agents',
403
- status: result.restored.agents ? output.success('Restored') : output.dim('Skipped'),
404
- count: result.stats.agentsRestored
405
- },
406
- {
407
- component: 'Tasks',
408
- status: result.restored.tasks ? output.success('Restored') : output.dim('Skipped'),
409
- count: result.stats.tasksRestored
410
- }
411
- ]
412
- });
413
-
414
- output.writeln();
415
- output.printSuccess(`Session ${sessionId} restored successfully`);
416
-
417
- if (ctx.flags.format === 'json') {
418
- output.printJson(result);
419
- }
420
-
421
- return { success: true, data: result };
422
- } catch (error) {
423
- spinner.fail('Failed to restore session');
424
- if (error instanceof MCPClientError) {
425
- output.printError(`Error: ${error.message}`);
426
- } else {
427
- output.printError(`Unexpected error: ${String(error)}`);
428
- }
429
- return { success: false, exitCode: 1 };
430
- }
431
- }
432
- };
433
-
434
- // Delete subcommand
435
- const deleteCommand: Command = {
436
- name: 'delete',
437
- aliases: ['rm', 'remove'],
438
- description: 'Delete a saved session',
439
- options: [
440
- {
441
- name: 'force',
442
- short: 'f',
443
- description: 'Delete without confirmation',
444
- type: 'boolean',
445
- default: false
446
- }
447
- ],
448
- action: async (ctx: CommandContext): Promise<CommandResult> => {
449
- const sessionId = ctx.args[0];
450
- const force = ctx.flags.force as boolean;
451
-
452
- if (!sessionId) {
453
- output.printError('Session ID is required');
454
- return { success: false, exitCode: 1 };
455
- }
456
-
457
- if (!force && ctx.interactive) {
458
- const confirmed = await confirm({
459
- message: `Delete session ${sessionId}? This cannot be undone.`,
460
- default: false
461
- });
462
-
463
- if (!confirmed) {
464
- output.printInfo('Operation cancelled');
465
- return { success: true };
466
- }
467
- }
468
-
469
- try {
470
- const result = await callMCPTool<{
471
- sessionId: string;
472
- deleted: boolean;
473
- deletedAt: string;
474
- }>('session/delete', { sessionId });
475
-
476
- output.writeln();
477
- output.printSuccess(`Session ${sessionId} deleted`);
478
-
479
- if (ctx.flags.format === 'json') {
480
- output.printJson(result);
481
- }
482
-
483
- return { success: true, data: result };
484
- } catch (error) {
485
- if (error instanceof MCPClientError) {
486
- output.printError(`Failed to delete session: ${error.message}`);
487
- } else {
488
- output.printError(`Unexpected error: ${String(error)}`);
489
- }
490
- return { success: false, exitCode: 1 };
491
- }
492
- }
493
- };
494
-
495
- // Export subcommand
496
- const exportCommand: Command = {
497
- name: 'export',
498
- description: 'Export session to file',
499
- options: [
500
- {
501
- name: 'output',
502
- short: 'o',
503
- description: 'Output file path',
504
- type: 'string'
505
- },
506
- {
507
- name: 'format',
508
- short: 'f',
509
- description: 'Export format (json, yaml)',
510
- type: 'string',
511
- choices: ['json', 'yaml'],
512
- default: 'json'
513
- },
514
- {
515
- name: 'include-memory',
516
- description: 'Include memory data',
517
- type: 'boolean',
518
- default: true
519
- },
520
- {
521
- name: 'compress',
522
- description: 'Compress output',
523
- type: 'boolean',
524
- default: false
525
- }
526
- ],
527
- action: async (ctx: CommandContext): Promise<CommandResult> => {
528
- let sessionId = ctx.args[0];
529
- let outputPath = ctx.flags.output as string;
530
- const exportFormat = ctx.flags.format as string;
531
- const compress = ctx.flags.compress as boolean;
532
-
533
- // Get current session if no ID provided
534
- if (!sessionId) {
535
- try {
536
- const current = await callMCPTool<{ sessionId: string }>('session/current', {});
537
- sessionId = current.sessionId;
538
- } catch {
539
- output.printError('No active session. Provide a session ID to export.');
540
- return { success: false, exitCode: 1 };
541
- }
542
- }
543
-
544
- // Generate output path if not provided
545
- if (!outputPath) {
546
- const ext = compress ? '.gz' : '';
547
- outputPath = `session-${sessionId}.${exportFormat}${ext}`;
548
- }
549
-
550
- const spinner = output.createSpinner({ text: 'Exporting session...' });
551
- spinner.start();
552
-
553
- try {
554
- const result = await callMCPTool<{
555
- sessionId: string;
556
- data: unknown;
557
- stats: {
558
- agentCount: number;
559
- taskCount: number;
560
- memoryEntries: number;
561
- };
562
- }>('session/export', {
563
- sessionId,
564
- includeMemory: ctx.flags['include-memory'] !== false
565
- });
566
-
567
- // Format output
568
- let content: string;
569
- if (exportFormat === 'yaml') {
570
- content = toSimpleYaml(result.data);
571
- } else {
572
- content = JSON.stringify(result.data, null, 2);
573
- }
574
-
575
- // Write to file
576
- const absolutePath = path.isAbsolute(outputPath)
577
- ? outputPath
578
- : path.join(ctx.cwd, outputPath);
579
-
580
- fs.writeFileSync(absolutePath, content, 'utf-8');
581
-
582
- spinner.succeed('Session exported');
583
- output.writeln();
584
-
585
- output.printTable({
586
- columns: [
587
- { key: 'property', header: 'Property', width: 18 },
588
- { key: 'value', header: 'Value', width: 40 }
589
- ],
590
- data: [
591
- { property: 'Session ID', value: sessionId },
592
- { property: 'Output File', value: absolutePath },
593
- { property: 'Format', value: exportFormat.toUpperCase() },
594
- { property: 'Agents', value: result.stats.agentCount },
595
- { property: 'Tasks', value: result.stats.taskCount },
596
- { property: 'Memory Entries', value: result.stats.memoryEntries },
597
- { property: 'File Size', value: formatSize(content.length) }
598
- ]
599
- });
600
-
601
- output.writeln();
602
- output.printSuccess(`Session exported to ${outputPath}`);
603
-
604
- return {
605
- success: true,
606
- data: { sessionId, outputPath, format: exportFormat, size: content.length }
607
- };
608
- } catch (error) {
609
- spinner.fail('Failed to export session');
610
- if (error instanceof MCPClientError) {
611
- output.printError(`Error: ${error.message}`);
612
- } else {
613
- output.printError(`Unexpected error: ${String(error)}`);
614
- }
615
- return { success: false, exitCode: 1 };
616
- }
617
- }
618
- };
619
-
620
- // Import subcommand
621
- const importCommand: Command = {
622
- name: 'import',
623
- description: 'Import session from file',
624
- options: [
625
- {
626
- name: 'name',
627
- short: 'n',
628
- description: 'Session name for imported session',
629
- type: 'string'
630
- },
631
- {
632
- name: 'activate',
633
- description: 'Activate session after import',
634
- type: 'boolean',
635
- default: false
636
- }
637
- ],
638
- action: async (ctx: CommandContext): Promise<CommandResult> => {
639
- const filePath = ctx.args[0];
640
- const sessionName = ctx.flags.name as string;
641
- const activate = ctx.flags.activate as boolean;
642
-
643
- if (!filePath) {
644
- output.printError('File path is required');
645
- return { success: false, exitCode: 1 };
646
- }
647
-
648
- const absolutePath = path.isAbsolute(filePath)
649
- ? filePath
650
- : path.join(ctx.cwd, filePath);
651
-
652
- if (!fs.existsSync(absolutePath)) {
653
- output.printError(`File not found: ${absolutePath}`);
654
- return { success: false, exitCode: 1 };
655
- }
656
-
657
- const spinner = output.createSpinner({ text: 'Importing session...' });
658
- spinner.start();
659
-
660
- try {
661
- const content = fs.readFileSync(absolutePath, 'utf-8');
662
- let data: unknown;
663
-
664
- // Parse based on extension
665
- if (absolutePath.endsWith('.yaml') || absolutePath.endsWith('.yml')) {
666
- // Simple YAML parsing (basic implementation)
667
- data = JSON.parse(content); // Would need proper YAML parser
668
- } else {
669
- data = JSON.parse(content);
670
- }
671
-
672
- const result = await callMCPTool<{
673
- sessionId: string;
674
- name: string;
675
- importedAt: string;
676
- stats: {
677
- agentsImported: number;
678
- tasksImported: number;
679
- memoryEntriesImported: number;
680
- };
681
- activated: boolean;
682
- }>('session/import', {
683
- data,
684
- name: sessionName,
685
- activate
686
- });
687
-
688
- spinner.succeed('Session imported');
689
- output.writeln();
690
-
691
- output.printTable({
692
- columns: [
693
- { key: 'property', header: 'Property', width: 20 },
694
- { key: 'value', header: 'Value', width: 35 }
695
- ],
696
- data: [
697
- { property: 'Session ID', value: result.sessionId },
698
- { property: 'Name', value: result.name },
699
- { property: 'Source File', value: path.basename(absolutePath) },
700
- { property: 'Agents Imported', value: result.stats.agentsImported },
701
- { property: 'Tasks Imported', value: result.stats.tasksImported },
702
- { property: 'Memory Entries', value: result.stats.memoryEntriesImported },
703
- { property: 'Activated', value: result.activated ? 'Yes' : 'No' }
704
- ]
705
- });
706
-
707
- output.writeln();
708
- output.printSuccess(`Session imported: ${result.sessionId}`);
709
-
710
- if (!result.activated) {
711
- output.printInfo(`Restore with: claude-flow session restore ${result.sessionId}`);
712
- }
713
-
714
- if (ctx.flags.format === 'json') {
715
- output.printJson(result);
716
- }
717
-
718
- return { success: true, data: result };
719
- } catch (error) {
720
- spinner.fail('Failed to import session');
721
- if (error instanceof MCPClientError) {
722
- output.printError(`Error: ${error.message}`);
723
- } else if (error instanceof SyntaxError) {
724
- output.printError('Invalid file format. Expected JSON or YAML.');
725
- } else {
726
- output.printError(`Unexpected error: ${String(error)}`);
727
- }
728
- return { success: false, exitCode: 1 };
729
- }
730
- }
731
- };
732
-
733
- // Current subcommand
734
- const currentCommand: Command = {
735
- name: 'current',
736
- description: 'Show current active session',
737
- action: async (ctx: CommandContext): Promise<CommandResult> => {
738
- try {
739
- const result = await callMCPTool<{
740
- sessionId: string;
741
- name?: string;
742
- status: string;
743
- startedAt: string;
744
- stats: {
745
- agentCount: number;
746
- taskCount: number;
747
- memoryEntries: number;
748
- duration: number;
749
- };
750
- }>('session/current', { includeStats: true });
751
-
752
- if (ctx.flags.format === 'json') {
753
- output.printJson(result);
754
- return { success: true, data: result };
755
- }
756
-
757
- output.writeln();
758
- output.writeln(output.bold('Current Session'));
759
- output.writeln();
760
-
761
- output.printTable({
762
- columns: [
763
- { key: 'property', header: 'Property', width: 18 },
764
- { key: 'value', header: 'Value', width: 35 }
765
- ],
766
- data: [
767
- { property: 'Session ID', value: result.sessionId },
768
- { property: 'Name', value: result.name || '-' },
769
- { property: 'Status', value: formatStatus(result.status) },
770
- { property: 'Started', value: new Date(result.startedAt).toLocaleString() },
771
- { property: 'Duration', value: formatDuration(result.stats.duration) },
772
- { property: 'Agents', value: result.stats.agentCount },
773
- { property: 'Tasks', value: result.stats.taskCount },
774
- { property: 'Memory Entries', value: result.stats.memoryEntries }
775
- ]
776
- });
777
-
778
- return { success: true, data: result };
779
- } catch (error) {
780
- if (error instanceof MCPClientError) {
781
- output.printWarning('No active session');
782
- output.printInfo('Start a session with "claude-flow start"');
783
- return { success: true, data: { active: false } };
784
- }
785
- output.printError(`Unexpected error: ${String(error)}`);
786
- return { success: false, exitCode: 1 };
787
- }
788
- }
789
- };
790
-
791
- // Helper functions
792
- function formatSize(bytes: number): string {
793
- if (bytes === 0) return '0 B';
794
- const k = 1024;
795
- const sizes = ['B', 'KB', 'MB', 'GB'];
796
- const i = Math.floor(Math.log(bytes) / Math.log(k));
797
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
798
- }
799
-
800
- function formatDuration(ms: number): string {
801
- const seconds = Math.floor(ms / 1000);
802
- const minutes = Math.floor(seconds / 60);
803
- const hours = Math.floor(minutes / 60);
804
-
805
- if (hours > 0) {
806
- return `${hours}h ${minutes % 60}m`;
807
- } else if (minutes > 0) {
808
- return `${minutes}m ${seconds % 60}s`;
809
- }
810
- return `${seconds}s`;
811
- }
812
-
813
- function toSimpleYaml(obj: unknown, indent: number = 0): string {
814
- // Simple YAML serializer (for basic types)
815
- if (obj === null) return 'null';
816
- if (typeof obj === 'boolean') return String(obj);
817
- if (typeof obj === 'number') return String(obj);
818
- if (typeof obj === 'string') return obj.includes(':') ? `"${obj}"` : obj;
819
-
820
- const spaces = ' '.repeat(indent);
821
- let result = '';
822
-
823
- if (Array.isArray(obj)) {
824
- for (const item of obj) {
825
- result += `${spaces}- ${toSimpleYaml(item, indent + 1).trim()}\n`;
826
- }
827
- return result;
828
- }
829
-
830
- if (typeof obj === 'object') {
831
- for (const [key, value] of Object.entries(obj)) {
832
- if (typeof value === 'object' && value !== null) {
833
- result += `${spaces}${key}:\n${toSimpleYaml(value, indent + 1)}`;
834
- } else {
835
- result += `${spaces}${key}: ${toSimpleYaml(value, indent)}\n`;
836
- }
837
- }
838
- return result;
839
- }
840
-
841
- return String(obj);
842
- }
843
-
844
- // Main session command
845
- export const sessionCommand: Command = {
846
- name: 'session',
847
- description: 'Session management commands',
848
- subcommands: [
849
- listCommand,
850
- saveCommand,
851
- restoreCommand,
852
- deleteCommand,
853
- exportCommand,
854
- importCommand,
855
- currentCommand
856
- ],
857
- options: [],
858
- examples: [
859
- { command: 'claude-flow session list', description: 'List all sessions' },
860
- { command: 'claude-flow session save -n "checkpoint-1"', description: 'Save current session' },
861
- { command: 'claude-flow session restore session-123', description: 'Restore a session' },
862
- { command: 'claude-flow session delete session-123', description: 'Delete a session' },
863
- { command: 'claude-flow session export -o backup.json', description: 'Export session to file' },
864
- { command: 'claude-flow session import backup.json', description: 'Import session from file' },
865
- { command: 'claude-flow session current', description: 'Show current session' }
866
- ],
867
- action: async (ctx: CommandContext): Promise<CommandResult> => {
868
- // Show help if no subcommand
869
- output.writeln();
870
- output.writeln(output.bold('Session Management Commands'));
871
- output.writeln();
872
- output.writeln('Usage: claude-flow session <subcommand> [options]');
873
- output.writeln();
874
- output.writeln('Subcommands:');
875
- output.printList([
876
- `${output.highlight('list')} - List all sessions`,
877
- `${output.highlight('save')} - Save current session state`,
878
- `${output.highlight('restore')} - Restore a saved session`,
879
- `${output.highlight('delete')} - Delete a saved session`,
880
- `${output.highlight('export')} - Export session to file`,
881
- `${output.highlight('import')} - Import session from file`,
882
- `${output.highlight('current')} - Show current active session`
883
- ]);
884
- output.writeln();
885
- output.writeln('Run "claude-flow session <subcommand> --help" for subcommand help');
886
-
887
- return { success: true };
888
- }
889
- };
890
-
891
- export default sessionCommand;