@mindrian_os/install 1.13.0-beta.11
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-plugin/plugin.json +21 -0
- package/.mcp.json +9 -0
- package/CHANGELOG.md +3333 -0
- package/LICENSE +123 -0
- package/README.md +673 -0
- package/agents/brain-query.md +80 -0
- package/agents/framework-runner.md +237 -0
- package/agents/grading.md +188 -0
- package/agents/investor.md +128 -0
- package/agents/larry-extended.md +135 -0
- package/agents/opportunity-scanner.md +91 -0
- package/agents/persona-analyst.md +132 -0
- package/agents/research.md +89 -0
- package/agents/reverse-salient-agent.md +27 -0
- package/bin/cli.js +142 -0
- package/bin/mindrian-mcp-server.cjs +182 -0
- package/bin/mindrian-tools.cjs +765 -0
- package/commands/act.md +439 -0
- package/commands/admin.md +404 -0
- package/commands/analyze-needs.md +42 -0
- package/commands/analyze-systems.md +39 -0
- package/commands/analyze-timing.md +42 -0
- package/commands/auto-explore.md +64 -0
- package/commands/beautiful-question.md +40 -0
- package/commands/brain-derive.md +78 -0
- package/commands/build-knowledge.md +42 -0
- package/commands/build-thesis.md +46 -0
- package/commands/causal.md +234 -0
- package/commands/challenge-assumptions.md +33 -0
- package/commands/compare-ventures.md +83 -0
- package/commands/dashboard.md +110 -0
- package/commands/deep-grade.md +82 -0
- package/commands/diagnose.md +58 -0
- package/commands/diagnostics.md +151 -0
- package/commands/doctor.md +151 -0
- package/commands/dominant-designs.md +40 -0
- package/commands/explain-decision.md +87 -0
- package/commands/explore-domains.md +42 -0
- package/commands/explore-futures.md +40 -0
- package/commands/explore-trends.md +42 -0
- package/commands/export.md +103 -0
- package/commands/file-meeting.md +724 -0
- package/commands/find-analogies.md +188 -0
- package/commands/find-bottlenecks.md +62 -0
- package/commands/find-connections.md +76 -0
- package/commands/funding.md +81 -0
- package/commands/grade.md +203 -0
- package/commands/graph.md +128 -0
- package/commands/hat-briefing.md +125 -0
- package/commands/heal.md +196 -0
- package/commands/help.md +399 -0
- package/commands/hmi-status.md +172 -0
- package/commands/jtbd.md +241 -0
- package/commands/leadership.md +73 -0
- package/commands/lean-canvas.md +40 -0
- package/commands/macro-trends.md +40 -0
- package/commands/map-unknowns.md +40 -0
- package/commands/memory.md +173 -0
- package/commands/models.md +175 -0
- package/commands/mos-reason.md +285 -0
- package/commands/mullins.md +120 -0
- package/commands/new-project.md +481 -0
- package/commands/onboard.md +434 -0
- package/commands/operator.md +149 -0
- package/commands/opportunities.md +144 -0
- package/commands/organize.md +497 -0
- package/commands/persona.md +198 -0
- package/commands/pipeline.md +112 -0
- package/commands/present.md +91 -0
- package/commands/publish.md +201 -0
- package/commands/query.md +124 -0
- package/commands/radar.md +72 -0
- package/commands/reanalyze.md +91 -0
- package/commands/research.md +196 -0
- package/commands/room.md +352 -0
- package/commands/rooms.md +598 -0
- package/commands/root-cause.md +40 -0
- package/commands/rs-experts.md +85 -0
- package/commands/rs-explain.md +100 -0
- package/commands/rs-fetch.md +94 -0
- package/commands/rs-thesis.md +85 -0
- package/commands/scenario-plan.md +40 -0
- package/commands/scheduled-tasks.md +285 -0
- package/commands/score-innovation.md +43 -0
- package/commands/scout.md +239 -0
- package/commands/setup.md +618 -0
- package/commands/snapshot.md +147 -0
- package/commands/speakers.md +84 -0
- package/commands/splash.md +28 -0
- package/commands/status.md +75 -0
- package/commands/structure-argument.md +42 -0
- package/commands/suggest-next.md +80 -0
- package/commands/systems-thinking.md +40 -0
- package/commands/think-hats.md +42 -0
- package/commands/update.md +181 -0
- package/commands/user-needs.md +40 -0
- package/commands/validate.md +40 -0
- package/commands/value-proposition.md +61 -0
- package/commands/vault.md +180 -0
- package/commands/visualize.md +52 -0
- package/commands/whitespace.md +507 -0
- package/commands/wiki.md +69 -0
- package/hooks/hooks.json +381 -0
- package/hooks/run-hook.cmd +64 -0
- package/lib/__init__.py +0 -0
- package/lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/lib/agents/auto-explore-agent.cjs +1043 -0
- package/lib/agents/reverse-salient-agent.cjs +679 -0
- package/lib/agents/tension-hook-agent.cjs +544 -0
- package/lib/brain/ROOM.md +44 -0
- package/lib/brain/chain-recommender.cjs +301 -0
- package/lib/chat/chat-context.js +185 -0
- package/lib/chat/chat-panel.js +721 -0
- package/lib/chat/fabric-chat.cjs +288 -0
- package/lib/chat/generative-tools.js +219 -0
- package/lib/conversation/ROOM.md +39 -0
- package/lib/conversation/classifier-rules.json +38 -0
- package/lib/conversation/classifier.cjs +264 -0
- package/lib/conversation/operator.cjs +287 -0
- package/lib/copy/115-spec-strings.cjs +55 -0
- package/lib/core/__init__.py +0 -0
- package/lib/core/__nav-stub.cjs +14 -0
- package/lib/core/__pycache__/__init__.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs-math.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_cache.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_corpus.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_hybrid.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_math.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_rooms.cpython-312.pyc +0 -0
- package/lib/core/artifact-id.cjs +148 -0
- package/lib/core/asset-ops.cjs +151 -0
- package/lib/core/auto-commit-throttle.cjs +129 -0
- package/lib/core/bearer-token.cjs +199 -0
- package/lib/core/brain-client.cjs +865 -0
- package/lib/core/brain-derivation-prompts.cjs +326 -0
- package/lib/core/brain-derivation-queue.cjs +431 -0
- package/lib/core/brain-derivation.cjs +580 -0
- package/lib/core/brain-md-schema.cjs +528 -0
- package/lib/core/brain-md-staleness.cjs +357 -0
- package/lib/core/brain-response-sanitize.cjs +188 -0
- package/lib/core/bridge-writer.cjs +477 -0
- package/lib/core/chat-context-builder.cjs +253 -0
- package/lib/core/cross-room-aggregator.cjs +762 -0
- package/lib/core/daily-briefing.cjs +438 -0
- package/lib/core/decision-capture.cjs +618 -0
- package/lib/core/deep-links.cjs +82 -0
- package/lib/core/dispatch-optimizer.cjs +354 -0
- package/lib/core/dual-path-detector.cjs +84 -0
- package/lib/core/dual-path-detector.test.cjs +334 -0
- package/lib/core/exports-log.cjs +79 -0
- package/lib/core/feynman-minto-invariants.cjs +605 -0
- package/lib/core/folder-memory-async.cjs +338 -0
- package/lib/core/folder-memory-shared.cjs +890 -0
- package/lib/core/folder-memory.cjs +416 -0
- package/lib/core/framework-chain-composer.cjs +411 -0
- package/lib/core/frontmatter-schemas.cjs +330 -0
- package/lib/core/git-ops.cjs +141 -0
- package/lib/core/graph-ops.cjs +258 -0
- package/lib/core/hat-persistence.cjs +362 -0
- package/lib/core/index.cjs +60 -0
- package/lib/core/integration-registry.cjs +232 -0
- package/lib/core/intelligence-cascade.cjs +661 -0
- package/lib/core/lazygraph-ops.cjs +1057 -0
- package/lib/core/lru-cache.cjs +139 -0
- package/lib/core/mcp-profiles.cjs +182 -0
- package/lib/core/meeting-ops.cjs +54 -0
- package/lib/core/memory-ops.cjs +600 -0
- package/lib/core/migrations/ROOM.md +33 -0
- package/lib/core/migrations/phase-109-nodes-provenance.cjs +339 -0
- package/lib/core/migrations/phase-109-session-focus.cjs +99 -0
- package/lib/core/model-profiles.cjs +246 -0
- package/lib/core/mullins-scaffold.cjs +160 -0
- package/lib/core/nav-dial.cjs +316 -0
- package/lib/core/navigation/ROOM.md +15 -0
- package/lib/core/navigation/explanation.cjs +43 -0
- package/lib/core/navigation/focus.cjs +135 -0
- package/lib/core/navigation/ingestion.cjs +82 -0
- package/lib/core/navigation/insights.cjs +350 -0
- package/lib/core/navigation/memory-events.cjs +118 -0
- package/lib/core/navigation/neighborhood.cjs +78 -0
- package/lib/core/navigation/packet.cjs +182 -0
- package/lib/core/navigation/room-home.cjs +127 -0
- package/lib/core/navigation/transitions.cjs +82 -0
- package/lib/core/navigation-engine-shared.cjs +242 -0
- package/lib/core/navigation-engine.cjs +664 -0
- package/lib/core/navigation.cjs +60 -0
- package/lib/core/nl-graph-queries.cjs +164 -0
- package/lib/core/offer-presenter.cjs +406 -0
- package/lib/core/opportunity-extractor.cjs +183 -0
- package/lib/core/opportunity-ops.cjs +1371 -0
- package/lib/core/persona-ops.cjs +537 -0
- package/lib/core/persona-taxonomy.cjs +190 -0
- package/lib/core/platform-gates.cjs +120 -0
- package/lib/core/platform.cjs +257 -0
- package/lib/core/proactive-intelligence.cjs +528 -0
- package/lib/core/problem-type-router.cjs +315 -0
- package/lib/core/reasoning-ops.cjs +639 -0
- package/lib/core/reverse-salient-persona-suffix.cjs +115 -0
- package/lib/core/room-classifier-strict-mode.cjs +229 -0
- package/lib/core/room-db.cjs +127 -0
- package/lib/core/room-ops-async.cjs +92 -0
- package/lib/core/room-ops-shared.cjs +64 -0
- package/lib/core/room-ops-sync.cjs +70 -0
- package/lib/core/room-ops.cjs +32 -0
- package/lib/core/room-type-detector.cjs +386 -0
- package/lib/core/rs-brain-substrate-prompts.cjs +129 -0
- package/lib/core/rs-brain-substrate.cjs +570 -0
- package/lib/core/rs-breakthrough-scorer.cjs +255 -0
- package/lib/core/rs-canon-violations.cjs +82 -0
- package/lib/core/rs-chain-feeder.cjs +343 -0
- package/lib/core/rs-commercial-assessor.cjs +280 -0
- package/lib/core/rs-differential-scorer.cjs +376 -0
- package/lib/core/rs-domain-analyzer.cjs +385 -0
- package/lib/core/rs-egress-prompts.cjs +113 -0
- package/lib/core/rs-egress-telemetry.cjs +225 -0
- package/lib/core/rs-egress-violations.cjs +53 -0
- package/lib/core/rs-expert-mapper.cjs +467 -0
- package/lib/core/rs-fetcher-academic.cjs +697 -0
- package/lib/core/rs-fetcher-experts.cjs +314 -0
- package/lib/core/rs-fetcher-industry.cjs +731 -0
- package/lib/core/rs-fetcher-patents.cjs +564 -0
- package/lib/core/rs-innovation-classifier.cjs +194 -0
- package/lib/core/rs-mind-map.cjs +656 -0
- package/lib/core/rs-neo4j-writer.cjs +388 -0
- package/lib/core/rs-nl-to-query.cjs +425 -0
- package/lib/core/rs-pinecone-bridge.cjs +303 -0
- package/lib/core/rs-preprocessor.cjs +350 -0
- package/lib/core/rs-query-matrix.cjs +316 -0
- package/lib/core/rs-query-to-text.cjs +438 -0
- package/lib/core/rs-sqlite-mirror.cjs +443 -0
- package/lib/core/rs-thesis-generator.cjs +188 -0
- package/lib/core/rs_cache.py +479 -0
- package/lib/core/rs_corpus.py +468 -0
- package/lib/core/rs_hybrid.py +586 -0
- package/lib/core/rs_math.py +287 -0
- package/lib/core/rs_rooms.py +193 -0
- package/lib/core/scheduled-scanner.cjs +463 -0
- package/lib/core/scratchpad-ops.cjs +201 -0
- package/lib/core/section-8-trace-schema.cjs +138 -0
- package/lib/core/section-registry.cjs +111 -0
- package/lib/core/session-state.cjs +144 -0
- package/lib/core/shallow-doc-parser.cjs +174 -0
- package/lib/core/shallow-doc-parser.test.cjs +226 -0
- package/lib/core/skill-activation-router.cjs +284 -0
- package/lib/core/state-ops.cjs +46 -0
- package/lib/core/statusline-cache.cjs +266 -0
- package/lib/core/token-estimator.cjs +348 -0
- package/lib/core/user-archetype.cjs +239 -0
- package/lib/core/user-md-ops.cjs +524 -0
- package/lib/core/visual-ops.cjs +624 -0
- package/lib/core/write-lock.cjs +149 -0
- package/lib/graph/canvas-graph.js +467 -0
- package/lib/graph/constellation-config.cjs +299 -0
- package/lib/graph/graph-detail-panel.js +165 -0
- package/lib/hmi/ROOM.md +47 -0
- package/lib/hmi/across-session-memory.cjs +604 -0
- package/lib/hmi/cross-room-memory.cjs +575 -0
- package/lib/hmi/decoy-tier.cjs +395 -0
- package/lib/hmi/jtbd-classifier.cjs +219 -0
- package/lib/hmi/jtbd-state.cjs +199 -0
- package/lib/hmi/jtbd-taxonomy.json +392 -0
- package/lib/hmi/selector-dispatcher.cjs +546 -0
- package/lib/hmi/selector-telemetry.cjs +263 -0
- package/lib/hmi/shape-f0-renderer.cjs +139 -0
- package/lib/hmi/shape-f1-fallback.cjs +80 -0
- package/lib/hmi/shape-f1-renderer.cjs +138 -0
- package/lib/hmi/shape-f2-renderer.cjs +132 -0
- package/lib/hmi/shape-f3-renderer.cjs +66 -0
- package/lib/hmi/shape-f4-renderer.cjs +72 -0
- package/lib/hmi/shape-f5-renderer.cjs +155 -0
- package/lib/hmi/shape-f6-plan-review-renderer.cjs +312 -0
- package/lib/hmi/shape-f6-renderer.cjs +144 -0
- package/lib/hmi/shape-g-renderer.cjs +219 -0
- package/lib/hmi/shape-h-renderer.cjs +222 -0
- package/lib/hmi/tier-check.cjs +63 -0
- package/lib/import/PRECONDITIONS.md +41 -0
- package/lib/import/branding.cjs +210 -0
- package/lib/import/branding.test.cjs +235 -0
- package/lib/import/classifications-sync.cjs +104 -0
- package/lib/import/classifications-sync.test.cjs +129 -0
- package/lib/import/enricher.cjs +296 -0
- package/lib/import/enricher.test.cjs +273 -0
- package/lib/import/integration.test.cjs +376 -0
- package/lib/import/manifest.cjs +129 -0
- package/lib/import/manifest.schema.json +185 -0
- package/lib/import/manifest.test.cjs +123 -0
- package/lib/import/meeting-detector.cjs +92 -0
- package/lib/import/meeting-detector.test.cjs +100 -0
- package/lib/import/person-detector.cjs +229 -0
- package/lib/import/person-detector.test.cjs +149 -0
- package/lib/import/report.cjs +186 -0
- package/lib/import/report.test.cjs +186 -0
- package/lib/import/room-md-scaffolder.cjs +49 -0
- package/lib/import/router.cjs +224 -0
- package/lib/import/router.test.cjs +356 -0
- package/lib/import/run-all-tests.cjs +36 -0
- package/lib/import/smoke-test.cjs +213 -0
- package/lib/import/smoke-test.test.cjs +148 -0
- package/lib/import/test-fixtures/collision-vault/preexisting-room/STATE.md +8 -0
- package/lib/import/test-fixtures/collision-vault/preexisting-room/problem-definition/onboarding/onboarding.md +7 -0
- package/lib/import/test-fixtures/collision-vault/source/onboarding.md +5 -0
- package/lib/import/test-fixtures/obsidian-vault/.obsidian/workspace.json +1 -0
- package/lib/import/test-fixtures/obsidian-vault/notes/with-wikilinks.md +4 -0
- package/lib/import/test-fixtures/tiny-vault/notes/2026-01-15-team-sync.md +9 -0
- package/lib/import/test-fixtures/tiny-vault/notes/empty.md +3 -0
- package/lib/import/test-fixtures/tiny-vault/notes/onboarding.md +5 -0
- package/lib/import/test-fixtures/tiny-vault/notes/pricing.md +5 -0
- package/lib/import/test-fixtures/tiny-vault/notes/random.md +4 -0
- package/lib/import/undo.test.cjs +199 -0
- package/lib/import/vault-scanner.cjs +105 -0
- package/lib/import/vault-scanner.test.cjs +67 -0
- package/lib/mcp/app-html/dashboard.html +316 -0
- package/lib/mcp/app-html/graph.html +428 -0
- package/lib/mcp/app-html/mindrian-platform.html +1841 -0
- package/lib/mcp/app-html/wiki.html +383 -0
- package/lib/mcp/app-views.cjs +322 -0
- package/lib/mcp/brain-router.cjs +418 -0
- package/lib/mcp/capability-registry.cjs +62 -0
- package/lib/mcp/larry-context.cjs +46 -0
- package/lib/mcp/larry-server-instructions.md +114 -0
- package/lib/mcp/pipeline-state.cjs +275 -0
- package/lib/mcp/prompts.cjs +302 -0
- package/lib/mcp/resources.cjs +227 -0
- package/lib/mcp/session-catchup.cjs +327 -0
- package/lib/mcp/surface-detect.cjs +75 -0
- package/lib/mcp/tool-router.cjs +1034 -0
- package/lib/memory/aaak-compress.cjs +403 -0
- package/lib/memory/aaak-compress.test.cjs +288 -0
- package/lib/memory/async-artifact-auto-commit.test.cjs +223 -0
- package/lib/memory/bearer-token.test.cjs +315 -0
- package/lib/memory/brain-cache-lru.test.cjs +259 -0
- package/lib/memory/brain-client-query-shape.test.cjs +160 -0
- package/lib/memory/brain-derivation-graceful-degradation.test.cjs +1019 -0
- package/lib/memory/brain-derivation-queue.test.cjs +539 -0
- package/lib/memory/brain-derivation.test.cjs +634 -0
- package/lib/memory/brain-derive-command.test.cjs +534 -0
- package/lib/memory/brain-md-invariants-validator.test.cjs +704 -0
- package/lib/memory/brain-md-schema.test.cjs +467 -0
- package/lib/memory/brain-md-staleness.test.cjs +525 -0
- package/lib/memory/brain-server-resolution.test.cjs +314 -0
- package/lib/memory/chain-recommender.test.cjs +233 -0
- package/lib/memory/chat-context.test.cjs +128 -0
- package/lib/memory/command-registry.test.cjs +220 -0
- package/lib/memory/cross-room-aggregator.test.cjs +909 -0
- package/lib/memory/dashboard-server.test.cjs +256 -0
- package/lib/memory/debouncer-drain-at-prompt.test.cjs +389 -0
- package/lib/memory/decision-capture.test.cjs +632 -0
- package/lib/memory/decision-capture.worker.cjs +70 -0
- package/lib/memory/explain-decision-command.test.cjs +521 -0
- package/lib/memory/explain-decision-footer.test.cjs +316 -0
- package/lib/memory/explored-materials-store.cjs +392 -0
- package/lib/memory/feynman-minto-guardian.test.cjs +736 -0
- package/lib/memory/feynman-minto-invariants.test.cjs +511 -0
- package/lib/memory/feynman-prompts-drift.test.cjs +144 -0
- package/lib/memory/feynman-prompts.cjs +151 -0
- package/lib/memory/feynman-prompts.test.cjs +96 -0
- package/lib/memory/folder-memory-quadruple.test.cjs +548 -0
- package/lib/memory/folder-memory.test.cjs +503 -0
- package/lib/memory/framework-chain-composer.test.cjs +515 -0
- package/lib/memory/frontmatter-schema-validator.test.cjs +290 -0
- package/lib/memory/heal-command.test.cjs +604 -0
- package/lib/memory/index-artifact-transaction.test.cjs +333 -0
- package/lib/memory/lazygraph-rs-discoveries-view.test.cjs +122 -0
- package/lib/memory/mcp-input-validation.test.cjs +240 -0
- package/lib/memory/mcp-server-brain-deps.test.cjs +270 -0
- package/lib/memory/mcp-stack-fallback.test.cjs +433 -0
- package/lib/memory/minto-debouncer.test.cjs +407 -0
- package/lib/memory/minto-debouncer.worker.cjs +46 -0
- package/lib/memory/minto-migration-v88.test.cjs +265 -0
- package/lib/memory/minto-schema-v88.test.cjs +390 -0
- package/lib/memory/mos-status-renderer.test.cjs +631 -0
- package/lib/memory/narrative-schema.cjs +376 -0
- package/lib/memory/narrative-schema.test.cjs +209 -0
- package/lib/memory/nav-dial.test.cjs +414 -0
- package/lib/memory/navigation-engine-core.test.cjs +722 -0
- package/lib/memory/navigation-invariants.test.cjs +483 -0
- package/lib/memory/offer-presenter.test.cjs +554 -0
- package/lib/memory/on-stop-snapshot.test.cjs +404 -0
- package/lib/memory/pending-tension-store.cjs +373 -0
- package/lib/memory/post-compact-reinjection.test.cjs +854 -0
- package/lib/memory/post-write-triple.test.cjs +317 -0
- package/lib/memory/pre-compact-snapshot.test.cjs +495 -0
- package/lib/memory/problem-type-router.test.cjs +656 -0
- package/lib/memory/query-efficiency-telemetry.test.cjs +370 -0
- package/lib/memory/recompile-room-references.test.cjs +392 -0
- package/lib/memory/recompile-room-references.worker.cjs +42 -0
- package/lib/memory/record-decision-dual-write.test.cjs +454 -0
- package/lib/memory/room-classifier-strict-mode.test.cjs +417 -0
- package/lib/memory/room-minto-hook.test.cjs +398 -0
- package/lib/memory/rs-discovery-engine.test.cjs +323 -0
- package/lib/memory/run-feynman-tests.cjs +1247 -0
- package/lib/memory/security-trifecta.test.cjs +312 -0
- package/lib/memory/session-start-brain-staleness.test.cjs +363 -0
- package/lib/memory/session-start-triple-injection.test.cjs +514 -0
- package/lib/memory/sessionstart-banner-formatter.cjs +318 -0
- package/lib/memory/sessionstart-minto-banner.test.cjs +373 -0
- package/lib/memory/skill-activation-router.test.cjs +419 -0
- package/lib/memory/stamp-artifact-write.test.cjs +304 -0
- package/lib/memory/statusline-active-room.test.cjs +315 -0
- package/lib/memory/statusline-minto-segment.test.cjs +292 -0
- package/lib/memory/sync-async-entry-points.test.cjs +204 -0
- package/lib/memory/test-bridge-writer-enhanced.cjs +452 -0
- package/lib/memory/test-rs-brain-substrate-shape.cjs +529 -0
- package/lib/memory/test-rs-brain-substrate.cjs +636 -0
- package/lib/memory/test-rs-breakthrough-scorer.cjs +375 -0
- package/lib/memory/test-rs-canon-violations.cjs +218 -0
- package/lib/memory/test-rs-chain-feeder-core.cjs +344 -0
- package/lib/memory/test-rs-chain-feeder-skill-spawn.cjs +297 -0
- package/lib/memory/test-rs-commercial-assessor.cjs +385 -0
- package/lib/memory/test-rs-differential-scorer.cjs +480 -0
- package/lib/memory/test-rs-discovery-engine.cjs +603 -0
- package/lib/memory/test-rs-domain-analyzer.cjs +492 -0
- package/lib/memory/test-rs-egress-primitives.cjs +420 -0
- package/lib/memory/test-rs-expert-mapper.cjs +547 -0
- package/lib/memory/test-rs-explain-command.cjs +443 -0
- package/lib/memory/test-rs-fetcher-academic.cjs +848 -0
- package/lib/memory/test-rs-fetcher-experts.cjs +496 -0
- package/lib/memory/test-rs-fetcher-industry.cjs +702 -0
- package/lib/memory/test-rs-fetcher-patents.cjs +674 -0
- package/lib/memory/test-rs-innovation-classifier.cjs +301 -0
- package/lib/memory/test-rs-mind-map.cjs +646 -0
- package/lib/memory/test-rs-neo4j-writer.cjs +518 -0
- package/lib/memory/test-rs-nl-to-query.cjs +449 -0
- package/lib/memory/test-rs-pinecone-bridge.cjs +277 -0
- package/lib/memory/test-rs-preprocessor.cjs +433 -0
- package/lib/memory/test-rs-query-matrix.cjs +391 -0
- package/lib/memory/test-rs-query-to-text.cjs +551 -0
- package/lib/memory/test-rs-sqlite-mirror.cjs +649 -0
- package/lib/memory/test-rs-thesis-generator.cjs +360 -0
- package/lib/memory/triple-context-formatter.cjs +473 -0
- package/lib/memory/triple-context-formatter.test.cjs +442 -0
- package/lib/memory/user-md-persona.test.cjs +565 -0
- package/lib/memory/userpromptsubmit-integration.test.cjs +690 -0
- package/lib/memory/validators/README.md +157 -0
- package/lib/memory/validators/brain-md-invariants.cjs +475 -0
- package/lib/memory/validators/brain-substrate-invariants.cjs +285 -0
- package/lib/memory/validators/external-academic-invariants.cjs +249 -0
- package/lib/memory/validators/external-industry-invariants.cjs +271 -0
- package/lib/memory/validators/external-patents-invariants.cjs +266 -0
- package/lib/memory/validators/minto-invariants.cjs +62 -0
- package/lib/memory/validators/navigation-invariants.cjs +340 -0
- package/lib/memory/validators/queue-health.cjs +95 -0
- package/lib/memory/validators/snapshot-integrity.cjs +129 -0
- package/lib/memory/validators/stale-lifecycle.cjs +116 -0
- package/lib/memory/vault-section-minto-generator-atomic.test.cjs +556 -0
- package/lib/memory/vault-section-minto-generator-atomic.worker.cjs +73 -0
- package/lib/memory/write-lock-atomic.test.cjs +137 -0
- package/lib/memory/write-lock-atomic.worker.cjs +55 -0
- package/lib/parity/check-parity.cjs +83 -0
- package/lib/presentation/presentation-server.cjs +101 -0
- package/lib/presentation/presentation-watcher.cjs +123 -0
- package/lib/quickview/hub-server.cjs +719 -0
- package/lib/quickview/server.cjs +533 -0
- package/lib/render/JTBD-PALETTES.md +145 -0
- package/lib/render/ROOM.md +59 -0
- package/lib/render/render-v2.cjs +486 -0
- package/lib/render/render-v2.test.cjs +267 -0
- package/lib/render/render.cjs +65 -0
- package/lib/state/ROOM.md +46 -0
- package/lib/state/state-md-parser.cjs +215 -0
- package/lib/statusline/ROOM.md +38 -0
- package/lib/statusline/banner-suppression.cjs +50 -0
- package/lib/statusline/surface-detect.cjs +85 -0
- package/lib/update-bootstrap.sh.template +145 -0
- package/lib/vault/frontmatter-schema.cjs +297 -0
- package/lib/vault/room-scanner.cjs +352 -0
- package/lib/vault/wikilink-builder.cjs +231 -0
- package/lib/vault/wikilink-builder.test.cjs +182 -0
- package/lib/wiki/graph-links.cjs +281 -0
- package/lib/wiki/page-renderer.cjs +229 -0
- package/lib/wiki/wiki-chat.cjs +81 -0
- package/lib/wiki/wiki-layout.cjs +1459 -0
- package/lib/wiki/wiki-search.cjs +142 -0
- package/lib/wiki/wiki-server.cjs +678 -0
- package/lib/wiki/wiki-watcher.cjs +105 -0
- package/lib/workflow/ROOM.md +47 -0
- package/lib/workflow/command-resolver.cjs +155 -0
- package/lib/workflow/command-resolver.test.cjs +235 -0
- package/package.json +44 -0
- package/pipelines/analogy/01-decompose.md +80 -0
- package/pipelines/analogy/02-abstract.md +87 -0
- package/pipelines/analogy/03-search.md +135 -0
- package/pipelines/analogy/04-transfer.md +101 -0
- package/pipelines/analogy/05-validate.md +106 -0
- package/pipelines/analogy/CHAIN.md +56 -0
- package/pipelines/discovery/01-explore-domains.md +44 -0
- package/pipelines/discovery/02-think-hats.md +50 -0
- package/pipelines/discovery/03-analyze-needs.md +54 -0
- package/pipelines/discovery/CHAIN.md +37 -0
- package/pipelines/thesis/01-structure-argument.md +45 -0
- package/pipelines/thesis/02-challenge-assumptions.md +48 -0
- package/pipelines/thesis/03-build-thesis.md +54 -0
- package/pipelines/thesis/CHAIN.md +37 -0
- package/references/brain/causal-directives.md +91 -0
- package/references/brain/causal-enrichment.cypher +165 -0
- package/references/brain/command-triggers-schema.md +226 -0
- package/references/brain/graph-architecture.md +317 -0
- package/references/brain/query-patterns.md +460 -0
- package/references/brain/room-hierarchy-schema.md +218 -0
- package/references/brain/schema.md +76 -0
- package/references/capability-radar/capabilities-index.md +241 -0
- package/references/capability-radar/changelog-cache.md +81 -0
- package/references/causal/causal-schema.md +103 -0
- package/references/design/email-template-standard.md +155 -0
- package/references/design/graph-visualization-standard.md +178 -0
- package/references/document-generation.md +179 -0
- package/references/hsi/HSI-TOOLS-REFERENCE.md +222 -0
- package/references/import-config.md +141 -0
- package/references/integrations/detection-patterns.md +101 -0
- package/references/meeting/artifact-template.md +377 -0
- package/references/meeting/cross-meeting-intelligence.md +216 -0
- package/references/meeting/cross-relationship-patterns.md +202 -0
- package/references/meeting/live-join-interface.md +244 -0
- package/references/meeting/section-mapping.md +192 -0
- package/references/meeting/segment-classification.md +258 -0
- package/references/meeting/speaker-profile-template.md +219 -0
- package/references/meeting/summary-template.md +348 -0
- package/references/meeting/transcript-patterns.md +226 -0
- package/references/methodology/analyze-needs.md +135 -0
- package/references/methodology/analyze-systems.md +121 -0
- package/references/methodology/analyze-timing.md +149 -0
- package/references/methodology/beautiful-question.md +109 -0
- package/references/methodology/build-knowledge.md +161 -0
- package/references/methodology/build-thesis.md +237 -0
- package/references/methodology/challenge-assumptions.md +127 -0
- package/references/methodology/diagnose.md +169 -0
- package/references/methodology/dominant-designs.md +212 -0
- package/references/methodology/explore-domains.md +147 -0
- package/references/methodology/explore-futures.md +163 -0
- package/references/methodology/explore-trends.md +129 -0
- package/references/methodology/find-bottlenecks.md +131 -0
- package/references/methodology/grade.md +211 -0
- package/references/methodology/index.md +97 -0
- package/references/methodology/leadership.md +200 -0
- package/references/methodology/lean-canvas.md +116 -0
- package/references/methodology/macro-trends.md +192 -0
- package/references/methodology/map-unknowns.md +137 -0
- package/references/methodology/mullins-7-domains.md +104 -0
- package/references/methodology/problem-types.md +65 -0
- package/references/methodology/root-cause.md +178 -0
- package/references/methodology/sapphire-encoding.md +355 -0
- package/references/methodology/scenario-plan.md +178 -0
- package/references/methodology/score-innovation.md +154 -0
- package/references/methodology/structure-argument.md +158 -0
- package/references/methodology/systems-thinking.md +159 -0
- package/references/methodology/think-hats.md +147 -0
- package/references/methodology/triz-matrix.json +751 -0
- package/references/methodology/triz-principles.md +501 -0
- package/references/methodology/user-needs.md +199 -0
- package/references/methodology/validate.md +163 -0
- package/references/methodology/value-proposition.md +244 -0
- package/references/opportunities/funding-lifecycle.md +103 -0
- package/references/opportunities/grant-api-patterns.md +99 -0
- package/references/opportunities/opportunity-template.md +84 -0
- package/references/personality/assessment-philosophy.md +72 -0
- package/references/personality/lexicon.md +100 -0
- package/references/personality/persona-chains.md +56 -0
- package/references/personality/pws-lexicon-full.md +499 -0
- package/references/personality/voice-dna.md +156 -0
- package/references/personas/hat-perspectives.md +76 -0
- package/references/personas/persona-template.md +63 -0
- package/references/pipeline/act-output-contract.md +88 -0
- package/references/pipeline/chains-index.md +39 -0
- package/references/pws-profile-generation.md +79 -0
- package/references/reasoning/reasoning-schema.md +143 -0
- package/references/reasoning/reasoning-template.md +68 -0
- package/references/reasoning/run-template.md +38 -0
- package/references/research/RESEARCH_14_CLAUDE_CODE_SOURCE_ARCHITECTURE.md +209 -0
- package/references/research/RESEARCH_15_V1.8_OPTIMIZATION_JTBD.md +375 -0
- package/references/research/RESEARCH_16_NATIVE_FIRST_PLUGIN_ARCHITECTURE.md +575 -0
- package/references/research/RESEARCH_17_MCP_UI_FRAMEWORKS.md +272 -0
- package/references/taxonomy/TAXONOMY.md +192 -0
- package/references/templates/MINTO.md +36 -0
- package/references/user-research/2026-04-05-leah-lawrence-session.md +202 -0
- package/references/vault-kit/README.md +35 -0
- package/references/vault-kit/app.json +12 -0
- package/references/vault-kit/appearance.json +12 -0
- package/references/vault-kit/graph.json +35 -0
- package/references/vault-kit/snippets/mindrian-destijl.css +297 -0
- package/references/vault-kit/templates/new-artifact.md +37 -0
- package/references/vault-kit/templates/new-meeting-note.md +35 -0
- package/references/vault-kit/templates/new-team-profile.md +29 -0
- package/references/vault-kit/templates/new-xref.md +35 -0
- package/references/visual/symbol-system.md +151 -0
- package/skills/MOSDeckEngine/SKILL.md +325 -0
- package/skills/brain-connector/SKILL.md +114 -0
- package/skills/context-engine/SKILL.md +147 -0
- package/skills/conversation-mode/SKILL.md +102 -0
- package/skills/larry-personality/SKILL.md +219 -0
- package/skills/larry-personality/framework-chains.md +92 -0
- package/skills/larry-personality/mode-engine.md +185 -0
- package/skills/mullins-scaffold/SKILL.md +61 -0
- package/skills/mullins-scaffold/scaffold.json +146 -0
- package/skills/pws-methodology/SKILL.md +49 -0
- package/skills/room-passive/SKILL.md +165 -0
- package/skills/room-proactive/SKILL.md +250 -0
- package/skills/ui-system/SKILL.md +277 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindrianOS Plugin -- Proactive Intelligence Persistence
|
|
3
|
+
* Parses analyze-room output, persists insights with repeat suppression,
|
|
4
|
+
* and tracks cross-room relationships.
|
|
5
|
+
*
|
|
6
|
+
* Exports: persistIntelligence, loadIntelligence, shouldSuppress, addCrossRoomRelationship
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
const INTELLIGENCE_FILE = '.proactive-intelligence.json';
|
|
15
|
+
const SUPPRESS_THRESHOLD = 3;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load existing intelligence from room directory.
|
|
19
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
20
|
+
* @returns {{ insights: Array, cross_room: Array, updated: string }}
|
|
21
|
+
*/
|
|
22
|
+
function loadIntelligence(roomDir) {
|
|
23
|
+
const filePath = path.join(roomDir, INTELLIGENCE_FILE);
|
|
24
|
+
try {
|
|
25
|
+
if (fs.existsSync(filePath)) {
|
|
26
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
27
|
+
const data = JSON.parse(raw);
|
|
28
|
+
return {
|
|
29
|
+
insights: Array.isArray(data.insights) ? data.insights : [],
|
|
30
|
+
cross_room: Array.isArray(data.cross_room) ? data.cross_room : [],
|
|
31
|
+
updated: data.updated || ''
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
} catch (_) {
|
|
35
|
+
// Corrupted file -- start fresh
|
|
36
|
+
}
|
|
37
|
+
return { insights: [], cross_room: [], updated: '' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Parse analyze-room stdout into structured insight objects.
|
|
42
|
+
* Handles: GAP:STRUCTURAL, GAP:SEMANTIC, GAP:ADJACENT, CONVERGE, CONTRADICT lines.
|
|
43
|
+
* @param {string} analyzeOutput - Raw stdout from analyze-room script
|
|
44
|
+
* @returns {Array<{ type: string, section?: string, term?: string, message: string, confidence: string }>}
|
|
45
|
+
*/
|
|
46
|
+
function parseAnalyzeOutput(analyzeOutput) {
|
|
47
|
+
if (!analyzeOutput || typeof analyzeOutput !== 'string') return [];
|
|
48
|
+
|
|
49
|
+
const insights = [];
|
|
50
|
+
const lines = analyzeOutput.split('\n');
|
|
51
|
+
|
|
52
|
+
for (const line of lines) {
|
|
53
|
+
const trimmed = line.trim();
|
|
54
|
+
|
|
55
|
+
// GAP:STRUCTURAL:{section}:{confidence}:{message}
|
|
56
|
+
// GAP:SEMANTIC:{section}:{confidence}:{message}
|
|
57
|
+
// GAP:ADJACENT:{section}:{confidence}:{message}
|
|
58
|
+
const gapMatch = trimmed.match(/^GAP:(STRUCTURAL|SEMANTIC|ADJACENT):([^:]+):([^:]+):(.+)$/);
|
|
59
|
+
if (gapMatch) {
|
|
60
|
+
insights.push({
|
|
61
|
+
type: 'gap',
|
|
62
|
+
subtype: gapMatch[1].toLowerCase(),
|
|
63
|
+
section: gapMatch[2],
|
|
64
|
+
confidence: gapMatch[3],
|
|
65
|
+
message: gapMatch[4]
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// CONVERGE:{term}:{count}:{confidence}:{message}
|
|
71
|
+
const convergeMatch = trimmed.match(/^CONVERGE:([^:]+):(\d+):([^:]+):(.+)$/);
|
|
72
|
+
if (convergeMatch) {
|
|
73
|
+
insights.push({
|
|
74
|
+
type: 'convergence',
|
|
75
|
+
term: convergeMatch[1],
|
|
76
|
+
count: parseInt(convergeMatch[2], 10),
|
|
77
|
+
confidence: convergeMatch[3],
|
|
78
|
+
message: convergeMatch[4]
|
|
79
|
+
});
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// CONTRADICT:{section1}:{section2}:{confidence}:{message}
|
|
84
|
+
const contradictMatch = trimmed.match(/^CONTRADICT:([^:]+):([^:]+):([^:]+):(.+)$/);
|
|
85
|
+
if (contradictMatch) {
|
|
86
|
+
insights.push({
|
|
87
|
+
type: 'contradiction',
|
|
88
|
+
section: contradictMatch[1],
|
|
89
|
+
section2: contradictMatch[2],
|
|
90
|
+
confidence: contradictMatch[3],
|
|
91
|
+
message: contradictMatch[4]
|
|
92
|
+
});
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return insights;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Match key for deduplication: type + section (for gaps/contradictions) or type + term (for convergence).
|
|
102
|
+
* @param {{ type: string, section?: string, term?: string, section2?: string }} insight
|
|
103
|
+
* @returns {string}
|
|
104
|
+
*/
|
|
105
|
+
function insightKey(insight) {
|
|
106
|
+
if (insight.type === 'convergence') {
|
|
107
|
+
return `convergence:${insight.term || ''}`;
|
|
108
|
+
}
|
|
109
|
+
if (insight.type === 'contradiction') {
|
|
110
|
+
return `contradiction:${insight.section || ''}:${insight.section2 || ''}`;
|
|
111
|
+
}
|
|
112
|
+
return `gap:${insight.subtype || ''}:${insight.section || ''}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Read recent semantic findings from the lazygraph and map them to insight
|
|
117
|
+
* records that match parseAnalyzeOutput()'s shape exactly so insightKey()
|
|
118
|
+
* dedup folds graph and bash-script findings together.
|
|
119
|
+
*
|
|
120
|
+
* Queries CONTRADICTS, CONVERGES, INVALIDATES edges with created_at
|
|
121
|
+
* greater than sinceTimestamp, walks INFORMS edges to Stakeholder nodes,
|
|
122
|
+
* and emits one insight per edge in the same shape as parseAnalyzeOutput.
|
|
123
|
+
* Empty array on any failure path. Never throws.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
126
|
+
* @param {number} sinceTimestamp - Unix ms; only edges with created_at greater than this
|
|
127
|
+
* @returns {Array<object>} insights in parseAnalyzeOutput() shape
|
|
128
|
+
*/
|
|
129
|
+
function readGraphFindings(roomDir, sinceTimestamp) {
|
|
130
|
+
try {
|
|
131
|
+
const lazygraph = require('./lazygraph-ops.cjs');
|
|
132
|
+
let handle;
|
|
133
|
+
try {
|
|
134
|
+
// Direct sync open of the room.db so we can run inside the cascade
|
|
135
|
+
// without await. If the file is missing, return empty findings.
|
|
136
|
+
const fsLocal = require('fs');
|
|
137
|
+
const pathLocal = require('path');
|
|
138
|
+
const { DatabaseSync } = require('node:sqlite');
|
|
139
|
+
const dbPath = pathLocal.join(pathLocal.resolve(roomDir), '.mindrian', 'room.db');
|
|
140
|
+
if (!fsLocal.existsSync(dbPath)) return [];
|
|
141
|
+
const db = new DatabaseSync(dbPath, { open: true, readOnly: true });
|
|
142
|
+
handle = { db, conn: db, _opened: 'sync' };
|
|
143
|
+
} catch (_) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const db = handle.db || handle.conn;
|
|
148
|
+
// Reference lazygraph to silence linters and signal contract dependency
|
|
149
|
+
void lazygraph;
|
|
150
|
+
const sinceMs = typeof sinceTimestamp === 'number' ? sinceTimestamp : 0;
|
|
151
|
+
const insights = [];
|
|
152
|
+
|
|
153
|
+
let edges = [];
|
|
154
|
+
try {
|
|
155
|
+
edges = db.prepare(
|
|
156
|
+
`SELECT source, target, type, properties FROM edges
|
|
157
|
+
WHERE type IN ('CONTRADICTS', 'CONVERGES', 'INVALIDATES')
|
|
158
|
+
LIMIT 50`
|
|
159
|
+
).all();
|
|
160
|
+
} catch (_) {
|
|
161
|
+
edges = [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
for (const edge of edges) {
|
|
165
|
+
// Filter by created_at when present in properties JSON
|
|
166
|
+
let createdAt = 0;
|
|
167
|
+
try {
|
|
168
|
+
const props = edge.properties ? JSON.parse(edge.properties) : {};
|
|
169
|
+
if (typeof props.created_at === 'number') createdAt = props.created_at;
|
|
170
|
+
} catch (_) {
|
|
171
|
+
createdAt = 0;
|
|
172
|
+
}
|
|
173
|
+
if (sinceMs > 0 && createdAt > 0 && createdAt <= sinceMs) continue;
|
|
174
|
+
|
|
175
|
+
// Resolve endpoint section names for shape-compatible insight keys
|
|
176
|
+
let sourceSection = '';
|
|
177
|
+
let targetSection = '';
|
|
178
|
+
try {
|
|
179
|
+
const srcNode = db.prepare("SELECT properties FROM nodes WHERE id = ?").get(edge.source);
|
|
180
|
+
const tgtNode = db.prepare("SELECT properties FROM nodes WHERE id = ?").get(edge.target);
|
|
181
|
+
if (srcNode && srcNode.properties) {
|
|
182
|
+
try { sourceSection = (JSON.parse(srcNode.properties).section) || edge.source.split('/')[0] || ''; } catch (_) { sourceSection = edge.source.split('/')[0] || ''; }
|
|
183
|
+
} else {
|
|
184
|
+
sourceSection = edge.source.split('/')[0] || '';
|
|
185
|
+
}
|
|
186
|
+
if (tgtNode && tgtNode.properties) {
|
|
187
|
+
try { targetSection = (JSON.parse(tgtNode.properties).section) || edge.target.split('/')[0] || ''; } catch (_) { targetSection = edge.target.split('/')[0] || ''; }
|
|
188
|
+
} else {
|
|
189
|
+
targetSection = edge.target.split('/')[0] || '';
|
|
190
|
+
}
|
|
191
|
+
} catch (_) {
|
|
192
|
+
sourceSection = edge.source.split('/')[0] || '';
|
|
193
|
+
targetSection = edge.target.split('/')[0] || '';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Cap stakeholder context to 5 other claims to bound injection noise
|
|
197
|
+
let stakeholderContext = '';
|
|
198
|
+
try {
|
|
199
|
+
const stakeholders = lazygraph.findStakeholdersByClaim
|
|
200
|
+
? db.prepare(
|
|
201
|
+
`SELECT s.id, s.name FROM stakeholders s
|
|
202
|
+
WHERE s.id IN (
|
|
203
|
+
SELECT source FROM edges WHERE target = ? AND type = 'INFORMS'
|
|
204
|
+
UNION
|
|
205
|
+
SELECT target FROM edges WHERE source = ? AND type = 'INFORMS'
|
|
206
|
+
) LIMIT 5`
|
|
207
|
+
).all(edge.source, edge.source)
|
|
208
|
+
: [];
|
|
209
|
+
if (stakeholders && stakeholders.length > 0) {
|
|
210
|
+
stakeholderContext = ' (stakeholders: ' + stakeholders.map(s => s.name).join(', ') + ')';
|
|
211
|
+
}
|
|
212
|
+
} catch (_) {
|
|
213
|
+
stakeholderContext = '';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (edge.type === 'CONTRADICTS') {
|
|
217
|
+
insights.push({
|
|
218
|
+
type: 'contradiction',
|
|
219
|
+
section: sourceSection,
|
|
220
|
+
section2: targetSection,
|
|
221
|
+
confidence: 'medium',
|
|
222
|
+
message: `Graph contradiction: ${edge.source} vs ${edge.target}${stakeholderContext}`
|
|
223
|
+
});
|
|
224
|
+
} else if (edge.type === 'CONVERGES') {
|
|
225
|
+
insights.push({
|
|
226
|
+
type: 'convergence',
|
|
227
|
+
term: `${sourceSection}+${targetSection}`,
|
|
228
|
+
count: 2,
|
|
229
|
+
confidence: 'medium',
|
|
230
|
+
message: `Graph convergence: ${edge.source} and ${edge.target}${stakeholderContext}`
|
|
231
|
+
});
|
|
232
|
+
} else if (edge.type === 'INVALIDATES') {
|
|
233
|
+
insights.push({
|
|
234
|
+
type: 'gap',
|
|
235
|
+
subtype: 'structural',
|
|
236
|
+
section: targetSection,
|
|
237
|
+
confidence: 'medium',
|
|
238
|
+
message: `Graph invalidation: ${edge.source} invalidates ${edge.target}${stakeholderContext}`
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Close the db handle if we opened it ourselves
|
|
244
|
+
try {
|
|
245
|
+
if (handle && handle._opened === 'sync' && handle.db) {
|
|
246
|
+
handle.db.close();
|
|
247
|
+
}
|
|
248
|
+
} catch (_) { /* ignore */ }
|
|
249
|
+
|
|
250
|
+
return insights;
|
|
251
|
+
} catch (_) {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Persist intelligence from analyze-room output with repeat suppression.
|
|
258
|
+
* Phase 84-05: also reads graph findings via readGraphFindings() and merges
|
|
259
|
+
* them into the same insight stream before shouldSuppress() dedup.
|
|
260
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
261
|
+
* @param {string} analyzeOutput - Raw stdout from analyze-room script
|
|
262
|
+
* @returns {{ persisted: number, new: number, suppressed: number }}
|
|
263
|
+
*/
|
|
264
|
+
function persistIntelligence(roomDir, analyzeOutput) {
|
|
265
|
+
const bashParsed = parseAnalyzeOutput(analyzeOutput);
|
|
266
|
+
|
|
267
|
+
// Phase 84-05: pull graph-sourced insights using the previous run's
|
|
268
|
+
// updated timestamp as the high-water mark. Failures fall through to [].
|
|
269
|
+
let graphParsed = [];
|
|
270
|
+
try {
|
|
271
|
+
const prior = loadIntelligence(roomDir);
|
|
272
|
+
let sinceMs = 0;
|
|
273
|
+
if (prior && prior.updated) {
|
|
274
|
+
const t = Date.parse(prior.updated);
|
|
275
|
+
if (!Number.isNaN(t)) sinceMs = t;
|
|
276
|
+
}
|
|
277
|
+
graphParsed = readGraphFindings(roomDir, sinceMs) || [];
|
|
278
|
+
} catch (_) {
|
|
279
|
+
graphParsed = [];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const parsed = bashParsed.concat(graphParsed);
|
|
283
|
+
if (parsed.length === 0) {
|
|
284
|
+
return { persisted: 0, new: 0, suppressed: 0 };
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const data = loadIntelligence(roomDir);
|
|
288
|
+
const now = new Date().toISOString();
|
|
289
|
+
|
|
290
|
+
// Build lookup by key
|
|
291
|
+
const existingMap = new Map();
|
|
292
|
+
for (let i = 0; i < data.insights.length; i++) {
|
|
293
|
+
existingMap.set(insightKey(data.insights[i]), i);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
let newCount = 0;
|
|
297
|
+
let suppressed = 0;
|
|
298
|
+
|
|
299
|
+
for (const insight of parsed) {
|
|
300
|
+
const key = insightKey(insight);
|
|
301
|
+
const existingIdx = existingMap.get(key);
|
|
302
|
+
|
|
303
|
+
if (existingIdx !== undefined) {
|
|
304
|
+
// Existing insight -- check for evidence changes, then increment times_shown
|
|
305
|
+
const existing = data.insights[existingIdx];
|
|
306
|
+
// Evidence-change detection: if confidence or message changed, reset suppression
|
|
307
|
+
const evidenceChanged = (existing.confidence !== insight.confidence) || (existing.message !== insight.message);
|
|
308
|
+
if (evidenceChanged && shouldSuppress(existing)) {
|
|
309
|
+
existing.times_shown = 0;
|
|
310
|
+
existing.confidence = insight.confidence;
|
|
311
|
+
existing.message = insight.message;
|
|
312
|
+
}
|
|
313
|
+
existing.times_shown = (existing.times_shown || 0) + 1;
|
|
314
|
+
existing.last_seen = now;
|
|
315
|
+
if (existing.times_shown >= SUPPRESS_THRESHOLD) {
|
|
316
|
+
suppressed++;
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
// New insight
|
|
320
|
+
const entry = {
|
|
321
|
+
...insight,
|
|
322
|
+
first_seen: now,
|
|
323
|
+
last_seen: now,
|
|
324
|
+
times_shown: 0
|
|
325
|
+
};
|
|
326
|
+
data.insights.push(entry);
|
|
327
|
+
existingMap.set(key, data.insights.length - 1);
|
|
328
|
+
newCount++;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
data.updated = now;
|
|
333
|
+
|
|
334
|
+
// Write atomically
|
|
335
|
+
const filePath = path.join(roomDir, INTELLIGENCE_FILE);
|
|
336
|
+
const tmpPath = filePath + '.tmp';
|
|
337
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');
|
|
338
|
+
fs.renameSync(tmpPath, filePath);
|
|
339
|
+
|
|
340
|
+
return { persisted: parsed.length, new: newCount, suppressed };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Check if an insight should be suppressed (shown 3+ times).
|
|
345
|
+
* @param {{ times_shown: number }} insight
|
|
346
|
+
* @returns {boolean}
|
|
347
|
+
*/
|
|
348
|
+
function shouldSuppress(insight) {
|
|
349
|
+
return (insight && typeof insight.times_shown === 'number' && insight.times_shown >= SUPPRESS_THRESHOLD);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Add or update a cross-room relationship.
|
|
354
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
355
|
+
* @param {string} sourceRoom - Source room name/path
|
|
356
|
+
* @param {string} targetRoom - Target room name/path
|
|
357
|
+
* @param {string[]} sharedConcepts - Array of shared concept strings
|
|
358
|
+
*/
|
|
359
|
+
function addCrossRoomRelationship(roomDir, sourceRoom, targetRoom, sharedConcepts) {
|
|
360
|
+
const data = loadIntelligence(roomDir);
|
|
361
|
+
const now = new Date().toISOString();
|
|
362
|
+
|
|
363
|
+
// Find existing relationship (same source + target)
|
|
364
|
+
const existing = data.cross_room.find(
|
|
365
|
+
cr => cr.source_room === sourceRoom && cr.target_room === targetRoom
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
if (existing) {
|
|
369
|
+
// Union shared concepts
|
|
370
|
+
const conceptSet = new Set([...(existing.shared_concepts || []), ...sharedConcepts]);
|
|
371
|
+
existing.shared_concepts = [...conceptSet];
|
|
372
|
+
existing.detected = now;
|
|
373
|
+
} else {
|
|
374
|
+
data.cross_room.push({
|
|
375
|
+
source_room: sourceRoom,
|
|
376
|
+
target_room: targetRoom,
|
|
377
|
+
shared_concepts: [...sharedConcepts],
|
|
378
|
+
detected: now
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
data.updated = now;
|
|
383
|
+
|
|
384
|
+
// Write atomically
|
|
385
|
+
const filePath = path.join(roomDir, INTELLIGENCE_FILE);
|
|
386
|
+
const tmpPath = filePath + '.tmp';
|
|
387
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');
|
|
388
|
+
fs.renameSync(tmpPath, filePath);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Get new or changed findings not previously seen by the user.
|
|
393
|
+
* Compares current analyze-room insights against persisted intelligence.
|
|
394
|
+
* Returns max 5 findings sorted by confidence descending.
|
|
395
|
+
*
|
|
396
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
397
|
+
* @param {Array<{ type: string, section?: string, term?: string, confidence: string, message: string }>} currentInsights - Parsed insights from current analyze-room run
|
|
398
|
+
* @returns {Array<{ type: string, section?: string, term?: string, confidence: string, message: string, isNew: boolean }>}
|
|
399
|
+
*/
|
|
400
|
+
function getNewFindings(roomDir, currentInsights) {
|
|
401
|
+
if (!Array.isArray(currentInsights) || currentInsights.length === 0) return [];
|
|
402
|
+
|
|
403
|
+
const data = loadIntelligence(roomDir);
|
|
404
|
+
|
|
405
|
+
// Build lookup of persisted insights by key
|
|
406
|
+
const persistedMap = new Map();
|
|
407
|
+
for (const insight of data.insights) {
|
|
408
|
+
persistedMap.set(insightKey(insight), insight);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const findings = [];
|
|
412
|
+
|
|
413
|
+
for (const insight of currentInsights) {
|
|
414
|
+
const key = insightKey(insight);
|
|
415
|
+
const existing = persistedMap.get(key);
|
|
416
|
+
|
|
417
|
+
// Skip insights that have been decided on
|
|
418
|
+
if (existing && existing.decided) continue;
|
|
419
|
+
|
|
420
|
+
// Skip suppressed insights (shown 3+ times)
|
|
421
|
+
if (existing && shouldSuppress(existing)) continue;
|
|
422
|
+
|
|
423
|
+
let isNew = false;
|
|
424
|
+
let include = false;
|
|
425
|
+
|
|
426
|
+
if (!existing) {
|
|
427
|
+
// Brand new insight
|
|
428
|
+
isNew = true;
|
|
429
|
+
include = true;
|
|
430
|
+
} else if (existing.confidence !== insight.confidence) {
|
|
431
|
+
// Confidence has changed -- updated finding
|
|
432
|
+
isNew = false;
|
|
433
|
+
include = true;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (include) {
|
|
437
|
+
findings.push({
|
|
438
|
+
type: insight.type,
|
|
439
|
+
subtype: insight.subtype,
|
|
440
|
+
section: insight.section,
|
|
441
|
+
term: insight.term,
|
|
442
|
+
section2: insight.section2,
|
|
443
|
+
confidence: insight.confidence,
|
|
444
|
+
message: insight.message,
|
|
445
|
+
isNew
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Sort by confidence descending
|
|
451
|
+
findings.sort((a, b) => parseFloat(b.confidence || '0') - parseFloat(a.confidence || '0'));
|
|
452
|
+
|
|
453
|
+
// Return max 5
|
|
454
|
+
return findings.slice(0, 5);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Record a user decision (approve/reject/defer) for an insight.
|
|
459
|
+
* Persists to .proactive-intelligence.json and marks insight as decided.
|
|
460
|
+
*
|
|
461
|
+
* @param {string} roomDir - Absolute path to room directory
|
|
462
|
+
* @param {string} key - Insight key (from insightKey())
|
|
463
|
+
* @param {'approve'|'reject'|'defer'} decision - The user's decision
|
|
464
|
+
* @param {string} reason - Reason for the decision (especially important for reject)
|
|
465
|
+
* @returns {{ recorded: boolean, edgeType: string }}
|
|
466
|
+
*/
|
|
467
|
+
function recordDecision(roomDir, key, decision, reason) {
|
|
468
|
+
const data = loadIntelligence(roomDir);
|
|
469
|
+
const now = new Date().toISOString();
|
|
470
|
+
|
|
471
|
+
// Initialize decisions array if not present
|
|
472
|
+
if (!Array.isArray(data.decisions)) {
|
|
473
|
+
data.decisions = [];
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Record the decision
|
|
477
|
+
const decisionEntry = {
|
|
478
|
+
insight_key: key,
|
|
479
|
+
decision,
|
|
480
|
+
reason: reason || '',
|
|
481
|
+
timestamp: now
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
// If rejection, store reason as separate field for graph enrichment (Decision #13)
|
|
485
|
+
if (decision === 'reject') {
|
|
486
|
+
decisionEntry.rejection_reason = reason || '';
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
data.decisions.push(decisionEntry);
|
|
490
|
+
|
|
491
|
+
// Mark the corresponding insight as decided so it won't be re-surfaced
|
|
492
|
+
for (const insight of data.insights) {
|
|
493
|
+
if (insightKey(insight) === key) {
|
|
494
|
+
insight.decided = true;
|
|
495
|
+
insight.decision_type = decision;
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
data.updated = now;
|
|
501
|
+
|
|
502
|
+
// Write atomically (tmp + rename pattern)
|
|
503
|
+
const filePath = path.join(roomDir, INTELLIGENCE_FILE);
|
|
504
|
+
const tmpPath = filePath + '.tmp';
|
|
505
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');
|
|
506
|
+
fs.renameSync(tmpPath, filePath);
|
|
507
|
+
|
|
508
|
+
// Map decision to SQLite edge type
|
|
509
|
+
const edgeTypeMap = {
|
|
510
|
+
approve: 'INVALIDATES',
|
|
511
|
+
reject: 'CONFIRMS',
|
|
512
|
+
defer: 'DEFERRED'
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
return { recorded: true, edgeType: edgeTypeMap[decision] || 'DEFERRED' };
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
module.exports = {
|
|
519
|
+
persistIntelligence,
|
|
520
|
+
loadIntelligence,
|
|
521
|
+
shouldSuppress,
|
|
522
|
+
addCrossRoomRelationship,
|
|
523
|
+
parseAnalyzeOutput,
|
|
524
|
+
insightKey,
|
|
525
|
+
getNewFindings,
|
|
526
|
+
recordDecision,
|
|
527
|
+
readGraphFindings
|
|
528
|
+
};
|