monomind 1.17.0 → 1.17.2
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.
- package/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/.claude/commands/mastermind/_repeat.md +4 -0
- package/.claude/commands/mastermind/master.md +52 -1
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/mastermind/_repeat.md +2 -0
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
- package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
- package/packages/@monomind/cli/dist/src/agents/registry-builder.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/agents/registry-builder.js +22 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
- package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +432 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +54 -943
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
- package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
- package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
- package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
- package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
- package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
- package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
- package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
- package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
- package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
- package/packages/@monomind/cli/dist/src/index.js +8 -37
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
- package/packages/@monomind/cli/dist/src/parser.js +11 -6
- package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
- package/packages/@monomind/cli/package.json +2 -3
- package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
|
@@ -572,7 +572,7 @@ const importCommand = {
|
|
|
572
572
|
: path.join(ctx.cwd, filePath);
|
|
573
573
|
// Path traversal protection: resolved path must stay within cwd or home
|
|
574
574
|
const resolvedPath = path.resolve(absolutePath);
|
|
575
|
-
const cwd = process.cwd();
|
|
575
|
+
const cwd = ctx.cwd || process.cwd();
|
|
576
576
|
const home = process.env.HOME || '';
|
|
577
577
|
const underCwd = resolvedPath === cwd || resolvedPath.startsWith(cwd + path.sep);
|
|
578
578
|
const underHome = home && (resolvedPath === home || resolvedPath.startsWith(home + path.sep));
|
|
@@ -635,30 +635,36 @@ const scaleCommand = {
|
|
|
635
635
|
output.printError('Swarm ID is required');
|
|
636
636
|
return { success: false, exitCode: 1 };
|
|
637
637
|
}
|
|
638
|
-
|
|
638
|
+
// 0 is a valid target (scale a swarm down to no agents) — check for
|
|
639
|
+
// presence, not truthiness.
|
|
640
|
+
if (targetAgents === undefined || Number.isNaN(targetAgents)) {
|
|
639
641
|
output.printError('Target agent count required. Use --agents or -a');
|
|
640
642
|
return { success: false, exitCode: 1 };
|
|
641
643
|
}
|
|
642
644
|
output.printInfo(`Scaling swarm ${swarmId} to ${targetAgents} agents...`);
|
|
643
|
-
// Calculate scaling delta — fetch actual count instead of hardcoded 8 (#1425)
|
|
644
|
-
let currentAgents = 0;
|
|
645
645
|
try {
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
646
|
+
const result = await callMCPTool('swarm_scale', { swarmId, targetAgents, agentType });
|
|
647
|
+
if (!result.success) {
|
|
648
|
+
output.printError(result.error || 'Failed to scale swarm');
|
|
649
|
+
return { success: false, exitCode: 1 };
|
|
650
|
+
}
|
|
651
|
+
if (result.spawned.length === 0 && result.terminated.length === 0) {
|
|
652
|
+
output.printInfo('Swarm already at target size');
|
|
653
|
+
return { success: true, data: result };
|
|
654
|
+
}
|
|
655
|
+
if (result.spawned.length > 0) {
|
|
656
|
+
output.printSuccess(`Spawned ${result.spawned.length} agent(s): ${result.spawned.join(', ')}`);
|
|
657
|
+
}
|
|
658
|
+
if (result.terminated.length > 0) {
|
|
659
|
+
output.printSuccess(`Terminated ${result.terminated.length} agent(s): ${result.terminated.join(', ')}`);
|
|
660
|
+
}
|
|
661
|
+
output.writeln(output.dim(` ${result.previousCount} → ${result.currentCount} agents`));
|
|
662
|
+
return { success: true, data: result };
|
|
653
663
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
return { success: true };
|
|
664
|
+
catch (error) {
|
|
665
|
+
output.printError(`Scale error: ${error instanceof MCPClientError ? error.message : String(error)}`);
|
|
666
|
+
return { success: false, exitCode: 1 };
|
|
658
667
|
}
|
|
659
|
-
// No swarm_scale MCP tool is available — report the computed delta but do not pretend to act
|
|
660
|
-
output.printWarning('Swarm scaling is not yet implemented. The target count was computed but no agents were spawned or stopped.');
|
|
661
|
-
return { success: false, message: 'Scaling not implemented', exitCode: 1 };
|
|
662
668
|
}
|
|
663
669
|
};
|
|
664
670
|
// Coordinate command (v1 specific)
|
|
@@ -439,50 +439,21 @@ export class CLI {
|
|
|
439
439
|
// Extra paths are read from MONOMIND_EXTRA_AGENT_PATHS env var (colon-separated)
|
|
440
440
|
// or fall back to the known local path when available.
|
|
441
441
|
try {
|
|
442
|
-
const { buildUnifiedRegistry } = await import('./agents/registry-builder.js');
|
|
442
|
+
const { buildUnifiedRegistry, computeAgentRoots } = await import('./agents/registry-builder.js');
|
|
443
443
|
const { mkdirSync } = await import('fs');
|
|
444
444
|
const { join } = await import('path');
|
|
445
|
-
const
|
|
446
|
-
const extraPaths = process.env.MONOMIND_EXTRA_AGENT_PATHS
|
|
447
|
-
? process.env.MONOMIND_EXTRA_AGENT_PATHS.split(':').filter(Boolean)
|
|
448
|
-
: [];
|
|
449
|
-
// Fallback: well-known sibling path relative to project root (no hardcoded dev paths)
|
|
450
|
-
const { existsSync } = await import('fs');
|
|
451
|
-
const siblingExtraPath = join(process.cwd(), '..', 'agency-agents');
|
|
452
|
-
if (extraPaths.length === 0 && existsSync(siblingExtraPath)) {
|
|
453
|
-
extraPaths.push(siblingExtraPath);
|
|
454
|
-
}
|
|
455
|
-
// extras-first so they win deduplication; dev agents fill in the rest
|
|
456
|
-
const roots = [...extraPaths, devAgentsRoot];
|
|
445
|
+
const roots = computeAgentRoots(process.cwd());
|
|
457
446
|
const outDir = join(process.cwd(), '.monomind');
|
|
458
447
|
mkdirSync(outDir, { recursive: true });
|
|
459
448
|
buildUnifiedRegistry(roots, join(outDir, 'registry.json'));
|
|
460
449
|
}
|
|
461
450
|
catch { /* optional — registry build failures must never block startup */ }
|
|
462
|
-
// Task 04: CapabilityMetadata
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if (existsSync(registryPath) && statSyncReg(registryPath).size <= MAX_REGISTRY_BYTES) {
|
|
469
|
-
const registry = JSON.parse(readFileSync(registryPath, 'utf-8'));
|
|
470
|
-
const entries = registry.agents ?? [];
|
|
471
|
-
const issues = [];
|
|
472
|
-
for (const agent of entries) {
|
|
473
|
-
if (!agent.slug)
|
|
474
|
-
issues.push(`Agent missing 'slug'`);
|
|
475
|
-
if (!agent.name)
|
|
476
|
-
issues.push(`Agent ${String(agent.slug ?? '?')} missing 'name'`);
|
|
477
|
-
if (!agent.description)
|
|
478
|
-
issues.push(`Agent ${String(agent.slug ?? '?')} missing 'description'`);
|
|
479
|
-
}
|
|
480
|
-
if (issues.length > 0) {
|
|
481
|
-
console.warn(`[CapabilityMetadata] ${issues.length} agent metadata issue(s) in registry — run 'monomind doctor' to review`);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
catch { /* optional */ }
|
|
451
|
+
// Task 04: CapabilityMetadata validation moved to `monomind doctor -c registry`
|
|
452
|
+
// (see doctor-project-checks.ts:checkAgentRegistry). Printing this from a
|
|
453
|
+
// fire-and-forget startup task raced process exit — short-lived commands
|
|
454
|
+
// could skip the warning even when the underlying issue was present. Doctor
|
|
455
|
+
// runs it synchronously within its own check pass instead, so it's always
|
|
456
|
+
// visible and itemized when you actually look for it.
|
|
486
457
|
// NOTE: Semantic routing (@monomind/routing) is constructed on-demand by
|
|
487
458
|
// its consumers — `monomind route` and `monomind agent --task` (see
|
|
488
459
|
// commands/route.ts and commands/agent.ts). It is intentionally NOT
|
|
@@ -8,6 +8,7 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, statSyn
|
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { randomBytes } from 'node:crypto';
|
|
10
10
|
import { getProjectCwd } from './types.js';
|
|
11
|
+
import { agentTools } from './agent-tools.js';
|
|
11
12
|
// Swarm state persistence
|
|
12
13
|
const SWARM_DIR = '.monomind/swarm';
|
|
13
14
|
const SWARM_STATE_FILE = 'swarm-state.json';
|
|
@@ -185,6 +186,82 @@ export const swarmTools = [
|
|
|
185
186
|
};
|
|
186
187
|
},
|
|
187
188
|
},
|
|
189
|
+
{
|
|
190
|
+
name: 'swarm_scale',
|
|
191
|
+
description: 'Scale a swarm to a target agent count by spawning or terminating agents',
|
|
192
|
+
category: 'swarm',
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: 'object',
|
|
195
|
+
properties: {
|
|
196
|
+
swarmId: { type: 'string', description: 'Swarm ID to scale' },
|
|
197
|
+
targetAgents: { type: 'number', description: 'Target number of agents' },
|
|
198
|
+
agentType: { type: 'string', description: 'Agent type for newly spawned agents (default: worker)' },
|
|
199
|
+
},
|
|
200
|
+
required: ['swarmId', 'targetAgents'],
|
|
201
|
+
},
|
|
202
|
+
handler: async (input) => {
|
|
203
|
+
const swarmId = input.swarmId;
|
|
204
|
+
const targetAgents = input.targetAgents;
|
|
205
|
+
const agentType = input.agentType || 'worker';
|
|
206
|
+
const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
207
|
+
if (!swarmId || FORBIDDEN_KEYS.has(swarmId)) {
|
|
208
|
+
return { success: false, error: 'Invalid swarm ID' };
|
|
209
|
+
}
|
|
210
|
+
if (!Number.isFinite(targetAgents) || targetAgents < 0 || !Number.isInteger(targetAgents)) {
|
|
211
|
+
return { success: false, error: 'targetAgents must be a non-negative integer' };
|
|
212
|
+
}
|
|
213
|
+
const store = loadSwarmStore();
|
|
214
|
+
if (!Object.hasOwn(store.swarms, swarmId)) {
|
|
215
|
+
return { success: false, error: `Swarm ${swarmId} not found` };
|
|
216
|
+
}
|
|
217
|
+
const swarm = store.swarms[swarmId];
|
|
218
|
+
const currentCount = swarm.agents.length;
|
|
219
|
+
const delta = targetAgents - currentCount;
|
|
220
|
+
const spawnTool = agentTools.find(t => t.name === 'agent_spawn');
|
|
221
|
+
const terminateTool = agentTools.find(t => t.name === 'agent_terminate');
|
|
222
|
+
const spawned = [];
|
|
223
|
+
const terminated = [];
|
|
224
|
+
if (delta > 0) {
|
|
225
|
+
for (let i = 0; i < delta; i++) {
|
|
226
|
+
const result = await spawnTool.handler({ agentType });
|
|
227
|
+
if (result.success && result.agentId) {
|
|
228
|
+
swarm.agents.push(result.agentId);
|
|
229
|
+
spawned.push(result.agentId);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (delta < 0) {
|
|
234
|
+
const toRemove = swarm.agents.slice(0, -delta);
|
|
235
|
+
for (const agentId of toRemove) {
|
|
236
|
+
const result = await terminateTool.handler({ agentId });
|
|
237
|
+
if (result.success) {
|
|
238
|
+
terminated.push(agentId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
swarm.agents = swarm.agents.filter(id => !terminated.includes(id));
|
|
242
|
+
}
|
|
243
|
+
swarm.maxAgents = Math.max(swarm.maxAgents, swarm.agents.length);
|
|
244
|
+
swarm.updatedAt = new Date().toISOString();
|
|
245
|
+
saveSwarmStore(store);
|
|
246
|
+
// Individual agent_spawn/agent_terminate calls can fail silently (e.g. a
|
|
247
|
+
// stale agent ID already evicted from the agent store) — report success
|
|
248
|
+
// only if the swarm actually reached the requested count, so callers
|
|
249
|
+
// can't mistake a no-op failure for "already at target size".
|
|
250
|
+
const targetReached = swarm.agents.length === targetAgents;
|
|
251
|
+
return {
|
|
252
|
+
success: targetReached,
|
|
253
|
+
error: targetReached
|
|
254
|
+
? undefined
|
|
255
|
+
: `Reached ${swarm.agents.length}/${targetAgents} agents — some spawn/terminate operations failed`,
|
|
256
|
+
swarmId,
|
|
257
|
+
previousCount: currentCount,
|
|
258
|
+
currentCount: swarm.agents.length,
|
|
259
|
+
targetAgents,
|
|
260
|
+
spawned,
|
|
261
|
+
terminated,
|
|
262
|
+
};
|
|
263
|
+
},
|
|
264
|
+
},
|
|
188
265
|
{
|
|
189
266
|
name: 'swarm_shutdown',
|
|
190
267
|
description: 'Shutdown a swarm and update persistent state',
|
|
@@ -296,12 +296,9 @@ export class CommandParser {
|
|
|
296
296
|
}
|
|
297
297
|
buildAliases() {
|
|
298
298
|
const aliases = {};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
// Add aliases from all commands and subcommands
|
|
299
|
+
// Add aliases from all commands and subcommands first (lowest priority) —
|
|
300
|
+
// any command's own options may still be re-applied by buildScopedAliases()
|
|
301
|
+
// once the resolved command is known.
|
|
305
302
|
for (const cmd of this.commands.values()) {
|
|
306
303
|
if (cmd.options) {
|
|
307
304
|
for (const opt of cmd.options) {
|
|
@@ -323,6 +320,14 @@ export class CommandParser {
|
|
|
323
320
|
}
|
|
324
321
|
}
|
|
325
322
|
}
|
|
323
|
+
// Global options are applied last so an unrelated command's short flag
|
|
324
|
+
// (e.g. "security scan --quick, -Q") can't silently shadow a global flag
|
|
325
|
+
// of the same letter (e.g. global "-Q, --quiet") for every other command.
|
|
326
|
+
for (const opt of this.globalOptions) {
|
|
327
|
+
if (opt.short) {
|
|
328
|
+
aliases[opt.short] = opt.name;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
326
331
|
return { ...aliases, ...this.options.aliases };
|
|
327
332
|
}
|
|
328
333
|
/**
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* Monomind always runs on top of Claude Code, so low-confidence route
|
|
5
5
|
* classification is delegated to the local `claude` CLI in headless print
|
|
6
6
|
* mode — NOT to the Anthropic API with a managed key. There is no
|
|
7
|
-
*
|
|
8
|
-
* host's existing Claude Code auth is reused.
|
|
7
|
+
* No API key required: the host's existing Claude Code auth is reused.
|
|
9
8
|
*
|
|
10
9
|
* The returned function matches `LLMFallbackConfig.llmCaller` from
|
|
11
10
|
* `@monomind/routing` — `(prompt: string) => Promise<string>`. When the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -81,8 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"typescript": "^5.3.0",
|
|
84
|
-
"vitest": "^4.1.4"
|
|
85
|
-
"@anthropic-ai/sdk": "^0.39.0"
|
|
84
|
+
"vitest": "^4.1.4"
|
|
86
85
|
},
|
|
87
86
|
"dependencies": {
|
|
88
87
|
"ws": "^8.21.0",
|
|
@@ -391,7 +391,7 @@ const FRAMEWORK_SIGNATURES = [
|
|
|
391
391
|
['Vite', 'package.json', ['"vite"']],
|
|
392
392
|
['Webpack', 'package.json', ['"webpack"']],
|
|
393
393
|
['TypeScript', 'package.json', ['"typescript"']],
|
|
394
|
-
['
|
|
394
|
+
['Claude Code', 'package.json', ['"@anthropic-ai/claude-code"']],
|
|
395
395
|
['Django', 'requirements.txt', ['django']],
|
|
396
396
|
['Flask', 'requirements.txt', ['flask']],
|
|
397
397
|
['FastAPI', 'requirements.txt', ['fastapi']],
|