monomind 1.19.0 → 2.0.1
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/README.md +13 -17
- package/package.json +16 -35
- package/packages/@monomind/cli/.claude/agents/github/issue-tracker.md +0 -2
- package/packages/@monomind/cli/.claude/agents/github/pr-manager.md +0 -2
- package/packages/@monomind/cli/.claude/agents/github/repo-architect.md +3 -11
- package/packages/@monomind/cli/.claude/agents/goal/goal-planner.md +0 -1
- package/packages/@monomind/cli/.claude/commands/github/issue-tracker.md +0 -2
- package/packages/@monomind/cli/.claude/commands/github/pr-manager.md +0 -2
- package/packages/@monomind/cli/.claude/commands/github/repo-architect.md +3 -10
- package/packages/@monomind/cli/.claude/commands/mastermind/help.md +3 -3
- package/packages/@monomind/cli/.claude/commands/workflows/README.md +0 -1
- package/packages/@monomind/cli/.claude/commands/workflows/workflow-create.md +0 -1
- package/packages/@monomind/cli/.claude/commands/workflows/workflow-execute.md +1 -3
- package/packages/@monomind/cli/.claude/commands/workflows/workflow-export.md +0 -2
- package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +18 -1
- package/packages/@monomind/cli/.claude/helpers/handlers/edit-handler.cjs +15 -0
- package/packages/@monomind/cli/.claude/helpers/handlers/gates-handler.cjs +2 -8
- package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +149 -7
- package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +47 -25
- package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +80 -43
- package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +8 -4
- package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +69 -16
- package/packages/@monomind/cli/.claude/helpers/intelligence.cjs +100 -9
- package/packages/@monomind/cli/.claude/helpers/router.cjs +78 -5
- package/packages/@monomind/cli/.claude/helpers/skill-registry.json +0 -189
- package/packages/@monomind/cli/.claude/helpers/token-tracker.cjs +10 -0
- package/packages/@monomind/cli/.claude/skills/github-toolkit/SKILL.md +60 -0
- package/packages/@monomind/cli/.claude/skills/hive-mind-advanced/SKILL.md +0 -15
- package/packages/@monomind/cli/.claude/skills/hooks-automation/SKILL.md +0 -1
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/_protocol.md +1 -1
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/build.md +1 -2
- package/packages/@monomind/cli/.claude/skills/memory-toolkit/SKILL.md +75 -0
- package/packages/@monomind/cli/.claude/skills/specialagent/SKILL.md +2 -4
- package/packages/@monomind/cli/.claude/skills/swarm-advanced/SKILL.md +0 -1
- package/packages/@monomind/cli/README.md +13 -17
- package/packages/@monomind/cli/dist/src/autopilot-state.js +4 -5
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +129 -2
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +214 -1764
- package/packages/@monomind/cli/dist/src/capabilities/index.d.ts +0 -2
- package/packages/@monomind/cli/dist/src/capabilities/index.js +0 -1
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +2 -6
- package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +0 -4
- package/packages/@monomind/cli/dist/src/commands/analyze.js +1 -29
- package/packages/@monomind/cli/dist/src/commands/browse-workflow.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/completions.js +3 -22
- package/packages/@monomind/cli/dist/src/commands/config.js +0 -6
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +12 -2
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +130 -22
- package/packages/@monomind/cli/dist/src/commands/doctor.js +6 -5
- package/packages/@monomind/cli/dist/src/commands/guidance.d.ts +5 -1
- package/packages/@monomind/cli/dist/src/commands/guidance.js +11 -556
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +11 -4
- package/packages/@monomind/cli/dist/src/commands/hive-mind.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +9 -6
- package/packages/@monomind/cli/dist/src/commands/hooks-formatting.d.ts +1 -5
- package/packages/@monomind/cli/dist/src/commands/hooks-formatting.js +1 -18
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +82 -330
- package/packages/@monomind/cli/dist/src/commands/index.d.ts +0 -5
- package/packages/@monomind/cli/dist/src/commands/index.js +0 -45
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/init.js +4 -24
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +11 -11
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +9 -11
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +10 -10
- package/packages/@monomind/cli/dist/src/commands/providers.js +90 -1
- package/packages/@monomind/cli/dist/src/commands/search-universal.d.ts +7 -1
- package/packages/@monomind/cli/dist/src/commands/search-universal.js +59 -5
- package/packages/@monomind/cli/dist/src/commands/security-cve.js +3 -5
- package/packages/@monomind/cli/dist/src/commands/session.js +143 -3
- package/packages/@monomind/cli/dist/src/commands/start.js +0 -18
- package/packages/@monomind/cli/dist/src/commands/swarm.js +112 -65
- package/packages/@monomind/cli/dist/src/consensus/audit-writer.js +43 -1
- package/packages/@monomind/cli/dist/src/consensus/tally.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/consensus/tally.js +34 -0
- package/packages/@monomind/cli/dist/src/index.d.ts +3 -2
- package/packages/@monomind/cli/dist/src/index.js +9 -12
- package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +10 -14
- package/packages/@monomind/cli/dist/src/init/executor.js +39 -86
- package/packages/@monomind/cli/dist/src/init/settings-generator.js +0 -12
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +62 -0
- package/packages/@monomind/cli/dist/src/init/types.d.ts +2 -6
- package/packages/@monomind/cli/dist/src/init/types.js +0 -3
- package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.js +18 -8
- package/packages/@monomind/cli/dist/src/mcp-client.js +0 -2
- package/packages/@monomind/cli/dist/src/mcp-server.js +12 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/coherence-check.js +1 -19
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +21 -20
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.js +3 -18
- package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +1 -7
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +7 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.d.ts +8 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +174 -38
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-advanced.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-advanced.js +25 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.d.ts +4 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +33 -482
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +51 -43
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-synthesis.d.ts +31 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-synthesis.js +196 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +10 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +20 -29
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +78 -220
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +9 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +242 -506
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.d.ts +12 -12
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/security-tools.js +103 -0
- package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +2 -1
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +56 -43
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +14 -9
- package/packages/@monomind/cli/dist/src/memory/memory-read.js +1 -19
- package/packages/@monomind/cli/dist/src/orgrt/types.d.ts +847 -0
- package/packages/@monomind/cli/dist/src/orgrt/types.js +51 -0
- package/packages/@monomind/cli/dist/src/parser.js +31 -5
- package/packages/@monomind/cli/dist/src/suggest.js +1 -7
- package/packages/@monomind/cli/dist/src/transfer/store/discovery.d.ts +3 -2
- package/packages/@monomind/cli/dist/src/transfer/store/discovery.js +22 -70
- package/packages/@monomind/cli/dist/src/ui/collector.mjs +69 -44
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +112 -25
- package/packages/@monomind/cli/dist/src/ui/orgs.html +54 -0
- package/packages/@monomind/cli/dist/src/ui/server.mjs +87 -12
- package/packages/@monomind/cli/dist/src/update/checker.js +0 -1
- package/packages/@monomind/cli/dist/src/utils/cosine-similarity.d.ts +22 -0
- package/packages/@monomind/cli/dist/src/utils/cosine-similarity.js +38 -0
- package/packages/@monomind/cli/dist/src/utils/input-guards.d.ts +51 -0
- package/packages/@monomind/cli/dist/src/utils/input-guards.js +223 -0
- package/packages/@monomind/cli/dist/src/utils/json-file.d.ts +33 -0
- package/packages/@monomind/cli/dist/src/utils/json-file.js +57 -0
- package/packages/@monomind/cli/package.json +11 -7
- package/packages/@monomind/cli/scripts/sync-claude-assets.sh +16 -20
- package/scripts/generate-agent-avatars.mjs +0 -8
- package/.claude/agents/architecture/system-design/arch-system-design.md +0 -54
- package/.claude/agents/consensus/crdt-synchronizer.md +0 -977
- package/.claude/agents/consensus/quorum-manager.md +0 -803
- package/.claude/agents/consensus/security-manager.md +0 -602
- package/.claude/agents/core/coder.md +0 -262
- package/.claude/agents/core/coordinator.md +0 -71
- package/.claude/agents/core/planner.md +0 -170
- package/.claude/agents/core/researcher.md +0 -197
- package/.claude/agents/core/reviewer.md +0 -327
- package/.claude/agents/core/tester.md +0 -318
- package/.claude/agents/design/design-monodesign.md +0 -121
- package/.claude/agents/engineering/engineering-ai-data-remediation-engineer.md +0 -212
- package/.claude/agents/engineering/engineering-ai-engineer.md +0 -165
- package/.claude/agents/engineering/engineering-autonomous-optimization-architect.md +0 -108
- package/.claude/agents/engineering/engineering-backend-architect.md +0 -254
- package/.claude/agents/engineering/engineering-code-reviewer.md +0 -95
- package/.claude/agents/engineering/engineering-data-engineer.md +0 -307
- package/.claude/agents/engineering/engineering-database-optimizer.md +0 -200
- package/.claude/agents/engineering/engineering-devops-automator.md +0 -430
- package/.claude/agents/engineering/engineering-embedded-firmware-engineer.md +0 -174
- package/.claude/agents/engineering/engineering-feishu-integration-developer.md +0 -607
- package/.claude/agents/engineering/engineering-frontend-developer.md +0 -249
- package/.claude/agents/engineering/engineering-git-workflow-master.md +0 -108
- package/.claude/agents/engineering/engineering-incident-response-commander.md +0 -482
- package/.claude/agents/engineering/engineering-mobile-app-builder.md +0 -499
- package/.claude/agents/engineering/engineering-rapid-prototyper.md +0 -463
- package/.claude/agents/engineering/engineering-security-engineer.md +0 -303
- package/.claude/agents/engineering/engineering-senior-developer.md +0 -195
- package/.claude/agents/engineering/engineering-software-architect.md +0 -100
- package/.claude/agents/engineering/engineering-solidity-smart-contract-engineer.md +0 -528
- package/.claude/agents/engineering/engineering-sre.md +0 -114
- package/.claude/agents/engineering/engineering-technical-writer.md +0 -412
- package/.claude/agents/engineering/engineering-threat-detection-engineer.md +0 -540
- package/.claude/agents/engineering/engineering-wechat-mini-program-developer.md +0 -351
- package/.claude/agents/generated/case-analyst.md +0 -50
- package/.claude/agents/generated/channel-intelligence-director.md +0 -87
- package/.claude/agents/generated/chief-growth-officer.md +0 -88
- package/.claude/agents/generated/churn-analyst.md +0 -53
- package/.claude/agents/generated/code-reviewer.md +0 -55
- package/.claude/agents/generated/code-validator.md +0 -57
- package/.claude/agents/generated/complexity-scanner.md +0 -56
- package/.claude/agents/generated/content-seo-strategist.md +0 -90
- package/.claude/agents/generated/copy-editor.md +0 -45
- package/.claude/agents/generated/court-reporter.md +0 -50
- package/.claude/agents/generated/defender.md +0 -51
- package/.claude/agents/generated/devbot-orchestrator.md +0 -58
- package/.claude/agents/generated/devbot-planner.md +0 -63
- package/.claude/agents/generated/developer-community-strategist.md +0 -91
- package/.claude/agents/generated/editor-in-chief.md +0 -45
- package/.claude/agents/generated/fact-checker.md +0 -45
- package/.claude/agents/generated/impact-assessor.md +0 -54
- package/.claude/agents/generated/judge.md +0 -51
- package/.claude/agents/generated/outreach-partnership-strategist.md +0 -90
- package/.claude/agents/generated/prosecutor.md +0 -51
- package/.claude/agents/generated/reporter.md +0 -45
- package/.claude/agents/generated/social-media-strategist.md +0 -91
- package/.claude/agents/generated/video-visual-strategist.md +0 -90
- package/.claude/agents/github/code-review-swarm.md +0 -557
- package/.claude/agents/github/github-modes.md +0 -154
- package/.claude/agents/github/issue-tracker.md +0 -299
- package/.claude/agents/github/multi-repo-swarm.md +0 -525
- package/.claude/agents/github/pr-manager.md +0 -163
- package/.claude/agents/github/project-board-sync.md +0 -478
- package/.claude/agents/github/release-manager.md +0 -296
- package/.claude/agents/github/repo-architect.md +0 -359
- package/.claude/agents/github/swarm-issue.md +0 -548
- package/.claude/agents/github/swarm-pr.md +0 -427
- package/.claude/agents/github/sync-coordinator.md +0 -355
- package/.claude/agents/github/workflow-automation.md +0 -640
- package/.claude/agents/goal/goal-planner.md +0 -168
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +0 -129
- package/.claude/agents/hive-mind/queen-coordinator.md +0 -202
- package/.claude/agents/hive-mind/scout-explorer.md +0 -241
- package/.claude/agents/hive-mind/swarm-memory-manager.md +0 -192
- package/.claude/agents/hive-mind/worker-specialist.md +0 -216
- package/.claude/agents/marketing/marketing-competitive-content.md +0 -155
- package/.claude/agents/marketing/marketing-cro-specialist.md +0 -147
- package/.claude/agents/marketing/marketing-email-specialist.md +0 -90
- package/.claude/agents/marketing/marketing-launch-strategist.md +0 -129
- package/.claude/agents/marketing/marketing-pricing-strategist.md +0 -127
- package/.claude/agents/optimization/benchmark-suite.md +0 -665
- package/.claude/agents/optimization/load-balancer.md +0 -431
- package/.claude/agents/optimization/performance-monitor.md +0 -672
- package/.claude/agents/optimization/resource-allocator.md +0 -674
- package/.claude/agents/optimization/topology-optimizer.md +0 -808
- package/.claude/agents/reengineer-squad/boss.md +0 -113
- package/.claude/agents/reengineer-squad/critic-architect.md +0 -132
- package/.claude/agents/reengineer-squad/git-manager.md +0 -145
- package/.claude/agents/reengineer-squad/idea-generator.md +0 -95
- package/.claude/agents/reengineer-squad/implementer.md +0 -112
- package/.claude/agents/reengineer-squad/integration-planner.md +0 -112
- package/.claude/agents/reengineer-squad/source-analyst.md +0 -103
- package/.claude/agents/reengineer-squad/target-analyst.md +0 -118
- package/.claude/agents/reengineer-squad/tester.md +0 -105
- package/.claude/agents/schemas/architecture-output.json +0 -43
- package/.claude/agents/schemas/code-review-output.json +0 -28
- package/.claude/agents/schemas/generic-task-input.json +0 -12
- package/.claude/agents/schemas/implementation-output.json +0 -18
- package/.claude/agents/schemas/research-output.json +0 -31
- package/.claude/agents/schemas/security-audit-output.json +0 -29
- package/.claude/agents/schemas/test-report-output.json +0 -29
- package/.claude/agents/sparc/architecture.md +0 -453
- package/.claude/agents/sparc/pseudocode.md +0 -299
- package/.claude/agents/sparc/refinement.md +0 -504
- package/.claude/agents/sparc/specification.md +0 -258
- package/.claude/agents/specialists/integration-architect.md +0 -94
- package/.claude/agents/specialized/agentic-identity-trust.md +0 -388
- package/.claude/agents/specialized/agents-orchestrator.md +0 -368
- package/.claude/agents/specialized/automation-governance-architect.md +0 -217
- package/.claude/agents/specialized/blockchain-security-auditor.md +0 -497
- package/.claude/agents/specialized/compliance-auditor.md +0 -159
- package/.claude/agents/specialized/identity-graph-operator.md +0 -261
- package/.claude/agents/specialized/lsp-index-engineer.md +0 -315
- package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +0 -89
- package/.claude/agents/specialized/specialized-cultural-intelligence-strategist.md +0 -89
- package/.claude/agents/specialized/specialized-developer-advocate.md +0 -318
- package/.claude/agents/specialized/specialized-document-generator.md +0 -56
- package/.claude/agents/specialized/specialized-mcp-builder.md +0 -64
- package/.claude/agents/specialized/specialized-model-qa.md +0 -489
- package/.claude/agents/specialized/specialized-workflow-architect.md +0 -595
- package/.claude/agents/specialized/zk-steward.md +0 -212
- package/.claude/agents/swarm/mesh-coordinator.md +0 -363
- package/.claude/agents/templates/automation-smart-agent.md +0 -185
- package/.claude/agents/templates/coordinator-swarm-init.md +0 -83
- package/.claude/agents/templates/implementer-sparc-coder.md +0 -231
- package/.claude/agents/testing/production-validator.md +0 -375
- package/.claude/agents/testing/tdd-london-swarm.md +0 -241
- package/.claude/agents/testing/testing-accessibility-auditor.md +0 -322
- package/.claude/agents/testing/testing-api-tester.md +0 -307
- package/.claude/agents/testing/testing-evidence-collector.md +0 -213
- package/.claude/agents/testing/testing-performance-benchmarker.md +0 -269
- package/.claude/agents/testing/testing-test-results-analyzer.md +0 -306
- package/.claude/agents/testing/testing-tool-evaluator.md +0 -395
- package/.claude/agents/testing/testing-workflow-optimizer.md +0 -451
- package/.claude/commands/agents/README.md +0 -14
- package/.claude/commands/agents/agent-capabilities.md +0 -25
- package/.claude/commands/agents/agent-coordination.md +0 -32
- package/.claude/commands/agents/agent-spawning.md +0 -32
- package/.claude/commands/agents/agent-types.md +0 -30
- package/.claude/commands/analysis/README.md +0 -18
- package/.claude/commands/analysis/bottleneck-detect.md +0 -69
- package/.claude/commands/analysis/performance-bottlenecks.md +0 -59
- package/.claude/commands/analysis/performance-report.md +0 -52
- package/.claude/commands/analysis/token-usage.md +0 -47
- package/.claude/commands/automation/README.md +0 -19
- package/.claude/commands/automation/auto-agent.md +0 -86
- package/.claude/commands/automation/self-healing.md +0 -108
- package/.claude/commands/automation/session-memory.md +0 -89
- package/.claude/commands/automation/smart-agents.md +0 -81
- package/.claude/commands/automation/smart-spawn.md +0 -66
- package/.claude/commands/automation/workflow-select.md +0 -60
- package/.claude/commands/coordination/README.md +0 -13
- package/.claude/commands/coordination/agent-spawn.md +0 -69
- package/.claude/commands/coordination/swarm-init.md +0 -82
- package/.claude/commands/coordination/task-orchestrate.md +0 -79
- package/.claude/commands/github/README.md +0 -24
- package/.claude/commands/github/github-modes.md +0 -151
- package/.claude/commands/github/issue-tracker.md +0 -293
- package/.claude/commands/github/pr-manager.md +0 -173
- package/.claude/commands/github/release-manager.md +0 -343
- package/.claude/commands/github/repo-architect.md +0 -379
- package/.claude/commands/github/sync-coordinator.md +0 -297
- package/.claude/commands/hive-mind/README.md +0 -42
- package/.claude/commands/hive-mind/hive-mind-consensus.md +0 -72
- package/.claude/commands/hive-mind/hive-mind-init.md +0 -68
- package/.claude/commands/hive-mind/hive-mind-memory.md +0 -73
- package/.claude/commands/hive-mind/hive-mind-spawn.md +0 -82
- package/.claude/commands/hive-mind/hive-mind-status.md +0 -56
- package/.claude/commands/hive-mind/hive-mind-stop.md +0 -55
- package/.claude/commands/hive-mind/hive-mind.md +0 -87
- package/.claude/commands/hooks/README.md +0 -66
- package/.claude/commands/hooks/overview.md +0 -112
- package/.claude/commands/hooks/post-edit.md +0 -78
- package/.claude/commands/hooks/post-task.md +0 -62
- package/.claude/commands/hooks/pre-edit.md +0 -81
- package/.claude/commands/hooks/pre-task.md +0 -73
- package/.claude/commands/hooks/session-end.md +0 -82
- package/.claude/commands/hooks/setup.md +0 -132
- package/.claude/commands/mastermind/_repeat.md +0 -492
- package/.claude/commands/mastermind/_taskfile.md +0 -232
- package/.claude/commands/mastermind/adr.md +0 -9
- package/.claude/commands/mastermind/approve.md +0 -91
- package/.claude/commands/mastermind/architect.md +0 -52
- package/.claude/commands/mastermind/autodev.md +0 -28
- package/.claude/commands/mastermind/brain.md +0 -99
- package/.claude/commands/mastermind/budget.md +0 -5
- package/.claude/commands/mastermind/build.md +0 -23
- package/.claude/commands/mastermind/code-review.md +0 -314
- package/.claude/commands/mastermind/content.md +0 -23
- package/.claude/commands/mastermind/createorg.md +0 -136
- package/.claude/commands/mastermind/createtask.md +0 -372
- package/.claude/commands/mastermind/debug.md +0 -19
- package/.claude/commands/mastermind/design.md +0 -17
- package/.claude/commands/mastermind/do.md +0 -525
- package/.claude/commands/mastermind/execute.md +0 -17
- package/.claude/commands/mastermind/finance.md +0 -23
- package/.claude/commands/mastermind/finish.md +0 -17
- package/.claude/commands/mastermind/graph-status.md +0 -5
- package/.claude/commands/mastermind/help.md +0 -115
- package/.claude/commands/mastermind/idea.md +0 -23
- package/.claude/commands/mastermind/ideate.md +0 -258
- package/.claude/commands/mastermind/improve.md +0 -342
- package/.claude/commands/mastermind/loops.md +0 -5
- package/.claude/commands/mastermind/marketing.md +0 -23
- package/.claude/commands/mastermind/master.md +0 -1124
- package/.claude/commands/mastermind/memory.md +0 -227
- package/.claude/commands/mastermind/okf-export.md +0 -14
- package/.claude/commands/mastermind/okf-import.md +0 -15
- package/.claude/commands/mastermind/ops.md +0 -23
- package/.claude/commands/mastermind/orgs.md +0 -18
- package/.claude/commands/mastermind/orgstatus.md +0 -56
- package/.claude/commands/mastermind/plan.md +0 -23
- package/.claude/commands/mastermind/receive-review.md +0 -17
- package/.claude/commands/mastermind/references/antigravity-tools.md +0 -60
- package/.claude/commands/mastermind/references/claude-code-tools.md +0 -50
- package/.claude/commands/mastermind/references/codex-tools.md +0 -64
- package/.claude/commands/mastermind/references/copilot-tools.md +0 -49
- package/.claude/commands/mastermind/references/gemini-tools.md +0 -63
- package/.claude/commands/mastermind/references/pi-tools.md +0 -28
- package/.claude/commands/mastermind/release.md +0 -23
- package/.claude/commands/mastermind/repeat.md +0 -254
- package/.claude/commands/mastermind/research.md +0 -23
- package/.claude/commands/mastermind/review.md +0 -34
- package/.claude/commands/mastermind/runorg.md +0 -153
- package/.claude/commands/mastermind/sales.md +0 -23
- package/.claude/commands/mastermind/skill-builder.md +0 -17
- package/.claude/commands/mastermind/specialagents.md +0 -122
- package/.claude/commands/mastermind/stoporg.md +0 -75
- package/.claude/commands/mastermind/swarm.md +0 -158
- package/.claude/commands/mastermind/taskdev.md +0 -23
- package/.claude/commands/mastermind/tdd.md +0 -19
- package/.claude/commands/mastermind/techport.md +0 -27
- package/.claude/commands/mastermind/understand.md +0 -136
- package/.claude/commands/mastermind/verify.md +0 -19
- package/.claude/commands/mastermind/worktree.md +0 -17
- package/.claude/commands/mastermind.md +0 -121
- package/.claude/commands/memory/README.md +0 -79
- package/.claude/commands/memory/memory-search.md +0 -77
- package/.claude/commands/monitoring/README.md +0 -69
- package/.claude/commands/monitoring/agent-metrics.md +0 -65
- package/.claude/commands/monitoring/agents.md +0 -71
- package/.claude/commands/monitoring/status.md +0 -108
- package/.claude/commands/monobrowse.md +0 -21
- package/.claude/commands/monoes/README.md +0 -30
- package/.claude/commands/monoes/install.md +0 -163
- package/.claude/commands/monoes/monoagent.md +0 -148
- package/.claude/commands/monoes/monoclip.md +0 -64
- package/.claude/commands/monoes/monotask.md +0 -137
- package/.claude/commands/monograph/README.md +0 -102
- package/.claude/commands/monograph/monograph-build.md +0 -79
- package/.claude/commands/monograph/monograph-search.md +0 -96
- package/.claude/commands/monograph/monograph-stats.md +0 -53
- package/.claude/commands/monograph/monograph-watch.md +0 -63
- package/.claude/commands/monograph/monograph-wiki.md +0 -91
- package/.claude/commands/optimization/auto-topology.md +0 -85
- package/.claude/commands/optimization/performance-optimize.md +0 -79
- package/.claude/commands/pair/README.md +0 -79
- package/.claude/commands/pair/examples.md +0 -156
- package/.claude/commands/pair/modes.md +0 -122
- package/.claude/commands/pair/session.md +0 -124
- package/.claude/commands/sparc/analyzer.md +0 -35
- package/.claude/commands/sparc/architect.md +0 -36
- package/.claude/commands/sparc/ask.md +0 -56
- package/.claude/commands/sparc/batch-executor.md +0 -37
- package/.claude/commands/sparc/code.md +0 -48
- package/.claude/commands/sparc/coder.md +0 -37
- package/.claude/commands/sparc/debug.md +0 -42
- package/.claude/commands/sparc/debugger.md +0 -37
- package/.claude/commands/sparc/designer.md +0 -36
- package/.claude/commands/sparc/devops.md +0 -68
- package/.claude/commands/sparc/docs-writer.md +0 -39
- package/.claude/commands/sparc/documenter.md +0 -37
- package/.claude/commands/sparc/innovator.md +0 -37
- package/.claude/commands/sparc/integration.md +0 -42
- package/.claude/commands/sparc/mcp.md +0 -76
- package/.claude/commands/sparc/memory-manager.md +0 -57
- package/.claude/commands/sparc/optimizer.md +0 -37
- package/.claude/commands/sparc/orchestrator.md +0 -70
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +0 -42
- package/.claude/commands/sparc/refinement-optimization-mode.md +0 -42
- package/.claude/commands/sparc/researcher.md +0 -37
- package/.claude/commands/sparc/reviewer.md +0 -37
- package/.claude/commands/sparc/security-review.md +0 -39
- package/.claude/commands/sparc/sparc-modes.md +0 -120
- package/.claude/commands/sparc/sparc.md +0 -71
- package/.claude/commands/sparc/spec-pseudocode.md +0 -39
- package/.claude/commands/sparc/supabase-admin.md +0 -301
- package/.claude/commands/sparc/swarm-coordinator.md +0 -50
- package/.claude/commands/sparc/tdd.md +0 -37
- package/.claude/commands/sparc/tester.md +0 -37
- package/.claude/commands/sparc/tutorial.md +0 -38
- package/.claude/commands/sparc/workflow-manager.md +0 -37
- package/.claude/commands/sparc.md +0 -112
- package/.claude/commands/stream-chain/pipeline.md +0 -116
- package/.claude/commands/stream-chain/run.md +0 -156
- package/.claude/commands/swarm/README.md +0 -40
- package/.claude/commands/swarm/analysis.md +0 -73
- package/.claude/commands/swarm/development.md +0 -72
- package/.claude/commands/swarm/examples.md +0 -103
- package/.claude/commands/swarm/maintenance.md +0 -75
- package/.claude/commands/swarm/optimization.md +0 -84
- package/.claude/commands/swarm/research.md +0 -76
- package/.claude/commands/swarm/swarm.md +0 -79
- package/.claude/commands/swarm/testing.md +0 -80
- package/.claude/commands/tokens.md +0 -18
- package/.claude/commands/truth/start.md +0 -121
- package/.claude/commands/ts.md +0 -14
- package/.claude/commands/workflows/README.md +0 -65
- package/.claude/commands/workflows/development.md +0 -86
- package/.claude/commands/workflows/research.md +0 -89
- package/.claude/commands/workflows/workflow-create.md +0 -84
- package/.claude/commands/workflows/workflow-execute.md +0 -103
- package/.claude/commands/workflows/workflow-export.md +0 -90
- package/.claude/helpers/control-start.cjs +0 -184
- package/.claude/helpers/event-logger.cjs +0 -155
- package/.claude/helpers/extras-registry.json +0 -5141
- package/.claude/helpers/graphify-freshen.cjs +0 -140
- package/.claude/helpers/handlers/adr-draft-handler.cjs +0 -78
- package/.claude/helpers/handlers/agent-start-handler.cjs +0 -83
- package/.claude/helpers/handlers/budget-status-handler.cjs +0 -14
- package/.claude/helpers/handlers/capture-handler.cjs +0 -583
- package/.claude/helpers/handlers/compact-handler.cjs +0 -35
- package/.claude/helpers/handlers/edit-handler.cjs +0 -145
- package/.claude/helpers/handlers/gates-handler.cjs +0 -138
- package/.claude/helpers/handlers/graph-status-handler.cjs +0 -45
- package/.claude/helpers/handlers/loops-status-handler.cjs +0 -48
- package/.claude/helpers/handlers/route-handler.cjs +0 -381
- package/.claude/helpers/handlers/session-handler.cjs +0 -234
- package/.claude/helpers/handlers/session-restore-handler.cjs +0 -375
- package/.claude/helpers/handlers/stats-handler.cjs +0 -14
- package/.claude/helpers/handlers/task-handler.cjs +0 -206
- package/.claude/helpers/hook-handler.cjs +0 -765
- package/.claude/helpers/intelligence.cjs +0 -338
- package/.claude/helpers/learning-service.mjs +0 -61
- package/.claude/helpers/loop-tracker.cjs +0 -119
- package/.claude/helpers/mastermind-activate.cjs +0 -35
- package/.claude/helpers/memory-palace.cjs +0 -461
- package/.claude/helpers/memory.cjs +0 -193
- package/.claude/helpers/metrics-db.mjs +0 -87
- package/.claude/helpers/monolean-activate.cjs +0 -30
- package/.claude/helpers/monolean-config.cjs +0 -76
- package/.claude/helpers/monolean-instructions.cjs +0 -109
- package/.claude/helpers/monolean-propagate.cjs +0 -13
- package/.claude/helpers/monolean-tracker.cjs +0 -18
- package/.claude/helpers/router.cjs +0 -364
- package/.claude/helpers/session.cjs +0 -140
- package/.claude/helpers/skill-registry.json +0 -1043
- package/.claude/helpers/statusline.cjs +0 -1344
- package/.claude/helpers/toggle-statusline.cjs +0 -73
- package/.claude/helpers/token-tracker.cjs +0 -934
- package/.claude/helpers/utils/micro-agents.cjs +0 -354
- package/.claude/helpers/utils/monograph.cjs +0 -480
- package/.claude/helpers/utils/telemetry.cjs +0 -146
- package/.claude/mcp.json +0 -3
- package/.claude/scheduled_tasks.lock +0 -1
- package/.claude/settings.json +0 -475
- package/.claude/skills/.monomind/data/ranked-context.json +0 -5
- package/.claude/skills/.monomind/sessions/current.json +0 -13
- package/.claude/skills/.monomind/sessions/session-1777829336455.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777831614725.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777832095857.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777839814183.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777841847131.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777843309463.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777880867159.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777881884593.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777884090471.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777884808221.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777885672155.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777886852818.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777896532690.json +0 -15
- package/.claude/skills/agent-browser-testing/SKILL.md +0 -964
- package/.claude/skills/agentic-jujutsu/SKILL.md +0 -645
- package/.claude/skills/github-issue-triage/SKILL.md +0 -354
- package/.claude/skills/github-repo-recap/SKILL.md +0 -207
- package/.claude/skills/hive-mind-advanced/SKILL.md +0 -709
- package/.claude/skills/hooks-automation/SKILL.md +0 -1193
- package/.claude/skills/mastermind-skills/_agent-select.md +0 -132
- package/.claude/skills/mastermind-skills/_delegation.md +0 -83
- package/.claude/skills/mastermind-skills/_intake.md +0 -83
- package/.claude/skills/mastermind-skills/_protocol.md +0 -404
- package/.claude/skills/mastermind-skills/_repeat.md +0 -171
- package/.claude/skills/mastermind-skills/access.md +0 -236
- package/.claude/skills/mastermind-skills/activity.md +0 -191
- package/.claude/skills/mastermind-skills/adapter-manager.md +0 -259
- package/.claude/skills/mastermind-skills/adapters.md +0 -204
- package/.claude/skills/mastermind-skills/agent-detail.md +0 -242
- package/.claude/skills/mastermind-skills/agents.md +0 -178
- package/.claude/skills/mastermind-skills/approval-detail.md +0 -259
- package/.claude/skills/mastermind-skills/approve.md +0 -188
- package/.claude/skills/mastermind-skills/architect.md +0 -862
- package/.claude/skills/mastermind-skills/autodev.md +0 -360
- package/.claude/skills/mastermind-skills/backup.md +0 -197
- package/.claude/skills/mastermind-skills/bootstrap.md +0 -190
- package/.claude/skills/mastermind-skills/budgets.md +0 -237
- package/.claude/skills/mastermind-skills/build.md +0 -170
- package/.claude/skills/mastermind-skills/code-quality-reviewer-prompt.md +0 -60
- package/.claude/skills/mastermind-skills/companies.md +0 -256
- package/.claude/skills/mastermind-skills/content.md +0 -197
- package/.claude/skills/mastermind-skills/costs.md +0 -151
- package/.claude/skills/mastermind-skills/createorg.md +0 -862
- package/.claude/skills/mastermind-skills/debug.md +0 -232
- package/.claude/skills/mastermind-skills/design.md +0 -189
- package/.claude/skills/mastermind-skills/diagnose.md +0 -249
- package/.claude/skills/mastermind-skills/env.md +0 -198
- package/.claude/skills/mastermind-skills/environments.md +0 -250
- package/.claude/skills/mastermind-skills/execute.md +0 -104
- package/.claude/skills/mastermind-skills/export.md +0 -333
- package/.claude/skills/mastermind-skills/finance.md +0 -166
- package/.claude/skills/mastermind-skills/finish.md +0 -251
- package/.claude/skills/mastermind-skills/goal-detail.md +0 -255
- package/.claude/skills/mastermind-skills/goals.md +0 -149
- package/.claude/skills/mastermind-skills/heartbeat.md +0 -164
- package/.claude/skills/mastermind-skills/idea.md +0 -1142
- package/.claude/skills/mastermind-skills/implementer-prompt.md +0 -109
- package/.claude/skills/mastermind-skills/import.md +0 -281
- package/.claude/skills/mastermind-skills/inbox.md +0 -214
- package/.claude/skills/mastermind-skills/instance-settings.md +0 -315
- package/.claude/skills/mastermind-skills/instance.md +0 -233
- package/.claude/skills/mastermind-skills/invite-landing.md +0 -227
- package/.claude/skills/mastermind-skills/invites.md +0 -254
- package/.claude/skills/mastermind-skills/issue-detail.md +0 -291
- package/.claude/skills/mastermind-skills/issues.md +0 -235
- package/.claude/skills/mastermind-skills/join-queue.md +0 -170
- package/.claude/skills/mastermind-skills/liveness.md +0 -392
- package/.claude/skills/mastermind-skills/marketing.md +0 -228
- package/.claude/skills/mastermind-skills/memory.md +0 -321
- package/.claude/skills/mastermind-skills/monitor.md +0 -1284
- package/.claude/skills/mastermind-skills/monotask.md +0 -350
- package/.claude/skills/mastermind-skills/my-issues.md +0 -146
- package/.claude/skills/mastermind-skills/new-agent.md +0 -241
- package/.claude/skills/mastermind-skills/ops.md +0 -168
- package/.claude/skills/mastermind-skills/org-chart.md +0 -209
- package/.claude/skills/mastermind-skills/org-settings.md +0 -254
- package/.claude/skills/mastermind-skills/orgs.md +0 -98
- package/.claude/skills/mastermind-skills/orgstatus.md +0 -194
- package/.claude/skills/mastermind-skills/plan-to-tasks.md +0 -136
- package/.claude/skills/mastermind-skills/plan.md +0 -198
- package/.claude/skills/mastermind-skills/plugin-manager.md +0 -241
- package/.claude/skills/mastermind-skills/plugin-settings.md +0 -273
- package/.claude/skills/mastermind-skills/plugins.md +0 -190
- package/.claude/skills/mastermind-skills/profile.md +0 -187
- package/.claude/skills/mastermind-skills/project-detail.md +0 -249
- package/.claude/skills/mastermind-skills/project-workspace.md +0 -244
- package/.claude/skills/mastermind-skills/projects.md +0 -164
- package/.claude/skills/mastermind-skills/receive-review.md +0 -213
- package/.claude/skills/mastermind-skills/references/copywriting-frameworks.md +0 -181
- package/.claude/skills/mastermind-skills/references/persuasion-psychology.md +0 -158
- package/.claude/skills/mastermind-skills/release.md +0 -168
- package/.claude/skills/mastermind-skills/research.md +0 -168
- package/.claude/skills/mastermind-skills/review.md +0 -233
- package/.claude/skills/mastermind-skills/routine-detail.md +0 -253
- package/.claude/skills/mastermind-skills/routines.md +0 -203
- package/.claude/skills/mastermind-skills/runorg.md +0 -714
- package/.claude/skills/mastermind-skills/sales.md +0 -170
- package/.claude/skills/mastermind-skills/search.md +0 -186
- package/.claude/skills/mastermind-skills/secrets.md +0 -199
- package/.claude/skills/mastermind-skills/skill-builder.md +0 -274
- package/.claude/skills/mastermind-skills/skills.md +0 -156
- package/.claude/skills/mastermind-skills/spec-reviewer-prompt.md +0 -63
- package/.claude/skills/mastermind-skills/stoporg.md +0 -138
- package/.claude/skills/mastermind-skills/taskdev.md +0 -307
- package/.claude/skills/mastermind-skills/tasks.md +0 -149
- package/.claude/skills/mastermind-skills/tdd.md +0 -394
- package/.claude/skills/mastermind-skills/techport.md +0 -777
- package/.claude/skills/mastermind-skills/threads.md +0 -259
- package/.claude/skills/mastermind-skills/tree-control.md +0 -250
- package/.claude/skills/mastermind-skills/verify.md +0 -196
- package/.claude/skills/mastermind-skills/wiki.md +0 -314
- package/.claude/skills/mastermind-skills/workspace-detail.md +0 -317
- package/.claude/skills/mastermind-skills/workspaces.md +0 -261
- package/.claude/skills/mastermind-skills/worktree.md +0 -215
- package/.claude/skills/monodesign/SKILL.md +0 -333
- package/.claude/skills/monodesign/adapt.md +0 -53
- package/.claude/skills/monodesign/agents/monodesign-asset-producer.md +0 -100
- package/.claude/skills/monodesign/animate.md +0 -65
- package/.claude/skills/monodesign/audit.md +0 -89
- package/.claude/skills/monodesign/bolder.md +0 -50
- package/.claude/skills/monodesign/clarify.md +0 -64
- package/.claude/skills/monodesign/colorize.md +0 -68
- package/.claude/skills/monodesign/craft.md +0 -51
- package/.claude/skills/monodesign/critique.md +0 -66
- package/.claude/skills/monodesign/delight.md +0 -47
- package/.claude/skills/monodesign/distill.md +0 -56
- package/.claude/skills/monodesign/document.md +0 -83
- package/.claude/skills/monodesign/extract.md +0 -74
- package/.claude/skills/monodesign/harden.md +0 -65
- package/.claude/skills/monodesign/live.md +0 -59
- package/.claude/skills/monodesign/onboard.md +0 -50
- package/.claude/skills/monodesign/optimize.md +0 -64
- package/.claude/skills/monodesign/overdrive.md +0 -56
- package/.claude/skills/monodesign/polish.md +0 -68
- package/.claude/skills/monodesign/quieter.md +0 -57
- package/.claude/skills/monodesign/reference/adapt.md +0 -190
- package/.claude/skills/monodesign/reference/animate.md +0 -175
- package/.claude/skills/monodesign/reference/antipatterns-catalog.md +0 -359
- package/.claude/skills/monodesign/reference/audit.md +0 -133
- package/.claude/skills/monodesign/reference/bolder.md +0 -113
- package/.claude/skills/monodesign/reference/brand-workflow.md +0 -180
- package/.claude/skills/monodesign/reference/brand.md +0 -114
- package/.claude/skills/monodesign/reference/clarify.md +0 -174
- package/.claude/skills/monodesign/reference/codex.md +0 -107
- package/.claude/skills/monodesign/reference/cognitive-load.md +0 -106
- package/.claude/skills/monodesign/reference/color-and-contrast.md +0 -105
- package/.claude/skills/monodesign/reference/colorize.md +0 -154
- package/.claude/skills/monodesign/reference/component-specs.md +0 -260
- package/.claude/skills/monodesign/reference/component-states.md +0 -274
- package/.claude/skills/monodesign/reference/component-system.md +0 -358
- package/.claude/skills/monodesign/reference/copy-formulas.md +0 -160
- package/.claude/skills/monodesign/reference/craft.md +0 -196
- package/.claude/skills/monodesign/reference/critique.md +0 -213
- package/.claude/skills/monodesign/reference/delight.md +0 -302
- package/.claude/skills/monodesign/reference/design-principles.md +0 -246
- package/.claude/skills/monodesign/reference/distill.md +0 -111
- package/.claude/skills/monodesign/reference/document.md +0 -427
- package/.claude/skills/monodesign/reference/extract.md +0 -69
- package/.claude/skills/monodesign/reference/harden.md +0 -347
- package/.claude/skills/monodesign/reference/heuristics-scoring.md +0 -234
- package/.claude/skills/monodesign/reference/hooks.md +0 -99
- package/.claude/skills/monodesign/reference/image-prompts.md +0 -130
- package/.claude/skills/monodesign/reference/interaction-design.md +0 -195
- package/.claude/skills/monodesign/reference/layout.md +0 -141
- package/.claude/skills/monodesign/reference/live.md +0 -622
- package/.claude/skills/monodesign/reference/motion-design.md +0 -109
- package/.claude/skills/monodesign/reference/onboard.md +0 -234
- package/.claude/skills/monodesign/reference/optimize.md +0 -258
- package/.claude/skills/monodesign/reference/overdrive.md +0 -130
- package/.claude/skills/monodesign/reference/personas.md +0 -179
- package/.claude/skills/monodesign/reference/polish.md +0 -233
- package/.claude/skills/monodesign/reference/pre-delivery-checklist.md +0 -108
- package/.claude/skills/monodesign/reference/product.md +0 -62
- package/.claude/skills/monodesign/reference/quieter.md +0 -99
- package/.claude/skills/monodesign/reference/responsive-design.md +0 -114
- package/.claude/skills/monodesign/reference/shape.md +0 -151
- package/.claude/skills/monodesign/reference/spatial-design.md +0 -100
- package/.claude/skills/monodesign/reference/teach.md +0 -156
- package/.claude/skills/monodesign/reference/token-architecture.md +0 -222
- package/.claude/skills/monodesign/reference/typeset.md +0 -124
- package/.claude/skills/monodesign/reference/typography.md +0 -159
- package/.claude/skills/monodesign/reference/ux-research.md +0 -143
- package/.claude/skills/monodesign/reference/ux-rules.md +0 -211
- package/.claude/skills/monodesign/reference/ux-writing.md +0 -107
- package/.claude/skills/monodesign/shape.md +0 -71
- package/.claude/skills/monodesign/teach.md +0 -69
- package/.claude/skills/monodesign/typeset.md +0 -59
- package/.claude/skills/monolean/SKILL.md +0 -118
- package/.claude/skills/monolean-audit/SKILL.md +0 -41
- package/.claude/skills/monolean-debt/SKILL.md +0 -46
- package/.claude/skills/monolean-help/SKILL.md +0 -60
- package/.claude/skills/monolean-review/SKILL.md +0 -57
- package/.claude/skills/monomind/.monomind/registry.json +0 -6
- package/.claude/skills/monomind/browse-agentcore.md +0 -115
- package/.claude/skills/monomind/browse-electron.md +0 -188
- package/.claude/skills/monomind/browse-qa.md +0 -228
- package/.claude/skills/monomind/browse-references/authentication.md +0 -161
- package/.claude/skills/monomind/browse-references/trust-boundaries.md +0 -40
- package/.claude/skills/monomind/browse-references/video-recording.md +0 -83
- package/.claude/skills/monomind/browse-slack.md +0 -188
- package/.claude/skills/monomind/browse-vercel.md +0 -239
- package/.claude/skills/monomind/browse.md +0 -724
- package/.claude/skills/monomotion/SKILL.md +0 -145
- package/.claude/skills/monomotion/rules/api-control.md +0 -139
- package/.claude/skills/monomotion/rules/effects.md +0 -109
- package/.claude/skills/monomotion/rules/integration.md +0 -140
- package/.claude/skills/monomotion/rules/scroll.md +0 -131
- package/.claude/skills/monomotion/rules/sequencing.md +0 -105
- package/.claude/skills/monomotion/rules/svg.md +0 -101
- package/.claude/skills/monomotion/rules/text.md +0 -119
- package/.claude/skills/pair-programming/SKILL.md +0 -1202
- package/.claude/skills/performance-analysis/SKILL.md +0 -560
- package/.claude/skills/skill-builder/SKILL.md +0 -910
- package/.claude/skills/sparc-methodology/SKILL.md +0 -950
- package/.claude/skills/specialagent/SKILL.md +0 -208
- package/.claude/skills/stop-slop/SKILL.md +0 -67
- package/.claude/skills/stop-slop/references/examples.md +0 -61
- package/.claude/skills/stop-slop/references/phrases.md +0 -130
- package/.claude/skills/stop-slop/references/structures.md +0 -136
- package/.claude/skills/swarm-advanced/SKILL.md +0 -937
- package/.claude/skills/swarm-orchestration/SKILL.md +0 -179
- package/.claude/skills/verification-quality/SKILL.md +0 -674
- package/.claude/workflows/feature-dev.yaml +0 -18
- package/.claude/workflows/security-audit.yaml +0 -10
- package/packages/@monomind/cli/.claude/agents/generated/case-analyst.md +0 -50
- package/packages/@monomind/cli/.claude/agents/generated/channel-intelligence-director.md +0 -87
- package/packages/@monomind/cli/.claude/agents/generated/chief-growth-officer.md +0 -88
- package/packages/@monomind/cli/.claude/agents/generated/churn-analyst.md +0 -53
- package/packages/@monomind/cli/.claude/agents/generated/code-reviewer.md +0 -55
- package/packages/@monomind/cli/.claude/agents/generated/code-validator.md +0 -57
- package/packages/@monomind/cli/.claude/agents/generated/complexity-scanner.md +0 -56
- package/packages/@monomind/cli/.claude/agents/generated/content-seo-strategist.md +0 -90
- package/packages/@monomind/cli/.claude/agents/generated/copy-editor.md +0 -45
- package/packages/@monomind/cli/.claude/agents/generated/court-reporter.md +0 -50
- package/packages/@monomind/cli/.claude/agents/generated/defender.md +0 -51
- package/packages/@monomind/cli/.claude/agents/generated/devbot-orchestrator.md +0 -58
- package/packages/@monomind/cli/.claude/agents/generated/devbot-planner.md +0 -63
- package/packages/@monomind/cli/.claude/agents/generated/developer-community-strategist.md +0 -91
- package/packages/@monomind/cli/.claude/agents/generated/editor-in-chief.md +0 -45
- package/packages/@monomind/cli/.claude/agents/generated/fact-checker.md +0 -45
- package/packages/@monomind/cli/.claude/agents/generated/impact-assessor.md +0 -54
- package/packages/@monomind/cli/.claude/agents/generated/judge.md +0 -51
- package/packages/@monomind/cli/.claude/agents/generated/outreach-partnership-strategist.md +0 -90
- package/packages/@monomind/cli/.claude/agents/generated/prosecutor.md +0 -51
- package/packages/@monomind/cli/.claude/agents/generated/reporter.md +0 -45
- package/packages/@monomind/cli/.claude/agents/generated/social-media-strategist.md +0 -91
- package/packages/@monomind/cli/.claude/agents/generated/video-visual-strategist.md +0 -90
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/boss.md +0 -113
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/critic-architect.md +0 -132
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/git-manager.md +0 -145
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/idea-generator.md +0 -95
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/implementer.md +0 -112
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/integration-planner.md +0 -112
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/source-analyst.md +0 -103
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/target-analyst.md +0 -118
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/tester.md +0 -105
- package/packages/@monomind/cli/.claude/agents/sparc/architecture.md +0 -453
- package/packages/@monomind/cli/.claude/agents/sparc/pseudocode.md +0 -299
- package/packages/@monomind/cli/.claude/agents/sparc/refinement.md +0 -504
- package/packages/@monomind/cli/.claude/agents/sparc/specification.md +0 -258
- package/packages/@monomind/cli/.claude/agents/templates/implementer-sparc-coder.md +0 -231
- package/packages/@monomind/cli/.claude/commands/sparc/analyzer.md +0 -35
- package/packages/@monomind/cli/.claude/commands/sparc/architect.md +0 -36
- package/packages/@monomind/cli/.claude/commands/sparc/ask.md +0 -56
- package/packages/@monomind/cli/.claude/commands/sparc/batch-executor.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/code.md +0 -48
- package/packages/@monomind/cli/.claude/commands/sparc/coder.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/debug.md +0 -42
- package/packages/@monomind/cli/.claude/commands/sparc/debugger.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/designer.md +0 -36
- package/packages/@monomind/cli/.claude/commands/sparc/devops.md +0 -68
- package/packages/@monomind/cli/.claude/commands/sparc/docs-writer.md +0 -39
- package/packages/@monomind/cli/.claude/commands/sparc/documenter.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/innovator.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/integration.md +0 -42
- package/packages/@monomind/cli/.claude/commands/sparc/mcp.md +0 -76
- package/packages/@monomind/cli/.claude/commands/sparc/memory-manager.md +0 -57
- package/packages/@monomind/cli/.claude/commands/sparc/optimizer.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/orchestrator.md +0 -70
- package/packages/@monomind/cli/.claude/commands/sparc/post-deployment-monitoring-mode.md +0 -42
- package/packages/@monomind/cli/.claude/commands/sparc/refinement-optimization-mode.md +0 -42
- package/packages/@monomind/cli/.claude/commands/sparc/researcher.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/reviewer.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/security-review.md +0 -39
- package/packages/@monomind/cli/.claude/commands/sparc/sparc-modes.md +0 -120
- package/packages/@monomind/cli/.claude/commands/sparc/sparc.md +0 -71
- package/packages/@monomind/cli/.claude/commands/sparc/spec-pseudocode.md +0 -39
- package/packages/@monomind/cli/.claude/commands/sparc/supabase-admin.md +0 -301
- package/packages/@monomind/cli/.claude/commands/sparc/swarm-coordinator.md +0 -50
- package/packages/@monomind/cli/.claude/commands/sparc/tdd.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/tester.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc/tutorial.md +0 -38
- package/packages/@monomind/cli/.claude/commands/sparc/workflow-manager.md +0 -37
- package/packages/@monomind/cli/.claude/commands/sparc.md +0 -112
- package/packages/@monomind/cli/.claude/skills/sparc-methodology/SKILL.md +0 -950
- package/packages/@monomind/cli/dist/src/capabilities/enrichment.d.ts +0 -44
- package/packages/@monomind/cli/dist/src/capabilities/enrichment.js +0 -141
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +0 -14
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +0 -295
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +0 -14
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +0 -304
- package/packages/@monomind/cli/dist/src/commands/claims.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/commands/claims.js +0 -650
- package/packages/@monomind/cli/dist/src/commands/daemon.d.ts +0 -8
- package/packages/@monomind/cli/dist/src/commands/daemon.js +0 -681
- package/packages/@monomind/cli/dist/src/commands/enrich.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/commands/enrich.js +0 -58
- package/packages/@monomind/cli/dist/src/commands/issues.d.ts +0 -21
- package/packages/@monomind/cli/dist/src/commands/issues.js +0 -575
- package/packages/@monomind/cli/dist/src/commands/workflow.d.ts +0 -8
- package/packages/@monomind/cli/dist/src/commands/workflow.js +0 -575
- package/packages/@monomind/cli/dist/src/consensus/vote-signer.d.ts +0 -36
- package/packages/@monomind/cli/dist/src/consensus/vote-signer.js +0 -88
- package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.d.ts +0 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +0 -717
- package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +0 -198
- package/packages/@monomind/cli/dist/src/services/claim-service.js +0 -890
- package/packages/@monomind/cli/dist/src/services/headless-worker-executor.d.ts +0 -311
- package/packages/@monomind/cli/dist/src/services/headless-worker-executor.js +0 -1183
- package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +0 -230
- package/packages/@monomind/cli/dist/src/services/worker-daemon.js +0 -1350
- package/packages/@monomind/cli/dist/src/ui/.monomind/capture/active-run.json +0 -1
- package/packages/@monomind/guidance/README.md +0 -87
- package/packages/@monomind/guidance/dist/adversarial.d.ts +0 -284
- package/packages/@monomind/guidance/dist/adversarial.js +0 -572
- package/packages/@monomind/guidance/dist/analyzer.d.ts +0 -530
- package/packages/@monomind/guidance/dist/analyzer.js +0 -2518
- package/packages/@monomind/guidance/dist/artifacts.d.ts +0 -283
- package/packages/@monomind/guidance/dist/artifacts.js +0 -356
- package/packages/@monomind/guidance/dist/authority.d.ts +0 -290
- package/packages/@monomind/guidance/dist/authority.js +0 -558
- package/packages/@monomind/guidance/dist/capabilities.d.ts +0 -209
- package/packages/@monomind/guidance/dist/capabilities.js +0 -485
- package/packages/@monomind/guidance/dist/coherence.d.ts +0 -233
- package/packages/@monomind/guidance/dist/coherence.js +0 -378
- package/packages/@monomind/guidance/dist/compiler.d.ts +0 -87
- package/packages/@monomind/guidance/dist/compiler.js +0 -425
- package/packages/@monomind/guidance/dist/conformance-kit.d.ts +0 -225
- package/packages/@monomind/guidance/dist/conformance-kit.js +0 -629
- package/packages/@monomind/guidance/dist/continue-gate.d.ts +0 -214
- package/packages/@monomind/guidance/dist/continue-gate.js +0 -353
- package/packages/@monomind/guidance/dist/crypto-utils.d.ts +0 -17
- package/packages/@monomind/guidance/dist/crypto-utils.js +0 -24
- package/packages/@monomind/guidance/dist/evolution.d.ts +0 -282
- package/packages/@monomind/guidance/dist/evolution.js +0 -500
- package/packages/@monomind/guidance/dist/gates.d.ts +0 -79
- package/packages/@monomind/guidance/dist/gates.js +0 -302
- package/packages/@monomind/guidance/dist/gateway.d.ts +0 -206
- package/packages/@monomind/guidance/dist/gateway.js +0 -452
- package/packages/@monomind/guidance/dist/generators.d.ts +0 -153
- package/packages/@monomind/guidance/dist/generators.js +0 -682
- package/packages/@monomind/guidance/dist/headless.d.ts +0 -177
- package/packages/@monomind/guidance/dist/headless.js +0 -342
- package/packages/@monomind/guidance/dist/hooks.d.ts +0 -109
- package/packages/@monomind/guidance/dist/hooks.js +0 -347
- package/packages/@monomind/guidance/dist/index.d.ts +0 -203
- package/packages/@monomind/guidance/dist/index.js +0 -320
- package/packages/@monomind/guidance/dist/ledger.d.ts +0 -162
- package/packages/@monomind/guidance/dist/ledger.js +0 -375
- package/packages/@monomind/guidance/dist/manifest-validator.d.ts +0 -289
- package/packages/@monomind/guidance/dist/manifest-validator.js +0 -838
- package/packages/@monomind/guidance/dist/memory-gate.d.ts +0 -222
- package/packages/@monomind/guidance/dist/memory-gate.js +0 -382
- package/packages/@monomind/guidance/dist/meta-governance.d.ts +0 -265
- package/packages/@monomind/guidance/dist/meta-governance.js +0 -348
- package/packages/@monomind/guidance/dist/optimizer.d.ts +0 -104
- package/packages/@monomind/guidance/dist/optimizer.js +0 -329
- package/packages/@monomind/guidance/dist/persistence.d.ts +0 -189
- package/packages/@monomind/guidance/dist/persistence.js +0 -464
- package/packages/@monomind/guidance/dist/proof.d.ts +0 -185
- package/packages/@monomind/guidance/dist/proof.js +0 -238
- package/packages/@monomind/guidance/dist/retriever.d.ts +0 -116
- package/packages/@monomind/guidance/dist/retriever.js +0 -394
- package/packages/@monomind/guidance/dist/ruvbot-integration.d.ts +0 -370
- package/packages/@monomind/guidance/dist/ruvbot-integration.js +0 -738
- package/packages/@monomind/guidance/dist/temporal.d.ts +0 -428
- package/packages/@monomind/guidance/dist/temporal.js +0 -660
- package/packages/@monomind/guidance/dist/trust.d.ts +0 -283
- package/packages/@monomind/guidance/dist/trust.js +0 -474
- package/packages/@monomind/guidance/dist/truth-anchors.d.ts +0 -276
- package/packages/@monomind/guidance/dist/truth-anchors.js +0 -488
- package/packages/@monomind/guidance/dist/types.d.ts +0 -378
- package/packages/@monomind/guidance/dist/types.js +0 -10
- package/packages/@monomind/guidance/dist/uncertainty.d.ts +0 -372
- package/packages/@monomind/guidance/dist/uncertainty.js +0 -619
- package/packages/@monomind/guidance/dist/wasm-kernel.d.ts +0 -48
- package/packages/@monomind/guidance/dist/wasm-kernel.js +0 -158
- package/packages/@monomind/guidance/package.json +0 -119
|
@@ -1,1350 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Worker Daemon Service
|
|
3
|
-
* Node.js-based background worker system that auto-runs like shell daemons
|
|
4
|
-
*
|
|
5
|
-
* Workers:
|
|
6
|
-
* - map: Codebase mapping (5 min interval)
|
|
7
|
-
* - audit: Security analysis (10 min interval)
|
|
8
|
-
* - optimize: Performance optimization (15 min interval)
|
|
9
|
-
* - consolidate: Memory consolidation (30 min interval)
|
|
10
|
-
* - testgaps, predict, document, refactor, preload: no local-mode
|
|
11
|
-
* implementation — real work only happens in headless mode via
|
|
12
|
-
* HeadlessWorkerExecutor (Claude Code CLI required)
|
|
13
|
-
*/
|
|
14
|
-
import { EventEmitter } from 'events';
|
|
15
|
-
import { existsSync, mkdirSync, writeFileSync, renameSync, readFileSync, appendFileSync, unlinkSync, statSync } from 'fs';
|
|
16
|
-
import { cpus } from 'os';
|
|
17
|
-
import { join, resolve } from 'path';
|
|
18
|
-
import { HeadlessWorkerExecutor, isHeadlessWorker, } from './headless-worker-executor.js';
|
|
19
|
-
// Default worker configurations with improved intervals (P0 fix: map 5min -> 15min)
|
|
20
|
-
const DEFAULT_WORKERS = [
|
|
21
|
-
{ type: 'map', intervalMs: 15 * 60 * 1000, offsetMs: 0, priority: 'normal', description: 'Codebase mapping', enabled: true },
|
|
22
|
-
{ type: 'audit', intervalMs: 10 * 60 * 1000, offsetMs: 2 * 60 * 1000, priority: 'critical', description: 'Security analysis', enabled: true },
|
|
23
|
-
{ type: 'optimize', intervalMs: 15 * 60 * 1000, offsetMs: 4 * 60 * 1000, priority: 'high', description: 'Performance optimization', enabled: true },
|
|
24
|
-
{ type: 'consolidate', intervalMs: 30 * 60 * 1000, offsetMs: 6 * 60 * 1000, priority: 'low', description: 'Memory consolidation', enabled: true },
|
|
25
|
-
{ type: 'testgaps', intervalMs: 20 * 60 * 1000, offsetMs: 8 * 60 * 1000, priority: 'normal', description: 'Test coverage analysis', enabled: true },
|
|
26
|
-
{ type: 'predict', intervalMs: 10 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Predictive preloading', enabled: false },
|
|
27
|
-
{ type: 'document', intervalMs: 60 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Auto-documentation', enabled: false },
|
|
28
|
-
];
|
|
29
|
-
// Worker timeout — must exceed the longest per-worker headless timeout (15 min for audit/refactor).
|
|
30
|
-
// Previously 5 min, which caused orphan processes when daemon timeout fired before executor timeout (#1117).
|
|
31
|
-
const DEFAULT_WORKER_TIMEOUT_MS = 16 * 60 * 1000;
|
|
32
|
-
/**
|
|
33
|
-
* Worker Daemon - Manages background workers with Node.js
|
|
34
|
-
*/
|
|
35
|
-
export class WorkerDaemon extends EventEmitter {
|
|
36
|
-
config;
|
|
37
|
-
workers = new Map();
|
|
38
|
-
timers = new Map();
|
|
39
|
-
running = false;
|
|
40
|
-
startedAt;
|
|
41
|
-
projectRoot;
|
|
42
|
-
runningWorkers = new Set(); // Track concurrent workers
|
|
43
|
-
pendingWorkers = []; // Queue for deferred workers
|
|
44
|
-
// Headless execution support
|
|
45
|
-
headlessExecutor = null;
|
|
46
|
-
headlessAvailable = false;
|
|
47
|
-
// Preserve the original constructor config so we can detect explicit overrides
|
|
48
|
-
// during state restoration (R1: constructor config takes priority over stale state)
|
|
49
|
-
originalConfig;
|
|
50
|
-
constructor(projectRoot, config) {
|
|
51
|
-
super();
|
|
52
|
-
// Resolve and validate projectRoot. Without this an attacker who can pass
|
|
53
|
-
// a crafted projectRoot (env var, untrusted CLI flag, MCP tool argument)
|
|
54
|
-
// gets arbitrary file write via the derived pidFile, logFile, stateFile,
|
|
55
|
-
// and metrics paths.
|
|
56
|
-
const resolved = resolve(projectRoot);
|
|
57
|
-
this.projectRoot = resolved;
|
|
58
|
-
this.originalConfig = config;
|
|
59
|
-
const monomindDir = join(resolved, '.monomind');
|
|
60
|
-
// Read daemon config from .monomind/config.json (Layer B)
|
|
61
|
-
const fileConfig = this.readDaemonConfigFromFile(monomindDir);
|
|
62
|
-
// CPU-proportional smart default instead of hardcoded 2.0
|
|
63
|
-
const cpuCount = WorkerDaemon.getEffectiveCpuCount();
|
|
64
|
-
const smartMaxCpuLoad = Math.max(cpuCount * 0.8, 2.0); // Floor of 2.0 for single-CPU machines
|
|
65
|
-
// Platform-aware default: macOS os.freemem() excludes reclaimable file cache,
|
|
66
|
-
// so reported "free" is much lower than actually available memory.
|
|
67
|
-
// Linux reports available memory (including reclaimable cache) more accurately.
|
|
68
|
-
const defaultMinFreeMemory = process.platform === 'darwin' ? 5 : 10;
|
|
69
|
-
// Priority: constructor arg > config.json > smart default
|
|
70
|
-
// For resourceThresholds, merge field-by-field so partial overrides
|
|
71
|
-
// (e.g. only --max-cpu-load) still pick up defaults for other fields.
|
|
72
|
-
this.config = {
|
|
73
|
-
autoStart: config?.autoStart ?? fileConfig.autoStart ?? false,
|
|
74
|
-
logDir: config?.logDir ?? join(monomindDir, 'logs'),
|
|
75
|
-
stateFile: config?.stateFile ?? join(monomindDir, 'daemon-state.json'),
|
|
76
|
-
maxConcurrent: config?.maxConcurrent ?? fileConfig.maxConcurrent ?? 2,
|
|
77
|
-
workerTimeoutMs: config?.workerTimeoutMs ?? fileConfig.workerTimeoutMs ?? DEFAULT_WORKER_TIMEOUT_MS,
|
|
78
|
-
resourceThresholds: {
|
|
79
|
-
maxCpuLoad: config?.resourceThresholds?.maxCpuLoad ?? fileConfig.maxCpuLoad ?? smartMaxCpuLoad,
|
|
80
|
-
minFreeMemoryPercent: config?.resourceThresholds?.minFreeMemoryPercent ?? fileConfig.minFreeMemoryPercent ?? defaultMinFreeMemory,
|
|
81
|
-
},
|
|
82
|
-
workers: config?.workers ?? DEFAULT_WORKERS,
|
|
83
|
-
};
|
|
84
|
-
// Setup graceful shutdown handlers
|
|
85
|
-
this.setupShutdownHandlers();
|
|
86
|
-
// Ensure directories exist
|
|
87
|
-
if (!existsSync(monomindDir)) {
|
|
88
|
-
mkdirSync(monomindDir, { recursive: true });
|
|
89
|
-
}
|
|
90
|
-
if (!existsSync(this.config.logDir)) {
|
|
91
|
-
mkdirSync(this.config.logDir, { recursive: true });
|
|
92
|
-
}
|
|
93
|
-
// Initialize worker states
|
|
94
|
-
this.initializeWorkerStates();
|
|
95
|
-
// Initialize headless executor (async, non-blocking)
|
|
96
|
-
this.initHeadlessExecutor().catch((err) => {
|
|
97
|
-
this.log('warn', `Headless executor init failed: ${err}`);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Initialize headless executor if Claude Code is available
|
|
102
|
-
*/
|
|
103
|
-
async initHeadlessExecutor() {
|
|
104
|
-
try {
|
|
105
|
-
this.headlessExecutor = new HeadlessWorkerExecutor(this.projectRoot, {
|
|
106
|
-
maxConcurrent: this.config.maxConcurrent,
|
|
107
|
-
});
|
|
108
|
-
this.headlessAvailable = await this.headlessExecutor.isAvailable();
|
|
109
|
-
if (this.headlessAvailable) {
|
|
110
|
-
this.log('info', 'Claude Code headless mode available - AI workers enabled');
|
|
111
|
-
// Forward headless executor events.
|
|
112
|
-
// The executor emits 'start', 'complete', 'error' (not 'execution:*').
|
|
113
|
-
this.headlessExecutor.on('start', (data) => {
|
|
114
|
-
this.emit('headless:start', data);
|
|
115
|
-
});
|
|
116
|
-
this.headlessExecutor.on('complete', (data) => {
|
|
117
|
-
this.emit('headless:complete', data);
|
|
118
|
-
});
|
|
119
|
-
this.headlessExecutor.on('error', (data) => {
|
|
120
|
-
this.emit('headless:error', data);
|
|
121
|
-
});
|
|
122
|
-
this.headlessExecutor.on('output', (data) => {
|
|
123
|
-
this.emit('headless:output', data);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
this.log('info', 'Claude Code not found - AI workers will run in local fallback mode');
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
this.log('warn', `Failed to initialize headless executor: ${error}`);
|
|
132
|
-
this.headlessAvailable = false;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Check if headless execution is available
|
|
137
|
-
*/
|
|
138
|
-
isHeadlessAvailable() {
|
|
139
|
-
return this.headlessAvailable;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Get headless executor instance
|
|
143
|
-
*/
|
|
144
|
-
getHeadlessExecutor() {
|
|
145
|
-
return this.headlessExecutor;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Detect effective CPU count for the current environment.
|
|
149
|
-
*
|
|
150
|
-
* Inside Docker / K8s containers, os.cpus().length reports the HOST cpu
|
|
151
|
-
* count, not the container limit (Node.js #28762 — wontfix). We read
|
|
152
|
-
* cgroup v2 / v1 quota files first so the maxCpuLoad threshold stays
|
|
153
|
-
* meaningful under resource-limited containers.
|
|
154
|
-
*/
|
|
155
|
-
static getEffectiveCpuCount() {
|
|
156
|
-
// 1. Try cgroup v2: /sys/fs/cgroup/cpu.max
|
|
157
|
-
try {
|
|
158
|
-
const cpuMax = readFileSync('/sys/fs/cgroup/cpu.max', 'utf8').trim();
|
|
159
|
-
const [quotaStr, periodStr] = cpuMax.split(' ');
|
|
160
|
-
if (quotaStr !== 'max') {
|
|
161
|
-
const quota = parseInt(quotaStr, 10);
|
|
162
|
-
const period = parseInt(periodStr, 10);
|
|
163
|
-
if (quota > 0 && period > 0)
|
|
164
|
-
return Math.ceil(quota / period);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch { /* not in cgroup v2 */ }
|
|
168
|
-
// 2. Try cgroup v1: /sys/fs/cgroup/cpu/cpu.cfs_quota_us
|
|
169
|
-
try {
|
|
170
|
-
const quota = parseInt(readFileSync('/sys/fs/cgroup/cpu/cpu.cfs_quota_us', 'utf8').trim(), 10);
|
|
171
|
-
const period = parseInt(readFileSync('/sys/fs/cgroup/cpu/cpu.cfs_period_us', 'utf8').trim(), 10);
|
|
172
|
-
if (quota > 0 && period > 0)
|
|
173
|
-
return Math.ceil(quota / period);
|
|
174
|
-
}
|
|
175
|
-
catch { /* not in cgroup v1 */ }
|
|
176
|
-
// 3. Fallback to os.cpus().length
|
|
177
|
-
return cpus().length || 1;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Read daemon-specific config from .monomind/config.json
|
|
181
|
-
* Supports dot-notation keys like 'daemon.resourceThresholds.maxCpuLoad'
|
|
182
|
-
*/
|
|
183
|
-
readDaemonConfigFromFile(monomindDir) {
|
|
184
|
-
const configPath = join(monomindDir, 'config.json');
|
|
185
|
-
if (!existsSync(configPath)) {
|
|
186
|
-
// Warn if config.yaml exists but config.json does not (#1395 Bug 4)
|
|
187
|
-
const yamlPath = join(monomindDir, 'config.yaml');
|
|
188
|
-
const ymlPath = join(monomindDir, 'config.yml');
|
|
189
|
-
if (existsSync(yamlPath) || existsSync(ymlPath)) {
|
|
190
|
-
this.log('warn', `Found ${existsSync(yamlPath) ? 'config.yaml' : 'config.yml'} but daemon reads only config.json — YAML config is being ignored. Convert to JSON or create config.json.`);
|
|
191
|
-
}
|
|
192
|
-
return {};
|
|
193
|
-
}
|
|
194
|
-
try {
|
|
195
|
-
// Guard against OOM from an oversized config file (tampered or corrupted).
|
|
196
|
-
const configSize = statSync(configPath).size;
|
|
197
|
-
if (configSize > 1_048_576 /* 1 MB */) {
|
|
198
|
-
this.log('warn', `config.json is unusually large (${configSize} bytes) — ignoring daemon config`);
|
|
199
|
-
return {};
|
|
200
|
-
}
|
|
201
|
-
const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
202
|
-
// Support both flat keys at root and nested under scopes.project
|
|
203
|
-
const cfg = raw?.scopes?.project ?? raw;
|
|
204
|
-
const rawCpuLoad = cfg['daemon.resourceThresholds.maxCpuLoad'] ?? raw['daemon.resourceThresholds.maxCpuLoad'];
|
|
205
|
-
const rawMinMem = cfg['daemon.resourceThresholds.minFreeMemoryPercent'] ?? raw['daemon.resourceThresholds.minFreeMemoryPercent'];
|
|
206
|
-
const rawMaxConcurrent = cfg['daemon.maxConcurrent'] ?? raw['daemon.maxConcurrent'];
|
|
207
|
-
const rawTimeout = cfg['daemon.workerTimeoutMs'] ?? raw['daemon.workerTimeoutMs'];
|
|
208
|
-
return {
|
|
209
|
-
autoStart: typeof raw['daemon.autoStart'] === 'boolean' ? raw['daemon.autoStart'] : undefined,
|
|
210
|
-
maxConcurrent: (typeof rawMaxConcurrent === 'number' && rawMaxConcurrent > 0) ? rawMaxConcurrent : undefined,
|
|
211
|
-
workerTimeoutMs: (typeof rawTimeout === 'number' && rawTimeout > 0) ? rawTimeout : undefined,
|
|
212
|
-
maxCpuLoad: (typeof rawCpuLoad === 'number' && rawCpuLoad > 0 && rawCpuLoad < 1000) ? rawCpuLoad : undefined,
|
|
213
|
-
minFreeMemoryPercent: (typeof rawMinMem === 'number' && rawMinMem >= 0 && rawMinMem <= 100) ? rawMinMem : undefined,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
catch {
|
|
217
|
-
return {};
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Setup graceful shutdown handlers
|
|
222
|
-
*/
|
|
223
|
-
setupShutdownHandlers() {
|
|
224
|
-
const shutdown = async () => {
|
|
225
|
-
this.log('info', 'Received shutdown signal, stopping daemon...');
|
|
226
|
-
await this.stop();
|
|
227
|
-
process.exit(0);
|
|
228
|
-
};
|
|
229
|
-
process.once('SIGTERM', shutdown);
|
|
230
|
-
process.once('SIGINT', shutdown);
|
|
231
|
-
process.once('SIGHUP', shutdown);
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Check if system resources allow worker execution
|
|
235
|
-
*/
|
|
236
|
-
async canRunWorker() {
|
|
237
|
-
const os = await import('os');
|
|
238
|
-
const cpuLoad = os.loadavg()[0];
|
|
239
|
-
const totalMem = os.totalmem();
|
|
240
|
-
const freeMem = os.freemem();
|
|
241
|
-
const freePercent = (freeMem / totalMem) * 100;
|
|
242
|
-
if (cpuLoad > this.config.resourceThresholds.maxCpuLoad) {
|
|
243
|
-
return { allowed: false, reason: `CPU load too high: ${cpuLoad.toFixed(2)}` };
|
|
244
|
-
}
|
|
245
|
-
if (freePercent < this.config.resourceThresholds.minFreeMemoryPercent) {
|
|
246
|
-
return { allowed: false, reason: `Memory too low: ${freePercent.toFixed(1)}% free` };
|
|
247
|
-
}
|
|
248
|
-
return { allowed: true };
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Process pending workers queue
|
|
252
|
-
*
|
|
253
|
-
* When executeWorkerWithConcurrencyControl defers a worker (returns null),
|
|
254
|
-
* we break immediately to avoid a busy-wait loop — the deferred worker is
|
|
255
|
-
* already back on the pendingWorkers queue by that point. If no workers are
|
|
256
|
-
* currently running when we break, we schedule a backoff retry so the queue
|
|
257
|
-
* does not get permanently stuck.
|
|
258
|
-
*/
|
|
259
|
-
async processPendingWorkers() {
|
|
260
|
-
while (this.pendingWorkers.length > 0 && this.runningWorkers.size < this.config.maxConcurrent) {
|
|
261
|
-
const workerType = this.pendingWorkers.shift();
|
|
262
|
-
const workerConfig = this.config.workers.find(w => w.type === workerType);
|
|
263
|
-
if (workerConfig) {
|
|
264
|
-
const result = await this.executeWorkerWithConcurrencyControl(workerConfig);
|
|
265
|
-
if (result === null) {
|
|
266
|
-
// Worker was deferred (resource pressure or concurrency limit).
|
|
267
|
-
// Break to avoid tight-looping — the next executeWorker() completion
|
|
268
|
-
// will call processPendingWorkers() again via the finally block.
|
|
269
|
-
if (this.runningWorkers.size === 0) {
|
|
270
|
-
// No workers running means nobody will trigger the finally-block
|
|
271
|
-
// callback, so schedule a backoff retry to avoid a stuck queue.
|
|
272
|
-
setTimeout(() => this.processPendingWorkers(), 30_000).unref();
|
|
273
|
-
}
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
initializeWorkerStates() {
|
|
280
|
-
// Try to restore state from file
|
|
281
|
-
if (existsSync(this.config.stateFile)) {
|
|
282
|
-
try {
|
|
283
|
-
// Guard against OOM from an oversized state file (tampered or corrupted).
|
|
284
|
-
const stateSize = statSync(this.config.stateFile).size;
|
|
285
|
-
if (stateSize > 5_242_880 /* 5 MB */) {
|
|
286
|
-
this.log('warn', `daemon-state.json is unusually large (${stateSize} bytes) — starting with fresh state`);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const saved = JSON.parse(readFileSync(this.config.stateFile, 'utf-8'));
|
|
290
|
-
// CRITICAL: Restore worker config (including enabled flag) from saved state
|
|
291
|
-
// This fixes #950: daemon enable command not persisting worker state
|
|
292
|
-
if (saved.config?.workers && Array.isArray(saved.config.workers)) {
|
|
293
|
-
for (const savedWorker of saved.config.workers) {
|
|
294
|
-
const workerConfig = this.config.workers.find(w => w.type === savedWorker.type);
|
|
295
|
-
if (workerConfig && typeof savedWorker.enabled === 'boolean') {
|
|
296
|
-
workerConfig.enabled = savedWorker.enabled;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
// Restore resourceThresholds, maxConcurrent, workerTimeoutMs from saved state
|
|
301
|
-
// Only restore if valid numeric values within sane ranges
|
|
302
|
-
if (saved.config?.resourceThresholds && !this.originalConfig?.resourceThresholds) {
|
|
303
|
-
const rt = saved.config.resourceThresholds;
|
|
304
|
-
if (typeof rt.maxCpuLoad === 'number' && rt.maxCpuLoad > 0 && rt.maxCpuLoad < 1000) {
|
|
305
|
-
this.config.resourceThresholds.maxCpuLoad = rt.maxCpuLoad;
|
|
306
|
-
}
|
|
307
|
-
if (typeof rt.minFreeMemoryPercent === 'number' && rt.minFreeMemoryPercent >= 0 && rt.minFreeMemoryPercent <= 100) {
|
|
308
|
-
this.config.resourceThresholds.minFreeMemoryPercent = rt.minFreeMemoryPercent;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
if (typeof saved.config?.maxConcurrent === 'number' && saved.config.maxConcurrent > 0) {
|
|
312
|
-
this.config.maxConcurrent = saved.config.maxConcurrent;
|
|
313
|
-
}
|
|
314
|
-
if (typeof saved.config?.workerTimeoutMs === 'number' && saved.config.workerTimeoutMs > 0) {
|
|
315
|
-
this.config.workerTimeoutMs = saved.config.workerTimeoutMs;
|
|
316
|
-
}
|
|
317
|
-
// Restore worker runtime states (runCount, successCount, etc.)
|
|
318
|
-
// Validate keys against an allowlist to defeat prototype-pollution
|
|
319
|
-
// attempts and reject unknown worker types injected into the file.
|
|
320
|
-
if (saved.workers && typeof saved.workers === 'object') {
|
|
321
|
-
const VALID_TYPES = new Set(this.config.workers.map(w => w.type));
|
|
322
|
-
const FORBIDDEN = new Set(['__proto__', 'constructor', 'prototype']);
|
|
323
|
-
const finiteNonNeg = (v) => {
|
|
324
|
-
if (typeof v !== 'number' || !Number.isFinite(v) || v < 0)
|
|
325
|
-
return 0;
|
|
326
|
-
return Math.floor(v);
|
|
327
|
-
};
|
|
328
|
-
for (const [type, state] of Object.entries(saved.workers)) {
|
|
329
|
-
if (FORBIDDEN.has(type) || !VALID_TYPES.has(type))
|
|
330
|
-
continue;
|
|
331
|
-
const savedState = state;
|
|
332
|
-
const lastRunValue = savedState.lastRun;
|
|
333
|
-
const lastRunDate = typeof lastRunValue === 'string' ? new Date(lastRunValue) : undefined;
|
|
334
|
-
this.workers.set(type, {
|
|
335
|
-
runCount: finiteNonNeg(savedState.runCount),
|
|
336
|
-
successCount: finiteNonNeg(savedState.successCount),
|
|
337
|
-
failureCount: finiteNonNeg(savedState.failureCount),
|
|
338
|
-
averageDurationMs: finiteNonNeg(savedState.averageDurationMs),
|
|
339
|
-
lastRun: lastRunDate && !isNaN(lastRunDate.getTime()) ? lastRunDate : undefined,
|
|
340
|
-
nextRun: undefined,
|
|
341
|
-
isRunning: false,
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
catch {
|
|
347
|
-
// Ignore parse errors, start fresh
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
// Initialize any missing workers
|
|
351
|
-
for (const workerConfig of this.config.workers) {
|
|
352
|
-
if (!this.workers.has(workerConfig.type)) {
|
|
353
|
-
this.workers.set(workerConfig.type, {
|
|
354
|
-
runCount: 0,
|
|
355
|
-
successCount: 0,
|
|
356
|
-
failureCount: 0,
|
|
357
|
-
averageDurationMs: 0,
|
|
358
|
-
isRunning: false,
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Get the PID file path for singleton enforcement (#1395 Bug 3).
|
|
365
|
-
*/
|
|
366
|
-
get pidFile() {
|
|
367
|
-
return join(this.projectRoot, '.monomind', 'daemon.pid');
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Check if another daemon instance is already running.
|
|
371
|
-
* Returns the existing PID if alive, or null if no daemon is running.
|
|
372
|
-
*/
|
|
373
|
-
checkExistingDaemon() {
|
|
374
|
-
if (!existsSync(this.pidFile))
|
|
375
|
-
return null;
|
|
376
|
-
try {
|
|
377
|
-
const pid = parseInt(readFileSync(this.pidFile, 'utf-8').trim(), 10);
|
|
378
|
-
if (isNaN(pid))
|
|
379
|
-
return null;
|
|
380
|
-
// Check if process is alive (signal 0 = existence check)
|
|
381
|
-
process.kill(pid, 0);
|
|
382
|
-
return pid; // Process is alive
|
|
383
|
-
}
|
|
384
|
-
catch {
|
|
385
|
-
// Process is dead — clean up stale PID file
|
|
386
|
-
try {
|
|
387
|
-
unlinkSync(this.pidFile);
|
|
388
|
-
}
|
|
389
|
-
catch { /* ignore */ }
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Write PID file with O_EXCL for atomic singleton enforcement (closes the
|
|
395
|
-
* TOCTOU window between checkExistingDaemon and writePidFile that previously
|
|
396
|
-
* allowed two concurrent `daemon start` calls to both succeed).
|
|
397
|
-
* Returns true on success, false if another daemon raced us.
|
|
398
|
-
*/
|
|
399
|
-
writePidFile() {
|
|
400
|
-
const dir = join(this.projectRoot, '.monomind');
|
|
401
|
-
if (!existsSync(dir))
|
|
402
|
-
mkdirSync(dir, { recursive: true });
|
|
403
|
-
try {
|
|
404
|
-
// wx flag = O_CREAT | O_EXCL — atomic create-or-fail
|
|
405
|
-
writeFileSync(this.pidFile, String(process.pid), { flag: 'wx' });
|
|
406
|
-
return true;
|
|
407
|
-
}
|
|
408
|
-
catch (e) {
|
|
409
|
-
const code = e.code;
|
|
410
|
-
if (code === 'EEXIST') {
|
|
411
|
-
// Recheck liveness — file may belong to a dead daemon we missed
|
|
412
|
-
const racePid = this.checkExistingDaemon();
|
|
413
|
-
if (racePid === null) {
|
|
414
|
-
// Stale file was just removed by checkExistingDaemon, retry once
|
|
415
|
-
try {
|
|
416
|
-
writeFileSync(this.pidFile, String(process.pid), { flag: 'wx' });
|
|
417
|
-
return true;
|
|
418
|
-
}
|
|
419
|
-
catch {
|
|
420
|
-
return false;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
throw e;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Remove PID file on shutdown.
|
|
430
|
-
*/
|
|
431
|
-
removePidFile() {
|
|
432
|
-
try {
|
|
433
|
-
unlinkSync(this.pidFile);
|
|
434
|
-
}
|
|
435
|
-
catch { /* ignore */ }
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Start the daemon and all enabled workers
|
|
439
|
-
*/
|
|
440
|
-
async start() {
|
|
441
|
-
if (this.running) {
|
|
442
|
-
this.emit('warning', 'Daemon already running');
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
// PID singleton enforcement (#1395 Bug 3): prevent daemon accumulation
|
|
446
|
-
const existingPid = this.checkExistingDaemon();
|
|
447
|
-
if (existingPid !== null) {
|
|
448
|
-
this.log('info', `Daemon already running (PID: ${existingPid}), skipping start`);
|
|
449
|
-
this.emit('warning', `Daemon already running (PID: ${existingPid})`);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
// Atomic PID file write — fails if another daemon raced us past
|
|
453
|
-
// checkExistingDaemon. Without this two `daemon start` calls could both
|
|
454
|
-
// pass the existence check then both clobber the PID file.
|
|
455
|
-
if (!this.writePidFile()) {
|
|
456
|
-
this.log('info', 'Another daemon won the PID race — aborting start');
|
|
457
|
-
this.emit('warning', 'Another daemon instance is starting/running');
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
this.running = true;
|
|
461
|
-
this.startedAt = new Date();
|
|
462
|
-
this.emit('started', { pid: process.pid, startedAt: this.startedAt });
|
|
463
|
-
// Schedule all enabled workers
|
|
464
|
-
for (const workerConfig of this.config.workers) {
|
|
465
|
-
if (workerConfig.enabled) {
|
|
466
|
-
this.scheduleWorker(workerConfig);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
// Save state
|
|
470
|
-
this.saveState();
|
|
471
|
-
this.log('info', `Daemon started (PID: ${process.pid}, CPUs: ${cpus().length}, workers: ${this.config.workers.filter(w => w.enabled).length}, maxCpuLoad: ${this.config.resourceThresholds.maxCpuLoad}, minFreeMemoryPercent: ${this.config.resourceThresholds.minFreeMemoryPercent}%)`);
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Stop the daemon and all workers
|
|
475
|
-
*/
|
|
476
|
-
async stop() {
|
|
477
|
-
if (!this.running) {
|
|
478
|
-
this.emit('warning', 'Daemon not running');
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
// Clear all timers (convert to array to avoid iterator issues)
|
|
482
|
-
const timerEntries = Array.from(this.timers.entries());
|
|
483
|
-
for (const [type, timer] of timerEntries) {
|
|
484
|
-
clearTimeout(timer);
|
|
485
|
-
this.log('info', `Stopped worker: ${type}`);
|
|
486
|
-
}
|
|
487
|
-
this.timers.clear();
|
|
488
|
-
this.running = false;
|
|
489
|
-
this.removePidFile();
|
|
490
|
-
this.saveState();
|
|
491
|
-
this.emit('stopped', { stoppedAt: new Date() });
|
|
492
|
-
this.log('info', 'Daemon stopped');
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Get daemon status
|
|
496
|
-
*/
|
|
497
|
-
getStatus() {
|
|
498
|
-
return {
|
|
499
|
-
running: this.running,
|
|
500
|
-
pid: process.pid,
|
|
501
|
-
startedAt: this.startedAt,
|
|
502
|
-
workers: new Map(this.workers),
|
|
503
|
-
config: this.config,
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
/**
|
|
507
|
-
* Schedule a worker to run at intervals with staggered start
|
|
508
|
-
*/
|
|
509
|
-
scheduleWorker(workerConfig) {
|
|
510
|
-
const state = this.workers.get(workerConfig.type);
|
|
511
|
-
const internalConfig = workerConfig;
|
|
512
|
-
const staggerOffset = internalConfig.offsetMs || 0;
|
|
513
|
-
// Calculate initial delay with stagger offset
|
|
514
|
-
let initialDelay = staggerOffset;
|
|
515
|
-
if (state.lastRun) {
|
|
516
|
-
const timeSinceLastRun = Date.now() - state.lastRun.getTime();
|
|
517
|
-
initialDelay = Math.max(staggerOffset, workerConfig.intervalMs - timeSinceLastRun);
|
|
518
|
-
}
|
|
519
|
-
state.nextRun = new Date(Date.now() + initialDelay);
|
|
520
|
-
const runAndReschedule = async () => {
|
|
521
|
-
if (!this.running)
|
|
522
|
-
return;
|
|
523
|
-
// Use concurrency-controlled execution (P0 fix)
|
|
524
|
-
await this.executeWorkerWithConcurrencyControl(workerConfig);
|
|
525
|
-
// Reschedule
|
|
526
|
-
if (this.running) {
|
|
527
|
-
const timer = setTimeout(runAndReschedule, workerConfig.intervalMs);
|
|
528
|
-
this.timers.set(workerConfig.type, timer);
|
|
529
|
-
state.nextRun = new Date(Date.now() + workerConfig.intervalMs);
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
|
-
// Schedule first run with stagger offset
|
|
533
|
-
const timer = setTimeout(runAndReschedule, initialDelay);
|
|
534
|
-
this.timers.set(workerConfig.type, timer);
|
|
535
|
-
this.log('info', `Scheduled ${workerConfig.type} (interval: ${workerConfig.intervalMs / 1000}s, first run in ${initialDelay / 1000}s)`);
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Execute a worker with concurrency control (P0 fix)
|
|
539
|
-
*/
|
|
540
|
-
async executeWorkerWithConcurrencyControl(workerConfig) {
|
|
541
|
-
// Dedup: under sustained resource pressure each scheduler tick re-pushes
|
|
542
|
-
// the same WorkerType. Without dedup, high-priority workers (audit) crowd
|
|
543
|
-
// out low-priority ones (consolidate) — starvation. Skip the push if the
|
|
544
|
-
// type is already pending.
|
|
545
|
-
const pushPending = (type) => {
|
|
546
|
-
if (!this.pendingWorkers.includes(type))
|
|
547
|
-
this.pendingWorkers.push(type);
|
|
548
|
-
};
|
|
549
|
-
// Check concurrency limit
|
|
550
|
-
if (this.runningWorkers.size >= this.config.maxConcurrent) {
|
|
551
|
-
this.log('info', `Worker ${workerConfig.type} deferred: max concurrent (${this.config.maxConcurrent}) reached`);
|
|
552
|
-
pushPending(workerConfig.type);
|
|
553
|
-
this.emit('worker:deferred', { type: workerConfig.type, reason: 'max_concurrent' });
|
|
554
|
-
return null;
|
|
555
|
-
}
|
|
556
|
-
// Check resource availability
|
|
557
|
-
const resourceCheck = await this.canRunWorker();
|
|
558
|
-
if (!resourceCheck.allowed) {
|
|
559
|
-
this.log('info', `Worker ${workerConfig.type} deferred: ${resourceCheck.reason}`);
|
|
560
|
-
pushPending(workerConfig.type);
|
|
561
|
-
this.emit('worker:deferred', { type: workerConfig.type, reason: resourceCheck.reason });
|
|
562
|
-
return null;
|
|
563
|
-
}
|
|
564
|
-
return this.executeWorker(workerConfig);
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Execute a worker with timeout protection
|
|
568
|
-
*/
|
|
569
|
-
async executeWorker(workerConfig) {
|
|
570
|
-
const state = this.workers.get(workerConfig.type);
|
|
571
|
-
const workerId = `${workerConfig.type}_${Date.now()}`;
|
|
572
|
-
const startTime = Date.now();
|
|
573
|
-
// Track the headless executionId assigned by HeadlessWorkerExecutor so we
|
|
574
|
-
// can cancel it precisely on timeout. The executor generates its own ID
|
|
575
|
-
// (format: `${type}_${ts}_${random}`) which never matches workerId, so we
|
|
576
|
-
// capture it from the 'start' event instead.
|
|
577
|
-
let headlessExecutionId = null;
|
|
578
|
-
const onHeadlessStart = (data) => {
|
|
579
|
-
headlessExecutionId = data.executionId ?? null;
|
|
580
|
-
};
|
|
581
|
-
if (this.headlessExecutor) {
|
|
582
|
-
this.headlessExecutor.on('start', onHeadlessStart);
|
|
583
|
-
}
|
|
584
|
-
// Track running worker
|
|
585
|
-
this.runningWorkers.add(workerConfig.type);
|
|
586
|
-
state.isRunning = true;
|
|
587
|
-
this.emit('worker:start', { workerId, type: workerConfig.type });
|
|
588
|
-
this.log('info', `Starting worker: ${workerConfig.type} (${this.runningWorkers.size}/${this.config.maxConcurrent} concurrent)`);
|
|
589
|
-
try {
|
|
590
|
-
// Execute worker logic with timeout (P1 fix)
|
|
591
|
-
// Pass cleanup callback to kill only this worker's child process on timeout.
|
|
592
|
-
// cancelAll() was too broad — it would kill concurrent healthy workers.
|
|
593
|
-
const output = await this.runWithTimeout(() => this.runWorkerLogic(workerConfig), this.config.workerTimeoutMs, `Worker ${workerConfig.type} timed out after ${this.config.workerTimeoutMs / 1000}s`, () => {
|
|
594
|
-
if (this.headlessExecutor) {
|
|
595
|
-
// Use the exact executionId captured from the 'start' event.
|
|
596
|
-
// Fall back to cancelByType only if we didn't capture an ID yet
|
|
597
|
-
// (e.g. timeout fired before the executor emitted 'start').
|
|
598
|
-
if (headlessExecutionId && this.headlessExecutor.cancel(headlessExecutionId)) {
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
this.headlessExecutor.cancelByType(workerConfig.type);
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
const durationMs = Date.now() - startTime;
|
|
605
|
-
// Update state
|
|
606
|
-
state.runCount++;
|
|
607
|
-
state.successCount++;
|
|
608
|
-
state.lastRun = new Date();
|
|
609
|
-
state.averageDurationMs = (state.averageDurationMs * (state.runCount - 1) + durationMs) / state.runCount;
|
|
610
|
-
state.isRunning = false;
|
|
611
|
-
const result = {
|
|
612
|
-
workerId,
|
|
613
|
-
type: workerConfig.type,
|
|
614
|
-
success: true,
|
|
615
|
-
durationMs,
|
|
616
|
-
output,
|
|
617
|
-
timestamp: new Date(),
|
|
618
|
-
};
|
|
619
|
-
this.emit('worker:complete', result);
|
|
620
|
-
this.log('info', `Worker ${workerConfig.type} completed in ${durationMs}ms`);
|
|
621
|
-
this.saveState();
|
|
622
|
-
return result;
|
|
623
|
-
}
|
|
624
|
-
catch (error) {
|
|
625
|
-
const durationMs = Date.now() - startTime;
|
|
626
|
-
state.runCount++;
|
|
627
|
-
state.failureCount++;
|
|
628
|
-
state.lastRun = new Date();
|
|
629
|
-
state.isRunning = false;
|
|
630
|
-
const result = {
|
|
631
|
-
workerId,
|
|
632
|
-
type: workerConfig.type,
|
|
633
|
-
success: false,
|
|
634
|
-
durationMs,
|
|
635
|
-
error: error instanceof Error ? error.message : String(error),
|
|
636
|
-
timestamp: new Date(),
|
|
637
|
-
};
|
|
638
|
-
this.emit('worker:error', result);
|
|
639
|
-
this.log('error', `Worker ${workerConfig.type} failed: ${result.error}`);
|
|
640
|
-
this.saveState();
|
|
641
|
-
return result;
|
|
642
|
-
}
|
|
643
|
-
finally {
|
|
644
|
-
// Remove from running set and process queue
|
|
645
|
-
this.runningWorkers.delete(workerConfig.type);
|
|
646
|
-
// Unsubscribe the executionId capture listener regardless of outcome
|
|
647
|
-
if (this.headlessExecutor) {
|
|
648
|
-
this.headlessExecutor.off('start', onHeadlessStart);
|
|
649
|
-
}
|
|
650
|
-
this.processPendingWorkers();
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Run a function with timeout (P1 fix)
|
|
655
|
-
* @param fn - The async function to execute
|
|
656
|
-
* @param timeoutMs - Timeout in milliseconds
|
|
657
|
-
* @param timeoutMessage - Error message on timeout
|
|
658
|
-
* @param onTimeout - Optional cleanup callback invoked when timeout fires (#1117: kills orphan processes)
|
|
659
|
-
*/
|
|
660
|
-
async runWithTimeout(fn, timeoutMs, timeoutMessage, onTimeout) {
|
|
661
|
-
return new Promise((resolve, reject) => {
|
|
662
|
-
let settled = false;
|
|
663
|
-
const timer = setTimeout(() => {
|
|
664
|
-
if (settled)
|
|
665
|
-
return;
|
|
666
|
-
settled = true;
|
|
667
|
-
// Kill orphan child processes before rejecting (#1117)
|
|
668
|
-
if (onTimeout) {
|
|
669
|
-
try {
|
|
670
|
-
onTimeout();
|
|
671
|
-
}
|
|
672
|
-
catch {
|
|
673
|
-
// Ignore cleanup errors
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
reject(new Error(timeoutMessage));
|
|
677
|
-
}, timeoutMs);
|
|
678
|
-
fn()
|
|
679
|
-
.then((result) => {
|
|
680
|
-
if (settled)
|
|
681
|
-
return;
|
|
682
|
-
settled = true;
|
|
683
|
-
clearTimeout(timer);
|
|
684
|
-
resolve(result);
|
|
685
|
-
})
|
|
686
|
-
.catch((error) => {
|
|
687
|
-
if (settled)
|
|
688
|
-
return;
|
|
689
|
-
settled = true;
|
|
690
|
-
clearTimeout(timer);
|
|
691
|
-
reject(error);
|
|
692
|
-
});
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Run the actual worker logic
|
|
697
|
-
*/
|
|
698
|
-
async runWorkerLogic(workerConfig) {
|
|
699
|
-
// Check if this is a headless worker type and headless execution is available
|
|
700
|
-
if (isHeadlessWorker(workerConfig.type) && this.headlessAvailable && this.headlessExecutor) {
|
|
701
|
-
try {
|
|
702
|
-
this.log('info', `Running ${workerConfig.type} in headless mode (Claude Code AI)`);
|
|
703
|
-
const result = await this.headlessExecutor.execute(workerConfig.type);
|
|
704
|
-
return {
|
|
705
|
-
mode: 'headless',
|
|
706
|
-
...result,
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
catch (error) {
|
|
710
|
-
this.log('warn', `Headless execution failed for ${workerConfig.type}, falling back to local mode`);
|
|
711
|
-
this.emit('headless:fallback', {
|
|
712
|
-
type: workerConfig.type,
|
|
713
|
-
error: error instanceof Error ? error.message : String(error),
|
|
714
|
-
});
|
|
715
|
-
// Fall through to local execution
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
// Local execution (fallback or for non-headless workers)
|
|
719
|
-
switch (workerConfig.type) {
|
|
720
|
-
case 'map':
|
|
721
|
-
return this.runMapWorker();
|
|
722
|
-
case 'audit':
|
|
723
|
-
return this.runAuditWorkerLocal();
|
|
724
|
-
case 'optimize':
|
|
725
|
-
return this.runOptimizeWorkerLocal();
|
|
726
|
-
case 'consolidate':
|
|
727
|
-
return this.runConsolidateWorker();
|
|
728
|
-
case 'ultralearn':
|
|
729
|
-
return this.runUltralearnWorkerLocal();
|
|
730
|
-
case 'deepdive':
|
|
731
|
-
return this.runDeepdiveWorkerLocal();
|
|
732
|
-
case 'benchmark':
|
|
733
|
-
return this.runBenchmarkWorkerLocal();
|
|
734
|
-
// testgaps/predict/document/refactor/preload have no real local-mode
|
|
735
|
-
// implementation — they only do real work in headless mode (see
|
|
736
|
-
// HeadlessWorkerExecutor). Without Claude Code CLI available there is
|
|
737
|
-
// nothing meaningful to run locally, so report that plainly instead of
|
|
738
|
-
// faking a result with hardcoded empty JSON (monolean).
|
|
739
|
-
case 'testgaps':
|
|
740
|
-
case 'predict':
|
|
741
|
-
case 'document':
|
|
742
|
-
case 'refactor':
|
|
743
|
-
case 'preload':
|
|
744
|
-
return { mode: 'local', note: 'Install Claude Code CLI for AI-powered analysis — no local implementation exists for this worker' };
|
|
745
|
-
default:
|
|
746
|
-
return { status: 'unknown worker type', mode: 'local' };
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
// Worker implementations
|
|
750
|
-
async runMapWorker() {
|
|
751
|
-
// Scan project structure and update metrics
|
|
752
|
-
const metricsFile = join(this.projectRoot, '.monomind', 'metrics', 'codebase-map.json');
|
|
753
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
754
|
-
if (!existsSync(metricsDir)) {
|
|
755
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
756
|
-
}
|
|
757
|
-
const map = {
|
|
758
|
-
timestamp: new Date().toISOString(),
|
|
759
|
-
structure: {
|
|
760
|
-
hasPackageJson: existsSync(join(this.projectRoot, 'package.json')),
|
|
761
|
-
hasTsConfig: existsSync(join(this.projectRoot, 'tsconfig.json')),
|
|
762
|
-
hasClaudeConfig: existsSync(join(this.projectRoot, '.claude')),
|
|
763
|
-
hasMonomind: existsSync(join(this.projectRoot, '.monomind')),
|
|
764
|
-
},
|
|
765
|
-
scannedAt: Date.now(),
|
|
766
|
-
};
|
|
767
|
-
// Enrich with monograph graph stats for LLM context injection.
|
|
768
|
-
// Lazy-import to avoid hard dependency; silently skip on any error.
|
|
769
|
-
try {
|
|
770
|
-
const { openDb, closeDb, countNodes, countEdges } = await import('@monoes/monograph');
|
|
771
|
-
const dbPath = join(this.projectRoot, '.monomind', 'monograph.db');
|
|
772
|
-
if (existsSync(dbPath)) {
|
|
773
|
-
const db = openDb(dbPath);
|
|
774
|
-
try {
|
|
775
|
-
// Node/edge counts
|
|
776
|
-
map['graph'] = {
|
|
777
|
-
nodes: countNodes(db),
|
|
778
|
-
edges: countEdges(db),
|
|
779
|
-
};
|
|
780
|
-
// Top 3 god nodes (high degree internal files) — same SQL as monograph_god_nodes tool
|
|
781
|
-
const excluded = ['File', 'Folder', 'Community', 'Concept'];
|
|
782
|
-
const rows = db.prepare(`
|
|
783
|
-
SELECT n.name, n.file_path, n.start_line,
|
|
784
|
-
COUNT(DISTINCT e1.id) + COUNT(DISTINCT e2.id) AS degree
|
|
785
|
-
FROM nodes n
|
|
786
|
-
LEFT JOIN edges e1 ON e1.source_id = n.id
|
|
787
|
-
LEFT JOIN edges e2 ON e2.target_id = n.id
|
|
788
|
-
WHERE n.label NOT IN (${excluded.map(() => '?').join(',')})
|
|
789
|
-
GROUP BY n.id HAVING degree > 0
|
|
790
|
-
ORDER BY degree DESC LIMIT 3
|
|
791
|
-
`).all(...excluded);
|
|
792
|
-
if (rows.length > 0) {
|
|
793
|
-
map['topFiles'] = rows.map(r => ({
|
|
794
|
-
ref: r.file_path
|
|
795
|
-
? (r.start_line != null ? `${r.file_path}:${r.start_line}` : r.file_path)
|
|
796
|
-
: r.name,
|
|
797
|
-
degree: r.degree,
|
|
798
|
-
}));
|
|
799
|
-
}
|
|
800
|
-
// Index staleness via git — same approach as monograph_health tool
|
|
801
|
-
try {
|
|
802
|
-
const { execSync } = await import('child_process');
|
|
803
|
-
const lastHash = db.prepare("SELECT value FROM meta WHERE key = 'last_commit_hash' LIMIT 1").get()?.value;
|
|
804
|
-
if (lastHash) {
|
|
805
|
-
const countOut = execSync(`git -C ${JSON.stringify(this.projectRoot)} rev-list --count ${lastHash}..HEAD`, { timeout: 5000 }).toString().trim();
|
|
806
|
-
const commitsBehind = parseInt(countOut, 10);
|
|
807
|
-
if (!isNaN(commitsBehind)) {
|
|
808
|
-
map['graphStaleness'] = { commitsBehind };
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
catch { /* git unavailable — skip staleness */ }
|
|
813
|
-
}
|
|
814
|
-
finally {
|
|
815
|
-
closeDb(db);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
catch { /* monograph unavailable — skip graph enrichment */ }
|
|
820
|
-
const metricsFileTmp1 = metricsFile + '.tmp';
|
|
821
|
-
writeFileSync(metricsFileTmp1, JSON.stringify(map, null, 2));
|
|
822
|
-
renameSync(metricsFileTmp1, metricsFile);
|
|
823
|
-
return map;
|
|
824
|
-
}
|
|
825
|
-
/**
|
|
826
|
-
* Local audit worker (fallback when headless unavailable)
|
|
827
|
-
*/
|
|
828
|
-
async runAuditWorkerLocal() {
|
|
829
|
-
// Basic security checks
|
|
830
|
-
const auditFile = join(this.projectRoot, '.monomind', 'metrics', 'security-audit.json');
|
|
831
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
832
|
-
if (!existsSync(metricsDir)) {
|
|
833
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
834
|
-
}
|
|
835
|
-
const audit = {
|
|
836
|
-
timestamp: new Date().toISOString(),
|
|
837
|
-
mode: 'local',
|
|
838
|
-
checks: {
|
|
839
|
-
envFilesProtected: !existsSync(join(this.projectRoot, '.env.local')),
|
|
840
|
-
gitIgnoreExists: existsSync(join(this.projectRoot, '.gitignore')),
|
|
841
|
-
noHardcodedSecrets: null, // Not checked in local mode — requires AI-powered scan
|
|
842
|
-
},
|
|
843
|
-
riskLevel: 'low',
|
|
844
|
-
recommendations: [],
|
|
845
|
-
note: 'Install Claude Code CLI for AI-powered security analysis',
|
|
846
|
-
};
|
|
847
|
-
// Enrich with monograph high-centrality files and surprising cross-community edges.
|
|
848
|
-
// God-node files are high-value targets for security review: they are imported by
|
|
849
|
-
// many consumers, so a vulnerability there has the largest blast radius.
|
|
850
|
-
// Cross-community edges reveal unexpected coupling that may indicate hidden attack surfaces.
|
|
851
|
-
try {
|
|
852
|
-
const { openDb, closeDb } = await import('@monoes/monograph');
|
|
853
|
-
const dbPath = join(this.projectRoot, '.monomind', 'monograph.db');
|
|
854
|
-
if (existsSync(dbPath)) {
|
|
855
|
-
const db = openDb(dbPath);
|
|
856
|
-
try {
|
|
857
|
-
const godFileRows = db.prepare(`
|
|
858
|
-
SELECT n.file_path,
|
|
859
|
-
COUNT(DISTINCT e1.id) + COUNT(DISTINCT e2.id) AS degree
|
|
860
|
-
FROM nodes n
|
|
861
|
-
LEFT JOIN edges e1 ON e1.source_id = n.id
|
|
862
|
-
LEFT JOIN edges e2 ON e2.target_id = n.id
|
|
863
|
-
WHERE n.label NOT IN ('File','Folder','Community','Concept')
|
|
864
|
-
AND n.file_path IS NOT NULL
|
|
865
|
-
AND n.file_path NOT LIKE '%node_modules%'
|
|
866
|
-
AND n.file_path NOT LIKE '%/dist/%'
|
|
867
|
-
AND n.file_path NOT LIKE '%.test.%'
|
|
868
|
-
AND n.file_path NOT LIKE '%.spec.%'
|
|
869
|
-
GROUP BY n.file_path
|
|
870
|
-
ORDER BY degree DESC
|
|
871
|
-
LIMIT 5
|
|
872
|
-
`).all();
|
|
873
|
-
const surpriseRows = db.prepare(`
|
|
874
|
-
SELECT n1.name as src_name, n2.name as tgt_name, e.relation, e.confidence_score,
|
|
875
|
-
n1.file_path as src_file, n2.file_path as tgt_file
|
|
876
|
-
FROM edges e
|
|
877
|
-
JOIN nodes n1 ON n1.id = e.source_id
|
|
878
|
-
JOIN nodes n2 ON n2.id = e.target_id
|
|
879
|
-
WHERE e.confidence != 'EXTRACTED'
|
|
880
|
-
AND n1.community_id IS NOT NULL
|
|
881
|
-
AND n2.community_id IS NOT NULL
|
|
882
|
-
AND n1.community_id != n2.community_id
|
|
883
|
-
ORDER BY e.confidence_score ASC
|
|
884
|
-
LIMIT 5
|
|
885
|
-
`).all();
|
|
886
|
-
if (godFileRows.length > 0) {
|
|
887
|
-
audit['priorityScanTargets'] = godFileRows.map(r => ({
|
|
888
|
-
file: r.file_path.replace(this.projectRoot + '/', '').replace(this.projectRoot + '\\', ''),
|
|
889
|
-
degree: r.degree,
|
|
890
|
-
reason: 'high-centrality: vulnerability here affects the most consumers',
|
|
891
|
-
}));
|
|
892
|
-
}
|
|
893
|
-
if (surpriseRows.length > 0) {
|
|
894
|
-
audit['unexpectedCoupling'] = surpriseRows.map(r => ({
|
|
895
|
-
edge: `${r.src_name} --${r.relation}--> ${r.tgt_name}`,
|
|
896
|
-
srcFile: r.src_file ?? '(unknown)',
|
|
897
|
-
tgtFile: r.tgt_file ?? '(unknown)',
|
|
898
|
-
confidenceScore: r.confidence_score,
|
|
899
|
-
reason: 'cross-community edge: may indicate hidden dependency or attack surface',
|
|
900
|
-
}));
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
finally {
|
|
904
|
-
closeDb(db);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
catch { /* monograph unavailable — skip graph enrichment */ }
|
|
909
|
-
const auditFileTmp = auditFile + '.tmp';
|
|
910
|
-
writeFileSync(auditFileTmp, JSON.stringify(audit, null, 2));
|
|
911
|
-
renameSync(auditFileTmp, auditFile);
|
|
912
|
-
return audit;
|
|
913
|
-
}
|
|
914
|
-
/**
|
|
915
|
-
* Local optimize worker (fallback when headless unavailable)
|
|
916
|
-
*/
|
|
917
|
-
async runOptimizeWorkerLocal() {
|
|
918
|
-
// Update performance metrics
|
|
919
|
-
const optimizeFile = join(this.projectRoot, '.monomind', 'metrics', 'performance.json');
|
|
920
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
921
|
-
if (!existsSync(metricsDir)) {
|
|
922
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
923
|
-
}
|
|
924
|
-
const perf = {
|
|
925
|
-
timestamp: new Date().toISOString(),
|
|
926
|
-
mode: 'local',
|
|
927
|
-
memoryUsage: process.memoryUsage(),
|
|
928
|
-
uptime: process.uptime(),
|
|
929
|
-
optimizations: {
|
|
930
|
-
cacheHitRate: null, // Not measured in local mode — requires AI-powered analysis
|
|
931
|
-
avgResponseTime: null, // Not measured in local mode — requires AI-powered analysis
|
|
932
|
-
},
|
|
933
|
-
note: 'Install Claude Code CLI for AI-powered optimization suggestions',
|
|
934
|
-
};
|
|
935
|
-
const optimizeFileTmp = optimizeFile + '.tmp';
|
|
936
|
-
writeFileSync(optimizeFileTmp, JSON.stringify(perf, null, 2));
|
|
937
|
-
renameSync(optimizeFileTmp, optimizeFile);
|
|
938
|
-
return perf;
|
|
939
|
-
}
|
|
940
|
-
async runConsolidateWorker() {
|
|
941
|
-
// RAPTOR-style memory consolidation: cluster episodic entries by namespace,
|
|
942
|
-
// generate a summary entry as 'contextual' type referencing source cluster.
|
|
943
|
-
// Source: https://arxiv.org/abs/2401.18059 (RAPTOR — ICLR 2024)
|
|
944
|
-
const consolidateFile = join(this.projectRoot, '.monomind', 'metrics', 'consolidation.json');
|
|
945
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
946
|
-
if (!existsSync(metricsDir)) {
|
|
947
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
948
|
-
}
|
|
949
|
-
let patternsConsolidated = 0;
|
|
950
|
-
let clustersCreated = 0;
|
|
951
|
-
try {
|
|
952
|
-
// Lazy-import memory bridge to avoid hard dependency in worker
|
|
953
|
-
const { bridgeSearchEntries, bridgeStoreEntry } = await import('../memory/memory-bridge.js');
|
|
954
|
-
// Retrieve recent episodic entries (short-term tier) for RAPTOR clustering
|
|
955
|
-
const episodic = await bridgeSearchEntries({
|
|
956
|
-
query: 'task outcome agent pattern',
|
|
957
|
-
namespace: 'patterns',
|
|
958
|
-
limit: 50,
|
|
959
|
-
threshold: 0.0,
|
|
960
|
-
});
|
|
961
|
-
if (episodic?.results && episodic.results.length >= 3) {
|
|
962
|
-
// Group into clusters of ~5 by simple sequential chunking
|
|
963
|
-
const CLUSTER_SIZE = 5;
|
|
964
|
-
for (let i = 0; i < episodic.results.length; i += CLUSTER_SIZE) {
|
|
965
|
-
const cluster = episodic.results.slice(i, i + CLUSTER_SIZE);
|
|
966
|
-
if (cluster.length < 2)
|
|
967
|
-
continue;
|
|
968
|
-
// Build cluster summary (lightweight abstraction without LLM)
|
|
969
|
-
const keys = cluster.map(r => r.key).join(', ');
|
|
970
|
-
const summary = `RAPTOR cluster [${Math.floor(i / CLUSTER_SIZE)}]: ` +
|
|
971
|
-
`${cluster.length} patterns consolidated. Topics: ${keys.slice(0, 120)}`;
|
|
972
|
-
await bridgeStoreEntry({
|
|
973
|
-
key: `raptor_cluster:${Date.now()}_${i}`,
|
|
974
|
-
value: summary,
|
|
975
|
-
namespace: 'contextual',
|
|
976
|
-
tags: ['raptor', 'cluster_summary'],
|
|
977
|
-
});
|
|
978
|
-
patternsConsolidated += cluster.length;
|
|
979
|
-
clustersCreated++;
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
catch { /* non-critical — bridge may be unavailable */ }
|
|
984
|
-
const result = {
|
|
985
|
-
timestamp: new Date().toISOString(),
|
|
986
|
-
patternsConsolidated,
|
|
987
|
-
clustersCreated,
|
|
988
|
-
memoryCleaned: 0,
|
|
989
|
-
duplicatesRemoved: 0,
|
|
990
|
-
mode: 'raptor',
|
|
991
|
-
};
|
|
992
|
-
const consolidateFileTmp = consolidateFile + '.tmp';
|
|
993
|
-
writeFileSync(consolidateFileTmp, JSON.stringify(result, null, 2));
|
|
994
|
-
renameSync(consolidateFileTmp, consolidateFile);
|
|
995
|
-
return result;
|
|
996
|
-
}
|
|
997
|
-
/**
|
|
998
|
-
* Local ultralearn worker (fallback when headless unavailable)
|
|
999
|
-
*/
|
|
1000
|
-
async runUltralearnWorkerLocal() {
|
|
1001
|
-
const result = {
|
|
1002
|
-
timestamp: new Date().toISOString(),
|
|
1003
|
-
mode: 'local',
|
|
1004
|
-
patternsLearned: 0,
|
|
1005
|
-
insightsGained: [],
|
|
1006
|
-
};
|
|
1007
|
-
// Enrich with monograph community clusters and bridge-node patterns for LLM context injection.
|
|
1008
|
-
// Bridge nodes (symbols that cross community boundaries) are architecturally significant —
|
|
1009
|
-
// they represent coupling points an LLM should be aware of when reasoning about change impact.
|
|
1010
|
-
try {
|
|
1011
|
-
const { openDb, closeDb, countNodes, countEdges } = await import('@monoes/monograph');
|
|
1012
|
-
const dbPath = join(this.projectRoot, '.monomind', 'monograph.db');
|
|
1013
|
-
if (existsSync(dbPath)) {
|
|
1014
|
-
const db = openDb(dbPath);
|
|
1015
|
-
try {
|
|
1016
|
-
const nodeCount = countNodes(db);
|
|
1017
|
-
const edgeCount = countEdges(db);
|
|
1018
|
-
const communityRows = db.prepare(`
|
|
1019
|
-
SELECT community_id, COUNT(*) AS member_count
|
|
1020
|
-
FROM nodes
|
|
1021
|
-
WHERE community_id IS NOT NULL
|
|
1022
|
-
AND label NOT IN ('File','Folder','Community','Concept')
|
|
1023
|
-
GROUP BY community_id
|
|
1024
|
-
ORDER BY member_count DESC
|
|
1025
|
-
LIMIT 5
|
|
1026
|
-
`).all();
|
|
1027
|
-
const bridgeRows = db.prepare(`
|
|
1028
|
-
SELECT n.name, n.label, n.file_path, n.start_line,
|
|
1029
|
-
COUNT(DISTINCT e.id) AS cross_edges
|
|
1030
|
-
FROM nodes n
|
|
1031
|
-
JOIN edges e ON (e.source_id = n.id OR e.target_id = n.id)
|
|
1032
|
-
JOIN nodes n2 ON (
|
|
1033
|
-
CASE WHEN e.source_id = n.id THEN e.target_id ELSE e.source_id END = n2.id
|
|
1034
|
-
)
|
|
1035
|
-
WHERE n.community_id IS NOT NULL
|
|
1036
|
-
AND n2.community_id IS NOT NULL
|
|
1037
|
-
AND n.community_id != n2.community_id
|
|
1038
|
-
AND n.label NOT IN ('File','Folder','Community','Concept')
|
|
1039
|
-
AND (n.file_path IS NULL OR (
|
|
1040
|
-
n.file_path NOT LIKE '%node_modules%'
|
|
1041
|
-
AND n.file_path NOT LIKE '%/dist/%'
|
|
1042
|
-
AND n.file_path NOT LIKE '%.test.%'
|
|
1043
|
-
AND n.file_path NOT LIKE '%.spec.%'
|
|
1044
|
-
))
|
|
1045
|
-
GROUP BY n.id
|
|
1046
|
-
ORDER BY cross_edges DESC
|
|
1047
|
-
LIMIT 5
|
|
1048
|
-
`).all();
|
|
1049
|
-
const insights = result['insightsGained'];
|
|
1050
|
-
if (communityRows.length > 0) {
|
|
1051
|
-
insights.push({
|
|
1052
|
-
category: 'community_clusters',
|
|
1053
|
-
description: `Top ${communityRows.length} community clusters by size`,
|
|
1054
|
-
items: communityRows.map(r => ({
|
|
1055
|
-
communityId: r.community_id,
|
|
1056
|
-
memberCount: r.member_count,
|
|
1057
|
-
})),
|
|
1058
|
-
});
|
|
1059
|
-
}
|
|
1060
|
-
if (bridgeRows.length > 0) {
|
|
1061
|
-
insights.push({
|
|
1062
|
-
category: 'bridge_nodes',
|
|
1063
|
-
description: `Top ${bridgeRows.length} bridge nodes crossing community boundaries (high coupling risk)`,
|
|
1064
|
-
items: bridgeRows.map(r => {
|
|
1065
|
-
const loc = r.file_path
|
|
1066
|
-
? (r.start_line != null ? `${r.file_path}:${r.start_line}` : r.file_path)
|
|
1067
|
-
: '(unknown)';
|
|
1068
|
-
return {
|
|
1069
|
-
name: r.name,
|
|
1070
|
-
label: r.label,
|
|
1071
|
-
location: loc,
|
|
1072
|
-
crossCommunityEdges: r.cross_edges,
|
|
1073
|
-
};
|
|
1074
|
-
}),
|
|
1075
|
-
});
|
|
1076
|
-
result['patternsLearned'] = bridgeRows.length + communityRows.length;
|
|
1077
|
-
}
|
|
1078
|
-
result['graph'] = { nodes: nodeCount, edges: edgeCount };
|
|
1079
|
-
}
|
|
1080
|
-
finally {
|
|
1081
|
-
closeDb(db);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
else {
|
|
1085
|
-
result['note'] = 'Monograph index not built — run `monomind monograph build` for deep learning';
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
catch { /* monograph unavailable — return minimal result */ }
|
|
1089
|
-
return result;
|
|
1090
|
-
}
|
|
1091
|
-
/**
|
|
1092
|
-
* Local deepdive worker (fallback when headless unavailable)
|
|
1093
|
-
*/
|
|
1094
|
-
async runDeepdiveWorkerLocal() {
|
|
1095
|
-
const deepdiveFile = join(this.projectRoot, '.monomind', 'metrics', 'deepdive.json');
|
|
1096
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
1097
|
-
if (!existsSync(metricsDir)) {
|
|
1098
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
1099
|
-
}
|
|
1100
|
-
const result = {
|
|
1101
|
-
timestamp: new Date().toISOString(),
|
|
1102
|
-
mode: 'local',
|
|
1103
|
-
analysisDepth: 'graph',
|
|
1104
|
-
findings: [],
|
|
1105
|
-
};
|
|
1106
|
-
// Enrich with monograph god nodes and high-degree file analysis for LLM context injection.
|
|
1107
|
-
// Lazy-import to avoid hard dependency; silently skip on any error.
|
|
1108
|
-
try {
|
|
1109
|
-
const { openDb, closeDb, countNodes, countEdges } = await import('@monoes/monograph');
|
|
1110
|
-
const dbPath = join(this.projectRoot, '.monomind', 'monograph.db');
|
|
1111
|
-
if (existsSync(dbPath)) {
|
|
1112
|
-
const db = openDb(dbPath);
|
|
1113
|
-
try {
|
|
1114
|
-
const nodeCount = countNodes(db);
|
|
1115
|
-
const edgeCount = countEdges(db);
|
|
1116
|
-
const godNodeRows = db.prepare(`
|
|
1117
|
-
SELECT n.name, n.file_path, n.label,
|
|
1118
|
-
COUNT(DISTINCT e1.id) + COUNT(DISTINCT e2.id) AS degree
|
|
1119
|
-
FROM nodes n
|
|
1120
|
-
LEFT JOIN edges e1 ON e1.source_id = n.id
|
|
1121
|
-
LEFT JOIN edges e2 ON e2.target_id = n.id
|
|
1122
|
-
WHERE n.label NOT IN ('File','Folder','Community','Concept')
|
|
1123
|
-
AND (n.file_path IS NULL OR (
|
|
1124
|
-
n.file_path NOT LIKE '%node_modules%'
|
|
1125
|
-
AND n.file_path NOT LIKE '%/dist/%'
|
|
1126
|
-
AND n.file_path NOT LIKE '%.test.%'
|
|
1127
|
-
AND n.file_path NOT LIKE '%.spec.%'
|
|
1128
|
-
))
|
|
1129
|
-
GROUP BY n.id
|
|
1130
|
-
ORDER BY degree DESC
|
|
1131
|
-
LIMIT 5
|
|
1132
|
-
`).all();
|
|
1133
|
-
const godNodes = godNodeRows.map(r => ({
|
|
1134
|
-
name: r.name,
|
|
1135
|
-
label: r.label,
|
|
1136
|
-
file: r.file_path ?? '(unknown)',
|
|
1137
|
-
degree: r.degree,
|
|
1138
|
-
}));
|
|
1139
|
-
const fileRows = db.prepare(`
|
|
1140
|
-
SELECT n.file_path,
|
|
1141
|
-
COUNT(DISTINCT e2.id) AS in_deg,
|
|
1142
|
-
COUNT(DISTINCT e1.id) AS out_deg
|
|
1143
|
-
FROM nodes n
|
|
1144
|
-
LEFT JOIN edges e1 ON e1.source_id = n.id
|
|
1145
|
-
LEFT JOIN edges e2 ON e2.target_id = n.id
|
|
1146
|
-
WHERE n.label = 'File'
|
|
1147
|
-
AND n.file_path NOT LIKE '%node_modules%'
|
|
1148
|
-
AND n.file_path NOT LIKE '%/dist/%'
|
|
1149
|
-
AND n.file_path NOT LIKE '%.test.%'
|
|
1150
|
-
AND n.file_path NOT LIKE '%.spec.%'
|
|
1151
|
-
GROUP BY n.id
|
|
1152
|
-
ORDER BY (in_deg + out_deg) DESC
|
|
1153
|
-
LIMIT 5
|
|
1154
|
-
`).all();
|
|
1155
|
-
const highDegFiles = fileRows.map(r => ({
|
|
1156
|
-
file: r.file_path
|
|
1157
|
-
.replace(this.projectRoot + '/', '')
|
|
1158
|
-
.replace(this.projectRoot + '\\', ''),
|
|
1159
|
-
inDegree: r.in_deg,
|
|
1160
|
-
outDegree: r.out_deg,
|
|
1161
|
-
totalDegree: r.in_deg + r.out_deg,
|
|
1162
|
-
}));
|
|
1163
|
-
const findings = [];
|
|
1164
|
-
if (godNodes.length > 0) {
|
|
1165
|
-
findings.push({
|
|
1166
|
-
category: 'god_nodes',
|
|
1167
|
-
description: `Top ${godNodes.length} high-centrality symbols (most imported/referenced)`,
|
|
1168
|
-
items: godNodes,
|
|
1169
|
-
});
|
|
1170
|
-
}
|
|
1171
|
-
if (highDegFiles.length > 0) {
|
|
1172
|
-
findings.push({
|
|
1173
|
-
category: 'high_degree_files',
|
|
1174
|
-
description: `Top ${highDegFiles.length} files by total edge degree (import + export connections)`,
|
|
1175
|
-
items: highDegFiles,
|
|
1176
|
-
});
|
|
1177
|
-
}
|
|
1178
|
-
result['graph'] = { nodes: nodeCount, edges: edgeCount };
|
|
1179
|
-
result['findings'] = findings;
|
|
1180
|
-
result['analysisDepth'] = 'graph';
|
|
1181
|
-
}
|
|
1182
|
-
finally {
|
|
1183
|
-
closeDb(db);
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
else {
|
|
1187
|
-
result['note'] = 'Monograph index not built — run `monomind monograph build` for deep analysis';
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
catch { /* monograph unavailable — return minimal result */ }
|
|
1191
|
-
const deepdiveFileTmp = deepdiveFile + '.tmp';
|
|
1192
|
-
writeFileSync(deepdiveFileTmp, JSON.stringify(result, null, 2));
|
|
1193
|
-
renameSync(deepdiveFileTmp, deepdiveFile);
|
|
1194
|
-
return result;
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* Local benchmark worker
|
|
1198
|
-
*/
|
|
1199
|
-
async runBenchmarkWorkerLocal() {
|
|
1200
|
-
const benchmarkFile = join(this.projectRoot, '.monomind', 'metrics', 'benchmark.json');
|
|
1201
|
-
const metricsDir = join(this.projectRoot, '.monomind', 'metrics');
|
|
1202
|
-
if (!existsSync(metricsDir)) {
|
|
1203
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
1204
|
-
}
|
|
1205
|
-
const result = {
|
|
1206
|
-
timestamp: new Date().toISOString(),
|
|
1207
|
-
mode: 'local',
|
|
1208
|
-
benchmarks: {
|
|
1209
|
-
memoryUsage: process.memoryUsage(),
|
|
1210
|
-
cpuUsage: process.cpuUsage(),
|
|
1211
|
-
uptime: process.uptime(),
|
|
1212
|
-
},
|
|
1213
|
-
};
|
|
1214
|
-
const benchmarkFileTmp = benchmarkFile + '.tmp';
|
|
1215
|
-
writeFileSync(benchmarkFileTmp, JSON.stringify(result, null, 2));
|
|
1216
|
-
renameSync(benchmarkFileTmp, benchmarkFile);
|
|
1217
|
-
return result;
|
|
1218
|
-
}
|
|
1219
|
-
/**
|
|
1220
|
-
* Manually trigger a worker
|
|
1221
|
-
*/
|
|
1222
|
-
async triggerWorker(type) {
|
|
1223
|
-
const workerConfig = this.config.workers.find(w => w.type === type);
|
|
1224
|
-
if (!workerConfig) {
|
|
1225
|
-
throw new Error(`Unknown worker type: ${type}`);
|
|
1226
|
-
}
|
|
1227
|
-
const result = await this.executeWorkerWithConcurrencyControl(workerConfig);
|
|
1228
|
-
if (result !== null)
|
|
1229
|
-
return result;
|
|
1230
|
-
// Concurrency limit reached — execute directly for explicit manual trigger.
|
|
1231
|
-
// Remove from pendingWorkers to avoid double execution when finally fires.
|
|
1232
|
-
const pendingIdx = this.pendingWorkers.indexOf(workerConfig.type);
|
|
1233
|
-
if (pendingIdx !== -1)
|
|
1234
|
-
this.pendingWorkers.splice(pendingIdx, 1);
|
|
1235
|
-
return this.executeWorker(workerConfig);
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Enable/disable a worker
|
|
1239
|
-
*/
|
|
1240
|
-
setWorkerEnabled(type, enabled) {
|
|
1241
|
-
const workerConfig = this.config.workers.find(w => w.type === type);
|
|
1242
|
-
if (workerConfig) {
|
|
1243
|
-
workerConfig.enabled = enabled;
|
|
1244
|
-
if (enabled && this.running) {
|
|
1245
|
-
this.scheduleWorker(workerConfig);
|
|
1246
|
-
}
|
|
1247
|
-
else if (!enabled) {
|
|
1248
|
-
const timer = this.timers.get(type);
|
|
1249
|
-
if (timer) {
|
|
1250
|
-
clearTimeout(timer);
|
|
1251
|
-
this.timers.delete(type);
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
this.saveState();
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Save daemon state to file
|
|
1259
|
-
*/
|
|
1260
|
-
saveState() {
|
|
1261
|
-
const state = {
|
|
1262
|
-
running: this.running,
|
|
1263
|
-
startedAt: this.startedAt?.toISOString(),
|
|
1264
|
-
workers: Object.fromEntries(Array.from(this.workers.entries()).map(([type, state]) => [
|
|
1265
|
-
type,
|
|
1266
|
-
{
|
|
1267
|
-
...state,
|
|
1268
|
-
lastRun: state.lastRun?.toISOString(),
|
|
1269
|
-
nextRun: state.nextRun?.toISOString(),
|
|
1270
|
-
}
|
|
1271
|
-
])),
|
|
1272
|
-
config: {
|
|
1273
|
-
...this.config,
|
|
1274
|
-
workers: this.config.workers.map(w => ({ ...w })),
|
|
1275
|
-
},
|
|
1276
|
-
savedAt: new Date().toISOString(),
|
|
1277
|
-
};
|
|
1278
|
-
try {
|
|
1279
|
-
const tmp = this.config.stateFile + '.tmp';
|
|
1280
|
-
writeFileSync(tmp, JSON.stringify(state, null, 2));
|
|
1281
|
-
renameSync(tmp, this.config.stateFile);
|
|
1282
|
-
}
|
|
1283
|
-
catch (error) {
|
|
1284
|
-
this.log('error', `Failed to save state: ${error}`);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
/**
|
|
1288
|
-
* Log message
|
|
1289
|
-
*/
|
|
1290
|
-
log(level, message) {
|
|
1291
|
-
const timestamp = new Date().toISOString();
|
|
1292
|
-
const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
|
|
1293
|
-
this.emit('log', { level, message, timestamp });
|
|
1294
|
-
// Also write to log file
|
|
1295
|
-
try {
|
|
1296
|
-
const logFile = join(this.config.logDir, 'daemon.log');
|
|
1297
|
-
appendFileSync(logFile, logMessage + '\n');
|
|
1298
|
-
// Opportunistic rotation: keep the log under 10 MB. When exceeded,
|
|
1299
|
-
// discard the oldest half so recent entries are always retained.
|
|
1300
|
-
const MAX_LOG_BYTES = 10 * 1024 * 1024;
|
|
1301
|
-
if (statSync(logFile).size > MAX_LOG_BYTES) {
|
|
1302
|
-
const content = readFileSync(logFile, 'utf-8');
|
|
1303
|
-
const lines = content.split('\n').filter(Boolean);
|
|
1304
|
-
const trimmed = lines.slice(Math.floor(lines.length / 2)).join('\n') + '\n';
|
|
1305
|
-
const tmp = `${logFile}.${process.pid}.${Date.now()}.tmp`;
|
|
1306
|
-
writeFileSync(tmp, trimmed);
|
|
1307
|
-
renameSync(tmp, logFile);
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
catch {
|
|
1311
|
-
// Ignore log write errors
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
// Singleton instance for global access
|
|
1316
|
-
let daemonInstance = null;
|
|
1317
|
-
/**
|
|
1318
|
-
* Get or create daemon instance
|
|
1319
|
-
*/
|
|
1320
|
-
export function getDaemon(projectRoot, config) {
|
|
1321
|
-
if (!daemonInstance && projectRoot) {
|
|
1322
|
-
daemonInstance = new WorkerDaemon(projectRoot, config);
|
|
1323
|
-
}
|
|
1324
|
-
if (!daemonInstance) {
|
|
1325
|
-
throw new Error('Daemon not initialized. Provide projectRoot on first call.');
|
|
1326
|
-
}
|
|
1327
|
-
return daemonInstance;
|
|
1328
|
-
}
|
|
1329
|
-
/**
|
|
1330
|
-
* Start daemon (for use in session-start hook)
|
|
1331
|
-
*/
|
|
1332
|
-
export async function startDaemon(projectRoot, config) {
|
|
1333
|
-
// A2: the daemon is a long-lived host — keep the SONA write-path enabled so
|
|
1334
|
-
// trajectories accumulate across worker runs and reach the consolidation
|
|
1335
|
-
// threshold (see startMCPServer for the one-shot-CLI rationale).
|
|
1336
|
-
process.env.MONOMIND_PERSISTENT_HOST = '1';
|
|
1337
|
-
const daemon = getDaemon(projectRoot, config);
|
|
1338
|
-
await daemon.start();
|
|
1339
|
-
return daemon;
|
|
1340
|
-
}
|
|
1341
|
-
/**
|
|
1342
|
-
* Stop daemon
|
|
1343
|
-
*/
|
|
1344
|
-
export async function stopDaemon() {
|
|
1345
|
-
if (daemonInstance) {
|
|
1346
|
-
await daemonInstance.stop();
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
export default WorkerDaemon;
|
|
1350
|
-
//# sourceMappingURL=worker-daemon.js.map
|