@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.
Files changed (597) hide show
  1. package/.claude-plugin/plugin.json +21 -0
  2. package/.mcp.json +9 -0
  3. package/CHANGELOG.md +3333 -0
  4. package/LICENSE +123 -0
  5. package/README.md +673 -0
  6. package/agents/brain-query.md +80 -0
  7. package/agents/framework-runner.md +237 -0
  8. package/agents/grading.md +188 -0
  9. package/agents/investor.md +128 -0
  10. package/agents/larry-extended.md +135 -0
  11. package/agents/opportunity-scanner.md +91 -0
  12. package/agents/persona-analyst.md +132 -0
  13. package/agents/research.md +89 -0
  14. package/agents/reverse-salient-agent.md +27 -0
  15. package/bin/cli.js +142 -0
  16. package/bin/mindrian-mcp-server.cjs +182 -0
  17. package/bin/mindrian-tools.cjs +765 -0
  18. package/commands/act.md +439 -0
  19. package/commands/admin.md +404 -0
  20. package/commands/analyze-needs.md +42 -0
  21. package/commands/analyze-systems.md +39 -0
  22. package/commands/analyze-timing.md +42 -0
  23. package/commands/auto-explore.md +64 -0
  24. package/commands/beautiful-question.md +40 -0
  25. package/commands/brain-derive.md +78 -0
  26. package/commands/build-knowledge.md +42 -0
  27. package/commands/build-thesis.md +46 -0
  28. package/commands/causal.md +234 -0
  29. package/commands/challenge-assumptions.md +33 -0
  30. package/commands/compare-ventures.md +83 -0
  31. package/commands/dashboard.md +110 -0
  32. package/commands/deep-grade.md +82 -0
  33. package/commands/diagnose.md +58 -0
  34. package/commands/diagnostics.md +151 -0
  35. package/commands/doctor.md +151 -0
  36. package/commands/dominant-designs.md +40 -0
  37. package/commands/explain-decision.md +87 -0
  38. package/commands/explore-domains.md +42 -0
  39. package/commands/explore-futures.md +40 -0
  40. package/commands/explore-trends.md +42 -0
  41. package/commands/export.md +103 -0
  42. package/commands/file-meeting.md +724 -0
  43. package/commands/find-analogies.md +188 -0
  44. package/commands/find-bottlenecks.md +62 -0
  45. package/commands/find-connections.md +76 -0
  46. package/commands/funding.md +81 -0
  47. package/commands/grade.md +203 -0
  48. package/commands/graph.md +128 -0
  49. package/commands/hat-briefing.md +125 -0
  50. package/commands/heal.md +196 -0
  51. package/commands/help.md +399 -0
  52. package/commands/hmi-status.md +172 -0
  53. package/commands/jtbd.md +241 -0
  54. package/commands/leadership.md +73 -0
  55. package/commands/lean-canvas.md +40 -0
  56. package/commands/macro-trends.md +40 -0
  57. package/commands/map-unknowns.md +40 -0
  58. package/commands/memory.md +173 -0
  59. package/commands/models.md +175 -0
  60. package/commands/mos-reason.md +285 -0
  61. package/commands/mullins.md +120 -0
  62. package/commands/new-project.md +481 -0
  63. package/commands/onboard.md +434 -0
  64. package/commands/operator.md +149 -0
  65. package/commands/opportunities.md +144 -0
  66. package/commands/organize.md +497 -0
  67. package/commands/persona.md +198 -0
  68. package/commands/pipeline.md +112 -0
  69. package/commands/present.md +91 -0
  70. package/commands/publish.md +201 -0
  71. package/commands/query.md +124 -0
  72. package/commands/radar.md +72 -0
  73. package/commands/reanalyze.md +91 -0
  74. package/commands/research.md +196 -0
  75. package/commands/room.md +352 -0
  76. package/commands/rooms.md +598 -0
  77. package/commands/root-cause.md +40 -0
  78. package/commands/rs-experts.md +85 -0
  79. package/commands/rs-explain.md +100 -0
  80. package/commands/rs-fetch.md +94 -0
  81. package/commands/rs-thesis.md +85 -0
  82. package/commands/scenario-plan.md +40 -0
  83. package/commands/scheduled-tasks.md +285 -0
  84. package/commands/score-innovation.md +43 -0
  85. package/commands/scout.md +239 -0
  86. package/commands/setup.md +618 -0
  87. package/commands/snapshot.md +147 -0
  88. package/commands/speakers.md +84 -0
  89. package/commands/splash.md +28 -0
  90. package/commands/status.md +75 -0
  91. package/commands/structure-argument.md +42 -0
  92. package/commands/suggest-next.md +80 -0
  93. package/commands/systems-thinking.md +40 -0
  94. package/commands/think-hats.md +42 -0
  95. package/commands/update.md +181 -0
  96. package/commands/user-needs.md +40 -0
  97. package/commands/validate.md +40 -0
  98. package/commands/value-proposition.md +61 -0
  99. package/commands/vault.md +180 -0
  100. package/commands/visualize.md +52 -0
  101. package/commands/whitespace.md +507 -0
  102. package/commands/wiki.md +69 -0
  103. package/hooks/hooks.json +381 -0
  104. package/hooks/run-hook.cmd +64 -0
  105. package/lib/__init__.py +0 -0
  106. package/lib/__pycache__/__init__.cpython-312.pyc +0 -0
  107. package/lib/agents/auto-explore-agent.cjs +1043 -0
  108. package/lib/agents/reverse-salient-agent.cjs +679 -0
  109. package/lib/agents/tension-hook-agent.cjs +544 -0
  110. package/lib/brain/ROOM.md +44 -0
  111. package/lib/brain/chain-recommender.cjs +301 -0
  112. package/lib/chat/chat-context.js +185 -0
  113. package/lib/chat/chat-panel.js +721 -0
  114. package/lib/chat/fabric-chat.cjs +288 -0
  115. package/lib/chat/generative-tools.js +219 -0
  116. package/lib/conversation/ROOM.md +39 -0
  117. package/lib/conversation/classifier-rules.json +38 -0
  118. package/lib/conversation/classifier.cjs +264 -0
  119. package/lib/conversation/operator.cjs +287 -0
  120. package/lib/copy/115-spec-strings.cjs +55 -0
  121. package/lib/core/__init__.py +0 -0
  122. package/lib/core/__nav-stub.cjs +14 -0
  123. package/lib/core/__pycache__/__init__.cpython-312.pyc +0 -0
  124. package/lib/core/__pycache__/rs-math.cpython-312.pyc +0 -0
  125. package/lib/core/__pycache__/rs_cache.cpython-312.pyc +0 -0
  126. package/lib/core/__pycache__/rs_corpus.cpython-312.pyc +0 -0
  127. package/lib/core/__pycache__/rs_hybrid.cpython-312.pyc +0 -0
  128. package/lib/core/__pycache__/rs_math.cpython-312.pyc +0 -0
  129. package/lib/core/__pycache__/rs_rooms.cpython-312.pyc +0 -0
  130. package/lib/core/artifact-id.cjs +148 -0
  131. package/lib/core/asset-ops.cjs +151 -0
  132. package/lib/core/auto-commit-throttle.cjs +129 -0
  133. package/lib/core/bearer-token.cjs +199 -0
  134. package/lib/core/brain-client.cjs +865 -0
  135. package/lib/core/brain-derivation-prompts.cjs +326 -0
  136. package/lib/core/brain-derivation-queue.cjs +431 -0
  137. package/lib/core/brain-derivation.cjs +580 -0
  138. package/lib/core/brain-md-schema.cjs +528 -0
  139. package/lib/core/brain-md-staleness.cjs +357 -0
  140. package/lib/core/brain-response-sanitize.cjs +188 -0
  141. package/lib/core/bridge-writer.cjs +477 -0
  142. package/lib/core/chat-context-builder.cjs +253 -0
  143. package/lib/core/cross-room-aggregator.cjs +762 -0
  144. package/lib/core/daily-briefing.cjs +438 -0
  145. package/lib/core/decision-capture.cjs +618 -0
  146. package/lib/core/deep-links.cjs +82 -0
  147. package/lib/core/dispatch-optimizer.cjs +354 -0
  148. package/lib/core/dual-path-detector.cjs +84 -0
  149. package/lib/core/dual-path-detector.test.cjs +334 -0
  150. package/lib/core/exports-log.cjs +79 -0
  151. package/lib/core/feynman-minto-invariants.cjs +605 -0
  152. package/lib/core/folder-memory-async.cjs +338 -0
  153. package/lib/core/folder-memory-shared.cjs +890 -0
  154. package/lib/core/folder-memory.cjs +416 -0
  155. package/lib/core/framework-chain-composer.cjs +411 -0
  156. package/lib/core/frontmatter-schemas.cjs +330 -0
  157. package/lib/core/git-ops.cjs +141 -0
  158. package/lib/core/graph-ops.cjs +258 -0
  159. package/lib/core/hat-persistence.cjs +362 -0
  160. package/lib/core/index.cjs +60 -0
  161. package/lib/core/integration-registry.cjs +232 -0
  162. package/lib/core/intelligence-cascade.cjs +661 -0
  163. package/lib/core/lazygraph-ops.cjs +1057 -0
  164. package/lib/core/lru-cache.cjs +139 -0
  165. package/lib/core/mcp-profiles.cjs +182 -0
  166. package/lib/core/meeting-ops.cjs +54 -0
  167. package/lib/core/memory-ops.cjs +600 -0
  168. package/lib/core/migrations/ROOM.md +33 -0
  169. package/lib/core/migrations/phase-109-nodes-provenance.cjs +339 -0
  170. package/lib/core/migrations/phase-109-session-focus.cjs +99 -0
  171. package/lib/core/model-profiles.cjs +246 -0
  172. package/lib/core/mullins-scaffold.cjs +160 -0
  173. package/lib/core/nav-dial.cjs +316 -0
  174. package/lib/core/navigation/ROOM.md +15 -0
  175. package/lib/core/navigation/explanation.cjs +43 -0
  176. package/lib/core/navigation/focus.cjs +135 -0
  177. package/lib/core/navigation/ingestion.cjs +82 -0
  178. package/lib/core/navigation/insights.cjs +350 -0
  179. package/lib/core/navigation/memory-events.cjs +118 -0
  180. package/lib/core/navigation/neighborhood.cjs +78 -0
  181. package/lib/core/navigation/packet.cjs +182 -0
  182. package/lib/core/navigation/room-home.cjs +127 -0
  183. package/lib/core/navigation/transitions.cjs +82 -0
  184. package/lib/core/navigation-engine-shared.cjs +242 -0
  185. package/lib/core/navigation-engine.cjs +664 -0
  186. package/lib/core/navigation.cjs +60 -0
  187. package/lib/core/nl-graph-queries.cjs +164 -0
  188. package/lib/core/offer-presenter.cjs +406 -0
  189. package/lib/core/opportunity-extractor.cjs +183 -0
  190. package/lib/core/opportunity-ops.cjs +1371 -0
  191. package/lib/core/persona-ops.cjs +537 -0
  192. package/lib/core/persona-taxonomy.cjs +190 -0
  193. package/lib/core/platform-gates.cjs +120 -0
  194. package/lib/core/platform.cjs +257 -0
  195. package/lib/core/proactive-intelligence.cjs +528 -0
  196. package/lib/core/problem-type-router.cjs +315 -0
  197. package/lib/core/reasoning-ops.cjs +639 -0
  198. package/lib/core/reverse-salient-persona-suffix.cjs +115 -0
  199. package/lib/core/room-classifier-strict-mode.cjs +229 -0
  200. package/lib/core/room-db.cjs +127 -0
  201. package/lib/core/room-ops-async.cjs +92 -0
  202. package/lib/core/room-ops-shared.cjs +64 -0
  203. package/lib/core/room-ops-sync.cjs +70 -0
  204. package/lib/core/room-ops.cjs +32 -0
  205. package/lib/core/room-type-detector.cjs +386 -0
  206. package/lib/core/rs-brain-substrate-prompts.cjs +129 -0
  207. package/lib/core/rs-brain-substrate.cjs +570 -0
  208. package/lib/core/rs-breakthrough-scorer.cjs +255 -0
  209. package/lib/core/rs-canon-violations.cjs +82 -0
  210. package/lib/core/rs-chain-feeder.cjs +343 -0
  211. package/lib/core/rs-commercial-assessor.cjs +280 -0
  212. package/lib/core/rs-differential-scorer.cjs +376 -0
  213. package/lib/core/rs-domain-analyzer.cjs +385 -0
  214. package/lib/core/rs-egress-prompts.cjs +113 -0
  215. package/lib/core/rs-egress-telemetry.cjs +225 -0
  216. package/lib/core/rs-egress-violations.cjs +53 -0
  217. package/lib/core/rs-expert-mapper.cjs +467 -0
  218. package/lib/core/rs-fetcher-academic.cjs +697 -0
  219. package/lib/core/rs-fetcher-experts.cjs +314 -0
  220. package/lib/core/rs-fetcher-industry.cjs +731 -0
  221. package/lib/core/rs-fetcher-patents.cjs +564 -0
  222. package/lib/core/rs-innovation-classifier.cjs +194 -0
  223. package/lib/core/rs-mind-map.cjs +656 -0
  224. package/lib/core/rs-neo4j-writer.cjs +388 -0
  225. package/lib/core/rs-nl-to-query.cjs +425 -0
  226. package/lib/core/rs-pinecone-bridge.cjs +303 -0
  227. package/lib/core/rs-preprocessor.cjs +350 -0
  228. package/lib/core/rs-query-matrix.cjs +316 -0
  229. package/lib/core/rs-query-to-text.cjs +438 -0
  230. package/lib/core/rs-sqlite-mirror.cjs +443 -0
  231. package/lib/core/rs-thesis-generator.cjs +188 -0
  232. package/lib/core/rs_cache.py +479 -0
  233. package/lib/core/rs_corpus.py +468 -0
  234. package/lib/core/rs_hybrid.py +586 -0
  235. package/lib/core/rs_math.py +287 -0
  236. package/lib/core/rs_rooms.py +193 -0
  237. package/lib/core/scheduled-scanner.cjs +463 -0
  238. package/lib/core/scratchpad-ops.cjs +201 -0
  239. package/lib/core/section-8-trace-schema.cjs +138 -0
  240. package/lib/core/section-registry.cjs +111 -0
  241. package/lib/core/session-state.cjs +144 -0
  242. package/lib/core/shallow-doc-parser.cjs +174 -0
  243. package/lib/core/shallow-doc-parser.test.cjs +226 -0
  244. package/lib/core/skill-activation-router.cjs +284 -0
  245. package/lib/core/state-ops.cjs +46 -0
  246. package/lib/core/statusline-cache.cjs +266 -0
  247. package/lib/core/token-estimator.cjs +348 -0
  248. package/lib/core/user-archetype.cjs +239 -0
  249. package/lib/core/user-md-ops.cjs +524 -0
  250. package/lib/core/visual-ops.cjs +624 -0
  251. package/lib/core/write-lock.cjs +149 -0
  252. package/lib/graph/canvas-graph.js +467 -0
  253. package/lib/graph/constellation-config.cjs +299 -0
  254. package/lib/graph/graph-detail-panel.js +165 -0
  255. package/lib/hmi/ROOM.md +47 -0
  256. package/lib/hmi/across-session-memory.cjs +604 -0
  257. package/lib/hmi/cross-room-memory.cjs +575 -0
  258. package/lib/hmi/decoy-tier.cjs +395 -0
  259. package/lib/hmi/jtbd-classifier.cjs +219 -0
  260. package/lib/hmi/jtbd-state.cjs +199 -0
  261. package/lib/hmi/jtbd-taxonomy.json +392 -0
  262. package/lib/hmi/selector-dispatcher.cjs +546 -0
  263. package/lib/hmi/selector-telemetry.cjs +263 -0
  264. package/lib/hmi/shape-f0-renderer.cjs +139 -0
  265. package/lib/hmi/shape-f1-fallback.cjs +80 -0
  266. package/lib/hmi/shape-f1-renderer.cjs +138 -0
  267. package/lib/hmi/shape-f2-renderer.cjs +132 -0
  268. package/lib/hmi/shape-f3-renderer.cjs +66 -0
  269. package/lib/hmi/shape-f4-renderer.cjs +72 -0
  270. package/lib/hmi/shape-f5-renderer.cjs +155 -0
  271. package/lib/hmi/shape-f6-plan-review-renderer.cjs +312 -0
  272. package/lib/hmi/shape-f6-renderer.cjs +144 -0
  273. package/lib/hmi/shape-g-renderer.cjs +219 -0
  274. package/lib/hmi/shape-h-renderer.cjs +222 -0
  275. package/lib/hmi/tier-check.cjs +63 -0
  276. package/lib/import/PRECONDITIONS.md +41 -0
  277. package/lib/import/branding.cjs +210 -0
  278. package/lib/import/branding.test.cjs +235 -0
  279. package/lib/import/classifications-sync.cjs +104 -0
  280. package/lib/import/classifications-sync.test.cjs +129 -0
  281. package/lib/import/enricher.cjs +296 -0
  282. package/lib/import/enricher.test.cjs +273 -0
  283. package/lib/import/integration.test.cjs +376 -0
  284. package/lib/import/manifest.cjs +129 -0
  285. package/lib/import/manifest.schema.json +185 -0
  286. package/lib/import/manifest.test.cjs +123 -0
  287. package/lib/import/meeting-detector.cjs +92 -0
  288. package/lib/import/meeting-detector.test.cjs +100 -0
  289. package/lib/import/person-detector.cjs +229 -0
  290. package/lib/import/person-detector.test.cjs +149 -0
  291. package/lib/import/report.cjs +186 -0
  292. package/lib/import/report.test.cjs +186 -0
  293. package/lib/import/room-md-scaffolder.cjs +49 -0
  294. package/lib/import/router.cjs +224 -0
  295. package/lib/import/router.test.cjs +356 -0
  296. package/lib/import/run-all-tests.cjs +36 -0
  297. package/lib/import/smoke-test.cjs +213 -0
  298. package/lib/import/smoke-test.test.cjs +148 -0
  299. package/lib/import/test-fixtures/collision-vault/preexisting-room/STATE.md +8 -0
  300. package/lib/import/test-fixtures/collision-vault/preexisting-room/problem-definition/onboarding/onboarding.md +7 -0
  301. package/lib/import/test-fixtures/collision-vault/source/onboarding.md +5 -0
  302. package/lib/import/test-fixtures/obsidian-vault/.obsidian/workspace.json +1 -0
  303. package/lib/import/test-fixtures/obsidian-vault/notes/with-wikilinks.md +4 -0
  304. package/lib/import/test-fixtures/tiny-vault/notes/2026-01-15-team-sync.md +9 -0
  305. package/lib/import/test-fixtures/tiny-vault/notes/empty.md +3 -0
  306. package/lib/import/test-fixtures/tiny-vault/notes/onboarding.md +5 -0
  307. package/lib/import/test-fixtures/tiny-vault/notes/pricing.md +5 -0
  308. package/lib/import/test-fixtures/tiny-vault/notes/random.md +4 -0
  309. package/lib/import/undo.test.cjs +199 -0
  310. package/lib/import/vault-scanner.cjs +105 -0
  311. package/lib/import/vault-scanner.test.cjs +67 -0
  312. package/lib/mcp/app-html/dashboard.html +316 -0
  313. package/lib/mcp/app-html/graph.html +428 -0
  314. package/lib/mcp/app-html/mindrian-platform.html +1841 -0
  315. package/lib/mcp/app-html/wiki.html +383 -0
  316. package/lib/mcp/app-views.cjs +322 -0
  317. package/lib/mcp/brain-router.cjs +418 -0
  318. package/lib/mcp/capability-registry.cjs +62 -0
  319. package/lib/mcp/larry-context.cjs +46 -0
  320. package/lib/mcp/larry-server-instructions.md +114 -0
  321. package/lib/mcp/pipeline-state.cjs +275 -0
  322. package/lib/mcp/prompts.cjs +302 -0
  323. package/lib/mcp/resources.cjs +227 -0
  324. package/lib/mcp/session-catchup.cjs +327 -0
  325. package/lib/mcp/surface-detect.cjs +75 -0
  326. package/lib/mcp/tool-router.cjs +1034 -0
  327. package/lib/memory/aaak-compress.cjs +403 -0
  328. package/lib/memory/aaak-compress.test.cjs +288 -0
  329. package/lib/memory/async-artifact-auto-commit.test.cjs +223 -0
  330. package/lib/memory/bearer-token.test.cjs +315 -0
  331. package/lib/memory/brain-cache-lru.test.cjs +259 -0
  332. package/lib/memory/brain-client-query-shape.test.cjs +160 -0
  333. package/lib/memory/brain-derivation-graceful-degradation.test.cjs +1019 -0
  334. package/lib/memory/brain-derivation-queue.test.cjs +539 -0
  335. package/lib/memory/brain-derivation.test.cjs +634 -0
  336. package/lib/memory/brain-derive-command.test.cjs +534 -0
  337. package/lib/memory/brain-md-invariants-validator.test.cjs +704 -0
  338. package/lib/memory/brain-md-schema.test.cjs +467 -0
  339. package/lib/memory/brain-md-staleness.test.cjs +525 -0
  340. package/lib/memory/brain-server-resolution.test.cjs +314 -0
  341. package/lib/memory/chain-recommender.test.cjs +233 -0
  342. package/lib/memory/chat-context.test.cjs +128 -0
  343. package/lib/memory/command-registry.test.cjs +220 -0
  344. package/lib/memory/cross-room-aggregator.test.cjs +909 -0
  345. package/lib/memory/dashboard-server.test.cjs +256 -0
  346. package/lib/memory/debouncer-drain-at-prompt.test.cjs +389 -0
  347. package/lib/memory/decision-capture.test.cjs +632 -0
  348. package/lib/memory/decision-capture.worker.cjs +70 -0
  349. package/lib/memory/explain-decision-command.test.cjs +521 -0
  350. package/lib/memory/explain-decision-footer.test.cjs +316 -0
  351. package/lib/memory/explored-materials-store.cjs +392 -0
  352. package/lib/memory/feynman-minto-guardian.test.cjs +736 -0
  353. package/lib/memory/feynman-minto-invariants.test.cjs +511 -0
  354. package/lib/memory/feynman-prompts-drift.test.cjs +144 -0
  355. package/lib/memory/feynman-prompts.cjs +151 -0
  356. package/lib/memory/feynman-prompts.test.cjs +96 -0
  357. package/lib/memory/folder-memory-quadruple.test.cjs +548 -0
  358. package/lib/memory/folder-memory.test.cjs +503 -0
  359. package/lib/memory/framework-chain-composer.test.cjs +515 -0
  360. package/lib/memory/frontmatter-schema-validator.test.cjs +290 -0
  361. package/lib/memory/heal-command.test.cjs +604 -0
  362. package/lib/memory/index-artifact-transaction.test.cjs +333 -0
  363. package/lib/memory/lazygraph-rs-discoveries-view.test.cjs +122 -0
  364. package/lib/memory/mcp-input-validation.test.cjs +240 -0
  365. package/lib/memory/mcp-server-brain-deps.test.cjs +270 -0
  366. package/lib/memory/mcp-stack-fallback.test.cjs +433 -0
  367. package/lib/memory/minto-debouncer.test.cjs +407 -0
  368. package/lib/memory/minto-debouncer.worker.cjs +46 -0
  369. package/lib/memory/minto-migration-v88.test.cjs +265 -0
  370. package/lib/memory/minto-schema-v88.test.cjs +390 -0
  371. package/lib/memory/mos-status-renderer.test.cjs +631 -0
  372. package/lib/memory/narrative-schema.cjs +376 -0
  373. package/lib/memory/narrative-schema.test.cjs +209 -0
  374. package/lib/memory/nav-dial.test.cjs +414 -0
  375. package/lib/memory/navigation-engine-core.test.cjs +722 -0
  376. package/lib/memory/navigation-invariants.test.cjs +483 -0
  377. package/lib/memory/offer-presenter.test.cjs +554 -0
  378. package/lib/memory/on-stop-snapshot.test.cjs +404 -0
  379. package/lib/memory/pending-tension-store.cjs +373 -0
  380. package/lib/memory/post-compact-reinjection.test.cjs +854 -0
  381. package/lib/memory/post-write-triple.test.cjs +317 -0
  382. package/lib/memory/pre-compact-snapshot.test.cjs +495 -0
  383. package/lib/memory/problem-type-router.test.cjs +656 -0
  384. package/lib/memory/query-efficiency-telemetry.test.cjs +370 -0
  385. package/lib/memory/recompile-room-references.test.cjs +392 -0
  386. package/lib/memory/recompile-room-references.worker.cjs +42 -0
  387. package/lib/memory/record-decision-dual-write.test.cjs +454 -0
  388. package/lib/memory/room-classifier-strict-mode.test.cjs +417 -0
  389. package/lib/memory/room-minto-hook.test.cjs +398 -0
  390. package/lib/memory/rs-discovery-engine.test.cjs +323 -0
  391. package/lib/memory/run-feynman-tests.cjs +1247 -0
  392. package/lib/memory/security-trifecta.test.cjs +312 -0
  393. package/lib/memory/session-start-brain-staleness.test.cjs +363 -0
  394. package/lib/memory/session-start-triple-injection.test.cjs +514 -0
  395. package/lib/memory/sessionstart-banner-formatter.cjs +318 -0
  396. package/lib/memory/sessionstart-minto-banner.test.cjs +373 -0
  397. package/lib/memory/skill-activation-router.test.cjs +419 -0
  398. package/lib/memory/stamp-artifact-write.test.cjs +304 -0
  399. package/lib/memory/statusline-active-room.test.cjs +315 -0
  400. package/lib/memory/statusline-minto-segment.test.cjs +292 -0
  401. package/lib/memory/sync-async-entry-points.test.cjs +204 -0
  402. package/lib/memory/test-bridge-writer-enhanced.cjs +452 -0
  403. package/lib/memory/test-rs-brain-substrate-shape.cjs +529 -0
  404. package/lib/memory/test-rs-brain-substrate.cjs +636 -0
  405. package/lib/memory/test-rs-breakthrough-scorer.cjs +375 -0
  406. package/lib/memory/test-rs-canon-violations.cjs +218 -0
  407. package/lib/memory/test-rs-chain-feeder-core.cjs +344 -0
  408. package/lib/memory/test-rs-chain-feeder-skill-spawn.cjs +297 -0
  409. package/lib/memory/test-rs-commercial-assessor.cjs +385 -0
  410. package/lib/memory/test-rs-differential-scorer.cjs +480 -0
  411. package/lib/memory/test-rs-discovery-engine.cjs +603 -0
  412. package/lib/memory/test-rs-domain-analyzer.cjs +492 -0
  413. package/lib/memory/test-rs-egress-primitives.cjs +420 -0
  414. package/lib/memory/test-rs-expert-mapper.cjs +547 -0
  415. package/lib/memory/test-rs-explain-command.cjs +443 -0
  416. package/lib/memory/test-rs-fetcher-academic.cjs +848 -0
  417. package/lib/memory/test-rs-fetcher-experts.cjs +496 -0
  418. package/lib/memory/test-rs-fetcher-industry.cjs +702 -0
  419. package/lib/memory/test-rs-fetcher-patents.cjs +674 -0
  420. package/lib/memory/test-rs-innovation-classifier.cjs +301 -0
  421. package/lib/memory/test-rs-mind-map.cjs +646 -0
  422. package/lib/memory/test-rs-neo4j-writer.cjs +518 -0
  423. package/lib/memory/test-rs-nl-to-query.cjs +449 -0
  424. package/lib/memory/test-rs-pinecone-bridge.cjs +277 -0
  425. package/lib/memory/test-rs-preprocessor.cjs +433 -0
  426. package/lib/memory/test-rs-query-matrix.cjs +391 -0
  427. package/lib/memory/test-rs-query-to-text.cjs +551 -0
  428. package/lib/memory/test-rs-sqlite-mirror.cjs +649 -0
  429. package/lib/memory/test-rs-thesis-generator.cjs +360 -0
  430. package/lib/memory/triple-context-formatter.cjs +473 -0
  431. package/lib/memory/triple-context-formatter.test.cjs +442 -0
  432. package/lib/memory/user-md-persona.test.cjs +565 -0
  433. package/lib/memory/userpromptsubmit-integration.test.cjs +690 -0
  434. package/lib/memory/validators/README.md +157 -0
  435. package/lib/memory/validators/brain-md-invariants.cjs +475 -0
  436. package/lib/memory/validators/brain-substrate-invariants.cjs +285 -0
  437. package/lib/memory/validators/external-academic-invariants.cjs +249 -0
  438. package/lib/memory/validators/external-industry-invariants.cjs +271 -0
  439. package/lib/memory/validators/external-patents-invariants.cjs +266 -0
  440. package/lib/memory/validators/minto-invariants.cjs +62 -0
  441. package/lib/memory/validators/navigation-invariants.cjs +340 -0
  442. package/lib/memory/validators/queue-health.cjs +95 -0
  443. package/lib/memory/validators/snapshot-integrity.cjs +129 -0
  444. package/lib/memory/validators/stale-lifecycle.cjs +116 -0
  445. package/lib/memory/vault-section-minto-generator-atomic.test.cjs +556 -0
  446. package/lib/memory/vault-section-minto-generator-atomic.worker.cjs +73 -0
  447. package/lib/memory/write-lock-atomic.test.cjs +137 -0
  448. package/lib/memory/write-lock-atomic.worker.cjs +55 -0
  449. package/lib/parity/check-parity.cjs +83 -0
  450. package/lib/presentation/presentation-server.cjs +101 -0
  451. package/lib/presentation/presentation-watcher.cjs +123 -0
  452. package/lib/quickview/hub-server.cjs +719 -0
  453. package/lib/quickview/server.cjs +533 -0
  454. package/lib/render/JTBD-PALETTES.md +145 -0
  455. package/lib/render/ROOM.md +59 -0
  456. package/lib/render/render-v2.cjs +486 -0
  457. package/lib/render/render-v2.test.cjs +267 -0
  458. package/lib/render/render.cjs +65 -0
  459. package/lib/state/ROOM.md +46 -0
  460. package/lib/state/state-md-parser.cjs +215 -0
  461. package/lib/statusline/ROOM.md +38 -0
  462. package/lib/statusline/banner-suppression.cjs +50 -0
  463. package/lib/statusline/surface-detect.cjs +85 -0
  464. package/lib/update-bootstrap.sh.template +145 -0
  465. package/lib/vault/frontmatter-schema.cjs +297 -0
  466. package/lib/vault/room-scanner.cjs +352 -0
  467. package/lib/vault/wikilink-builder.cjs +231 -0
  468. package/lib/vault/wikilink-builder.test.cjs +182 -0
  469. package/lib/wiki/graph-links.cjs +281 -0
  470. package/lib/wiki/page-renderer.cjs +229 -0
  471. package/lib/wiki/wiki-chat.cjs +81 -0
  472. package/lib/wiki/wiki-layout.cjs +1459 -0
  473. package/lib/wiki/wiki-search.cjs +142 -0
  474. package/lib/wiki/wiki-server.cjs +678 -0
  475. package/lib/wiki/wiki-watcher.cjs +105 -0
  476. package/lib/workflow/ROOM.md +47 -0
  477. package/lib/workflow/command-resolver.cjs +155 -0
  478. package/lib/workflow/command-resolver.test.cjs +235 -0
  479. package/package.json +44 -0
  480. package/pipelines/analogy/01-decompose.md +80 -0
  481. package/pipelines/analogy/02-abstract.md +87 -0
  482. package/pipelines/analogy/03-search.md +135 -0
  483. package/pipelines/analogy/04-transfer.md +101 -0
  484. package/pipelines/analogy/05-validate.md +106 -0
  485. package/pipelines/analogy/CHAIN.md +56 -0
  486. package/pipelines/discovery/01-explore-domains.md +44 -0
  487. package/pipelines/discovery/02-think-hats.md +50 -0
  488. package/pipelines/discovery/03-analyze-needs.md +54 -0
  489. package/pipelines/discovery/CHAIN.md +37 -0
  490. package/pipelines/thesis/01-structure-argument.md +45 -0
  491. package/pipelines/thesis/02-challenge-assumptions.md +48 -0
  492. package/pipelines/thesis/03-build-thesis.md +54 -0
  493. package/pipelines/thesis/CHAIN.md +37 -0
  494. package/references/brain/causal-directives.md +91 -0
  495. package/references/brain/causal-enrichment.cypher +165 -0
  496. package/references/brain/command-triggers-schema.md +226 -0
  497. package/references/brain/graph-architecture.md +317 -0
  498. package/references/brain/query-patterns.md +460 -0
  499. package/references/brain/room-hierarchy-schema.md +218 -0
  500. package/references/brain/schema.md +76 -0
  501. package/references/capability-radar/capabilities-index.md +241 -0
  502. package/references/capability-radar/changelog-cache.md +81 -0
  503. package/references/causal/causal-schema.md +103 -0
  504. package/references/design/email-template-standard.md +155 -0
  505. package/references/design/graph-visualization-standard.md +178 -0
  506. package/references/document-generation.md +179 -0
  507. package/references/hsi/HSI-TOOLS-REFERENCE.md +222 -0
  508. package/references/import-config.md +141 -0
  509. package/references/integrations/detection-patterns.md +101 -0
  510. package/references/meeting/artifact-template.md +377 -0
  511. package/references/meeting/cross-meeting-intelligence.md +216 -0
  512. package/references/meeting/cross-relationship-patterns.md +202 -0
  513. package/references/meeting/live-join-interface.md +244 -0
  514. package/references/meeting/section-mapping.md +192 -0
  515. package/references/meeting/segment-classification.md +258 -0
  516. package/references/meeting/speaker-profile-template.md +219 -0
  517. package/references/meeting/summary-template.md +348 -0
  518. package/references/meeting/transcript-patterns.md +226 -0
  519. package/references/methodology/analyze-needs.md +135 -0
  520. package/references/methodology/analyze-systems.md +121 -0
  521. package/references/methodology/analyze-timing.md +149 -0
  522. package/references/methodology/beautiful-question.md +109 -0
  523. package/references/methodology/build-knowledge.md +161 -0
  524. package/references/methodology/build-thesis.md +237 -0
  525. package/references/methodology/challenge-assumptions.md +127 -0
  526. package/references/methodology/diagnose.md +169 -0
  527. package/references/methodology/dominant-designs.md +212 -0
  528. package/references/methodology/explore-domains.md +147 -0
  529. package/references/methodology/explore-futures.md +163 -0
  530. package/references/methodology/explore-trends.md +129 -0
  531. package/references/methodology/find-bottlenecks.md +131 -0
  532. package/references/methodology/grade.md +211 -0
  533. package/references/methodology/index.md +97 -0
  534. package/references/methodology/leadership.md +200 -0
  535. package/references/methodology/lean-canvas.md +116 -0
  536. package/references/methodology/macro-trends.md +192 -0
  537. package/references/methodology/map-unknowns.md +137 -0
  538. package/references/methodology/mullins-7-domains.md +104 -0
  539. package/references/methodology/problem-types.md +65 -0
  540. package/references/methodology/root-cause.md +178 -0
  541. package/references/methodology/sapphire-encoding.md +355 -0
  542. package/references/methodology/scenario-plan.md +178 -0
  543. package/references/methodology/score-innovation.md +154 -0
  544. package/references/methodology/structure-argument.md +158 -0
  545. package/references/methodology/systems-thinking.md +159 -0
  546. package/references/methodology/think-hats.md +147 -0
  547. package/references/methodology/triz-matrix.json +751 -0
  548. package/references/methodology/triz-principles.md +501 -0
  549. package/references/methodology/user-needs.md +199 -0
  550. package/references/methodology/validate.md +163 -0
  551. package/references/methodology/value-proposition.md +244 -0
  552. package/references/opportunities/funding-lifecycle.md +103 -0
  553. package/references/opportunities/grant-api-patterns.md +99 -0
  554. package/references/opportunities/opportunity-template.md +84 -0
  555. package/references/personality/assessment-philosophy.md +72 -0
  556. package/references/personality/lexicon.md +100 -0
  557. package/references/personality/persona-chains.md +56 -0
  558. package/references/personality/pws-lexicon-full.md +499 -0
  559. package/references/personality/voice-dna.md +156 -0
  560. package/references/personas/hat-perspectives.md +76 -0
  561. package/references/personas/persona-template.md +63 -0
  562. package/references/pipeline/act-output-contract.md +88 -0
  563. package/references/pipeline/chains-index.md +39 -0
  564. package/references/pws-profile-generation.md +79 -0
  565. package/references/reasoning/reasoning-schema.md +143 -0
  566. package/references/reasoning/reasoning-template.md +68 -0
  567. package/references/reasoning/run-template.md +38 -0
  568. package/references/research/RESEARCH_14_CLAUDE_CODE_SOURCE_ARCHITECTURE.md +209 -0
  569. package/references/research/RESEARCH_15_V1.8_OPTIMIZATION_JTBD.md +375 -0
  570. package/references/research/RESEARCH_16_NATIVE_FIRST_PLUGIN_ARCHITECTURE.md +575 -0
  571. package/references/research/RESEARCH_17_MCP_UI_FRAMEWORKS.md +272 -0
  572. package/references/taxonomy/TAXONOMY.md +192 -0
  573. package/references/templates/MINTO.md +36 -0
  574. package/references/user-research/2026-04-05-leah-lawrence-session.md +202 -0
  575. package/references/vault-kit/README.md +35 -0
  576. package/references/vault-kit/app.json +12 -0
  577. package/references/vault-kit/appearance.json +12 -0
  578. package/references/vault-kit/graph.json +35 -0
  579. package/references/vault-kit/snippets/mindrian-destijl.css +297 -0
  580. package/references/vault-kit/templates/new-artifact.md +37 -0
  581. package/references/vault-kit/templates/new-meeting-note.md +35 -0
  582. package/references/vault-kit/templates/new-team-profile.md +29 -0
  583. package/references/vault-kit/templates/new-xref.md +35 -0
  584. package/references/visual/symbol-system.md +151 -0
  585. package/skills/MOSDeckEngine/SKILL.md +325 -0
  586. package/skills/brain-connector/SKILL.md +114 -0
  587. package/skills/context-engine/SKILL.md +147 -0
  588. package/skills/conversation-mode/SKILL.md +102 -0
  589. package/skills/larry-personality/SKILL.md +219 -0
  590. package/skills/larry-personality/framework-chains.md +92 -0
  591. package/skills/larry-personality/mode-engine.md +185 -0
  592. package/skills/mullins-scaffold/SKILL.md +61 -0
  593. package/skills/mullins-scaffold/scaffold.json +146 -0
  594. package/skills/pws-methodology/SKILL.md +49 -0
  595. package/skills/room-passive/SKILL.md +165 -0
  596. package/skills/room-proactive/SKILL.md +250 -0
  597. package/skills/ui-system/SKILL.md +277 -0
