monomind 1.8.0 → 1.9.0
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/design/design-monodesign.md +121 -0
- package/.claude/agents/github/issue-tracker.md +12 -12
- package/.claude/agents/github/pr-manager.md +10 -10
- package/.claude/agents/github/release-manager.md +49 -105
- package/.claude/agents/github/repo-architect.md +73 -92
- package/.claude/agents/github/sync-coordinator.md +55 -123
- package/.claude/agents/marketing/marketing-competitive-content.md +155 -0
- package/.claude/agents/marketing/marketing-content-creator.md +13 -0
- package/.claude/agents/marketing/marketing-cro-specialist.md +147 -0
- package/.claude/agents/marketing/marketing-email-specialist.md +90 -0
- package/.claude/agents/marketing/marketing-launch-strategist.md +129 -0
- package/.claude/agents/marketing/marketing-pricing-strategist.md +127 -0
- package/.claude/agents/specialists/integration-architect.md +94 -0
- package/.claude/commands/agents/README.md +4 -0
- package/.claude/commands/agents/agent-capabilities.md +6 -2
- package/.claude/commands/agents/agent-coordination.md +4 -0
- package/.claude/commands/agents/agent-spawning.md +4 -0
- package/.claude/commands/agents/agent-types.md +6 -2
- package/.claude/commands/analysis/README.md +14 -5
- package/.claude/commands/analysis/bottleneck-detect.md +30 -123
- package/.claude/commands/analysis/performance-bottlenecks.md +14 -14
- package/.claude/commands/analysis/performance-report.md +38 -11
- package/.claude/commands/analysis/token-efficiency.md +13 -16
- package/.claude/commands/analysis/token-usage.md +34 -12
- package/.claude/commands/automation/README.md +15 -5
- package/.claude/commands/automation/auto-agent.md +49 -85
- package/.claude/commands/automation/self-healing.md +20 -18
- package/.claude/commands/automation/session-memory.md +28 -29
- package/.claude/commands/automation/smart-agents.md +17 -9
- package/.claude/commands/automation/smart-spawn.md +52 -11
- package/.claude/commands/automation/workflow-select.md +46 -11
- package/.claude/commands/browse.md +5 -0
- package/.claude/commands/coordination/README.md +9 -5
- package/.claude/commands/coordination/agent-spawn.md +53 -9
- package/.claude/commands/coordination/swarm-init.md +39 -42
- package/.claude/commands/coordination/task-orchestrate.md +65 -11
- package/.claude/commands/github/README.md +21 -8
- package/.claude/commands/github/github-modes.md +9 -5
- package/.claude/commands/github/issue-tracker.md +34 -33
- package/.claude/commands/github/pr-manager.md +20 -17
- package/.claude/commands/github/release-manager.md +37 -49
- package/.claude/commands/github/repo-architect.md +39 -41
- package/.claude/commands/github/sync-coordinator.md +45 -49
- package/.claude/commands/hive-mind/README.md +42 -17
- package/.claude/commands/hive-mind/hive-mind-consensus.md +68 -4
- package/.claude/commands/hive-mind/hive-mind-init.md +55 -5
- package/.claude/commands/hive-mind/hive-mind-memory.md +69 -4
- package/.claude/commands/hive-mind/hive-mind-spawn.md +71 -10
- package/.claude/commands/hive-mind/hive-mind-status.md +52 -4
- package/.claude/commands/hive-mind/hive-mind-stop.md +51 -4
- package/.claude/commands/hive-mind/hive-mind.md +74 -14
- package/.claude/commands/hooks/README.md +62 -7
- package/.claude/commands/hooks/overview.md +94 -35
- package/.claude/commands/hooks/post-edit.md +48 -87
- package/.claude/commands/hooks/post-task.md +37 -87
- package/.claude/commands/hooks/pre-edit.md +52 -84
- package/.claude/commands/hooks/pre-task.md +46 -81
- package/.claude/commands/hooks/session-end.md +49 -85
- package/.claude/commands/hooks/setup.md +87 -58
- package/.claude/commands/mastermind/_repeat.md +308 -0
- package/.claude/commands/mastermind/architect.md +49 -0
- package/.claude/commands/mastermind/brain.md +98 -0
- package/.claude/commands/mastermind/build.md +22 -0
- package/.claude/commands/mastermind/content.md +22 -0
- package/.claude/commands/mastermind/createorg.md +94 -0
- package/.claude/commands/mastermind/finance.md +22 -0
- package/.claude/commands/mastermind/idea.md +22 -0
- package/.claude/commands/mastermind/marketing.md +22 -0
- package/.claude/commands/mastermind/master.md +379 -0
- package/.claude/commands/mastermind/ops.md +22 -0
- package/.claude/commands/mastermind/release.md +22 -0
- package/.claude/commands/mastermind/research.md +22 -0
- package/.claude/commands/mastermind/review.md +22 -0
- package/.claude/commands/mastermind/runorg.md +106 -0
- package/.claude/commands/mastermind/sales.md +22 -0
- package/.claude/commands/mastermind/techport.md +17 -0
- package/.claude/commands/memory/README.md +75 -5
- package/.claude/commands/memory/memory-search.md +63 -11
- package/.claude/commands/monitoring/README.md +64 -4
- package/.claude/commands/monitoring/agent-metrics.md +50 -10
- package/.claude/commands/monitoring/agents.md +59 -32
- package/.claude/commands/monitoring/status.md +96 -34
- package/.claude/commands/monograph/README.md +102 -0
- package/.claude/commands/monograph/monograph-build.md +79 -0
- package/.claude/commands/monograph/monograph-search.md +96 -0
- package/.claude/commands/monograph/monograph-stats.md +53 -0
- package/.claude/commands/monograph/monograph-watch.md +63 -0
- package/.claude/commands/monograph/monograph-wiki.md +91 -0
- package/.claude/commands/monomind/createtask.md +277 -0
- package/.claude/commands/{monomind-do.md → monomind/do.md} +21 -8
- package/.claude/commands/monomind/help.md +118 -0
- package/.claude/commands/{monomind-idea.md → monomind/idea.md} +22 -28
- package/.claude/commands/{monomind-improve.md → monomind/improve.md} +21 -27
- package/.claude/commands/monomind/memory.md +230 -0
- package/.claude/commands/monomind/repeat.md +201 -0
- package/.claude/commands/monomind/review.md +313 -0
- package/.claude/commands/monomind/specialagents.md +125 -0
- package/.claude/commands/monomind/swarm.md +161 -0
- package/.claude/commands/monomind/understand.md +148 -0
- package/.claude/commands/optimization/README.md +69 -5
- package/.claude/commands/optimization/auto-topology.md +66 -43
- package/.claude/commands/optimization/parallel-execution.md +65 -39
- package/.claude/commands/optimization/performance-optimize.md +79 -0
- package/.claude/commands/pair/README.md +48 -230
- package/.claude/commands/pair/examples.md +85 -441
- package/.claude/commands/pair/modes.md +77 -303
- package/.claude/commands/pair/session.md +76 -359
- package/.claude/commands/sparc/analyzer.md +9 -26
- package/.claude/commands/sparc/architect.md +8 -25
- package/.claude/commands/sparc/ask.md +27 -68
- package/.claude/commands/sparc/batch-executor.md +8 -25
- package/.claude/commands/sparc/code.md +12 -53
- package/.claude/commands/sparc/coder.md +8 -25
- package/.claude/commands/sparc/debug.md +12 -53
- package/.claude/commands/sparc/debugger.md +8 -25
- package/.claude/commands/sparc/designer.md +8 -25
- package/.claude/commands/sparc/devops.md +16 -57
- package/.claude/commands/sparc/docs-writer.md +12 -53
- package/.claude/commands/sparc/documenter.md +8 -25
- package/.claude/commands/sparc/innovator.md +8 -25
- package/.claude/commands/sparc/integration.md +12 -53
- package/.claude/commands/sparc/mcp.md +12 -53
- package/.claude/commands/sparc/memory-manager.md +28 -25
- package/.claude/commands/sparc/optimizer.md +8 -25
- package/.claude/commands/sparc/orchestrator.md +35 -97
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +13 -54
- package/.claude/commands/sparc/refinement-optimization-mode.md +13 -54
- package/.claude/commands/sparc/researcher.md +8 -25
- package/.claude/commands/sparc/reviewer.md +8 -25
- package/.claude/commands/sparc/security-review.md +13 -54
- package/.claude/commands/sparc/sparc-modes.md +97 -151
- package/.claude/commands/sparc/sparc.md +16 -56
- package/.claude/commands/sparc/spec-pseudocode.md +13 -54
- package/.claude/commands/sparc/supabase-admin.md +19 -66
- package/.claude/commands/sparc/swarm-coordinator.md +21 -25
- package/.claude/commands/sparc/tdd.md +8 -25
- package/.claude/commands/sparc/tester.md +8 -25
- package/.claude/commands/sparc/tutorial.md +12 -53
- package/.claude/commands/sparc/workflow-manager.md +8 -25
- package/.claude/commands/sparc.md +76 -130
- package/.claude/commands/stream-chain/pipeline.md +72 -77
- package/.claude/commands/stream-chain/run.md +133 -47
- package/.claude/commands/swarm/README.md +37 -12
- package/.claude/commands/swarm/analysis.md +47 -69
- package/.claude/commands/swarm/development.md +45 -69
- package/.claude/commands/swarm/examples.md +77 -142
- package/.claude/commands/swarm/maintenance.md +47 -74
- package/.claude/commands/swarm/optimization.md +54 -87
- package/.claude/commands/swarm/research.md +47 -107
- package/.claude/commands/swarm/swarm-analysis.md +58 -4
- package/.claude/commands/swarm/swarm-background.md +61 -4
- package/.claude/commands/swarm/swarm-modes.md +63 -4
- package/.claude/commands/swarm/swarm-monitor.md +50 -4
- package/.claude/commands/swarm/swarm-status.md +40 -4
- package/.claude/commands/swarm/swarm-strategies.md +73 -5
- package/.claude/commands/swarm/swarm.md +70 -18
- package/.claude/commands/swarm/testing.md +51 -102
- package/.claude/commands/tokens.md +6 -1
- package/.claude/commands/training/README.md +36 -6
- package/.claude/commands/training/model-update.md +68 -15
- package/.claude/commands/training/neural-patterns.md +54 -55
- package/.claude/commands/training/neural-train.md +70 -16
- package/.claude/commands/training/pattern-learn.md +60 -16
- package/.claude/commands/training/specialization.md +78 -49
- package/.claude/commands/truth/start.md +87 -109
- package/.claude/commands/ts.md +7 -2
- package/.claude/commands/verify/check.md +90 -34
- package/.claude/commands/verify/start.md +71 -94
- package/.claude/commands/workflows/README.md +62 -6
- package/.claude/commands/workflows/development.md +69 -61
- package/.claude/commands/workflows/research.md +73 -47
- package/.claude/commands/workflows/workflow-create.md +75 -16
- package/.claude/commands/workflows/workflow-execute.md +94 -16
- package/.claude/commands/workflows/workflow-export.md +81 -16
- package/.claude/helpers/control-start.cjs +91 -0
- package/.claude/helpers/extras-registry.json +4104 -1991
- package/.claude/helpers/graphify-freshen.cjs +44 -13
- package/.claude/helpers/hook-handler.cjs +256 -1
- package/.claude/helpers/learning-service.mjs +0 -0
- package/.claude/helpers/loop-tracker.cjs +107 -0
- package/.claude/helpers/metrics-db.mjs +0 -0
- package/.claude/helpers/router.cjs +48 -68
- package/.claude/helpers/skill-registry.json +89 -104
- package/.claude/helpers/statusline.cjs +33 -2
- package/.claude/helpers/swarm-hooks.sh +0 -0
- package/.claude/scheduled_tasks.lock +1 -0
- package/.claude/settings.json +15 -0
- package/.claude/skills/.monomind/data/ranked-context.json +5 -0
- package/.claude/skills/.monomind/sessions/current.json +13 -0
- package/.claude/skills/.monomind/sessions/session-1777829336455.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777831614725.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777832095857.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777839814183.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777841847131.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777843309463.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777880867159.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777881884593.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777884090471.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777884808221.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777885672155.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777886852818.json +15 -0
- package/.claude/skills/.monomind/sessions/session-1777896532690.json +15 -0
- package/.claude/skills/agentdb-advanced/SKILL.md +11 -12
- package/.claude/skills/agentdb-learning/SKILL.md +20 -21
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +28 -30
- package/.claude/skills/agentdb-optimization/SKILL.md +11 -12
- package/.claude/skills/agentdb-vector-search/SKILL.md +37 -41
- package/.claude/skills/{v3-integration-deep → agentic-integration}/SKILL.md +20 -13
- package/.claude/skills/agentic-jujutsu/SKILL.md +22 -22
- package/.claude/skills/{v3-cli-modernization → cli-modernization}/SKILL.md +17 -8
- package/.claude/skills/{v3-core-implementation → core-implementation}/SKILL.md +33 -8
- package/.claude/skills/{v3-ddd-architecture → ddd-architecture}/SKILL.md +18 -25
- package/.claude/skills/github-code-review/SKILL.md +82 -83
- package/.claude/skills/github-multi-repo/SKILL.md +42 -46
- package/.claude/skills/github-project-management/SKILL.md +83 -88
- package/.claude/skills/github-release-management/SKILL.md +12 -18
- package/.claude/skills/github-workflow-automation/SKILL.md +70 -74
- package/.claude/skills/hooks-automation/SKILL.md +9 -13
- package/.claude/skills/mastermind/_intake.md +83 -0
- package/.claude/skills/mastermind/_protocol.md +275 -0
- package/.claude/skills/mastermind/architect.md +847 -0
- package/.claude/skills/mastermind/build.md +158 -0
- package/.claude/skills/mastermind/content.md +185 -0
- package/.claude/skills/mastermind/createorg.md +318 -0
- package/.claude/skills/mastermind/finance.md +154 -0
- package/.claude/skills/mastermind/idea.md +158 -0
- package/.claude/skills/mastermind/marketing.md +216 -0
- package/.claude/skills/mastermind/monotask.md +350 -0
- package/.claude/skills/mastermind/ops.md +156 -0
- package/.claude/skills/mastermind/references/copywriting-frameworks.md +181 -0
- package/.claude/skills/mastermind/references/persuasion-psychology.md +158 -0
- package/.claude/skills/mastermind/release.md +156 -0
- package/.claude/skills/mastermind/research.md +156 -0
- package/.claude/skills/mastermind/review.md +157 -0
- package/.claude/skills/mastermind/runorg.md +308 -0
- package/.claude/skills/mastermind/sales.md +158 -0
- package/.claude/skills/mastermind/techport.md +743 -0
- package/.claude/skills/{v3-mcp-optimization → mcp-optimization}/SKILL.md +35 -14
- package/.claude/skills/{v3-memory-unification → memory-unification}/SKILL.md +20 -4
- package/.claude/skills/monodesign/SKILL.md +302 -0
- package/.claude/skills/monodesign/reference/adapt.md +190 -0
- package/.claude/skills/monodesign/reference/animate.md +175 -0
- package/.claude/skills/monodesign/reference/antipatterns-catalog.md +187 -0
- package/.claude/skills/monodesign/reference/audit.md +133 -0
- package/.claude/skills/monodesign/reference/bolder.md +113 -0
- package/.claude/skills/monodesign/reference/brand-workflow.md +180 -0
- package/.claude/skills/monodesign/reference/brand.md +114 -0
- package/.claude/skills/monodesign/reference/clarify.md +174 -0
- package/.claude/skills/monodesign/reference/cognitive-load.md +106 -0
- package/.claude/skills/monodesign/reference/color-and-contrast.md +105 -0
- package/.claude/skills/monodesign/reference/colorize.md +154 -0
- package/.claude/skills/monodesign/reference/component-specs.md +260 -0
- package/.claude/skills/monodesign/reference/component-states.md +274 -0
- package/.claude/skills/monodesign/reference/component-system.md +358 -0
- package/.claude/skills/monodesign/reference/copy-formulas.md +160 -0
- package/.claude/skills/monodesign/reference/craft.md +193 -0
- package/.claude/skills/monodesign/reference/critique.md +213 -0
- package/.claude/skills/monodesign/reference/delight.md +302 -0
- package/.claude/skills/monodesign/reference/design-principles.md +246 -0
- package/.claude/skills/monodesign/reference/distill.md +111 -0
- package/.claude/skills/monodesign/reference/document.md +427 -0
- package/.claude/skills/monodesign/reference/extract.md +69 -0
- package/.claude/skills/monodesign/reference/harden.md +347 -0
- package/.claude/skills/monodesign/reference/heuristics-scoring.md +234 -0
- package/.claude/skills/monodesign/reference/image-prompts.md +118 -0
- package/.claude/skills/monodesign/reference/interaction-design.md +195 -0
- package/.claude/skills/monodesign/reference/layout.md +141 -0
- package/.claude/skills/monodesign/reference/live.md +622 -0
- package/.claude/skills/monodesign/reference/motion-design.md +109 -0
- package/.claude/skills/monodesign/reference/onboard.md +234 -0
- package/.claude/skills/monodesign/reference/optimize.md +258 -0
- package/.claude/skills/monodesign/reference/overdrive.md +130 -0
- package/.claude/skills/monodesign/reference/personas.md +179 -0
- package/.claude/skills/monodesign/reference/polish.md +233 -0
- package/.claude/skills/monodesign/reference/pre-delivery-checklist.md +108 -0
- package/.claude/skills/monodesign/reference/product.md +62 -0
- package/.claude/skills/monodesign/reference/quieter.md +99 -0
- package/.claude/skills/monodesign/reference/responsive-design.md +114 -0
- package/.claude/skills/monodesign/reference/shape.md +151 -0
- package/.claude/skills/monodesign/reference/spatial-design.md +100 -0
- package/.claude/skills/monodesign/reference/teach.md +156 -0
- package/.claude/skills/monodesign/reference/token-architecture.md +222 -0
- package/.claude/skills/monodesign/reference/typeset.md +124 -0
- package/.claude/skills/monodesign/reference/typography.md +159 -0
- package/.claude/skills/monodesign/reference/ux-research.md +143 -0
- package/.claude/skills/monodesign/reference/ux-rules.md +211 -0
- package/.claude/skills/monodesign/reference/ux-writing.md +107 -0
- package/.claude/skills/monomotion/SKILL.md +145 -0
- package/.claude/skills/monomotion/rules/api-control.md +139 -0
- package/.claude/skills/monomotion/rules/effects.md +109 -0
- package/.claude/skills/monomotion/rules/integration.md +140 -0
- package/.claude/skills/monomotion/rules/scroll.md +131 -0
- package/.claude/skills/monomotion/rules/sequencing.md +105 -0
- package/.claude/skills/monomotion/rules/svg.md +101 -0
- package/.claude/skills/monomotion/rules/text.md +119 -0
- package/.claude/skills/pair-programming/SKILL.md +1 -1
- package/.claude/skills/performance-analysis/SKILL.md +3 -3
- package/.claude/skills/{v3-performance-optimization → performance-optimization}/SKILL.md +16 -8
- package/.claude/skills/reasoningbank-agentdb/SKILL.md +17 -19
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +4 -6
- package/.claude/skills/{v3-security-overhaul → security-hardening}/SKILL.md +13 -3
- package/.claude/skills/skill-builder/SKILL.md +19 -19
- package/.claude/skills/sparc-methodology/SKILL.md +55 -211
- package/.claude/skills/stop-slop/SKILL.md +67 -0
- package/.claude/skills/stop-slop/references/examples.md +61 -0
- package/.claude/skills/stop-slop/references/phrases.md +130 -0
- package/.claude/skills/stop-slop/references/structures.md +136 -0
- package/.claude/skills/swarm-advanced/SKILL.md +13 -43
- package/.claude/skills/{v3-swarm-coordination → swarm-coordination}/SKILL.md +39 -21
- package/.claude/skills/swarm-orchestration/SKILL.md +12 -12
- package/.claude/skills/verification-quality/SKILL.md +5 -5
- package/.claude/statusline-command.sh +0 -0
- package/.claude/statusline.sh +0 -0
- package/.claude-plugin/scripts/install.sh +0 -0
- package/.claude-plugin/scripts/uninstall.sh +0 -0
- package/.claude-plugin/scripts/verify.sh +0 -0
- package/README.md +5 -5
- package/package.json +17 -17
- package/packages/@monomind/cli/README.md +441 -0
- package/packages/@monomind/cli/bin/cli.js +78 -13
- package/packages/@monomind/cli/bin/mcp-server.js +0 -0
- package/packages/@monomind/cli/dist/src/agents/halt-signal.js +33 -7
- package/packages/@monomind/cli/dist/src/agents/managed-agent.js +5 -2
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +3 -2
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +1 -1
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +5 -2
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +26 -4
- package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +17 -9
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +5 -3
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +58 -10
- package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +0 -1
- package/packages/@monomind/cli/dist/src/agents/version-store.js +44 -21
- package/packages/@monomind/cli/dist/src/autopilot-state.js +79 -28
- package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +7 -2
- package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +20 -8
- package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.d.ts +2 -1
- package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +25 -2
- package/packages/@monomind/cli/dist/src/commands/agent.js +6 -4
- package/packages/@monomind/cli/dist/src/commands/appliance-advanced.js +23 -0
- package/packages/@monomind/cli/dist/src/commands/autopilot.js +3 -3
- package/packages/@monomind/cli/dist/src/commands/benchmark.js +119 -8
- package/packages/@monomind/cli/dist/src/commands/claims.js +22 -14
- package/packages/@monomind/cli/dist/src/commands/config.js +32 -0
- package/packages/@monomind/cli/dist/src/commands/daemon.js +13 -11
- package/packages/@monomind/cli/dist/src/commands/deployment.js +21 -2
- package/packages/@monomind/cli/dist/src/commands/doctor.js +5 -4
- package/packages/@monomind/cli/dist/src/commands/embeddings.js +124 -48
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +15 -14
- package/packages/@monomind/cli/dist/src/commands/hooks.js +45 -41
- package/packages/@monomind/cli/dist/src/commands/index.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/commands/index.js +20 -7
- package/packages/@monomind/cli/dist/src/commands/init.js +53 -19
- package/packages/@monomind/cli/dist/src/commands/mcp.js +31 -44
- package/packages/@monomind/cli/dist/src/commands/memory.js +47 -15
- package/packages/@monomind/cli/dist/src/commands/migrate.js +156 -108
- package/packages/@monomind/cli/dist/src/commands/monograph.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/monograph.js +526 -0
- package/packages/@monomind/cli/dist/src/commands/neural.js +96 -56
- package/packages/@monomind/cli/dist/src/commands/performance.js +30 -8
- package/packages/@monomind/cli/dist/src/commands/plugins.js +13 -37
- package/packages/@monomind/cli/dist/src/commands/process.js +25 -2
- package/packages/@monomind/cli/dist/src/commands/providers.js +37 -5
- package/packages/@monomind/cli/dist/src/commands/replay.js +4 -4
- package/packages/@monomind/cli/dist/src/commands/route.js +37 -5
- package/packages/@monomind/cli/dist/src/commands/ruvector/import.js +12 -2
- package/packages/@monomind/cli/dist/src/commands/ruvector/init.js +15 -0
- package/packages/@monomind/cli/dist/src/commands/ruvector/status.js +16 -3
- package/packages/@monomind/cli/dist/src/commands/security.js +342 -193
- package/packages/@monomind/cli/dist/src/commands/session.js +51 -8
- package/packages/@monomind/cli/dist/src/commands/start.js +18 -4
- package/packages/@monomind/cli/dist/src/commands/swarm.js +47 -36
- package/packages/@monomind/cli/dist/src/commands/tokens.js +11 -11
- package/packages/@monomind/cli/dist/src/commands/transfer-store.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/workflow.js +31 -4
- package/packages/@monomind/cli/dist/src/config-adapter.d.ts +2 -1
- package/packages/@monomind/cli/dist/src/consensus/audit-writer.js +46 -13
- package/packages/@monomind/cli/dist/src/consensus/vote-signer.d.ts +0 -3
- package/packages/@monomind/cli/dist/src/consensus/vote-signer.js +9 -1
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +4 -2
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +25 -8
- package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.d.ts +10 -3
- package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.js +50 -16
- package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +27 -5
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +26 -16
- package/packages/@monomind/cli/dist/src/eval/trace-collector.js +23 -3
- package/packages/@monomind/cli/dist/src/index.js +12 -10
- package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +8 -8
- package/packages/@monomind/cli/dist/src/init/executor.js +153 -70
- package/packages/@monomind/cli/dist/src/init/helpers-generator.js +35 -22
- package/packages/@monomind/cli/dist/src/init/mcp-generator.js +3 -3
- package/packages/@monomind/cli/dist/src/init/settings-generator.js +10 -3
- package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +18 -3
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -1
- package/packages/@monomind/cli/dist/src/init/types.d.ts +35 -11
- package/packages/@monomind/cli/dist/src/init/types.js +5 -9
- package/packages/@monomind/cli/dist/src/interactive/interrupt.js +8 -3
- package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +38 -4
- package/packages/@monomind/cli/dist/src/mcp-client.js +10 -4
- package/packages/@monomind/cli/dist/src/mcp-server.d.ts +9 -2
- package/packages/@monomind/cli/dist/src/mcp-server.js +182 -35
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +66 -34
- package/packages/@monomind/cli/dist/src/mcp-tools/agentdb-tools.js +34 -7
- package/packages/@monomind/cli/dist/src/mcp-tools/analyze-tools.js +25 -16
- package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.js +4 -6
- package/packages/@monomind/cli/dist/src/mcp-tools/autopilot-tools.js +12 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +199 -20
- package/packages/@monomind/cli/dist/src/mcp-tools/claims-tools.js +68 -18
- package/packages/@monomind/cli/dist/src/mcp-tools/config-tools.js +33 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.js +59 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.js +46 -10
- package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +46 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +29 -16
- package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +38 -10
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +96 -33
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +70 -37
- package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +29 -13
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +5867 -56
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +121 -37
- package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +21 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +10 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/request-tracker.js +4 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.js +19 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/session-tools.js +57 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +35 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +4 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/task-tools.js +53 -13
- package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.js +63 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/transfer-tools.js +21 -16
- package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +92 -23
- package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +41 -10
- package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +39 -13
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +149 -56
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +107 -45
- package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +8 -1
- package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +25 -8
- package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +40 -0
- package/packages/@monomind/cli/dist/src/observability/replay-reader.js +138 -0
- package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +35 -5
- package/packages/@monomind/cli/dist/src/parser.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/parser.js +48 -14
- package/packages/@monomind/cli/dist/src/plugins/manager.js +112 -19
- package/packages/@monomind/cli/dist/src/plugins/store/discovery.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +80 -62
- package/packages/@monomind/cli/dist/src/production/circuit-breaker.js +8 -1
- package/packages/@monomind/cli/dist/src/production/error-handler.d.ts +4 -2
- package/packages/@monomind/cli/dist/src/production/error-handler.js +27 -5
- package/packages/@monomind/cli/dist/src/production/monitoring.js +8 -4
- package/packages/@monomind/cli/dist/src/production/rate-limiter.js +30 -22
- package/packages/@monomind/cli/dist/src/ruvector/agent-wasm.js +2 -2
- package/packages/@monomind/cli/dist/src/ruvector/coverage-router.js +19 -9
- package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.js +26 -6
- package/packages/@monomind/cli/dist/src/ruvector/enhanced-model-router.js +24 -2
- package/packages/@monomind/cli/dist/src/ruvector/index.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/ruvector/index.js +2 -2
- package/packages/@monomind/cli/dist/src/ruvector/model-router.d.ts +4 -2
- package/packages/@monomind/cli/dist/src/ruvector/model-router.js +30 -6
- package/packages/@monomind/cli/dist/src/ruvector/moe-router.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/ruvector/moe-router.js +35 -12
- package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.d.ts +7 -1
- package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.js +40 -9
- package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +3 -1
- package/packages/@monomind/cli/dist/src/services/claim-service.js +33 -2
- package/packages/@monomind/cli/dist/src/services/config-file-manager.d.ts +16 -2
- package/packages/@monomind/cli/dist/src/services/config-file-manager.js +105 -17
- package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +51 -11
- package/packages/@monomind/cli/dist/src/services/headless-worker-executor.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/services/headless-worker-executor.js +188 -45
- package/packages/@monomind/cli/dist/src/services/registry-api.js +62 -9
- package/packages/@monomind/cli/dist/src/services/ruvector-training.js +8 -0
- package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +4 -1
- package/packages/@monomind/cli/dist/src/services/worker-daemon.js +112 -28
- package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +9 -2
- package/packages/@monomind/cli/dist/src/services/worker-queue.js +86 -5
- package/packages/@monomind/cli/dist/src/suggest.js +9 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +5 -3
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +17 -5
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +30 -6
- package/packages/@monomind/cli/dist/src/transfer/anonymization/index.js +5 -3
- package/packages/@monomind/cli/dist/src/transfer/export.js +5 -3
- package/packages/@monomind/cli/dist/src/transfer/ipfs/client.js +84 -7
- package/packages/@monomind/cli/dist/src/transfer/ipfs/upload.js +13 -4
- package/packages/@monomind/cli/dist/src/transfer/storage/gcs.js +19 -10
- package/packages/@monomind/cli/dist/src/transfer/store/discovery.d.ts +9 -2
- package/packages/@monomind/cli/dist/src/transfer/store/discovery.js +68 -13
- package/packages/@monomind/cli/dist/src/transfer/store/download.d.ts +15 -6
- package/packages/@monomind/cli/dist/src/transfer/store/download.js +113 -24
- package/packages/@monomind/cli/dist/src/transfer/store/publish.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/transfer/store/publish.js +13 -14
- package/packages/@monomind/cli/dist/src/transfer/store/registry.d.ts +3 -3
- package/packages/@monomind/cli/dist/src/transfer/store/registry.js +32 -16
- package/packages/@monomind/cli/dist/src/update/checker.js +17 -4
- package/packages/@monomind/cli/dist/src/update/executor.js +25 -20
- package/packages/@monomind/cli/dist/src/update/rate-limiter.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/update/rate-limiter.js +23 -3
- package/packages/@monomind/cli/dist/src/utils/parse-jsonl.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/utils/parse-jsonl.js +22 -0
- package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +37 -3
- package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +27 -11
- package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +51 -13
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +6 -2
- package/packages/@monomind/cli/dist/src/workflow/template-engine.js +7 -0
- package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +95 -14
- package/packages/@monomind/cli/package.json +5 -3
- package/packages/@monomind/guidance/README.md +1192 -0
- package/packages/@monomind/shared/README.md +322 -0
- package/packages/@monomind/shared/dist/types/consensus-audit.d.ts +3 -1
- package/packages/README.md +513 -0
- package/.claude/agents/design/design-brand-guardian.md +0 -323
- package/.claude/agents/design/design-image-prompt-engineer.md +0 -237
- package/.claude/agents/design/design-inclusive-visuals-specialist.md +0 -72
- package/.claude/agents/design/design-ui-designer.md +0 -384
- package/.claude/agents/design/design-ux-architect.md +0 -470
- package/.claude/agents/design/design-ux-researcher.md +0 -330
- package/.claude/agents/design/design-visual-storyteller.md +0 -150
- package/.claude/agents/design/design-whimsy-injector.md +0 -439
- package/.claude/agents/v3/integration-architect.md +0 -338
- package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +0 -54
- package/.claude/commands/coordination/init.md +0 -44
- package/.claude/commands/coordination/orchestrate.md +0 -43
- package/.claude/commands/coordination/spawn.md +0 -45
- package/.claude/commands/github/code-review-swarm.md +0 -550
- package/.claude/commands/github/code-review.md +0 -25
- package/.claude/commands/github/github-swarm.md +0 -121
- package/.claude/commands/github/issue-triage.md +0 -25
- package/.claude/commands/github/multi-repo-swarm.md +0 -519
- package/.claude/commands/github/pr-enhance.md +0 -26
- package/.claude/commands/github/project-board-sync.md +0 -471
- package/.claude/commands/github/release-swarm.md +0 -590
- package/.claude/commands/github/repo-analyze.md +0 -25
- package/.claude/commands/github/swarm-issue.md +0 -482
- package/.claude/commands/github/swarm-pr.md +0 -310
- package/.claude/commands/github/workflow-automation.md +0 -468
- package/.claude/commands/hive-mind/hive-mind-metrics.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-resume.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-sessions.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-wizard.md +0 -8
- package/.claude/commands/list-agents.md +0 -17
- package/.claude/commands/memory/memory-persist.md +0 -25
- package/.claude/commands/memory/memory-usage.md +0 -25
- package/.claude/commands/memory/neural.md +0 -47
- package/.claude/commands/metrics.md +0 -11
- package/.claude/commands/monitoring/real-time-view.md +0 -25
- package/.claude/commands/monitoring/swarm-monitor.md +0 -25
- package/.claude/commands/monomind-createtask.md +0 -302
- package/.claude/commands/monomind-help.md +0 -103
- package/.claude/commands/monomind-memory.md +0 -107
- package/.claude/commands/monomind-repeat.md +0 -149
- package/.claude/commands/monomind-swarm.md +0 -205
- package/.claude/commands/optimization/cache-manage.md +0 -25
- package/.claude/commands/optimization/topology-optimize.md +0 -25
- package/.claude/commands/pair/commands.md +0 -546
- package/.claude/commands/pair/config.md +0 -510
- package/.claude/commands/pair/start.md +0 -209
- package/.claude/commands/use-agent.md +0 -67
- package/.claude/skills/monomind-createtask/SKILL.md +0 -269
- package/.claude/skills/monomind-task-engine/SKILL.md +0 -358
- /package/.claude/agents/{v3 → specialists}/memory-specialist.md +0 -0
- /package/.claude/agents/{v3 → specialists}/performance-engineer.md +0 -0
- /package/.claude/agents/{v3 → specialists}/queen-coordinator.md +0 -0
- /package/.claude/agents/{v3 → specialists}/security-architect.md +0 -0
|
@@ -13,13 +13,38 @@
|
|
|
13
13
|
* - Health check: <10ms
|
|
14
14
|
* - Graceful shutdown: <5s
|
|
15
15
|
*
|
|
16
|
-
* @module @
|
|
16
|
+
* @module @monomind/cli/mcp-server
|
|
17
17
|
* @version 3.0.0
|
|
18
18
|
*/
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
|
+
import { execSync } from 'child_process';
|
|
21
|
+
import * as http from 'http';
|
|
20
22
|
import { randomUUID } from 'crypto';
|
|
21
23
|
import * as path from 'path';
|
|
22
24
|
import * as fs from 'fs';
|
|
25
|
+
/**
|
|
26
|
+
* Recursively strip prototype-pollution keys from a JSON-RPC message before
|
|
27
|
+
* downstream tool handlers consume it. Tool handlers commonly do shallow
|
|
28
|
+
* merges like `{ ...defaults, ...input }`, which would propagate
|
|
29
|
+
* `__proto__`/`constructor`/`prototype` payloads onto config objects.
|
|
30
|
+
*/
|
|
31
|
+
const FORBIDDEN_PROTO_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
32
|
+
function sanitizeJsonRpcMessage(value, depth = 0) {
|
|
33
|
+
if (depth > 16)
|
|
34
|
+
return null;
|
|
35
|
+
if (Array.isArray(value))
|
|
36
|
+
return value.map(v => sanitizeJsonRpcMessage(v, depth + 1));
|
|
37
|
+
if (value !== null && typeof value === 'object') {
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const [k, v] of Object.entries(value)) {
|
|
40
|
+
if (FORBIDDEN_PROTO_KEYS.has(k))
|
|
41
|
+
continue;
|
|
42
|
+
out[k] = sanitizeJsonRpcMessage(v, depth + 1);
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
23
48
|
import * as os from 'os';
|
|
24
49
|
import { fileURLToPath } from 'url';
|
|
25
50
|
import { dirname } from 'path';
|
|
@@ -30,12 +55,22 @@ const __dirname = dirname(__filename);
|
|
|
30
55
|
/**
|
|
31
56
|
* Default configuration
|
|
32
57
|
*/
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a per-user state directory under $HOME/.monomind. /tmp is shared and
|
|
60
|
+
* world-traversable; placing the PID/log files there made them symlink-
|
|
61
|
+
* attackable (a local attacker pre-creates /tmp/monomind-mcp.pid as a symlink
|
|
62
|
+
* to e.g. ~/.ssh/authorized_keys, then a writeFile clobbers the target).
|
|
63
|
+
*/
|
|
64
|
+
function getDefaultStateDir() {
|
|
65
|
+
const home = os.homedir();
|
|
66
|
+
return path.join(home, '.monomind');
|
|
67
|
+
}
|
|
33
68
|
const DEFAULT_OPTIONS = {
|
|
34
69
|
transport: 'stdio',
|
|
35
70
|
host: 'localhost',
|
|
36
71
|
port: 3000,
|
|
37
|
-
pidFile: path.join(
|
|
38
|
-
logFile: path.join(
|
|
72
|
+
pidFile: path.join(getDefaultStateDir(), 'mcp.pid'),
|
|
73
|
+
logFile: path.join(getDefaultStateDir(), 'mcp.log'),
|
|
39
74
|
tools: 'all',
|
|
40
75
|
daemonize: false,
|
|
41
76
|
timeout: 30000,
|
|
@@ -50,6 +85,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
50
85
|
process;
|
|
51
86
|
server;
|
|
52
87
|
startTime;
|
|
88
|
+
_stdioServerStarted = false;
|
|
53
89
|
healthCheckInterval;
|
|
54
90
|
constructor(options = {}) {
|
|
55
91
|
super();
|
|
@@ -128,6 +164,13 @@ export class MCPServerManager extends EventEmitter {
|
|
|
128
164
|
});
|
|
129
165
|
this.server = undefined;
|
|
130
166
|
}
|
|
167
|
+
if (this._mcpServer) {
|
|
168
|
+
try {
|
|
169
|
+
await this._mcpServer.close();
|
|
170
|
+
}
|
|
171
|
+
catch { /* ignore */ }
|
|
172
|
+
this._mcpServer = undefined;
|
|
173
|
+
}
|
|
131
174
|
// Remove PID file
|
|
132
175
|
await this.removePidFile();
|
|
133
176
|
this.startTime = undefined;
|
|
@@ -149,7 +192,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
149
192
|
// (e.g., launched by Claude Code via `claude mcp add`).
|
|
150
193
|
const isStdio = !process.stdin.isTTY;
|
|
151
194
|
const envTransport = process.env.MONOMIND_MCP_TRANSPORT;
|
|
152
|
-
if (isStdio || envTransport === 'stdio' || this.
|
|
195
|
+
if (isStdio || envTransport === 'stdio' || this._stdioServerStarted) {
|
|
153
196
|
return {
|
|
154
197
|
running: true,
|
|
155
198
|
pid: process.pid,
|
|
@@ -233,6 +276,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
233
276
|
* Handles stdin/stdout directly like V2 implementation
|
|
234
277
|
*/
|
|
235
278
|
async startStdioServer() {
|
|
279
|
+
this._stdioServerStarted = true;
|
|
236
280
|
// Import the tool registry
|
|
237
281
|
const { listMCPTools, callMCPTool, hasTool } = await import('./mcp-client.js');
|
|
238
282
|
const VERSION = '3.0.0';
|
|
@@ -309,31 +353,52 @@ export class MCPServerManager extends EventEmitter {
|
|
|
309
353
|
for (const line of lines) {
|
|
310
354
|
if (line.trim()) {
|
|
311
355
|
try {
|
|
312
|
-
|
|
356
|
+
// Sanitize against prototype pollution. JSON.parse on its own does
|
|
357
|
+
// not pollute, but downstream tool handlers that shallow-merge
|
|
358
|
+
// input into option defaults would propagate `__proto__`,
|
|
359
|
+
// `constructor`, or `prototype` keys. Strip them at the boundary.
|
|
360
|
+
const message = sanitizeJsonRpcMessage(JSON.parse(line));
|
|
313
361
|
const response = await this.handleMCPMessage(message, sessionId);
|
|
314
362
|
if (response) {
|
|
315
363
|
console.log(JSON.stringify(response));
|
|
316
364
|
}
|
|
317
365
|
}
|
|
318
366
|
catch (error) {
|
|
319
|
-
|
|
367
|
+
// Log-injection defense: stringify message fragment instead of
|
|
368
|
+
// letting raw line content land in the log unescaped.
|
|
369
|
+
const safeMsg = (error instanceof Error ? error.message : String(error))
|
|
370
|
+
.replace(/[\r\n\x00-\x1f\x7f]/g, '?').slice(0, 500);
|
|
371
|
+
console.error(`[${new Date().toISOString()}] ERROR [monomind-mcp] Failed to parse message: ${safeMsg}`);
|
|
320
372
|
}
|
|
321
373
|
}
|
|
322
374
|
}
|
|
323
375
|
});
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
376
|
+
// Centralized graceful shutdown — clears the health-check interval and
|
|
377
|
+
// removes the PID file before exiting. Without this an abrupt
|
|
378
|
+
// `process.exit(0)` leaves a stale PID file plus a dangling interval and
|
|
379
|
+
// unflushed in-flight tool calls.
|
|
380
|
+
let shuttingDown = false;
|
|
381
|
+
const shutdown = async (reason) => {
|
|
382
|
+
if (shuttingDown)
|
|
383
|
+
return;
|
|
384
|
+
shuttingDown = true;
|
|
385
|
+
console.error(`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) ${reason}, shutting down...`);
|
|
386
|
+
try {
|
|
387
|
+
if (this.healthCheckInterval) {
|
|
388
|
+
clearInterval(this.healthCheckInterval);
|
|
389
|
+
this.healthCheckInterval = undefined;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch { /* best-effort */ }
|
|
393
|
+
try {
|
|
394
|
+
await this.removePidFile();
|
|
395
|
+
}
|
|
396
|
+
catch { /* best-effort */ }
|
|
335
397
|
process.exit(0);
|
|
336
|
-
}
|
|
398
|
+
};
|
|
399
|
+
process.stdin.on('end', () => { void shutdown('stdin closed'); });
|
|
400
|
+
process.on('SIGINT', () => { void shutdown('Received SIGINT'); });
|
|
401
|
+
process.on('SIGTERM', () => { void shutdown('Received SIGTERM'); });
|
|
337
402
|
// Mark as ready immediately for stdio
|
|
338
403
|
this.emit('ready');
|
|
339
404
|
}
|
|
@@ -378,9 +443,27 @@ export class MCPServerManager extends EventEmitter {
|
|
|
378
443
|
})),
|
|
379
444
|
},
|
|
380
445
|
};
|
|
381
|
-
case 'tools/call':
|
|
446
|
+
case 'tools/call': {
|
|
447
|
+
// Strict boundary validation. Without this, `params.name` could be
|
|
448
|
+
// an array/object (silently coerced) and `params.arguments` could be
|
|
449
|
+
// an array (downstream `Object.keys` returns numeric indices).
|
|
450
|
+
if (typeof params.name !== 'string') {
|
|
451
|
+
return {
|
|
452
|
+
jsonrpc: '2.0',
|
|
453
|
+
id: message.id,
|
|
454
|
+
error: { code: -32602, message: 'Invalid params.name: must be a string' },
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
const rawArgs = params.arguments;
|
|
458
|
+
if (rawArgs !== undefined && (typeof rawArgs !== 'object' || rawArgs === null || Array.isArray(rawArgs))) {
|
|
459
|
+
return {
|
|
460
|
+
jsonrpc: '2.0',
|
|
461
|
+
id: message.id,
|
|
462
|
+
error: { code: -32602, message: 'Invalid params.arguments: must be an object' },
|
|
463
|
+
};
|
|
464
|
+
}
|
|
382
465
|
const toolName = params.name;
|
|
383
|
-
const toolParams = (
|
|
466
|
+
const toolParams = (rawArgs || {});
|
|
384
467
|
if (!hasTool(toolName)) {
|
|
385
468
|
return {
|
|
386
469
|
jsonrpc: '2.0',
|
|
@@ -399,15 +482,19 @@ export class MCPServerManager extends EventEmitter {
|
|
|
399
482
|
}
|
|
400
483
|
catch (error) {
|
|
401
484
|
trackRequest(toolName, false);
|
|
485
|
+
const errMsg = process.env.NODE_ENV === 'production'
|
|
486
|
+
? 'Tool execution failed'
|
|
487
|
+
: (error instanceof Error ? error.message : 'Tool execution failed');
|
|
402
488
|
return {
|
|
403
489
|
jsonrpc: '2.0',
|
|
404
490
|
id: message.id,
|
|
405
491
|
error: {
|
|
406
492
|
code: -32603,
|
|
407
|
-
message:
|
|
493
|
+
message: errMsg,
|
|
408
494
|
},
|
|
409
495
|
};
|
|
410
496
|
}
|
|
497
|
+
}
|
|
411
498
|
case 'notifications/initialized':
|
|
412
499
|
// Client notification - no response needed
|
|
413
500
|
console.error(`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Client initialized`);
|
|
@@ -427,30 +514,66 @@ export class MCPServerManager extends EventEmitter {
|
|
|
427
514
|
}
|
|
428
515
|
}
|
|
429
516
|
catch (error) {
|
|
430
|
-
|
|
517
|
+
// Log-injection defense: caller-controlled `message.method` may contain
|
|
518
|
+
// newlines, ANSI escapes, or other control bytes that forge log lines.
|
|
519
|
+
// JSON.stringify quotes the string and escapes control chars.
|
|
520
|
+
const safeMethod = JSON.stringify(message.method);
|
|
521
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
522
|
+
console.error(`[${new Date().toISOString()}] ERROR [monomind-mcp] Error handling ${safeMethod}: ${errMsg.replace(/[\r\n]/g, ' ')}`);
|
|
523
|
+
// Sanitize outgoing error messages — internal Error.message often
|
|
524
|
+
// contains absolute paths or partial secrets. In production return a
|
|
525
|
+
// generic message; in dev/debug return the full message for triage.
|
|
526
|
+
const isProd = process.env.NODE_ENV === 'production';
|
|
527
|
+
const outMessage = error instanceof Error
|
|
528
|
+
? (isProd ? 'Internal error' : error.message)
|
|
529
|
+
: 'Internal error';
|
|
431
530
|
return {
|
|
432
531
|
jsonrpc: '2.0',
|
|
433
532
|
id: message.id,
|
|
434
|
-
error: {
|
|
435
|
-
code: -32603,
|
|
436
|
-
message: error instanceof Error ? error.message : 'Internal error',
|
|
437
|
-
},
|
|
533
|
+
error: { code: -32603, message: outMessage },
|
|
438
534
|
};
|
|
439
535
|
}
|
|
440
536
|
}
|
|
441
537
|
/**
|
|
442
|
-
* Start HTTP server in-process
|
|
538
|
+
* Start HTTP server in-process.
|
|
539
|
+
*
|
|
540
|
+
* SECURITY: refuses to bind to non-loopback hosts unless the operator opts
|
|
541
|
+
* in via MONOMIND_MCP_ALLOW_REMOTE=1 AND provides a bearer token via
|
|
542
|
+
* MONOMIND_MCP_TOKEN. Without this gate, `--host 0.0.0.0` exposed every
|
|
543
|
+
* registered tool (including agent_spawn, terminal-tools, system tools) to
|
|
544
|
+
* any LAN attacker as unauthenticated RCE.
|
|
443
545
|
*/
|
|
444
546
|
async startHttpServer() {
|
|
547
|
+
// Loopback gate
|
|
548
|
+
const host = this.options.host;
|
|
549
|
+
const isLoopback = host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '::ffff:127.0.0.1';
|
|
550
|
+
const allowRemote = process.env.MONOMIND_MCP_ALLOW_REMOTE === '1';
|
|
551
|
+
const token = process.env.MONOMIND_MCP_TOKEN;
|
|
552
|
+
if (!isLoopback && !allowRemote) {
|
|
553
|
+
throw new Error(`Refusing to bind MCP HTTP transport to non-loopback host "${host}". ` +
|
|
554
|
+
`Set MONOMIND_MCP_ALLOW_REMOTE=1 and MONOMIND_MCP_TOKEN=<secret> to enable remote access.`);
|
|
555
|
+
}
|
|
556
|
+
if (!isLoopback && allowRemote && (!token || token.length < 32)) {
|
|
557
|
+
throw new Error('Remote MCP transport requires MONOMIND_MCP_TOKEN to be set to a strong secret (>= 32 chars).');
|
|
558
|
+
}
|
|
445
559
|
// Dynamically import the MCP server package
|
|
446
560
|
// FIX for issue #942: Use proper package import instead of broken relative path
|
|
447
|
-
const { createMCPServer } = await import('@
|
|
561
|
+
const { createMCPServer } = await import('@monomind/mcp');
|
|
448
562
|
const logger = {
|
|
449
563
|
debug: (msg, data) => this.emit('log', { level: 'debug', msg, data }),
|
|
450
564
|
info: (msg, data) => this.emit('log', { level: 'info', msg, data }),
|
|
451
565
|
warn: (msg, data) => this.emit('log', { level: 'warn', msg, data }),
|
|
452
566
|
error: (msg, data) => this.emit('log', { level: 'error', msg, data }),
|
|
453
567
|
};
|
|
568
|
+
// SECURITY: actually wire the token into the underlying server's auth
|
|
569
|
+
// config. The startup gate above only *validates* that a token was set —
|
|
570
|
+
// without passing it through here, the token was never enforced on
|
|
571
|
+
// requests. Operators believed their server was protected when it wasn't.
|
|
572
|
+
// For loopback we still configure auth when a token is set, so users who
|
|
573
|
+
// explicitly opt-in to bind 0.0.0.0 with a token get end-to-end protection.
|
|
574
|
+
const authConfig = token && token.length >= 32
|
|
575
|
+
? { enabled: true, method: 'token', tokens: [token] }
|
|
576
|
+
: (isLoopback ? undefined : { enabled: true, method: 'token', tokens: [] });
|
|
454
577
|
const mcpServer = createMCPServer({
|
|
455
578
|
name: 'Monomind MCP Server V1',
|
|
456
579
|
version: '3.0.0',
|
|
@@ -459,6 +582,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
459
582
|
port: this.options.port,
|
|
460
583
|
enableMetrics: true,
|
|
461
584
|
enableCaching: true,
|
|
585
|
+
...(authConfig ? { auth: authConfig } : {}),
|
|
462
586
|
}, logger);
|
|
463
587
|
await mcpServer.start();
|
|
464
588
|
// Store reference for stopping
|
|
@@ -521,7 +645,29 @@ export class MCPServerManager extends EventEmitter {
|
|
|
521
645
|
*/
|
|
522
646
|
async writePidFile() {
|
|
523
647
|
const pid = this.process?.pid || process.pid;
|
|
524
|
-
|
|
648
|
+
// Ensure the state dir exists (user-private, not /tmp)
|
|
649
|
+
const dir = path.dirname(this.options.pidFile);
|
|
650
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
651
|
+
// wx flag = O_CREAT | O_EXCL: fails fast on a pre-existing path including
|
|
652
|
+
// a symlinked one, so we never follow an attacker-staged link to write
|
|
653
|
+
// PIDs into ~/.ssh/authorized_keys or similar.
|
|
654
|
+
try {
|
|
655
|
+
await fs.promises.writeFile(this.options.pidFile, String(pid), { flag: 'wx', mode: 0o600 });
|
|
656
|
+
}
|
|
657
|
+
catch (e) {
|
|
658
|
+
const code = e.code;
|
|
659
|
+
if (code === 'EEXIST') {
|
|
660
|
+
// Stale PID file (the existence-check + isProcessRunning gate above
|
|
661
|
+
// already passed, so the file belongs to a dead daemon). Replace it
|
|
662
|
+
// by unlinking-then-creating with O_EXCL again — never write through
|
|
663
|
+
// an existing path that might be a symlink.
|
|
664
|
+
await fs.promises.unlink(this.options.pidFile);
|
|
665
|
+
await fs.promises.writeFile(this.options.pidFile, String(pid), { flag: 'wx', mode: 0o600 });
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
throw e;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
525
671
|
}
|
|
526
672
|
/**
|
|
527
673
|
* Read PID file
|
|
@@ -569,15 +715,17 @@ export class MCPServerManager extends EventEmitter {
|
|
|
569
715
|
catch {
|
|
570
716
|
return false;
|
|
571
717
|
}
|
|
572
|
-
// Verify it's actually
|
|
718
|
+
// Verify it's actually our MCP server process (guards against PID reuse by
|
|
719
|
+
// an unrelated Node.js program that happened to get the same PID).
|
|
720
|
+
// We require the command line to mention both "node"/"npx" AND "monomind"/"mcp".
|
|
573
721
|
try {
|
|
574
|
-
const
|
|
575
|
-
const cmdline = execSync(`cat /proc/${pid}/cmdline 2>/dev/null || ps -p ${pid} -o comm= 2>/dev/null`, {
|
|
722
|
+
const cmdline = execSync(`cat /proc/${pid}/cmdline 2>/dev/null || ps -p ${pid} -o args= 2>/dev/null`, {
|
|
576
723
|
encoding: 'utf8',
|
|
577
724
|
timeout: 1000,
|
|
578
725
|
}).trim();
|
|
579
|
-
|
|
580
|
-
|
|
726
|
+
const isMonomindMcp = (cmdline.includes('node') || cmdline.includes('npx')) &&
|
|
727
|
+
(cmdline.includes('monomind') || cmdline.includes('mcp'));
|
|
728
|
+
return isMonomindMcp;
|
|
581
729
|
}
|
|
582
730
|
catch {
|
|
583
731
|
// If we can't inspect the process (macOS, Windows, permissions), fall back to kill check
|
|
@@ -590,7 +738,6 @@ export class MCPServerManager extends EventEmitter {
|
|
|
590
738
|
async httpRequest(url, method, timeout) {
|
|
591
739
|
return new Promise((resolve, reject) => {
|
|
592
740
|
const urlObj = new URL(url);
|
|
593
|
-
const http = require('http');
|
|
594
741
|
const req = http.request({
|
|
595
742
|
hostname: urlObj.hostname,
|
|
596
743
|
port: urlObj.port,
|
|
@@ -4,17 +4,10 @@
|
|
|
4
4
|
* Tool definitions for agent lifecycle management with file persistence.
|
|
5
5
|
* Includes model routing integration for intelligent model selection.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync,
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync, statSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
|
+
import { randomBytes } from 'node:crypto';
|
|
9
10
|
import { getProjectCwd } from './types.js';
|
|
10
|
-
function logEvent(kind, data) {
|
|
11
|
-
try {
|
|
12
|
-
const dir = join(getProjectCwd(), '.monomind', 'swarm');
|
|
13
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
14
|
-
const event = { ts: new Date().toISOString(), source: 'mcp', kind, ...data };
|
|
15
|
-
appendFileSync(join(dir, 'events.jsonl'), JSON.stringify(event) + '\n');
|
|
16
|
-
} catch { }
|
|
17
|
-
}
|
|
18
11
|
// Storage paths
|
|
19
12
|
const STORAGE_DIR = '.monomind';
|
|
20
13
|
const AGENT_DIR = 'agents';
|
|
@@ -31,12 +24,18 @@ function ensureAgentDir() {
|
|
|
31
24
|
mkdirSync(dir, { recursive: true });
|
|
32
25
|
}
|
|
33
26
|
}
|
|
27
|
+
const MAX_AGENT_STORE_BYTES = 50 * 1024 * 1024;
|
|
34
28
|
function loadAgentStore() {
|
|
35
29
|
try {
|
|
36
30
|
const path = getAgentPath();
|
|
37
31
|
if (existsSync(path)) {
|
|
32
|
+
if (statSync(path).size > MAX_AGENT_STORE_BYTES)
|
|
33
|
+
return { agents: {}, version: '3.0.0' };
|
|
38
34
|
const data = readFileSync(path, 'utf-8');
|
|
39
|
-
|
|
35
|
+
const parsed = JSON.parse(data);
|
|
36
|
+
if (parsed && typeof parsed === 'object' && Object.prototype.hasOwnProperty.call(parsed, '__proto__'))
|
|
37
|
+
return { agents: {}, version: '3.0.0' };
|
|
38
|
+
return parsed;
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
catch {
|
|
@@ -45,8 +44,21 @@ function loadAgentStore() {
|
|
|
45
44
|
return { agents: {}, version: '3.0.0' };
|
|
46
45
|
}
|
|
47
46
|
function saveAgentStore(store) {
|
|
47
|
+
// Cap terminated agents to prevent unbounded growth
|
|
48
|
+
const MAX_TERMINATED = 500;
|
|
49
|
+
const terminated = Object.entries(store.agents)
|
|
50
|
+
.filter(([, a]) => a.status === 'terminated')
|
|
51
|
+
.sort(([, a], [, b]) => (a.createdAt ?? '').localeCompare(b.createdAt ?? ''));
|
|
52
|
+
if (terminated.length > MAX_TERMINATED) {
|
|
53
|
+
for (const [id] of terminated.slice(0, terminated.length - MAX_TERMINATED)) {
|
|
54
|
+
delete store.agents[id];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
48
57
|
ensureAgentDir();
|
|
49
|
-
|
|
58
|
+
const dest = getAgentPath();
|
|
59
|
+
const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
|
|
60
|
+
writeFileSync(tmp, JSON.stringify(store, null, 2), 'utf-8');
|
|
61
|
+
renameSync(tmp, dest);
|
|
50
62
|
}
|
|
51
63
|
// Default model mappings for agent types (can be overridden)
|
|
52
64
|
const AGENT_TYPE_MODEL_DEFAULTS = {
|
|
@@ -111,7 +123,7 @@ async function determineAgentModel(agentType, config, task) {
|
|
|
111
123
|
};
|
|
112
124
|
}
|
|
113
125
|
return {
|
|
114
|
-
model: routeResult.model,
|
|
126
|
+
model: (routeResult.model ?? 'sonnet'),
|
|
115
127
|
routedBy: 'router',
|
|
116
128
|
tier: routeResult.tier,
|
|
117
129
|
};
|
|
@@ -161,8 +173,18 @@ export const agentTools = [
|
|
|
161
173
|
},
|
|
162
174
|
handler: async (input) => {
|
|
163
175
|
const store = loadAgentStore();
|
|
164
|
-
const agentId = input.agentId || `agent-${Date.now()}-${
|
|
176
|
+
const agentId = input.agentId || `agent-${Date.now()}-${randomBytes(4).toString('hex')}`;
|
|
165
177
|
const agentType = input.agentType;
|
|
178
|
+
if (['__proto__', 'constructor', 'prototype'].includes(agentId)) {
|
|
179
|
+
return { success: false, agentId, error: 'Forbidden agent ID' };
|
|
180
|
+
}
|
|
181
|
+
if (input.agentId && store.agents[agentId]) {
|
|
182
|
+
return {
|
|
183
|
+
success: false,
|
|
184
|
+
agentId,
|
|
185
|
+
error: `Agent ${agentId} already exists. Terminate it first or omit agentId to auto-generate.`,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
166
188
|
const config = input.config || {};
|
|
167
189
|
// Add explicit model to config if provided
|
|
168
190
|
if (input.model) {
|
|
@@ -188,7 +210,7 @@ export const agentTools = [
|
|
|
188
210
|
saveAgentStore(store);
|
|
189
211
|
// Task 46: AgentSandboxing — register sandbox for isolated agent execution
|
|
190
212
|
try {
|
|
191
|
-
const { WasmSandbox, DockerSandbox, register } = await import('@
|
|
213
|
+
const { WasmSandbox, DockerSandbox, register } = await import('@monomind/security');
|
|
192
214
|
const sandboxType = config.sandbox?.type ?? 'wasm';
|
|
193
215
|
const sandboxConfig = config.sandbox ?? {};
|
|
194
216
|
const sandbox = sandboxType === 'docker'
|
|
@@ -196,8 +218,7 @@ export const agentTools = [
|
|
|
196
218
|
: WasmSandbox.create(agentId, sandboxConfig);
|
|
197
219
|
register(agentId, sandbox);
|
|
198
220
|
}
|
|
199
|
-
catch { /* optional — @
|
|
200
|
-
logEvent('agent.spawn', { agentId, agentType, model: routingResult.model, routedBy: routingResult.routedBy, domain: input.domain, task });
|
|
221
|
+
catch { /* optional — @monomind/security may not be installed */ }
|
|
201
222
|
// Include Agent Booster routing info if applicable
|
|
202
223
|
const response = {
|
|
203
224
|
success: true,
|
|
@@ -234,16 +255,17 @@ export const agentTools = [
|
|
|
234
255
|
required: ['agentId'],
|
|
235
256
|
},
|
|
236
257
|
handler: async (input) => {
|
|
237
|
-
const store = loadAgentStore();
|
|
238
258
|
const agentId = input.agentId;
|
|
239
|
-
if (
|
|
240
|
-
|
|
259
|
+
if (!agentId || typeof agentId !== 'string' || ['__proto__', 'constructor', 'prototype'].includes(agentId)) {
|
|
260
|
+
return { success: false, agentId, error: 'Invalid agent ID' };
|
|
261
|
+
}
|
|
262
|
+
const store = loadAgentStore();
|
|
263
|
+
if (Object.hasOwn(store.agents, agentId)) {
|
|
241
264
|
store.agents[agentId].status = 'terminated';
|
|
242
265
|
saveAgentStore(store);
|
|
243
|
-
logEvent('agent.terminate', { agentId, agentType });
|
|
244
266
|
// Task 46: AgentSandboxing — clean up sandbox on termination
|
|
245
267
|
try {
|
|
246
|
-
const { cleanup } = await import('@
|
|
268
|
+
const { cleanup } = await import('@monomind/security');
|
|
247
269
|
cleanup(agentId);
|
|
248
270
|
}
|
|
249
271
|
catch { /* optional */ }
|
|
@@ -273,9 +295,12 @@ export const agentTools = [
|
|
|
273
295
|
required: ['agentId'],
|
|
274
296
|
},
|
|
275
297
|
handler: async (input) => {
|
|
276
|
-
const store = loadAgentStore();
|
|
277
298
|
const agentId = input.agentId;
|
|
278
|
-
|
|
299
|
+
if (!agentId || typeof agentId !== 'string' || ['__proto__', 'constructor', 'prototype'].includes(agentId)) {
|
|
300
|
+
return { agentId, error: 'Invalid agent ID' };
|
|
301
|
+
}
|
|
302
|
+
const store = loadAgentStore();
|
|
303
|
+
const agent = Object.hasOwn(store.agents, agentId) ? store.agents[agentId] : undefined;
|
|
279
304
|
if (agent) {
|
|
280
305
|
return {
|
|
281
306
|
agentId: agent.agentId,
|
|
@@ -347,7 +372,7 @@ export const agentTools = [
|
|
|
347
372
|
inputSchema: {
|
|
348
373
|
type: 'object',
|
|
349
374
|
properties: {
|
|
350
|
-
action: { type: 'string', enum: ['status', 'scale', 'drain'
|
|
375
|
+
action: { type: 'string', enum: ['status', 'scale', 'drain'], description: 'Pool action' },
|
|
351
376
|
targetSize: { type: 'number', description: 'Target pool size (for scale action)' },
|
|
352
377
|
agentType: { type: 'string', description: 'Agent type filter' },
|
|
353
378
|
},
|
|
@@ -372,9 +397,6 @@ export const agentTools = [
|
|
|
372
397
|
// CLI expected fields
|
|
373
398
|
poolId: 'agent-pool-default',
|
|
374
399
|
currentSize: agents.length,
|
|
375
|
-
minSize: input.min || 0,
|
|
376
|
-
maxSize: input.max || 100,
|
|
377
|
-
autoScale: input.autoScale ?? false,
|
|
378
400
|
utilization,
|
|
379
401
|
agents: agents.map(a => ({
|
|
380
402
|
id: a.agentId,
|
|
@@ -391,7 +413,7 @@ export const agentTools = [
|
|
|
391
413
|
};
|
|
392
414
|
}
|
|
393
415
|
if (action === 'scale') {
|
|
394
|
-
const targetSize = input.targetSize || 5;
|
|
416
|
+
const targetSize = Math.min(Math.max(input.targetSize || 5, 1), 50);
|
|
395
417
|
const agentType = input.agentType || 'worker';
|
|
396
418
|
const currentSize = agents.filter(a => a.agentType === agentType).length;
|
|
397
419
|
const delta = targetSize - currentSize;
|
|
@@ -399,7 +421,7 @@ export const agentTools = [
|
|
|
399
421
|
const removed = [];
|
|
400
422
|
if (delta > 0) {
|
|
401
423
|
for (let i = 0; i < delta; i++) {
|
|
402
|
-
const agentId = `agent-${Date.now()}-${
|
|
424
|
+
const agentId = `agent-${Date.now()}-${randomBytes(4).toString('hex')}`;
|
|
403
425
|
store.agents[agentId] = {
|
|
404
426
|
agentId,
|
|
405
427
|
agentType,
|
|
@@ -467,8 +489,15 @@ export const agentTools = [
|
|
|
467
489
|
const store = loadAgentStore();
|
|
468
490
|
const agents = Object.values(store.agents).filter(a => a.status !== 'terminated');
|
|
469
491
|
const threshold = input.threshold || 0.5;
|
|
470
|
-
if (input.agentId) {
|
|
471
|
-
const
|
|
492
|
+
if (input.agentId !== undefined) {
|
|
493
|
+
const agentId = input.agentId;
|
|
494
|
+
if (typeof agentId !== 'string' ||
|
|
495
|
+
['__proto__', 'constructor', 'prototype'].includes(agentId)) {
|
|
496
|
+
return { agentId, error: 'Invalid agent ID' };
|
|
497
|
+
}
|
|
498
|
+
const agent = Object.hasOwn(store.agents, agentId)
|
|
499
|
+
? store.agents[agentId]
|
|
500
|
+
: undefined;
|
|
472
501
|
if (agent) {
|
|
473
502
|
return {
|
|
474
503
|
agentId: agent.agentId,
|
|
@@ -479,7 +508,7 @@ export const agentTools = [
|
|
|
479
508
|
uptime: Date.now() - new Date(agent.createdAt).getTime(),
|
|
480
509
|
};
|
|
481
510
|
}
|
|
482
|
-
return { agentId
|
|
511
|
+
return { agentId, error: 'Agent not found' };
|
|
483
512
|
}
|
|
484
513
|
const healthyAgents = agents.filter(a => a.health >= threshold);
|
|
485
514
|
const degradedAgents = agents.filter(a => a.health >= 0.3 && a.health < threshold);
|
|
@@ -538,9 +567,12 @@ export const agentTools = [
|
|
|
538
567
|
required: ['agentId'],
|
|
539
568
|
},
|
|
540
569
|
handler: async (input) => {
|
|
541
|
-
const store = loadAgentStore();
|
|
542
570
|
const agentId = input.agentId;
|
|
543
|
-
|
|
571
|
+
if (!agentId || typeof agentId !== 'string' || ['__proto__', 'constructor', 'prototype'].includes(agentId)) {
|
|
572
|
+
return { success: false, agentId, error: 'Invalid agent ID' };
|
|
573
|
+
}
|
|
574
|
+
const store = loadAgentStore();
|
|
575
|
+
const agent = Object.hasOwn(store.agents, agentId) ? store.agents[agentId] : undefined;
|
|
544
576
|
if (agent) {
|
|
545
577
|
if (input.status)
|
|
546
578
|
agent.status = input.status;
|