@goondocks/myco 0.17.2 → 0.18.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 (182) hide show
  1. package/README.md +14 -22
  2. package/bin/myco-run +15 -2
  3. package/dist/{agent-run-7AYHXIEF.js → agent-run-2NFYMQXW.js} +7 -7
  4. package/dist/{agent-tasks-UUIFKBD4.js → agent-tasks-MEIYLXGN.js} +7 -7
  5. package/dist/{chunk-XD3NEN3Q.js → chunk-2V7HR7HB.js} +2 -2
  6. package/dist/{chunk-CTF7TQMJ.js → chunk-55QEICRO.js} +14 -4
  7. package/dist/chunk-55QEICRO.js.map +1 -0
  8. package/dist/{chunk-DT42247G.js → chunk-75AZFBFW.js} +3 -3
  9. package/dist/{chunk-ZSJPI5MS.js → chunk-7OYXB2NM.js} +2 -2
  10. package/dist/{chunk-XZWFMMJR.js → chunk-BUIR3JWM.js} +3 -3
  11. package/dist/{chunk-7DAH5GLC.js → chunk-CKJAWZQE.js} +5 -1
  12. package/dist/chunk-CKJAWZQE.js.map +1 -0
  13. package/dist/{chunk-ML6GTPZU.js → chunk-CML4MCYF.js} +2 -2
  14. package/dist/{chunk-BZDZORVP.js → chunk-DLFDBKEV.js} +4 -4
  15. package/dist/{chunk-SI5BBQAT.js → chunk-EO2RQW4S.js} +2 -2
  16. package/dist/{chunk-EBIYONNZ.js → chunk-FABWUX5G.js} +20 -2
  17. package/dist/chunk-FABWUX5G.js.map +1 -0
  18. package/dist/{chunk-RMJPQZGF.js → chunk-JDI4DPWD.js} +127 -125
  19. package/dist/chunk-JDI4DPWD.js.map +1 -0
  20. package/dist/chunk-JMOUFG6Y.js +65 -0
  21. package/dist/chunk-JMOUFG6Y.js.map +1 -0
  22. package/dist/{chunk-HPZ7YAMA.js → chunk-KWTOCJLB.js} +3 -3
  23. package/dist/{chunk-F6C4IC6R.js → chunk-NI23QCHB.js} +3 -3
  24. package/dist/{chunk-IGBHLFV5.js → chunk-NZI7WBZI.js} +2 -2
  25. package/dist/{chunk-C3C5QVLK.js → chunk-O3TRN3RC.js} +2 -2
  26. package/dist/{chunk-UTLWSKDV.js → chunk-OW433Q4C.js} +2 -2
  27. package/dist/{chunk-5ZISXCDC.js → chunk-PFWIPRF6.js} +39 -5
  28. package/dist/chunk-PFWIPRF6.js.map +1 -0
  29. package/dist/{chunk-3NCVCGUZ.js → chunk-RAV5YMRU.js} +3 -3
  30. package/dist/{chunk-RKPTMHED.js → chunk-U3J2DDSR.js} +2 -2
  31. package/dist/{chunk-25WHTV4N.js → chunk-U7GJTVSX.js} +2 -2
  32. package/dist/{chunk-NUSTG3BH.js → chunk-VOCGURV7.js} +3 -3
  33. package/dist/{chunk-VVGZL2HX.js → chunk-WYOE4IAX.js} +153 -15
  34. package/dist/{chunk-VVGZL2HX.js.map → chunk-WYOE4IAX.js.map} +1 -1
  35. package/dist/{cli-WJVYP2QT.js → cli-IIMBALPV.js} +40 -40
  36. package/dist/{client-LZ3ZR4HC.js → client-VZCUISHZ.js} +4 -4
  37. package/dist/{config-ZQIMG3FB.js → config-DA4IUVFL.js} +3 -3
  38. package/dist/{detect-NJ2OREDP.js → detect-GEM3NVK6.js} +2 -2
  39. package/dist/{detect-providers-C64L3QET.js → detect-providers-PSVKXTWE.js} +4 -4
  40. package/dist/{doctor-XEPBNHM3.js → doctor-QYD34X7Q.js} +12 -12
  41. package/dist/{executor-NXKJU5KW.js → executor-NSPRTH4M.js} +17 -17
  42. package/dist/{init-BHVQAQ27.js → init-WYYL44KZ.js} +13 -13
  43. package/dist/{installer-45ZLP2RP.js → installer-BWJED3ED.js} +2 -2
  44. package/dist/{llm-KTD6SR55.js → llm-KEDHK3TQ.js} +4 -4
  45. package/dist/{loader-SHRKUKOS.js → loader-Q3P3R4UP.js} +3 -3
  46. package/dist/{loader-NEX3UF6U.js → loader-SKKUMT5C.js} +3 -3
  47. package/dist/{main-YFVBIRRK.js → main-6PY3ITQ5.js} +388 -125
  48. package/dist/main-6PY3ITQ5.js.map +1 -0
  49. package/dist/{open-2U7ZRGA3.js → open-HRFMJDQX.js} +7 -7
  50. package/dist/{post-compact-QIBMEWL3.js → post-compact-HT24YMAN.js} +7 -7
  51. package/dist/{post-tool-use-ICGFXDVY.js → post-tool-use-DENRI5WB.js} +6 -6
  52. package/dist/{post-tool-use-failure-C7TLH3XQ.js → post-tool-use-failure-A6SNJX42.js} +7 -7
  53. package/dist/{pre-compact-IF7K4TQK.js → pre-compact-3Q4BALCL.js} +7 -7
  54. package/dist/{provider-check-LTLQ6BUZ.js → provider-check-AE3L5Z6R.js} +4 -4
  55. package/dist/{registry-TFQ22Z7N.js → registry-O2NZLO3V.js} +4 -4
  56. package/dist/{remove-FBGM2QVJ.js → remove-YB5A6HY2.js} +9 -9
  57. package/dist/{resolution-events-HGKIJOTA.js → resolution-events-XWYLLDRK.js} +4 -4
  58. package/dist/{restart-TQEECRNW.js → restart-RGDVHELZ.js} +8 -8
  59. package/dist/{search-NN5FC4Z6.js → search-WOHT3G55.js} +8 -8
  60. package/dist/{server-XMWJ4GF7.js → server-6SUNYDV7.js} +4 -4
  61. package/dist/{session-GLPAFYPO.js → session-W3SKRFRV.js} +9 -9
  62. package/dist/{session-end-TI3ILRBC.js → session-end-OUTY7AFF.js} +6 -6
  63. package/dist/{session-start-PJLJDVJJ.js → session-start-5MB3LFOA.js} +24 -13
  64. package/dist/{session-start-PJLJDVJJ.js.map → session-start-5MB3LFOA.js.map} +1 -1
  65. package/dist/{setup-llm-AQSWLXCZ.js → setup-llm-ZMYGIQX5.js} +8 -8
  66. package/dist/src/cli.js +1 -1
  67. package/dist/src/daemon/main.js +1 -1
  68. package/dist/src/hooks/post-tool-use.js +1 -1
  69. package/dist/src/hooks/session-end.js +1 -1
  70. package/dist/src/hooks/session-start.js +1 -1
  71. package/dist/src/hooks/stop.js +1 -1
  72. package/dist/src/hooks/user-prompt-submit.js +1 -1
  73. package/dist/src/mcp/server.js +1 -1
  74. package/dist/src/symbionts/manifests/codex.yaml +47 -0
  75. package/dist/src/symbionts/templates/claude-code/hooks.json +12 -12
  76. package/dist/src/symbionts/templates/claude-code/settings.json +3 -3
  77. package/dist/src/symbionts/templates/codex/hooks.json +4 -4
  78. package/dist/src/symbionts/templates/cursor/hooks.json +9 -9
  79. package/dist/src/symbionts/templates/cursor/settings.json +2 -2
  80. package/dist/src/symbionts/templates/gemini/hooks.json +6 -6
  81. package/dist/src/symbionts/templates/gemini/settings.json +2 -2
  82. package/dist/src/symbionts/templates/myco-run.cjs +44 -0
  83. package/dist/src/symbionts/templates/opencode/settings.json +2 -2
  84. package/dist/src/symbionts/templates/vscode-copilot/hooks.json +7 -7
  85. package/dist/src/symbionts/templates/vscode-copilot/settings.json +2 -2
  86. package/dist/src/symbionts/templates/windsurf/hooks.json +4 -4
  87. package/dist/src/symbionts/templates/windsurf/settings.json +2 -2
  88. package/dist/src/worker/package-lock.json +4338 -0
  89. package/dist/src/worker/package.json +5 -0
  90. package/dist/src/worker/src/index.ts +50 -63
  91. package/dist/src/worker/src/mcp/auth.ts +65 -0
  92. package/dist/src/worker/src/mcp/server.ts +53 -0
  93. package/dist/src/worker/src/mcp/tools/context.ts +13 -0
  94. package/dist/src/worker/src/mcp/tools/get.ts +15 -0
  95. package/dist/src/worker/src/mcp/tools/graph.ts +35 -0
  96. package/dist/src/worker/src/mcp/tools/search.ts +32 -0
  97. package/dist/src/worker/src/mcp/tools/sessions.ts +24 -0
  98. package/dist/src/worker/src/mcp/tools/skills.ts +16 -0
  99. package/dist/src/worker/src/mcp/tools/team.ts +9 -0
  100. package/dist/src/worker/src/schema.ts +3 -1
  101. package/dist/src/worker/src/search-helpers.ts +70 -0
  102. package/dist/src/worker/wrangler.toml +9 -0
  103. package/dist/{stats-BISBIBXZ.js → stats-DGI6B3HX.js} +9 -9
  104. package/dist/{stop-47BJ42EO.js → stop-YGHODSP7.js} +6 -6
  105. package/dist/{stop-failure-VU5BTLWX.js → stop-failure-7IJTPJ6W.js} +7 -7
  106. package/dist/{subagent-start-SPTKQRHU.js → subagent-start-ZBQ5PJB5.js} +7 -7
  107. package/dist/{subagent-stop-UU75BYLC.js → subagent-stop-N2TDQU2D.js} +7 -7
  108. package/dist/{task-completed-MVDO7TZF.js → task-completed-BDLMRSBB.js} +7 -7
  109. package/dist/{team-7X64J4Y6.js → team-2ZFGTSIN.js} +97 -14
  110. package/dist/team-2ZFGTSIN.js.map +1 -0
  111. package/dist/ui/assets/{index-rpmSpJpm.js → index-DtT9_nlT.js} +120 -120
  112. package/dist/ui/index.html +1 -1
  113. package/dist/{update-DA7VEXOS.js → update-STLAN7LR.js} +18 -9
  114. package/dist/update-STLAN7LR.js.map +1 -0
  115. package/dist/{user-prompt-submit-ADZ4NTVO.js → user-prompt-submit-4IBFUYQ3.js} +27 -7
  116. package/dist/user-prompt-submit-4IBFUYQ3.js.map +1 -0
  117. package/dist/{verify-QYSERHF7.js → verify-EJYPO7QA.js} +5 -5
  118. package/dist/{version-A72TAL2J.js → version-YPBIKH77.js} +2 -2
  119. package/package.json +1 -1
  120. package/dist/chunk-5ZISXCDC.js.map +0 -1
  121. package/dist/chunk-7DAH5GLC.js.map +0 -1
  122. package/dist/chunk-CTF7TQMJ.js.map +0 -1
  123. package/dist/chunk-EBIYONNZ.js.map +0 -1
  124. package/dist/chunk-RMJPQZGF.js.map +0 -1
  125. package/dist/main-YFVBIRRK.js.map +0 -1
  126. package/dist/src/symbionts/templates/hook-guard.cjs +0 -19
  127. package/dist/team-7X64J4Y6.js.map +0 -1
  128. package/dist/update-DA7VEXOS.js.map +0 -1
  129. package/dist/user-prompt-submit-ADZ4NTVO.js.map +0 -1
  130. /package/dist/{agent-run-7AYHXIEF.js.map → agent-run-2NFYMQXW.js.map} +0 -0
  131. /package/dist/{agent-tasks-UUIFKBD4.js.map → agent-tasks-MEIYLXGN.js.map} +0 -0
  132. /package/dist/{chunk-XD3NEN3Q.js.map → chunk-2V7HR7HB.js.map} +0 -0
  133. /package/dist/{chunk-DT42247G.js.map → chunk-75AZFBFW.js.map} +0 -0
  134. /package/dist/{chunk-ZSJPI5MS.js.map → chunk-7OYXB2NM.js.map} +0 -0
  135. /package/dist/{chunk-XZWFMMJR.js.map → chunk-BUIR3JWM.js.map} +0 -0
  136. /package/dist/{chunk-ML6GTPZU.js.map → chunk-CML4MCYF.js.map} +0 -0
  137. /package/dist/{chunk-BZDZORVP.js.map → chunk-DLFDBKEV.js.map} +0 -0
  138. /package/dist/{chunk-SI5BBQAT.js.map → chunk-EO2RQW4S.js.map} +0 -0
  139. /package/dist/{chunk-HPZ7YAMA.js.map → chunk-KWTOCJLB.js.map} +0 -0
  140. /package/dist/{chunk-F6C4IC6R.js.map → chunk-NI23QCHB.js.map} +0 -0
  141. /package/dist/{chunk-IGBHLFV5.js.map → chunk-NZI7WBZI.js.map} +0 -0
  142. /package/dist/{chunk-C3C5QVLK.js.map → chunk-O3TRN3RC.js.map} +0 -0
  143. /package/dist/{chunk-UTLWSKDV.js.map → chunk-OW433Q4C.js.map} +0 -0
  144. /package/dist/{chunk-3NCVCGUZ.js.map → chunk-RAV5YMRU.js.map} +0 -0
  145. /package/dist/{chunk-RKPTMHED.js.map → chunk-U3J2DDSR.js.map} +0 -0
  146. /package/dist/{chunk-25WHTV4N.js.map → chunk-U7GJTVSX.js.map} +0 -0
  147. /package/dist/{chunk-NUSTG3BH.js.map → chunk-VOCGURV7.js.map} +0 -0
  148. /package/dist/{cli-WJVYP2QT.js.map → cli-IIMBALPV.js.map} +0 -0
  149. /package/dist/{client-LZ3ZR4HC.js.map → client-VZCUISHZ.js.map} +0 -0
  150. /package/dist/{config-ZQIMG3FB.js.map → config-DA4IUVFL.js.map} +0 -0
  151. /package/dist/{detect-NJ2OREDP.js.map → detect-GEM3NVK6.js.map} +0 -0
  152. /package/dist/{detect-providers-C64L3QET.js.map → detect-providers-PSVKXTWE.js.map} +0 -0
  153. /package/dist/{doctor-XEPBNHM3.js.map → doctor-QYD34X7Q.js.map} +0 -0
  154. /package/dist/{executor-NXKJU5KW.js.map → executor-NSPRTH4M.js.map} +0 -0
  155. /package/dist/{init-BHVQAQ27.js.map → init-WYYL44KZ.js.map} +0 -0
  156. /package/dist/{installer-45ZLP2RP.js.map → installer-BWJED3ED.js.map} +0 -0
  157. /package/dist/{llm-KTD6SR55.js.map → llm-KEDHK3TQ.js.map} +0 -0
  158. /package/dist/{loader-NEX3UF6U.js.map → loader-Q3P3R4UP.js.map} +0 -0
  159. /package/dist/{loader-SHRKUKOS.js.map → loader-SKKUMT5C.js.map} +0 -0
  160. /package/dist/{open-2U7ZRGA3.js.map → open-HRFMJDQX.js.map} +0 -0
  161. /package/dist/{post-compact-QIBMEWL3.js.map → post-compact-HT24YMAN.js.map} +0 -0
  162. /package/dist/{post-tool-use-ICGFXDVY.js.map → post-tool-use-DENRI5WB.js.map} +0 -0
  163. /package/dist/{post-tool-use-failure-C7TLH3XQ.js.map → post-tool-use-failure-A6SNJX42.js.map} +0 -0
  164. /package/dist/{pre-compact-IF7K4TQK.js.map → pre-compact-3Q4BALCL.js.map} +0 -0
  165. /package/dist/{provider-check-LTLQ6BUZ.js.map → provider-check-AE3L5Z6R.js.map} +0 -0
  166. /package/dist/{registry-TFQ22Z7N.js.map → registry-O2NZLO3V.js.map} +0 -0
  167. /package/dist/{remove-FBGM2QVJ.js.map → remove-YB5A6HY2.js.map} +0 -0
  168. /package/dist/{resolution-events-HGKIJOTA.js.map → resolution-events-XWYLLDRK.js.map} +0 -0
  169. /package/dist/{restart-TQEECRNW.js.map → restart-RGDVHELZ.js.map} +0 -0
  170. /package/dist/{search-NN5FC4Z6.js.map → search-WOHT3G55.js.map} +0 -0
  171. /package/dist/{server-XMWJ4GF7.js.map → server-6SUNYDV7.js.map} +0 -0
  172. /package/dist/{session-GLPAFYPO.js.map → session-W3SKRFRV.js.map} +0 -0
  173. /package/dist/{session-end-TI3ILRBC.js.map → session-end-OUTY7AFF.js.map} +0 -0
  174. /package/dist/{setup-llm-AQSWLXCZ.js.map → setup-llm-ZMYGIQX5.js.map} +0 -0
  175. /package/dist/{stats-BISBIBXZ.js.map → stats-DGI6B3HX.js.map} +0 -0
  176. /package/dist/{stop-47BJ42EO.js.map → stop-YGHODSP7.js.map} +0 -0
  177. /package/dist/{stop-failure-VU5BTLWX.js.map → stop-failure-7IJTPJ6W.js.map} +0 -0
  178. /package/dist/{subagent-start-SPTKQRHU.js.map → subagent-start-ZBQ5PJB5.js.map} +0 -0
  179. /package/dist/{subagent-stop-UU75BYLC.js.map → subagent-stop-N2TDQU2D.js.map} +0 -0
  180. /package/dist/{task-completed-MVDO7TZF.js.map → task-completed-BDLMRSBB.js.map} +0 -0
  181. /package/dist/{verify-QYSERHF7.js.map → verify-EJYPO7QA.js.map} +0 -0
  182. /package/dist/{version-A72TAL2J.js.map → version-YPBIKH77.js.map} +0 -0
