claude-flow 3.5.69 → 3.5.71

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 (101) hide show
  1. package/package.json +1 -1
  2. package/v3/@claude-flow/cli/dist/src/commands/autopilot.js +1 -1
  3. package/v3/@claude-flow/cli/dist/src/commands/hooks.js +4 -7
  4. package/v3/@claude-flow/cli/dist/src/commands/init.js +0 -1
  5. package/v3/@claude-flow/cli/dist/src/commands/neural.js +1 -0
  6. package/v3/@claude-flow/cli/dist/src/commands/providers.js +228 -96
  7. package/v3/@claude-flow/cli/dist/src/commands/security.js +1 -1
  8. package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-tools.js +35 -1
  9. package/v3/@claude-flow/cli/dist/src/mcp-tools/agentdb-tools.js +81 -0
  10. package/v3/@claude-flow/cli/dist/src/mcp-tools/analyze-tools.js +29 -0
  11. package/v3/@claude-flow/cli/dist/src/mcp-tools/autopilot-tools.js +4 -0
  12. package/v3/@claude-flow/cli/dist/src/mcp-tools/browser-tools.js +146 -0
  13. package/v3/@claude-flow/cli/dist/src/mcp-tools/claims-tools.js +116 -0
  14. package/v3/@claude-flow/cli/dist/src/mcp-tools/config-tools.js +53 -0
  15. package/v3/@claude-flow/cli/dist/src/mcp-tools/coordination-tools.js +31 -0
  16. package/v3/@claude-flow/cli/dist/src/mcp-tools/daa-tools.js +61 -0
  17. package/v3/@claude-flow/cli/dist/src/mcp-tools/embeddings-tools.js +26 -0
  18. package/v3/@claude-flow/cli/dist/src/mcp-tools/github-tools.js +96 -0
  19. package/v3/@claude-flow/cli/dist/src/mcp-tools/guidance-tools.js +21 -0
  20. package/v3/@claude-flow/cli/dist/src/mcp-tools/hive-mind-tools.js +56 -0
  21. package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +176 -0
  22. package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +18 -2
  23. package/v3/@claude-flow/cli/dist/src/mcp-tools/neural-tools.js +51 -0
  24. package/v3/@claude-flow/cli/dist/src/mcp-tools/performance-tools.js +11 -0
  25. package/v3/@claude-flow/cli/dist/src/mcp-tools/ruvllm-tools.js +31 -0
  26. package/v3/@claude-flow/cli/dist/src/mcp-tools/security-tools.js +36 -0
  27. package/v3/@claude-flow/cli/dist/src/mcp-tools/session-tools.js +29 -0
  28. package/v3/@claude-flow/cli/dist/src/mcp-tools/swarm-tools.js +30 -0
  29. package/v3/@claude-flow/cli/dist/src/mcp-tools/system-tools.js +6 -0
  30. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +33 -0
  31. package/v3/@claude-flow/cli/dist/src/mcp-tools/terminal-tools.js +31 -0
  32. package/v3/@claude-flow/cli/dist/src/mcp-tools/transfer-tools.js +51 -0
  33. package/v3/@claude-flow/cli/dist/src/mcp-tools/wasm-agent-tools.js +61 -0
  34. package/v3/@claude-flow/cli/dist/src/mcp-tools/workflow-tools.js +82 -0
  35. package/v3/@claude-flow/cli/dist/src/memory/intelligence.d.ts +6 -1
  36. package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +51 -1
  37. package/v3/@claude-flow/cli/package.json +1 -1
  38. package/v3/@claude-flow/guidance/dist/adversarial.d.ts +284 -0
  39. package/v3/@claude-flow/guidance/dist/adversarial.js +572 -0
  40. package/v3/@claude-flow/guidance/dist/analyzer.d.ts +530 -0
  41. package/v3/@claude-flow/guidance/dist/analyzer.js +2518 -0
  42. package/v3/@claude-flow/guidance/dist/artifacts.d.ts +283 -0
  43. package/v3/@claude-flow/guidance/dist/artifacts.js +356 -0
  44. package/v3/@claude-flow/guidance/dist/authority.d.ts +290 -0
  45. package/v3/@claude-flow/guidance/dist/authority.js +558 -0
  46. package/v3/@claude-flow/guidance/dist/capabilities.d.ts +209 -0
  47. package/v3/@claude-flow/guidance/dist/capabilities.js +485 -0
  48. package/v3/@claude-flow/guidance/dist/coherence.d.ts +233 -0
  49. package/v3/@claude-flow/guidance/dist/coherence.js +372 -0
  50. package/v3/@claude-flow/guidance/dist/compiler.d.ts +87 -0
  51. package/v3/@claude-flow/guidance/dist/compiler.js +419 -0
  52. package/v3/@claude-flow/guidance/dist/conformance-kit.d.ts +225 -0
  53. package/v3/@claude-flow/guidance/dist/conformance-kit.js +629 -0
  54. package/v3/@claude-flow/guidance/dist/continue-gate.d.ts +214 -0
  55. package/v3/@claude-flow/guidance/dist/continue-gate.js +353 -0
  56. package/v3/@claude-flow/guidance/dist/crypto-utils.d.ts +17 -0
  57. package/v3/@claude-flow/guidance/dist/crypto-utils.js +24 -0
  58. package/v3/@claude-flow/guidance/dist/evolution.d.ts +282 -0
  59. package/v3/@claude-flow/guidance/dist/evolution.js +500 -0
  60. package/v3/@claude-flow/guidance/dist/gates.d.ts +79 -0
  61. package/v3/@claude-flow/guidance/dist/gates.js +302 -0
  62. package/v3/@claude-flow/guidance/dist/gateway.d.ts +206 -0
  63. package/v3/@claude-flow/guidance/dist/gateway.js +452 -0
  64. package/v3/@claude-flow/guidance/dist/generators.d.ts +153 -0
  65. package/v3/@claude-flow/guidance/dist/generators.js +682 -0
  66. package/v3/@claude-flow/guidance/dist/headless.d.ts +177 -0
  67. package/v3/@claude-flow/guidance/dist/headless.js +342 -0
  68. package/v3/@claude-flow/guidance/dist/hooks.d.ts +109 -0
  69. package/v3/@claude-flow/guidance/dist/hooks.js +347 -0
  70. package/v3/@claude-flow/guidance/dist/index.d.ts +205 -0
  71. package/v3/@claude-flow/guidance/dist/index.js +321 -0
  72. package/v3/@claude-flow/guidance/dist/ledger.d.ts +162 -0
  73. package/v3/@claude-flow/guidance/dist/ledger.js +375 -0
  74. package/v3/@claude-flow/guidance/dist/manifest-validator.d.ts +289 -0
  75. package/v3/@claude-flow/guidance/dist/manifest-validator.js +838 -0
  76. package/v3/@claude-flow/guidance/dist/memory-gate.d.ts +222 -0
  77. package/v3/@claude-flow/guidance/dist/memory-gate.js +382 -0
  78. package/v3/@claude-flow/guidance/dist/meta-governance.d.ts +265 -0
  79. package/v3/@claude-flow/guidance/dist/meta-governance.js +348 -0
  80. package/v3/@claude-flow/guidance/dist/optimizer.d.ts +104 -0
  81. package/v3/@claude-flow/guidance/dist/optimizer.js +329 -0
  82. package/v3/@claude-flow/guidance/dist/persistence.d.ts +189 -0
  83. package/v3/@claude-flow/guidance/dist/persistence.js +464 -0
  84. package/v3/@claude-flow/guidance/dist/proof.d.ts +185 -0
  85. package/v3/@claude-flow/guidance/dist/proof.js +238 -0
  86. package/v3/@claude-flow/guidance/dist/retriever.d.ts +116 -0
  87. package/v3/@claude-flow/guidance/dist/retriever.js +394 -0
  88. package/v3/@claude-flow/guidance/dist/ruvbot-integration.d.ts +370 -0
  89. package/v3/@claude-flow/guidance/dist/ruvbot-integration.js +738 -0
  90. package/v3/@claude-flow/guidance/dist/temporal.d.ts +426 -0
  91. package/v3/@claude-flow/guidance/dist/temporal.js +658 -0
  92. package/v3/@claude-flow/guidance/dist/trust.d.ts +283 -0
  93. package/v3/@claude-flow/guidance/dist/trust.js +473 -0
  94. package/v3/@claude-flow/guidance/dist/truth-anchors.d.ts +276 -0
  95. package/v3/@claude-flow/guidance/dist/truth-anchors.js +488 -0
  96. package/v3/@claude-flow/guidance/dist/types.d.ts +378 -0
  97. package/v3/@claude-flow/guidance/dist/types.js +10 -0
  98. package/v3/@claude-flow/guidance/dist/uncertainty.d.ts +372 -0
  99. package/v3/@claude-flow/guidance/dist/uncertainty.js +619 -0
  100. package/v3/@claude-flow/guidance/dist/wasm-kernel.d.ts +48 -0
  101. package/v3/@claude-flow/guidance/dist/wasm-kernel.js +158 -0
