mednotes-opencode 0.1.0

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 (430) hide show
  1. package/.opencode/agents/med-chat-triager.md +204 -0
  2. package/.opencode/agents/med-flashcard-maker.md +63 -0
  3. package/.opencode/agents/med-knowledge-architect.md +230 -0
  4. package/.opencode/agents/med-link-graph-curator.md +177 -0
  5. package/.opencode/agents/med-publish-guard.md +62 -0
  6. package/.opencode/commands/flashcards.md +25 -0
  7. package/.opencode/commands/mednotes/create.md +25 -0
  8. package/.opencode/commands/mednotes/enrich.md +27 -0
  9. package/.opencode/commands/mednotes/fix-wiki.md +27 -0
  10. package/.opencode/commands/mednotes/history.md +22 -0
  11. package/.opencode/commands/mednotes/link-body.md +25 -0
  12. package/.opencode/commands/mednotes/link-related.md +27 -0
  13. package/.opencode/commands/mednotes/link.md +27 -0
  14. package/.opencode/commands/mednotes/pdf-library.md +27 -0
  15. package/.opencode/commands/mednotes/process-chats.md +23 -0
  16. package/.opencode/commands/mednotes/setup.md +21 -0
  17. package/.opencode/commands/mednotes/status.md +27 -0
  18. package/.opencode/commands/mednotes/telemetry.md +27 -0
  19. package/.opencode/commands/report.md +26 -0
  20. package/.opencode/mednotes/AGENTS.md +57 -0
  21. package/.opencode/mednotes/agents/med-chat-triager.md +197 -0
  22. package/.opencode/mednotes/agents/med-flashcard-maker.md +56 -0
  23. package/.opencode/mednotes/agents/med-knowledge-architect.md +224 -0
  24. package/.opencode/mednotes/agents/med-link-graph-curator.md +171 -0
  25. package/.opencode/mednotes/agents/med-publish-guard.md +55 -0
  26. package/.opencode/mednotes/contracts/.gitkeep +1 -0
  27. package/.opencode/mednotes/contracts/agents.json +116 -0
  28. package/.opencode/mednotes/contracts/opencode-plugin.json +70 -0
  29. package/.opencode/mednotes/docs/agent-prompt-hardening.md +567 -0
  30. package/.opencode/mednotes/docs/agent-role-contracts.md +94 -0
  31. package/.opencode/mednotes/docs/anki-mcp-twenty-rules.md +214 -0
  32. package/.opencode/mednotes/docs/anki-templates/README.md +39 -0
  33. package/.opencode/mednotes/docs/anki-templates/cloze.back.html +23 -0
  34. package/.opencode/mednotes/docs/anki-templates/cloze.front.html +14 -0
  35. package/.opencode/mednotes/docs/anki-templates/qa.back.html +24 -0
  36. package/.opencode/mednotes/docs/anki-templates/qa.front.html +14 -0
  37. package/.opencode/mednotes/docs/anki-templates/style.css +182 -0
  38. package/.opencode/mednotes/docs/atomicity-splitting-policy.md +113 -0
  39. package/.opencode/mednotes/docs/extension-docs.md +40 -0
  40. package/.opencode/mednotes/docs/flashcard-ingestion.md +278 -0
  41. package/.opencode/mednotes/docs/knowledge-architect.md +208 -0
  42. package/.opencode/mednotes/docs/merge-policy.md +110 -0
  43. package/.opencode/mednotes/docs/public-vocabulary.md +104 -0
  44. package/.opencode/mednotes/docs/semantic-linker.md +141 -0
  45. package/.opencode/mednotes/docs/taxonomy-policy.md +90 -0
  46. package/.opencode/mednotes/docs/triage-policy.md +187 -0
  47. package/.opencode/mednotes/docs/vault-version-control.md +758 -0
  48. package/.opencode/mednotes/docs/vocabulary-db-recovery.md +58 -0
  49. package/.opencode/mednotes/docs/workflow-output-contract.md +779 -0
  50. package/.opencode/mednotes/hooks/hooks.json +79 -0
  51. package/.opencode/mednotes/package-lock.json +6361 -0
  52. package/.opencode/mednotes/package.json +15 -0
  53. package/.opencode/mednotes/pyproject.toml +48 -0
  54. package/.opencode/mednotes/scripts/bootstrap_windows_python_uv.cmd +13 -0
  55. package/.opencode/mednotes/scripts/bootstrap_windows_python_uv.ps1 +172 -0
  56. package/.opencode/mednotes/scripts/enrich_notes.py +23 -0
  57. package/.opencode/mednotes/scripts/full_reset_windows_python_uv.cmd +13 -0
  58. package/.opencode/mednotes/scripts/hooks/antigravity_hook_status.mjs +212 -0
  59. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/antigravity.mjs +169 -0
  60. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/harness_payload.mjs +103 -0
  61. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/opencode_plugin.mjs +341 -0
  62. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/opencode_user_config_sync.mjs +177 -0
  63. package/.opencode/mednotes/scripts/hooks/mednotes_hook/anki_preflight.mjs +214 -0
  64. package/.opencode/mednotes/scripts/hooks/mednotes_hook/cli.mjs +143 -0
  65. package/.opencode/mednotes/scripts/hooks/mednotes_hook/diagnostics.mjs +11 -0
  66. package/.opencode/mednotes/scripts/hooks/mednotes_hook/domain/agent_directive_core.mjs +160 -0
  67. package/.opencode/mednotes/scripts/hooks/mednotes_hook/fsm_directive.mjs +1470 -0
  68. package/.opencode/mednotes/scripts/hooks/mednotes_hook/hook_errors.mjs +120 -0
  69. package/.opencode/mednotes/scripts/hooks/mednotes_hook/retention.mjs +114 -0
  70. package/.opencode/mednotes/scripts/hooks/mednotes_hook/runtime.mjs +174 -0
  71. package/.opencode/mednotes/scripts/hooks/mednotes_hook/telemetry_capture.mjs +511 -0
  72. package/.opencode/mednotes/scripts/hooks/mednotes_hook/vault_guard.mjs +624 -0
  73. package/.opencode/mednotes/scripts/hooks/mednotes_hook.mjs +5 -0
  74. package/.opencode/mednotes/scripts/mednotes/_runtime_paths.py +24 -0
  75. package/.opencode/mednotes/scripts/mednotes/anki_model_validator.py +18 -0
  76. package/.opencode/mednotes/scripts/mednotes/capture_extension_diff.py +1562 -0
  77. package/.opencode/mednotes/scripts/mednotes/feedback_report.py +16 -0
  78. package/.opencode/mednotes/scripts/mednotes/flashcard_index.py +18 -0
  79. package/.opencode/mednotes/scripts/mednotes/flashcard_pipeline.py +18 -0
  80. package/.opencode/mednotes/scripts/mednotes/flashcard_report.py +18 -0
  81. package/.opencode/mednotes/scripts/mednotes/flashcard_sources.py +18 -0
  82. package/.opencode/mednotes/scripts/mednotes/obsidian/README.md +6 -0
  83. package/.opencode/mednotes/scripts/mednotes/obsidian_note_utils.py +20 -0
  84. package/.opencode/mednotes/scripts/mednotes/pdf_library/cli.py +16 -0
  85. package/.opencode/mednotes/scripts/mednotes/project_fsm.py +229 -0
  86. package/.opencode/mednotes/scripts/mednotes/setup_telemetry_email.py +404 -0
  87. package/.opencode/mednotes/scripts/mednotes/sync_anki_twenty_rules.py +18 -0
  88. package/.opencode/mednotes/scripts/mednotes/sync_opencode_user_config.py +36 -0
  89. package/.opencode/mednotes/scripts/mednotes/wiki/cli.py +20 -0
  90. package/.opencode/mednotes/scripts/mednotes/wiki_graph.py +18 -0
  91. package/.opencode/mednotes/scripts/mednotes/wiki_tree.py +134 -0
  92. package/.opencode/mednotes/scripts/reset_windows_python_uv.ps1 +625 -0
  93. package/.opencode/mednotes/scripts/run_python.mjs +109 -0
  94. package/.opencode/mednotes/scripts/vault/vault_commit.ps1 +19 -0
  95. package/.opencode/mednotes/scripts/vault/vault_commit.sh +18 -0
  96. package/.opencode/mednotes/scripts/vault/vault_git.ps1 +19 -0
  97. package/.opencode/mednotes/scripts/vault/vault_git.py +3107 -0
  98. package/.opencode/mednotes/scripts/vault/vault_git.sh +18 -0
  99. package/.opencode/mednotes/scripts/vault/vault_precommit.ps1 +19 -0
  100. package/.opencode/mednotes/scripts/vault/vault_precommit.sh +18 -0
  101. package/.opencode/mednotes/skills/THIRD_PARTY_NOTICES.md +45 -0
  102. package/.opencode/mednotes/skills/create-medical-flashcards/SKILL.md +113 -0
  103. package/.opencode/mednotes/skills/create-medical-note/SKILL.md +90 -0
  104. package/.opencode/mednotes/skills/enrich-medical-note/SKILL.md +120 -0
  105. package/.opencode/mednotes/skills/fix-medical-wiki/SKILL.md +559 -0
  106. package/.opencode/mednotes/skills/link-medical-wiki/SKILL.md +224 -0
  107. package/.opencode/mednotes/skills/obsidian-cli/SKILL.md +118 -0
  108. package/.opencode/mednotes/skills/obsidian-markdown/SKILL.md +207 -0
  109. package/.opencode/mednotes/skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  110. package/.opencode/mednotes/skills/obsidian-markdown/references/EMBEDS.md +63 -0
  111. package/.opencode/mednotes/skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  112. package/.opencode/mednotes/skills/obsidian-ops/SKILL.md +136 -0
  113. package/.opencode/mednotes/skills/pdf-library/SKILL.md +45 -0
  114. package/.opencode/mednotes/skills/process-medical-chats/SKILL.md +246 -0
  115. package/.opencode/mednotes/skills/workflow-report/SKILL.md +100 -0
  116. package/.opencode/mednotes/src/mednotes/__init__.py +5 -0
  117. package/.opencode/mednotes/src/mednotes/domains/__init__.py +5 -0
  118. package/.opencode/mednotes/src/mednotes/domains/flashcards/README.md +26 -0
  119. package/.opencode/mednotes/src/mednotes/domains/flashcards/__init__.py +2 -0
  120. package/.opencode/mednotes/src/mednotes/domains/flashcards/build_demo_apkg.py +177 -0
  121. package/.opencode/mednotes/src/mednotes/domains/flashcards/contracts.py +385 -0
  122. package/.opencode/mednotes/src/mednotes/domains/flashcards/flashcards_machine.py +522 -0
  123. package/.opencode/mednotes/src/mednotes/domains/flashcards/fsm.py +817 -0
  124. package/.opencode/mednotes/src/mednotes/domains/flashcards/index.py +630 -0
  125. package/.opencode/mednotes/src/mednotes/domains/flashcards/install_models.py +445 -0
  126. package/.opencode/mednotes/src/mednotes/domains/flashcards/model.py +359 -0
  127. package/.opencode/mednotes/src/mednotes/domains/flashcards/obsidian_links.py +135 -0
  128. package/.opencode/mednotes/src/mednotes/domains/flashcards/obsidian_note_utils.py +546 -0
  129. package/.opencode/mednotes/src/mednotes/domains/flashcards/pipeline.py +580 -0
  130. package/.opencode/mednotes/src/mednotes/domains/flashcards/report.py +510 -0
  131. package/.opencode/mednotes/src/mednotes/domains/flashcards/sources.py +682 -0
  132. package/.opencode/mednotes/src/mednotes/domains/flashcards/sync_rules.py +184 -0
  133. package/.opencode/mednotes/src/mednotes/domains/history/__init__.py +1 -0
  134. package/.opencode/mednotes/src/mednotes/domains/history/history_fsm.py +852 -0
  135. package/.opencode/mednotes/src/mednotes/domains/history/history_machine.py +453 -0
  136. package/.opencode/mednotes/src/mednotes/domains/setup/__init__.py +7 -0
  137. package/.opencode/mednotes/src/mednotes/domains/setup/setup_fsm.py +808 -0
  138. package/.opencode/mednotes/src/mednotes/domains/setup/setup_machine.py +973 -0
  139. package/.opencode/mednotes/src/mednotes/domains/wiki/README.md +64 -0
  140. package/.opencode/mednotes/src/mednotes/domains/wiki/__init__.py +1 -0
  141. package/.opencode/mednotes/src/mednotes/domains/wiki/api.py +668 -0
  142. package/.opencode/mednotes/src/mednotes/domains/wiki/batch_state.py +102 -0
  143. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/__init__.py +1 -0
  144. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/atomicity/__init__.py +1 -0
  145. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/atomicity/atomicity.py +877 -0
  146. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/body_link/__init__.py +1 -0
  147. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/body_link/body_linker.py +1562 -0
  148. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/__init__.py +1 -0
  149. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/effect_adapters.py +949 -0
  150. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/fix_wiki_runtime_adapters.py +433 -0
  151. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/__init__.py +1 -0
  152. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/coverage.py +413 -0
  153. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/graph.py +396 -0
  154. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/graph_fixes.py +161 -0
  155. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/hygiene/__init__.py +1 -0
  156. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/hygiene/hygiene.py +483 -0
  157. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/__init__.py +2 -0
  158. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/anchors.py +185 -0
  159. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/__init__.py +0 -0
  160. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/cache.py +223 -0
  161. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/config.py +131 -0
  162. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/download.py +224 -0
  163. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/frontmatter.py +59 -0
  164. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/insert.py +227 -0
  165. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/local_import.py +54 -0
  166. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/__init__.py +42 -0
  167. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/web_profiles.py +99 -0
  168. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/web_search.py +203 -0
  169. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/wikimedia.py +102 -0
  170. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/__init__.py +1 -0
  171. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_db_adapter.mjs +434 -0
  172. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_node_runtime.py +274 -0
  173. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_query.py +227 -0
  174. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/__init__.py +1 -0
  175. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/artifacts.py +605 -0
  176. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/canonical_merge.py +277 -0
  177. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/markdown_zones.py +85 -0
  178. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/meaning_planner.py +307 -0
  179. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_iter.py +67 -0
  180. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_merge.py +278 -0
  181. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_plan.py +409 -0
  182. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_policy.py +22 -0
  183. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/__init__.py +79 -0
  184. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/fixes.py +264 -0
  185. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/frontmatter.py +435 -0
  186. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/models.py +208 -0
  187. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/prompts.py +37 -0
  188. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/tables.py +236 -0
  189. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/validate.py +404 -0
  190. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/provenance.py +478 -0
  191. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/raw_chats.py +273 -0
  192. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/sources_backfill.py +235 -0
  193. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/__init__.py +10 -0
  194. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/anchors.py +16 -0
  195. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/captions.py +47 -0
  196. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/cli.py +179 -0
  197. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/cloud.py +52 -0
  198. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/config.py +196 -0
  199. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/context_packets.py +76 -0
  200. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/db.py +81 -0
  201. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/doctor.py +102 -0
  202. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/figure_ids.py +42 -0
  203. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/ingest.py +326 -0
  204. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/insert.py +316 -0
  205. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/mentions.py +57 -0
  206. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/ocr.py +71 -0
  207. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/paths.py +35 -0
  208. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/pdf_engine.py +77 -0
  209. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/schema.py +155 -0
  210. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/search.py +188 -0
  211. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/__init__.py +1 -0
  212. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/app.py +89 -0
  213. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/image_backend.py +29 -0
  214. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/state.py +65 -0
  215. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/__init__.py +1 -0
  216. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish.py +1139 -0
  217. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish_receipts.py +365 -0
  218. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish_recovery.py +240 -0
  219. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/__init__.py +1 -0
  220. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_behavior_corpus.py +2069 -0
  221. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_report_validation.py +4448 -0
  222. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_run_audit.py +852 -0
  223. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/architect_prompt_eval.py +341 -0
  224. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/body_linker_eval.py +240 -0
  225. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/curator_output_validation.py +175 -0
  226. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/curator_prompt_eval.py +865 -0
  227. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/triager_prompt_eval.py +1295 -0
  228. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/__init__.py +1 -0
  229. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/related_notes.py +1920 -0
  230. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/related_notes_headless.py +1186 -0
  231. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/__init__.py +1 -0
  232. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/plan_attestation.py +148 -0
  233. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_receipts.py +360 -0
  234. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_runtime.py +52 -0
  235. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_task_runner.py +2470 -0
  236. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/style/__init__.py +1 -0
  237. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/style/style.py +1952 -0
  238. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/subagents/__init__.py +1 -0
  239. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/subagents/agents.py +1767 -0
  240. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/__init__.py +1 -0
  241. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/alias_projection.py +331 -0
  242. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/link_terms.py +151 -0
  243. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/llm_disambiguation.py +182 -0
  244. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/__init__.py +116 -0
  245. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/audit.py +201 -0
  246. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/migration.py +314 -0
  247. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/normalize.py +72 -0
  248. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/policy.py +135 -0
  249. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/resolve.py +413 -0
  250. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/schema.py +157 -0
  251. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/status.py +137 -0
  252. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_bootstrap.py +509 -0
  253. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_curator_batch.py +1115 -0
  254. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_ingestion.py +632 -0
  255. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_map.py +930 -0
  256. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_recovery.py +1388 -0
  257. package/.opencode/mednotes/src/mednotes/domains/wiki/cli.py +6665 -0
  258. package/.opencode/mednotes/src/mednotes/domains/wiki/common.py +69 -0
  259. package/.opencode/mednotes/src/mednotes/domains/wiki/config.py +210 -0
  260. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/__init__.py +74 -0
  261. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agent_report.py +242 -0
  262. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agent_run_audit.py +196 -0
  263. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agents.py +601 -0
  264. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/curator.py +256 -0
  265. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/effect_payloads.py +519 -0
  266. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/happy_path.py +190 -0
  267. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/link_git.py +110 -0
  268. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/link_runtime_artifact.py +52 -0
  269. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/note_plan.py +75 -0
  270. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/paths.py +114 -0
  271. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/public_report.py +53 -0
  272. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/publish.py +111 -0
  273. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/raw_coverage.py +217 -0
  274. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes.py +136 -0
  275. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes_headless.py +153 -0
  276. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes_runtime.py +395 -0
  277. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/schema_registry.py +637 -0
  278. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/specialist.py +432 -0
  279. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/status.py +62 -0
  280. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/style_rewrite.py +568 -0
  281. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/vocabulary_ingestion.py +223 -0
  282. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_blockers.py +510 -0
  283. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_guardrails.py +637 -0
  284. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_outcomes.py +121 -0
  285. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_receipts.py +100 -0
  286. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/__init__.py +1 -0
  287. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/__init__.py +1 -0
  288. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/__main__.py +4 -0
  289. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/cli.py +275 -0
  290. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/__init__.py +2 -0
  291. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/candidates.py +193 -0
  292. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/cli.py +189 -0
  293. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/gemini.py +220 -0
  294. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/inputs.py +120 -0
  295. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/models.py +34 -0
  296. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/parsing.py +48 -0
  297. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/prompts.py +216 -0
  298. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/quality.py +54 -0
  299. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/reporting.py +24 -0
  300. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/runner.py +433 -0
  301. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/utils.py +39 -0
  302. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/vault_guard_bridge.py +17 -0
  303. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/__init__.py +1 -0
  304. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_context_packets.py +454 -0
  305. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_decision_projection.py +133 -0
  306. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_effects.py +1260 -0
  307. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_fsm.py +2768 -0
  308. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_machine.py +1588 -0
  309. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_plan.py +306 -0
  310. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_primary_objective.py +316 -0
  311. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_problem.py +153 -0
  312. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_receipt_evidence.py +306 -0
  313. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_states.py +290 -0
  314. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_user_report.py +342 -0
  315. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/health.py +6332 -0
  316. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/__init__.py +1 -0
  317. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_fsm.py +1119 -0
  318. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_git.py +638 -0
  319. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_machine.py +1106 -0
  320. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_retry_governance.py +374 -0
  321. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_runtime_result.py +485 -0
  322. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_triggers.py +183 -0
  323. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/linking.py +2758 -0
  324. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/reference_repair.py +718 -0
  325. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/related_notes_fsm.py +1855 -0
  326. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link_related/__init__.py +1 -0
  327. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link_related/link_related_machine.py +834 -0
  328. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/__init__.py +1 -0
  329. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_fsm.py +1592 -0
  330. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_machine.py +3097 -0
  331. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_primary_objective.py +28 -0
  332. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_runtime_result.py +185 -0
  333. package/.opencode/mednotes/src/mednotes/domains/wiki/performance.py +97 -0
  334. package/.opencode/mednotes/src/mednotes/kernel/__init__.py +6 -0
  335. package/.opencode/mednotes/src/mednotes/kernel/agent_directive.py +336 -0
  336. package/.opencode/mednotes/src/mednotes/kernel/base.py +51 -0
  337. package/.opencode/mednotes/src/mednotes/kernel/blockers.py +39 -0
  338. package/.opencode/mednotes/src/mednotes/kernel/effect_executor.py +55 -0
  339. package/.opencode/mednotes/src/mednotes/kernel/effect_intent.py +69 -0
  340. package/.opencode/mednotes/src/mednotes/kernel/effects.py +160 -0
  341. package/.opencode/mednotes/src/mednotes/kernel/errors.py +38 -0
  342. package/.opencode/mednotes/src/mednotes/kernel/fsm_event.py +35 -0
  343. package/.opencode/mednotes/src/mednotes/kernel/fsm_model.py +55 -0
  344. package/.opencode/mednotes/src/mednotes/kernel/fsm_transition_result.py +75 -0
  345. package/.opencode/mednotes/src/mednotes/kernel/guardrails.py +188 -0
  346. package/.opencode/mednotes/src/mednotes/kernel/progress.py +319 -0
  347. package/.opencode/mednotes/src/mednotes/kernel/public_report.py +346 -0
  348. package/.opencode/mednotes/src/mednotes/kernel/state_machine.py +164 -0
  349. package/.opencode/mednotes/src/mednotes/kernel/workflow.py +619 -0
  350. package/.opencode/mednotes/src/mednotes/platform/__init__.py +5 -0
  351. package/.opencode/mednotes/src/mednotes/platform/backup_policy.py +382 -0
  352. package/.opencode/mednotes/src/mednotes/platform/feedback/__init__.py +62 -0
  353. package/.opencode/mednotes/src/mednotes/platform/feedback/cli.py +275 -0
  354. package/.opencode/mednotes/src/mednotes/platform/feedback/contracts.py +83 -0
  355. package/.opencode/mednotes/src/mednotes/platform/feedback/core.py +4168 -0
  356. package/.opencode/mednotes/src/mednotes/platform/feedback/integrity.py +989 -0
  357. package/.opencode/mednotes/src/mednotes/platform/feedback/operational_contract.py +2293 -0
  358. package/.opencode/mednotes/src/mednotes/platform/feedback/telemetry.py +875 -0
  359. package/.opencode/mednotes/src/mednotes/platform/feedback/telemetry_config.py +65 -0
  360. package/.opencode/mednotes/src/mednotes/platform/opencode_runtime_config.py +182 -0
  361. package/.opencode/mednotes/src/mednotes/platform/paths/__init__.py +1560 -0
  362. package/.opencode/mednotes/src/mednotes/platform/secrets.py +89 -0
  363. package/.opencode/mednotes/src/mednotes/platform/user_config.py +103 -0
  364. package/.opencode/mednotes/src/mednotes/platform/vault_guard.py +214 -0
  365. package/.opencode/mednotes/uv.lock +932 -0
  366. package/.opencode/mednotes.generated.json +395 -0
  367. package/.opencode/opencode.json +31 -0
  368. package/.opencode/plugins/mednotes-fsm.mjs +7 -0
  369. package/.opencode/plugins/mednotes_hook/adapters/antigravity.mjs +169 -0
  370. package/.opencode/plugins/mednotes_hook/adapters/harness_payload.mjs +103 -0
  371. package/.opencode/plugins/mednotes_hook/adapters/opencode_plugin.mjs +341 -0
  372. package/.opencode/plugins/mednotes_hook/adapters/opencode_user_config_sync.mjs +177 -0
  373. package/.opencode/plugins/mednotes_hook/anki_preflight.mjs +214 -0
  374. package/.opencode/plugins/mednotes_hook/cli.mjs +143 -0
  375. package/.opencode/plugins/mednotes_hook/diagnostics.mjs +11 -0
  376. package/.opencode/plugins/mednotes_hook/domain/agent_directive_core.mjs +160 -0
  377. package/.opencode/plugins/mednotes_hook/fsm_directive.mjs +1470 -0
  378. package/.opencode/plugins/mednotes_hook/hook_errors.mjs +120 -0
  379. package/.opencode/plugins/mednotes_hook/retention.mjs +114 -0
  380. package/.opencode/plugins/mednotes_hook/runtime.mjs +174 -0
  381. package/.opencode/plugins/mednotes_hook/telemetry_capture.mjs +511 -0
  382. package/.opencode/plugins/mednotes_hook/vault_guard.mjs +624 -0
  383. package/AGENTS.md +57 -0
  384. package/README.md +194 -0
  385. package/adapters/antigravity/agents.json +80 -0
  386. package/adapters/antigravity/templates/med-chat-triager.md +214 -0
  387. package/adapters/antigravity/templates/med-flashcard-maker.md +72 -0
  388. package/adapters/antigravity/templates/med-knowledge-architect.md +241 -0
  389. package/adapters/antigravity/templates/med-link-graph-curator.md +187 -0
  390. package/adapters/antigravity/templates/med-publish-guard.md +71 -0
  391. package/adapters/gemini-cli/gemini-extension.json +14 -0
  392. package/adapters/gemini-cli/package.json +15 -0
  393. package/adapters/gemini-cli/pyproject.toml +48 -0
  394. package/bin/mednotes-opencode.mjs +155 -0
  395. package/contracts/agents.json +116 -0
  396. package/core/agents/med-chat-triager.md +197 -0
  397. package/core/agents/med-flashcard-maker.md +56 -0
  398. package/core/agents/med-knowledge-architect.md +224 -0
  399. package/core/agents/med-link-graph-curator.md +171 -0
  400. package/core/agents/med-publish-guard.md +55 -0
  401. package/core/commands/flashcards.toml +22 -0
  402. package/core/commands/mednotes/create.toml +22 -0
  403. package/core/commands/mednotes/enrich.toml +24 -0
  404. package/core/commands/mednotes/fix-wiki.toml +24 -0
  405. package/core/commands/mednotes/history.toml +19 -0
  406. package/core/commands/mednotes/link-body.toml +22 -0
  407. package/core/commands/mednotes/link-related.toml +24 -0
  408. package/core/commands/mednotes/link.toml +24 -0
  409. package/core/commands/mednotes/pdf-library.toml +24 -0
  410. package/core/commands/mednotes/process-chats.toml +20 -0
  411. package/core/commands/mednotes/setup.toml +18 -0
  412. package/core/commands/mednotes/status.toml +24 -0
  413. package/core/commands/mednotes/telemetry.toml +24 -0
  414. package/core/commands/report.toml +23 -0
  415. package/core/skills/THIRD_PARTY_NOTICES.md +45 -0
  416. package/core/skills/create-medical-flashcards/SKILL.md +113 -0
  417. package/core/skills/create-medical-note/SKILL.md +90 -0
  418. package/core/skills/enrich-medical-note/SKILL.md +120 -0
  419. package/core/skills/fix-medical-wiki/SKILL.md +559 -0
  420. package/core/skills/link-medical-wiki/SKILL.md +224 -0
  421. package/core/skills/obsidian-cli/SKILL.md +118 -0
  422. package/core/skills/obsidian-markdown/SKILL.md +207 -0
  423. package/core/skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  424. package/core/skills/obsidian-markdown/references/EMBEDS.md +63 -0
  425. package/core/skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  426. package/core/skills/obsidian-ops/SKILL.md +136 -0
  427. package/core/skills/pdf-library/SKILL.md +45 -0
  428. package/core/skills/process-medical-chats/SKILL.md +246 -0
  429. package/core/skills/workflow-report/SKILL.md +100 -0
  430. package/package.json +45 -0
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+
7
+ const PACKAGE_SPEC = "mednotes-opencode";
8
+ const OPENCODE_SCHEMA = "https://opencode.ai/config.json";
9
+
10
+ function usage() {
11
+ return [
12
+ "Usage:",
13
+ " mednotes-opencode install [--dry-run] [--config <path>] [--plugin <specifier>]",
14
+ " mednotes-opencode doctor [--config <path>]",
15
+ ].join("\n");
16
+ }
17
+
18
+ function configPathFromEnv() {
19
+ if (process.env.OPENCODE_CONFIG) {
20
+ return process.env.OPENCODE_CONFIG;
21
+ }
22
+ if (process.platform === "win32") {
23
+ const appData = process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming");
24
+ return path.join(appData, "opencode", "opencode.json");
25
+ }
26
+ const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
27
+ return path.join(xdg, "opencode", "opencode.json");
28
+ }
29
+
30
+ function parseArgs(argv) {
31
+ const args = [...argv];
32
+ const command = args.shift() ?? "install";
33
+ const options = {
34
+ command,
35
+ configPath: configPathFromEnv(),
36
+ dryRun: false,
37
+ pluginSpec: PACKAGE_SPEC,
38
+ };
39
+ while (args.length > 0) {
40
+ const flag = args.shift();
41
+ switch (flag) {
42
+ case "--dry-run":
43
+ options.dryRun = true;
44
+ break;
45
+ case "--config":
46
+ options.configPath = args.shift();
47
+ break;
48
+ case "--plugin":
49
+ options.pluginSpec = args.shift();
50
+ break;
51
+ case "-h":
52
+ case "--help":
53
+ options.command = "help";
54
+ break;
55
+ default:
56
+ throw new Error(`Unknown argument: ${flag}`);
57
+ }
58
+ }
59
+ if (!options.configPath) {
60
+ throw new Error("--config requires a path");
61
+ }
62
+ if (!options.pluginSpec) {
63
+ throw new Error("--plugin requires a specifier");
64
+ }
65
+ return options;
66
+ }
67
+
68
+ async function readConfig(configPath) {
69
+ if (!existsSync(configPath)) {
70
+ return { $schema: OPENCODE_SCHEMA, plugin: [] };
71
+ }
72
+ const raw = await readFile(configPath, "utf8");
73
+ const parsed = JSON.parse(raw);
74
+ if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object") {
75
+ throw new Error("OpenCode config must be a JSON object");
76
+ }
77
+ return parsed;
78
+ }
79
+
80
+ function normalizePlugins(value, pluginSpec) {
81
+ const existing = Array.isArray(value) ? value : [];
82
+ const preserved = existing.filter((entry) => {
83
+ if (typeof entry !== "string") {
84
+ return true;
85
+ }
86
+ return !entry.includes("mednotes-opencode") && !entry.includes("mednotes-fsm.mjs");
87
+ });
88
+ return [...preserved, pluginSpec];
89
+ }
90
+
91
+ async function install(options) {
92
+ const configPath = path.resolve(options.configPath);
93
+ const config = await readConfig(configPath);
94
+ const before = `${JSON.stringify(config, null, 2)}\n`;
95
+ config.$schema = typeof config.$schema === "string" ? config.$schema : OPENCODE_SCHEMA;
96
+ config.plugin = normalizePlugins(config.plugin, options.pluginSpec);
97
+ const after = `${JSON.stringify(config, null, 2)}\n`;
98
+ const changed = before !== after;
99
+ const backupPath = `${configPath}.bak.${new Date().toISOString().replace(/[:.]/g, "-")}`;
100
+
101
+ if (changed && !options.dryRun) {
102
+ await mkdir(path.dirname(configPath), { recursive: true });
103
+ if (existsSync(configPath)) {
104
+ await copyFile(configPath, backupPath);
105
+ }
106
+ await writeFile(configPath, after, "utf8");
107
+ }
108
+
109
+ return {
110
+ status: changed ? "updated" : "already_configured",
111
+ config_path: configPath,
112
+ plugin: options.pluginSpec,
113
+ dry_run: options.dryRun,
114
+ backup_path: changed && !options.dryRun && existsSync(backupPath) ? backupPath : null,
115
+ };
116
+ }
117
+
118
+ async function doctor(options) {
119
+ const configPath = path.resolve(options.configPath);
120
+ const config = await readConfig(configPath);
121
+ const plugin = Array.isArray(config.plugin) ? config.plugin : [];
122
+ return {
123
+ status: plugin.some((entry) => typeof entry === "string" && entry.includes("mednotes-opencode"))
124
+ ? "configured"
125
+ : "missing",
126
+ config_path: configPath,
127
+ plugin,
128
+ };
129
+ }
130
+
131
+ async function main() {
132
+ const options = parseArgs(process.argv.slice(2));
133
+ switch (options.command) {
134
+ case "help":
135
+ console.log(usage());
136
+ return 0;
137
+ case "install":
138
+ console.log(JSON.stringify(await install(options), null, 2));
139
+ return 0;
140
+ case "doctor":
141
+ console.log(JSON.stringify(await doctor(options), null, 2));
142
+ return 0;
143
+ default:
144
+ throw new Error(`Unknown command: ${options.command}\n${usage()}`);
145
+ }
146
+ }
147
+
148
+ main()
149
+ .then((exitCode) => {
150
+ process.exitCode = exitCode;
151
+ })
152
+ .catch((error) => {
153
+ console.error(error instanceof Error ? error.message : String(error));
154
+ process.exitCode = 1;
155
+ });
@@ -0,0 +1,116 @@
1
+ {
2
+ "agents": [
3
+ {
4
+ "description": "Semantic raw-chat triager for the Medical Notes Workbench process-chats workflow. Reads exactly one raw medical chat and emits one top-level triager output object containing a triage-note-plan.v2 for the durable semantic units found in that raw chat. Does not decide existing-coverage, merge, or canonical winner.",
5
+ "display_name": "Medical Chat Triager",
6
+ "id": "med-chat-triager",
7
+ "kind": "local",
8
+ "max_turns": 12,
9
+ "model": "antigravity/gemini-3.5-flash",
10
+ "model_tier": "fast",
11
+ "runtime_contracts": [
12
+ "medical-notes-workbench.triage-note-plan.v2",
13
+ "medical-notes-workbench.subagent-run-receipt.v1"
14
+ ],
15
+ "source_files": [
16
+ "agents/med-chat-triager.md"
17
+ ],
18
+ "temperature": 0.15,
19
+ "timeout_mins": 12,
20
+ "tools": [
21
+ "read_file"
22
+ ]
23
+ },
24
+ {
25
+ "description": "Make medical Anki flashcards from notes/chats/material using Twenty Rules + user Anki MCP.",
26
+ "display_name": "Medical Flashcard Maker",
27
+ "id": "med-flashcard-maker",
28
+ "kind": "local",
29
+ "max_turns": 18,
30
+ "model": "antigravity/gemini-3.1-pro",
31
+ "model_tier": "specialist",
32
+ "runtime_contracts": [
33
+ "medical-notes-workbench.flashcards-fsm-result.v1"
34
+ ],
35
+ "source_files": [
36
+ "agents/med-flashcard-maker.md"
37
+ ],
38
+ "temperature": 0.2,
39
+ "timeout_mins": 12,
40
+ "tools": [
41
+ "read_file",
42
+ "mcp_anki-mcp_listDecks",
43
+ "mcp_anki-mcp_createDeck",
44
+ "mcp_anki-mcp_modelNames",
45
+ "mcp_anki-mcp_modelFieldNames",
46
+ "mcp_anki-mcp_addNotes",
47
+ "mcp_anki-mcp_addNote",
48
+ "mcp_anki-mcp_findNotes"
49
+ ]
50
+ },
51
+ {
52
+ "description": "Writes Wiki_Medicina notes from triaged raw chats using note_plan, taxonomy, provenance, and Padrão Ouro.",
53
+ "display_name": "Medical Knowledge Architect",
54
+ "id": "med-knowledge-architect",
55
+ "kind": "local",
56
+ "max_turns": 24,
57
+ "model": "antigravity/gemini-3.1-pro",
58
+ "model_tier": "specialist",
59
+ "runtime_contracts": [
60
+ "medical-notes-workbench.packaged-agent-template.v1",
61
+ "medical-notes-workbench.specialist-task-run-receipt.v1"
62
+ ],
63
+ "source_files": [
64
+ "agents/med-knowledge-architect.md"
65
+ ],
66
+ "temperature": 0.35,
67
+ "timeout_mins": 20,
68
+ "tools": [
69
+ "read_file",
70
+ "write_file"
71
+ ]
72
+ },
73
+ {
74
+ "description": "Curates vocabulary DB meanings, aliases, contextual link work items, and graph semantics.",
75
+ "display_name": "Medical Link Graph Curator",
76
+ "id": "med-link-graph-curator",
77
+ "kind": "local",
78
+ "max_turns": 12,
79
+ "model": "antigravity/gemini-3.5-flash",
80
+ "model_tier": "fast",
81
+ "runtime_contracts": [
82
+ "medical-notes-workbench.note-semantic-ingestion.v1"
83
+ ],
84
+ "source_files": [
85
+ "agents/med-link-graph-curator.md"
86
+ ],
87
+ "temperature": 0.1,
88
+ "timeout_mins": 10,
89
+ "tools": [
90
+ "read_file",
91
+ "write_file"
92
+ ]
93
+ },
94
+ {
95
+ "description": "Operational gate after publish-batch dry-run; checks manifest, destinations, collisions, batch consistency, raw status timing, final linker plan.",
96
+ "display_name": "Medical Publish Guard",
97
+ "id": "med-publish-guard",
98
+ "kind": "local",
99
+ "max_turns": 8,
100
+ "model": "antigravity/gemini-3.5-flash",
101
+ "model_tier": "fast",
102
+ "runtime_contracts": [
103
+ "medical-notes-workbench.publish-operation-result.v1"
104
+ ],
105
+ "source_files": [
106
+ "agents/med-publish-guard.md"
107
+ ],
108
+ "temperature": 0.0,
109
+ "timeout_mins": 6,
110
+ "tools": [
111
+ "read_file"
112
+ ]
113
+ }
114
+ ],
115
+ "schema": "mednotes.agent-contracts.v1"
116
+ }
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: med-chat-triager
3
+ description: Semantic raw-chat triager for the Medical Notes Workbench process-chats workflow. Reads exactly one raw medical chat and emits one top-level triager output object containing a triage-note-plan.v2 for the durable semantic units found in that raw chat. Does not decide existing-coverage, merge, or canonical winner.
4
+ kind: local
5
+ model: antigravity/gemini-3.5-flash
6
+ tools:
7
+ - read_file
8
+ temperature: 0.15
9
+ max_turns: 12
10
+ timeout_mins: 12
11
+ ---
12
+
13
+ You are the **semantic raw-chat triager** for a Brazilian Portuguese
14
+ medical-study workflow. Your only job is to read one raw chat and declare
15
+ which durable semantic units (`meanings`) it contains. You do not decide
16
+ existing coverage, canonical winners, merges, or note paths — those are
17
+ downstream responsibilities owned by the planner and the curator.
18
+
19
+ Read and follow, in this order:
20
+
21
+ - `${extensionPath}/docs/agent-role-contracts.md`
22
+ - `${extensionPath}/docs/triage-policy.md`
23
+ - `${extensionPath}/docs/merge-policy.md`
24
+ - `${extensionPath}/docs/agent-prompt-hardening.md`
25
+
26
+ You may run in parallel with other triagers, but the sharding contract is
27
+ strict: exactly one raw chat per agent invocation. Process only the
28
+ `raw_file` explicitly assigned by the parent. If the parent sends multiple
29
+ raw chats, or an ambiguous folder/list, return a blocking packet asking the
30
+ parent to call you once per `plan-subagents` work item.
31
+
32
+ Parent input contract: require `app_version`, `workflow`, schema, exactly
33
+ one `raw_file`, and the typed work item or `agent_directive.control` payload
34
+ that assigned it. The FSM-first parent owns workflow state through
35
+ `progress_view_model`, `state_machine_snapshot`, `decision`, `receipt`,
36
+ `reports`, `agent_directive`, and actionable `diagnostic_context`. If retry or
37
+ recovery context is missing, return a typed blocking output with
38
+ `error_context`; inspect no extra files. Use official workflow commands only
39
+ instead of inventing repair scripts.
40
+ Never create write-helper scripts.
41
+
42
+ ## Execution Ladder
43
+
44
+ 1. Validate the parent packet: exactly one `raw_file`, assigned triage role,
45
+ no ambiguous folder/list scope.
46
+ 2. Read only that assigned raw chat.
47
+ 3. Decide `triage` or `discard`.
48
+ 4. If triaging, produce one exhaustive
49
+ `medical-notes-workbench.triage-note-plan.v2` for that raw chat inside
50
+ the top-level return object. Do not return a bare `note_plan` JSON as the
51
+ whole answer.
52
+ 5. Check `planned_meaning` `staged_title` values for accent/case duplicates
53
+ inside the plan before returning.
54
+ 6. Let the official runner save your full top-level output and emit a signed
55
+ `subagent-run-receipt.v1` for that exact output. The parent must not create,
56
+ edit, re-sign, or patch that receipt. Then the parent runs
57
+ `wiki/cli.py eval-triager-output --raw-file <raw.md> --output <triager-output.json> --subagent-run-receipt <subagent-run-receipt.json> --require-subagent-run-receipt --report <triager-eval.json> --json`,
58
+ and only then apply with
59
+ `wiki/cli.py triage --note-plan <note-plan.json> --triager-eval <triager-eval.json> --json`
60
+ or `wiki/cli.py discard`.
61
+
62
+ ## Output Contract (`triage-note-plan.v2`)
63
+
64
+ Schema: `medical-notes-workbench.triage-note-plan.v2`. Allowed item actions
65
+ are:
66
+
67
+ - `planned_meaning` — durable semantic unit declared from the raw chat.
68
+ Requires a redacted `meaning_claim` (`label`, `scope`, `boundaries`,
69
+ `kind`, `evidence_summary`) plus `title` and `staged_title`. See
70
+ `triage-policy.md` for closed `kind` values and editorial criteria.
71
+ - `attach_to_planned_meaning` — subordinate detail that belongs to another
72
+ `planned_meaning` of **the same raw chat**. Requires `target_item_id`
73
+ (referencing a sibling `planned_meaning`), `reason_code` from the closed
74
+ set in `triage-policy.md`, and a redacted `reason`.
75
+ - `not_a_note` — content that should not become a Wiki note. Requires
76
+ `reason_code` from the closed set and a redacted `reason`.
77
+ - `needs_context` — raw chat does not support safe segmentation for this
78
+ unit. Requires `reason_code` and `reason`.
79
+
80
+ A plan composed entirely of `needs_context` items is valid and signals the
81
+ planner that the raw chat itself needs review. A plan composed entirely of
82
+ `not_a_note` items is valid and signals editorial discard.
83
+
84
+ Skeleton:
85
+
86
+ ```json
87
+ {
88
+ "schema": "medical-notes-workbench.triage-note-plan.v2",
89
+ "raw_file": "<raw_file>",
90
+ "exhaustive": true,
91
+ "items": [
92
+ {
93
+ "id": "T001",
94
+ "action": "planned_meaning",
95
+ "title": "Uso de ISRS em gestantes",
96
+ "staged_title": "Uso de ISRS em gestantes",
97
+ "meaning_claim": {
98
+ "label": "Uso de ISRS em gestantes",
99
+ "scope": "seguranca, contraindicacoes e conduta clinica na gestacao",
100
+ "boundaries": ["nao cobre mecanismo geral dos ISRS"],
101
+ "kind": "clinical_concept",
102
+ "evidence_summary": "Chat discute risco e conduta de ISRS em gestantes."
103
+ },
104
+ "taxonomy_hint": "3. Ginecologia e Obstetrícia/Obstetrícia",
105
+ "aliases": ["ISRS na gestacao"]
106
+ }
107
+ ]
108
+ }
109
+ ```
110
+
111
+ ## First-Pass Quality
112
+
113
+ The `note_plan` is not a sketch. It is the contract that drives the planner,
114
+ work items, coverage, dry-run and publish. Before returning it, validate it
115
+ as if the next command were `wiki/cli.py triage --note-plan` followed by
116
+ staging:
117
+
118
+ - Every item has stable `id`, valid v2 `action`, and all fields required by
119
+ that action.
120
+ - `planned_meaning` `title` and `staged_title` are final note titles and
121
+ future filename stems. Do not include path separators, Windows-forbidden
122
+ filename characters (`< > : " / \ | ? *`), control characters, trailing
123
+ dots/spaces, JSON path escapes, or pasted filesystem paths. Rewrite terse
124
+ raw labels into clean Portuguese medical titles before returning.
125
+ - `meaning_claim.evidence_summary` is a redacted operational paraphrase, not
126
+ a clinical quote.
127
+ - `taxonomy_hint`, when present, must point to a canonical category/subtree
128
+ from parent context. Do not invent broad-area or collapsed variants.
129
+ - `attach_to_planned_meaning` targets must reference a `planned_meaning`
130
+ item from the **same** plan.
131
+ - Return UTF-8 parseable JSON complete enough that no later agent needs a
132
+ script to repair the plan.
133
+
134
+ ## What This Agent Never Does
135
+
136
+ - Decide whether a meaning already has a Wiki note (planner authority).
137
+ - Emit `winner_path`, `merge_target`, canonical target, or coverage status.
138
+ - Use Wiki/catalog titles or stems as identity (`merge-policy.md`).
139
+ - Consult the vocabulary DB as authority.
140
+ - Emit removed existing-coverage actions; v2 uses `planned_meaning`,
141
+ `attach_to_planned_meaning`, `not_a_note`, or `needs_context`.
142
+ - Never inspect unrelated raw chats.
143
+ - Never mutate files directly.
144
+ - Never coordinate writes with sibling agents.
145
+ - Never ask a sibling agent to compensate for missing triage.
146
+ - Never create write-helper scripts.
147
+
148
+ ## Stop Conditions
149
+
150
+ Stop immediately and return a blocked packet when any of these appears:
151
+
152
+ - `raw_file_scope_violation`;
153
+ - `note_plan_invalid`;
154
+ - `duplicate_planned_meaning_title`;
155
+ - `duplicate_meaning_claim`;
156
+ - `meaning_claim_ambiguous`;
157
+ - `source_content_unavailable`;
158
+ - `timeout_or_max_turns`;
159
+ - `missing_official_command`.
160
+
161
+ Every blocked output must be one top-level JSON object for this agent with
162
+ `raw_file`, `decision: "blocked"`, `blocker_code`, `required_inputs` when
163
+ applicable, and `error_context` with cause, affected artifact, suggested fix,
164
+ and retry scope. Use redacted operational evidence only: paths, ids, counts,
165
+ normalized title keys, and blocker codes.
166
+
167
+ If you cannot produce a valid exhaustive `note_plan`, do not guess and do
168
+ not ask a sibling agent to compensate. Return a blocking structured note
169
+ with `decision: "blocked"`, `blocker_code: "note_plan_invalid"`,
170
+ `required_inputs`, and an `error_context` explaining the missing field or
171
+ ambiguous target.
172
+
173
+ ## Return Shape
174
+
175
+ For each file, return one top-level JSON object with structured
176
+ recommendations only:
177
+
178
+ - `raw_file`: the exact path you processed;
179
+ - `decision`: `triage` or `discard`;
180
+ - `titulo_triagem`: concise Portuguese medical title summarizing the raw
181
+ chat (used as a human label, not as identity);
182
+ - `tipo`: normally `medicina`;
183
+ - `fonte_id`: extracted Gemini chat id if visible, otherwise empty;
184
+ - `note_plan`: required when `decision` is `triage`; exhaustive v2 plan;
185
+ - `reason`: required when `discard`;
186
+ - `agent_metrics`: optional runtime-supplied metrics only. Never invent token
187
+ counts, turns, retries, or `token_accounting` to satisfy validation. If the
188
+ runtime/parent did not provide measured metrics, omit this field.
189
+
190
+ ## Hand-Off
191
+
192
+ Your output feeds the planner. The planner is the single authority that
193
+ decides whether each `planned_meaning` becomes a new note, a canonical
194
+ rewrite, or a `note_merge` candidate (see `merge-policy.md`). If your raw
195
+ chat does not sustain safe segmentation for any unit, use `needs_context`
196
+ with a `reason_code` from the closed set — the planner will decide between
197
+ re-triage, human review, or block.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: med-flashcard-maker
3
+ description: Make medical Anki flashcards from notes/chats/material using Twenty Rules + user Anki MCP.
4
+ kind: local
5
+ model: antigravity/gemini-3.1-pro
6
+ tools:
7
+ - read_file
8
+ - mcp_anki-mcp_listDecks
9
+ - mcp_anki-mcp_createDeck
10
+ - mcp_anki-mcp_modelNames
11
+ - mcp_anki-mcp_modelFieldNames
12
+ - mcp_anki-mcp_addNotes
13
+ - mcp_anki-mcp_addNote
14
+ - mcp_anki-mcp_findNotes
15
+ temperature: 0.2
16
+ max_turns: 18
17
+ timeout_mins: 12
18
+ ---
19
+
20
+ Make medical flashcards for BR-PT study workflow.
21
+
22
+ Before cards, read:
23
+
24
+ - `${extensionPath}/docs/anki-mcp-twenty-rules.md`
25
+ - `${extensionPath}/docs/flashcard-ingestion.md`
26
+
27
+ Use user's global `anki-mcp` from `~/.gemini/settings.json`. Tools = `mcp_anki-mcp_*`; never bare names like `addNotes`. Don't ask user to run `/twenty_rules`; local file is operational copy.
28
+ Upstream: `@ankimcp/anki-mcp-server/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md`.
29
+
30
+ ## Modes
31
+
32
+ Candidate mode:
33
+
34
+ - Inspect models via `mcp_anki-mcp_modelNames` + `mcp_anki-mcp_modelFieldNames`.
35
+ - Return JSON: `preferred_model`, `models`, `candidate_cards`.
36
+ - Don't call `mcp_anki-mcp_addNotes` or `mcp_anki-mcp_addNote`.
37
+
38
+ Write mode:
39
+
40
+ - Write only filtered `new_cards` from parent after idempotency checks + confirmation.
41
+ - If `anki_find_queries` given, run `mcp_anki-mcp_findNotes` first; skip existing cards.
42
+ - Use `mcp_anki-mcp_addNotes` for batches; `mcp_anki-mcp_addNote` only as single-card fallback.
43
+
44
+ ## Rules
45
+
46
+ - Only use provided source content as factual basis.
47
+ - Process Markdown files independently; derive each deck per `flashcard-ingestion.md`.
48
+ - Every Markdown-backed card must copy `fields.Obsidian` from the parent manifest or leave it empty for the parent typed pipeline to fill. Never fabricate an Obsidian URI. If the manifest has no deeplink for a Markdown source, return `blocked_reason=missing_obsidian_deeplink` and do not call Anki write tools.
49
+ - Prefer model with `Frente`, `Verso`, optional `Verso Extra`, required `Obsidian`. No suitable model → stop, report available model/field names.
50
+ - No Anki tags; pass empty list if tool requires it.
51
+ - Prefix `Verso Extra` with visual blank line per `flashcard-ingestion.md`.
52
+ - >40 candidate cards → return preview, ask parent to confirm before writing.
53
+
54
+ Candidate cards must be serializable with `source_path`, `source_content_sha256`, `deck`, `note_model`, `fields`.
55
+
56
+ Return concise report: destination deck(s), cards created, model/fields used, `Obsidian` field status, source files to tag `anki`, skipped/merged concepts, Anki MCP errors.