package/README.md CHANGED
@@ -47,25 +47,17 @@ Myco hooks into your agent's lifecycle — session starts, prompts, tool calls,
47
47
 
48
48
  ### Intelligence
49
49
 
50
- The Myco agent is a multi-phase reasoning pipeline that runs in the background, processing captured data through a dependency graph of tasks. Phases are organized into **waves** groups that execute in parallel computed via topological sort from a DAG of dependencies.
50
+ Myco runs an intelligence pipeline in the background that reads captured sessions and turns them into durable knowledge. It extracts **spores** (observations like decisions, gotchas, discoveries, trade-offs, bug fixes), generates session titles and summaries, links entities into a knowledge graph, and refreshes digest extracts — all automatically.
51
51
 
52
- The full intelligence pipeline flows through five waves:
52
+ When the agent finds 3+ semantically similar spores, it synthesizes them into a **wisdom** spore — a higher-order observation that captures the pattern across sessions. Individual observations become institutional knowledge.
53
53
 
54
- ```
55
- read-state → extract + summarize → consolidate + graph → digest → report
56
- ```
57
-
58
- Each phase runs with scoped tools, a turn budget, isolated provider config, and results from prior phases as context. The agent extracts **spores** (observations like decisions, gotchas, discoveries, trade-offs, bug fixes), generates session summaries, links entities in the knowledge graph, and synthesizes digest extracts — all automatically.
59
-
60
- **Consolidation** is where individual observations become institutional knowledge. When the agent finds 3+ semantically similar spores, it synthesizes them into a **wisdom** spore — a higher-order observation that captures the pattern across sessions. Source spores are preserved with lineage metadata, and the wisdom spore becomes the canonical reference going forward.
61
-
62
- **Provider flexibility** — every task and phase can use a different LLM provider. Run title generation on a fast local model via Ollama, extraction on Claude, and consolidation on a larger local model via LM Studio. Configure globally or per-task in `myco.yaml`, or use the [dashboard](#dashboard) to manage assignments visually.
54
+ Every task can use a different LLM provider. Run title generation on a fast local model via Ollama, extraction on Claude, consolidation on a larger local model via LM Studio. Configure globally or per-task in `myco.yaml`, or use the [dashboard](#dashboard) to manage assignments visually.
63
55
 
64
- Ten built-in tasks cover the full lifecycle — seven for intelligence processing (from lightweight `title-summary` to the complete `full-intelligence` pipeline) and three for the skill lifecycle engine (`skill-survey`, `skill-generate`, `skill-evolve`). For the full breakdown — wave execution, phase dependencies, tool scoping, read-only enforcement, orchestrator planning, and provider config — see the [Agent Harness docs](docs/agent-harness.md).
56
+ See the [Intelligence Pipeline docs](docs/agent-harness.md) for the task catalog, provider configuration, and scheduling.
65
57
 
66
58
  ### Digest
67
59
 
68
- The digest system synthesizes accumulated knowledge into tiered **extracts** — pre-computed context at different depths:
60
+ The digest synthesizes accumulated knowledge into tiered **extracts** — pre-computed context at different depths:
69
61
 
70
62
  | Tier | Purpose |
71
63
  |------|---------|
@@ -73,11 +65,11 @@ The digest system synthesizes accumulated knowledge into tiered **extracts** —
73
65
  | **5,000 tokens** | Deep onboarding — trade-offs, patterns, team dynamics |
74
66
  | **10,000 tokens** | Institutional knowledge — full thread history and design tensions |
75
67
 
76
- The digest runs on an adaptive **metabolism**: active when new substrate (undigested data) arrives, slowing through cooling phases, and entering dormancy when the project goes quiet. New sessions reactivate it.
68
+ Extracts refresh in the background as new knowledge arrives. When the project goes quiet, refresh slows; new sessions wake it back up.
77
69
 
78
70
  ### Search
79
71
 
80
- Every record is indexed for both keyword search (FTS5) and semantic similarity (vector embeddings). Embedding providers are pluggable — use [Ollama](https://ollama.com) locally, or [OpenRouter](https://openrouter.ai) / [OpenAI](https://platform.openai.com) in the cloud. The index is fully rebuildable from the database.
72
+ Every record is indexed for both keyword search and semantic similarity. Use [Ollama](https://ollama.com) locally for embeddings, or [OpenRouter](https://openrouter.ai) / [OpenAI](https://platform.openai.com) in the cloud. The index is fully rebuildable from the database.
81
73
 
82
74
  ### Context injection
83
75
 
@@ -98,9 +90,7 @@ A local web dashboard provides configuration and operations management. Manage i
98
90
 
99
91
  ### Symbionts
100
92
 
101
- Myco integrates with coding agents through **symbiont** adapters — named for the mycorrhizal symbiotic relationship between fungi and their host trees. Each adapter handles transcript discovery, conversation parsing, and project registration for its host agent.
102
-
103
- `myco init` detects available agents and lets you choose which to configure. Registration is project-local — hooks, MCP servers, skills, and auto-approve settings are written directly to each agent's config files.
93
+ Myco integrates with coding agents through **symbionts** — named for the mycorrhizal symbiotic relationship between fungi and their host trees. `myco init` detects available agents and lets you choose which to configure. Registration is project-local — hooks, MCP servers, skills, and auto-approve settings are written directly to each agent's config files.
104
94
 
105
95
  | Agent | Hooks | MCP | Skills | Auto-Approve | Plans |
106
96
  |-------|-------|-----|--------|-------------|-------|
@@ -121,7 +111,7 @@ See the [Symbiont docs](docs/symbionts.md) for detailed setup information per ag
121
111
  Share knowledge across machines and team members with one command:
122
112
 
123
113
  ```bash
124
- myco team init # Provisions Cloudflare D1 + Vectorize + Worker
114
+ myco team init # Provisions Cloudflare D1 + Vectorize + KV + Worker
125
115
  ```
126
116
 
127
117
  Share the output URL and API key with teammates — they connect from the Team page in the dashboard. Once connected, knowledge syncs automatically: new spores, session summaries, plans, and graph edges push to the team store in the background. Search queries fan out to both local and cloud databases, merging results by relevance score.
@@ -130,13 +120,15 @@ Local databases remain the source of truth. The cloud store is a queryable mirro
130
120
 
131
121
  Runs on the Cloudflare free tier. See the [Team Sync docs](docs/team-sync.md) for the full guide.
132
122
 
123
+ ### Cloud MCP Server
124
+
125
+ Team sync also deploys a read-only **Cloud MCP server** on the same Worker — a Streamable HTTP endpoint that exposes your project's intelligence to cloud agents like Anthropic Managed Agents, OpenAI Workflows, and N8N. Connect any tool that speaks MCP and it gets the same project context your local agents already have. See the [Cloud MCP docs](docs/cloud-mcp.md) for the tool reference and setup.
126
+
133
127
  ### Skills — automated curation, not just memory
134
128
 
135
129
  Memory is table stakes. Myco goes further: it turns everything your team learns into **repeatable workflows** that every agent follows. The intelligence pipeline identifies procedural patterns across sessions — debugging the build, adding API routes, configuring providers, resolving common gotchas — and surfaces them as candidates. You approve what becomes canon, and Myco generates validated SKILL.md files under `.agents/skills/`, symlinked into every agent's native skills directory.
136
130
 
137
- The result is consistency, quality, and excellence enforced by tooling. New teammates ship correctly on day one. Agents stop repeating the same mistakes. Your project's hard-won knowledge becomes the default path, not an optional footnote.
138
-
139
- Skills evolve as your code does. When a pattern is abandoned, a new gotcha is discovered, or a workflow shifts, the evolve task detects the drift and rewrites affected skills — preserving what's still accurate, incorporating what's new, and splitting skills that have grown too broad. Every change records full lineage: generation number, rationale, and a content snapshot. See the [Skills docs](docs/skills.md) for the full lifecycle.
131
+ Skills evolve as your code does. When a pattern is abandoned, a new gotcha is discovered, or a workflow shifts, the evolve task rewrites affected skills preserving what's still accurate, incorporating what's new, and splitting skills that have grown too broad. See the [Skills docs](docs/skills.md) for the full lifecycle.
140
132
 
141
133
  ### Backup & restore
142
134
 
package/bin/myco-run CHANGED
@@ -1,2 +1,15 @@
1
- #!/bin/sh
2
- exec "${MYCO_CMD:-myco}" "$@"
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { execFileSync } from 'node:child_process';
6
+
7
+ const scriptPath = fs.realpathSync(process.argv[1]);
8
+ const cliEntry = path.resolve(path.dirname(scriptPath), '..', 'dist', 'src', 'cli.js');
9
+
10
+ try {
11
+ execFileSync(process.execPath, [cliEntry, ...process.argv.slice(2)], { stdio: 'inherit' });
12
+ } catch (error) {
13
+ if (error.code === 'ENOENT') process.exit(0);
14
+ process.exit(error.status ?? 1);
15
+ }
@@ -1,15 +1,15 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  connectToDaemon
4
- } from "./chunk-CTF7TQMJ.js";
4
+ } from "./chunk-55QEICRO.js";
5
5
  import "./chunk-SAKJMNSR.js";
6
- import "./chunk-VVGZL2HX.js";
7
- import "./chunk-ML6GTPZU.js";
6
+ import "./chunk-WYOE4IAX.js";
7
+ import "./chunk-CML4MCYF.js";
8
8
  import "./chunk-MYX5NCRH.js";
9
- import "./chunk-XZWFMMJR.js";
10
- import "./chunk-SI5BBQAT.js";
9
+ import "./chunk-BUIR3JWM.js";
10
+ import "./chunk-EO2RQW4S.js";
11
11
  import "./chunk-LPUQPDC2.js";
12
- import "./chunk-7DAH5GLC.js";
12
+ import "./chunk-CKJAWZQE.js";
13
13
  import "./chunk-E7NUADTQ.js";
14
14
  import "./chunk-PZUWP5VK.js";
15
15
 
@@ -32,4 +32,4 @@ async function run(args, vaultDir) {
32
32
  export {
33
33
  run
34
34
  };
35
- //# sourceMappingURL=agent-run-7AYHXIEF.js.map
35
+ //# sourceMappingURL=agent-run-2NFYMQXW.js.map
@@ -1,15 +1,15 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  connectToDaemon
4
- } from "./chunk-CTF7TQMJ.js";
4
+ } from "./chunk-55QEICRO.js";
5
5
  import "./chunk-SAKJMNSR.js";
6
- import "./chunk-VVGZL2HX.js";
7
- import "./chunk-ML6GTPZU.js";
6
+ import "./chunk-WYOE4IAX.js";
7
+ import "./chunk-CML4MCYF.js";
8
8
  import "./chunk-MYX5NCRH.js";
9
- import "./chunk-XZWFMMJR.js";
10
- import "./chunk-SI5BBQAT.js";
9
+ import "./chunk-BUIR3JWM.js";
10
+ import "./chunk-EO2RQW4S.js";
11
11
  import "./chunk-LPUQPDC2.js";
12
- import "./chunk-7DAH5GLC.js";
12
+ import "./chunk-CKJAWZQE.js";
13
13
  import "./chunk-E7NUADTQ.js";
14
14
  import "./chunk-PZUWP5VK.js";
15
15
 
@@ -178,4 +178,4 @@ async function run(args, vaultDir) {
178
178
  export {
179
179
  run
180
180
  };
181
- //# sourceMappingURL=agent-tasks-UUIFKBD4.js.map
181
+ //# sourceMappingURL=agent-tasks-MEIYLXGN.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  SCHEDULABLE_POWER_STATES
4
- } from "./chunk-7DAH5GLC.js";
4
+ } from "./chunk-CKJAWZQE.js";
5
5
  import {
6
6
  require_dist
7
7
  } from "./chunk-D7TYRPRM.js";
