@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,258 @@
1
+ /**
2
+ * MindrianOS Plugin -- Graph Operations
3
+ * Wraps existing Bash scripts via execSync AND lazygraph-ops.cjs for SQLite.
4
+ * build-graph: Bash script wrapper (JSON export for dashboard).
5
+ * index/rebuild/query/stats: SQLite via lazygraph-ops.cjs (per-project graph).
6
+ *
7
+ * All lazygraph functions use open-use-close pattern to avoid DB locking.
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const { execSync } = require('child_process');
13
+ const path = require('path');
14
+ const lazygraph = require('./lazygraph-ops.cjs');
15
+ const { acquireLock, releaseLock } = require('./write-lock.cjs');
16
+
17
+ // Promise-chain write queue: serializes all SQLite writes.
18
+ // Read operations bypass this queue (SQLite WAL allows concurrent reads).
19
+ let writeQueue = Promise.resolve();
20
+
21
+ function enqueueWrite(roomDir, fn) {
22
+ const op = writeQueue.then(async () => {
23
+ acquireLock(roomDir);
24
+ try {
25
+ return await fn();
26
+ } finally {
27
+ releaseLock(roomDir);
28
+ }
29
+ });
30
+ writeQueue = op.catch(() => {}); // prevent unhandled rejection from blocking queue
31
+ return op;
32
+ }
33
+
34
+ const SCRIPTS_DIR = path.resolve(__dirname, '../../scripts');
35
+
36
+ /**
37
+ * Run build-graph script against a room directory.
38
+ * @param {string} roomDir - Path to room directory
39
+ * @param {string} [outputPath] - Output path for graph JSON (defaults to ./dashboard/graph.json)
40
+ * @returns {{ success: boolean, outputPath: string }} Result object
41
+ */
42
+ function buildGraph(roomDir, outputPath) {
43
+ const resolved = path.resolve(roomDir);
44
+ const resolvedOutput = outputPath || './dashboard/graph.json';
45
+ const scriptPath = path.join(SCRIPTS_DIR, 'build-graph');
46
+ try {
47
+ execSync(`bash "${scriptPath}" "${resolved}" "${resolvedOutput}"`, {
48
+ timeout: 30000,
49
+ encoding: 'utf-8',
50
+ stdio: ['pipe', 'pipe', 'pipe'],
51
+ });
52
+ return { success: true, outputPath: resolvedOutput };
53
+ } catch (e) {
54
+ throw new Error(`build-graph failed: ${e.message}`);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Index a single artifact into the per-project SQLite graph.
60
+ * Opens graph, indexes artifact, closes graph (open-use-close pattern).
61
+ * @param {string} roomDir - Path to room directory
62
+ * @param {string} filePath - Path to .md file to index
63
+ * @returns {Promise<{ success: boolean, id: string, section: string, title: string }>}
64
+ */
65
+ async function indexArtifact(roomDir, filePath) {
66
+ return enqueueWrite(roomDir, async () => {
67
+ const { db, conn } = await lazygraph.openGraph(roomDir);
68
+ try {
69
+ const result = await lazygraph.indexArtifact(conn, roomDir, filePath);
70
+ return { success: true, id: result.id, section: result.section, title: result.title };
71
+ } finally {
72
+ await lazygraph.closeGraph(db);
73
+ }
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Rebuild the entire per-project SQLite graph from all room artifacts.
79
+ * Opens graph, clears and re-indexes everything, closes graph.
80
+ * @param {string} roomDir - Path to room directory
81
+ * @returns {Promise<{ success: boolean, artifacts: number, sections: number }>}
82
+ */
83
+ async function rebuildGraph(roomDir) {
84
+ return enqueueWrite(roomDir, async () => {
85
+ const { db, conn } = await lazygraph.openGraph(roomDir);
86
+ try {
87
+ const result = await lazygraph.rebuildGraph(conn, roomDir);
88
+ return { success: true, artifacts: result.artifacts, sections: result.sections };
89
+ } finally {
90
+ await lazygraph.closeGraph(db);
91
+ }
92
+ });
93
+ }
94
+
95
+ /**
96
+ * Execute a SQL query against the per-project SQLite graph.
97
+ * Opens graph, runs query, closes graph.
98
+ * @param {string} roomDir - Path to room directory
99
+ * @param {string} sql - SQL query string
100
+ * @returns {Promise<{ success: boolean, rows: Array<object>, count: number }>}
101
+ */
102
+ async function queryGraph(roomDir, sql) {
103
+ const { db, conn } = await lazygraph.openGraph(roomDir);
104
+ try {
105
+ const rows = await lazygraph.queryGraph(conn, sql);
106
+ return { success: true, rows, count: rows.length };
107
+ } finally {
108
+ await lazygraph.closeGraph(db);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Get graph statistics from the per-project SQLite graph.
114
+ * Opens graph, gets stats, closes graph.
115
+ * @param {string} roomDir - Path to room directory
116
+ * @returns {Promise<{ nodes: object, edges: object, total: { nodes: number, edges: number } }>}
117
+ */
118
+ async function graphStats(roomDir) {
119
+ const { db, conn } = await lazygraph.openGraph(roomDir);
120
+ try {
121
+ return await lazygraph.graphStats(conn);
122
+ } finally {
123
+ await lazygraph.closeGraph(db);
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Build graph.json from SQLite as primary source.
129
+ * Falls back to file-scanning buildGraph if SQLite fails.
130
+ * NOTE: This function calls the build-graph-from-sqlite.cjs script.
131
+ * @param {string} roomDir - Path to room directory
132
+ * @param {string} [outputPath] - Output path for graph JSON
133
+ * @returns {{ success: boolean, outputPath: string, source: string }}
134
+ */
135
+ function buildGraphFromSQLite(roomDir, outputPath) {
136
+ const resolved = path.resolve(roomDir);
137
+ const resolvedOutput = outputPath || path.join(resolved, '.presentation', 'graph.json');
138
+ const scriptPath = path.join(SCRIPTS_DIR, 'build-graph-from-sqlite.cjs');
139
+
140
+ try {
141
+ execSync(`node "${scriptPath}" "${resolved}" "${resolvedOutput}"`, {
142
+ timeout: 10000,
143
+ encoding: 'utf-8',
144
+ stdio: ['pipe', 'pipe', 'pipe'],
145
+ });
146
+
147
+ // Check if file was actually created (script exits 0 even on graceful degradation)
148
+ const fs = require('fs');
149
+ if (fs.existsSync(resolvedOutput)) {
150
+ return { success: true, outputPath: resolvedOutput, source: 'sqlite' };
151
+ }
152
+ } catch (_e) {
153
+ // Fall through to file-scanning fallback
154
+ }
155
+
156
+ // Fallback to existing file-scanning build-graph
157
+ try {
158
+ const result = buildGraph(roomDir, resolvedOutput);
159
+ return { success: true, outputPath: resolvedOutput, source: 'fallback-filescan' };
160
+ } catch (_e2) {
161
+ return { success: false, outputPath: resolvedOutput, source: 'none' };
162
+ }
163
+ }
164
+
165
+ // Keep legacy name as alias for backward compatibility
166
+ const buildGraphFromKuzu = buildGraphFromSQLite;
167
+
168
+ /**
169
+ * Persist a decision edge (INVALIDATES/CONFIRMS/DEFERRED) to SQLite.
170
+ * Uses enqueueWrite for serialized access + open-use-close pattern.
171
+ *
172
+ * @param {string} roomDir - Path to room directory
173
+ * @param {string} sourceArtifactId - Source artifact ID
174
+ * @param {string} targetArtifactId - Target artifact ID
175
+ * @param {'INVALIDATES'|'CONFIRMS'|'DEFERRED'} edgeType - Edge type from recordDecision
176
+ * @param {Object} [properties={}] - Edge properties (reason, timestamp)
177
+ * @returns {Promise<{ success: boolean, edgeType: string }>}
178
+ */
179
+ async function persistDecisionEdge(roomDir, sourceArtifactId, targetArtifactId, edgeType, properties = {}) {
180
+ return enqueueWrite(roomDir, async () => {
181
+ const { db, conn } = await lazygraph.openGraph(roomDir);
182
+ try {
183
+ const edgeProps = JSON.stringify({
184
+ reason: properties.reason || '',
185
+ timestamp: properties.timestamp || new Date().toISOString(),
186
+ });
187
+
188
+ conn.prepare(
189
+ 'INSERT INTO edges (source, target, type, properties) VALUES (?, ?, ?, ?) ON CONFLICT(source, target, type) DO UPDATE SET properties = excluded.properties'
190
+ ).run(sourceArtifactId, targetArtifactId, edgeType, edgeProps);
191
+
192
+ return { success: true, edgeType };
193
+ } finally {
194
+ await lazygraph.closeGraph(db);
195
+ }
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Index an opportunity into the per-project SQLite graph.
201
+ * Creates Opportunity node, ADDRESSES edges to domain artifacts, IN_DOMAIN edge to section.
202
+ * Uses enqueueWrite for serialized SQLite access (open-use-close pattern).
203
+ *
204
+ * @param {string} roomDir - Path to room directory
205
+ * @param {object} opportunity - Opportunity object with problem_hash, domain, etc.
206
+ * @returns {Promise<{success: boolean, problem_hash: string}>}
207
+ */
208
+ async function indexOpportunity(roomDir, opportunity) {
209
+ return enqueueWrite(roomDir, async () => {
210
+ const { db, conn } = await lazygraph.openGraph(roomDir);
211
+ try {
212
+ // Create opportunity node (upsert = idempotent)
213
+ if (typeof lazygraph.createOpportunityNode === 'function') {
214
+ await lazygraph.createOpportunityNode(conn, opportunity);
215
+ } else {
216
+ // Fallback: create as generic node
217
+ const props = JSON.stringify(opportunity);
218
+ conn.prepare(
219
+ 'INSERT INTO nodes (id, type, properties) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET properties = excluded.properties'
220
+ ).run(opportunity.problem_hash, 'Opportunity', props);
221
+ }
222
+
223
+ // ADDRESSES edge: link to artifacts in the opportunity's domain section
224
+ if (opportunity.domain) {
225
+ const rows = conn.prepare(
226
+ "SELECT id FROM nodes WHERE type = 'Artifact' AND json_extract(properties, '$.section') = ? LIMIT 5"
227
+ ).all(opportunity.domain);
228
+
229
+ for (const row of rows) {
230
+ if (typeof lazygraph.createAddressesEdge === 'function') {
231
+ await lazygraph.createAddressesEdge(conn, opportunity.problem_hash, row.id);
232
+ } else {
233
+ conn.prepare(
234
+ 'INSERT INTO edges (source, target, type) VALUES (?, ?, ?) ON CONFLICT DO NOTHING'
235
+ ).run(opportunity.problem_hash, row.id, 'ADDRESSES');
236
+ }
237
+ }
238
+ }
239
+
240
+ // IN_DOMAIN edge: link to section node
241
+ if (opportunity.domain) {
242
+ if (typeof lazygraph.createInDomainEdge === 'function') {
243
+ await lazygraph.createInDomainEdge(conn, opportunity.problem_hash, opportunity.domain);
244
+ } else {
245
+ conn.prepare(
246
+ 'INSERT INTO edges (source, target, type) VALUES (?, ?, ?) ON CONFLICT DO NOTHING'
247
+ ).run(opportunity.problem_hash, opportunity.domain, 'IN_DOMAIN');
248
+ }
249
+ }
250
+
251
+ return { success: true, problem_hash: opportunity.problem_hash };
252
+ } finally {
253
+ await lazygraph.closeGraph(db);
254
+ }
255
+ });
256
+ }
257
+
258
+ module.exports = { buildGraph, buildGraphFromKuzu, buildGraphFromSQLite, indexArtifact, rebuildGraph, queryGraph, graphStats, enqueueWrite, persistDecisionEdge, indexOpportunity };
@@ -0,0 +1,362 @@
1
+ /**
2
+ * MindrianOS Plugin -- De Bono Hat Persistence
3
+ * Manages persistent hat state across sessions for each room.
4
+ *
5
+ * Storage layout:
6
+ * room/.mindrian/hats/{color}/STATE.md - Current hat state (focus, concerns, opportunities)
7
+ * room/.mindrian/hats/{color}/session-log/YYYY-MM-DD.md - Daily session findings
8
+ *
9
+ * Exports: loadHatState, saveHatState, logSession, loadAllHatStates, getRecentLogs
10
+ *
11
+ * Pure Node.js built-ins only (zero npm deps per Phase 10 decision).
12
+ */
13
+
14
+ 'use strict';
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const HAT_COLORS = ['white', 'red', 'black', 'yellow', 'green', 'blue'];
20
+
21
+ const HAT_LABELS = {
22
+ white: 'Facts & Data',
23
+ red: 'Emotions & Intuition',
24
+ black: 'Risks & Dangers',
25
+ yellow: 'Benefits & Opportunities',
26
+ green: 'Creativity & Alternatives',
27
+ blue: 'Process & Meta',
28
+ };
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Directory helpers
32
+ // ---------------------------------------------------------------------------
33
+
34
+ /**
35
+ * Get the hat directory for a given color within a room.
36
+ * @param {string} roomDir - Absolute path to room directory
37
+ * @param {string} color - Hat color (white|red|black|yellow|green|blue)
38
+ * @returns {string}
39
+ */
40
+ function hatDir(roomDir, color) {
41
+ return path.join(path.resolve(roomDir), '.mindrian', 'hats', color);
42
+ }
43
+
44
+ /**
45
+ * Ensure hat directories exist for a given color.
46
+ * @param {string} roomDir
47
+ * @param {string} color
48
+ */
49
+ function ensureHatDirs(roomDir, color) {
50
+ const dir = hatDir(roomDir, color);
51
+ fs.mkdirSync(path.join(dir, 'session-log'), { recursive: true });
52
+ }
53
+
54
+ // ---------------------------------------------------------------------------
55
+ // STATE.md parsing / serialization
56
+ // ---------------------------------------------------------------------------
57
+
58
+ /**
59
+ * Parse a hat STATE.md into structured data.
60
+ * @param {string} content - Raw markdown content
61
+ * @returns {{ current_focus: string, last_analysis: string, top_concerns: string[], top_opportunities: string[], methodology_notes: string[], session_count: number }}
62
+ */
63
+ function parseHatState(content) {
64
+ const state = {
65
+ current_focus: '',
66
+ last_analysis: '',
67
+ top_concerns: [],
68
+ top_opportunities: [],
69
+ methodology_notes: [],
70
+ session_count: 0,
71
+ };
72
+
73
+ if (!content || typeof content !== 'string') return state;
74
+
75
+ // Parse frontmatter
76
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
77
+ if (fmMatch) {
78
+ const lines = fmMatch[1].split('\n');
79
+ for (const line of lines) {
80
+ const kvMatch = line.match(/^([a-z_]+):\s*(.*)$/);
81
+ if (kvMatch) {
82
+ const key = kvMatch[1];
83
+ const val = kvMatch[2].trim();
84
+ if (key === 'current_focus') state.current_focus = val;
85
+ if (key === 'last_analysis') state.last_analysis = val;
86
+ if (key === 'session_count') state.session_count = parseInt(val, 10) || 0;
87
+ }
88
+ const listMatch = line.match(/^\s+-\s+(.+)$/);
89
+ if (listMatch) {
90
+ // Determine which list this belongs to based on preceding key
91
+ // Simple heuristic: check what the last key was
92
+ }
93
+ }
94
+ }
95
+
96
+ // Parse sections from body
97
+ const bodyStart = content.indexOf('---', content.indexOf('---') + 3);
98
+ const body = bodyStart >= 0 ? content.slice(bodyStart + 3) : content;
99
+
100
+ const concernsMatch = body.match(/## Top Concerns\n([\s\S]*?)(?=\n## |$)/);
101
+ if (concernsMatch) {
102
+ state.top_concerns = concernsMatch[1]
103
+ .split('\n')
104
+ .filter(l => l.trim().startsWith('-'))
105
+ .map(l => l.replace(/^\s*-\s*/, '').trim())
106
+ .filter(Boolean);
107
+ }
108
+
109
+ const oppsMatch = body.match(/## Top Opportunities\n([\s\S]*?)(?=\n## |$)/);
110
+ if (oppsMatch) {
111
+ state.top_opportunities = oppsMatch[1]
112
+ .split('\n')
113
+ .filter(l => l.trim().startsWith('-'))
114
+ .map(l => l.replace(/^\s*-\s*/, '').trim())
115
+ .filter(Boolean);
116
+ }
117
+
118
+ const methMatch = body.match(/## Methodology Notes\n([\s\S]*?)(?=\n## |$)/);
119
+ if (methMatch) {
120
+ state.methodology_notes = methMatch[1]
121
+ .split('\n')
122
+ .filter(l => l.trim().startsWith('-'))
123
+ .map(l => l.replace(/^\s*-\s*/, '').trim())
124
+ .filter(Boolean);
125
+ }
126
+
127
+ return state;
128
+ }
129
+
130
+ /**
131
+ * Serialize hat state to STATE.md markdown content.
132
+ * @param {string} color
133
+ * @param {object} state
134
+ * @returns {string}
135
+ */
136
+ function serializeHatState(color, state) {
137
+ const label = HAT_LABELS[color] || color;
138
+ const concerns = (state.top_concerns || []).map(c => `- ${c}`).join('\n') || '- None yet';
139
+ const opps = (state.top_opportunities || []).map(o => `- ${o}`).join('\n') || '- None yet';
140
+ const meth = (state.methodology_notes || []).map(m => `- ${m}`).join('\n') || '- None yet';
141
+
142
+ return `---
143
+ hat: ${color}
144
+ hat_label: ${label}
145
+ current_focus: ${state.current_focus || 'General analysis'}
146
+ last_analysis: ${state.last_analysis || 'never'}
147
+ session_count: ${state.session_count || 0}
148
+ ---
149
+
150
+ # ${color.charAt(0).toUpperCase() + color.slice(1)} Hat -- ${label}
151
+
152
+ ## Top Concerns
153
+ ${concerns}
154
+
155
+ ## Top Opportunities
156
+ ${opps}
157
+
158
+ ## Methodology Notes
159
+ ${meth}
160
+ `;
161
+ }
162
+
163
+ // ---------------------------------------------------------------------------
164
+ // Core API
165
+ // ---------------------------------------------------------------------------
166
+
167
+ /**
168
+ * Load the persistent state for a given hat color.
169
+ * Returns default state if no STATE.md exists yet.
170
+ * @param {string} roomDir - Absolute path to room directory
171
+ * @param {string} color - Hat color
172
+ * @returns {{ current_focus: string, last_analysis: string, top_concerns: string[], top_opportunities: string[], methodology_notes: string[], session_count: number }}
173
+ */
174
+ function loadHatState(roomDir, color) {
175
+ if (!HAT_COLORS.includes(color)) {
176
+ return { error: `Invalid hat color: ${color}. Must be one of: ${HAT_COLORS.join(', ')}` };
177
+ }
178
+
179
+ const statePath = path.join(hatDir(roomDir, color), 'STATE.md');
180
+ try {
181
+ const content = fs.readFileSync(statePath, 'utf-8');
182
+ return parseHatState(content);
183
+ } catch (e) {
184
+ // No state yet -- return defaults
185
+ return {
186
+ current_focus: 'General analysis',
187
+ last_analysis: 'never',
188
+ top_concerns: [],
189
+ top_opportunities: [],
190
+ methodology_notes: [],
191
+ session_count: 0,
192
+ };
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Save hat state to disk. Creates directories if needed.
198
+ * @param {string} roomDir - Absolute path to room directory
199
+ * @param {string} color - Hat color
200
+ * @param {object} state - State to persist
201
+ * @returns {{ saved: boolean, path: string }}
202
+ */
203
+ function saveHatState(roomDir, color, state) {
204
+ if (!HAT_COLORS.includes(color)) {
205
+ return { error: `Invalid hat color: ${color}` };
206
+ }
207
+
208
+ ensureHatDirs(roomDir, color);
209
+ const statePath = path.join(hatDir(roomDir, color), 'STATE.md');
210
+
211
+ // Merge with existing state to preserve fields not in this update
212
+ const existing = loadHatState(roomDir, color);
213
+ const merged = {
214
+ current_focus: state.current_focus || existing.current_focus,
215
+ last_analysis: state.last_analysis || new Date().toISOString().split('T')[0],
216
+ top_concerns: state.top_concerns || existing.top_concerns,
217
+ top_opportunities: state.top_opportunities || existing.top_opportunities,
218
+ methodology_notes: state.methodology_notes || existing.methodology_notes,
219
+ session_count: (state.session_count !== undefined) ? state.session_count : existing.session_count,
220
+ };
221
+
222
+ const content = serializeHatState(color, merged);
223
+ fs.writeFileSync(statePath, content, 'utf-8');
224
+
225
+ return { saved: true, path: statePath };
226
+ }
227
+
228
+ /**
229
+ * Log a session's findings for a hat color. Appends to the daily log file.
230
+ * @param {string} roomDir - Absolute path to room directory
231
+ * @param {string} color - Hat color
232
+ * @param {{ focus: string, findings: string[], concerns: string[], opportunities: string[], artifact?: string }} findings
233
+ * @returns {{ logged: boolean, path: string }}
234
+ */
235
+ function logSession(roomDir, color, findings) {
236
+ if (!HAT_COLORS.includes(color)) {
237
+ return { error: `Invalid hat color: ${color}` };
238
+ }
239
+
240
+ ensureHatDirs(roomDir, color);
241
+
242
+ const today = new Date().toISOString().split('T')[0];
243
+ const time = new Date().toISOString().split('T')[1].replace(/\.\d+Z/, 'Z');
244
+ const logPath = path.join(hatDir(roomDir, color), 'session-log', `${today}.md`);
245
+
246
+ const label = HAT_LABELS[color] || color;
247
+ const entry = [
248
+ '',
249
+ `## Session at ${time}`,
250
+ '',
251
+ `**Focus:** ${findings.focus || 'General analysis'}`,
252
+ findings.artifact ? `**Artifact:** ${findings.artifact}` : '',
253
+ '',
254
+ '### Findings',
255
+ ...(findings.findings || []).map(f => `- ${f}`),
256
+ '',
257
+ '### Concerns',
258
+ ...(findings.concerns || []).map(c => `- ${c}`),
259
+ '',
260
+ '### Opportunities',
261
+ ...(findings.opportunities || []).map(o => `- ${o}`),
262
+ '',
263
+ '---',
264
+ ].filter(l => l !== undefined).join('\n');
265
+
266
+ // If file exists, append. Otherwise create with header.
267
+ let content;
268
+ try {
269
+ content = fs.readFileSync(logPath, 'utf-8');
270
+ content += '\n' + entry;
271
+ } catch (e) {
272
+ content = `# ${color.charAt(0).toUpperCase() + color.slice(1)} Hat -- ${label} Session Log (${today})\n` + entry;
273
+ }
274
+
275
+ fs.writeFileSync(logPath, content, 'utf-8');
276
+
277
+ // Update session count in STATE.md
278
+ const state = loadHatState(roomDir, color);
279
+ state.session_count = (state.session_count || 0) + 1;
280
+ state.last_analysis = today;
281
+
282
+ // Merge new concerns/opportunities into state (keep last 5 each)
283
+ if (findings.concerns && findings.concerns.length > 0) {
284
+ const merged = [...findings.concerns, ...(state.top_concerns || [])];
285
+ state.top_concerns = [...new Set(merged)].slice(0, 5);
286
+ }
287
+ if (findings.opportunities && findings.opportunities.length > 0) {
288
+ const merged = [...findings.opportunities, ...(state.top_opportunities || [])];
289
+ state.top_opportunities = [...new Set(merged)].slice(0, 5);
290
+ }
291
+ if (findings.focus) {
292
+ state.current_focus = findings.focus;
293
+ }
294
+
295
+ saveHatState(roomDir, color, state);
296
+
297
+ return { logged: true, path: logPath };
298
+ }
299
+
300
+ /**
301
+ * Load all 6 hat states for a room. Returns map of color -> state.
302
+ * @param {string} roomDir
303
+ * @returns {Object<string, object>}
304
+ */
305
+ function loadAllHatStates(roomDir) {
306
+ const states = {};
307
+ for (const color of HAT_COLORS) {
308
+ states[color] = loadHatState(roomDir, color);
309
+ }
310
+ return states;
311
+ }
312
+
313
+ /**
314
+ * Get recent session logs for a hat (last N days).
315
+ * @param {string} roomDir
316
+ * @param {string} color
317
+ * @param {number} [days=7] - How many days back to look
318
+ * @returns {Array<{ date: string, content: string }>}
319
+ */
320
+ function getRecentLogs(roomDir, color, days = 7) {
321
+ if (!HAT_COLORS.includes(color)) return [];
322
+
323
+ const logDir = path.join(hatDir(roomDir, color), 'session-log');
324
+ let files;
325
+ try {
326
+ files = fs.readdirSync(logDir).filter(f => f.endsWith('.md')).sort().reverse();
327
+ } catch (e) {
328
+ return [];
329
+ }
330
+
331
+ const cutoff = new Date();
332
+ cutoff.setDate(cutoff.getDate() - days);
333
+ const cutoffStr = cutoff.toISOString().split('T')[0];
334
+
335
+ const logs = [];
336
+ for (const file of files) {
337
+ const date = file.replace('.md', '');
338
+ if (date < cutoffStr) break;
339
+ try {
340
+ const content = fs.readFileSync(path.join(logDir, file), 'utf-8');
341
+ logs.push({ date, content });
342
+ } catch (e) {
343
+ // skip unreadable
344
+ }
345
+ }
346
+
347
+ return logs;
348
+ }
349
+
350
+ // ---------------------------------------------------------------------------
351
+ // Exports
352
+ // ---------------------------------------------------------------------------
353
+
354
+ module.exports = {
355
+ HAT_COLORS,
356
+ HAT_LABELS,
357
+ loadHatState,
358
+ saveHatState,
359
+ logSession,
360
+ loadAllHatStates,
361
+ getRecentLogs,
362
+ };
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MindrianOS Plugin — Shared Core Helpers
3
+ * Pure Node.js built-ins only. No npm dependencies.
4
+ *
5
+ * Replicates the GSD gsd-tools.cjs output pattern:
6
+ * - JSON to stdout for structured data
7
+ * - Large payloads (>50KB) written to tmpfile with @file: prefix
8
+ * - Errors to stderr with exit 1
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const os = require('os');
16
+
17
+ /** Root of the plugin repository */
18
+ const PLUGIN_ROOT = path.resolve(__dirname, '../..');
19
+
20
+ /**
21
+ * Output structured result to stdout.
22
+ * If raw mode, write rawValue directly.
23
+ * Otherwise JSON-stringify; if >50KB, write to tmpfile with @file: prefix.
24
+ */
25
+ function output(result, raw, rawValue) {
26
+ if (raw && rawValue !== undefined) {
27
+ process.stdout.write(String(rawValue));
28
+ } else {
29
+ const json = JSON.stringify(result, null, 2);
30
+ if (json.length > 50000) {
31
+ const tmpPath = path.join(os.tmpdir(), `mindrian-${Date.now()}.json`);
32
+ fs.writeFileSync(tmpPath, json, 'utf-8');
33
+ process.stdout.write('@file:' + tmpPath);
34
+ } else {
35
+ process.stdout.write(json);
36
+ }
37
+ }
38
+ process.exit(0);
39
+ }
40
+
41
+ /**
42
+ * Write error message to stderr and exit 1.
43
+ */
44
+ function error(msg) {
45
+ process.stderr.write('ERROR: ' + msg + '\n');
46
+ process.exit(1);
47
+ }
48
+
49
+ /**
50
+ * Read file contents safely. Returns string or null if not found.
51
+ */
52
+ function safeReadFile(filePath) {
53
+ try {
54
+ return fs.readFileSync(filePath, 'utf-8');
55
+ } catch (e) {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ module.exports = { output, error, safeReadFile, PLUGIN_ROOT };