@@ -0,0 +1,719 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * MindrianOS Hub Quick-View Server
6
+ *
7
+ * Serves the SnapshotHub export-template.html LIVE on localhost,
8
+ * injecting fresh ROOM_DATA on every request. Same Mondrian grid,
9
+ * same document view, same graph -- but always current.
10
+ *
11
+ * This is NOT a new dashboard. It's the existing SnapshotHub
12
+ * rendered live instead of as a static export.
13
+ *
14
+ * Usage: node lib/quickview/hub-server.cjs [ROOM_DIR] [PORT]
15
+ */
16
+
17
+ const fs = require('fs');
18
+ const path = require('path');
19
+ const { execSync } = require('child_process');
20
+ const http = require('http');
21
+
22
+ // ── Paths ──
23
+
24
+ const PLUGIN_ROOT = path.resolve(__dirname, '..', '..');
25
+ const TEMPLATE_PATH = path.join(PLUGIN_ROOT, 'dashboard', 'export-template.html');
26
+ const GENERATE_SCRIPT = path.join(PLUGIN_ROOT, 'scripts', 'generate-export.cjs');
27
+
28
+ // ── Section Config (mirrors generate-export.cjs) ──
29
+
30
+ const SECTION_COLORS = {
31
+ 'problem-definition': '#A63D2F',
32
+ 'market-analysis': '#C8A43C',
33
+ 'solution-design': '#5C5A56',
34
+ 'business-model': '#2D6B4A',
35
+ 'competitive-analysis': '#B5602A',
36
+ 'team-execution': '#1E3A6E',
37
+ 'legal-ip': '#6B4E8B',
38
+ 'financial-model': '#2A6B5E',
39
+ 'opportunity-bank': '#C87137',
40
+ 'funding': '#3A7B5E',
41
+ 'personas': '#7B4A8B'
42
+ };
43
+
44
+ const LIGHT_TEXT_SECTIONS = new Set([
45
+ 'problem-definition', 'solution-design', 'business-model',
46
+ 'team-execution', 'legal-ip', 'financial-model', 'personas'
47
+ ]);
48
+
49
+ const SECTION_LABELS = {
50
+ 'problem-definition': 'Problem Definition',
51
+ 'market-analysis': 'Market Analysis',
52
+ 'solution-design': 'Solution Design',
53
+ 'business-model': 'Business Model',
54
+ 'competitive-analysis': 'Competitive Analysis',
55
+ 'team-execution': 'Team & Execution',
56
+ 'legal-ip': 'Legal & IP',
57
+ 'financial-model': 'Financial Model',
58
+ 'opportunity-bank': 'Opportunities',
59
+ 'funding': 'Funding',
60
+ 'personas': 'Thinking Hats'
61
+ };
62
+
63
+ const SKIP_DIRS = new Set(['.lazygraph', '.mindrian', 'meetings', 'team', 'exports', '.context', '.planning', 'personas']);
64
+ const SKIP_FILES = new Set(['ROOM.md', 'STATE.md', 'MINTO.md', 'USER.md',
65
+ 'ROOM-INTELLIGENCE.md', 'MEETINGS-INTELLIGENCE.md']);
66
+
67
+ // ── Room Data Collection ──
68
+
69
+ function collectRoomData(roomDir) {
70
+ const data = {
71
+ roomName: 'Data Room',
72
+ stage: 'Pre-opportunity',
73
+ generatedDate: new Date().toISOString().split('T')[0],
74
+ updates: [],
75
+ sections: [],
76
+ intelligence: { gaps: [], convergence: [], contradictions: [] },
77
+ graph: { elements: { nodes: [], edges: [] } },
78
+ stats: { artifacts: 0, meetings: 0, speakers: 0, sections: 0, empty: 0 },
79
+ };
80
+
81
+ // Read STATE.md -- mirrors generate-export.cjs name resolution
82
+ const statePath = path.join(roomDir, 'STATE.md');
83
+ if (fs.existsSync(statePath)) {
84
+ const content = fs.readFileSync(statePath, 'utf-8');
85
+ const fm = {};
86
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
87
+ if (fmMatch) {
88
+ for (const line of fmMatch[1].split('\n')) {
89
+ const idx = line.indexOf(':');
90
+ if (idx > 0) fm[line.slice(0, idx).trim()] = line.slice(idx + 1).trim().replace(/^["']|["']$/g, '');
91
+ }
92
+ }
93
+ // Name: try venture_name, room_name, name, then parent dir, then H1
94
+ if (fm.venture_name) data.roomName = fm.venture_name;
95
+ else if (fm.room_name) data.roomName = fm.room_name;
96
+ else if (fm.name) data.roomName = fm.name;
97
+ else {
98
+ // Fallback: parent directory name (cleaned up)
99
+ const dirName = path.basename(path.dirname(roomDir));
100
+ if (dirName && dirName !== '.' && dirName !== '/') {
101
+ data.roomName = dirName.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
102
+ }
103
+ // Fallback: H1 heading
104
+ const h1 = content.match(/^# (.+)$/m);
105
+ if (h1 && data.roomName === 'Data Room') data.roomName = h1[1].trim();
106
+ }
107
+ // Stage
108
+ if (fm.venture_stage) data.stage = fm.venture_stage;
109
+ else if (fm.stage) data.stage = fm.stage;
110
+ // Room ID (for multi-room tracking)
111
+ data.roomId = fm.room_id || fm.id || path.basename(roomDir);
112
+ }
113
+
114
+ // Scan sections
115
+ let totalArtifacts = 0;
116
+ const entries = fs.readdirSync(roomDir, { withFileTypes: true });
117
+
118
+ for (const entry of entries) {
119
+ if (!entry.isDirectory() || SKIP_DIRS.has(entry.name)) continue;
120
+
121
+ const sectionDir = path.join(roomDir, entry.name);
122
+ const sectionId = entry.name;
123
+ const label = SECTION_LABELS[sectionId] || sectionId.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
124
+ const color = SECTION_COLORS[sectionId] || '#5C5A56';
125
+ const lightText = LIGHT_TEXT_SECTIONS.has(sectionId);
126
+
127
+ // Collect artifacts
128
+ const artifacts = [];
129
+ try {
130
+ const files = fs.readdirSync(sectionDir)
131
+ .filter(f => f.endsWith('.md') && !SKIP_FILES.has(f))
132
+ .sort();
133
+
134
+ for (const file of files) {
135
+ const filePath = path.join(sectionDir, file);
136
+ const content = fs.readFileSync(filePath, 'utf-8');
137
+
138
+ // Parse frontmatter
139
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
140
+ const fm = {};
141
+ if (fmMatch) {
142
+ for (const line of fmMatch[1].split('\n')) {
143
+ const idx = line.indexOf(':');
144
+ if (idx > 0) fm[line.slice(0, idx).trim()] = line.slice(idx + 1).trim().replace(/^["']|["']$/g, '');
145
+ }
146
+ }
147
+
148
+ // Extract title
149
+ const titleMatch = content.match(/^# (.+)$/m);
150
+ const title = titleMatch ? titleMatch[1].trim() : file.replace('.md', '');
151
+
152
+ // Extract first paragraph as summary (strip markdown syntax)
153
+ const bodyStart = fmMatch ? content.indexOf('---', 4) + 3 : 0;
154
+ const body = content.slice(bodyStart).trim();
155
+ const firstPara = body.split('\n\n').find(p => {
156
+ const t = p.trim();
157
+ // Skip headings, tables, frontmatter-like lines, metadata lines, empty
158
+ return t && !t.startsWith('#') && !t.startsWith('|') && !t.startsWith('---')
159
+ && !t.match(/^\*?\*?(?:Filed|Source|Category|Reference|Cross-reference|Depends on|Full (?:paper|reference)):?\*?\*?:/i);
160
+ });
161
+ // Clean markdown syntax from summary
162
+ const rawSummary = firstPara ? firstPara.trim() : '';
163
+ const summary = rawSummary
164
+ .replace(/\*\*([^*]+)\*\*/g, '$1') // strip bold
165
+ .replace(/\*([^*]+)\*/g, '$1') // strip italic
166
+ .replace(/`([^`]+)`/g, '$1') // strip code
167
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // strip links, keep text
168
+ .replace(/^>\s*/gm, '') // strip blockquote markers
169
+ .replace(/^[-*]\s+/gm, '') // strip list markers
170
+ .replace(/\s+/g, ' ') // collapse whitespace
171
+ .trim()
172
+ .slice(0, 180);
173
+
174
+ // Extract links: internal cross-references and external citations
175
+ const internalLinks = []; // [[section/file]] or references to other room sections
176
+ const externalLinks = []; // [text](https://...) URLs
177
+ const citations = []; // "Source:", "Reference:", "Cross-reference:" lines
178
+
179
+ // Markdown links: [text](url)
180
+ const mdLinkRegex = /\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g;
181
+ let linkMatch;
182
+ while ((linkMatch = mdLinkRegex.exec(body)) !== null) {
183
+ externalLinks.push({ text: linkMatch[1], url: linkMatch[2] });
184
+ }
185
+
186
+ // Bare URLs
187
+ const bareUrlRegex = /(?<!\()(https?:\/\/[^\s)>\]]+)/g;
188
+ while ((linkMatch = bareUrlRegex.exec(body)) !== null) {
189
+ if (!externalLinks.some(l => l.url === linkMatch[1])) {
190
+ externalLinks.push({ text: linkMatch[1].replace(/^https?:\/\//, '').slice(0, 60), url: linkMatch[1] });
191
+ }
192
+ }
193
+
194
+ // Internal cross-references: mentions of other section names or RESEARCH_NN files
195
+ for (const otherSection of Object.keys(SECTION_LABELS)) {
196
+ if (otherSection !== sectionId && body.toLowerCase().includes(otherSection)) {
197
+ internalLinks.push({ section: otherSection, label: SECTION_LABELS[otherSection] || otherSection });
198
+ }
199
+ }
200
+ // Cross-ref patterns: "RESEARCH_14", "room/solution-design/", etc.
201
+ const crossRefRegex = /RESEARCH_(\d+)[_\w]*/g;
202
+ while ((linkMatch = crossRefRegex.exec(body)) !== null) {
203
+ internalLinks.push({ section: 'research', label: linkMatch[0] });
204
+ }
205
+
206
+ // Citation lines: "Source:", "Reference:", "Cross-reference:", "Filed:", "Depends on:"
207
+ const citationRegex = /^(?:\*?\*?(?:Source|Reference|Cross-reference|Filed|Depends on|Full (?:paper|reference|analysis)):?\*?\*?:?\s*)(.+)$/gm;
208
+ while ((linkMatch = citationRegex.exec(body)) !== null) {
209
+ citations.push(linkMatch[1].trim());
210
+ }
211
+
212
+ artifacts.push({
213
+ id: file.replace('.md', ''),
214
+ title,
215
+ summary,
216
+ content: body,
217
+ frontmatter: fm,
218
+ date: fm.created || fm.date || null,
219
+ methodology: fm.methodology || null,
220
+ links: {
221
+ internal: internalLinks,
222
+ external: externalLinks.slice(0, 20), // cap at 20 to control payload size
223
+ citations: citations.slice(0, 10),
224
+ },
225
+ });
226
+ }
227
+ } catch (e) { /* empty section */ }
228
+
229
+ data.sections.push({
230
+ id: sectionId,
231
+ label,
232
+ color,
233
+ lightText,
234
+ entryCount: artifacts.length,
235
+ summary: artifacts.length > 0 ? artifacts[0].summary : '',
236
+ artifacts,
237
+ });
238
+
239
+ totalArtifacts += artifacts.length;
240
+ data.stats.sections++;
241
+ if (artifacts.length === 0) data.stats.empty++;
242
+ }
243
+
244
+ data.stats.artifacts = totalArtifacts;
245
+
246
+ // Add expected-but-missing sections as empty gaps
247
+ const existingIds = new Set(data.sections.map(s => s.id));
248
+ for (const [sectionId, label] of Object.entries(SECTION_LABELS)) {
249
+ if (!existingIds.has(sectionId)) {
250
+ data.sections.push({
251
+ id: sectionId,
252
+ label,
253
+ color: SECTION_COLORS[sectionId] || '#5C5A56',
254
+ lightText: LIGHT_TEXT_SECTIONS.has(sectionId),
255
+ entryCount: 0,
256
+ summary: '',
257
+ artifacts: [],
258
+ });
259
+ data.stats.sections++;
260
+ data.stats.empty++;
261
+ }
262
+ }
263
+
264
+ // Count meetings
265
+ const meetingsDir = path.join(roomDir, 'meetings');
266
+ if (fs.existsSync(meetingsDir)) {
267
+ data.stats.meetings = fs.readdirSync(meetingsDir, { withFileTypes: true })
268
+ .filter(d => d.isDirectory()).length;
269
+ }
270
+
271
+ // Build intelligence (format must match export-template.html buildIntelligence())
272
+ // Gaps: {section, message, severity}
273
+ for (const s of data.sections) {
274
+ if (s.entryCount === 0) {
275
+ data.intelligence.gaps.push({
276
+ section: s.label,
277
+ message: `${s.label} is empty -- highest-priority structural gap`,
278
+ severity: 'HIGH',
279
+ });
280
+ } else if (s.entryCount === 1) {
281
+ data.intelligence.gaps.push({
282
+ section: s.label,
283
+ message: `${s.label} has only 1 entry -- single-lens risk`,
284
+ severity: 'MEDIUM',
285
+ });
286
+ }
287
+ }
288
+
289
+ // Convergence: look for themes appearing in 3+ sections
290
+ const themeCounts = {};
291
+ for (const s of data.sections) {
292
+ for (const a of s.artifacts) {
293
+ const words = (a.title + ' ' + (a.summary || '')).toLowerCase().split(/\W+/);
294
+ for (const w of words) {
295
+ if (w.length > 5) {
296
+ if (!themeCounts[w]) themeCounts[w] = new Set();
297
+ themeCounts[w].add(s.id);
298
+ }
299
+ }
300
+ }
301
+ }
302
+ for (const [theme, sections] of Object.entries(themeCounts)) {
303
+ if (sections.size >= 3) {
304
+ data.intelligence.convergence.push(theme);
305
+ }
306
+ }
307
+ // Keep top 8 convergence themes
308
+ data.intelligence.convergence = data.intelligence.convergence.slice(0, 8);
309
+
310
+ // Build graph nodes from sections + artifacts
311
+ const nodes = [];
312
+ const edges = [];
313
+
314
+ for (const s of data.sections) {
315
+ // Section node
316
+ nodes.push({
317
+ data: {
318
+ id: s.id,
319
+ label: s.label,
320
+ color: s.color,
321
+ section: s.id,
322
+ layer: 'section',
323
+ entryCount: s.entryCount,
324
+ },
325
+ classes: 'section-group'
326
+ });
327
+
328
+ // Artifact nodes
329
+ for (const a of s.artifacts) {
330
+ const nodeId = `${s.id}--${a.id}`;
331
+ nodes.push({
332
+ data: {
333
+ id: nodeId,
334
+ label: a.title,
335
+ color: s.color,
336
+ section: s.id,
337
+ layer: 'content',
338
+ methodology: a.methodology,
339
+ },
340
+ classes: 'artifact'
341
+ });
342
+
343
+ // Edge from section to artifact
344
+ edges.push({
345
+ data: {
346
+ id: `e-${s.id}-${nodeId}`,
347
+ source: s.id,
348
+ target: nodeId,
349
+ edgeType: 'CONTAINS',
350
+ }
351
+ });
352
+ }
353
+ }
354
+
355
+ // Cross-section edges (simple keyword matching)
356
+ for (let i = 0; i < data.sections.length; i++) {
357
+ for (let j = i + 1; j < data.sections.length; j++) {
358
+ const a = data.sections[i];
359
+ const b = data.sections[j];
360
+ if (a.entryCount > 0 && b.entryCount > 0) {
361
+ // Check if any artifact in A references section B's label
362
+ const aText = a.artifacts.map(x => x.content).join(' ').toLowerCase();
363
+ const bLabel = b.label.toLowerCase();
364
+ if (aText.includes(bLabel) || aText.includes(b.id)) {
365
+ edges.push({
366
+ data: {
367
+ id: `e-cross-${a.id}-${b.id}`,
368
+ source: a.id,
369
+ target: b.id,
370
+ edgeType: 'INFORMS',
371
+ }
372
+ });
373
+ }
374
+ }
375
+ }
376
+ }
377
+
378
+ data.graph = { elements: { nodes, edges } };
379
+
380
+ return data;
381
+ }
382
+
383
+ // ── Template Injection ──
384
+
385
+ function injectRoomData(template, roomData) {
386
+ // Replace the ROOM_DATA placeholder with live data
387
+ // CRITICAL: escape </script> to prevent XSS breakout from artifact content
388
+ const jsonStr = JSON.stringify(roomData).replace(/<\/script>/gi, '<\\/script>');
389
+
390
+ // The template has: var ROOM_DATA = /*ROOM_DATA_PLACEHOLDER*/{...};
391
+ // Replace everything between /*ROOM_DATA_PLACEHOLDER*/ and the next semicolon
392
+ let html = template.replace(
393
+ /var ROOM_DATA = \/\*ROOM_DATA_PLACEHOLDER\*\/[^;]+;/,
394
+ `var ROOM_DATA = ${jsonStr};`
395
+ );
396
+
397
+ // Inject content script blocks for the document view
398
+ // The template's openDoc() reads from <script id="content-{sectionId}" type="text/markdown">
399
+ const contentScripts = (roomData.sections || []).map(section => {
400
+ if (!section.artifacts || section.artifacts.length === 0) return '';
401
+ // Combine all artifacts in the section into one content block with separators
402
+ const combined = section.artifacts.map(a => {
403
+ const header = `# ${a.title}\n`;
404
+ const meta = a.frontmatter ? Object.entries(a.frontmatter)
405
+ .map(([k, v]) => `**${k}:** ${v}`).join(' \n') + '\n\n' : '';
406
+ return header + meta + (a.content || '');
407
+ }).join('\n\n---\n\n');
408
+ const safe = combined.replace(/<\/script>/gi, '<\\/script>');
409
+ return `<script id="content-${section.id}" type="text/markdown">${safe}</script>`;
410
+ }).filter(Boolean).join('\n');
411
+
412
+ html = html.replace('<!-- CONTENT_SCRIPTS_PLACEHOLDER -->', contentScripts);
413
+
414
+ // Update the title
415
+ html = html.replace(
416
+ /<title>MindrianOS Data Room<\/title>/,
417
+ `<title>${roomData.roomName} -- MindrianOS Live View</title>`
418
+ );
419
+
420
+ // Add internal hyperlink wiring + citation rendering + live-reload before </body>
421
+ const internalLinksScript = `
422
+ <script>
423
+ // Wire internal cross-references as clickable links in document view
424
+ (function() {
425
+ var SECTION_IDS = ${JSON.stringify(Object.keys(SECTION_LABELS))};
426
+ var origOpenDoc = window.openDoc;
427
+
428
+ // After marked.parse renders the doc body, post-process for internal links
429
+ var observer = new MutationObserver(function(mutations) {
430
+ mutations.forEach(function(m) {
431
+ if (m.target.id !== 'doc-body') return;
432
+ var body = m.target;
433
+
434
+ // 1. Make section references clickable
435
+ SECTION_IDS.forEach(function(sid) {
436
+ var label = sid.replace(/-/g, ' ');
437
+ // Find text nodes containing section names (case-insensitive)
438
+ var walker = document.createTreeWalker(body, NodeFilter.SHOW_TEXT, null, false);
439
+ var textNode;
440
+ while ((textNode = walker.nextNode())) {
441
+ var re = new RegExp('(' + sid + '|' + label + ')', 'gi');
442
+ if (re.test(textNode.nodeValue) && textNode.parentNode.tagName !== 'A') {
443
+ var span = document.createElement('span');
444
+ span.innerHTML = textNode.nodeValue.replace(re,
445
+ '<a href="#" class="internal-ref" data-section="' + sid + '" style="color:var(--mondrian-blue);text-decoration:underline;cursor:pointer;">$1</a>'
446
+ );
447
+ textNode.parentNode.replaceChild(span, textNode);
448
+ }
449
+ }
450
+ });
451
+
452
+ // 2. Make RESEARCH_XX references clickable (link to solution-design section)
453
+ body.querySelectorAll('*').forEach(function(el) {
454
+ if (el.children.length === 0 && el.tagName !== 'A' && el.textContent.match(/RESEARCH_\\d+/)) {
455
+ el.innerHTML = el.innerHTML.replace(/(RESEARCH_\\d+[\\w_]*)/g,
456
+ '<a href="#" class="internal-ref" data-section="solution-design" style="color:var(--mondrian-blue);text-decoration:underline;cursor:pointer;">$1</a>'
457
+ );
458
+ }
459
+ });
460
+
461
+ // 3. Style citation lines
462
+ body.querySelectorAll('p, li').forEach(function(el) {
463
+ if (/^\\*?\\*?(?:Source|Reference|Cross-reference|Filed|Depends on|Full (?:paper|reference|analysis)):/.test(el.textContent)) {
464
+ el.style.borderLeft = '3px solid var(--mondrian-yellow, #E8B931)';
465
+ el.style.paddingLeft = '12px';
466
+ el.style.fontSize = '13px';
467
+ el.style.color = 'rgba(26,26,26,0.6)';
468
+ el.style.fontFamily = '"JetBrains Mono", monospace';
469
+ }
470
+ });
471
+
472
+ // 4. Ensure all external links open in new tab
473
+ body.querySelectorAll('a[href^="http"]').forEach(function(a) {
474
+ a.setAttribute('target', '_blank');
475
+ a.setAttribute('rel', 'noopener');
476
+ });
477
+ });
478
+ });
479
+
480
+ observer.observe(document.getElementById('doc-body') || document.body, { childList: true, subtree: true });
481
+
482
+ // Handle clicks on internal references
483
+ document.addEventListener('click', function(e) {
484
+ var ref = e.target.closest('.internal-ref');
485
+ if (ref) {
486
+ e.preventDefault();
487
+ var section = ref.getAttribute('data-section');
488
+ if (section && typeof openDoc === 'function') openDoc(section);
489
+ }
490
+ });
491
+ })();
492
+ </script>`;
493
+
494
+ html = html.replace('</body>', internalLinksScript + '\n</body>');
495
+
496
+ // Add live-reload script before </body>
497
+ const liveReloadScript = `
498
+ <script>
499
+ // Live reload: check for changes every 8 seconds
500
+ (function() {
501
+ var lastHash = '';
502
+ setInterval(async function() {
503
+ try {
504
+ var res = await fetch('/api/hash');
505
+ var data = await res.json();
506
+ if (lastHash && data.hash !== lastHash) {
507
+ window.location.reload();
508
+ }
509
+ lastHash = data.hash;
510
+ } catch(e) {}
511
+ }, 8000);
512
+ })();
513
+ </script>`;
514
+
515
+ html = html.replace('</body>', liveReloadScript + '\n</body>');
516
+
517
+ return html;
518
+ }
519
+
520
+ // ── Content Hash (for live reload detection) ──
521
+
522
+ function computeHash(roomDir) {
523
+ // Simple hash based on file modification times
524
+ let hash = '';
525
+ try {
526
+ const walk = (dir) => {
527
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
528
+ for (const e of entries) {
529
+ if (e.name.startsWith('.')) continue;
530
+ const full = path.join(dir, e.name);
531
+ if (e.isDirectory() && !SKIP_DIRS.has(e.name)) {
532
+ walk(full);
533
+ } else if (e.isFile() && e.name.endsWith('.md')) {
534
+ const stat = fs.statSync(full);
535
+ hash += stat.mtimeMs.toString(36);
536
+ }
537
+ }
538
+ };
539
+ walk(roomDir);
540
+ } catch (e) {
541
+ process.stderr.write(`Warning: hash computation failed: ${e.message}\n`);
542
+ }
543
+ // Simple string hash
544
+ let h = 0;
545
+ for (let i = 0; i < hash.length; i++) {
546
+ h = ((h << 5) - h + hash.charCodeAt(i)) | 0;
547
+ }
548
+ return h.toString(36);
549
+ }
550
+
551
+ // ── HTTP Server ──
552
+
553
+ function startServer(roomDir, port) {
554
+ // Read template once (it doesn't change)
555
+ if (!fs.existsSync(TEMPLATE_PATH)) {
556
+ process.stderr.write(`Template not found: ${TEMPLATE_PATH}\n`);
557
+ process.exit(1);
558
+ }
559
+ const template = fs.readFileSync(TEMPLATE_PATH, 'utf-8');
560
+
561
+ const server = http.createServer((req, res) => {
562
+ // API: room data as JSON
563
+ if (req.url === '/api/state') {
564
+ res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
565
+ res.end(JSON.stringify(collectRoomData(roomDir)));
566
+ return;
567
+ }
568
+
569
+ // API: content hash for live reload
570
+ if (req.url === '/api/hash') {
571
+ res.writeHead(200, { 'Content-Type': 'application/json' });
572
+ res.end(JSON.stringify({ hash: computeHash(roomDir) }));
573
+ return;
574
+ }
575
+
576
+ // API: available actions per section
577
+ if (req.url === '/api/actions') {
578
+ res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
579
+ res.end(JSON.stringify({
580
+ section: [
581
+ { id: 'analyze', label: 'Analyze', icon: '>', cmd: '/mos:reason', desc: 'Run Minto/MECE structured reasoning' },
582
+ { id: 'grade', label: 'Grade', icon: '*', cmd: '/mos:grade', desc: 'Score problem discovery quality' },
583
+ { id: 'diagnose', label: 'Diagnose', icon: '?', cmd: '/mos:diagnose', desc: 'Classify problem type and match methodology' },
584
+ { id: 'hats', label: '6 Hats', icon: '#', cmd: '/mos:think-hats', desc: 'Force perspective shifts' },
585
+ ],
586
+ room: [
587
+ { id: 'status', label: 'Status', icon: '>', cmd: '/mos:status', desc: 'Room state and next steps' },
588
+ { id: 'suggest', label: 'Suggest Next', icon: '>', cmd: '/mos:suggest-next', desc: 'What should you work on next' },
589
+ { id: 'grade-room', label: 'Deep Grade', icon: '*', cmd: '/mos:deep-grade', desc: 'Full venture assessment' },
590
+ { id: 'export', label: 'Export', icon: '>', cmd: '/mos:export', desc: 'Generate professional export' },
591
+ ]
592
+ }));
593
+ return;
594
+ }
595
+
596
+ // API: execute a CLI command (POST)
597
+ if (req.url === '/api/command' && req.method === 'POST') {
598
+ let body = '';
599
+ req.on('data', chunk => { body += chunk; });
600
+ req.on('end', () => {
601
+ try {
602
+ const { command, section } = JSON.parse(body);
603
+ // Sanitize: only allow /mos: commands
604
+ if (!command || !command.startsWith('/mos:')) {
605
+ res.writeHead(400, { 'Content-Type': 'application/json' });
606
+ res.end(JSON.stringify({ error: 'Only /mos: commands are allowed' }));
607
+ return;
608
+ }
609
+
610
+ // Build the CLI invocation
611
+ const sectionArg = section || '';
612
+
613
+ // Respond immediately with JSON (not SSE)
614
+ // Generate a clipboard-ready command the user can paste into their CLI
615
+ res.writeHead(200, {
616
+ 'Content-Type': 'application/json',
617
+ 'Access-Control-Allow-Origin': '*',
618
+ });
619
+
620
+ // For sections with content, include a quick summary
621
+ const roomData = collectRoomData(roomDir);
622
+ const targetSection = roomData.sections.find(s => s.id === sectionArg);
623
+ const sectionInfo = targetSection
624
+ ? `${targetSection.label}: ${targetSection.entryCount} artifact(s). ${targetSection.summary || 'No summary.'}`
625
+ : 'Room-level command.';
626
+
627
+ // Generate the CLI command to copy
628
+ const cliCommand = sectionArg
629
+ ? `${command} on the ${sectionArg} section`
630
+ : command;
631
+
632
+ // Quick analysis based on room data
633
+ let quickAnalysis = '';
634
+ if (targetSection && targetSection.artifacts.length > 0) {
635
+ quickAnalysis = `\n\nSection: ${targetSection.label}\n`;
636
+ quickAnalysis += `Artifacts: ${targetSection.entryCount}\n`;
637
+ quickAnalysis += `---\n`;
638
+ targetSection.artifacts.forEach(a => {
639
+ quickAnalysis += `\n## ${a.title}\n`;
640
+ if (a.summary) quickAnalysis += `${a.summary}\n`;
641
+ if (a.frontmatter && a.frontmatter.methodology) quickAnalysis += `Methodology: ${a.frontmatter.methodology}\n`;
642
+ });
643
+ } else if (!targetSection || targetSection.entryCount === 0) {
644
+ quickAnalysis = `\n\nThis section is empty -- a structural gap.\nRun the command in your CLI to start filling it.`;
645
+ }
646
+
647
+ res.end(JSON.stringify({
648
+ command: cliCommand,
649
+ section: sectionInfo,
650
+ analysis: quickAnalysis,
651
+ clipboardCmd: cliCommand,
652
+ message: 'Paste this command in your Claude Code CLI to run the full analysis.',
653
+ }));
654
+
655
+ } catch (e) {
656
+ res.writeHead(400, { 'Content-Type': 'application/json' });
657
+ res.end(JSON.stringify({ error: e.message }));
658
+ }
659
+ });
660
+ return;
661
+ }
662
+
663
+ // CORS preflight for API
664
+ if (req.method === 'OPTIONS') {
665
+ res.writeHead(200, {
666
+ 'Access-Control-Allow-Origin': '*',
667
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
668
+ 'Access-Control-Allow-Headers': 'Content-Type',
669
+ });
670
+ res.end();
671
+ return;
672
+ }
673
+
674
+ // Serve the SnapshotHub template with live data
675
+ const roomData = collectRoomData(roomDir);
676
+ const html = injectRoomData(template, roomData);
677
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
678
+ res.end(html);
679
+ });
680
+
681
+ // CRITICAL: handle port-in-use before listen
682
+ server.on('error', (err) => {
683
+ if (err.code === 'EADDRINUSE') {
684
+ process.stderr.write(`Port ${port} is already in use. Try: node hub-server.cjs "${roomDir}" ${port + 1}\n`);
685
+ process.exit(1);
686
+ }
687
+ throw err;
688
+ });
689
+
690
+ server.listen(port, () => {
691
+ const url = `http://localhost:${port}`;
692
+ process.stderr.write(`\n MindrianOS Live Hub: ${url}\n`);
693
+ process.stderr.write(` Room: ${roomDir}\n`);
694
+ process.stderr.write(` Auto-refreshes when files change\n\n`);
695
+
696
+ // Auto-open browser (use execFileSync to prevent command injection)
697
+ const { platform } = process;
698
+ const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';
699
+ try { require('child_process').execFileSync(cmd, [url], { stdio: 'ignore' }); } catch (e) { /* no browser */ }
700
+ });
701
+
702
+ return server;
703
+ }
704
+
705
+ // ── CLI Entry ──
706
+
707
+ if (require.main === module) {
708
+ const roomDir = path.resolve(process.argv[2] || path.join(process.cwd(), 'room'));
709
+ const port = parseInt(process.argv[3] || '8450', 10);
710
+
711
+ if (!fs.existsSync(roomDir)) {
712
+ process.stderr.write(`Room not found: ${roomDir}\n`);
713
+ process.exit(1);
714
+ }
715
+
716
+ startServer(roomDir, port);
717
+ }
718
+
719
+ module.exports = { startServer, collectRoomData };