@@ -430,4 +430,4 @@ export {
430
430
  getEnabledSymbiontNames,
431
431
  updateTeamConfig
432
432
  };
433
- //# sourceMappingURL=chunk-XD3NEN3Q.js.map
433
+ //# sourceMappingURL=chunk-2V7HR7HB.js.map
@@ -1,11 +1,11 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  SymbiontInstaller
4
- } from "./chunk-VVGZL2HX.js";
4
+ } from "./chunk-WYOE4IAX.js";
5
5
  import {
6
6
  LmStudioBackend,
7
7
  OllamaBackend
8
- } from "./chunk-ML6GTPZU.js";
8
+ } from "./chunk-CML4MCYF.js";
9
9
  import {
10
10
  closeDatabase,
11
11
  initDatabase,
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-MYX5NCRH.js";
14
14
  import {
15
15
  DaemonClient
16
- } from "./chunk-XZWFMMJR.js";
16
+ } from "./chunk-BUIR3JWM.js";
17
17
 
18
18
  // src/cli/shared.ts
19
19
  import fs from "fs";
@@ -69,11 +69,21 @@ secrets.env
69
69
  # Machine ID
70
70
  machine_id
71
71
 
72
+ # Update tracking \u2014 per-machine state
73
+ last-update-version
74
+ restart-reason.json
75
+
72
76
  # Binary attachments \u2014 screenshots captured from transcripts
73
77
  attachments/
74
78
 
75
79
  # Team worker deployment \u2014 patched wrangler.toml + source copy
76
80
  .team-worker/