@@ -12,6 +12,7 @@
12
12
  * Note: Some optimization suggestions are illustrative
13
13
  */
14
14
  import { getProjectCwd } from './types.js';
15
+ import { validateIdentifier } from './validate-input.js';
15
16
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
16
17
  import { join } from 'node:path';
17
18
  import * as os from 'node:os';
@@ -158,6 +159,11 @@ export const performanceTools = [
158
159
  },
159
160
  },
160
161
  handler: async (_input) => {
162
+ if (_input.component) {
163
+ const v = validateIdentifier(_input.component, 'component');
164
+ if (!v.valid)
165
+ return { success: false, error: v.error };
166
+ }
161
167
  const loadAvg = os.loadavg();
162
168
  const cpus = os.cpus();
163
169
  const cpuPercent = Math.min((loadAvg[0] / cpus.length) * 100, 100);
@@ -346,6 +352,11 @@ export const performanceTools = [
346
352
  },
347
353
  },
348
354
  handler: async (input) => {
355
+ if (input.target) {
356
+ const v = validateIdentifier(input.target, 'target');
357
+ if (!v.valid)
358
+ return { success: false, error: v.error };
359
+ }
349
360
  const target = input.target || 'all';
350
361
  const durationSec = Math.min(input.duration || 1, 10);
351
362
  const durationMs = durationSec * 1000;
@@ -4,6 +4,7 @@
4
4
  * Exposes @ruvector/ruvllm-wasm operations via MCP protocol.
5
5
  * All tools gracefully degrade when the WASM package is not installed.
6
6
  */
7
+ import { validateIdentifier, validateText } from './validate-input.js';
7
8
  async function loadRuvllmWasm() {
8
9
  return import('../ruvector/ruvllm-wasm.js');
9
10
  }
@@ -67,6 +68,16 @@ export const ruvllmWasmTools = [
67
68
  required: ['routerId', 'name', 'embedding'],
68
69
  },
69
70
  handler: async (args) => {
71
+ {
72
+ const v = validateIdentifier(args.routerId, 'routerId');
73
+ if (!v.valid)
74
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
75
+ }
76
+ {
77
+ const v = validateIdentifier(args.name, 'name');
78
+ if (!v.valid)
79
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
80
+ }
70
81
  try {
71
82
  const router = hnswRouters.get(args.routerId);
72
83
  if (!router)
@@ -97,6 +108,11 @@ export const ruvllmWasmTools = [
97
108
  required: ['routerId', 'query'],
98
109
  },
99
110
  handler: async (args) => {
111
+ {
112
+ const v = validateIdentifier(args.routerId, 'routerId');
113
+ if (!v.valid)
114
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
115
+ }
100
116
  try {
101
117
  const router = hnswRouters.get(args.routerId);
102
118
  if (!router)
@@ -150,6 +166,11 @@ export const ruvllmWasmTools = [
150
166
  required: ['sonaId', 'quality'],
151
167
  },
152
168
  handler: async (args) => {
169
+ {
170
+ const v = validateIdentifier(args.sonaId, 'sonaId');
171
+ if (!v.valid)
172
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
173
+ }
153
174
  try {
154
175
  const sona = sonaInstances.get(args.sonaId);
155
176
  if (!sona)
@@ -207,6 +228,11 @@ export const ruvllmWasmTools = [
207
228
  required: ['loraId', 'quality'],
208
229
  },
209
230
  handler: async (args) => {
231
+ {
232
+ const v = validateIdentifier(args.loraId, 'loraId');
233
+ if (!v.valid)
234
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
235
+ }
210
236
  try {
211
237
  const lora = loraInstances.get(args.loraId);
212
238
  if (!lora)
@@ -235,6 +261,11 @@ export const ruvllmWasmTools = [
235
261
  required: ['messages', 'template'],
236
262
  },
237
263
  handler: async (args) => {
264
+ {
265
+ const v = validateText(args.template, 'template', 256);
266
+ if (!v.valid)
267
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
268
+ }
238
269
  try {
239
270
  const mod = await loadRuvllmWasm();
240
271
  const messages = args.messages;
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * Created with ❤️ by ruv.io
11
11
  */
12
+ import { validateText, validateIdentifier } from './validate-input.js';
12
13
  import { autoInstallPackage } from './auto-install.js';
13
14
  import { createRequire } from 'module';
14
15
  // Create require for resolving module paths
@@ -93,6 +94,11 @@ const aidefenceScanTool = {
93
94
  required: ['input'],
94
95
  },
95
96
  handler: async (args) => {
97
+ {
98
+ const v = validateText(args.input, 'input');
99
+ if (!v.valid)
100
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
101
+ }
96
102
  const input = args.input;
97
103
  const quick = args.quick;
98
104
  try {
@@ -167,6 +173,11 @@ const aidefenceAnalyzeTool = {
167
173
  required: ['input'],
168
174
  },
169
175
  handler: async (args) => {
176
+ {
177
+ const v = validateText(args.input, 'input');
178
+ if (!v.valid)
179
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
180
+ }
170
181
  const input = args.input;
171
182
  const searchSimilar = args.searchSimilar !== false;
172
183
  const k = args.k || 5;
@@ -296,6 +307,21 @@ const aidefenceLearnTool = {
296
307
  required: ['input', 'wasAccurate'],
297
308
  },
298
309
  handler: async (args) => {
310
+ {
311
+ const v = validateText(args.input, 'input');
312
+ if (!v.valid)
313
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
314
+ }
315
+ if (args.verdict) {
316
+ const v = validateText(args.verdict, 'verdict');
317
+ if (!v.valid)
318
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
319
+ }
320
+ if (args.threatType) {
321
+ const v = validateIdentifier(args.threatType, 'threatType');
322
+ if (!v.valid)
323
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
324
+ }
299
325
  const input = args.input;
300
326
  const wasAccurate = args.wasAccurate;
301
327
  const verdict = args.verdict;
@@ -358,6 +384,11 @@ const aidefenceIsSafeTool = {
358
384
  required: ['input'],
359
385
  },
360
386
  handler: async (args) => {
387
+ {
388
+ const v = validateText(args.input, 'input');
389
+ if (!v.valid)
390
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
391
+ }
361
392
  const input = args.input;
362
393
  try {
363
394
  const { isSafe } = await import('@claude-flow/aidefence');
@@ -397,6 +428,11 @@ const aidefenceHasPIITool = {
397
428
  required: ['input'],
398
429
  },
399
430
  handler: async (args) => {
431
+ {
432
+ const v = validateText(args.input, 'input');
433
+ if (!v.valid)
434
+ return { content: [{ type: 'text', text: JSON.stringify({ error: v.error }) }], isError: true };
435
+ }
400
436
  const input = args.input;
401
437
  try {
402
438
  const defender = await getAIDefence();
@@ -6,6 +6,7 @@
6
6
  import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync, statSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  import { getProjectCwd } from './types.js';
9
+ import { validateIdentifier, validateText } from './validate-input.js';
9
10
  // Storage paths
10
11
  const STORAGE_DIR = '.claude-flow';
11
12
  const SESSION_DIR = 'sessions';
@@ -105,6 +106,15 @@ export const sessionTools = [
105
106
  required: ['name'],
106
107
  },
107
108
  handler: async (input) => {
109
+ // Validate user-provided input (#1425)
110
+ const vName = validateText(input.name, 'name', 256);
111
+ if (!vName.valid)
112
+ return { success: false, error: vName.error };
113
+ if (input.description) {
114
+ const v = validateText(input.description, 'description');
115
+ if (!v.valid)
116
+ return { success: false, error: v.error };
117
+ }
108
118
  const sessionId = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
109
119
  // Load related data based on options
110
120
  const data = loadRelatedStores({
@@ -152,6 +162,17 @@ export const sessionTools = [
152
162
  },
153
163
  },
154
164
  handler: async (input) => {
165
+ // Validate user-provided input (#1425)
166
+ if (input.sessionId) {
167
+ const v = validateIdentifier(input.sessionId, 'sessionId');
168
+ if (!v.valid)
169
+ return { success: false, error: v.error };
170
+ }
171
+ if (input.name) {
172
+ const v = validateText(input.name, 'name', 256);
173
+ if (!v.valid)
174
+ return { success: false, error: v.error };
175
+ }
155
176
  let session = null;
156
177
  // Try to find by sessionId first
157
178
  if (input.sessionId) {
@@ -279,6 +300,10 @@ export const sessionTools = [
279
300
  required: ['sessionId'],
280
301
  },
281
302
  handler: async (input) => {
303
+ // Validate user-provided input (#1425)
304
+ const vId = validateIdentifier(input.sessionId, 'sessionId');
305
+ if (!vId.valid)
306
+ return { success: false, error: vId.error };
282
307
  const sessionId = input.sessionId;
283
308
  const path = getSessionPath(sessionId);
284
309
  if (existsSync(path)) {
@@ -308,6 +333,10 @@ export const sessionTools = [
308
333
  required: ['sessionId'],
309
334
  },
310
335
  handler: async (input) => {
336
+ // Validate user-provided input (#1425)
337
+ const vId = validateIdentifier(input.sessionId, 'sessionId');
338
+ if (!vId.valid)
339
+ return { success: false, error: vId.error };
311
340
  const sessionId = input.sessionId;
312
341
  const session = loadSession(sessionId);
313
342
  if (session) {
@@ -7,6 +7,7 @@
7
7
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
8
8
  import { join } from 'node:path';
9
9
  import { getProjectCwd } from './types.js';
10
+ import { validateIdentifier } from './validate-input.js';
10
11
  // Swarm state persistence
11
12
  const SWARM_DIR = '.claude-flow/swarm';
12
13
  const SWARM_STATE_FILE = 'swarm-state.json';
@@ -55,6 +56,17 @@ export const swarmTools = [
55
56
  },
56
57
  },
57
58
  handler: async (input) => {
59
+ // Validate user-provided input (#1425)
60
+ if (input.topology) {
61
+ const v = validateIdentifier(input.topology, 'topology');
62
+ if (!v.valid)
63
+ return { success: false, error: v.error };
64
+ }
65
+ if (input.strategy) {
66
+ const v = validateIdentifier(input.strategy, 'strategy');
67
+ if (!v.valid)
68
+ return { success: false, error: v.error };
69
+ }
58
70
  const topology = input.topology || 'hierarchical-mesh';
59
71
  const maxAgents = Math.min(Math.max(input.maxAgents || 15, 1), 50);
60
72
  const strategy = input.strategy || 'specialized';
@@ -111,6 +123,12 @@ export const swarmTools = [
111
123
  },
112
124
  },
113
125
  handler: async (input) => {
126
+ // Validate user-provided input (#1425)
127
+ if (input.swarmId) {
128
+ const v = validateIdentifier(input.swarmId, 'swarmId');
129
+ if (!v.valid)
130
+ return { success: false, error: v.error };
131
+ }
114
132
  const store = loadSwarmStore();
115
133
  const swarmId = input.swarmId;
116
134
  if (swarmId && store.swarms[swarmId]) {
@@ -165,6 +183,12 @@ export const swarmTools = [
165
183
  },
166
184
  },
167
185
  handler: async (input) => {
186
+ // Validate user-provided input (#1425)
187
+ if (input.swarmId) {
188
+ const v = validateIdentifier(input.swarmId, 'swarmId');
189
+ if (!v.valid)
190
+ return { success: false, error: v.error };
191
+ }
168
192
  const store = loadSwarmStore();
169
193
  const swarmId = input.swarmId;
170
194
  // Find the swarm
@@ -216,6 +240,12 @@ export const swarmTools = [
216
240
  },
217
241
  },
218
242
  handler: async (input) => {
243
+ // Validate user-provided input (#1425)
244
+ if (input.swarmId) {
245
+ const v = validateIdentifier(input.swarmId, 'swarmId');
246
+ if (!v.valid)
247
+ return { success: false, error: v.error };
248
+ }
219
249
  const store = loadSwarmStore();
220
250
  const swarmId = input.swarmId;
221
251
  // Find the swarm
@@ -9,6 +9,7 @@
9
9
  * - os module for system information
10
10
  */
11
11
  import { getProjectCwd } from './types.js';
12
+ import { validateIdentifier } from './validate-input.js';
12
13
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
13
14
  import { join, dirname } from 'node:path';
14
15
  import { fileURLToPath } from 'node:url';
@@ -437,6 +438,11 @@ export const systemTools = [
437
438
  if (!input.confirm) {
438
439
  return { success: false, error: 'Reset requires confirmation' };
439
440
  }
441
+ if (input.component) {
442
+ const v = validateIdentifier(input.component, 'component');
443
+ if (!v.valid)
444
+ return { success: false, error: v.error };
445
+ }
440
446
  const component = input.component || 'metrics';
441
447
  // Reset metrics to defaults
442
448
  const defaultMetrics = {
@@ -6,6 +6,7 @@
6
6
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  import { getProjectCwd } from './types.js';
9
+ import { validateIdentifier, validateText } from './validate-input.js';
9
10
  // Storage paths
10
11
  const STORAGE_DIR = '.claude-flow';
11
12
  const TASK_DIR = 'tasks';
@@ -56,6 +57,13 @@ export const taskTools = [
56
57
  required: ['type', 'description'],
57
58
  },
58
59
  handler: async (input) => {
60
+ // Validate user-provided input (#1425)
61
+ const vType = validateIdentifier(input.type, 'type');
62
+ if (!vType.valid)
63
+ return { success: false, error: vType.error };
64
+ const vDesc = validateText(input.description, 'description');
65
+ if (!vDesc.valid)
66
+ return { success: false, error: vDesc.error };
59
67
  const store = loadTaskStore();
60
68
  const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
61
69
  const task = {
@@ -97,6 +105,10 @@ export const taskTools = [
97
105
  required: ['taskId'],
98
106
  },
99
107
  handler: async (input) => {
108
+ // Validate user-provided input (#1425)
109
+ const vId = validateIdentifier(input.taskId, 'taskId');
110
+ if (!vId.valid)
111
+ return { success: false, error: vId.error };
100
112
  const store = loadTaskStore();
101
113
  const taskId = input.taskId;
102
114
  const task = store.tasks[taskId];
@@ -194,6 +206,10 @@ export const taskTools = [
194
206
  required: ['taskId'],
195
207
  },
196
208
  handler: async (input) => {
209
+ // Validate user-provided input (#1425)
210
+ const vId = validateIdentifier(input.taskId, 'taskId');
211
+ if (!vId.valid)
212
+ return { success: false, error: vId.error };
197
213
  const store = loadTaskStore();
198
214
  const taskId = input.taskId;
199
215
  const task = store.tasks[taskId];
@@ -254,6 +270,10 @@ export const taskTools = [
254
270
  required: ['taskId'],
255
271
  },
256
272
  handler: async (input) => {
273
+ // Validate user-provided input (#1425)
274
+ const vId = validateIdentifier(input.taskId, 'taskId');
275
+ if (!vId.valid)
276
+ return { success: false, error: vId.error };
257
277
  const store = loadTaskStore();
258
278
  const taskId = input.taskId;
259
279
  const task = store.tasks[taskId];
@@ -301,6 +321,10 @@ export const taskTools = [
301
321
  required: ['taskId'],
302
322
  },
303
323
  handler: async (input) => {
324
+ // Validate user-provided input (#1425)
325
+ const vId = validateIdentifier(input.taskId, 'taskId');
326
+ if (!vId.valid)
327
+ return { success: false, error: vId.error };
304
328
  const store = loadTaskStore();
305
329
  const taskId = input.taskId;
306
330
  const task = store.tasks[taskId];
@@ -380,6 +404,15 @@ export const taskTools = [
380
404
  required: ['taskId'],
381
405
  },
382
406
  handler: async (input) => {
407
+ // Validate user-provided input (#1425)
408
+ const vId = validateIdentifier(input.taskId, 'taskId');
409
+ if (!vId.valid)
410
+ return { success: false, error: vId.error };
411
+ if (input.reason) {
412
+ const v = validateText(input.reason, 'reason');
413
+ if (!v.valid)
414
+ return { success: false, error: v.error };
415
+ }
383
416
  const store = loadTaskStore();
384
417
  const taskId = input.taskId;
385
418
  const task = store.tasks[taskId];
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { getProjectCwd } from './types.js';
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
8
+ import { validateIdentifier, validatePath, validateText } from './validate-input.js';
8
9
  import { join } from 'node:path';
9
10
  import { execSync } from 'node:child_process';
10
11
  // Storage paths
@@ -53,6 +54,17 @@ export const terminalTools = [
53
54
  },
54
55
  },
55
56
  handler: async (input) => {
57
+ // Validate user-provided input (#1425)
58
+ if (input.name) {
59
+ const v = validateText(input.name, 'name', 256);
60
+ if (!v.valid)
61
+ return { success: false, error: v.error };
62
+ }
63
+ if (input.workingDir) {
64
+ const v = validatePath(input.workingDir, 'workingDir');
65
+ if (!v.valid)
66
+ return { success: false, error: v.error };
67
+ }
56
68
  const store = loadTerminalStore();
57
69
  const id = `term-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
58
70
  const session = {
@@ -92,6 +104,15 @@ export const terminalTools = [
92
104
  required: ['command'],
93
105
  },
94
106
  handler: async (input) => {
107
+ // Validate user-provided input (#1425)
108
+ const vCmd = validateText(input.command, 'command', 10_000);
109
+ if (!vCmd.valid)
110
+ return { success: false, error: vCmd.error };
111
+ if (input.sessionId) {
112
+ const v = validateIdentifier(input.sessionId, 'sessionId');
113
+ if (!v.valid)
114
+ return { success: false, error: v.error };
115
+ }
95
116
  const store = loadTerminalStore();
96
117
  const sessionId = input.sessionId;
97
118
  const command = input.command;
@@ -201,6 +222,10 @@ export const terminalTools = [
201
222
  required: ['sessionId'],
202
223
  },
203
224
  handler: async (input) => {
225
+ // Validate user-provided input (#1425)
226
+ const vId = validateIdentifier(input.sessionId, 'sessionId');
227
+ if (!vId.valid)
228
+ return { success: false, error: vId.error };
204
229
  const store = loadTerminalStore();
205
230
  const sessionId = input.sessionId;
206
231
  const session = store.sessions[sessionId];
@@ -229,6 +254,12 @@ export const terminalTools = [
229
254
  },
230
255
  },
231
256
  handler: async (input) => {
257
+ // Validate user-provided input (#1425)
258
+ if (input.sessionId) {
259
+ const v = validateIdentifier(input.sessionId, 'sessionId');
260
+ if (!v.valid)
261
+ return { success: false, error: v.error };
262
+ }
232
263
  const store = loadTerminalStore();
233
264
  const sessionId = input.sessionId;
234
265
  const limit = input.limit || 50;
@@ -5,6 +5,7 @@
5
5
  * @module @claude-flow/cli/mcp-tools/transfer-tools
6
6
  * @version 3.0.0
7
7
  */
8
+ import { validateIdentifier, validateText } from './validate-input.js';
8
9
  /**
9
10
  * Helper to create MCP tool result
10
11
  */
@@ -42,6 +43,11 @@ export const transferTools = [
42
43
  required: ['content'],
43
44
  },
44
45
  handler: async (input) => {
46
+ {
47
+ const v = validateText(input.content, 'content');
48
+ if (!v.valid)
49
+ return createResult({ error: v.error }, true);
50
+ }
45
51
  try {
46
52
  const { detectPII } = await import('../transfer/anonymization/index.js');
47
53
  const result = detectPII(input.content);
@@ -71,6 +77,11 @@ export const transferTools = [
71
77
  required: ['name'],
72
78
  },
73
79
  handler: async (input) => {
80
+ {
81
+ const v = validateIdentifier(input.name, 'name');
82
+ if (!v.valid)
83
+ return createResult({ error: v.error }, true);
84
+ }
74
85
  try {
75
86
  const { resolveIPNS } = await import('../transfer/ipfs/client.js');
76
87
  const result = await resolveIPNS(input.name);
@@ -115,6 +126,16 @@ export const transferTools = [
115
126
  },
116
127
  },
117
128
  handler: async (input) => {
129
+ if (input.query) {
130
+ const v = validateText(input.query, 'query');
131
+ if (!v.valid)
132
+ return createResult({ error: v.error }, true);
133
+ }
134
+ if (input.category) {
135
+ const v = validateIdentifier(input.category, 'category');
136
+ if (!v.valid)
137
+ return createResult({ error: v.error }, true);
138
+ }
118
139
  try {
119
140
  const { PatternStore } = await import('../transfer/store/index.js');
120
141
  const store = new PatternStore();
@@ -143,6 +164,11 @@ export const transferTools = [
143
164
  required: ['id'],
144
165
  },
145
166
  handler: async (input) => {
167
+ {
168
+ const v = validateIdentifier(input.id, 'id');
169
+ if (!v.valid)
170
+ return createResult({ error: v.error }, true);
171
+ }
146
172
  try {
147
173
  const { PatternStore } = await import('../transfer/store/index.js');
148
174
  const store = new PatternStore();
@@ -178,6 +204,11 @@ export const transferTools = [
178
204
  required: ['id'],
179
205
  },
180
206
  handler: async (input) => {
207
+ {
208
+ const v = validateIdentifier(input.id, 'id');
209
+ if (!v.valid)
210
+ return createResult({ error: v.error }, true);
211
+ }
181
212
  try {
182
213
  const { PatternStore } = await import('../transfer/store/index.js');
183
214
  const store = new PatternStore();
@@ -284,6 +315,21 @@ export const transferTools = [
284
315
  },
285
316
  },
286
317
  handler: async (input) => {
318
+ if (input.query) {
319
+ const v = validateText(input.query, 'query');
320
+ if (!v.valid)
321
+ return createResult({ error: v.error }, true);
322
+ }
323
+ if (input.category) {
324
+ const v = validateIdentifier(input.category, 'category');
325
+ if (!v.valid)
326
+ return createResult({ error: v.error }, true);
327
+ }
328
+ if (input.type) {
329
+ const v = validateIdentifier(input.type, 'type');
330
+ if (!v.valid)
331
+ return createResult({ error: v.error }, true);
332
+ }
287
333
  try {
288
334
  const { createPluginDiscoveryService, searchPlugins } = await import('../plugins/store/index.js');
289
335
  const discovery = createPluginDiscoveryService();
@@ -316,6 +362,11 @@ export const transferTools = [
316
362
  required: ['name'],
317
363
  },
318
364
  handler: async (input) => {
365
+ {
366
+ const v = validateIdentifier(input.name, 'name');
367
+ if (!v.valid)
368
+ return createResult({ error: v.error }, true);
369
+ }
319
370
  try {
320
371
  const { createPluginDiscoveryService } = await import('../plugins/store/index.js');
321
372
  const discovery = createPluginDiscoveryService();