@goondocks/myco 0.6.5 → 0.9.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.
- package/.claude-plugin/marketplace.json +2 -3
- package/.claude-plugin/plugin.json +3 -3
- package/CONTRIBUTING.md +37 -30
- package/README.md +64 -28
- package/bin/myco-run +2 -0
- package/dist/agent-run-EFICNTAU.js +34 -0
- package/dist/agent-run-EFICNTAU.js.map +1 -0
- package/dist/agent-tasks-RXJ7Z5NG.js +180 -0
- package/dist/agent-tasks-RXJ7Z5NG.js.map +1 -0
- package/dist/chunk-2T7RPVPP.js +116 -0
- package/dist/chunk-2T7RPVPP.js.map +1 -0
- package/dist/chunk-3K5WGSJ4.js +165 -0
- package/dist/chunk-3K5WGSJ4.js.map +1 -0
- package/dist/chunk-46PWOKSI.js +26 -0
- package/dist/chunk-46PWOKSI.js.map +1 -0
- package/dist/chunk-4LPQ26CK.js +277 -0
- package/dist/chunk-4LPQ26CK.js.map +1 -0
- package/dist/chunk-5PEUFJ6U.js +92 -0
- package/dist/chunk-5PEUFJ6U.js.map +1 -0
- package/dist/chunk-5VZ52A4T.js +136 -0
- package/dist/chunk-5VZ52A4T.js.map +1 -0
- package/dist/chunk-BUSP3OJB.js +103 -0
- package/dist/chunk-BUSP3OJB.js.map +1 -0
- package/dist/chunk-D7TYRPRM.js +7312 -0
- package/dist/chunk-D7TYRPRM.js.map +1 -0
- package/dist/chunk-DCXRSSBP.js +22 -0
- package/dist/chunk-DCXRSSBP.js.map +1 -0
- package/dist/chunk-E4VLWIJC.js +2 -0
- package/dist/chunk-FFAYUQ5N.js +39 -0
- package/dist/chunk-FFAYUQ5N.js.map +1 -0
- package/dist/chunk-IB76KGBY.js +2 -0
- package/dist/chunk-JMJJEQ3P.js +486 -0
- package/dist/chunk-JMJJEQ3P.js.map +1 -0
- package/dist/{chunk-N33KUCFP.js → chunk-JTYZRPX5.js} +1 -9
- package/dist/chunk-JTYZRPX5.js.map +1 -0
- package/dist/{chunk-54WVLTKD.js → chunk-JYOOJCPQ.js} +33 -17
- package/dist/chunk-JYOOJCPQ.js.map +1 -0
- package/dist/{chunk-F7GAYVWF.js → chunk-KB4DGYIY.js} +91 -9
- package/dist/chunk-KB4DGYIY.js.map +1 -0
- package/dist/{chunk-ERG2IEWX.js → chunk-KH64DHOY.js} +3 -7413
- package/dist/chunk-KH64DHOY.js.map +1 -0
- package/dist/chunk-KV4OC4H3.js +498 -0
- package/dist/chunk-KV4OC4H3.js.map +1 -0
- package/dist/chunk-KYLDNM7H.js +66 -0
- package/dist/chunk-KYLDNM7H.js.map +1 -0
- package/dist/chunk-LPUQPDC2.js +19 -0
- package/dist/chunk-LPUQPDC2.js.map +1 -0
- package/dist/chunk-M5XWW7UI.js +97 -0
- package/dist/chunk-M5XWW7UI.js.map +1 -0
- package/dist/chunk-MHSCMET3.js +275 -0
- package/dist/chunk-MHSCMET3.js.map +1 -0
- package/dist/chunk-MYX5NCRH.js +45 -0
- package/dist/chunk-MYX5NCRH.js.map +1 -0
- package/dist/chunk-OXZSXYAT.js +877 -0
- package/dist/chunk-OXZSXYAT.js.map +1 -0
- package/dist/chunk-PB6TOLRQ.js +35 -0
- package/dist/chunk-PB6TOLRQ.js.map +1 -0
- package/dist/chunk-PT5IC642.js +162 -0
- package/dist/chunk-PT5IC642.js.map +1 -0
- package/dist/chunk-QIK2XSDQ.js +187 -0
- package/dist/chunk-QIK2XSDQ.js.map +1 -0
- package/dist/chunk-RJ6ZQKG5.js +26 -0
- package/dist/chunk-RJ6ZQKG5.js.map +1 -0
- package/dist/{chunk-4B5RO2YV.js → chunk-TRUJLI6K.js} +29 -43
- package/dist/chunk-TRUJLI6K.js.map +1 -0
- package/dist/chunk-U3IBO3O3.js +41 -0
- package/dist/chunk-U3IBO3O3.js.map +1 -0
- package/dist/{chunk-4DYD4HHG.js → chunk-UBZPD4HN.js} +2 -2
- package/dist/{chunk-HIN3UVOG.js → chunk-V7XG6V6C.js} +20 -11
- package/dist/chunk-V7XG6V6C.js.map +1 -0
- package/dist/chunk-WGTCA2NU.js +84 -0
- package/dist/chunk-WGTCA2NU.js.map +1 -0
- package/dist/{chunk-AHZN4Z34.js → chunk-XNOCTDHF.js} +2 -2
- package/dist/chunk-YDN4OM33.js +80 -0
- package/dist/chunk-YDN4OM33.js.map +1 -0
- package/dist/cli-ODLFRIYS.js +128 -0
- package/dist/cli-ODLFRIYS.js.map +1 -0
- package/dist/client-EYOTW3JU.js +19 -0
- package/dist/client-MXRNQ5FI.js +13 -0
- package/dist/{config-IBS6KOLQ.js → config-UR5BSGVX.js} +21 -34
- package/dist/config-UR5BSGVX.js.map +1 -0
- package/dist/detect-H5OPI7GD.js +17 -0
- package/dist/detect-H5OPI7GD.js.map +1 -0
- package/dist/detect-providers-Q42OD4OS.js +26 -0
- package/dist/detect-providers-Q42OD4OS.js.map +1 -0
- package/dist/doctor-JLKTXDEH.js +258 -0
- package/dist/doctor-JLKTXDEH.js.map +1 -0
- package/dist/executor-ONSDHPGX.js +1441 -0
- package/dist/executor-ONSDHPGX.js.map +1 -0
- package/dist/init-6GWY345B.js +198 -0
- package/dist/init-6GWY345B.js.map +1 -0
- package/dist/init-wizard-UONLDYLI.js +294 -0
- package/dist/init-wizard-UONLDYLI.js.map +1 -0
- package/dist/llm-BV3QNVRD.js +17 -0
- package/dist/llm-BV3QNVRD.js.map +1 -0
- package/dist/loader-SH67XD54.js +28 -0
- package/dist/loader-SH67XD54.js.map +1 -0
- package/dist/loader-XVXKZZDH.js +18 -0
- package/dist/loader-XVXKZZDH.js.map +1 -0
- package/dist/{chunk-F7PGDD2X.js → logs-QZVYF6FP.js} +74 -5
- package/dist/logs-QZVYF6FP.js.map +1 -0
- package/dist/main-BMCL7CPO.js +4393 -0
- package/dist/main-BMCL7CPO.js.map +1 -0
- package/dist/openai-embeddings-C265WRNK.js +14 -0
- package/dist/openai-embeddings-C265WRNK.js.map +1 -0
- package/dist/openrouter-U6VFCRX2.js +14 -0
- package/dist/openrouter-U6VFCRX2.js.map +1 -0
- package/dist/post-compact-OWFSOITU.js +26 -0
- package/dist/post-compact-OWFSOITU.js.map +1 -0
- package/dist/post-tool-use-DOUM7CGQ.js +56 -0
- package/dist/post-tool-use-DOUM7CGQ.js.map +1 -0
- package/dist/post-tool-use-failure-SG3C7PE6.js +28 -0
- package/dist/post-tool-use-failure-SG3C7PE6.js.map +1 -0
- package/dist/pre-compact-3J33CHXQ.js +25 -0
- package/dist/pre-compact-3J33CHXQ.js.map +1 -0
- package/dist/provider-check-3WBPZADE.js +12 -0
- package/dist/provider-check-3WBPZADE.js.map +1 -0
- package/dist/registry-J4XTWARS.js +25 -0
- package/dist/registry-J4XTWARS.js.map +1 -0
- package/dist/resolution-events-TFEQPVKS.js +12 -0
- package/dist/resolution-events-TFEQPVKS.js.map +1 -0
- package/dist/resolve-3FEUV462.js +9 -0
- package/dist/resolve-3FEUV462.js.map +1 -0
- package/dist/{restart-UIP7US4U.js → restart-2VM33WOB.js} +10 -6
- package/dist/{restart-UIP7US4U.js.map → restart-2VM33WOB.js.map} +1 -1
- package/dist/search-ZGQR5MDE.js +91 -0
- package/dist/search-ZGQR5MDE.js.map +1 -0
- package/dist/{server-43KSJ65Q.js → server-6KMBJCHZ.js} +267 -524
- package/dist/server-6KMBJCHZ.js.map +1 -0
- package/dist/session-Z2FXDDG6.js +68 -0
- package/dist/session-Z2FXDDG6.js.map +1 -0
- package/dist/session-end-FLVX32LE.js +38 -0
- package/dist/session-end-FLVX32LE.js.map +1 -0
- package/dist/session-start-UCLK7PXE.js +169 -0
- package/dist/session-start-UCLK7PXE.js.map +1 -0
- package/dist/setup-digest-4KDSXAIV.js +15 -0
- package/dist/setup-digest-4KDSXAIV.js.map +1 -0
- package/dist/setup-llm-GKMCHURK.js +81 -0
- package/dist/setup-llm-GKMCHURK.js.map +1 -0
- package/dist/src/agent/definitions/agent.yaml +35 -0
- package/dist/src/agent/definitions/tasks/digest-only.yaml +84 -0
- package/dist/src/agent/definitions/tasks/extract-only.yaml +87 -0
- package/dist/src/agent/definitions/tasks/full-intelligence.yaml +472 -0
- package/dist/src/agent/definitions/tasks/graph-maintenance.yaml +92 -0
- package/dist/src/agent/definitions/tasks/review-session.yaml +132 -0
- package/dist/src/agent/definitions/tasks/supersession-sweep.yaml +86 -0
- package/dist/src/agent/definitions/tasks/title-summary.yaml +88 -0
- package/dist/src/agent/prompts/agent.md +121 -0
- package/dist/src/agent/prompts/orchestrator.md +91 -0
- package/dist/src/cli.js +1 -8
- package/dist/src/cli.js.map +1 -1
- package/dist/src/daemon/main.js +1 -8
- package/dist/src/daemon/main.js.map +1 -1
- package/dist/src/hooks/post-tool-use.js +3 -50
- package/dist/src/hooks/post-tool-use.js.map +1 -1
- package/dist/src/hooks/session-end.js +3 -32
- package/dist/src/hooks/session-end.js.map +1 -1
- package/dist/src/hooks/session-start.js +2 -8
- package/dist/src/hooks/session-start.js.map +1 -1
- package/dist/src/hooks/stop.js +3 -42
- package/dist/src/hooks/stop.js.map +1 -1
- package/dist/src/hooks/user-prompt-submit.js +3 -53
- package/dist/src/hooks/user-prompt-submit.js.map +1 -1
- package/dist/src/mcp/server.js +1 -8
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/prompts/digest-system.md +1 -1
- package/dist/src/symbionts/manifests/claude-code.yaml +16 -0
- package/dist/src/symbionts/manifests/cursor.yaml +14 -0
- package/dist/stats-IUJPZSVZ.js +94 -0
- package/dist/stats-IUJPZSVZ.js.map +1 -0
- package/dist/stop-XRQLLXST.js +42 -0
- package/dist/stop-XRQLLXST.js.map +1 -0
- package/dist/stop-failure-2CAJJKRG.js +26 -0
- package/dist/stop-failure-2CAJJKRG.js.map +1 -0
- package/dist/subagent-start-MWWQTZMQ.js +26 -0
- package/dist/subagent-start-MWWQTZMQ.js.map +1 -0
- package/dist/subagent-stop-PJXYGRXB.js +28 -0
- package/dist/subagent-stop-PJXYGRXB.js.map +1 -0
- package/dist/task-completed-4LFRJVGI.js +27 -0
- package/dist/task-completed-4LFRJVGI.js.map +1 -0
- package/dist/ui/assets/index-DZrElonz.js +744 -0
- package/dist/ui/assets/index-TkeiYbZB.css +1 -0
- package/dist/ui/favicon.svg +7 -7
- package/dist/ui/fonts/Inter-Variable.woff2 +0 -0
- package/dist/ui/fonts/JetBrainsMono-Variable.woff2 +0 -0
- package/dist/ui/fonts/Newsreader-Italic-Variable.woff2 +0 -0
- package/dist/ui/fonts/Newsreader-Variable.woff2 +0 -0
- package/dist/ui/index.html +2 -2
- package/dist/user-prompt-submit-KSM3AR6P.js +59 -0
- package/dist/user-prompt-submit-KSM3AR6P.js.map +1 -0
- package/dist/{verify-X272WGBD.js → verify-UDAYVX37.js} +17 -22
- package/dist/verify-UDAYVX37.js.map +1 -0
- package/dist/{version-XE4GYTBV.js → version-KLBN4HZT.js} +3 -4
- package/dist/version-KLBN4HZT.js.map +1 -0
- package/hooks/hooks.json +82 -5
- package/package.json +6 -3
- package/skills/myco/SKILL.md +10 -10
- package/skills/myco/references/cli-usage.md +15 -13
- package/skills/myco/references/vault-status.md +3 -3
- package/skills/myco/references/wisdom.md +4 -4
- package/skills/myco-curate/SKILL.md +86 -0
- package/dist/chunk-4B5RO2YV.js.map +0 -1
- package/dist/chunk-4RMSHZE4.js +0 -107
- package/dist/chunk-4RMSHZE4.js.map +0 -1
- package/dist/chunk-54WVLTKD.js.map +0 -1
- package/dist/chunk-5LMRZDH3.js +0 -65
- package/dist/chunk-5LMRZDH3.js.map +0 -1
- package/dist/chunk-6FQISQNA.js +0 -61
- package/dist/chunk-6FQISQNA.js.map +0 -1
- package/dist/chunk-DYDBF5W6.js +0 -147
- package/dist/chunk-DYDBF5W6.js.map +0 -1
- package/dist/chunk-ERG2IEWX.js.map +0 -1
- package/dist/chunk-F7GAYVWF.js.map +0 -1
- package/dist/chunk-F7PGDD2X.js.map +0 -1
- package/dist/chunk-GENQ5QGP.js +0 -37
- package/dist/chunk-GENQ5QGP.js.map +0 -1
- package/dist/chunk-HIN3UVOG.js.map +0 -1
- package/dist/chunk-HYVT345Y.js +0 -159
- package/dist/chunk-HYVT345Y.js.map +0 -1
- package/dist/chunk-LEK6DEAE.js +0 -113
- package/dist/chunk-LEK6DEAE.js.map +0 -1
- package/dist/chunk-MDLSAFPP.js +0 -99
- package/dist/chunk-MDLSAFPP.js.map +0 -1
- package/dist/chunk-N33KUCFP.js.map +0 -1
- package/dist/chunk-O6TBHGVO.js +0 -168
- package/dist/chunk-O6TBHGVO.js.map +0 -1
- package/dist/chunk-OEGZ5YTJ.js +0 -56
- package/dist/chunk-OEGZ5YTJ.js.map +0 -1
- package/dist/chunk-P723N2LP.js +0 -147
- package/dist/chunk-P723N2LP.js.map +0 -1
- package/dist/chunk-RGVBGTD6.js +0 -21
- package/dist/chunk-RGVBGTD6.js.map +0 -1
- package/dist/chunk-TK7A4RX7.js +0 -1085
- package/dist/chunk-TK7A4RX7.js.map +0 -1
- package/dist/chunk-TWSTAVLO.js +0 -132
- package/dist/chunk-TWSTAVLO.js.map +0 -1
- package/dist/chunk-V6BJVYNH.js +0 -4423
- package/dist/chunk-V6BJVYNH.js.map +0 -1
- package/dist/chunk-XH34FX4C.js +0 -43
- package/dist/chunk-XH34FX4C.js.map +0 -1
- package/dist/chunk-YRIIBPJD.js +0 -86
- package/dist/chunk-YRIIBPJD.js.map +0 -1
- package/dist/cli-OJYHLO4Y.js +0 -97
- package/dist/cli-OJYHLO4Y.js.map +0 -1
- package/dist/client-SS3C5MF6.js +0 -12
- package/dist/config-IBS6KOLQ.js.map +0 -1
- package/dist/curate-4CKEMOPV.js +0 -78
- package/dist/curate-4CKEMOPV.js.map +0 -1
- package/dist/detect-providers-LFIVJYQO.js +0 -35
- package/dist/detect-providers-LFIVJYQO.js.map +0 -1
- package/dist/digest-ZLARHLLY.js +0 -85
- package/dist/digest-ZLARHLLY.js.map +0 -1
- package/dist/init-3LVKVQ4L.js +0 -109
- package/dist/init-3LVKVQ4L.js.map +0 -1
- package/dist/logs-6CWVP574.js +0 -84
- package/dist/logs-6CWVP574.js.map +0 -1
- package/dist/main-RB727YRP.js +0 -5836
- package/dist/main-RB727YRP.js.map +0 -1
- package/dist/rebuild-QWVVCBCZ.js +0 -64
- package/dist/rebuild-QWVVCBCZ.js.map +0 -1
- package/dist/reprocess-YG3WLUI2.js +0 -79
- package/dist/reprocess-YG3WLUI2.js.map +0 -1
- package/dist/search-BQLBW5CS.js +0 -120
- package/dist/search-BQLBW5CS.js.map +0 -1
- package/dist/server-43KSJ65Q.js.map +0 -1
- package/dist/session-F326AWCH.js +0 -44
- package/dist/session-F326AWCH.js.map +0 -1
- package/dist/session-start-6SHGT2AW.js +0 -192
- package/dist/session-start-6SHGT2AW.js.map +0 -1
- package/dist/setup-digest-X735EZSD.js +0 -15
- package/dist/setup-llm-QBSTQO7N.js +0 -15
- package/dist/src/prompts/classification.md +0 -43
- package/dist/stats-QBLIEFWL.js +0 -58
- package/dist/stats-QBLIEFWL.js.map +0 -1
- package/dist/templates-XPRBOWCE.js +0 -38
- package/dist/templates-XPRBOWCE.js.map +0 -1
- package/dist/ui/assets/index-CjWGVHhF.css +0 -1
- package/dist/ui/assets/index-Cq-H7wgE.js +0 -369
- package/dist/verify-X272WGBD.js.map +0 -1
- package/skills/setup/SKILL.md +0 -174
- package/skills/setup/references/model-recommendations.md +0 -83
- /package/dist/{client-SS3C5MF6.js.map → chunk-E4VLWIJC.js.map} +0 -0
- /package/dist/{setup-digest-X735EZSD.js.map → chunk-IB76KGBY.js.map} +0 -0
- /package/dist/{chunk-4DYD4HHG.js.map → chunk-UBZPD4HN.js.map} +0 -0
- /package/dist/{chunk-AHZN4Z34.js.map → chunk-XNOCTDHF.js.map} +0 -0
- /package/dist/{setup-llm-QBSTQO7N.js.map → client-EYOTW3JU.js.map} +0 -0
- /package/dist/{version-XE4GYTBV.js.map → client-MXRNQ5FI.js.map} +0 -0
|
@@ -88,7 +88,7 @@ Read the last line of `<vault>/digest/trace.jsonl`. Each line is a JSON object w
|
|
|
88
88
|
- `cycleId` — short identifier for the cycle
|
|
89
89
|
- `timestamp` — ISO timestamp of when the cycle ran
|
|
90
90
|
- `tiersGenerated` — which tiers were written
|
|
91
|
-
- `substrateCount` — number of
|
|
91
|
+
- `substrateCount` — number of records processed as input
|
|
92
92
|
- `durationMs` — how long the cycle took
|
|
93
93
|
|
|
94
94
|
**Metabolism config:**
|
|
@@ -127,7 +127,7 @@ Check for these problems when assessing vault health:
|
|
|
127
127
|
| **Stale buffers** | `.jsonl` files in `<vault>/buffer/` older than 24 hours | Events were captured but never processed — LLM may have been unavailable |
|
|
128
128
|
| **Missing index** | `<vault>/index.db` does not exist | FTS search will not work; suggest `node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js rebuild` |
|
|
129
129
|
| **Missing vectors** | `<vault>/vectors.db` does not exist | Semantic search disabled; embeddings may be unconfigured |
|
|
130
|
-
| **Old config version** | `version` in `myco.yaml` is less than `2` | Vault may need migration; suggest running
|
|
130
|
+
| **Old config version** | `version` in `myco.yaml` is less than `2` | Vault may need migration; suggest running `myco init` |
|
|
131
131
|
|
|
132
132
|
Report all issues found, or "None found." if the vault is clean.
|
|
133
133
|
|
|
@@ -221,4 +221,4 @@ Lineage tracks parent-child relationships between sessions. A high count of `sem
|
|
|
221
221
|
| Stale buffers | Check if LLM provider was down during those sessions; events will process on next daemon start |
|
|
222
222
|
| Missing index | Run `node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js rebuild` to regenerate FTS and vector indexes |
|
|
223
223
|
| Provider unreachable | Ensure the provider is running (e.g., `ollama serve`); verify model name in `myco.yaml`; reconfigure with CLI commands |
|
|
224
|
-
| Config version < 2 | Run
|
|
224
|
+
| Config version < 2 | Run `myco init` to migrate the vault configuration |
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
When you notice patterns in vault spores — recurring themes, conflicting advice, outdated observations — use these tools to keep the vault clean and its knowledge sharp.
|
|
4
4
|
|
|
5
|
-
## Automatic
|
|
5
|
+
## Automatic Intelligence
|
|
6
6
|
|
|
7
7
|
Myco automatically checks for supersession every time a new spore is written. After the spore is saved and embedded, a fire-and-forget pipeline searches for semantically similar active spores of the same observation type and asks the LLM whether any are now outdated. If so, they're marked superseded automatically. This means most vault hygiene happens without manual intervention.
|
|
8
8
|
|
|
9
9
|
For vault-wide cleanup (e.g., after a large refactor), use the CLI:
|
|
10
10
|
```sh
|
|
11
|
-
node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js
|
|
12
|
-
node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js
|
|
11
|
+
node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js agent --dry-run # preview
|
|
12
|
+
node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js agent # execute
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Supersede
|
|
16
16
|
|
|
17
|
-
Use `myco_supersede` for manual supersession when you spot a stale spore that automatic
|
|
17
|
+
Use `myco_supersede` for manual supersession when you spot a stale spore that automatic intelligence missed.
|
|
18
18
|
|
|
19
19
|
**Signals:**
|
|
20
20
|
- A decision was reversed in a later session
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: myco-curate
|
|
3
|
+
description: >-
|
|
4
|
+
Trigger the Myco intelligence agent to process unprocessed session data,
|
|
5
|
+
extract observations, and maintain the vault knowledge graph
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Bash
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Myco Curate — Run the Intelligence Agent
|
|
11
|
+
|
|
12
|
+
This skill triggers an intelligence agent run via the daemon API. The intelligence agent processes unprocessed prompt batches, extracts observations (spores), and maintains the vault's knowledge graph.
|
|
13
|
+
|
|
14
|
+
## Arguments
|
|
15
|
+
|
|
16
|
+
The user may provide:
|
|
17
|
+
- **task name** — which intelligence task to run (e.g., "full-intelligence", "extraction-only")
|
|
18
|
+
- **instruction** — free-text instruction to guide the agent's focus
|
|
19
|
+
|
|
20
|
+
Parse the user's message for these. Both are optional.
|
|
21
|
+
|
|
22
|
+
## Step 1: Resolve Daemon Port
|
|
23
|
+
|
|
24
|
+
Read the daemon.json file to find the running daemon's port:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cat "$(node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js stats 2>/dev/null | grep -oP 'path: \K.*' || echo ~/.myco/vaults/myco)/daemon.json" 2>/dev/null
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If that fails, use the vault directory from the environment. The daemon.json contains `{ "pid": ..., "port": ... }`. Extract the `port` value.
|
|
31
|
+
|
|
32
|
+
If the daemon is not running, tell the user:
|
|
33
|
+
|
|
34
|
+
> "The Myco daemon is not running. Start a new session or run `node ${CLAUDE_PLUGIN_ROOT}/dist/src/cli.js restart` to start it."
|
|
35
|
+
|
|
36
|
+
## Step 2: Trigger Agent Run
|
|
37
|
+
|
|
38
|
+
Send a POST request to the daemon API:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
curl -s -X POST http://localhost:<port>/api/agent/run \
|
|
42
|
+
-H 'Content-Type: application/json' \
|
|
43
|
+
-d '{"task": "<task-name-or-null>", "instruction": "<instruction-or-null>"}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Omit `task` and `instruction` fields from the JSON body if they were not provided by the user.
|
|
47
|
+
|
|
48
|
+
Report the response to the user. The response will be `{ "ok": true, "message": "Intelligence agent started" }`.
|
|
49
|
+
|
|
50
|
+
## Step 3: Check Run Status
|
|
51
|
+
|
|
52
|
+
The intelligence agent runs in the background. To check its progress, poll the runs endpoint:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -s http://localhost:<port>/api/agent/runs?limit=1
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This returns the most recent run. Show the user:
|
|
59
|
+
- **Run ID** — the unique identifier
|
|
60
|
+
- **Status** — pending, running, completed, failed, or skipped
|
|
61
|
+
- **Task** — which task was executed
|
|
62
|
+
- **Tokens used** — total tokens consumed (if completed)
|
|
63
|
+
- **Cost** — USD cost (if completed)
|
|
64
|
+
- **Error** — error message (if failed)
|
|
65
|
+
|
|
66
|
+
If the run is still `running`, tell the user they can check again later or wait.
|
|
67
|
+
|
|
68
|
+
## Step 4: Show Reports (if completed)
|
|
69
|
+
|
|
70
|
+
If the run completed, fetch the decision reports:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -s http://localhost:<port>/api/agent/runs/<run-id>/reports
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Summarize the reports for the user:
|
|
77
|
+
- How many actions were taken
|
|
78
|
+
- What types of actions (extraction, consolidation, supersession, etc.)
|
|
79
|
+
- Key observations or decisions made
|
|
80
|
+
|
|
81
|
+
## Constraints
|
|
82
|
+
|
|
83
|
+
- Always use the daemon API, never call the executor directly from the skill.
|
|
84
|
+
- The intelligence agent runs asynchronously — the POST returns immediately.
|
|
85
|
+
- If the user asks for a specific task, pass it in the `task` field.
|
|
86
|
+
- If the user provides natural language guidance, pass it in the `instruction` field.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/client.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { DAEMON_CLIENT_TIMEOUT_MS, DAEMON_HEALTH_CHECK_TIMEOUT_MS, DAEMON_HEALTH_RETRY_DELAYS, DAEMON_STALE_GRACE_PERIOD_MS } from '../constants.js';\nimport { AgentRegistry } from '../agents/registry.js';\nimport { getPluginVersion } from '../version.js';\n\ninterface DaemonInfo {\n pid: number;\n port: number;\n}\n\ninterface HealthResponse {\n myco: boolean;\n version?: string;\n}\n\ninterface ClientResult {\n ok: boolean;\n data?: any;\n}\n\nexport class DaemonClient {\n private vaultDir: string;\n\n constructor(vaultDir: string) {\n this.vaultDir = vaultDir;\n }\n\n async post(endpoint: string, body: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async get(endpoint: string): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n const info = this.readDaemonJson();\n if (!info) return false;\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n return data.myco === true;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if the daemon is running a stale version.\n * Returns true if the daemon's version doesn't match the current plugin version.\n * Skips the check if daemon.json was written recently (grace period) to prevent\n * rapid restart loops from concurrent hooks or session reloads.\n */\n private async isStale(): Promise<boolean> {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const stat = fs.statSync(jsonPath);\n if (Date.now() - stat.mtimeMs < DAEMON_STALE_GRACE_PERIOD_MS) {\n return false;\n }\n\n const info = this.readDaemonJson();\n if (!info) return false;\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n if (!data.myco) return false;\n\n // No version in response = old daemon that predates this check\n if (!data.version) return true;\n\n return data.version !== getPluginVersion();\n } catch {\n return false;\n }\n }\n\n /**\n * Kill the running daemon process.\n */\n private killDaemon(): void {\n try {\n const info = this.readDaemonJson();\n if (!info) return;\n process.kill(info.pid, 'SIGTERM');\n } catch { /* already dead */ }\n try {\n fs.unlinkSync(path.join(this.vaultDir, 'daemon.json'));\n } catch { /* already gone */ }\n }\n\n /**\n * Ensure the daemon is running. Spawns it if unhealthy.\n * When checkStale is true (default), also restarts a healthy daemon if its\n * version doesn't match the current plugin version. Use checkStale: false\n * for hooks that just need the daemon alive (e.g., stop) without triggering\n * version-driven restarts.\n */\n async ensureRunning(opts?: { checkStale?: boolean }): Promise<boolean> {\n const checkStale = opts?.checkStale ?? true;\n\n if (checkStale && await this.isStale()) {\n this.killDaemon();\n // Brief pause for port release\n await new Promise((r) => setTimeout(r, 200));\n } else if (await this.isHealthy()) {\n return true;\n }\n\n this.spawnDaemon();\n\n for (const delay of DAEMON_HEALTH_RETRY_DELAYS) {\n await new Promise((r) => setTimeout(r, delay));\n if (await this.isHealthy()) return true;\n }\n return false;\n }\n\n spawnDaemon(): void {\n const daemonScript = this.resolveDaemonScript();\n if (!daemonScript || !fs.existsSync(daemonScript)) return;\n\n const child = spawn('node', [daemonScript, '--vault', this.vaultDir], {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n }\n\n /**\n * Resolve the daemon entry script path.\n * Priority:\n * 1. Plugin root env var (set by the agent host) → dist/src/daemon/main.js\n * 2. Walk up from the current file to find the dist/ directory containing\n * the daemon entry. This handles both chunk files (dist/chunk-*.js) and\n * thin entry points (dist/src/hooks/*.js) after bundling.\n */\n private resolveDaemonScript(): string | undefined {\n const pluginRoot = new AgentRegistry().resolvePluginRoot();\n if (pluginRoot) {\n return path.join(pluginRoot, 'dist', 'src', 'daemon', 'main.js');\n }\n\n // Walk up from import.meta.dirname looking for the daemon entry\n let dir = import.meta.dirname;\n for (let i = 0; i < 5; i++) {\n const candidate = path.join(dir, 'dist', 'src', 'daemon', 'main.js');\n if (fs.existsSync(candidate)) return candidate;\n // Also check if we're already inside dist/\n const inDist = path.join(dir, 'src', 'daemon', 'main.js');\n if (fs.existsSync(inDist)) return inDist;\n dir = path.dirname(dir);\n }\n return undefined;\n }\n\n private readDaemonJson(): DaemonInfo | null {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const content = fs.readFileSync(jsonPath, 'utf-8');\n const info = JSON.parse(content);\n if (typeof info.port !== 'number') return null;\n return info as DaemonInfo;\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-4RMSHZE4.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
-
|
|
3
|
-
// src/index/vectors.ts
|
|
4
|
-
import Database from "better-sqlite3";
|
|
5
|
-
import * as sqliteVec from "sqlite-vec";
|
|
6
|
-
var VectorIndex = class {
|
|
7
|
-
db;
|
|
8
|
-
dimensions;
|
|
9
|
-
constructor(dbPath, dimensions) {
|
|
10
|
-
this.dimensions = dimensions;
|
|
11
|
-
this.db = new Database(dbPath);
|
|
12
|
-
sqliteVec.load(this.db);
|
|
13
|
-
this.init();
|
|
14
|
-
}
|
|
15
|
-
init() {
|
|
16
|
-
this.db.exec(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS vec_metadata (
|
|
18
|
-
id TEXT PRIMARY KEY,
|
|
19
|
-
type TEXT NOT NULL DEFAULT '',
|
|
20
|
-
importance TEXT NOT NULL DEFAULT '',
|
|
21
|
-
session_id TEXT NOT NULL DEFAULT '',
|
|
22
|
-
file_path TEXT NOT NULL DEFAULT '',
|
|
23
|
-
branch TEXT NOT NULL DEFAULT '',
|
|
24
|
-
created TEXT NOT NULL DEFAULT (datetime('now'))
|
|
25
|
-
);
|
|
26
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS vec_embeddings USING vec0(
|
|
27
|
-
id TEXT PRIMARY KEY,
|
|
28
|
-
embedding float[${this.dimensions}]
|
|
29
|
-
);
|
|
30
|
-
`);
|
|
31
|
-
}
|
|
32
|
-
upsert(id, embedding, metadata = {}) {
|
|
33
|
-
this.db.prepare("DELETE FROM vec_metadata WHERE id = ?").run(id);
|
|
34
|
-
this.db.prepare("DELETE FROM vec_embeddings WHERE id = ?").run(id);
|
|
35
|
-
this.db.prepare(
|
|
36
|
-
"INSERT INTO vec_metadata (id, type, importance, session_id, file_path, branch) VALUES (?, ?, ?, ?, ?, ?)"
|
|
37
|
-
).run(id, metadata.type ?? "", metadata.importance ?? "", metadata.session_id ?? "", metadata.file_path ?? "", metadata.branch ?? "");
|
|
38
|
-
this.db.prepare("INSERT INTO vec_embeddings (id, embedding) VALUES (?, ?)").run(id, new Float32Array(embedding));
|
|
39
|
-
}
|
|
40
|
-
search(query, options = {}) {
|
|
41
|
-
const limit = options.limit ?? 10;
|
|
42
|
-
const knnParams = [new Float32Array(query), limit * 4];
|
|
43
|
-
const knnRows = this.db.prepare(`
|
|
44
|
-
SELECT id, distance
|
|
45
|
-
FROM vec_embeddings
|
|
46
|
-
WHERE embedding MATCH ?
|
|
47
|
-
ORDER BY distance
|
|
48
|
-
LIMIT ?
|
|
49
|
-
`).all(...knnParams);
|
|
50
|
-
if (knnRows.length === 0) return [];
|
|
51
|
-
const metaConditions = ["id IN (" + knnRows.map(() => "?").join(",") + ")"];
|
|
52
|
-
const metaParams = knnRows.map((r) => r.id);
|
|
53
|
-
if (options.type) {
|
|
54
|
-
metaConditions.push("type = ?");
|
|
55
|
-
metaParams.push(options.type);
|
|
56
|
-
}
|
|
57
|
-
if (options.importance) {
|
|
58
|
-
metaConditions.push("importance = ?");
|
|
59
|
-
metaParams.push(options.importance);
|
|
60
|
-
}
|
|
61
|
-
const metaRows = this.db.prepare(`
|
|
62
|
-
SELECT id, type, importance, session_id, file_path, branch
|
|
63
|
-
FROM vec_metadata
|
|
64
|
-
WHERE ${metaConditions.join(" AND ")}
|
|
65
|
-
`).all(...metaParams);
|
|
66
|
-
const metaMap = new Map(metaRows.map((m) => [m.id, m]));
|
|
67
|
-
const scored = knnRows.filter((r) => metaMap.has(r.id)).map((r) => {
|
|
68
|
-
const m = metaMap.get(r.id);
|
|
69
|
-
return {
|
|
70
|
-
id: r.id,
|
|
71
|
-
similarity: 1 - r.distance,
|
|
72
|
-
metadata: { type: m.type, importance: m.importance, session_id: m.session_id, file_path: m.file_path, branch: m.branch }
|
|
73
|
-
};
|
|
74
|
-
});
|
|
75
|
-
if (scored.length === 0) return [];
|
|
76
|
-
const topScore = scored[0].similarity;
|
|
77
|
-
const threshold = options.relativeThreshold ?? 0.5;
|
|
78
|
-
const floor = topScore * threshold;
|
|
79
|
-
return scored.filter((r) => r.similarity >= floor).slice(0, limit);
|
|
80
|
-
}
|
|
81
|
-
/** Retrieve the stored embedding for a given ID, or null if not found. */
|
|
82
|
-
getEmbedding(id) {
|
|
83
|
-
const row = this.db.prepare("SELECT embedding FROM vec_embeddings WHERE id = ?").get(id);
|
|
84
|
-
if (!row) return null;
|
|
85
|
-
return Array.from(new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4));
|
|
86
|
-
}
|
|
87
|
-
/** Check whether an embedding exists for the given ID. */
|
|
88
|
-
has(id) {
|
|
89
|
-
const row = this.db.prepare("SELECT 1 FROM vec_metadata WHERE id = ?").get(id);
|
|
90
|
-
return row !== void 0;
|
|
91
|
-
}
|
|
92
|
-
delete(id) {
|
|
93
|
-
this.db.prepare("DELETE FROM vec_metadata WHERE id = ?").run(id);
|
|
94
|
-
this.db.prepare("DELETE FROM vec_embeddings WHERE id = ?").run(id);
|
|
95
|
-
}
|
|
96
|
-
count() {
|
|
97
|
-
return this.db.prepare("SELECT COUNT(*) as c FROM vec_metadata").get().c;
|
|
98
|
-
}
|
|
99
|
-
close() {
|
|
100
|
-
this.db.close();
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export {
|
|
105
|
-
VectorIndex
|
|
106
|
-
};
|
|
107
|
-
//# sourceMappingURL=chunk-4RMSHZE4.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index/vectors.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport * as sqliteVec from 'sqlite-vec';\n\nexport interface VectorSearchResult {\n id: string;\n similarity: number;\n metadata: Record<string, string>;\n}\n\nexport interface VectorSearchOptions {\n limit?: number;\n /** Drop results below this fraction of the top result's score (0-1). Default 0.5. */\n relativeThreshold?: number;\n type?: string;\n importance?: string;\n}\n\nexport class VectorIndex {\n private db: Database.Database;\n private dimensions: number;\n\n constructor(dbPath: string, dimensions: number) {\n this.dimensions = dimensions;\n this.db = new Database(dbPath);\n sqliteVec.load(this.db);\n this.init();\n }\n\n private init(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS vec_metadata (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL DEFAULT '',\n importance TEXT NOT NULL DEFAULT '',\n session_id TEXT NOT NULL DEFAULT '',\n file_path TEXT NOT NULL DEFAULT '',\n branch TEXT NOT NULL DEFAULT '',\n created TEXT NOT NULL DEFAULT (datetime('now'))\n );\n CREATE VIRTUAL TABLE IF NOT EXISTS vec_embeddings USING vec0(\n id TEXT PRIMARY KEY,\n embedding float[${this.dimensions}]\n );\n `);\n }\n\n upsert(id: string, embedding: number[], metadata: Record<string, string> = {}): void {\n this.db.prepare('DELETE FROM vec_metadata WHERE id = ?').run(id);\n this.db.prepare('DELETE FROM vec_embeddings WHERE id = ?').run(id);\n\n this.db.prepare(\n 'INSERT INTO vec_metadata (id, type, importance, session_id, file_path, branch) VALUES (?, ?, ?, ?, ?, ?)',\n ).run(id, metadata.type ?? '', metadata.importance ?? '', metadata.session_id ?? '', metadata.file_path ?? '', metadata.branch ?? '');\n\n this.db.prepare('INSERT INTO vec_embeddings (id, embedding) VALUES (?, ?)').run(id, new Float32Array(embedding));\n }\n\n search(query: number[], options: VectorSearchOptions = {}): VectorSearchResult[] {\n const limit = options.limit ?? 10;\n\n // vec0 KNN queries require LIMIT to be a direct constraint on the virtual table.\n // JOINs with additional WHERE filters confuse the query planner, so we use a\n // subquery to get KNN candidates first, then filter by metadata in the outer query.\n const knnParams: unknown[] = [new Float32Array(query), limit * 4];\n const knnRows = this.db.prepare(`\n SELECT id, distance\n FROM vec_embeddings\n WHERE embedding MATCH ?\n ORDER BY distance\n LIMIT ?\n `).all(...knnParams) as Array<{ id: string; distance: number }>;\n\n if (knnRows.length === 0) return [];\n\n // Now fetch metadata for the candidates and apply optional filters\n const metaConditions: string[] = ['id IN (' + knnRows.map(() => '?').join(',') + ')'];\n const metaParams: unknown[] = knnRows.map((r) => r.id);\n\n if (options.type) { metaConditions.push('type = ?'); metaParams.push(options.type); }\n if (options.importance) { metaConditions.push('importance = ?'); metaParams.push(options.importance); }\n\n const metaRows = this.db.prepare(`\n SELECT id, type, importance, session_id, file_path, branch\n FROM vec_metadata\n WHERE ${metaConditions.join(' AND ')}\n `).all(...metaParams) as Array<{ id: string; type: string; importance: string; session_id: string; file_path: string; branch: string }>;\n\n const metaMap = new Map(metaRows.map((m) => [m.id, m]));\n\n const scored = knnRows\n .filter((r) => metaMap.has(r.id))\n .map((r) => {\n const m = metaMap.get(r.id)!;\n return {\n id: r.id,\n similarity: 1 - r.distance,\n metadata: { type: m.type, importance: m.importance, session_id: m.session_id, file_path: m.file_path, branch: m.branch },\n };\n });\n\n if (scored.length === 0) return [];\n\n // Relative threshold: drop results below a fraction of the best score.\n // Adapts automatically to any embedding model's score distribution.\n const topScore = scored[0].similarity;\n const threshold = options.relativeThreshold ?? 0.5;\n const floor = topScore * threshold;\n\n return scored\n .filter((r) => r.similarity >= floor)\n .slice(0, limit);\n }\n\n /** Retrieve the stored embedding for a given ID, or null if not found. */\n getEmbedding(id: string): number[] | null {\n const row = this.db.prepare('SELECT embedding FROM vec_embeddings WHERE id = ?').get(id) as { embedding: Buffer } | undefined;\n if (!row) return null;\n return Array.from(new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4));\n }\n\n /** Check whether an embedding exists for the given ID. */\n has(id: string): boolean {\n const row = this.db.prepare('SELECT 1 FROM vec_metadata WHERE id = ?').get(id);\n return row !== undefined;\n }\n\n delete(id: string): void {\n this.db.prepare('DELETE FROM vec_metadata WHERE id = ?').run(id);\n this.db.prepare('DELETE FROM vec_embeddings WHERE id = ?').run(id);\n }\n\n count(): number {\n return (this.db.prepare('SELECT COUNT(*) as c FROM vec_metadata').get() as { c: number }).c;\n }\n\n close(): void { this.db.close(); }\n}\n"],"mappings":"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","names":[]}
|