81
+
82
+ # Runtime command alias \u2014 per-contributor override for which myco binary
83
+ # the hook guard invokes. Default (file absent) is \`myco\`; \`make dev-link\`
84
+ # writes \`myco-dev\`; users can hand-edit for PATH conflicts or pinning.
85
+ # Never committed \u2014 different contributors use different aliases.
86
+ runtime.command
77
87
  `;
78
88
  function registerSymbionts(manifests, projectRoot, packageRoot, verb) {
79
89
  let count = 0;
@@ -110,4 +120,4 @@ export {
110
120
  VAULT_GITIGNORE,
111
121
  registerSymbionts
112
122
  };
113
- //# sourceMappingURL=chunk-CTF7TQMJ.js.map
123
+ //# sourceMappingURL=chunk-55QEICRO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/shared.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { OllamaBackend } from '../intelligence/ollama.js';\nimport { LmStudioBackend } from '../intelligence/lm-studio.js';\n\nimport { DaemonClient } from '../hooks/client.js';\nimport { initDatabase, closeDatabase, vaultDbPath } from '../db/client.js';\nimport { SymbiontInstaller } from '../symbionts/installer.js';\nimport type { SymbiontManifest } from '../symbionts/manifest-schema.js';\n\nexport { parseStringFlag, parseIntFlag } from '../logs/format.js';\n\n/**\n * Initialize the singleton database for direct CLI reads.\n * Used by CLI commands that only need reads (stats, search, session).\n * Does NOT require the daemon to be running — WAL mode allows concurrent reads.\n *\n * @returns a cleanup function that closes the database.\n */\nexport function initVaultDb(vaultDir: string): () => void {\n initDatabase(vaultDbPath(vaultDir));\n return closeDatabase;\n}\n\n/** Connect to the daemon, ensuring it's running. Exits on failure. */\nexport async function connectToDaemon(vaultDir: string): Promise<DaemonClient> {\n const client = new DaemonClient(vaultDir);\n const healthy = await client.ensureRunning();\n if (!healthy) {\n console.error('Failed to connect to daemon');\n process.exit(1);\n }\n return client;\n}\n\n/** Load .env from cwd (not script location — that's the plugin install dir). */\nexport function loadEnv(): void {\n const envPath = path.resolve(process.cwd(), '.env');\n if (!fs.existsSync(envPath)) return;\n for (const line of fs.readFileSync(envPath, 'utf-8').split('\\n')) {\n const match = line.match(/^\\s*([^#=]+?)\\s*=\\s*(.*?)\\s*$/);\n if (match && !process.env[match[1]]) {\n process.env[match[1]] = match[2];\n }\n }\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\n\n// --- Provider defaults (sourced from backend classes) ---\nexport const PROVIDER_DEFAULTS: Record<string, { base_url: string }> = {\n ollama: { base_url: OllamaBackend.DEFAULT_BASE_URL },\n 'lm-studio': { base_url: LmStudioBackend.DEFAULT_BASE_URL },\n};\n\n\nexport const VAULT_GITIGNORE = `# SQLite database\nmyco.db*\nvectors.db*\n\n# Daemon state — per-machine, ephemeral\ndaemon.json\nbuffer/\nlogs/\n\n# Secrets — API keys for cloud providers\nsecrets.env\n\n# Machine ID\nmachine_id\n\n# Update tracking — per-machine state\nlast-update-version\nrestart-reason.json\n\n# Binary attachments — screenshots captured from transcripts\nattachments/\n\n# Team worker deployment — patched wrangler.toml + source copy\n.team-worker/\n\n# Runtime command alias — per-contributor override for which myco binary\n# the hook guard invokes. Default (file absent) is \\`myco\\`; \\`make dev-link\\`\n# writes \\`myco-dev\\`; users can hand-edit for PATH conflicts or pinning.\n# Never committed — different contributors use different aliases.\nruntime.command\n`;\n\n/** Collapse an absolute home-dir path to its `~/` form for portable config storage. */\nexport function collapseHomePath(absPath: string): string {\n const home = os.homedir();\n if (absPath.startsWith(home + path.sep) || absPath === home) {\n return '~' + absPath.slice(home.length);\n }\n return absPath;\n}\n\n/**\n * Run the SymbiontInstaller for each symbiont manifest and log results.\n * Shared between myco init and myco update.\n */\nexport function registerSymbionts(\n manifests: SymbiontManifest[],\n projectRoot: string,\n packageRoot: string,\n verb: 'Registered' | 'Updated',\n): number {\n let count = 0;\n for (const manifest of manifests) {\n try {\n const installer = new SymbiontInstaller(manifest, projectRoot, packageRoot);\n const result = installer.install();\n\n const installed = [\n result.hooks && 'hooks',\n result.mcp && 'MCP server',\n result.skills && 'skills',\n result.settings && 'settings',\n result.instructions && 'instructions',\n result.pluginPackage && 'plugin deps',\n ].filter(Boolean);\n\n if (installed.length > 0) {\n console.log(` \\u2713 ${verb} ${manifest.displayName}: ${installed.join(', ')}`);\n count++;\n } else {\n console.log(` \\u2013 ${manifest.displayName}: no registration targets configured`);\n }\n } catch (err) {\n console.error(` \\u2717 Failed to register ${manifest.displayName}: ${(err as Error).message}`);\n }\n }\n return count;\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AAkBR,SAAS,YAAY,UAA8B;AACxD,eAAa,YAAY,QAAQ,CAAC;AAClC,SAAO;AACT;AAGA,eAAsB,gBAAgB,UAAyC;AAC7E,QAAM,SAAS,IAAI,aAAa,QAAQ;AACxC,QAAM,UAAU,MAAM,OAAO,cAAc;AAC3C,MAAI,CAAC,SAAS;AACZ,YAAQ,MAAM,6BAA6B;AAC3C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAGO,SAAS,UAAgB;AAC9B,QAAM,UAAU,KAAK,QAAQ,QAAQ,IAAI,GAAG,MAAM;AAClD,MAAI,CAAC,GAAG,WAAW,OAAO,EAAG;AAC7B,aAAW,QAAQ,GAAG,aAAa,SAAS,OAAO,EAAE,MAAM,IAAI,GAAG;AAChE,UAAM,QAAQ,KAAK,MAAM,+BAA+B;AACxD,QAAI,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,GAAG;AACnC,cAAQ,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC;AAAA,IACjC;AAAA,EACF;AACF;AAEO,SAAS,eAAe,KAAsB;AACnD,MAAI;AAAE,YAAQ,KAAK,KAAK,CAAC;AAAG,WAAO;AAAA,EAAM,QAAQ;AAAE,WAAO;AAAA,EAAO;AACnE;AAGO,IAAM,oBAA0D;AAAA,EACrE,QAAQ,EAAE,UAAU,cAAc,iBAAiB;AAAA,EACnD,aAAa,EAAE,UAAU,gBAAgB,iBAAiB;AAC5D;AAGO,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CxB,SAAS,kBACd,WACA,aACA,aACA,MACQ;AACR,MAAI,QAAQ;AACZ,aAAW,YAAY,WAAW;AAChC,QAAI;AACF,YAAM,YAAY,IAAI,kBAAkB,UAAU,aAAa,WAAW;AAC1E,YAAM,SAAS,UAAU,QAAQ;AAEjC,YAAM,YAAY;AAAA,QAChB,OAAO,SAAS;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,OAAO,UAAU;AAAA,QACjB,OAAO,YAAY;AAAA,QACnB,OAAO,gBAAgB;AAAA,QACvB,OAAO,iBAAiB;AAAA,MAC1B,EAAE,OAAO,OAAO;AAEhB,UAAI,UAAU,SAAS,GAAG;AACxB,gBAAQ,IAAI,YAAY,IAAI,IAAI,SAAS,WAAW,KAAK,UAAU,KAAK,IAAI,CAAC,EAAE;AAC/E;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,YAAY,SAAS,WAAW,sCAAsC;AAAA,MACpF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,+BAA+B,SAAS,WAAW,KAAM,IAAc,OAAO,EAAE;AAAA,IAChG;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -2,10 +2,10 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
2
2
  import {
3
3
  LmStudioBackend,
4
4
  OllamaBackend
5
- } from "./chunk-ML6GTPZU.js";
5
+ } from "./chunk-CML4MCYF.js";
6
6
  import {
7
7
  PROVIDER_DETECT_TIMEOUT_MS
8
- } from "./chunk-7DAH5GLC.js";
8
+ } from "./chunk-CKJAWZQE.js";
9
9
 
10
10
  // src/intelligence/provider-check.ts
11
11
  async function checkLocalProvider(type, baseUrl) {
@@ -19,4 +19,4 @@ async function checkLocalProvider(type, baseUrl) {
19
19
  export {
20
20
  checkLocalProvider
21
21
  };
22
- //# sourceMappingURL=chunk-DT42247G.js.map
22
+ //# sourceMappingURL=chunk-75AZFBFW.js.map
@@ -2,7 +2,7 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
2
2
  import {
3
3
  getTeamMachineId,
4
4
  syncRow
5
- } from "./chunk-C3C5QVLK.js";
5
+ } from "./chunk-O3TRN3RC.js";
6
6
  import {
7
7
  getDatabase
8
8
  } from "./chunk-MYX5NCRH.js";
@@ -183,4 +183,4 @@ export {
183
183
  listSporeIdsSince,
184
184
  updateSporeStatus
185
185
  };
186
- //# sourceMappingURL=chunk-ZSJPI5MS.js.map
186
+ //# sourceMappingURL=chunk-7OYXB2NM.js.map
@@ -1,13 +1,13 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  getPluginVersion
4
- } from "./chunk-SI5BBQAT.js";
4
+ } from "./chunk-EO2RQW4S.js";
5
5
  import {
6
6
  DAEMON_CLIENT_TIMEOUT_MS,
7
7
  DAEMON_HEALTH_CHECK_TIMEOUT_MS,
8
8
  DAEMON_HEALTH_RETRY_DELAYS,
9
9
  DAEMON_STALE_GRACE_PERIOD_MS
10
- } from "./chunk-7DAH5GLC.js";
10
+ } from "./chunk-CKJAWZQE.js";
11
11
 
12
12
  // src/hooks/client.ts
13
13
  import fs from "fs";
@@ -185,4 +185,4 @@ export {
185
185
  resolveCliEntryPath,
186
186
  DaemonClient
187
187
  };
188
- //# sourceMappingURL=chunk-XZWFMMJR.js.map
188
+ //# sourceMappingURL=chunk-BUIR3JWM.js.map
@@ -8,6 +8,8 @@ var MYCO_GLOBAL_DIR = path.join(os.homedir(), ".myco");
8
8
  var UPDATE_CHECK_CACHE_PATH = path.join(MYCO_GLOBAL_DIR, "last-update-check.json");
9
9
  var UPDATE_CONFIG_PATH = path.join(MYCO_GLOBAL_DIR, "update.yaml");
10
10
  var UPDATE_ERROR_PATH = path.join(MYCO_GLOBAL_DIR, "update-error.json");
11
+ var UPDATE_STAMP_FILENAME = "last-update-version";
12
+ var RESTART_REASON_FILENAME = "restart-reason.json";
11
13
  var UPDATE_CHECK_INTERVAL_HOURS = 6;
12
14
  var MS_PER_HOUR = 36e5;
13
15
  var NPM_PACKAGE_NAME = "@goondocks/myco";
