@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,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindrianOS Plugin -- Shared Room Scanner
|
|
3
|
+
*
|
|
4
|
+
* Walks a Data Room and returns a structured snapshot of its anatomy:
|
|
5
|
+
* top-level sections, sub-rooms, team profiles, meetings + filed-to stubs,
|
|
6
|
+
* and all non-system content files. Zero npm dependencies (fs + path only).
|
|
7
|
+
*
|
|
8
|
+
* Consumed by the vault wikilink injector, branded footer injector, and any
|
|
9
|
+
* other vault-layer script that needs a consistent view of the room.
|
|
10
|
+
*
|
|
11
|
+
* const { scanRoom } = require('./lib/vault/room-scanner.cjs');
|
|
12
|
+
* const room = scanRoom('/path/to/room');
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
// Files that are "system" (identity/state/navigation), not content artifacts.
|
|
21
|
+
// Matches the skip-set used by build-ecosystem-graph.cjs.
|
|
22
|
+
const SYSTEM_FILES = new Set([
|
|
23
|
+
'STATE.md',
|
|
24
|
+
'ROOM.md',
|
|
25
|
+
'CLAUDE.md',
|
|
26
|
+
'COWORK-INSTRUCTIONS.md',
|
|
27
|
+
'TODOS.md',
|
|
28
|
+
'WHATS-NEXT.md',
|
|
29
|
+
'INDEX.md',
|
|
30
|
+
'MILESTONES.md',
|
|
31
|
+
'TEAM-STATE.md',
|
|
32
|
+
'MEETINGS-INTELLIGENCE.md',
|
|
33
|
+
'action-items.md',
|
|
34
|
+
// Phase 81-02: MINTO.md is generator OUTPUT, not user content. Excluding
|
|
35
|
+
// it from the content scan is required for --write determinism: without
|
|
36
|
+
// this, a second --write run sees the previously written MINTO.md as a
|
|
37
|
+
// new artifact and injects it into the sources list and MECE tree.
|
|
38
|
+
'MINTO.md',
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
const SKIP_DIRS = new Set([
|
|
42
|
+
'.mindrian',
|
|
43
|
+
'.git',
|
|
44
|
+
'node_modules',
|
|
45
|
+
'.lazygraph',
|
|
46
|
+
'.context',
|
|
47
|
+
'exports',
|
|
48
|
+
'export',
|
|
49
|
+
'diagrams',
|
|
50
|
+
'.obsidian',
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
// Canonical Data Room section names (top level + sub-room level).
|
|
54
|
+
const KNOWN_SECTIONS = new Set([
|
|
55
|
+
'business-model',
|
|
56
|
+
'competitive-analysis',
|
|
57
|
+
'financial-model',
|
|
58
|
+
'legal-ip',
|
|
59
|
+
'market-analysis',
|
|
60
|
+
'meetings',
|
|
61
|
+
'opportunity-bank',
|
|
62
|
+
'problem-definition',
|
|
63
|
+
'solution-design',
|
|
64
|
+
'team',
|
|
65
|
+
'team-execution',
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
/** Safe readdir that returns [] on error. */
|
|
69
|
+
function safeReaddir(dir) {
|
|
70
|
+
try {
|
|
71
|
+
return fs.readdirSync(dir, { withFileTypes: true });
|
|
72
|
+
} catch (_) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Safe readFile. Returns string or null. */
|
|
78
|
+
function safeRead(file) {
|
|
79
|
+
try {
|
|
80
|
+
return fs.readFileSync(file, 'utf-8');
|
|
81
|
+
} catch (_) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Parse YAML frontmatter into a flat string->string map. Returns {} if none. */
|
|
87
|
+
function parseFrontmatter(content) {
|
|
88
|
+
if (!content || !content.startsWith('---')) return {};
|
|
89
|
+
const end = content.indexOf('\n---', 3);
|
|
90
|
+
if (end === -1) return {};
|
|
91
|
+
const block = content.slice(3, end);
|
|
92
|
+
const out = {};
|
|
93
|
+
for (const line of block.split('\n')) {
|
|
94
|
+
const m = line.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
|
|
95
|
+
if (m) {
|
|
96
|
+
let v = m[2].trim();
|
|
97
|
+
// Strip surrounding quotes
|
|
98
|
+
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
|
|
99
|
+
v = v.slice(1, -1);
|
|
100
|
+
}
|
|
101
|
+
out[m[1]] = v;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Title-case a kebab slug: "avital-leibovich" -> "Avital Leibovich". */
|
|
108
|
+
function slugToTitle(slug) {
|
|
109
|
+
return slug
|
|
110
|
+
.split(/[-_]/)
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
113
|
+
.join(' ');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Extract a display name from a PROFILE.md file.
|
|
118
|
+
* Priority: frontmatter.name -> first H1 heading (stripped of parenthetical) -> title-cased folder name.
|
|
119
|
+
*/
|
|
120
|
+
function extractDisplayName(profilePath, folderName) {
|
|
121
|
+
const content = safeRead(profilePath);
|
|
122
|
+
if (!content) return slugToTitle(folderName);
|
|
123
|
+
const fm = parseFrontmatter(content);
|
|
124
|
+
if (fm.name) return fm.name;
|
|
125
|
+
// Scan post-frontmatter body for first H1
|
|
126
|
+
let body = content;
|
|
127
|
+
if (content.startsWith('---')) {
|
|
128
|
+
const end = content.indexOf('\n---', 3);
|
|
129
|
+
if (end !== -1) body = content.slice(end + 4);
|
|
130
|
+
}
|
|
131
|
+
const h1 = body.match(/^#\s+(.+)$/m);
|
|
132
|
+
if (h1) {
|
|
133
|
+
// Strip trailing parenthetical like "(Diplomatic Communications ...)"
|
|
134
|
+
return h1[1].replace(/\s*\(.*\)\s*$/, '').trim();
|
|
135
|
+
}
|
|
136
|
+
return slugToTitle(folderName);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Walk team/ directory recursively to find all PROFILE.md files.
|
|
141
|
+
* Returns array of { name, displayName, path, relPath, category }.
|
|
142
|
+
*/
|
|
143
|
+
function findTeamProfiles(roomDir) {
|
|
144
|
+
const profiles = [];
|
|
145
|
+
const teamDir = path.join(roomDir, 'team');
|
|
146
|
+
if (!fs.existsSync(teamDir)) return profiles;
|
|
147
|
+
|
|
148
|
+
// Walk one level of categories (founders, advisors, partners, ...)
|
|
149
|
+
for (const catEntry of safeReaddir(teamDir)) {
|
|
150
|
+
if (!catEntry.isDirectory()) continue;
|
|
151
|
+
if (SKIP_DIRS.has(catEntry.name)) continue;
|
|
152
|
+
const category = catEntry.name;
|
|
153
|
+
const catDir = path.join(teamDir, category);
|
|
154
|
+
|
|
155
|
+
// Inside a category, each subfolder is a profile folder with PROFILE.md
|
|
156
|
+
for (const personEntry of safeReaddir(catDir)) {
|
|
157
|
+
if (!personEntry.isDirectory()) continue;
|
|
158
|
+
const personDir = path.join(catDir, personEntry.name);
|
|
159
|
+
const profilePath = path.join(personDir, 'PROFILE.md');
|
|
160
|
+
if (!fs.existsSync(profilePath)) continue;
|
|
161
|
+
const displayName = extractDisplayName(profilePath, personEntry.name);
|
|
162
|
+
profiles.push({
|
|
163
|
+
name: personEntry.name,
|
|
164
|
+
displayName,
|
|
165
|
+
path: profilePath,
|
|
166
|
+
relPath: path.relative(roomDir, profilePath).split(path.sep).join('/'),
|
|
167
|
+
category,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return profiles;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Detect top-level section directories. A section is a top-level child directory
|
|
176
|
+
* whose name appears in KNOWN_SECTIONS.
|
|
177
|
+
*/
|
|
178
|
+
function findSections(roomDir) {
|
|
179
|
+
const sections = [];
|
|
180
|
+
for (const entry of safeReaddir(roomDir)) {
|
|
181
|
+
if (!entry.isDirectory()) continue;
|
|
182
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
183
|
+
if (!KNOWN_SECTIONS.has(entry.name)) continue;
|
|
184
|
+
const secPath = path.join(roomDir, entry.name);
|
|
185
|
+
sections.push({
|
|
186
|
+
name: entry.name,
|
|
187
|
+
path: secPath,
|
|
188
|
+
hasRoom: fs.existsSync(path.join(secPath, 'ROOM.md')),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return sections;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Detect sub-rooms under sub-rooms/. Each sub-room has its own sections array.
|
|
196
|
+
*/
|
|
197
|
+
function findSubRooms(roomDir) {
|
|
198
|
+
const subRooms = [];
|
|
199
|
+
const subRoomsDir = path.join(roomDir, 'sub-rooms');
|
|
200
|
+
if (!fs.existsSync(subRoomsDir)) return subRooms;
|
|
201
|
+
|
|
202
|
+
for (const entry of safeReaddir(subRoomsDir)) {
|
|
203
|
+
if (!entry.isDirectory()) continue;
|
|
204
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
205
|
+
const srPath = path.join(subRoomsDir, entry.name);
|
|
206
|
+
// Recurse to find sections inside
|
|
207
|
+
const innerSections = [];
|
|
208
|
+
for (const inner of safeReaddir(srPath)) {
|
|
209
|
+
if (!inner.isDirectory()) continue;
|
|
210
|
+
if (SKIP_DIRS.has(inner.name)) continue;
|
|
211
|
+
if (!KNOWN_SECTIONS.has(inner.name)) continue;
|
|
212
|
+
innerSections.push({
|
|
213
|
+
name: inner.name,
|
|
214
|
+
path: path.join(srPath, inner.name),
|
|
215
|
+
hasRoom: fs.existsSync(path.join(srPath, inner.name, 'ROOM.md')),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
subRooms.push({ name: entry.name, path: srPath, sections: innerSections });
|
|
219
|
+
}
|
|
220
|
+
return subRooms;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Find meetings under meetings/YYYY-MM-DD-*. For each, detect summary/transcript
|
|
225
|
+
* and parse filed-to/ stubs to resolve their target artifact paths.
|
|
226
|
+
*/
|
|
227
|
+
function findMeetings(roomDir) {
|
|
228
|
+
const meetings = [];
|
|
229
|
+
const meetingsDir = path.join(roomDir, 'meetings');
|
|
230
|
+
if (!fs.existsSync(meetingsDir)) return meetings;
|
|
231
|
+
|
|
232
|
+
for (const entry of safeReaddir(meetingsDir)) {
|
|
233
|
+
if (!entry.isDirectory()) continue;
|
|
234
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
235
|
+
// Require YYYY-MM-DD prefix to filter noise
|
|
236
|
+
if (!/^\d{4}-\d{2}-\d{2}/.test(entry.name)) continue;
|
|
237
|
+
|
|
238
|
+
const mtgPath = path.join(meetingsDir, entry.name);
|
|
239
|
+
const hasSummary = fs.existsSync(path.join(mtgPath, 'summary.md'));
|
|
240
|
+
const hasTranscript =
|
|
241
|
+
fs.existsSync(path.join(mtgPath, 'transcript.md')) ||
|
|
242
|
+
fs.existsSync(path.join(mtgPath, 'transcript.txt'));
|
|
243
|
+
|
|
244
|
+
// Parse filed-to/ stubs
|
|
245
|
+
const filedTo = [];
|
|
246
|
+
const filedDir = path.join(mtgPath, 'filed-to');
|
|
247
|
+
if (fs.existsSync(filedDir)) {
|
|
248
|
+
for (const stub of safeReaddir(filedDir)) {
|
|
249
|
+
if (!stub.isFile()) continue;
|
|
250
|
+
if (!stub.name.endsWith('.md')) continue;
|
|
251
|
+
const stubPath = path.join(filedDir, stub.name);
|
|
252
|
+
const content = safeRead(stubPath);
|
|
253
|
+
const fm = parseFrontmatter(content);
|
|
254
|
+
const stubName = stub.name.replace(/\.md$/, '');
|
|
255
|
+
filedTo.push({
|
|
256
|
+
name: stubName,
|
|
257
|
+
path: stubPath,
|
|
258
|
+
relPath: path
|
|
259
|
+
.relative(roomDir, stubPath)
|
|
260
|
+
.split(path.sep)
|
|
261
|
+
.join('/'),
|
|
262
|
+
targetPath: fm.filed_to || null,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
meetings.push({
|
|
268
|
+
slug: entry.name,
|
|
269
|
+
path: mtgPath,
|
|
270
|
+
relPath: path
|
|
271
|
+
.relative(roomDir, mtgPath)
|
|
272
|
+
.split(path.sep)
|
|
273
|
+
.join('/'),
|
|
274
|
+
hasSummary,
|
|
275
|
+
hasTranscript,
|
|
276
|
+
filedTo,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return meetings;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Walk the room and collect every non-system .md content file.
|
|
284
|
+
* Marks each with its top-level section and whether it is a filed-to stub
|
|
285
|
+
* or an xref (based on filename heuristics).
|
|
286
|
+
*/
|
|
287
|
+
function findContentFiles(roomDir) {
|
|
288
|
+
const files = [];
|
|
289
|
+
|
|
290
|
+
function walk(dir, topSection) {
|
|
291
|
+
for (const entry of safeReaddir(dir)) {
|
|
292
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
293
|
+
const p = path.join(dir, entry.name);
|
|
294
|
+
if (entry.isDirectory()) {
|
|
295
|
+
// Only recurse into relevant dirs -- skip the team/ PROFILE tree here
|
|
296
|
+
// (it's cataloged separately) and sub-rooms/ (scanned via findSubRooms).
|
|
297
|
+
walk(p, topSection || (KNOWN_SECTIONS.has(entry.name) ? entry.name : null));
|
|
298
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
299
|
+
if (SYSTEM_FILES.has(entry.name)) continue;
|
|
300
|
+
const rel = path.relative(roomDir, p).split(path.sep).join('/');
|
|
301
|
+
const isFiledTo = rel.includes('/filed-to/');
|
|
302
|
+
const isXref = /(^|\/)xref-|cross-ref/.test(rel);
|
|
303
|
+
files.push({
|
|
304
|
+
path: p,
|
|
305
|
+
relPath: rel,
|
|
306
|
+
section: topSection || null,
|
|
307
|
+
isXref,
|
|
308
|
+
isFiledTo,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
walk(roomDir, null);
|
|
315
|
+
return files;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Main entry point. Scan a Data Room and return a structured snapshot.
|
|
320
|
+
*/
|
|
321
|
+
function scanRoom(roomDir) {
|
|
322
|
+
if (!roomDir || typeof roomDir !== 'string') {
|
|
323
|
+
throw new Error('scanRoom: roomDir must be a string');
|
|
324
|
+
}
|
|
325
|
+
const absRoom = path.resolve(roomDir);
|
|
326
|
+
if (!fs.existsSync(absRoom)) {
|
|
327
|
+
throw new Error('scanRoom: room directory does not exist: ' + absRoom);
|
|
328
|
+
}
|
|
329
|
+
if (!fs.statSync(absRoom).isDirectory()) {
|
|
330
|
+
throw new Error('scanRoom: room path is not a directory: ' + absRoom);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
roomName: path.basename(absRoom),
|
|
335
|
+
roomDir: absRoom,
|
|
336
|
+
sections: findSections(absRoom),
|
|
337
|
+
subRooms: findSubRooms(absRoom),
|
|
338
|
+
teamProfiles: findTeamProfiles(absRoom),
|
|
339
|
+
meetings: findMeetings(absRoom),
|
|
340
|
+
contentFiles: findContentFiles(absRoom),
|
|
341
|
+
systemFiles: Array.from(SYSTEM_FILES),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
module.exports = {
|
|
346
|
+
scanRoom,
|
|
347
|
+
parseFrontmatter,
|
|
348
|
+
slugToTitle,
|
|
349
|
+
SYSTEM_FILES,
|
|
350
|
+
SKIP_DIRS,
|
|
351
|
+
KNOWN_SECTIONS,
|
|
352
|
+
};
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindrianOS Plugin -- Wikilink Builder (pure functions)
|
|
3
|
+
*
|
|
4
|
+
* Shared builder module for native wikilink injection at filing time.
|
|
5
|
+
* Extracted from scripts/vault-wikilink-injector.cjs (Phase 76) so any filing
|
|
6
|
+
* pathway -- /mos:file-meeting, room-passive, xref generators -- can inject
|
|
7
|
+
* wikilinks at write time instead of relying on a retroactive batch pass.
|
|
8
|
+
*
|
|
9
|
+
* Zero fs/child_process imports. Callers pass in team-profile arrays and
|
|
10
|
+
* receive transformed strings. Idempotent: running twice produces the same
|
|
11
|
+
* output.
|
|
12
|
+
*
|
|
13
|
+
* const wb = require('./lib/vault/wikilink-builder.cjs');
|
|
14
|
+
* const linked = wb.buildTeamLinks(content, room.teamProfiles, {
|
|
15
|
+
* ownProfilePath: filePath,
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
'use strict';
|
|
20
|
+
|
|
21
|
+
// ---------- Pure helpers (verbatim from Phase 76 injector) ----------
|
|
22
|
+
|
|
23
|
+
/** Escape regex metacharacters. */
|
|
24
|
+
function reEscape(s) {
|
|
25
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Return { bodyStart } -- offset into `content` after any YAML frontmatter
|
|
30
|
+
* block. Body modifications should only occur at offsets >= bodyStart.
|
|
31
|
+
*/
|
|
32
|
+
function frontmatterSplit(content) {
|
|
33
|
+
if (!content || !content.startsWith('---')) return { bodyStart: 0 };
|
|
34
|
+
const end = content.indexOf('\n---', 3);
|
|
35
|
+
if (end === -1) return { bodyStart: 0 };
|
|
36
|
+
return { bodyStart: end + 4 };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Replace the first occurrence of `needle` in `haystack` at or after `offset`
|
|
41
|
+
* that is NOT already inside a [[wikilink]]. Whole-word boundary enforced via
|
|
42
|
+
* \b. Returns the new string, or null if no suitable occurrence was found.
|
|
43
|
+
*/
|
|
44
|
+
function replaceFirstOutsideLinks(haystack, needle, replacement, offset) {
|
|
45
|
+
const re = new RegExp('\\b' + reEscape(needle) + '\\b', 'g');
|
|
46
|
+
re.lastIndex = offset || 0;
|
|
47
|
+
let m;
|
|
48
|
+
while ((m = re.exec(haystack)) !== null) {
|
|
49
|
+
const idx = m.index;
|
|
50
|
+
const before = haystack.slice(0, idx);
|
|
51
|
+
const lastOpen = before.lastIndexOf('[[');
|
|
52
|
+
const lastClose = before.lastIndexOf(']]');
|
|
53
|
+
if (lastOpen > lastClose) {
|
|
54
|
+
// Inside a wikilink; skip.
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
return (
|
|
58
|
+
haystack.slice(0, idx) + replacement + haystack.slice(idx + needle.length)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Append a structural line after frontmatter (or at the top if none). */
|
|
65
|
+
function appendStructuralLine(content, line) {
|
|
66
|
+
if (content.startsWith('---')) {
|
|
67
|
+
const fmEnd = content.indexOf('\n---', 3);
|
|
68
|
+
if (fmEnd !== -1) {
|
|
69
|
+
const fmClose = fmEnd + 4;
|
|
70
|
+
return (
|
|
71
|
+
content.slice(0, fmClose) + '\n' + line + '\n' + content.slice(fmClose)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return line + '\n' + content;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** "2026-04-09-align-strategy-session" -> "Align Strategy Session". */
|
|
79
|
+
function meetingDisplayName(slug) {
|
|
80
|
+
if (!slug) return '';
|
|
81
|
+
const rest = slug.replace(/^\d{4}-\d{2}-\d{2}-?/, '');
|
|
82
|
+
if (!rest) return slug;
|
|
83
|
+
return rest
|
|
84
|
+
.split('-')
|
|
85
|
+
.filter(Boolean)
|
|
86
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
87
|
+
.join(' ');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** "business-model" -> "Business Model". */
|
|
91
|
+
function slugToTitle(slug) {
|
|
92
|
+
if (!slug) return '';
|
|
93
|
+
return slug
|
|
94
|
+
.split(/[-_]/)
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
97
|
+
.join(' ');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---------- Public API ----------
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Replace the first occurrence of each team member's display name in `text`
|
|
104
|
+
* with a wikilink to their PROFILE.md. Only touches body (skips frontmatter).
|
|
105
|
+
* Case-sensitive whole-word match. Sorts by display name length DESC so
|
|
106
|
+
* longer names win over shorter prefixes. Skips self-link when the file being
|
|
107
|
+
* processed IS that person's own profile.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} text
|
|
110
|
+
* @param {Array<{name:string,displayName:string,path:string,category:string}>} teamProfiles
|
|
111
|
+
* @param {{ ownProfilePath?: string|null }} [opts]
|
|
112
|
+
* @returns {string} new text (original unchanged if no replacements)
|
|
113
|
+
*/
|
|
114
|
+
function buildTeamLinks(text, teamProfiles, opts) {
|
|
115
|
+
if (!text || !Array.isArray(teamProfiles) || teamProfiles.length === 0) {
|
|
116
|
+
return text;
|
|
117
|
+
}
|
|
118
|
+
const ownProfilePath = (opts && opts.ownProfilePath) || null;
|
|
119
|
+
const { bodyStart } = frontmatterSplit(text);
|
|
120
|
+
|
|
121
|
+
const targets = teamProfiles
|
|
122
|
+
.filter((p) => p && p.displayName && p.name && p.category)
|
|
123
|
+
.map((p) => ({
|
|
124
|
+
displayName: p.displayName,
|
|
125
|
+
linkTarget: `[[team/${p.category}/${p.name}/PROFILE.md|${p.displayName}]]`,
|
|
126
|
+
ownProfilePath: p.path || null,
|
|
127
|
+
}))
|
|
128
|
+
.sort((a, b) => b.displayName.length - a.displayName.length);
|
|
129
|
+
|
|
130
|
+
let current = text;
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
for (const t of targets) {
|
|
133
|
+
if (seen.has(t.displayName)) continue;
|
|
134
|
+
if (ownProfilePath && t.ownProfilePath === ownProfilePath) continue;
|
|
135
|
+
const next = replaceFirstOutsideLinks(
|
|
136
|
+
current,
|
|
137
|
+
t.displayName,
|
|
138
|
+
t.linkTarget,
|
|
139
|
+
bodyStart
|
|
140
|
+
);
|
|
141
|
+
if (next && next !== current) {
|
|
142
|
+
current = next;
|
|
143
|
+
seen.add(t.displayName);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return current;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Build a section wikilink.
|
|
151
|
+
* @param {string} sectionName
|
|
152
|
+
* @param {{ display?: string }} [opts]
|
|
153
|
+
* @returns {string}
|
|
154
|
+
*/
|
|
155
|
+
function buildSectionLink(sectionName, opts) {
|
|
156
|
+
const display = (opts && opts.display) || sectionName;
|
|
157
|
+
return `[[${sectionName}/ROOM.md|${display}]]`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Build a meeting summary wikilink.
|
|
162
|
+
* @param {string} meetingSlug
|
|
163
|
+
* @returns {string}
|
|
164
|
+
*/
|
|
165
|
+
function buildMeetingLink(meetingSlug) {
|
|
166
|
+
return `[[meetings/${meetingSlug}/summary.md|${meetingDisplayName(meetingSlug)}]]`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Build the filed-to footer lines (2-line block, or 1 line if targetPath null).
|
|
171
|
+
* @param {{ targetPath: string|null, meetingSlug: string }} args
|
|
172
|
+
* @returns {string}
|
|
173
|
+
*/
|
|
174
|
+
function buildFiledToFooter(args) {
|
|
175
|
+
const targetPath = args && args.targetPath;
|
|
176
|
+
const meetingSlug = args && args.meetingSlug;
|
|
177
|
+
const lines = [];
|
|
178
|
+
if (targetPath) {
|
|
179
|
+
lines.push(`-> Full artifact: [[${targetPath}]]`);
|
|
180
|
+
}
|
|
181
|
+
if (meetingSlug) {
|
|
182
|
+
const display = meetingDisplayName(meetingSlug);
|
|
183
|
+
lines.push(`<- Source meeting: [[meetings/${meetingSlug}/summary.md|${display}]]`);
|
|
184
|
+
}
|
|
185
|
+
return lines.join('\n');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Inject filed-to footer lines into `content` after the frontmatter block.
|
|
190
|
+
* Idempotent: if a line is already present, it is not duplicated.
|
|
191
|
+
*
|
|
192
|
+
* @param {string} content
|
|
193
|
+
* @param {{ targetPath: string|null, meetingSlug: string }} args
|
|
194
|
+
* @returns {string}
|
|
195
|
+
*/
|
|
196
|
+
function injectFiledToFooter(content, args) {
|
|
197
|
+
if (!content) return content;
|
|
198
|
+
const targetPath = args && args.targetPath;
|
|
199
|
+
const meetingSlug = args && args.meetingSlug;
|
|
200
|
+
let current = content;
|
|
201
|
+
|
|
202
|
+
if (targetPath) {
|
|
203
|
+
const line = `-> Full artifact: [[${targetPath}]]`;
|
|
204
|
+
if (!current.includes(line)) {
|
|
205
|
+
current = appendStructuralLine(current, line);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (meetingSlug) {
|
|
209
|
+
const display = meetingDisplayName(meetingSlug);
|
|
210
|
+
const line = `<- Source meeting: [[meetings/${meetingSlug}/summary.md|${display}]]`;
|
|
211
|
+
if (!current.includes(line)) {
|
|
212
|
+
current = appendStructuralLine(current, line);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return current;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
module.exports = {
|
|
219
|
+
// Public builders
|
|
220
|
+
buildTeamLinks,
|
|
221
|
+
buildSectionLink,
|
|
222
|
+
buildMeetingLink,
|
|
223
|
+
buildFiledToFooter,
|
|
224
|
+
injectFiledToFooter,
|
|
225
|
+
// Helpers exported for downstream reuse
|
|
226
|
+
meetingDisplayName,
|
|
227
|
+
slugToTitle,
|
|
228
|
+
frontmatterSplit,
|
|
229
|
+
replaceFirstOutsideLinks,
|
|
230
|
+
appendStructuralLine,
|
|
231
|
+
};
|