monomind 1.14.7 → 1.15.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/.claude/agents/reengineer-squad/boss.md +113 -0
- package/.claude/agents/reengineer-squad/critic-architect.md +132 -0
- package/.claude/agents/reengineer-squad/git-manager.md +145 -0
- package/.claude/agents/reengineer-squad/idea-generator.md +95 -0
- package/.claude/agents/reengineer-squad/implementer.md +112 -0
- package/.claude/agents/reengineer-squad/integration-planner.md +112 -0
- package/.claude/agents/reengineer-squad/source-analyst.md +103 -0
- package/.claude/agents/reengineer-squad/target-analyst.md +118 -0
- package/.claude/agents/reengineer-squad/tester.md +105 -0
- package/.claude/commands/mastermind/master.md +35 -14
- package/.claude/helpers/handlers/capture-handler.cjs +155 -18
- package/.claude/helpers/monolean-activate.cjs +20 -0
- package/.claude/helpers/monolean-config.cjs +76 -0
- package/.claude/helpers/monolean-instructions.cjs +109 -0
- package/.claude/helpers/monolean-propagate.cjs +9 -0
- package/.claude/helpers/monolean-tracker.cjs +18 -0
- package/.claude/helpers/skill-registry.json +2 -2
- package/.claude/settings.json +34 -2
- package/.claude/skills/agent-browser-testing/SKILL.md +301 -18
- package/.claude/skills/mastermind/runorg.md +69 -23
- package/.claude/skills/monodesign/SKILL.md +32 -1
- package/.claude/skills/monodesign/adapt.md +53 -0
- package/.claude/skills/monodesign/agents/monodesign-asset-producer.md +100 -0
- package/.claude/skills/monodesign/animate.md +65 -0
- package/.claude/skills/monodesign/audit.md +89 -0
- package/.claude/skills/monodesign/bolder.md +50 -0
- package/.claude/skills/monodesign/clarify.md +64 -0
- package/.claude/skills/monodesign/colorize.md +68 -0
- package/.claude/skills/monodesign/craft.md +51 -0
- package/.claude/skills/monodesign/critique.md +66 -0
- package/.claude/skills/monodesign/delight.md +47 -0
- package/.claude/skills/monodesign/distill.md +56 -0
- package/.claude/skills/monodesign/document.md +80 -0
- package/.claude/skills/monodesign/extract.md +74 -0
- package/.claude/skills/monodesign/harden.md +65 -0
- package/.claude/skills/monodesign/live.md +59 -0
- package/.claude/skills/monodesign/onboard.md +50 -0
- package/.claude/skills/monodesign/optimize.md +64 -0
- package/.claude/skills/monodesign/overdrive.md +56 -0
- package/.claude/skills/monodesign/polish.md +68 -0
- package/.claude/skills/monodesign/quieter.md +57 -0
- package/.claude/skills/monodesign/reference/antipatterns-catalog.md +248 -76
- package/.claude/skills/monodesign/reference/codex.md +107 -0
- package/.claude/skills/monodesign/reference/craft.md +3 -0
- package/.claude/skills/monodesign/reference/hooks.md +99 -0
- package/.claude/skills/monodesign/reference/image-prompts.md +12 -0
- package/.claude/skills/monodesign/shape.md +71 -0
- package/.claude/skills/monodesign/teach.md +69 -0
- package/.claude/skills/monodesign/typeset.md +59 -0
- package/.claude/skills/monolean/SKILL.md +118 -0
- package/.claude/skills/monolean-audit/SKILL.md +41 -0
- package/.claude/skills/monolean-debt/SKILL.md +46 -0
- package/.claude/skills/monolean-help/SKILL.md +60 -0
- package/.claude/skills/monolean-review/SKILL.md +57 -0
- package/package.json +8 -3
- package/packages/@monomind/cli/bin/cli.js +3 -1
- package/packages/@monomind/cli/dist/dashboard/server.js +137 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-adapters.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-adapters.test.js +51 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +68 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-builtin-handlers.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-builtin-handlers.test.js +139 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-cdp.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-cdp.test.js +169 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-dashboard.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-dashboard.test.js +179 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-engine.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-engine.test.js +122 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-expression.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-expression.test.js +54 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-store.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-store.test.js +99 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-workflow-types.test.d.ts +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-workflow-types.test.js +33 -0
- package/packages/@monomind/cli/dist/src/browser/action-builder/analyzer.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/browser/action-builder/analyzer.js +71 -0
- package/packages/@monomind/cli/dist/src/browser/action-builder/types.d.ts +47 -0
- package/packages/@monomind/cli/dist/src/browser/action-builder/types.js +2 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/gemini.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/gemini.js +16 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/google.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/google.js +17 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/index.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/index.js +23 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/instagram.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/instagram.js +17 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/linkedin.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/linkedin.js +19 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/microsoft.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/microsoft.js +16 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/x.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/adapters/x.js +19 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/api-types.d.ts +50 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/api-types.js +14 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +62 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +1811 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/builtin-handlers.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/builtin-handlers.js +343 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/engine.d.ts +15 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/engine.js +127 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/expression.d.ts +4 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/expression.js +64 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/store.d.ts +24 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/store.js +145 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/types.d.ts +48 -0
- package/packages/@monomind/cli/dist/src/browser/workflow/types.js +2 -0
- package/packages/@monomind/cli/dist/src/commands/browse-action.d.ts +4 -0
- package/packages/@monomind/cli/dist/src/commands/browse-action.js +151 -0
- package/packages/@monomind/cli/dist/src/commands/browse-platform.d.ts +4 -0
- package/packages/@monomind/cli/dist/src/commands/browse-platform.js +117 -0
- package/packages/@monomind/cli/dist/src/commands/browse-workflow.d.ts +4 -0
- package/packages/@monomind/cli/dist/src/commands/browse-workflow.js +153 -0
- package/packages/@monomind/cli/dist/src/commands/browse.d.ts +10 -6
- package/packages/@monomind/cli/dist/src/commands/browse.js +11 -2154
- package/packages/@monomind/cli/dist/src/commands/design-detect.d.ts +21 -0
- package/packages/@monomind/cli/dist/src/commands/design-detect.js +127 -0
- package/packages/@monomind/cli/dist/src/commands/design-palette.d.ts +22 -0
- package/packages/@monomind/cli/dist/src/commands/design-palette.js +539 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-core-commands.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-core-commands.js +377 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1217 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-utils.d.ts +42 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-utils.js +220 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.js +579 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-formatting.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-formatting.js +42 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-routing-commands.d.ts +15 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-routing-commands.js +723 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +782 -0
- package/packages/@monomind/cli/dist/src/commands/hooks.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/hooks.js +179 -4103
- package/packages/@monomind/cli/dist/src/commands/index.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/commands/index.js +6 -0
- package/packages/@monomind/cli/dist/src/commands/org.js +14 -15
- package/packages/@monomind/cli/dist/src/commands/tokens.js +77 -1
- package/packages/@monomind/cli/dist/src/graph/enrich.mjs +362 -0
- package/packages/@monomind/cli/dist/src/init/executor.js +18 -8
- package/packages/@monomind/cli/dist/src/init/settings-generator.js +39 -5
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +25 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.d.ts +3 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +619 -326
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-embedding.d.ts +161 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-embedding.js +506 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +1328 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.d.ts +27 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +1591 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.d.ts +3 -38
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +5 -3393
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +24 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +54 -1
- package/packages/@monomind/cli/dist/src/memory/embedding-operations.d.ts +58 -0
- package/packages/@monomind/cli/dist/src/memory/embedding-operations.js +299 -0
- package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +37 -3
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.d.ts +130 -0
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +400 -0
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +42 -23
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +52 -8
- package/packages/@monomind/cli/dist/src/memory/memory-crud.d.ts +67 -0
- package/packages/@monomind/cli/dist/src/memory/memory-crud.js +415 -0
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.d.ts +9 -322
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +17 -1794
- package/packages/@monomind/cli/dist/src/memory/memory-migrations.d.ts +30 -0
- package/packages/@monomind/cli/dist/src/memory/memory-migrations.js +134 -0
- package/packages/@monomind/cli/dist/src/memory/memory-read.d.ts +78 -0
- package/packages/@monomind/cli/dist/src/memory/memory-read.js +331 -0
- package/packages/@monomind/cli/dist/src/memory/memory-schema.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/memory/memory-schema.js +167 -0
- package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +37 -4
- package/packages/@monomind/cli/dist/src/monovector/route-outcomes.js +16 -6
- package/packages/@monomind/cli/dist/src/pricing/model-pricing.d.ts +41 -0
- package/packages/@monomind/cli/dist/src/pricing/model-pricing.js +61 -0
- package/packages/@monomind/cli/dist/src/ui/.monomind/capture/active-run.json +1 -0
- package/packages/@monomind/cli/dist/src/ui/collector.mjs +799 -0
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +13986 -0
- package/packages/@monomind/cli/dist/src/ui/data/agent-avatars.html +763 -0
- package/packages/@monomind/cli/dist/src/ui/data/agent-avatars.json +966 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/account-strategist.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/accounts-payable.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/adaptive-coordinator.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/adaptive-coordinator2.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/ai-citation.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/ai-engineer.svg +61 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/analytics-reporter.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/api-tester.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/architecture.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/automation-governance.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/backend-dev.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/benchmarker.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/blockchain-auditor.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/byzantine-coord.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/case-analyst.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/cicd-engineer.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/cloud-architect.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/code-review-swarm.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/coder-v119.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/coder.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/collective-coord.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/compliance-auditor.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/consensus-coordinator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/content-creator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/crdt-synchronizer.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/cro-specialist.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/data-consolidator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/data-engineer.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/database-optimizer.svg +61 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/deal-strategist.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/defender.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/devops-automator.svg +56 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/discovery-coach.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/email-marketing.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/embedded-firmware.svg +61 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/evidence-collector.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/experiment-tracker.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/feedback-synthesizer.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/finance-tracker.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/frontend-developer.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/game-audio-engineer.svg +59 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/game-designer.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/gossip-coordinator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/hierarchical-coord.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/incident-commander.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/infrastructure.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/input-validator.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/ios-developer.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/issue-tracker.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/judge.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/launch-strategist.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/legal-compliance.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/level-designer.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/load-balancer.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/mcp-builder.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/memory-coordinator.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/mesh-coordinator.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/ml-developer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/mobile-app-builder.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/mobile-dev.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/model-qa.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/narrative-designer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/outbound-strategist.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/path-validator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/payment-agent.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/perf-analyzer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/pipeline-analyst.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/planner.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/pr-manager.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/pricing-strategist.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/product-manager.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/production-validator.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/project-shepherd.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/proposal-strategist.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/prosecutor.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/pseudocode.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/queen-coordinator.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/quorum-manager.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/raft-manager.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/reality-checker.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/recruitment.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/refinement.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/release-manager.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/repo-architect.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/researcher.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/resource-allocator.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/reviewer.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/safe-executor.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sales-coach.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sales-engineer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/scout-explorer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/security-architect.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/security-auditor.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/senior-developer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/senior-pm.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/seo-specialist.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/social-media.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/solidity-engineer.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sparc-coder.svg +58 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sparc-coord.svg +56 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/specification.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sprint-prioritizer.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/sre.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/studio-operations.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/studio-producer.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/support-responder.svg +56 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/system-architect.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/task-orchestrator.svg +56 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/technical-artist.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/technical-writer.svg +59 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/tester.svg +53 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/threat-detection.svg +61 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/trend-researcher.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/trial-director.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/unity-architect.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/visionos-engineer.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/worker-specialist.svg +55 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/workflow-architect.svg +57 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/workflow-automation.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/avatars/zk-steward.svg +54 -0
- package/packages/@monomind/cli/dist/src/ui/data/known-projects.json +1 -0
- package/packages/@monomind/cli/dist/src/ui/data/mastermind-sessions.json +1 -0
- package/packages/@monomind/cli/dist/src/ui/data/sessions/_index.json +1 -0
- package/packages/@monomind/cli/dist/src/ui/orgs.html +2215 -0
- package/packages/@monomind/cli/dist/src/ui/server.mjs +6206 -0
- package/packages/@monomind/cli/dist/src/ui/sse-manager.mjs +119 -0
- package/packages/@monomind/cli/dist/src/update/checker.js +1 -1
- package/packages/@monomind/cli/dist/workflow/builtin-handlers.js +321 -0
- package/packages/@monomind/cli/dist/workflow/engine.js +253 -0
- package/packages/@monomind/cli/dist/workflow/expression.js +98 -0
- package/packages/@monomind/cli/dist/workflow/types.js +2 -0
- package/packages/@monomind/cli/package.json +8 -6
|
@@ -31,6 +31,7 @@ export { cleanupCommand } from './cleanup.js';
|
|
|
31
31
|
export { autopilotCommand } from './autopilot.js';
|
|
32
32
|
export { monographCommand } from './monograph.js';
|
|
33
33
|
export { platformsCommand } from './platforms.js';
|
|
34
|
+
export { designCommand } from './design-detect.js';
|
|
34
35
|
export declare function getConfigCommand(): Promise<Command | undefined>;
|
|
35
36
|
export declare function getMigrateCommand(): Promise<Command | undefined>;
|
|
36
37
|
export declare function getWorkflowCommand(): Promise<Command | undefined>;
|
|
@@ -70,6 +70,8 @@ const commandLoaders = {
|
|
|
70
70
|
platforms: () => import('./platforms.js'),
|
|
71
71
|
// Org management (list, delete)
|
|
72
72
|
org: () => import('./org.js'),
|
|
73
|
+
// Design tooling (anti-pattern detection)
|
|
74
|
+
design: () => import('./design-detect.js'),
|
|
73
75
|
};
|
|
74
76
|
// Cache for loaded commands
|
|
75
77
|
const loadedCommands = new Map();
|
|
@@ -146,6 +148,7 @@ import { benchmarkCommand } from './benchmark.js';
|
|
|
146
148
|
import storeCommand from './transfer-store.js';
|
|
147
149
|
import tokensCommand from './tokens.js';
|
|
148
150
|
import { platformsCommand } from './platforms.js';
|
|
151
|
+
import { designCommand } from './design-detect.js';
|
|
149
152
|
// Pre-populate cache with core commands
|
|
150
153
|
loadedCommands.set('init', initCommand);
|
|
151
154
|
loadedCommands.set('start', startCommand);
|
|
@@ -174,6 +177,7 @@ loadedCommands.set('transfer-store', storeCommand);
|
|
|
174
177
|
loadedCommands.set('tokens', tokensCommand);
|
|
175
178
|
loadedCommands.set('platforms', platformsCommand);
|
|
176
179
|
loadedCommands.set('browse', browseCommand);
|
|
180
|
+
loadedCommands.set('design', designCommand);
|
|
177
181
|
// =============================================================================
|
|
178
182
|
// Exports (maintain backwards compatibility)
|
|
179
183
|
// =============================================================================
|
|
@@ -200,6 +204,7 @@ export { cleanupCommand } from './cleanup.js';
|
|
|
200
204
|
export { autopilotCommand } from './autopilot.js';
|
|
201
205
|
export { monographCommand } from './monograph.js';
|
|
202
206
|
export { platformsCommand } from './platforms.js';
|
|
207
|
+
export { designCommand } from './design-detect.js';
|
|
203
208
|
// Lazy-loaded command re-exports (for backwards compatibility, but async-only)
|
|
204
209
|
export async function getConfigCommand() { return loadCommand('config'); }
|
|
205
210
|
export async function getMigrateCommand() { return loadCommand('migrate'); }
|
|
@@ -253,6 +258,7 @@ export const commands = [
|
|
|
253
258
|
autopilotCommand,
|
|
254
259
|
monographCommand,
|
|
255
260
|
platformsCommand,
|
|
261
|
+
designCommand,
|
|
256
262
|
];
|
|
257
263
|
/**
|
|
258
264
|
* Commands organized by category for help display
|
|
@@ -4,14 +4,13 @@ import { join, resolve } from 'path';
|
|
|
4
4
|
const orgCommand = {
|
|
5
5
|
name: 'org',
|
|
6
6
|
description: 'Manage monomind organisations',
|
|
7
|
-
subcommands: ['delete', 'list'],
|
|
8
|
-
usage: 'monomind org <subcommand> [options]',
|
|
9
7
|
examples: [
|
|
10
|
-
'monomind org list',
|
|
11
|
-
'monomind org delete my-org',
|
|
12
|
-
'monomind org delete my-org --yes',
|
|
8
|
+
{ command: 'monomind org list', description: 'List all orgs in the project' },
|
|
9
|
+
{ command: 'monomind org delete my-org', description: 'Delete an org (with confirmation)' },
|
|
10
|
+
{ command: 'monomind org delete my-org --yes', description: 'Delete without confirmation' },
|
|
13
11
|
],
|
|
14
|
-
async
|
|
12
|
+
action: async (context) => {
|
|
13
|
+
const args = context.args ?? [];
|
|
15
14
|
const sub = args[0];
|
|
16
15
|
if (!sub || sub === 'help') {
|
|
17
16
|
output.info('Usage: monomind org <subcommand>');
|
|
@@ -22,7 +21,7 @@ const orgCommand = {
|
|
|
22
21
|
return { success: true };
|
|
23
22
|
}
|
|
24
23
|
if (sub === 'list') {
|
|
25
|
-
const cwd = context.
|
|
24
|
+
const cwd = context.cwd || process.cwd();
|
|
26
25
|
const orgsDir = join(cwd, '.monomind', 'orgs');
|
|
27
26
|
if (!existsSync(orgsDir)) {
|
|
28
27
|
output.info('No orgs directory found. Create an org first with /mastermind:createorg');
|
|
@@ -45,24 +44,24 @@ const orgCommand = {
|
|
|
45
44
|
const orgName = args[1];
|
|
46
45
|
if (!orgName) {
|
|
47
46
|
output.error('Usage: monomind org delete <name>');
|
|
48
|
-
return { success: false,
|
|
47
|
+
return { success: false, message: 'org name required' };
|
|
49
48
|
}
|
|
50
49
|
if (!/^[a-z0-9][a-z0-9_-]*$/i.test(orgName)) {
|
|
51
50
|
output.error(`Invalid org name: ${orgName}`);
|
|
52
|
-
return { success: false,
|
|
51
|
+
return { success: false, message: 'invalid org name' };
|
|
53
52
|
}
|
|
54
53
|
const confirmed = args.includes('--yes') || args.includes('-y');
|
|
55
54
|
if (!confirmed) {
|
|
56
|
-
output.
|
|
57
|
-
output.
|
|
58
|
-
return { success: false,
|
|
55
|
+
output.warning(`This will permanently delete org "${orgName}" and all its data.`);
|
|
56
|
+
output.warning('Pass --yes to confirm.');
|
|
57
|
+
return { success: false, message: 'confirmation required' };
|
|
59
58
|
}
|
|
60
|
-
const cwd = resolve(context.
|
|
59
|
+
const cwd = resolve(context.cwd || process.cwd());
|
|
61
60
|
const orgsDir = join(cwd, '.monomind', 'orgs');
|
|
62
61
|
const configFile = join(orgsDir, `${orgName}.json`);
|
|
63
62
|
if (!existsSync(configFile)) {
|
|
64
63
|
output.error(`Org not found: ${orgName}`);
|
|
65
|
-
return { success: false,
|
|
64
|
+
return { success: false, message: 'org not found' };
|
|
66
65
|
}
|
|
67
66
|
const suffixes = ['', '-state', '-goals', '-routines', '-approvals', '-activity',
|
|
68
67
|
'-issues', '-members', '-projects', '-workspaces', '-worktrees', '-environments',
|
|
@@ -107,7 +106,7 @@ const orgCommand = {
|
|
|
107
106
|
return { success: true };
|
|
108
107
|
}
|
|
109
108
|
output.error(`Unknown subcommand: ${sub}. Run "monomind org help" for usage.`);
|
|
110
|
-
return { success: false,
|
|
109
|
+
return { success: false, message: `unknown subcommand: ${sub}` };
|
|
111
110
|
},
|
|
112
111
|
};
|
|
113
112
|
export default orgCommand;
|
|
@@ -103,10 +103,86 @@ const todaySubcommand = {
|
|
|
103
103
|
}
|
|
104
104
|
},
|
|
105
105
|
};
|
|
106
|
+
const leanDeltaSubcommand = {
|
|
107
|
+
name: 'lean-delta',
|
|
108
|
+
description: 'Compare token cost: sessions with monolean active vs without',
|
|
109
|
+
options: [],
|
|
110
|
+
action: async (_ctx) => {
|
|
111
|
+
try {
|
|
112
|
+
const { join: pathJoin, dirname: pathDirname } = await import('path');
|
|
113
|
+
const { fileURLToPath } = await import('url');
|
|
114
|
+
const { readdirSync, readFileSync } = await import('fs');
|
|
115
|
+
// Locate capture directory
|
|
116
|
+
const __dirname = pathDirname(fileURLToPath(import.meta.url));
|
|
117
|
+
const projectRoot = pathJoin(__dirname, '..', '..', '..', '..', '..', '..');
|
|
118
|
+
const captureDir = pathJoin(projectRoot, '.monomind', 'capture');
|
|
119
|
+
// Load all run capture logs
|
|
120
|
+
let snapshots = [];
|
|
121
|
+
try {
|
|
122
|
+
const orgsDir = pathJoin(projectRoot, '.monomind', 'orgs');
|
|
123
|
+
const orgEntries = readdirSync(orgsDir, { withFileTypes: true });
|
|
124
|
+
for (const org of orgEntries) {
|
|
125
|
+
if (!org.isDirectory())
|
|
126
|
+
continue;
|
|
127
|
+
const runsDir = pathJoin(orgsDir, org.name, 'runs');
|
|
128
|
+
try {
|
|
129
|
+
const runFiles = readdirSync(runsDir).filter(f => f.endsWith('-captures.jsonl'));
|
|
130
|
+
for (const rf of runFiles) {
|
|
131
|
+
const lines = readFileSync(pathJoin(runsDir, rf), 'utf8').split('\n').filter(Boolean);
|
|
132
|
+
for (const line of lines) {
|
|
133
|
+
try {
|
|
134
|
+
snapshots.push(JSON.parse(line));
|
|
135
|
+
}
|
|
136
|
+
catch { /* skip */ }
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch { /* no runs dir */ }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch { /* no orgs dir */ }
|
|
144
|
+
// Also check snap files in capture dir for leanMode field
|
|
145
|
+
try {
|
|
146
|
+
const snapFiles = readdirSync(captureDir).filter(f => f.startsWith('snap-') && f.endsWith('.json'));
|
|
147
|
+
for (const sf of snapFiles) {
|
|
148
|
+
try {
|
|
149
|
+
snapshots.push(JSON.parse(readFileSync(pathJoin(captureDir, sf), 'utf8')));
|
|
150
|
+
}
|
|
151
|
+
catch { /* skip */ }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch { /* no capture dir */ }
|
|
155
|
+
const lean = snapshots.filter(s => s.leanMode && s.leanMode !== 'off' && s.cost_usd != null);
|
|
156
|
+
const normal = snapshots.filter(s => (!s.leanMode || s.leanMode === 'off') && s.cost_usd != null);
|
|
157
|
+
if (lean.length < 3 || normal.length < 3) {
|
|
158
|
+
output.writeln('Not enough data yet. Need 3+ sessions in each group.');
|
|
159
|
+
output.writeln(`Current: ${lean.length} lean sessions, ${normal.length} normal sessions.`);
|
|
160
|
+
return { success: true };
|
|
161
|
+
}
|
|
162
|
+
const avg = (arr) => arr.reduce((s, x) => s + (x.cost_usd || 0), 0) / arr.length;
|
|
163
|
+
const leanAvg = avg(lean);
|
|
164
|
+
const normalAvg = avg(normal);
|
|
165
|
+
const delta = ((leanAvg - normalAvg) / normalAvg * 100).toFixed(1);
|
|
166
|
+
const sign = leanAvg <= normalAvg ? '' : '+';
|
|
167
|
+
output.writeln('');
|
|
168
|
+
output.writeln('Monolean Token Delta');
|
|
169
|
+
output.writeln('─'.repeat(50));
|
|
170
|
+
output.writeln(`Sessions with monolean: ${lean.length.toString().padStart(4)} avg cost: $${leanAvg.toFixed(4)}`);
|
|
171
|
+
output.writeln(`Sessions without: ${normal.length.toString().padStart(4)} avg cost: $${normalAvg.toFixed(4)}`);
|
|
172
|
+
output.writeln(`delta: ${sign}${delta}%`);
|
|
173
|
+
output.writeln('');
|
|
174
|
+
return { success: true, data: { leanSessions: lean.length, normalSessions: normal.length, leanAvg, normalAvg, deltaPct: parseFloat(delta) } };
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
output.error('lean-delta error: ' + (err instanceof Error ? err.message : String(err)));
|
|
178
|
+
return { success: false };
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
};
|
|
106
182
|
export const tokensCommand = {
|
|
107
183
|
name: 'tokens',
|
|
108
184
|
description: 'Token usage tracking and cost visualization',
|
|
109
|
-
subcommands: [dashboardSubcommand, summarySubcommand, todaySubcommand],
|
|
185
|
+
subcommands: [dashboardSubcommand, summarySubcommand, todaySubcommand, leanDeltaSubcommand],
|
|
110
186
|
};
|
|
111
187
|
export default tokensCommand;
|
|
112
188
|
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// post-build knowledge graph enrichment engine
|
|
2
|
+
// Reads graph.json, enriches nodes with TypeScript AST data, resolves
|
|
3
|
+
// cross-module calls, computes PageRank + eigenvector centrality,
|
|
4
|
+
// then writes graph.enriched.json.
|
|
5
|
+
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import crypto from 'crypto';
|
|
9
|
+
import { createRequire } from 'module';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
// packages/@monomind/cli/dist/src/graph/ → 6 levels up → project root
|
|
15
|
+
const projectRoot = path.resolve(__dirname, '../../../../../..');
|
|
16
|
+
const _require = createRequire(path.join(projectRoot, 'package.json'));
|
|
17
|
+
|
|
18
|
+
// ── dependencies ──────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
let ts;
|
|
21
|
+
try { ts = _require('typescript'); }
|
|
22
|
+
catch { ts = _require(path.join(projectRoot, 'node_modules/typescript/lib/typescript.js')); }
|
|
23
|
+
|
|
24
|
+
function findPnpmPkg(name) {
|
|
25
|
+
const pnpmDir = path.join(projectRoot, 'node_modules', '.pnpm');
|
|
26
|
+
if (!fs.existsSync(pnpmDir)) return null;
|
|
27
|
+
const prefix = name.replace('/', '+') + '@';
|
|
28
|
+
const entries = fs.readdirSync(pnpmDir).filter(e => e.startsWith(prefix)).sort().reverse();
|
|
29
|
+
return entries.length ? path.join(pnpmDir, entries[0], 'node_modules', name) : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function loadGraphology() {
|
|
33
|
+
for (const fn of [() => _require('graphology'), () => _require(findPnpmPkg('graphology'))]) {
|
|
34
|
+
try { const m = fn(); return m.default ?? m; } catch {}
|
|
35
|
+
}
|
|
36
|
+
throw new Error('graphology not found');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function loadGraphologyMetrics() {
|
|
40
|
+
const base = findPnpmPkg('graphology-metrics') ?? path.join(projectRoot, 'node_modules/graphology-metrics');
|
|
41
|
+
return {
|
|
42
|
+
assignPageRank: _require(path.join(base, 'centrality/pagerank')).assign,
|
|
43
|
+
assignEigen: _require(path.join(base, 'centrality/eigenvector')).assign,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ── cache ─────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
const sha256 = str => crypto.createHash('sha256').update(str).digest('hex');
|
|
50
|
+
const cacheFileFor = (fp, dir) => path.join(dir, sha256(fp) + '.json');
|
|
51
|
+
|
|
52
|
+
function readFromCache(filePath, cacheDir) {
|
|
53
|
+
try {
|
|
54
|
+
const cf = cacheFileFor(filePath, cacheDir);
|
|
55
|
+
if (fs.statSync(cf).mtimeMs >= fs.statSync(filePath).mtimeMs)
|
|
56
|
+
return JSON.parse(fs.readFileSync(cf, 'utf8'));
|
|
57
|
+
} catch {}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function writeToCache(filePath, data, cacheDir) {
|
|
62
|
+
try {
|
|
63
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
64
|
+
fs.writeFileSync(cacheFileFor(filePath, cacheDir), JSON.stringify(data));
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ── TypeScript AST extraction ─────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
function getJsDoc(node, sf) {
|
|
71
|
+
try {
|
|
72
|
+
return (ts.getJSDocCommentsAndTags(node) ?? [])
|
|
73
|
+
.filter(t => ts.isJSDoc(t))
|
|
74
|
+
.map(t => typeof t.comment === 'string' ? t.comment : '')
|
|
75
|
+
.join('\n').trim();
|
|
76
|
+
} catch { return ''; }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const getParams = (node, sf) => (node.parameters ?? []).map(p => ({
|
|
80
|
+
name: p.name?.getText(sf) ?? '', type: p.type?.getText(sf) ?? 'any', optional: !!p.questionToken,
|
|
81
|
+
}));
|
|
82
|
+
|
|
83
|
+
const buildSig = (params, ret) => {
|
|
84
|
+
const ps = params.map(p => `${p.name}${p.optional ? '?' : ''}: ${p.type}`).join(', ');
|
|
85
|
+
return `(${ps})${ret ? ': ' + ret : ''}`;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const isExported = node => !!(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export);
|
|
89
|
+
const lineOf = (node, sf) => sf.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
90
|
+
|
|
91
|
+
function extractSymbolsFromAst(filePath, content) {
|
|
92
|
+
const sf = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
93
|
+
const symbols = new Map();
|
|
94
|
+
|
|
95
|
+
function visit(node) {
|
|
96
|
+
try {
|
|
97
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
98
|
+
const params = getParams(node, sf); const ret = node.type?.getText(sf) ?? '';
|
|
99
|
+
symbols.set(node.name.getText(sf), { kind: 'function', signature: buildSig(params, ret),
|
|
100
|
+
parameters: params, returnType: ret, isExported: isExported(node),
|
|
101
|
+
documentation: getJsDoc(node, sf), lineStart: lineOf(node, sf) });
|
|
102
|
+
} else if (ts.isClassDeclaration(node) && node.name) {
|
|
103
|
+
const name = node.name.getText(sf);
|
|
104
|
+
const heritage = (node.heritageClauses ?? []).flatMap(c => c.types.map(t => t.expression.getText(sf)));
|
|
105
|
+
const methods = (node.members ?? []).filter(m => ts.isMethodDeclaration(m) && m.name).map(m => {
|
|
106
|
+
const mp = getParams(m, sf); const mr = m.type?.getText(sf) ?? '';
|
|
107
|
+
return { name: m.name.getText(sf), signature: buildSig(mp, mr), documentation: getJsDoc(m, sf) };
|
|
108
|
+
});
|
|
109
|
+
symbols.set(name, { kind: 'class', signature: name + (heritage.length ? ' extends ' + heritage[0] : ''),
|
|
110
|
+
parameters: [], returnType: '', isExported: isExported(node),
|
|
111
|
+
documentation: getJsDoc(node, sf), lineStart: lineOf(node, sf), heritage, methods });
|
|
112
|
+
} else if (ts.isInterfaceDeclaration(node) && node.name) {
|
|
113
|
+
const name = node.name.getText(sf);
|
|
114
|
+
symbols.set(name, { kind: 'interface', signature: name, parameters: [], returnType: '',
|
|
115
|
+
isExported: isExported(node), documentation: getJsDoc(node, sf), lineStart: lineOf(node, sf) });
|
|
116
|
+
} else if (ts.isTypeAliasDeclaration(node) && node.name) {
|
|
117
|
+
const name = node.name.getText(sf);
|
|
118
|
+
symbols.set(name, { kind: 'type', signature: name, parameters: [], returnType: '',
|
|
119
|
+
isExported: isExported(node), documentation: getJsDoc(node, sf), lineStart: lineOf(node, sf) });
|
|
120
|
+
} else if (ts.isVariableStatement(node)) {
|
|
121
|
+
const exp = isExported(node);
|
|
122
|
+
for (const decl of node.declarationList.declarations) {
|
|
123
|
+
if (decl.name && decl.initializer &&
|
|
124
|
+
(ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {
|
|
125
|
+
const params = getParams(decl.initializer, sf); const ret = decl.initializer.type?.getText(sf) ?? '';
|
|
126
|
+
symbols.set(decl.name.getText(sf), { kind: 'variable', signature: buildSig(params, ret),
|
|
127
|
+
parameters: params, returnType: ret, isExported: exp,
|
|
128
|
+
documentation: getJsDoc(node, sf), lineStart: lineOf(node, sf) });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
133
|
+
ts.forEachChild(node, visit);
|
|
134
|
+
}
|
|
135
|
+
ts.forEachChild(sf, visit);
|
|
136
|
+
return symbols;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function extractImportMap(filePath, content) {
|
|
140
|
+
const sf = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
141
|
+
const importMap = new Map();
|
|
142
|
+
function visit(node) {
|
|
143
|
+
if (ts.isImportDeclaration(node)) {
|
|
144
|
+
try {
|
|
145
|
+
const spec = node.moduleSpecifier.getText(sf).replace(/^['"]|['"]$/g, '');
|
|
146
|
+
if (!spec.startsWith('.')) return; // skip node_modules
|
|
147
|
+
const resolved = resolveRelativeImport(spec, filePath);
|
|
148
|
+
if (!resolved) return;
|
|
149
|
+
const clause = node.importClause;
|
|
150
|
+
if (!clause) return;
|
|
151
|
+
if (clause.name) importMap.set(clause.name.getText(sf), resolved);
|
|
152
|
+
const b = clause.namedBindings;
|
|
153
|
+
if (b) {
|
|
154
|
+
if (ts.isNamespaceImport(b)) importMap.set(b.name.getText(sf), resolved);
|
|
155
|
+
else if (ts.isNamedImports(b)) for (const el of b.elements) importMap.set(el.name.getText(sf), resolved);
|
|
156
|
+
}
|
|
157
|
+
} catch {}
|
|
158
|
+
}
|
|
159
|
+
ts.forEachChild(node, visit);
|
|
160
|
+
}
|
|
161
|
+
ts.forEachChild(sf, visit);
|
|
162
|
+
return importMap;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function resolveRelativeImport(spec, fromFile) {
|
|
166
|
+
const base = path.resolve(path.dirname(fromFile), spec);
|
|
167
|
+
const exts = ['.ts', '.tsx', '.js', '.mjs', '.cjs'];
|
|
168
|
+
if (fs.existsSync(base) && fs.statSync(base).isFile()) return base;
|
|
169
|
+
for (const ext of exts) if (fs.existsSync(base + ext)) return base + ext;
|
|
170
|
+
for (const ext of exts) { const c = path.join(base, 'index' + ext); if (fs.existsSync(c)) return c; }
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ── regex fallback ────────────────────────────────────────────────────────
|
|
175
|
+
|
|
176
|
+
function extractSymbolsRegex(content) {
|
|
177
|
+
const symbols = new Map(); let m;
|
|
178
|
+
const fn = /export\s+(async\s+)?function\s+(\w+)\(([^)]*)\)/g;
|
|
179
|
+
while ((m = fn.exec(content)) !== null) {
|
|
180
|
+
const params = m[3].trim() ? m[3].trim().split(',').map(p => ({ name: p.trim(), type: 'any', optional: false })) : [];
|
|
181
|
+
symbols.set(m[2], { kind: 'function', signature: buildSig(params, ''), parameters: params,
|
|
182
|
+
returnType: '', isExported: true, documentation: '', lineStart: 0 });
|
|
183
|
+
}
|
|
184
|
+
const cl = /export\s+class\s+(\w+)/g;
|
|
185
|
+
while ((m = cl.exec(content)) !== null)
|
|
186
|
+
symbols.set(m[1], { kind: 'class', signature: m[1], parameters: [], returnType: '',
|
|
187
|
+
isExported: true, documentation: '', lineStart: 0 });
|
|
188
|
+
return symbols;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ── per-file extraction ───────────────────────────────────────────────────
|
|
192
|
+
|
|
193
|
+
const MAX_TS_SIZE = 500 * 1024;
|
|
194
|
+
|
|
195
|
+
function extractFile(filePath, cacheDir) {
|
|
196
|
+
const cached = readFromCache(filePath, cacheDir);
|
|
197
|
+
if (cached) return { symbols: new Map(Object.entries(cached.symbols)), importMap: new Map(Object.entries(cached.importMap)) };
|
|
198
|
+
|
|
199
|
+
let content;
|
|
200
|
+
try { content = fs.readFileSync(filePath, 'utf8'); } catch { return { symbols: new Map(), importMap: new Map() }; }
|
|
201
|
+
|
|
202
|
+
const isTs = /\.[cm]?ts$|\.tsx$/.test(filePath);
|
|
203
|
+
let symbols, importMap = new Map();
|
|
204
|
+
if (isTs && content.length <= MAX_TS_SIZE) {
|
|
205
|
+
try { symbols = extractSymbolsFromAst(filePath, content); importMap = extractImportMap(filePath, content); }
|
|
206
|
+
catch { symbols = extractSymbolsRegex(content); }
|
|
207
|
+
} else {
|
|
208
|
+
symbols = extractSymbolsRegex(content);
|
|
209
|
+
}
|
|
210
|
+
writeToCache(filePath, { symbols: Object.fromEntries(symbols), importMap: Object.fromEntries(importMap) }, cacheDir);
|
|
211
|
+
return { symbols, importMap };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ── main ──────────────────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
export async function enrichGraph(projectDir, options = {}) {
|
|
217
|
+
const graphDir = options.graphDir ?? path.join(projectDir, '.monomind', 'graph');
|
|
218
|
+
const verbose = options.verbose ?? false;
|
|
219
|
+
const forceRebuild = options.forceRebuild ?? false;
|
|
220
|
+
const cacheDir = path.join(graphDir, 'cache', 'symbols');
|
|
221
|
+
|
|
222
|
+
const graphPath = path.join(graphDir, 'graph.json');
|
|
223
|
+
if (!fs.existsSync(graphPath)) throw new Error(`graph.json not found at ${graphPath}`);
|
|
224
|
+
const rawGraph = JSON.parse(fs.readFileSync(graphPath, 'utf8'));
|
|
225
|
+
const nodes = rawGraph.nodes ?? [];
|
|
226
|
+
const links = rawGraph.links ?? rawGraph.edges ?? [];
|
|
227
|
+
|
|
228
|
+
// Phase 1+2: extract symbols + import maps per unique source file
|
|
229
|
+
const uniqueFiles = [...new Set(nodes.map(n => n.sourceFile).filter(Boolean))];
|
|
230
|
+
const symbolCache = new Map(), importCache = new Map();
|
|
231
|
+
let filesProcessed = 0;
|
|
232
|
+
for (const fp of uniqueFiles) {
|
|
233
|
+
if (forceRebuild) { try { fs.unlinkSync(cacheFileFor(fp, cacheDir)); } catch {} }
|
|
234
|
+
const { symbols, importMap } = extractFile(fp, cacheDir);
|
|
235
|
+
symbolCache.set(fp, symbols); importCache.set(fp, importMap);
|
|
236
|
+
filesProcessed++;
|
|
237
|
+
if (filesProcessed % 100 === 0 || verbose) {
|
|
238
|
+
console.log(`[enrich] processed ${filesProcessed}/${uniqueFiles.length} files (${Math.round(filesProcessed / uniqueFiles.length * 100)}%)`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Phase 3: enrich nodes
|
|
243
|
+
let enrichedCount = 0;
|
|
244
|
+
const enrichedNodes = nodes.map(node => {
|
|
245
|
+
const n = { ...node, inDegree: 0, outDegree: 0 };
|
|
246
|
+
const info = symbolCache.get(n.sourceFile)?.get(n.label) ?? symbolCache.get(n.sourceFile)?.get(n.id);
|
|
247
|
+
if (info) {
|
|
248
|
+
Object.assign(n, { kind: info.kind, signature: info.signature, parameters: info.parameters,
|
|
249
|
+
returnType: info.returnType, isExported: info.isExported, documentation: info.documentation });
|
|
250
|
+
enrichedCount++;
|
|
251
|
+
}
|
|
252
|
+
return n;
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Phase 4: resolve call/import edges to cross-module links
|
|
256
|
+
const nodeById = new Map(enrichedNodes.map(n => [n.id, n]));
|
|
257
|
+
const nodesByFile = new Map();
|
|
258
|
+
for (const n of enrichedNodes) {
|
|
259
|
+
if (!n.sourceFile) continue;
|
|
260
|
+
if (!nodesByFile.has(n.sourceFile)) nodesByFile.set(n.sourceFile, []);
|
|
261
|
+
nodesByFile.get(n.sourceFile).push(n);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Walk importCache directly: sourceFile → (importedSymbol → resolvedAbsolutePath).
|
|
265
|
+
// This avoids the graph.json edge format mismatch where link.source is a short filename/path
|
|
266
|
+
// rather than a symbol-name node ID, which caused resolvedCallEdges: 0 when iterating links.
|
|
267
|
+
//
|
|
268
|
+
// One edge per (sourceFile → target node) — not one per source symbol. Fanning out to all
|
|
269
|
+
// N nodes in a file per import inflates edge counts by O(N) and corrupts PageRank.
|
|
270
|
+
// We use the first node in the file as a stable representative for the file-level dependency.
|
|
271
|
+
const resolvedLinks = []; const seenEdgeKeys = new Set();
|
|
272
|
+
for (const [sourceFile, symbolMap] of importCache) {
|
|
273
|
+
const fileNodes = nodesByFile.get(sourceFile) ?? [];
|
|
274
|
+
if (!fileNodes.length) continue;
|
|
275
|
+
const repNode = fileNodes[0]; // representative node for this source file
|
|
276
|
+
for (const [symbolName, resolvedPath] of symbolMap) {
|
|
277
|
+
const candidates = nodesByFile.get(resolvedPath) ?? [];
|
|
278
|
+
// Prefer a node in the target file whose label/id matches the imported symbol name
|
|
279
|
+
const tgt = candidates.find(n => n.label === symbolName || n.id === symbolName) ?? candidates[0];
|
|
280
|
+
if (!tgt) continue;
|
|
281
|
+
if (repNode.id === tgt.id) continue; // skip self-edges
|
|
282
|
+
// Deduplicate by (sourceFile, tgt.id) — one edge per file-level import relationship
|
|
283
|
+
const key = `${sourceFile}:${tgt.id}`;
|
|
284
|
+
if (seenEdgeKeys.has(key)) continue;
|
|
285
|
+
seenEdgeKeys.add(key);
|
|
286
|
+
resolvedLinks.push({ source: repNode.id, target: tgt.id, relation: 'calls_module',
|
|
287
|
+
confidence: 'INFERRED', weight: 1, resolvedFrom: symbolName });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Phase 5: degree counts.
|
|
292
|
+
// Raw graph.json links use filename paths as link.source, not symbol IDs, so nodeById
|
|
293
|
+
// lookups on raw links return undefined. Only resolvedLinks have symbol-name IDs on both
|
|
294
|
+
// ends and reliably hit nodeById.
|
|
295
|
+
const allEdges = [...links, ...resolvedLinks];
|
|
296
|
+
for (const link of resolvedLinks) {
|
|
297
|
+
const s = nodeById.get(link.source); const t = nodeById.get(link.target);
|
|
298
|
+
if (s) s.outDegree++; if (t) t.inDegree++;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Phase 6: PageRank + eigenvector centrality
|
|
302
|
+
const Graph = loadGraphology();
|
|
303
|
+
const { assignPageRank, assignEigen } = loadGraphologyMetrics();
|
|
304
|
+
const G = new Graph({ type: 'directed', multi: false });
|
|
305
|
+
for (const n of enrichedNodes) G.addNode(n.id, { ...n });
|
|
306
|
+
// Guard both endpoints: raw links have filename paths as source which are not graph nodes.
|
|
307
|
+
for (const link of allEdges) {
|
|
308
|
+
try {
|
|
309
|
+
if (G.hasNode(link.source) && G.hasNode(link.target))
|
|
310
|
+
G.addEdge(link.source, link.target, { weight: link.weight ?? 1 });
|
|
311
|
+
} catch {}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
let pageRankComputed = false, centralityComputed = false;
|
|
315
|
+
try { assignPageRank(G, { alpha: 0.85, maxIterations: 100, tolerance: 1e-6 }); pageRankComputed = true; }
|
|
316
|
+
catch (e) { console.warn('[enrich] PageRank failed:', e.message); }
|
|
317
|
+
try { assignEigen(G, { maxIterations: 500, tolerance: 1e-4, normalize: true }); centralityComputed = true; }
|
|
318
|
+
catch (e) { console.warn('[enrich] Eigenvector centrality skipped (disconnected graph):', e.message); }
|
|
319
|
+
|
|
320
|
+
// Map graphology attr names (pagerank, eigenvectorCentrality) to output (pageRank, centrality)
|
|
321
|
+
G.forEachNode((id, attrs) => {
|
|
322
|
+
const n = nodeById.get(id); if (!n) return;
|
|
323
|
+
n.pageRank = attrs.pagerank ?? 0; n.centrality = attrs.eigenvectorCentrality ?? 0;
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Phase 7: write graph.enriched.json
|
|
327
|
+
const metrics = { totalNodes: enrichedNodes.length, enrichedNodes: enrichedCount,
|
|
328
|
+
totalEdges: allEdges.length, analyzedEdges: G.size,
|
|
329
|
+
resolvedCallEdges: resolvedLinks.length, pageRankComputed, centralityComputed };
|
|
330
|
+
const output = { version: '1.0.0', builtAt: rawGraph.builtAt ?? 0, projectPath: projectDir,
|
|
331
|
+
enrichedAt: Date.now(), nodes: enrichedNodes, links: allEdges, metrics };
|
|
332
|
+
const outputPath = path.join(graphDir, 'graph.enriched.json');
|
|
333
|
+
fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
|
|
334
|
+
console.log(`[enrich] wrote ${outputPath}`);
|
|
335
|
+
|
|
336
|
+
// Update stats.json
|
|
337
|
+
const statsPath = path.join(graphDir, 'stats.json');
|
|
338
|
+
try {
|
|
339
|
+
const stats = fs.existsSync(statsPath) ? JSON.parse(fs.readFileSync(statsPath, 'utf8')) : {};
|
|
340
|
+
stats.enrichedAt = Date.now(); stats.enrichedNodes = enrichedCount;
|
|
341
|
+
fs.writeFileSync(statsPath, JSON.stringify(stats, null, 2));
|
|
342
|
+
} catch {}
|
|
343
|
+
|
|
344
|
+
return { enrichedNodes, resolvedEdges: resolvedLinks, metrics };
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ── CLI entrypoint ────────────────────────────────────────────────────────
|
|
348
|
+
|
|
349
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
350
|
+
const projectDir = process.argv[2];
|
|
351
|
+
if (!projectDir) {
|
|
352
|
+
console.error('Usage: node enrich.mjs <project-dir> [--graph-dir <dir>] [--verbose] [--force]');
|
|
353
|
+
process.exit(1);
|
|
354
|
+
}
|
|
355
|
+
const args = process.argv.slice(3);
|
|
356
|
+
const opts = { verbose: args.includes('--verbose'), forceRebuild: args.includes('--force') };
|
|
357
|
+
const gdIdx = args.indexOf('--graph-dir');
|
|
358
|
+
if (gdIdx !== -1 && args[gdIdx + 1]) opts.graphDir = args[gdIdx + 1];
|
|
359
|
+
enrichGraph(path.resolve(projectDir), opts)
|
|
360
|
+
.then(({ metrics }) => console.log('[enrich] done:', JSON.stringify(metrics, null, 2)))
|
|
361
|
+
.catch(err => { console.error('[enrich] fatal:', err.message); process.exit(1); });
|
|
362
|
+
}
|
|
@@ -56,6 +56,11 @@ const SKILLS_MAP = {
|
|
|
56
56
|
'mastermind',
|
|
57
57
|
'monodesign',
|
|
58
58
|
'monomotion',
|
|
59
|
+
'monolean',
|
|
60
|
+
'monolean-review',
|
|
61
|
+
'monolean-audit',
|
|
62
|
+
'monolean-debt',
|
|
63
|
+
'monolean-help',
|
|
59
64
|
'hive-mind-advanced',
|
|
60
65
|
],
|
|
61
66
|
browser: ['agent-browser-testing'],
|
|
@@ -1238,14 +1243,19 @@ function findSourceHelpersDir(sourceBaseDir) {
|
|
|
1238
1243
|
possiblePaths.push(path.join(sourceBaseDir, '.claude', 'helpers'));
|
|
1239
1244
|
}
|
|
1240
1245
|
// Strategy 1: require.resolve to find package root (most reliable for npx)
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1246
|
+
// Try both published package names (@monoes/monomindcli is the scoped CLI package,
|
|
1247
|
+
// monomind is the umbrella — neither is @monomind/cli which is the monorepo name only)
|
|
1248
|
+
for (const pkgName of ['@monoes/monomindcli/package.json', 'monomind/packages/@monomind/cli/package.json', '@monomind/cli/package.json']) {
|
|
1249
|
+
try {
|
|
1250
|
+
const esmRequire = createRequire(import.meta.url);
|
|
1251
|
+
const pkgJsonPath = esmRequire.resolve(pkgName);
|
|
1252
|
+
const pkgRoot = path.dirname(pkgJsonPath);
|
|
1253
|
+
possiblePaths.push(path.join(pkgRoot, '.claude', 'helpers'));
|
|
1254
|
+
break;
|
|
1255
|
+
}
|
|
1256
|
+
catch {
|
|
1257
|
+
// Not installed under this name — try next
|
|
1258
|
+
}
|
|
1249
1259
|
}
|
|
1250
1260
|
// Strategy 2: __dirname-based (dist/src/init -> package root)
|
|
1251
1261
|
const packageRoot = path.resolve(__dirname, '..', '..', '..');
|