@@ -98,6 +100,8 @@ export {
98
100
  UPDATE_CHECK_CACHE_PATH,
99
101
  UPDATE_CONFIG_PATH,
100
102
  UPDATE_ERROR_PATH,
103
+ UPDATE_STAMP_FILENAME,
104
+ RESTART_REASON_FILENAME,
101
105
  UPDATE_CHECK_INTERVAL_HOURS,
102
106
  MS_PER_HOUR,
103
107
  NPM_PACKAGE_NAME,
@@ -175,4 +179,4 @@ export {
175
179
  WRANGLER_COMMAND_TIMEOUT_MS,
176
180
  RESTART_RESPONSE_FLUSH_MS
177
181
  };
178
- //# sourceMappingURL=chunk-7DAH5GLC.js.map
182
+ //# sourceMappingURL=chunk-CKJAWZQE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants/update.ts","../src/constants.ts"],"sourcesContent":["import path from 'node:path';\nimport os from 'node:os';\n\n/** npm registry URL for the Myco package. */\nexport const NPM_REGISTRY_URL = 'https://registry.npmjs.org/@goondocks/myco';\n\n/** Global Myco directory for machine-wide state. */\nexport const MYCO_GLOBAL_DIR = path.join(os.homedir(), '.myco');\n\n/** Path to the cached update check result. */\nexport const UPDATE_CHECK_CACHE_PATH = path.join(MYCO_GLOBAL_DIR, 'last-update-check.json');\n\n/** Path to the update configuration file (channel, interval). */\nexport const UPDATE_CONFIG_PATH = path.join(MYCO_GLOBAL_DIR, 'update.yaml');\n\n/** Path to the update error file (written by update script on failure). */\nexport const UPDATE_ERROR_PATH = path.join(MYCO_GLOBAL_DIR, 'update-error.json');\n\n/** Filename for the version stamp written by `myco update` (lives inside vault .myco/). */\nexport const UPDATE_STAMP_FILENAME = 'last-update-version';\n\n/** Filename for the restart reason signal file (lives inside vault .myco/). */\nexport const RESTART_REASON_FILENAME = 'restart-reason.json';\n\n/** Default check interval in hours. */\nexport const UPDATE_CHECK_INTERVAL_HOURS = 6;\n\n/** Milliseconds per hour. */\nexport const MS_PER_HOUR = 3_600_000;\n\n/** npm package name. */\nexport const NPM_PACKAGE_NAME = '@goondocks/myco';\n\n/** Delay in seconds before update script starts (allows daemon to exit). */\nexport const UPDATE_SCRIPT_DELAY_SECONDS = 2;\n\n/** Valid release channels. */\nexport const RELEASE_CHANNELS = ['stable', 'beta'] as const;\nexport type ReleaseChannel = (typeof RELEASE_CHANNELS)[number];\n\n/** Default release channel. */\nexport const DEFAULT_RELEASE_CHANNEL: ReleaseChannel = 'stable';\n","/**\n * Shared constants for the Myco codebase.\n * Per CLAUDE.md: \"No Magic Literals — Numeric and string constants\n * MUST NOT appear inline in logic.\"\n */\n\nexport { LOG_KINDS, type LogKind, kindToComponent } from './constants/log-kinds.js';\n\n// --- Agent phase prompt composition ---\n/**\n * Maximum chars per phase summary passed to subsequent phases.\n * Set to 4000 to ensure the digest-assess phase findings pass\n * untruncated to parallel tier phases.\n */\nexport const PHASE_SUMMARY_MAX_CHARS = 4000;\n\n// --- Token estimation ---\n/** Approximate characters per token for the chars/4 heuristic. */\nexport const CHARS_PER_TOKEN = 4;\n\n/** Estimate token count from character length using the CHARS_PER_TOKEN heuristic. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\n// --- Time (primitives — must precede derived constants) ---\n/** Milliseconds per second. */\nexport const MS_PER_SECOND = 1000;\n\n// --- Embedding ---\n/** Max characters of text sent to the embedding model. */\nexport const EMBEDDING_INPUT_LIMIT = 8000;\n\n/** Max rows per embedding worker cycle. */\nexport const EMBEDDING_BATCH_SIZE = 10;\n\n/** Content hash algorithm for staleness detection. */\nexport const CONTENT_HASH_ALGORITHM = 'sha256';\n\n// --- Truncation limits (display/preview) ---\n/** Max chars for a user prompt preview in event summaries. */\nexport const PROMPT_PREVIEW_CHARS = 300;\n/** Max chars for an AI response preview in event summaries. */\nexport const AI_RESPONSE_PREVIEW_CHARS = 500;\n/** Max chars for a command string preview. */\nexport const COMMAND_PREVIEW_CHARS = 80;\n/** Max chars for a content snippet in search results. */\nexport const CONTENT_SNIPPET_CHARS = 120;\n/** Max chars for a tool output preview in hooks. */\nexport const TOOL_OUTPUT_PREVIEW_CHARS = 200;\n/** Max chars for a session summary preview in MCP tools. */\nexport const SESSION_SUMMARY_PREVIEW_CHARS = 300;\n/** Max chars for a recall summary preview. */\nexport const RECALL_SUMMARY_PREVIEW_CHARS = 200;\n/** Max chars for search result and hydrated context previews. */\nexport const SEARCH_PREVIEW_CHARS = 300;\n\n// --- Log preview limits (short previews for structured log fields) ---\n/** Max chars for a user prompt preview in log entries. */\nexport const LOG_PROMPT_PREVIEW_CHARS = 50;\n/** Max chars for an assistant message preview in log entries. */\nexport const LOG_MESSAGE_PREVIEW_CHARS = 80;\n\n// --- Context injection layer budgets (chars, not tokens — used with .slice()) ---\nexport const CONTEXT_SESSION_PREVIEW_CHARS = 80;\nexport const CONTEXT_SPORE_PREVIEW_CHARS = 80;\n\n// --- Processor maxTokens budgets ---\n/** Response token budget for observation extraction. */\nexport const EXTRACTION_MAX_TOKENS = 2048;\n/** Response token budget for session summary. */\nexport const SUMMARY_MAX_TOKENS = 512;\n/** Response token budget for session title generation. */\nexport const TITLE_MAX_TOKENS = 32;\n\n// --- Timeouts ---\n/** Daemon client HTTP request timeout (ms). */\nexport const DAEMON_CLIENT_TIMEOUT_MS = 2000;\n/** Health check timeout (ms) — fail fast if daemon isn't responding. */\nexport const DAEMON_HEALTH_CHECK_TIMEOUT_MS = 500;\n/** LLM request timeout (ms). All LLM calls are background daemon work — no need to be aggressive. */\nexport const LLM_REQUEST_TIMEOUT_MS = 180_000;\n/** Embedding request timeout (ms). Embeddings run in background batch processing — generous timeout. */\nexport const EMBEDDING_REQUEST_TIMEOUT_MS = 60_000;\n/** Digest LLM request timeout (ms). Digest cycles use large context windows and may need model loading time. */\nexport const DIGEST_LLM_REQUEST_TIMEOUT_MS = 600_000;\n/** Stdin read timeout for hooks (ms). */\nexport const STDIN_TIMEOUT_MS = 100;\n/** Provider detection timeout for detect-providers CLI command (ms). */\nexport const PROVIDER_DETECT_TIMEOUT_MS = 3000;\n\n// --- Time ---\n/** Milliseconds in one day. */\nexport const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/** Current Unix epoch in seconds. */\nexport function epochSeconds(): number {\n return Math.floor(Date.now() / MS_PER_SECOND);\n}\n\n// --- Buffer cleanup ---\n/** Max age for stale buffer files before cleanup (ms). */\nexport const STALE_BUFFER_MAX_AGE_MS = 1 * MS_PER_DAY;\n\n// --- Retry backoff ---\n/** Retry delays for daemon health check (ms). */\nexport const DAEMON_HEALTH_RETRY_DELAYS = [100, 200, 400, 800, 1500];\n\n/** Grace period after daemon.json is written before stale checks can trigger a restart (ms).\n * Prevents rapid restart loops from concurrent hooks or session reloads. */\nexport const DAEMON_STALE_GRACE_PERIOD_MS = 60_000;\n\n/** Grace period for SIGTERM before escalating to SIGKILL (ms).\n * Gives the old daemon a chance to shut down cleanly, but force-kills\n * to guarantee the configured port is reclaimed. */\nexport const DAEMON_EVICT_TIMEOUT_MS = 3000;\n/** Poll interval when waiting for an evicted daemon to die (ms). */\nexport const DAEMON_EVICT_POLL_MS = 100;\n\n// --- Slug limits ---\n/** Max length for slugified artifact IDs. */\n\n// --- Turn rendering ---\n/** Max file paths displayed per turn in session notes. */\nexport const TURN_MAX_FILES_DISPLAYED = 10;\n\n// --- Transcript mining ---\n/** Minimum content length to consider a transcript entry meaningful. */\nexport const MIN_TRANSCRIPT_CONTENT_LENGTH = 10;\n\n// --- Graph edge types (lineage — auto-created by daemon) ---\n/** Spore was extracted during this session. */\nexport const EDGE_TYPE_FROM_SESSION = 'FROM_SESSION';\n/** Spore was extracted from this prompt batch. */\nexport const EDGE_TYPE_EXTRACTED_FROM = 'EXTRACTED_FROM';\n/** Wisdom spore was derived from (consolidated) this source spore. */\nexport const EDGE_TYPE_DERIVED_FROM = 'DERIVED_FROM';\n/** Session contains this prompt batch. */\nexport const EDGE_TYPE_HAS_BATCH = 'HAS_BATCH';\n// --- Query defaults ---\n/** Default row limit for query module list operations. */\nexport const QUERY_DEFAULT_LIST_LIMIT = 100;\n/** Default LIMIT for paginated list queries. */\nexport const DEFAULT_LIST_LIMIT = 50;\n/** Default confidence score for graph edges. */\nexport const GRAPH_EDGE_DEFAULT_CONFIDENCE = 1.0;\n\n// --- Query limits ---\n/** Max recent sessions to check for lineage heuristics. */\nexport const LINEAGE_RECENT_SESSIONS_LIMIT = 5;\n/** Max related spores to query for session notes. */\nexport const RELATED_SPORES_LIMIT = 50;\n\n// --- Context injection ---\n/** Max spores to inject per prompt. */\nexport const PROMPT_CONTEXT_MAX_SPORES = 3;\n/** Minimum similarity score for prompt context injection (0-1). */\nexport const PROMPT_CONTEXT_MIN_SIMILARITY = 0.3;\n/** Max token budget for session-start context injection. */\nexport const SESSION_CONTEXT_MAX_TOKENS = 500;\n/** Max token budget for per-prompt context injection. */\nexport const PROMPT_CONTEXT_MAX_TOKENS = 300;\n/** Minimum prompt length to trigger context search. */\nexport const PROMPT_CONTEXT_MIN_LENGTH = 10;\n\n/** Over-fetch multiplier for vector search to compensate for post-filtering. */\nexport const PROMPT_VECTOR_OVER_FETCH = 2;\n\n// --- Spore status filtering ---\n/** Spore statuses excluded from search results and context injection. */\nexport const EXCLUDED_SPORE_STATUSES = new Set(['superseded', 'archived']);\n\n// --- Agent identity ---\n/** Default agent ID for the built-in intelligence agent. */\nexport const DEFAULT_AGENT_ID = 'myco-agent';\n/** Agent ID for user-initiated MCP operations. */\nexport const USER_AGENT_ID = 'user';\n/** Agent name for user-initiated MCP operations. */\nexport const USER_AGENT_NAME = 'User (MCP)';\n\n// --- MCP tool defaults ---\n/** Default result limit for myco_search. */\nexport const MCP_SEARCH_DEFAULT_LIMIT = 10;\n/** Default result limit for myco_sessions. */\nexport const MCP_SESSIONS_DEFAULT_LIMIT = 20;\n/** Default result limit for myco_logs. */\nexport const MCP_LOGS_DEFAULT_LIMIT = 50;\n/** Default result limit for myco_skills and myco_skill_candidates. */\nexport const MCP_SKILLS_DEFAULT_LIMIT = 50;\n\n// --- Feed ---\n/** Default number of entries returned by the activity feed. */\nexport const FEED_DEFAULT_LIMIT = 50;\n\n// --- Digest — Tiers ---\n/** Available token-budget tiers for digest synthesis. */\nexport const DIGEST_TIERS = [1500, 5000, 10000] as const;\nexport type DigestTier = (typeof DIGEST_TIERS)[number];\n\n// --- Digest — Context window minimums per tier ---\n/** Minimum context window (tokens) required to run a digest at a given tier. */\nexport const DIGEST_TIER_MIN_CONTEXT: Record<number, number> = {\n 1500: 6500,\n 5000: 18500,\n 10000: 30500,\n};\n\n// --- Digest — Substrate ---\n/** Default minimum substrate notes required before a digest cycle runs. */\nexport const DIGEST_MIN_NOTES_FOR_CYCLE = 10;\n\n/** Scoring weights by note type when selecting substrate for synthesis. */\nexport const DIGEST_SUBSTRATE_TYPE_WEIGHTS: Record<string, number> = {\n session: 3,\n spore: 3,\n plan: 2,\n artifact: 1,\n team: 1,\n};\n\n// --- LLM reasoning control ---\n/** Reasoning mode for all Myco LLM calls. Suppresses chain-of-thought tokens from reasoning models. */\nexport const LLM_REASONING_MODE = 'off' as const;\n\n// --- Digest — System prompt overhead estimate ---\n\n// --- Vault intelligence ---\n/** Max candidate spores after post-filtering for supersession check. */\nexport const SUPERSESSION_CANDIDATE_LIMIT = 5;\n\n/** Over-fetch from vector index before post-filtering by status/type. */\nexport const SUPERSESSION_VECTOR_FETCH_LIMIT = 20;\n\n/** Max output tokens for supersession LLM evaluation. */\nexport const SUPERSESSION_MAX_TOKENS = 256;\n\n/** Similarity threshold for clustering related spores in batch agent processing. */\nexport const AGENT_CLUSTER_SIMILARITY = 0.75;\n\n// --- Search ---\n/** Default number of results returned by vector search and fullTextSearch. */\nexport const SEARCH_RESULTS_DEFAULT_LIMIT = 20;\n/** Minimum cosine similarity score for semantic search results (0-1). */\nexport const SEARCH_SIMILARITY_THRESHOLD = 0.3;\n\n// --- Pipeline processing ---\n/** Default page size for pipeline items API listing. */\nexport const PIPELINE_ITEMS_DEFAULT_LIMIT = 50;\n\n// --- Pipeline retry ---\n/** Max retries for parse (structural) pipeline failures — fail fast. */\nexport const PIPELINE_PARSE_MAX_RETRIES = 1;\n/** Exponential backoff multiplier for successive pipeline retries. */\nexport const PIPELINE_BACKOFF_MULTIPLIER = 4;\n\n// --- Pipeline stages (ordered) ---\nexport const PIPELINE_STAGES = ['capture', 'extraction', 'embedding', 'consolidation', 'digest'] as const;\nexport type PipelineStage = typeof PIPELINE_STAGES[number];\n\n// --- Pipeline statuses ---\nexport const PIPELINE_STATUSES = ['pending', 'processing', 'succeeded', 'failed', 'blocked', 'skipped', 'poisoned'] as const;\nexport type PipelineStatus = typeof PIPELINE_STATUSES[number];\n\n// --- Provider roles for circuit breakers ---\nexport const PIPELINE_PROVIDER_ROLES = ['llm', 'embedding', 'digest-llm'] as const;\nexport type PipelineProviderRole = typeof PIPELINE_PROVIDER_ROLES[number];\n\n// --- Stage to provider role mapping ---\nexport const STAGE_PROVIDER_MAP: Record<PipelineStage, PipelineProviderRole | null> = {\n capture: null,\n extraction: 'llm',\n embedding: 'embedding',\n consolidation: 'digest-llm',\n digest: 'digest-llm',\n};\n\n/**\n * Stages processed by the pipeline tick timer.\n * Capture is handled at registration time, digest is gated by the metabolism timer.\n */\nexport const PIPELINE_TICK_STAGES: PipelineStage[] = ['extraction', 'embedding', 'consolidation'];\n\n// --- Item type to applicable stages ---\n// Sessions skip consolidation — consolidation applies to the spores\n// extracted FROM sessions, not the session work item itself.\n// Lineage detection stays outside the pipeline (fire-and-forget, non-critical).\nexport const ITEM_STAGE_MAP: Record<string, PipelineStage[]> = {\n session: ['capture', 'extraction', 'embedding', 'digest'],\n spore: ['capture', 'embedding', 'consolidation', 'digest'],\n artifact: ['capture', 'embedding', 'digest'],\n};\n\n// --- User task registry ---\n/** Subdirectory within the vault for user-created task YAML files. */\nexport const USER_TASKS_DIR = 'tasks';\n\n/** Source label for user-created tasks. */\nexport const USER_TASK_SOURCE = 'user';\n\n/** Source label for built-in tasks shipped with the package. */\nexport const BUILT_IN_SOURCE = 'built-in';\n\n/** Task name validation pattern (lowercase, hyphens, digits). */\nexport const TASK_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;\n\n/** Maximum length for task names. */\nexport const MAX_TASK_NAME_LENGTH = 50;\n\n// --- Automatic consolidation ---\n/** Minimum cluster size required before asking LLM to consolidate. */\nexport const CONSOLIDATION_MIN_CLUSTER_SIZE = 3;\n\n/** Over-fetch from vector index before post-filtering by status/type. */\nexport const CONSOLIDATION_VECTOR_FETCH_LIMIT = 20;\n\n/** Max output tokens for consolidation LLM synthesis.\n * Must be large enough for the full JSON response including content field. */\nexport const CONSOLIDATION_MAX_TOKENS = 2048;\n\n// --- Power management ---\n/** PowerManager states valid for task scheduling (excludes deep_sleep which halts all ticks). */\nexport const SCHEDULABLE_POWER_STATES = ['active', 'idle', 'sleep'] as const;\nexport type SchedulablePowerState = typeof SCHEDULABLE_POWER_STATES[number];\n\n/** Time without activity before transitioning to idle (ms). */\nexport const POWER_IDLE_THRESHOLD_MS = 5 * 60 * MS_PER_SECOND;\n/** Time without activity before transitioning to sleep (ms). */\nexport const POWER_SLEEP_THRESHOLD_MS = 30 * 60 * MS_PER_SECOND;\n/** Time without activity before transitioning to deep sleep (ms). */\nexport const POWER_DEEP_SLEEP_THRESHOLD_MS = 90 * 60 * MS_PER_SECOND;\n/** Job cycle interval during active/idle states (ms). */\nexport const POWER_ACTIVE_INTERVAL_MS = 60 * MS_PER_SECOND;\n/** Job cycle interval during sleep state (ms). */\nexport const POWER_SLEEP_INTERVAL_MS = 5 * 60 * MS_PER_SECOND;\n\n// --- Session maintenance ---\n/** Time without new prompts before an active session is auto-completed (ms). */\nexport const STALE_SESSION_THRESHOLD_MS = 60 * 60 * MS_PER_SECOND;\n/**\n * Max prompt count for a session to be considered dead and auto-deleted.\n *\n * Set to 0: only sessions that were registered but never received a prompt\n * are eligible for dead-session cleanup. A session with even ONE real user\n * prompt has produced captured state worth preserving — the user did work,\n * the agent likely responded, tool calls may have happened, code may have\n * changed. Deleting such a session was a real data-loss failure mode seen\n * during opencode testing where a 1-prompt session that made an actual\n * committed code change was auto-deleted within a minute of TUI exit.\n */\nexport const DEAD_SESSION_MAX_PROMPTS = 0;\n\n// --- Init wizard ---\n/** Minimum Node.js major version required by Myco. */\nexport const MIN_NODE_MAJOR_VERSION = 22;\n\n/** Recommended context window for local intelligence models. */\nexport const RECOMMENDED_LOCAL_CONTEXT_WINDOW = 8192;\n\n/** Default Ollama embedding model recommended during init. */\nexport const DEFAULT_OLLAMA_EMBEDDING_MODEL = 'bge-m3';\n\n/** Default OpenAI embedding model recommended during init. */\nexport const DEFAULT_OPENAI_EMBEDDING_MODEL = 'text-embedding-3-small';\n\n// --- Sync protocol ---\n/** Protocol version for backup and team sync wire format. */\nexport const SYNC_PROTOCOL_VERSION = 1;\n\n// --- Team sync ---\n/** Default machine ID for rows created before multi-machine support. */\nexport const DEFAULT_MACHINE_ID = 'local';\n/** Prefix for team search result source attribution. */\nexport const TEAM_SOURCE_PREFIX = 'team:';\n/** Timeout for team search requests (ms). */\nexport const TEAM_SEARCH_TIMEOUT_MS = 3000;\n/** Timeout for team health check requests (ms). */\nexport const TEAM_HEALTH_TIMEOUT_MS = 5000;\n/** Secrets key for the team API key in secrets.env. */\nexport const TEAM_API_KEY_SECRET = 'MYCO_TEAM_API_KEY';\n/** Timeout for wrangler CLI commands (ms). */\nexport const WRANGLER_COMMAND_TIMEOUT_MS = 60_000;\n\n// --- HTTP response flush ---\n/** Delay before initiating shutdown — allows the HTTP response to flush. */\nexport const RESTART_RESPONSE_FLUSH_MS = 500;\n\n// --- Self-update ---\nexport {\n NPM_REGISTRY_URL,\n MYCO_GLOBAL_DIR,\n UPDATE_CHECK_CACHE_PATH,\n UPDATE_CONFIG_PATH,\n UPDATE_ERROR_PATH,\n UPDATE_CHECK_INTERVAL_HOURS,\n MS_PER_HOUR,\n NPM_PACKAGE_NAME,\n UPDATE_SCRIPT_DELAY_SECONDS,\n RELEASE_CHANNELS,\n DEFAULT_RELEASE_CHANNEL,\n type ReleaseChannel,\n} from './constants/update.js';\n"],"mappings":";;;AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAGR,IAAM,mBAAmB;AAGzB,IAAM,kBAAkB,KAAK,KAAK,GAAG,QAAQ,GAAG,OAAO;AAGvD,IAAM,0BAA0B,KAAK,KAAK,iBAAiB,wBAAwB;AAGnF,IAAM,qBAAqB,KAAK,KAAK,iBAAiB,aAAa;AAGnE,IAAM,oBAAoB,KAAK,KAAK,iBAAiB,mBAAmB;AAGxE,IAAM,wBAAwB;AAG9B,IAAM,0BAA0B;AAGhC,IAAM,8BAA8B;AAGpC,IAAM,cAAc;AAGpB,IAAM,mBAAmB;AAGzB,IAAM,8BAA8B;AAGpC,IAAM,mBAAmB,CAAC,UAAU,MAAM;AAI1C,IAAM,0BAA0C;;;AC3BhD,IAAM,0BAA0B;AAIhC,IAAM,kBAAkB;AAGxB,SAAS,eAAe,MAAsB;AACnD,SAAO,KAAK,KAAK,KAAK,SAAS,eAAe;AAChD;AAIO,IAAM,gBAAgB;AAOtB,IAAM,uBAAuB;AAG7B,IAAM,yBAAyB;AAI/B,IAAM,uBAAuB;AAM7B,IAAM,wBAAwB;AAE9B,IAAM,4BAA4B;AAMlC,IAAM,uBAAuB;AAI7B,IAAM,2BAA2B;AAEjC,IAAM,4BAA4B;AAGlC,IAAM,gCAAgC;AACtC,IAAM,8BAA8B;AAYpC,IAAM,2BAA2B;AAEjC,IAAM,iCAAiC;AAEvC,IAAM,yBAAyB;AAE/B,IAAM,+BAA+B;AAIrC,IAAM,mBAAmB;AAEzB,IAAM,6BAA6B;AAInC,IAAM,aAAa,KAAK,KAAK,KAAK;AAGlC,SAAS,eAAuB;AACrC,SAAO,KAAK,MAAM,KAAK,IAAI,IAAI,aAAa;AAC9C;AAIO,IAAM,0BAA0B,IAAI;AAIpC,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI;AAI5D,IAAM,+BAA+B;AAKrC,IAAM,0BAA0B;AAEhC,IAAM,uBAAuB;AAe7B,IAAM,yBAAyB;AAE/B,IAAM,2BAA2B;AAEjC,IAAM,yBAAyB;AAE/B,IAAM,sBAAsB;AAG5B,IAAM,2BAA2B;AAEjC,IAAM,qBAAqB;AAE3B,IAAM,gCAAgC;AAYtC,IAAM,gCAAgC;AAItC,IAAM,4BAA4B;AAElC,IAAM,4BAA4B;AAGlC,IAAM,2BAA2B;AAIjC,IAAM,0BAA0B,oBAAI,IAAI,CAAC,cAAc,UAAU,CAAC;AAIlE,IAAM,mBAAmB;AAEzB,IAAM,gBAAgB;AAEtB,IAAM,kBAAkB;AAIxB,IAAM,2BAA2B;AAEjC,IAAM,6BAA6B;AAInC,IAAM,2BAA2B;AAIjC,IAAM,qBAAqB;AAI3B,IAAM,eAAe,CAAC,MAAM,KAAM,GAAK;AA6CvC,IAAM,+BAA+B;AAErC,IAAM,8BAA8B;AAmDpC,IAAM,iBAAiB;AAGvB,IAAM,mBAAmB;AAGzB,IAAM,kBAAkB;AAGxB,IAAM,oBAAoB;AAG1B,IAAM,uBAAuB;AAe7B,IAAM,2BAA2B,CAAC,UAAU,QAAQ,OAAO;AAI3D,IAAM,0BAA0B,IAAI,KAAK;AAEzC,IAAM,2BAA2B,KAAK,KAAK;AAE3C,IAAM,gCAAgC,KAAK,KAAK;AAEhD,IAAM,2BAA2B,KAAK;AAEtC,IAAM,0BAA0B,IAAI,KAAK;AAIzC,IAAM,6BAA6B,KAAK,KAAK;AAY7C,IAAM,2BAA2B;AAUjC,IAAM,iCAAiC;AAOvC,IAAM,wBAAwB;AAI9B,IAAM,qBAAqB;AAE3B,IAAM,qBAAqB;AAE3B,IAAM,yBAAyB;AAE/B,IAAM,yBAAyB;AAE/B,IAAM,sBAAsB;AAE5B,IAAM,8BAA8B;AAIpC,IAAM,4BAA4B;","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  DAEMON_CLIENT_TIMEOUT_MS,
4
4
  EMBEDDING_REQUEST_TIMEOUT_MS,
5
5
  LLM_REQUEST_TIMEOUT_MS
6
- } from "./chunk-7DAH5GLC.js";
6
+ } from "./chunk-CKJAWZQE.js";
7
7
 
