monomind 1.7.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} +22 -9
- package/.claude/commands/monomind/help.md +118 -0
- package/.claude/commands/{monomind-idea.md → monomind/idea.md} +23 -29
- package/.claude/commands/{monomind-improve.md → monomind/improve.md} +24 -30
- 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/loop-tracker.cjs +107 -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/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/README.md +5 -5
- package/package.json +1 -1
- package/packages/@monomind/cli/README.md +5 -5
- package/packages/@monomind/cli/bin/cli.js +78 -13
- 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 +28 -62
- 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 +163 -137
- package/packages/@monomind/cli/dist/src/init/helpers-generator.js +49 -36
- 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 +15 -6
- 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/graphify-tools.d.ts +4 -67
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +40 -1250
- 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/index.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/index.js +1 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +29 -13
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +6306 -0
- 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 -2
- package/packages/@monomind/guidance/README.md +0 -3
- package/packages/@monomind/shared/README.md +0 -1
- package/packages/@monomind/shared/dist/types/consensus-audit.d.ts +3 -1
- package/packages/README.md +15 -16
- 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
|
@@ -4,35 +4,81 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Monomind Command Line Interface
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* MCP mode requires explicit `mcp start` subcommand or MONOMIND_MCP_AUTODETECT=1.
|
|
8
|
+
* Usage: npx @monomind/cli mcp start
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { randomUUID } from 'crypto';
|
|
12
12
|
|
|
13
|
-
// Check if we should run in MCP server mode
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
13
|
+
// Check if we should run in MCP server mode.
|
|
14
|
+
// SECURITY: only accept explicit `mcp start` plus piped stdin, OR the explicit
|
|
15
|
+
// `MONOMIND_MCP_AUTODETECT=1` opt-in for the legacy "no args + non-TTY" path.
|
|
16
|
+
// Previously any `monomind` invocation with redirected stdin (CI pipes, xargs,
|
|
17
|
+
// editor integrations) silently flipped into MCP server mode and accepted
|
|
18
|
+
// JSON-RPC tools/call — privilege escalation by environment.
|
|
17
19
|
const cliArgs = process.argv.slice(2);
|
|
18
20
|
const isExplicitMCP = cliArgs.length >= 1 && cliArgs[0] === 'mcp' && (cliArgs.length === 1 || cliArgs[1] === 'start');
|
|
19
|
-
const
|
|
21
|
+
const allowAutoDetect = process.env.MONOMIND_MCP_AUTODETECT === '1';
|
|
22
|
+
const isMCPMode = !process.stdin.isTTY && (isExplicitMCP || (allowAutoDetect && process.argv.length === 2));
|
|
20
23
|
|
|
21
24
|
if (isMCPMode) {
|
|
22
25
|
// Run MCP server mode
|
|
23
26
|
const { listMCPTools, callMCPTool, hasTool } = await import('../dist/src/mcp-client.js');
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
// Read version from package.json instead of hardcoding (prevents stale
|
|
29
|
+
// version drift between bin entry and the published package).
|
|
30
|
+
let VERSION = '0.0.0';
|
|
31
|
+
try {
|
|
32
|
+
const { readFileSync } = await import('fs');
|
|
33
|
+
const { fileURLToPath } = await import('url');
|
|
34
|
+
const { dirname, join } = await import('path');
|
|
35
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
36
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
37
|
+
if (typeof pkg.version === 'string') VERSION = pkg.version;
|
|
38
|
+
} catch { /* fall back to 0.0.0 */ }
|
|
26
39
|
const sessionId = `mcp-${Date.now()}-${randomUUID().slice(0, 8)}`;
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
41
|
+
// Don't leak nodeVersion/platform/arch/pid to stderr by default; gate behind
|
|
42
|
+
// MONOMIND_LOG_LEVEL=debug to reduce fingerprinting in shared log aggregators.
|
|
43
|
+
if (process.env.MONOMIND_LOG_LEVEL === 'debug') {
|
|
44
|
+
console.error(
|
|
45
|
+
`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Starting in stdio mode (node=${process.version} platform=${process.platform} arch=${process.arch})`
|
|
46
|
+
);
|
|
47
|
+
} else {
|
|
48
|
+
console.error(
|
|
49
|
+
`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Starting in stdio mode`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Top-level safety nets — without these, an unhandled async error in a tool
|
|
54
|
+
// handler crashes the process with no observable cleanup.
|
|
55
|
+
process.on('uncaughtException', (err) => {
|
|
56
|
+
console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] uncaughtException: ${err && err.message ? err.message : String(err)}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
});
|
|
59
|
+
process.on('unhandledRejection', (reason) => {
|
|
60
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
61
|
+
console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] unhandledRejection: ${msg}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
const shutdown = (sig) => {
|
|
65
|
+
console.error(`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) ${sig} received, shutting down`);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
};
|
|
68
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
69
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
31
70
|
|
|
71
|
+
// Cap on accumulated input buffer so a peer pumping a single multi-GB line
|
|
72
|
+
// (or a slow trickle without newlines) cannot OOM-kill the process.
|
|
73
|
+
const MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
32
74
|
let buffer = '';
|
|
33
75
|
process.stdin.setEncoding('utf8');
|
|
34
76
|
process.stdin.on('data', async (chunk) => {
|
|
35
77
|
buffer += chunk;
|
|
78
|
+
if (buffer.length > MAX_BUFFER_BYTES) {
|
|
79
|
+
console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] input exceeds ${MAX_BUFFER_BYTES} bytes`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
36
82
|
let lines = buffer.split('\n');
|
|
37
83
|
buffer = lines.pop() || '';
|
|
38
84
|
|
|
@@ -146,11 +192,30 @@ if (isMCPMode) {
|
|
|
146
192
|
}
|
|
147
193
|
}
|
|
148
194
|
} else {
|
|
149
|
-
// Run normal CLI mode
|
|
195
|
+
// Run normal CLI mode.
|
|
196
|
+
// Install top-level handlers so an asynchronous error fired from an event-
|
|
197
|
+
// loop callback does not bypass the synchronous .catch below. Default Node
|
|
198
|
+
// handler prints the full stack to stderr — which on this codebase includes
|
|
199
|
+
// attacker-influenced bytes from registry/config error messages and full
|
|
200
|
+
// filesystem paths. Sanitize before logging and exit non-zero.
|
|
201
|
+
const safeMsg = (m) =>
|
|
202
|
+
String(m == null ? '' : m).replace(/[\x00-\x1f\x7f-\x9f]/g, '?').slice(0, 1000);
|
|
203
|
+
process.on('uncaughtException', (err) => {
|
|
204
|
+
console.error(`[${new Date().toISOString()}] FATAL [monomind] uncaughtException: ${safeMsg(err && err.message)}`);
|
|
205
|
+
if (process.env.DEBUG) console.error(err && err.stack);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
});
|
|
208
|
+
process.on('unhandledRejection', (reason) => {
|
|
209
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
210
|
+
console.error(`[${new Date().toISOString()}] FATAL [monomind] unhandledRejection: ${safeMsg(msg)}`);
|
|
211
|
+
if (process.env.DEBUG && reason instanceof Error) console.error(reason.stack);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
});
|
|
214
|
+
|
|
150
215
|
const { CLI } = await import('../dist/src/index.js');
|
|
151
216
|
const cli = new CLI();
|
|
152
217
|
cli.run().catch((error) => {
|
|
153
|
-
console.error('Fatal error:', error.message);
|
|
218
|
+
console.error('Fatal error:', safeMsg(error && error.message));
|
|
154
219
|
process.exit(1);
|
|
155
220
|
});
|
|
156
221
|
}
|
|
@@ -6,14 +6,23 @@
|
|
|
6
6
|
* can query whether a halt has been issued.
|
|
7
7
|
*/
|
|
8
8
|
import { randomUUID } from 'crypto';
|
|
9
|
-
import { existsSync, mkdirSync, appendFileSync, readFileSync } from 'fs';
|
|
10
|
-
import { join, dirname } from 'path';
|
|
11
|
-
const
|
|
9
|
+
import { existsSync, mkdirSync, appendFileSync, readFileSync, statSync } from 'fs';
|
|
10
|
+
import { join, dirname, resolve, sep } from 'path';
|
|
11
|
+
const ALLOWED_ROOT = () => resolve(process.env.MONOMIND_DATA_DIR ?? process.cwd());
|
|
12
|
+
const DEFAULT_FILE = () => join(ALLOWED_ROOT(), 'data', 'halt-signals.jsonl');
|
|
13
|
+
function safeHaltFilePath(filePath) {
|
|
14
|
+
const allowedRoot = ALLOWED_ROOT();
|
|
15
|
+
const resolved = resolve(filePath);
|
|
16
|
+
if (resolved !== allowedRoot && !resolved.startsWith(allowedRoot + sep)) {
|
|
17
|
+
throw new Error(`Halt signal file path escapes allowed directory: ${filePath}`);
|
|
18
|
+
}
|
|
19
|
+
return resolved;
|
|
20
|
+
}
|
|
12
21
|
/**
|
|
13
22
|
* Broadcast a halt signal for a swarm.
|
|
14
23
|
*/
|
|
15
24
|
export function broadcast(swarmId, sourceAgentId, reason, filePath) {
|
|
16
|
-
const target = filePath
|
|
25
|
+
const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
|
|
17
26
|
const dir = dirname(target);
|
|
18
27
|
if (!existsSync(dir)) {
|
|
19
28
|
mkdirSync(dir, { recursive: true });
|
|
@@ -32,10 +41,22 @@ export function broadcast(swarmId, sourceAgentId, reason, filePath) {
|
|
|
32
41
|
* Check whether any halt signal exists for the given swarm.
|
|
33
42
|
*/
|
|
34
43
|
export function isHalted(swarmId, filePath) {
|
|
35
|
-
const target = filePath
|
|
44
|
+
const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
|
|
36
45
|
if (!existsSync(target)) {
|
|
37
46
|
return false;
|
|
38
47
|
}
|
|
48
|
+
// Size cap. isHalted is on the swarm-coordination hot path; without this
|
|
49
|
+
// cap a planted multi-GB file (or unbounded broadcast accumulation over
|
|
50
|
+
// weeks) reliably OOMs the CLI on the next call. Treat oversized halt
|
|
51
|
+
// logs as "no halt" — fail-safe in the swarm-termination flow.
|
|
52
|
+
try {
|
|
53
|
+
const stat = statSync(target);
|
|
54
|
+
if (stat.size > 10 * 1024 * 1024)
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
39
60
|
const raw = readFileSync(target, 'utf-8').trim();
|
|
40
61
|
if (!raw)
|
|
41
62
|
return false;
|
|
@@ -43,8 +64,13 @@ export function isHalted(swarmId, filePath) {
|
|
|
43
64
|
.split('\n')
|
|
44
65
|
.filter(Boolean)
|
|
45
66
|
.some((line) => {
|
|
46
|
-
|
|
47
|
-
|
|
67
|
+
try {
|
|
68
|
+
const rec = JSON.parse(line);
|
|
69
|
+
return rec.swarmId === swarmId;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
48
74
|
});
|
|
49
75
|
}
|
|
50
76
|
//# sourceMappingURL=halt-signal.js.map
|
|
@@ -8,10 +8,13 @@ export async function spawnAndAwait(agentSlug, task, runner, options = {}) {
|
|
|
8
8
|
const startedAt = Date.now();
|
|
9
9
|
const taskId = `managed-${Date.now().toString(36)}-${randomBytes(4).toString('hex')}`;
|
|
10
10
|
try {
|
|
11
|
+
let timeoutHandle;
|
|
11
12
|
const output = await Promise.race([
|
|
12
13
|
runner(agentSlug, taskId, task),
|
|
13
|
-
new Promise((_, reject) =>
|
|
14
|
-
|
|
14
|
+
new Promise((_, reject) => {
|
|
15
|
+
timeoutHandle = setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms`)), timeoutMs);
|
|
16
|
+
}),
|
|
17
|
+
]).finally(() => clearTimeout(timeoutHandle));
|
|
15
18
|
return {
|
|
16
19
|
agentSlug, taskId, output, status: 'success',
|
|
17
20
|
durationMs: Date.now() - startedAt,
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* routes to the candidate or control version. Falls back to the active version
|
|
6
6
|
* when no experiment is running.
|
|
7
7
|
*
|
|
8
|
-
* @module @
|
|
8
|
+
* @module @monomind/cli/agents/prompt-experiment
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
type PromptVersionStore = any;
|
|
11
11
|
export interface ResolvedPrompt {
|
|
12
12
|
prompt: string;
|
|
13
13
|
version: string;
|
|
@@ -19,4 +19,5 @@ export declare class PromptExperimentRouter {
|
|
|
19
19
|
constructor(store: PromptVersionStore);
|
|
20
20
|
resolvePromptForSpawn(agentSlug: string): ResolvedPrompt;
|
|
21
21
|
}
|
|
22
|
+
export {};
|
|
22
23
|
//# sourceMappingURL=prompt-experiment.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* routes to the candidate or control version. Falls back to the active version
|
|
6
6
|
* when no experiment is running.
|
|
7
7
|
*
|
|
8
|
-
* @module @
|
|
8
|
+
* @module @monomind/cli/agents/prompt-experiment
|
|
9
9
|
*/
|
|
10
10
|
export class PromptExperimentRouter {
|
|
11
11
|
store;
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* Provides publish-from-file, promote, rollback, and experiment
|
|
5
5
|
* start/stop workflows on top of PromptVersionStore.
|
|
6
6
|
*
|
|
7
|
-
* @module @
|
|
7
|
+
* @module @monomind/cli/agents/prompt-version-manager
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
type PromptVersionStore = any;
|
|
10
|
+
type PromptVersion = any;
|
|
11
|
+
type PromptExperiment = any;
|
|
10
12
|
export declare class PromptVersionManager {
|
|
11
13
|
private readonly store;
|
|
12
14
|
constructor(store: PromptVersionStore);
|
|
@@ -16,4 +18,5 @@ export declare class PromptVersionManager {
|
|
|
16
18
|
startExperiment(experiment: PromptExperiment): void;
|
|
17
19
|
stopExperiment(agentSlug: string, promoteWinner?: boolean): void;
|
|
18
20
|
}
|
|
21
|
+
export {};
|
|
19
22
|
//# sourceMappingURL=prompt-version-manager.d.ts.map
|
|
@@ -4,16 +4,39 @@
|
|
|
4
4
|
* Provides publish-from-file, promote, rollback, and experiment
|
|
5
5
|
* start/stop workflows on top of PromptVersionStore.
|
|
6
6
|
*
|
|
7
|
-
* @module @
|
|
7
|
+
* @module @monomind/cli/agents/prompt-version-manager
|
|
8
8
|
*/
|
|
9
9
|
import * as fs from 'node:fs';
|
|
10
|
+
import * as path from 'node:path';
|
|
10
11
|
export class PromptVersionManager {
|
|
11
12
|
store;
|
|
12
13
|
constructor(store) {
|
|
13
14
|
this.store = store;
|
|
14
15
|
}
|
|
15
16
|
publishFromFile(agentSlug, filePath, newVersion, changelog) {
|
|
16
|
-
|
|
17
|
+
// Symlink-aware containment: path.resolve does NOT follow symlinks, so
|
|
18
|
+
// a symlink under cwd pointing at /etc/shadow would have passed the
|
|
19
|
+
// prefix-check below. Use realpathSync on both sides and reject symlinks
|
|
20
|
+
// at the leaf so the resolved file is provably inside the project.
|
|
21
|
+
const allowedRoot = fs.realpathSync(process.cwd());
|
|
22
|
+
const requested = path.resolve(filePath);
|
|
23
|
+
if (!fs.existsSync(requested)) {
|
|
24
|
+
throw new Error(`filePath does not exist: ${requested}`);
|
|
25
|
+
}
|
|
26
|
+
if (fs.lstatSync(requested).isSymbolicLink()) {
|
|
27
|
+
throw new Error('filePath must not be a symlink');
|
|
28
|
+
}
|
|
29
|
+
const resolved = fs.realpathSync(requested);
|
|
30
|
+
const rel = path.relative(allowedRoot, resolved);
|
|
31
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
32
|
+
throw new Error(`filePath must be inside the project directory: ${allowedRoot}`);
|
|
33
|
+
}
|
|
34
|
+
const MAX_PROMPT_BYTES = 1 * 1024 * 1024;
|
|
35
|
+
const fileSize = fs.statSync(resolved).size;
|
|
36
|
+
if (fileSize > MAX_PROMPT_BYTES) {
|
|
37
|
+
throw new Error(`filePath exceeds maximum allowed size (${MAX_PROMPT_BYTES} bytes): ${resolved}`);
|
|
38
|
+
}
|
|
39
|
+
const prompt = fs.readFileSync(resolved, 'utf-8');
|
|
17
40
|
const version = {
|
|
18
41
|
agentSlug,
|
|
19
42
|
version: newVersion,
|
|
@@ -47,8 +70,7 @@ export class PromptVersionManager {
|
|
|
47
70
|
if (!experiment) {
|
|
48
71
|
throw new Error(`No active experiment for "${agentSlug}"`);
|
|
49
72
|
}
|
|
50
|
-
|
|
51
|
-
const winnerId = experiment.control;
|
|
73
|
+
const winnerId = (experiment.winner ?? experiment.control);
|
|
52
74
|
this.store.concludeExperiment(agentSlug, winnerId);
|
|
53
75
|
if (promoteWinner) {
|
|
54
76
|
this.store.setActive(agentSlug, winnerId);
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* JSONL-based per-agent-per-task-type scoring with time-decay.
|
|
5
5
|
* Enables monomind to prefer historically successful agents for specific task types.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs';
|
|
8
|
+
import { randomBytes } from 'crypto';
|
|
8
9
|
import { dirname } from 'path';
|
|
9
10
|
import { calculateDecayFactor } from './score-decay.js';
|
|
11
|
+
import { parseJsonl } from '../utils/parse-jsonl.js';
|
|
10
12
|
/** Key used to identify a unique agent+taskType pair in the JSONL store. */
|
|
11
13
|
function scoreKey(agentSlug, taskType) {
|
|
12
14
|
return `${agentSlug}::${taskType}`;
|
|
@@ -34,17 +36,23 @@ export class SpecializationScorer {
|
|
|
34
36
|
if (!existsSync(this.filePath)) {
|
|
35
37
|
return [];
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
// 10MB cap. readAll is on the routing hot path; without this cap a
|
|
40
|
+
// bloated scorer file (planted or grown via repeated recordOutcome calls
|
|
41
|
+
// with diverse agentSlug::taskType keys) crashes the CLI on every route.
|
|
42
|
+
const stat = statSync(this.filePath);
|
|
43
|
+
if (stat.size > 10 * 1024 * 1024) {
|
|
44
|
+
throw new Error('Scorer store exceeds 10MB; run compaction');
|
|
45
|
+
}
|
|
46
|
+
const raw = readFileSync(this.filePath, 'utf-8');
|
|
47
|
+
return parseJsonl(raw).filter((r) => r !== null && typeof r === 'object' && !Array.isArray(r) &&
|
|
48
|
+
Object.getPrototypeOf(r) === Object.prototype);
|
|
44
49
|
}
|
|
45
50
|
writeAll(records) {
|
|
46
51
|
const lines = records.map((r) => JSON.stringify(r));
|
|
47
|
-
|
|
52
|
+
// Unique tmp filename so concurrent recordOutcome calls don't collide.
|
|
53
|
+
const tmp = `${this.filePath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
54
|
+
writeFileSync(tmp, lines.join('\n') + '\n', 'utf-8');
|
|
55
|
+
renameSync(tmp, this.filePath);
|
|
48
56
|
}
|
|
49
57
|
// ---------------------------------------------------------------------------
|
|
50
58
|
// Public API
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
* - `inject` matches accumulate as additional candidates.
|
|
10
10
|
* - Invalid regex patterns are silently skipped.
|
|
11
11
|
*/
|
|
12
|
-
import type { TriggerPattern, TriggerMatch, TriggerIndex } from '../../../../@
|
|
12
|
+
import type { TriggerPattern, TriggerMatch, TriggerIndex } from '../../../../@monomind/shared/src/types/trigger.js';
|
|
13
13
|
export declare class TriggerScanner {
|
|
14
14
|
private compiled;
|
|
15
15
|
private patterns;
|
|
16
16
|
private totalAgentsScanned;
|
|
17
|
+
private buildingIndex;
|
|
17
18
|
constructor(patterns?: TriggerPattern[]);
|
|
18
19
|
/**
|
|
19
20
|
* Test all patterns against `taskDescription` and return matches.
|
|
@@ -29,7 +30,8 @@ export declare class TriggerScanner {
|
|
|
29
30
|
* Reads each `.md` file, extracts YAML frontmatter, and looks for
|
|
30
31
|
* `triggers:` entries with `pattern`, `mode`, and optional `priority`.
|
|
31
32
|
*/
|
|
32
|
-
buildIndex(agentDir: string): TriggerIndex;
|
|
33
|
+
buildIndex(agentDir: string, allowedRoot?: string): TriggerIndex;
|
|
34
|
+
private _buildIndex;
|
|
33
35
|
/** Add a pattern to the index at runtime. */
|
|
34
36
|
addPattern(pattern: TriggerPattern): void;
|
|
35
37
|
/**
|
|
@@ -43,7 +45,7 @@ export declare class TriggerScanner {
|
|
|
43
45
|
get size(): number;
|
|
44
46
|
private compileAndAdd;
|
|
45
47
|
private sortByPriority;
|
|
46
|
-
/** Recursively collect `.md` files. */
|
|
48
|
+
/** Recursively collect `.md` files (symlinks skipped, visited inodes tracked). */
|
|
47
49
|
private collectMdFiles;
|
|
48
50
|
/** Derive slug from filename. */
|
|
49
51
|
private slugFromPath;
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
* - `inject` matches accumulate as additional candidates.
|
|
10
10
|
* - Invalid regex patterns are silently skipped.
|
|
11
11
|
*/
|
|
12
|
-
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
13
|
-
import { join, extname } from 'path';
|
|
12
|
+
import { readFileSync, readdirSync, lstatSync, statSync, realpathSync } from 'fs';
|
|
13
|
+
import { join, extname, resolve, sep } from 'path';
|
|
14
14
|
export class TriggerScanner {
|
|
15
15
|
compiled = [];
|
|
16
16
|
patterns = [];
|
|
17
17
|
totalAgentsScanned = 0;
|
|
18
|
+
buildingIndex = false;
|
|
18
19
|
constructor(patterns = []) {
|
|
19
20
|
for (const p of patterns) {
|
|
20
21
|
this.compileAndAdd(p);
|
|
@@ -59,14 +60,48 @@ export class TriggerScanner {
|
|
|
59
60
|
* Reads each `.md` file, extracts YAML frontmatter, and looks for
|
|
60
61
|
* `triggers:` entries with `pattern`, `mode`, and optional `priority`.
|
|
61
62
|
*/
|
|
62
|
-
buildIndex(agentDir) {
|
|
63
|
+
buildIndex(agentDir, allowedRoot) {
|
|
64
|
+
if (this.buildingIndex) {
|
|
65
|
+
throw new Error('buildIndex is already running; concurrent invocations are not safe');
|
|
66
|
+
}
|
|
67
|
+
this.buildingIndex = true;
|
|
68
|
+
try {
|
|
69
|
+
return this._buildIndex(agentDir, allowedRoot);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
this.buildingIndex = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
_buildIndex(agentDir, allowedRoot) {
|
|
76
|
+
if (allowedRoot) {
|
|
77
|
+
let resolvedDir;
|
|
78
|
+
let resolvedRoot;
|
|
79
|
+
try {
|
|
80
|
+
resolvedDir = realpathSync(resolve(agentDir));
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
resolvedDir = resolve(agentDir);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
resolvedRoot = realpathSync(resolve(allowedRoot));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
resolvedRoot = resolve(allowedRoot);
|
|
90
|
+
}
|
|
91
|
+
if (!resolvedDir.startsWith(resolvedRoot + sep) && resolvedDir !== resolvedRoot) {
|
|
92
|
+
throw new Error(`Agent directory escapes workspace: ${resolvedDir}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
63
95
|
const mdFiles = this.collectMdFiles(agentDir);
|
|
64
96
|
this.patterns = [];
|
|
65
97
|
this.compiled = [];
|
|
66
98
|
this.totalAgentsScanned = mdFiles.length;
|
|
99
|
+
const MAX_AGENT_FILE_BYTES = 1 * 1024 * 1024;
|
|
67
100
|
for (const filePath of mdFiles) {
|
|
68
101
|
let content;
|
|
69
102
|
try {
|
|
103
|
+
if (statSync(filePath).size > MAX_AGENT_FILE_BYTES)
|
|
104
|
+
continue;
|
|
70
105
|
content = readFileSync(filePath, 'utf-8');
|
|
71
106
|
}
|
|
72
107
|
catch {
|
|
@@ -118,6 +153,14 @@ export class TriggerScanner {
|
|
|
118
153
|
// Internal helpers
|
|
119
154
|
// ---------------------------------------------------------------------------
|
|
120
155
|
compileAndAdd(pattern) {
|
|
156
|
+
if (pattern.pattern.length > 200)
|
|
157
|
+
return;
|
|
158
|
+
// Reject patterns with nested/repeated quantifiers (ReDoS vectors)
|
|
159
|
+
// Covers: (a+)+, (a|b+)+, (a?){n}, ((a)+)+, [a-z]+{n}
|
|
160
|
+
if (/(\(.*[+*?].*\)|[+*?]){2,}|\{[0-9,]+\}.*[+*?]|(\[[^\]]*\]|\.)[+*?][+*?]/.test(pattern.pattern))
|
|
161
|
+
return;
|
|
162
|
+
if (/\([^)]*([+*][^)]*){2,}\)/.test(pattern.pattern))
|
|
163
|
+
return;
|
|
121
164
|
try {
|
|
122
165
|
const regex = new RegExp(pattern.pattern, 'i');
|
|
123
166
|
this.patterns.push(pattern);
|
|
@@ -134,8 +177,8 @@ export class TriggerScanner {
|
|
|
134
177
|
this.patterns = indexed.map((x) => x.p);
|
|
135
178
|
this.compiled = indexed.map((x) => x.c);
|
|
136
179
|
}
|
|
137
|
-
/** Recursively collect `.md` files. */
|
|
138
|
-
collectMdFiles(dir) {
|
|
180
|
+
/** Recursively collect `.md` files (symlinks skipped, visited inodes tracked). */
|
|
181
|
+
collectMdFiles(dir, visited = new Set()) {
|
|
139
182
|
const results = [];
|
|
140
183
|
let entries;
|
|
141
184
|
try {
|
|
@@ -146,17 +189,22 @@ export class TriggerScanner {
|
|
|
146
189
|
}
|
|
147
190
|
for (const entry of entries) {
|
|
148
191
|
const full = join(dir, entry);
|
|
149
|
-
let
|
|
192
|
+
let lstat;
|
|
150
193
|
try {
|
|
151
|
-
|
|
194
|
+
lstat = lstatSync(full);
|
|
152
195
|
}
|
|
153
196
|
catch {
|
|
154
197
|
continue;
|
|
155
198
|
}
|
|
156
|
-
if (
|
|
157
|
-
|
|
199
|
+
if (lstat.isSymbolicLink())
|
|
200
|
+
continue;
|
|
201
|
+
if (lstat.isDirectory()) {
|
|
202
|
+
if (visited.has(lstat.ino))
|
|
203
|
+
continue;
|
|
204
|
+
visited.add(lstat.ino);
|
|
205
|
+
results.push(...this.collectMdFiles(full, visited));
|
|
158
206
|
}
|
|
159
|
-
else if (
|
|
207
|
+
else if (lstat.isFile() && extname(entry) === '.md') {
|
|
160
208
|
results.push(full);
|
|
161
209
|
}
|
|
162
210
|
}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* JSONL-based append-only storage for agent definition versions.
|
|
5
5
|
* Supports save, list, get, rollback, and diff operations.
|
|
6
6
|
*/
|
|
7
|
-
import { createHash, randomUUID } from 'crypto';
|
|
8
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync,
|
|
7
|
+
import { createHash, randomUUID, randomBytes } from 'crypto';
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs';
|
|
9
9
|
import { join } from 'path';
|
|
10
10
|
import { computeUnifiedDiff } from './version-diff.js';
|
|
11
|
+
import { parseJsonl } from '../utils/parse-jsonl.js';
|
|
11
12
|
function toStored(r) {
|
|
12
13
|
return {
|
|
13
14
|
id: r.id,
|
|
@@ -63,21 +64,41 @@ export class AgentVersionStore {
|
|
|
63
64
|
if (!existsSync(this.filePath)) {
|
|
64
65
|
return [];
|
|
65
66
|
}
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
const stat = statSync(this.filePath);
|
|
68
|
+
if (stat.size > 10 * 1024 * 1024) {
|
|
69
|
+
throw new Error('Version store exceeds size limit; run compaction');
|
|
70
|
+
}
|
|
71
|
+
const raw = readFileSync(this.filePath, 'utf-8');
|
|
72
|
+
// Drop any record whose stored contentHash does not match the SHA-256 of
|
|
73
|
+
// its content. saveVersion advertises tamper-evidence by computing the
|
|
74
|
+
// hash; without this verification step, an attacker who can write the
|
|
75
|
+
// JSONL file can swap `content` with a poisoned agent prompt while
|
|
76
|
+
// leaving `contentHash` unchanged, and the next getCurrent() returns
|
|
77
|
+
// the tampered prompt verbatim into the LLM context.
|
|
78
|
+
const records = parseJsonl(raw);
|
|
79
|
+
const verified = [];
|
|
80
|
+
for (const r of records) {
|
|
81
|
+
if (typeof r?.content !== 'string' ||
|
|
82
|
+
typeof r?.contentHash !== 'string' ||
|
|
83
|
+
typeof r?.id !== 'string' ||
|
|
84
|
+
typeof r?.slug !== 'string' ||
|
|
85
|
+
typeof r?.version !== 'string' ||
|
|
86
|
+
typeof r?.changelog !== 'string' ||
|
|
87
|
+
typeof r?.capturedBy !== 'string' ||
|
|
88
|
+
typeof r?.capturedAt !== 'string')
|
|
89
|
+
continue;
|
|
90
|
+
const actual = createHash('sha256').update(r.content).digest('hex');
|
|
91
|
+
if (actual !== r.contentHash)
|
|
92
|
+
continue; // silently drop tampered record
|
|
93
|
+
verified.push(r);
|
|
94
|
+
}
|
|
95
|
+
return verified.map(fromStored);
|
|
73
96
|
}
|
|
74
97
|
writeAll(records) {
|
|
75
98
|
const lines = records.map((r) => JSON.stringify(toStored(r)));
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const line = JSON.stringify(toStored(record)) + '\n';
|
|
80
|
-
appendFileSync(this.filePath, line, 'utf-8');
|
|
99
|
+
const tmp = `${this.filePath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
100
|
+
writeFileSync(tmp, lines.join('\n') + '\n', 'utf-8');
|
|
101
|
+
renameSync(tmp, this.filePath);
|
|
81
102
|
}
|
|
82
103
|
// ---------------------------------------------------------------------------
|
|
83
104
|
// Public API
|
|
@@ -89,19 +110,20 @@ export class AgentVersionStore {
|
|
|
89
110
|
* the same slug as non-current, and appends the new record.
|
|
90
111
|
*/
|
|
91
112
|
saveVersion(slug, content, version, changelog, opts = {}) {
|
|
113
|
+
const MAX_CONTENT_BYTES = 512 * 1024;
|
|
114
|
+
if (Buffer.byteLength(content, 'utf-8') > MAX_CONTENT_BYTES) {
|
|
115
|
+
throw new Error(`content exceeds maximum allowed size (${MAX_CONTENT_BYTES} bytes)`);
|
|
116
|
+
}
|
|
92
117
|
const contentHash = createHash('sha256').update(content).digest('hex');
|
|
93
|
-
//
|
|
118
|
+
// SINGLE-WRITER CONTRACT: version-store is written only by the daemon process.
|
|
119
|
+
// Concurrent saveVersion() calls from multiple processes would race on readAll/writeAll.
|
|
120
|
+
// If multi-writer access is needed in future, introduce an advisory lock here.
|
|
94
121
|
const existing = this.readAll();
|
|
95
|
-
let changed = false;
|
|
96
122
|
for (const rec of existing) {
|
|
97
123
|
if (rec.slug === slug && rec.isCurrent) {
|
|
98
124
|
rec.isCurrent = false;
|
|
99
|
-
changed = true;
|
|
100
125
|
}
|
|
101
126
|
}
|
|
102
|
-
if (changed) {
|
|
103
|
-
this.writeAll(existing);
|
|
104
|
-
}
|
|
105
127
|
const record = {
|
|
106
128
|
id: randomUUID(),
|
|
107
129
|
slug,
|
|
@@ -115,7 +137,8 @@ export class AgentVersionStore {
|
|
|
115
137
|
capturedBy: opts.capturedBy ?? 'system',
|
|
116
138
|
isCurrent: true,
|
|
117
139
|
};
|
|
118
|
-
|
|
140
|
+
existing.push(record);
|
|
141
|
+
this.writeAll(existing);
|
|
119
142
|
return record;
|
|
120
143
|
}
|
|
121
144
|
/**
|