8
8
  // src/intelligence/ollama.ts
9
9
  var ENDPOINT_GENERATE = "/api/generate";
@@ -325,4 +325,4 @@ export {
325
325
  OllamaBackend,
326
326
  LmStudioBackend
327
327
  };
328
- //# sourceMappingURL=chunk-ML6GTPZU.js.map
328
+ //# sourceMappingURL=chunk-CML4MCYF.js.map
@@ -1,16 +1,16 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  isProcessAlive
4
- } from "./chunk-CTF7TQMJ.js";
4
+ } from "./chunk-55QEICRO.js";
5
5
  import {
6
6
  loadConfig
7
- } from "./chunk-XD3NEN3Q.js";
7
+ } from "./chunk-2V7HR7HB.js";
8
8
  import {
9
9
  getDatabase
10
10
  } from "./chunk-MYX5NCRH.js";
11
11
  import {
12
12
  DIGEST_TIERS
13
- } from "./chunk-7DAH5GLC.js";
13
+ } from "./chunk-CKJAWZQE.js";
14
14
 
15
15
  // src/db/queries/embeddings.ts
16
16
  var EMBEDDABLE_TABLES = ["sessions", "spores", "plans", "artifacts"];
@@ -184,4 +184,4 @@ export {
184
184
  getEmbeddingQueueDepth,
185
185
  gatherStats
186
186
  };
187
- //# sourceMappingURL=chunk-BZDZORVP.js.map
187
+ //# sourceMappingURL=chunk-DLFDBKEV.js.map
@@ -11,7 +11,7 @@ var cached;
11
11
  function getPluginVersion() {
12
12
  if (cached) return cached;
13
13
  if (true) {
14
- cached = "0.17.2";
14
+ cached = "0.18.0";
15
15
  return cached;
16
16
  }
17
17
  const root = findPackageRoot(path.dirname(fileURLToPath(import.meta.url)));
@@ -32,4 +32,4 @@ function getPluginVersion() {
32
32
  export {
33
33
  getPluginVersion
34
34
  };
35
- //# sourceMappingURL=chunk-SI5BBQAT.js.map
35
+ //# sourceMappingURL=chunk-EO2RQW4S.js.map
@@ -13,8 +13,26 @@ import {
13
13
  } from "./chunk-PZUWP5VK.js";
14
14
 
15
15
  // src/symbionts/manifest-schema.ts
16
+ var CaptureRuleSchema = external_exports.object({
17
+ event: external_exports.enum(["session_start", "user_prompt"]),
18
+ scope: external_exports.enum(["this_agent", "any_agent"]).default("this_agent"),
19
+ when: external_exports.object({
20
+ prompt_starts_with: external_exports.string().optional(),
21
+ prompt_contains: external_exports.string().optional(),
22
+ /** Structural: fires when transcript_path is absent or empty. */
23
+ transcript_path_missing: external_exports.boolean().optional()
24
+ }),
25
+ action: external_exports.enum(["drop", "rewrite_prompt"]),
26
+ /** Short audit string logged when the rule matches (e.g., "codex-internal-title-gen"). */
27
+ reason: external_exports.string().optional(),
28
+ /** For rewrite_prompt: keep only the substring after this marker (first occurrence). */
29
+ extract_after: external_exports.string().optional(),
30
+ /** For rewrite_prompt: trim whitespace from the extracted substring. Default true. */
31
+ trim: external_exports.boolean().default(true)
32
+ });
16
33
  var CaptureManifestSchema = external_exports.object({
17
- planDirs: external_exports.array(external_exports.string()).default([])
34
+ planDirs: external_exports.array(external_exports.string()).default([]),
35
+ rules: external_exports.array(CaptureRuleSchema).default([])
18
36
  });
19
37
  var RegistrationSchema = external_exports.object({
20
38
  hooksTarget: external_exports.string().optional(),
@@ -127,4 +145,4 @@ export {
127
145
  detectSymbionts,
128
146
  resolvePackageRoot
129
147
  };
130
- //# sourceMappingURL=chunk-EBIYONNZ.js.map
148
+ //# sourceMappingURL=chunk-FABWUX5G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/symbionts/manifest-schema.ts","../src/symbionts/detect.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Declarative capture rules owned per-symbiont in its YAML manifest.\n *\n * Rules let each symbiont describe how Myco should filter or rewrite\n * captured events *without* adding symbiont-specific branches inside\n * the generic hook handlers. The hook loads the rules, a generic\n * evaluator decides the action, and the hook acts on the result.\n *\n * Condition types (in `when`):\n * - `transcript_path_missing`: structural. Fires when the hook's\n * transcript_path field is absent/empty. A legitimate user-facing\n * session records a transcript; an ephemeral sub-invocation (e.g.,\n * an agent's internal title-generation call) does not. Preferred\n * over text matching because it doesn't drift as UIs evolve.\n * - `prompt_starts_with` / `prompt_contains`: text fallback. Use\n * when no structural signal is available. Document the upgrade path\n * in the YAML so future maintainers can replace it when a better\n * signal appears.\n *\n * Scope semantics:\n * - `this_agent` (default): rule fires only when the detected agent\n * matches the manifest that owns the rule. Use for behavior that\n * is specific to the symbiont and can rely on detection working.\n * - `any_agent`: rule fires regardless of detected agent. Use for\n * patterns where detection itself might fail — e.g., an internal\n * sub-invocation that omits the fields agent detection keys on.\n *\n * Events:\n * - `session_start`: fires on SessionStart, before any prompts or\n * tools are captured. The right place to catch ephemeral sub-\n * invocations so they're never registered as sessions at all.\n * - `user_prompt`: fires on UserPromptSubmit. Safety net for anything\n * that slips past session_start, and the only layer where\n * `rewrite_prompt` makes sense (prompt text doesn't exist until\n * the prompt is submitted).\n *\n * Actions:\n * - `drop`: discard the event entirely. For session_start, the hook\n * skips registering the session row. For user_prompt, the hook\n * skips posting the event and cascade-deletes any session row that\n * may have been registered before the drop rule could fire.\n * - `rewrite_prompt`: replace the captured prompt with the substring\n * after `extract_after`. Only valid for `user_prompt` events.\n */\nconst CaptureRuleSchema = z.object({\n event: z.enum(['session_start', 'user_prompt']),\n scope: z.enum(['this_agent', 'any_agent']).default('this_agent'),\n when: z.object({\n prompt_starts_with: z.string().optional(),\n prompt_contains: z.string().optional(),\n /** Structural: fires when transcript_path is absent or empty. */\n transcript_path_missing: z.boolean().optional(),\n }),\n action: z.enum(['drop', 'rewrite_prompt']),\n /** Short audit string logged when the rule matches (e.g., \"codex-internal-title-gen\"). */\n reason: z.string().optional(),\n /** For rewrite_prompt: keep only the substring after this marker (first occurrence). */\n extract_after: z.string().optional(),\n /** For rewrite_prompt: trim whitespace from the extracted substring. Default true. */\n trim: z.boolean().default(true),\n});\n\nexport type CaptureRule = z.infer<typeof CaptureRuleSchema>;\n\nconst CaptureManifestSchema = z.object({\n planDirs: z.array(z.string()).default([]),\n rules: z.array(CaptureRuleSchema).default([]),\n});\n\nconst RegistrationSchema = z.object({\n hooksTarget: z.string().optional(),\n /**\n * Format of the hooks target.\n * - 'json' (default): hooks template is merged into a JSON settings file.\n * - 'plugin-file': the hooks template is a verbatim file (e.g., an opencode TS plugin)\n * copied to hooksTarget without JSON parsing. Used for agents with plugin-based hook\n * systems rather than JSON hook entries.\n */\n hooksFormat: z.enum(['json', 'plugin-file']).default('json'),\n /**\n * Optional file path for a plugin deps package.json. When set, the installer writes\n * a package.json declaring the plugin SDK dependency so the agent's package manager\n * (e.g., opencode's Bun) can install it at startup. Preserved on uninstall so\n * contributors can keep their own deps.\n */\n pluginPackageTarget: z.string().optional(),\n mcpTarget: z.string().optional(),\n mcpFormat: z.enum(['json', 'toml']).default('json'),\n /**\n * JSON key under which MCP server entries are stored in the MCP config file.\n * Defaults to 'mcpServers' (used by Claude Code, Cursor, etc.). opencode uses 'mcp'.\n */\n mcpServersKey: z.string().default('mcpServers'),\n skillsTarget: z.string().optional(),\n settingsTarget: z.string().optional(),\n /** Format of the settings file. TOML-format agents (e.g., Codex) emit top-level template keys as TOML sections. */\n settingsFormat: z.enum(['json', 'toml']).default('json'),\n /** Instruction file that stubs out to AGENTS.md. Only for agents that don't read AGENTS.md natively. */\n instructionsFile: z.string().optional(),\n});\n\nexport const SymbiontManifestSchema = z.object({\n name: z.string(),\n displayName: z.string(),\n binary: z.string(),\n configDir: z.string(),\n pluginRootEnvVar: z.string(),\n settingsPath: z.string().optional(),\n hookFields: z.object({\n sessionId: z.string(),\n transcriptPath: z.string(),\n lastResponse: z.string(),\n prompt: z.string().default('prompt'),\n toolName: z.string().default('tool_name'),\n toolInput: z.string().default('tool_input'),\n toolOutput: z.string().default('tool_output'),\n /** Env var fallback for session ID (e.g., GEMINI_SESSION_ID). */\n sessionIdEnv: z.string().optional(),\n }),\n /** Resume command template with {sessionId} placeholder. Omit for IDE-based agents. */\n resumeCommand: z.string().optional(),\n capture: CaptureManifestSchema.optional(),\n registration: RegistrationSchema.optional(),\n});\n\nexport type SymbiontManifest = z.infer<typeof SymbiontManifestSchema>;\nexport type SymbiontRegistration = z.infer<typeof RegistrationSchema>;\n","import { SymbiontManifestSchema, type SymbiontManifest } from './manifest-schema.js';\nimport { findPackageRoot } from '../utils/find-package-root.js';\nimport { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\n\nexport interface DetectedSymbiont {\n manifest: SymbiontManifest;\n binaryFound: boolean;\n configDirFound: boolean;\n}\n\nconst MANIFESTS_SUBDIR = 'symbionts/manifests';\n\n/** Cached manifests — static files that never change at runtime. */\nlet manifestCache: SymbiontManifest[] | null = null;\n\n/** Load all symbiont manifests from the package's dist directory. */\nexport function loadManifests(): SymbiontManifest[] {\n if (manifestCache) return manifestCache;\n const candidates = [\n // Source layout: src/symbionts/detect.ts → src/symbionts/manifests/\n path.resolve(import.meta.dirname, MANIFESTS_SUBDIR),\n // Dist layout: dist/src/symbionts/ → dist/src/symbionts/manifests/\n // (or dist/src/daemon/ → dist/src/symbionts/manifests/)\n path.resolve(import.meta.dirname, '..', MANIFESTS_SUBDIR),\n path.resolve(import.meta.dirname, '..', '..', MANIFESTS_SUBDIR),\n // Chunk layout: dist/chunk-*.js → dist/src/symbionts/manifests/\n path.resolve(import.meta.dirname, 'src', MANIFESTS_SUBDIR),\n ];\n\n for (const dir of candidates) {\n if (!fs.existsSync(dir)) continue;\n const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml'));\n if (files.length === 0) continue;\n manifestCache = files.map(f => {\n const raw = YAML.parse(fs.readFileSync(path.join(dir, f), 'utf-8'));\n return SymbiontManifestSchema.parse(raw);\n });\n return manifestCache;\n }\n return [];\n}\n\n/** Check if a binary is available on PATH. */\nfunction isBinaryOnPath(binary: string): boolean {\n try {\n execFileSync('which', [binary], { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n/** Detect which symbionts are available for a project. */\nexport function detectSymbionts(projectRoot: string): DetectedSymbiont[] {\n const manifests = loadManifests();\n return manifests.map(manifest => ({\n manifest,\n binaryFound: isBinaryOnPath(manifest.binary),\n configDirFound: fs.existsSync(path.join(projectRoot, manifest.configDir)),\n })).filter(d => d.binaryFound || d.configDirFound);\n}\n\n/** Find the Myco package root (where package.json lives). */\nexport function resolvePackageRoot(): string {\n return findPackageRoot(import.meta.dirname) ?? process.cwd();\n}\n"],"mappings":";;;;;;;;;;;;;;;AA8CA,IAAM,oBAAoB,iBAAE,OAAO;AAAA,EACjC,OAAO,iBAAE,KAAK,CAAC,iBAAiB,aAAa,CAAC;AAAA,EAC9C,OAAO,iBAAE,KAAK,CAAC,cAAc,WAAW,CAAC,EAAE,QAAQ,YAAY;AAAA,EAC/D,MAAM,iBAAE,OAAO;AAAA,IACb,oBAAoB,iBAAE,OAAO,EAAE,SAAS;AAAA,IACxC,iBAAiB,iBAAE,OAAO,EAAE,SAAS;AAAA;AAAA,IAErC,yBAAyB,iBAAE,QAAQ,EAAE,SAAS;AAAA,EAChD,CAAC;AAAA,EACD,QAAQ,iBAAE,KAAK,CAAC,QAAQ,gBAAgB,CAAC;AAAA;AAAA,EAEzC,QAAQ,iBAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE5B,eAAe,iBAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEnC,MAAM,iBAAE,QAAQ,EAAE,QAAQ,IAAI;AAChC,CAAC;AAID,IAAM,wBAAwB,iBAAE,OAAO;AAAA,EACrC,UAAU,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxC,OAAO,iBAAE,MAAM,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,IAAM,qBAAqB,iBAAE,OAAO;AAAA,EAClC,aAAa,iBAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjC,aAAa,iBAAE,KAAK,CAAC,QAAQ,aAAa,CAAC,EAAE,QAAQ,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3D,qBAAqB,iBAAE,OAAO,EAAE,SAAS;AAAA,EACzC,WAAW,iBAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,iBAAE,KAAK,CAAC,QAAQ,MAAM,CAAC,EAAE,QAAQ,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlD,eAAe,iBAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EAC9C,cAAc,iBAAE,OAAO,EAAE,SAAS;AAAA,EAClC,gBAAgB,iBAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEpC,gBAAgB,iBAAE,KAAK,CAAC,QAAQ,MAAM,CAAC,EAAE,QAAQ,MAAM;AAAA;AAAA,EAEvD,kBAAkB,iBAAE,OAAO,EAAE,SAAS;AACxC,CAAC;AAEM,IAAM,yBAAyB,iBAAE,OAAO;AAAA,EAC7C,MAAM,iBAAE,OAAO;AAAA,EACf,aAAa,iBAAE,OAAO;AAAA,EACtB,QAAQ,iBAAE,OAAO;AAAA,EACjB,WAAW,iBAAE,OAAO;AAAA,EACpB,kBAAkB,iBAAE,OAAO;AAAA,EAC3B,cAAc,iBAAE,OAAO,EAAE,SAAS;AAAA,EAClC,YAAY,iBAAE,OAAO;AAAA,IACnB,WAAW,iBAAE,OAAO;AAAA,IACpB,gBAAgB,iBAAE,OAAO;AAAA,IACzB,cAAc,iBAAE,OAAO;AAAA,IACvB,QAAQ,iBAAE,OAAO,EAAE,QAAQ,QAAQ;AAAA,IACnC,UAAU,iBAAE,OAAO,EAAE,QAAQ,WAAW;AAAA,IACxC,WAAW,iBAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,IAC1C,YAAY,iBAAE,OAAO,EAAE,QAAQ,aAAa;AAAA;AAAA,IAE5C,cAAc,iBAAE,OAAO,EAAE,SAAS;AAAA,EACpC,CAAC;AAAA;AAAA,EAED,eAAe,iBAAE,OAAO,EAAE,SAAS;AAAA,EACnC,SAAS,sBAAsB,SAAS;AAAA,EACxC,cAAc,mBAAmB,SAAS;AAC5C,CAAC;;;ACxHD,kBAAiB;AAHjB,SAAS,oBAAoB;AAC7B,OAAO,QAAQ;AACf,OAAO,UAAU;AASjB,IAAM,mBAAmB;AAGzB,IAAI,gBAA2C;AAGxC,SAAS,gBAAoC;AAClD,MAAI,cAAe,QAAO;AAC1B,QAAM,aAAa;AAAA;AAAA,IAEjB,KAAK,QAAQ,YAAY,SAAS,gBAAgB;AAAA;AAAA;AAAA,IAGlD,KAAK,QAAQ,YAAY,SAAS,MAAM,gBAAgB;AAAA,IACxD,KAAK,QAAQ,YAAY,SAAS,MAAM,MAAM,gBAAgB;AAAA;AAAA,IAE9D,KAAK,QAAQ,YAAY,SAAS,OAAO,gBAAgB;AAAA,EAC3D;AAEA,aAAW,OAAO,YAAY;AAC5B,QAAI,CAAC,GAAG,WAAW,GAAG,EAAG;AACzB,UAAM,QAAQ,GAAG,YAAY,GAAG,EAAE,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC;AACjE,QAAI,MAAM,WAAW,EAAG;AACxB,oBAAgB,MAAM,IAAI,OAAK;AAC7B,YAAM,MAAM,YAAAA,QAAK,MAAM,GAAG,aAAa,KAAK,KAAK,KAAK,CAAC,GAAG,OAAO,CAAC;AAClE,aAAO,uBAAuB,MAAM,GAAG;AAAA,IACzC,CAAC;AACD,WAAO;AAAA,EACT;AACA,SAAO,CAAC;AACV;AAGA,SAAS,eAAe,QAAyB;AAC/C,MAAI;AACF,iBAAa,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,OAAO,CAAC;AACjD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,aAAyC;AACvE,QAAM,YAAY,cAAc;AAChC,SAAO,UAAU,IAAI,eAAa;AAAA,IAChC;AAAA,IACA,aAAa,eAAe,SAAS,MAAM;AAAA,IAC3C,gBAAgB,GAAG,WAAW,KAAK,KAAK,aAAa,SAAS,SAAS,CAAC;AAAA,EAC1E,EAAE,EAAE,OAAO,OAAK,EAAE,eAAe,EAAE,cAAc;AACnD;AAGO,SAAS,qBAA6B;AAC3C,SAAO,gBAAgB,YAAY,OAAO,KAAK,QAAQ,IAAI;AAC7D;","names":["YAML"]}