@goondocks/myco 0.16.1 → 0.17.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/CONTRIBUTING.md +3 -3
- package/README.md +4 -3
- package/dist/{agent-run-LOZGH6P5.js → agent-run-ZDHXORE2.js} +7 -7
- package/dist/{agent-tasks-SNQ55FUN.js → agent-tasks-IPUWMMDZ.js} +7 -7
- package/dist/{chunk-P6C6ADBU.js → chunk-2IJ6C63F.js} +2 -2
- package/dist/{chunk-V2ZBYKDU.js → chunk-2WRXLYG6.js} +3 -3
- package/dist/{chunk-TIAYBVSI.js → chunk-4JPUC6RL.js} +170 -56
- package/dist/chunk-4JPUC6RL.js.map +1 -0
- package/dist/{chunk-34NHDRWI.js → chunk-6SDC6V3N.js} +2 -2
- package/dist/{chunk-34NHDRWI.js.map → chunk-6SDC6V3N.js.map} +1 -1
- package/dist/{chunk-6JZEAOLG.js → chunk-CPL76CYD.js} +3 -3
- package/dist/{chunk-VWXDSDJU.js → chunk-DKSQMH5X.js} +2 -2
- package/dist/{chunk-GSKXOCFG.js → chunk-EBIYONNZ.js} +21 -1
- package/dist/chunk-EBIYONNZ.js.map +1 -0
- package/dist/{chunk-XAXQ72L3.js → chunk-FEX6ALLH.js} +2 -2
- package/dist/{chunk-UILSK6DK.js → chunk-GBYLHPML.js} +2 -2
- package/dist/{chunk-DZWSHCAC.js → chunk-KGL5QSDN.js} +2 -2
- package/dist/{chunk-4JVHWBZF.js → chunk-KKEMVH6D.js} +2 -2
- package/dist/{chunk-35FAQCKJ.js → chunk-MSM775XQ.js} +6 -5
- package/dist/{chunk-35FAQCKJ.js.map → chunk-MSM775XQ.js.map} +1 -1
- package/dist/{chunk-CJ2KTRWI.js → chunk-OGNEW5CN.js} +2 -2
- package/dist/{chunk-VTSNXAW7.js → chunk-PFF4KB4O.js} +2 -2
- package/dist/{chunk-HA7HO2X2.js → chunk-QBB6LX57.js} +3 -3
- package/dist/{chunk-C3GNF7RJ.js → chunk-QQ7CXA7Q.js} +5 -5
- package/dist/{chunk-I3S6L7QC.js → chunk-U3SSOSIR.js} +2 -2
- package/dist/{chunk-G42PTGMC.js → chunk-U63GDHYJ.js} +3 -3
- package/dist/{chunk-IRSNOBGD.js → chunk-UDBCAFXS.js} +2 -2
- package/dist/{chunk-SGYYOTNM.js → chunk-VGVRBSLC.js} +2 -2
- package/dist/{chunk-W7ZOOZMK.js → chunk-VQQ57UPG.js} +3 -3
- package/dist/{chunk-TPTF3R77.js → chunk-XVWJ273L.js} +4 -4
- package/dist/{chunk-RPILIIYT.js → chunk-Y7QCKCEJ.js} +2 -2
- package/dist/{chunk-D63XTGBV.js → chunk-YTOD6L6N.js} +6 -6
- package/dist/{chunk-D2NTFSVO.js → chunk-ZUSTCXHT.js} +3 -3
- package/dist/{cli-W66XNY2H.js → cli-BRDOPJW3.js} +40 -40
- package/dist/{client-IZM3GJMT.js → client-AQZMD3LB.js} +4 -4
- package/dist/{config-VHHCGE4F.js → config-K3CJEFFO.js} +3 -3
- package/dist/{detect-6FNYONJF.js → detect-NJ2OREDP.js} +2 -2
- package/dist/{detect-providers-R7QOB3H6.js → detect-providers-OE6HWW3M.js} +4 -4
- package/dist/{doctor-WLV7QNRP.js → doctor-YOUCIJJY.js} +14 -13
- package/dist/doctor-YOUCIJJY.js.map +1 -0
- package/dist/{executor-PUKL76TU.js → executor-UYNV4EOQ.js} +50 -24
- package/dist/executor-UYNV4EOQ.js.map +1 -0
- package/dist/{init-5TB6A2RV.js → init-MTMEFG4E.js} +17 -17
- package/dist/{init-wizard-2Y52AX2A.js → init-wizard-ZS3CV6CM.js} +7 -7
- package/dist/{installer-AARSFXI6.js → installer-CTWQB4RS.js} +2 -2
- package/dist/{llm-LS7U7BHC.js → llm-PGETQHZ2.js} +7 -7
- package/dist/{loader-QDWQTBX4.js → loader-AVWL7PNO.js} +3 -3
- package/dist/{loader-YQDG5GI5.js → loader-J56KP27U.js} +3 -3
- package/dist/{main-3ZXFA56L.js → main-ZIMYW2AB.js} +105 -60
- package/dist/main-ZIMYW2AB.js.map +1 -0
- package/dist/{open-ZOZLFBEA.js → open-77QXL7VY.js} +7 -7
- package/dist/{openai-embeddings-FUW6CSN2.js → openai-embeddings-LZKY6RV5.js} +4 -4
- package/dist/{openrouter-YSIUSUQL.js → openrouter-UTOZG6Z5.js} +4 -4
- package/dist/{post-compact-QSID23PX.js → post-compact-CA7O7QPL.js} +7 -7
- package/dist/{post-tool-use-4MTNNDTO.js → post-tool-use-JNXJIGNK.js} +6 -6
- package/dist/{post-tool-use-failure-WKSMUGJI.js → post-tool-use-failure-V52CZWVZ.js} +7 -7
- package/dist/{pre-compact-HFGKNBYV.js → pre-compact-J2GSDQCJ.js} +7 -7
- package/dist/{provider-check-VEYONGNU.js → provider-check-CESRPIY5.js} +4 -4
- package/dist/{registry-5R3DLJQH.js → registry-SPKP2WLI.js} +4 -4
- package/dist/{remove-S5G6VGVT.js → remove-ODPLWK7O.js} +9 -9
- package/dist/{resolution-events-CHOKR35X.js → resolution-events-CLDXZF67.js} +4 -4
- package/dist/{restart-A7HJTFFM.js → restart-6KKZODOI.js} +8 -8
- package/dist/{search-HKBGO3QV.js → search-U6N2DSOI.js} +8 -8
- package/dist/{server-UAATWKNX.js → server-SP4G7MY7.js} +5 -5
- package/dist/{server-UAATWKNX.js.map → server-SP4G7MY7.js.map} +1 -1
- package/dist/{session-D2WPQTSR.js → session-6R3RNVKD.js} +9 -9
- package/dist/{session-end-S4RYJG3Y.js → session-end-TCFCYDBL.js} +6 -6
- package/dist/{session-start-4RJ32KS5.js → session-start-XXN2TVNI.js} +11 -11
- package/dist/{setup-llm-EZRNEIW2.js → setup-llm-GISFI73Z.js} +8 -8
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/src/symbionts/manifests/claude-code.yaml +4 -0
- package/dist/src/symbionts/manifests/opencode.yaml +26 -0
- package/dist/src/symbionts/templates/opencode/mcp.json +6 -0
- package/dist/src/symbionts/templates/opencode/package.json +5 -0
- package/dist/src/symbionts/templates/opencode/plugin.ts +690 -0
- package/dist/src/symbionts/templates/opencode/settings.json +8 -0
- package/dist/{stats-PW7OGIBR.js → stats-MYQD4OVD.js} +9 -9
- package/dist/{stop-FVMLTWXU.js → stop-K6TDJORY.js} +6 -6
- package/dist/{stop-failure-MD52CGFX.js → stop-failure-U635O5A3.js} +7 -7
- package/dist/{subagent-start-ZJZA7EAJ.js → subagent-start-LLGQBC5Q.js} +7 -7
- package/dist/{subagent-stop-56H22JSE.js → subagent-stop-BO3GZWXD.js} +7 -7
- package/dist/{task-completed-TQ4WW2HW.js → task-completed-3ZJHSI2E.js} +7 -7
- package/dist/{team-RXYFXGUT.js → team-OJLQCVE3.js} +5 -5
- package/dist/ui/assets/{index-RYHXSJv1.js → index-2UyTdjlV.js} +12 -12
- package/dist/ui/assets/index-Cts1wLEW.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/{update-HIJUK5ZK.js → update-HR7WMESA.js} +9 -9
- package/dist/{user-prompt-submit-SLQNTQFL.js → user-prompt-submit-NM73R4I3.js} +6 -6
- package/dist/{verify-ITBMLK67.js → verify-PSERIZPF.js} +8 -8
- package/dist/{version-4YUDRPU4.js → version-YCODQZSX.js} +2 -2
- package/package.json +1 -1
- package/skills/rules/SKILL.md +1 -1
- package/dist/chunk-GSKXOCFG.js.map +0 -1
- package/dist/chunk-TIAYBVSI.js.map +0 -1
- package/dist/doctor-WLV7QNRP.js.map +0 -1
- package/dist/executor-PUKL76TU.js.map +0 -1
- package/dist/main-3ZXFA56L.js.map +0 -1
- package/dist/ui/assets/index-Bjv_ck3c.css +0 -1
- /package/dist/{agent-run-LOZGH6P5.js.map → agent-run-ZDHXORE2.js.map} +0 -0
- /package/dist/{agent-tasks-SNQ55FUN.js.map → agent-tasks-IPUWMMDZ.js.map} +0 -0
- /package/dist/{chunk-P6C6ADBU.js.map → chunk-2IJ6C63F.js.map} +0 -0
- /package/dist/{chunk-V2ZBYKDU.js.map → chunk-2WRXLYG6.js.map} +0 -0
- /package/dist/{chunk-6JZEAOLG.js.map → chunk-CPL76CYD.js.map} +0 -0
- /package/dist/{chunk-VWXDSDJU.js.map → chunk-DKSQMH5X.js.map} +0 -0
- /package/dist/{chunk-XAXQ72L3.js.map → chunk-FEX6ALLH.js.map} +0 -0
- /package/dist/{chunk-UILSK6DK.js.map → chunk-GBYLHPML.js.map} +0 -0
- /package/dist/{chunk-DZWSHCAC.js.map → chunk-KGL5QSDN.js.map} +0 -0
- /package/dist/{chunk-4JVHWBZF.js.map → chunk-KKEMVH6D.js.map} +0 -0
- /package/dist/{chunk-CJ2KTRWI.js.map → chunk-OGNEW5CN.js.map} +0 -0
- /package/dist/{chunk-VTSNXAW7.js.map → chunk-PFF4KB4O.js.map} +0 -0
- /package/dist/{chunk-HA7HO2X2.js.map → chunk-QBB6LX57.js.map} +0 -0
- /package/dist/{chunk-C3GNF7RJ.js.map → chunk-QQ7CXA7Q.js.map} +0 -0
- /package/dist/{chunk-I3S6L7QC.js.map → chunk-U3SSOSIR.js.map} +0 -0
- /package/dist/{chunk-G42PTGMC.js.map → chunk-U63GDHYJ.js.map} +0 -0
- /package/dist/{chunk-IRSNOBGD.js.map → chunk-UDBCAFXS.js.map} +0 -0
- /package/dist/{chunk-SGYYOTNM.js.map → chunk-VGVRBSLC.js.map} +0 -0
- /package/dist/{chunk-W7ZOOZMK.js.map → chunk-VQQ57UPG.js.map} +0 -0
- /package/dist/{chunk-TPTF3R77.js.map → chunk-XVWJ273L.js.map} +0 -0
- /package/dist/{chunk-RPILIIYT.js.map → chunk-Y7QCKCEJ.js.map} +0 -0
- /package/dist/{chunk-D63XTGBV.js.map → chunk-YTOD6L6N.js.map} +0 -0
- /package/dist/{chunk-D2NTFSVO.js.map → chunk-ZUSTCXHT.js.map} +0 -0
- /package/dist/{cli-W66XNY2H.js.map → cli-BRDOPJW3.js.map} +0 -0
- /package/dist/{client-IZM3GJMT.js.map → client-AQZMD3LB.js.map} +0 -0
- /package/dist/{config-VHHCGE4F.js.map → config-K3CJEFFO.js.map} +0 -0
- /package/dist/{detect-6FNYONJF.js.map → detect-NJ2OREDP.js.map} +0 -0
- /package/dist/{detect-providers-R7QOB3H6.js.map → detect-providers-OE6HWW3M.js.map} +0 -0
- /package/dist/{init-5TB6A2RV.js.map → init-MTMEFG4E.js.map} +0 -0
- /package/dist/{init-wizard-2Y52AX2A.js.map → init-wizard-ZS3CV6CM.js.map} +0 -0
- /package/dist/{installer-AARSFXI6.js.map → installer-CTWQB4RS.js.map} +0 -0
- /package/dist/{llm-LS7U7BHC.js.map → llm-PGETQHZ2.js.map} +0 -0
- /package/dist/{loader-QDWQTBX4.js.map → loader-AVWL7PNO.js.map} +0 -0
- /package/dist/{loader-YQDG5GI5.js.map → loader-J56KP27U.js.map} +0 -0
- /package/dist/{open-ZOZLFBEA.js.map → open-77QXL7VY.js.map} +0 -0
- /package/dist/{openai-embeddings-FUW6CSN2.js.map → openai-embeddings-LZKY6RV5.js.map} +0 -0
- /package/dist/{openrouter-YSIUSUQL.js.map → openrouter-UTOZG6Z5.js.map} +0 -0
- /package/dist/{post-compact-QSID23PX.js.map → post-compact-CA7O7QPL.js.map} +0 -0
- /package/dist/{post-tool-use-4MTNNDTO.js.map → post-tool-use-JNXJIGNK.js.map} +0 -0
- /package/dist/{post-tool-use-failure-WKSMUGJI.js.map → post-tool-use-failure-V52CZWVZ.js.map} +0 -0
- /package/dist/{pre-compact-HFGKNBYV.js.map → pre-compact-J2GSDQCJ.js.map} +0 -0
- /package/dist/{provider-check-VEYONGNU.js.map → provider-check-CESRPIY5.js.map} +0 -0
- /package/dist/{registry-5R3DLJQH.js.map → registry-SPKP2WLI.js.map} +0 -0
- /package/dist/{remove-S5G6VGVT.js.map → remove-ODPLWK7O.js.map} +0 -0
- /package/dist/{resolution-events-CHOKR35X.js.map → resolution-events-CLDXZF67.js.map} +0 -0
- /package/dist/{restart-A7HJTFFM.js.map → restart-6KKZODOI.js.map} +0 -0
- /package/dist/{search-HKBGO3QV.js.map → search-U6N2DSOI.js.map} +0 -0
- /package/dist/{session-D2WPQTSR.js.map → session-6R3RNVKD.js.map} +0 -0
- /package/dist/{session-end-S4RYJG3Y.js.map → session-end-TCFCYDBL.js.map} +0 -0
- /package/dist/{session-start-4RJ32KS5.js.map → session-start-XXN2TVNI.js.map} +0 -0
- /package/dist/{setup-llm-EZRNEIW2.js.map → setup-llm-GISFI73Z.js.map} +0 -0
- /package/dist/{stats-PW7OGIBR.js.map → stats-MYQD4OVD.js.map} +0 -0
- /package/dist/{stop-FVMLTWXU.js.map → stop-K6TDJORY.js.map} +0 -0
- /package/dist/{stop-failure-MD52CGFX.js.map → stop-failure-U635O5A3.js.map} +0 -0
- /package/dist/{subagent-start-ZJZA7EAJ.js.map → subagent-start-LLGQBC5Q.js.map} +0 -0
- /package/dist/{subagent-stop-56H22JSE.js.map → subagent-stop-BO3GZWXD.js.map} +0 -0
- /package/dist/{task-completed-TQ4WW2HW.js.map → task-completed-3ZJHSI2E.js.map} +0 -0
- /package/dist/{team-RXYFXGUT.js.map → team-OJLQCVE3.js.map} +0 -0
- /package/dist/{update-HIJUK5ZK.js.map → update-HR7WMESA.js.map} +0 -0
- /package/dist/{user-prompt-submit-SLQNTQFL.js.map → user-prompt-submit-NM73R4I3.js.map} +0 -0
- /package/dist/{verify-ITBMLK67.js.map → verify-PSERIZPF.js.map} +0 -0
- /package/dist/{version-4YUDRPU4.js.map → version-YCODQZSX.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/symbionts/installer.ts","../src/symbionts/toml-helpers.ts","../src/symbionts/settings-merge.ts","../src/symbionts/json-helpers.ts","../src/symbionts/install-helpers.ts"],"sourcesContent":["import type { SymbiontManifest } from './manifest-schema.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { findTomlSectionEnd, buildTomlMcpSection, upsertTomlSection, removeTomlSectionKeys } from './toml-helpers.js';\nimport { deepMergeSettings, deepRemoveSettings } from './settings-merge.js';\nimport { readJsonFile, writeJsonFile, writeOrDeleteJsonFile } from './json-helpers.js';\nimport { ensureAgentsMd, ensureSymlink, isMycoHookGroup } from './install-helpers.js';\n\n/** Current comment header for Myco-managed .gitignore block. */\nconst GITIGNORE_COMMENT = '# Myco managed (machine-specific)';\n\n/** Legacy comment header — recognized for cleanup during reconciliation. */\nconst GITIGNORE_SKILLS_COMMENT_LEGACY = '# Myco skill symlinks (machine-specific)';\n\n/** Wrangler cache directory created by team sync operations. */\nconst WRANGLER_CACHE_DIR = '.wrangler/';\n\n/** Subdirectory within the package where symbiont templates live. */\nconst TEMPLATES_SUBDIR = 'src/symbionts/templates';\n\n/** Filename of the hook guard template in the templates directory. */\nconst HOOK_GUARD_TEMPLATE_FILENAME = 'hook-guard.cjs';\n\n/** Filename when installed into the project .agents/ directory. */\nconst HOOK_GUARD_INSTALLED_FILENAME = 'myco-hook.cjs';\n\n/** Project-relative path where the hook guard is installed. */\nconst HOOK_GUARD_PROJECT_PATH = `.agents/${HOOK_GUARD_INSTALLED_FILENAME}`;\n\n/** Subdirectory within the package where skills live. */\nconst SKILLS_SUBDIR = 'skills';\n\n/** Canonical cross-agent skills directory. */\nconst CANONICAL_SKILLS_DIR = '.agents/skills';\n\n/** MCP server name used by Myco in all symbiont configurations. */\nexport const MYCO_MCP_SERVER_NAME = 'myco';\n\n/**\n * Marker substring written into plugin-file hook templates (e.g., opencode's plugin.ts).\n * Uninstall only deletes plugin files whose content contains this marker, so\n * contributors who hand-edit a plugin file without removing the marker are protected.\n */\nconst MYCO_PLUGIN_FILE_MARKER = 'myco:plugin-marker';\n\n/** `hooksFormat` value selecting verbatim plugin-file install over JSON merge. */\nconst HOOKS_FORMAT_PLUGIN_FILE = 'plugin-file';\n\n/** Marker text used to identify unmodified instruction stubs. */\nconst INSTRUCTIONS_STUB_MARKER = 'Edit AGENTS.md, not this file';\n\n/** Start/end markers for the reference block prepended to existing instruction files. */\nconst INSTRUCTIONS_REF_START = '<!-- myco:agents-ref:start -->';\nconst INSTRUCTIONS_REF_END = '<!-- myco:agents-ref:end -->';\n\n/** Reference block prepended to existing instruction files. */\nconst INSTRUCTIONS_REF_BLOCK = `${INSTRUCTIONS_REF_START}\n> **Project intelligence:** This project uses [Myco](https://myco.sh). The canonical project rules are in [\\`AGENTS.md\\`](AGENTS.md) — read and follow it alongside this file.\n${INSTRUCTIONS_REF_END}\n\n`;\n\nexport interface InstallResult {\n hooks: boolean;\n mcp: boolean;\n skills: boolean;\n settings: boolean;\n instructions: boolean;\n /**\n * Plugin deps package.json (e.g., .opencode/package.json). Only present for agents\n * with `registration.pluginPackageTarget` set. False otherwise.\n */\n pluginPackage: boolean;\n}\n\nexport class SymbiontInstaller {\n constructor(\n private manifest: SymbiontManifest,\n private projectRoot: string,\n private packageRoot: string,\n ) {}\n\n /**\n * Read a template file as raw text, checking both source and dist layouts.\n * `relPath` is relative to `TEMPLATES_SUBDIR` — e.g. `'hook-guard.cjs'` for\n * a shared template or `'opencode/plugin.ts'` for a per-agent template.\n */\n private readTemplateFile(relPath: string): string | null {\n const candidates = [\n path.join(this.packageRoot, TEMPLATES_SUBDIR, relPath),\n // tsup preserves the src/ prefix under dist/, so the same subdir works in both layouts\n path.join(this.packageRoot, 'dist', TEMPLATES_SUBDIR, relPath),\n ];\n for (const filePath of candidates) {\n try { return fs.readFileSync(filePath, 'utf-8'); } catch { /* try next */ }\n }\n return null;\n }\n\n /**\n * Write a Myco-managed file with a content-diff gate. Creates parent dirs as\n * needed. Returns `true` if the file was written (new or updated), `false` if\n * the on-disk content already matches and the write was skipped.\n */\n private writeManagedFile(absPath: string, content: string): boolean {\n try {\n if (fs.readFileSync(absPath, 'utf-8') === content) return false;\n } catch { /* doesn't exist — proceed */ }\n fs.mkdirSync(path.dirname(absPath), { recursive: true });\n fs.writeFileSync(absPath, content, 'utf-8');\n return true;\n }\n\n /**\n * Copy the hook-guard script into .agents/myco-hook.cjs.\n * Returns true if the file was written (or updated); false if skipped or N/A.\n */\n installHookGuard(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n const guardTemplate = this.readTemplateFile(HOOK_GUARD_TEMPLATE_FILENAME);\n if (!guardTemplate) return false;\n\n return this.writeManagedFile(\n path.join(this.projectRoot, HOOK_GUARD_PROJECT_PATH),\n guardTemplate,\n );\n }\n\n /**\n * Remove the hook-guard script from .agents/myco-hook.cjs.\n * Returns true if the file was removed; false otherwise.\n */\n uninstallHookGuard(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n const targetPath = path.join(this.projectRoot, HOOK_GUARD_PROJECT_PATH);\n try {\n fs.unlinkSync(targetPath);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Load a JSON template file for this symbiont. Returns null if not found. */\n loadTemplate(name: string): Record<string, unknown> | null {\n const raw = this.readTemplateFile(path.join(this.manifest.name, `${name}.json`));\n if (raw === null) return null;\n try { return JSON.parse(raw); } catch { return null; }\n }\n\n /**\n * Load a template file verbatim (no JSON parsing).\n * Used for plugin-file hook templates (e.g., opencode's plugin.ts) and any\n * other template that is copied to the project without structural merging.\n */\n loadTemplateRaw(filename: string): string | null {\n return this.readTemplateFile(path.join(this.manifest.name, filename));\n }\n\n /** Run all registration steps. */\n install(): InstallResult {\n const reg = this.manifest.registration;\n // Install hook guard before hooks so the guard script is in place when hooks reference it\n this.installHookGuard();\n const result = this.shouldBatchJsonTargets(reg)\n ? this.installBatchedJson(reg!)\n : {\n hooks: this.installHooks(),\n mcp: this.installMcp(),\n skills: this.installSkills(),\n settings: this.installSettings(),\n instructions: this.installInstructions(),\n pluginPackage: this.installPluginPackage(),\n };\n this.updateGitignore();\n return result;\n }\n\n /**\n * Check if ALL non-null JSON targets share the same file (e.g., Gemini).\n * Only batches when every target resolves to one path — partial overlaps\n * (e.g., Claude Code: hooks+settings share but MCP is separate) use normal path.\n *\n * Plugin-file hooks (e.g., opencode) naturally fall out of batching because their\n * hooksTarget is a distinct .ts file path, yielding a Set size ≥ 2.\n */\n private shouldBatchJsonTargets(reg: typeof this.manifest.registration): boolean {\n if (!reg) return false;\n const mcpFormat = reg.mcpFormat ?? 'json';\n if (mcpFormat !== 'json') return false;\n const targets = [reg.hooksTarget, reg.mcpTarget, reg.settingsTarget].filter(Boolean);\n return targets.length > 1 && new Set(targets).size === 1;\n }\n\n /**\n * Batched install for agents where hooks, MCP, and settings share one JSON file.\n * Single read → apply all transforms in memory → single write.\n */\n private installBatchedJson(reg: NonNullable<typeof this.manifest.registration>): InstallResult {\n const targetPath = path.join(this.projectRoot, reg.hooksTarget ?? reg.mcpTarget ?? reg.settingsTarget!);\n let data = readJsonFile(targetPath);\n let hooks = false, mcp = false, settings = false;\n\n // Apply hooks transform\n const hooksTemplate = reg.hooksTarget ? this.loadTemplate('hooks') : null;\n if (hooksTemplate) {\n const existingHooks = (data.hooks ?? {}) as Record<string, unknown[]>;\n const mergedHooks: Record<string, unknown[]> = {};\n for (const [event, groups] of Object.entries(existingHooks)) {\n const nonMyco = (groups as Array<Record<string, unknown>>).filter((g) => !isMycoHookGroup(g));\n if (nonMyco.length > 0) mergedHooks[event] = nonMyco;\n }\n for (const [event, groups] of Object.entries(hooksTemplate)) {\n mergedHooks[event] = [...(mergedHooks[event] ?? []), ...(groups as unknown[])];\n }\n data.hooks = mergedHooks;\n hooks = true;\n }\n\n // Apply MCP transform\n const mcpTemplate = reg.mcpTarget ? this.loadTemplate('mcp') : null;\n if (mcpTemplate) {\n const serversKey = reg.mcpServersKey ?? 'mcpServers';\n const servers = (data[serversKey] ?? {}) as Record<string, unknown>;\n for (const [name, def] of Object.entries(mcpTemplate)) {\n servers[name] = def;\n }\n data[serversKey] = servers;\n mcp = true;\n }\n\n // Apply settings transform\n const settingsTemplate = reg.settingsTarget ? this.loadTemplate('settings') : null;\n if (settingsTemplate) {\n data = deepMergeSettings(data, settingsTemplate);\n settings = true;\n }\n\n writeJsonFile(targetPath, data);\n\n return {\n hooks,\n mcp,\n skills: this.installSkills(),\n settings,\n instructions: this.installInstructions(),\n pluginPackage: this.installPluginPackage(),\n };\n }\n\n /** Remove all Myco registration from this symbiont's project files. */\n uninstall(): InstallResult {\n const reg = this.manifest.registration;\n const result = this.shouldBatchJsonTargets(reg)\n ? this.uninstallBatchedJson(reg!)\n : {\n hooks: this.uninstallHooks(),\n mcp: this.uninstallMcp(),\n skills: this.uninstallSkills(),\n settings: this.uninstallSettings(),\n instructions: this.uninstallInstructions(),\n pluginPackage: false,\n };\n // Remove hook guard after hooks/settings so the file is cleaned up last\n this.uninstallHookGuard();\n this.cleanGitignore();\n return result;\n }\n\n /**\n * Batched uninstall for agents where hooks, MCP, and settings share one JSON file.\n */\n private uninstallBatchedJson(reg: NonNullable<typeof this.manifest.registration>): InstallResult {\n const targetPath = path.join(this.projectRoot, reg.hooksTarget ?? reg.mcpTarget ?? reg.settingsTarget!);\n const data = readJsonFile(targetPath);\n if (Object.keys(data).length === 0) {\n return {\n hooks: false,\n mcp: false,\n skills: this.uninstallSkills(),\n settings: false,\n instructions: this.uninstallInstructions(),\n pluginPackage: false,\n };\n }\n\n let hooks = false, mcp = false, settings = false;\n\n // Remove hooks\n if (reg.hooksTarget) {\n const existingHooks = (data.hooks ?? {}) as Record<string, unknown[]>;\n if (Object.keys(existingHooks).length > 0) {\n const cleaned: Record<string, unknown[]> = {};\n for (const [event, groups] of Object.entries(existingHooks)) {\n const nonMyco = (groups as Array<Record<string, unknown>>).filter((g) => !isMycoHookGroup(g));\n if (nonMyco.length > 0) cleaned[event] = nonMyco;\n }\n if (Object.keys(cleaned).length === 0) {\n delete data.hooks;\n } else {\n data.hooks = cleaned;\n }\n hooks = true;\n }\n }\n\n // Remove MCP\n if (reg.mcpTarget) {\n const serversKey = reg.mcpServersKey ?? 'mcpServers';\n const servers = (data[serversKey] ?? {}) as Record<string, unknown>;\n if (servers[MYCO_MCP_SERVER_NAME]) {\n delete servers[MYCO_MCP_SERVER_NAME];\n if (Object.keys(servers).length === 0) delete data[serversKey];\n else data[serversKey] = servers;\n mcp = true;\n }\n }\n\n // Remove settings\n const settingsTemplate = reg.settingsTarget ? this.loadTemplate('settings') : null;\n if (settingsTemplate) {\n settings = deepRemoveSettings(data, settingsTemplate);\n }\n\n writeOrDeleteJsonFile(targetPath, data);\n\n return {\n hooks,\n mcp,\n skills: this.uninstallSkills(),\n settings,\n instructions: this.uninstallInstructions(),\n pluginPackage: false,\n };\n }\n\n /**\n * Ensure the instruction file references AGENTS.md.\n * - File doesn't exist: write the full stub template.\n * - File exists without reference: prepend a reference block.\n * - File already has reference: skip (idempotent).\n *\n * Also ensures AGENTS.md exists — creates a starter if missing.\n */\n installInstructions(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.instructionsFile) return false;\n\n // Ensure AGENTS.md exists before creating stubs that reference it\n ensureAgentsMd(this.projectRoot, this.packageRoot);\n\n const targetPath = path.join(this.projectRoot, reg.instructionsFile);\n\n // Check if file already exists\n let existing: string | null = null;\n try { existing = fs.readFileSync(targetPath, 'utf-8'); } catch { /* doesn't exist */ }\n\n if (existing !== null) {\n // File exists — check if it already has our reference\n if (existing.includes(INSTRUCTIONS_REF_START) || existing.includes(INSTRUCTIONS_STUB_MARKER)) {\n return false; // Already has reference — idempotent\n }\n // Prepend reference block to existing content\n fs.writeFileSync(targetPath, INSTRUCTIONS_REF_BLOCK + existing, 'utf-8');\n return true;\n }\n\n // File doesn't exist — write the full stub template\n const templateCandidates = [\n path.join(this.packageRoot, 'src/symbionts/templates/instructions-stub.md'),\n path.join(this.packageRoot, 'dist/src/symbionts/templates/instructions-stub.md'),\n ];\n let stub: string | null = null;\n for (const p of templateCandidates) {\n try { stub = fs.readFileSync(p, 'utf-8'); break; } catch { /* try next */ }\n }\n if (!stub) return false;\n\n stub = stub.replace('{agentDisplayName}', this.manifest.displayName);\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, stub, 'utf-8');\n return true;\n }\n\n /**\n * Remove Myco's instruction file reference.\n * - If file is the full stub (only Myco content): delete it.\n * - If file has user content + prepended reference: remove just the reference block.\n */\n uninstallInstructions(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.instructionsFile) return false;\n\n const targetPath = path.join(this.projectRoot, reg.instructionsFile);\n let content: string;\n try { content = fs.readFileSync(targetPath, 'utf-8'); } catch { return false; }\n\n // Case 1: Full stub — delete the file entirely\n if (content.includes(INSTRUCTIONS_STUB_MARKER)) {\n fs.unlinkSync(targetPath);\n return true;\n }\n\n // Case 2: Prepended reference block — remove just the block\n if (content.includes(INSTRUCTIONS_REF_START)) {\n const startIdx = content.indexOf(INSTRUCTIONS_REF_START);\n const endIdx = content.indexOf(INSTRUCTIONS_REF_END);\n if (endIdx > startIdx) {\n // Remove from start marker through end marker + trailing whitespace\n const afterEnd = endIdx + INSTRUCTIONS_REF_END.length;\n const cleaned = (content.slice(0, startIdx) + content.slice(afterEnd)).replace(/^\\n+/, '');\n fs.writeFileSync(targetPath, cleaned, 'utf-8');\n return true;\n }\n }\n\n return false;\n }\n\n /** List skill directory names from the package root. Returns empty array if not found. */\n private listSkillDirs(): string[] {\n try {\n return fs.readdirSync(path.join(this.packageRoot, SKILLS_SUBDIR), { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n } catch { return []; }\n }\n\n /**\n * Reconcile Myco-owned skill entries in project .gitignore.\n * Computes the desired entry set, strips any existing Myco block\n * (and legacy entries), then writes the current block if changed.\n */\n private updateGitignore(): void {\n const reg = this.manifest.registration;\n if (!reg?.skillsTarget) return;\n\n const skillNames = this.listSkillDirs();\n\n // Desired state: canonical per-skill entries + infrastructure artifacts.\n // Agent-specific targets (e.g. .claude/skills/) use local .gitignore files\n // instead of polluting the project-level .gitignore.\n const desired = [\n ...skillNames.map((name) => `${CANONICAL_SKILLS_DIR}/${name}`),\n WRANGLER_CACHE_DIR,\n ];\n\n const gitignorePath = path.join(this.projectRoot, '.gitignore');\n let content = '';\n try { content = fs.readFileSync(gitignorePath, 'utf-8'); } catch { /* doesn't exist yet */ }\n\n // Strip existing Myco block and any legacy entries\n const stripped = this.stripMycoGitignoreBlock(content, skillNames);\n\n // Build the new block\n const desiredBlock = desired.length > 0\n ? `${GITIGNORE_COMMENT}\\n${desired.join('\\n')}\\n`\n : '';\n\n // Check if anything changed\n if (stripped === content && desiredBlock === '') return;\n const separator = stripped.length > 0 && !stripped.endsWith('\\n') ? '\\n' : '';\n const spacer = stripped.length > 0 && desiredBlock.length > 0 ? '\\n' : '';\n const result = stripped + separator + spacer + desiredBlock;\n if (result === content) return;\n\n fs.writeFileSync(gitignorePath, result, 'utf-8');\n }\n\n /**\n * Remove all Myco-owned gitignore entries: the comment header, per-skill\n * entries for both canonical and agent-specific paths, and legacy blanket\n * directory entries. Returns the cleaned content.\n */\n private stripMycoGitignoreBlock(content: string, skillNames: string[]): string {\n const reg = this.manifest.registration;\n const ownedLines = new Set<string>([\n GITIGNORE_COMMENT,\n GITIGNORE_SKILLS_COMMENT_LEGACY,\n `${CANONICAL_SKILLS_DIR}/`, // legacy blanket entry\n WRANGLER_CACHE_DIR,\n ]);\n for (const name of skillNames) {\n ownedLines.add(`${CANONICAL_SKILLS_DIR}/${name}`);\n if (reg?.skillsTarget && reg.skillsTarget !== CANONICAL_SKILLS_DIR) {\n ownedLines.add(`${reg.skillsTarget}/${name}`);\n }\n }\n\n const lines = content.split('\\n');\n const filtered = lines.filter((line) => !ownedLines.has(line));\n return filtered.join('\\n').replace(/\\n{3,}/g, '\\n\\n').trimEnd() + (filtered.length > 0 ? '\\n' : '');\n }\n\n /**\n * Merge hooks template into the target settings file.\n * Replaces all Myco-owned hook groups; preserves non-Myco hooks.\n *\n * For plugin-file agents (e.g., opencode) this dispatches to `installPluginHookFile()`\n * which writes a verbatim .ts plugin source to hooksTarget instead of merging JSON.\n */\n installHooks(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n if (reg.hooksFormat === HOOKS_FORMAT_PLUGIN_FILE) return this.installPluginHookFile();\n\n const template = this.loadTemplate('hooks');\n if (!template) return false;\n\n const targetPath = path.join(this.projectRoot, reg.hooksTarget);\n const settings = readJsonFile(targetPath);\n const existingHooks = (settings.hooks ?? {}) as Record<string, unknown[]>;\n\n // Build merged hooks: for each event, keep non-Myco groups + add template groups\n const mergedHooks: Record<string, unknown[]> = {};\n\n // Preserve non-Myco hooks from existing config\n for (const [event, groups] of Object.entries(existingHooks)) {\n const nonMycoGroups = (groups as Array<Record<string, unknown>>).filter(\n (group) => !isMycoHookGroup(group),\n );\n if (nonMycoGroups.length > 0) {\n mergedHooks[event] = nonMycoGroups;\n }\n }\n\n // Add template hooks\n for (const [event, groups] of Object.entries(template)) {\n mergedHooks[event] = [...(mergedHooks[event] ?? []), ...(groups as unknown[])];\n }\n\n settings.hooks = mergedHooks;\n writeJsonFile(targetPath, settings);\n return true;\n }\n\n /**\n * Install a plugin-file hook target by copying a verbatim template.\n * Used for agents whose hook system is plugin-based rather than JSON entry-based\n * (e.g., opencode's TypeScript plugin system).\n */\n private installPluginHookFile(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n const templateContent = this.loadTemplateRaw('plugin.ts');\n if (templateContent === null) return false;\n\n return this.writeManagedFile(\n path.join(this.projectRoot, reg.hooksTarget),\n templateContent,\n );\n }\n\n /**\n * Remove a plugin-file hook target.\n * Only deletes files whose content contains the Myco plugin marker — contributors\n * who hand-edit the plugin file without removing the marker are protected.\n */\n private uninstallPluginHookFile(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n const targetPath = path.join(this.projectRoot, reg.hooksTarget);\n let content: string;\n try { content = fs.readFileSync(targetPath, 'utf-8'); } catch { return false; }\n\n if (!content.includes(MYCO_PLUGIN_FILE_MARKER)) return false;\n\n try {\n fs.unlinkSync(targetPath);\n // Remove parent plugins dir if now empty\n try { fs.rmdirSync(path.dirname(targetPath)); } catch { /* not empty or missing */ }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Install a plugin deps package.json for plugin-file agents (e.g., opencode).\n * Writes the template verbatim so the agent's package manager can install the SDK.\n */\n private installPluginPackage(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.pluginPackageTarget) return false;\n\n const templateContent = this.loadTemplateRaw('package.json');\n if (templateContent === null) return false;\n\n return this.writeManagedFile(\n path.join(this.projectRoot, reg.pluginPackageTarget),\n templateContent,\n );\n }\n\n /**\n * Merge MCP server template into the target config file.\n * Replaces the `myco` server entry; preserves other servers.\n */\n installMcp(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.mcpTarget) return false;\n\n const template = this.loadTemplate('mcp');\n if (!template) return false;\n\n const targetPath = path.join(this.projectRoot, reg.mcpTarget);\n if (reg.mcpFormat === 'toml') {\n return this.installMcpToml(targetPath, template);\n }\n return this.installMcpJson(targetPath, template);\n }\n\n /**\n * Write MCP servers to a JSON config file under the manifest-configured key.\n * Most agents use the canonical `mcpServers` key; opencode uses `mcp`.\n *\n * The `?? 'mcpServers'` fallback protects against test fixtures that construct\n * manifests as plain object literals and bypass the schema's default.\n */\n private installMcpJson(targetPath: string, template: Record<string, unknown>): boolean {\n const serversKey = this.manifest.registration!.mcpServersKey ?? 'mcpServers';\n const config = readJsonFile(targetPath);\n const servers = (config[serversKey] ?? {}) as Record<string, unknown>;\n\n for (const [name, def] of Object.entries(template)) {\n servers[name] = def;\n }\n\n config[serversKey] = servers;\n writeJsonFile(targetPath, config);\n return true;\n }\n\n /** Write MCP servers to a TOML config file. */\n private installMcpToml(targetPath: string, template: Record<string, unknown>): boolean {\n let raw = '';\n try { raw = fs.readFileSync(targetPath, 'utf-8'); } catch { /* doesn't exist */ }\n\n for (const [name, def] of Object.entries(template)) {\n raw = buildTomlMcpSection(raw, name, def as Record<string, unknown>);\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, raw, 'utf-8');\n return true;\n }\n\n /**\n * Create symlinks for skills through .agents/skills/ canonical layer.\n * Canonical: .agents/skills/<name> -> <packageRoot>/skills/<name>\n * Agent-specific: <skillsTarget>/<name> -> ../../.agents/skills/<name>\n */\n installSkills(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.skillsTarget) return false;\n\n const skillNames = this.listSkillDirs();\n if (skillNames.length === 0) return false;\n\n const skillsSrc = path.join(this.packageRoot, SKILLS_SUBDIR);\n\n // Create canonical symlinks: .agents/skills/<name> -> package skills\n const canonicalDir = path.join(this.projectRoot, CANONICAL_SKILLS_DIR);\n fs.mkdirSync(canonicalDir, { recursive: true });\n\n for (const name of skillNames) {\n const canonicalLink = path.join(canonicalDir, name);\n const target = path.join(skillsSrc, name);\n ensureSymlink(canonicalLink, target);\n }\n\n // Create agent-specific symlinks if skillsTarget differs from canonical\n const agentSkillsDir = path.join(this.projectRoot, reg.skillsTarget);\n const canonicalRel = path.relative(agentSkillsDir, canonicalDir);\n\n if (reg.skillsTarget !== CANONICAL_SKILLS_DIR) {\n fs.mkdirSync(agentSkillsDir, { recursive: true });\n for (const name of skillNames) {\n const agentLink = path.join(agentSkillsDir, name);\n const relTarget = path.join(canonicalRel, name);\n ensureSymlink(agentLink, relTarget);\n }\n ensureLocalSkillsGitignore(agentSkillsDir);\n }\n\n return true;\n }\n\n /**\n * Merge settings template into the target settings file.\n * JSON targets: deep-merges objects and deduplicates arrays.\n * TOML targets: emits each top-level template key as a [section] with scalar children.\n */\n installSettings(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.settingsTarget) return false;\n\n const template = this.loadTemplate('settings');\n if (!template) return false;\n\n const targetPath = path.join(this.projectRoot, reg.settingsTarget);\n const settingsFormat = reg.settingsFormat ?? 'json';\n\n if (settingsFormat === 'toml') {\n return this.installSettingsToml(targetPath, template);\n }\n\n const existing = readJsonFile(targetPath);\n const merged = deepMergeSettings(existing, template);\n writeJsonFile(targetPath, merged);\n return true;\n }\n\n /**\n * Merge a settings template into a TOML config file.\n * Each top-level key in the template becomes a [section] header, with its\n * children written as scalar key = value lines. Existing sections and keys\n * outside the template (including unrelated sections like [mcp_servers.*])\n * are preserved.\n */\n private installSettingsToml(targetPath: string, template: Record<string, unknown>): boolean {\n let raw = '';\n try { raw = fs.readFileSync(targetPath, 'utf-8'); } catch { /* doesn't exist */ }\n\n for (const [sectionName, values] of Object.entries(template)) {\n if (!values || typeof values !== 'object' || Array.isArray(values)) continue;\n raw = upsertTomlSection(raw, sectionName, values as Record<string, unknown>);\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, raw, 'utf-8');\n return true;\n }\n\n /**\n * Remove Myco entries from the target settings file.\n * Template-driven: loads the settings template and removes matching values.\n * JSON: arrays filtered by template values, object keys deleted by name.\n * TOML: removes each template key from its section; empty sections are dropped.\n */\n uninstallSettings(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.settingsTarget) return false;\n\n const template = this.loadTemplate('settings');\n if (!template) return false;\n\n const targetPath = path.join(this.projectRoot, reg.settingsTarget);\n const settingsFormat = reg.settingsFormat ?? 'json';\n\n if (settingsFormat === 'toml') {\n return this.uninstallSettingsToml(targetPath, template);\n }\n\n const settings = readJsonFile(targetPath);\n if (Object.keys(settings).length === 0) return false;\n\n const changed = deepRemoveSettings(settings, template);\n if (!changed) return false;\n\n writeOrDeleteJsonFile(targetPath, settings);\n return true;\n }\n\n /**\n * Remove template-defined keys from TOML settings file.\n * For each section in the template, deletes only the keys the template owns;\n * other keys and unrelated sections stay intact. Empty sections are stripped.\n * Deletes the file entirely if no TOML content remains.\n */\n private uninstallSettingsToml(targetPath: string, template: Record<string, unknown>): boolean {\n let raw = '';\n try { raw = fs.readFileSync(targetPath, 'utf-8'); } catch { return false; }\n if (!raw.trim()) return false;\n\n let changed = false;\n for (const [sectionName, values] of Object.entries(template)) {\n if (!values || typeof values !== 'object' || Array.isArray(values)) continue;\n const keys = Object.keys(values as Record<string, unknown>);\n const next = removeTomlSectionKeys(raw, sectionName, keys);\n if (next !== raw) {\n raw = next;\n changed = true;\n }\n }\n\n if (!changed) return false;\n\n if (!raw.trim()) {\n try { fs.unlinkSync(targetPath); } catch { /* ignore */ }\n } else {\n fs.writeFileSync(targetPath, raw, 'utf-8');\n }\n return true;\n }\n\n /**\n * Remove Myco hook groups from the target settings file.\n *\n * For plugin-file agents (e.g., opencode) this dispatches to `uninstallPluginHookFile()`\n * which deletes the verbatim plugin file (guarded by the Myco plugin marker).\n */\n uninstallHooks(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.hooksTarget) return false;\n\n if (reg.hooksFormat === HOOKS_FORMAT_PLUGIN_FILE) return this.uninstallPluginHookFile();\n\n const targetPath = path.join(this.projectRoot, reg.hooksTarget);\n const settings = readJsonFile(targetPath);\n const existingHooks = (settings.hooks ?? {}) as Record<string, unknown[]>;\n if (Object.keys(existingHooks).length === 0) return false;\n\n const cleaned: Record<string, unknown[]> = {};\n for (const [event, groups] of Object.entries(existingHooks)) {\n const nonMyco = (groups as Array<Record<string, unknown>>).filter(\n (group) => !isMycoHookGroup(group),\n );\n if (nonMyco.length > 0) {\n cleaned[event] = nonMyco;\n }\n }\n\n if (Object.keys(cleaned).length === 0) {\n delete settings.hooks;\n } else {\n settings.hooks = cleaned;\n }\n\n writeOrDeleteJsonFile(targetPath, settings);\n return true;\n }\n\n /** Remove Myco MCP server entry from the target config file. */\n uninstallMcp(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.mcpTarget) return false;\n\n const targetPath = path.join(this.projectRoot, reg.mcpTarget);\n if (reg.mcpFormat === 'toml') {\n return this.uninstallMcpToml(targetPath);\n }\n return this.uninstallMcpJson(targetPath);\n }\n\n private uninstallMcpJson(targetPath: string): boolean {\n // Fallback matches the schema default; protects test fixtures that bypass .parse().\n const serversKey = this.manifest.registration!.mcpServersKey ?? 'mcpServers';\n const config = readJsonFile(targetPath);\n const servers = (config[serversKey] ?? {}) as Record<string, unknown>;\n if (!servers[MYCO_MCP_SERVER_NAME]) return false;\n\n delete servers[MYCO_MCP_SERVER_NAME];\n\n if (Object.keys(servers).length === 0) {\n delete config[serversKey];\n } else {\n config[serversKey] = servers;\n }\n\n writeOrDeleteJsonFile(targetPath, config);\n return true;\n }\n\n private uninstallMcpToml(targetPath: string): boolean {\n let raw = '';\n try { raw = fs.readFileSync(targetPath, 'utf-8'); } catch { return false; }\n\n const sectionHeader = `[mcp_servers.${MYCO_MCP_SERVER_NAME}]`;\n if (!raw.includes(sectionHeader)) return false;\n\n const startIdx = raw.indexOf(sectionHeader);\n const endIdx = findTomlSectionEnd(raw, startIdx + sectionHeader.length, `mcp_servers.${MYCO_MCP_SERVER_NAME}`);\n const before = raw.slice(0, startIdx).trimEnd();\n const after = raw.slice(endIdx).trimStart();\n const updated = (before + (before && after ? '\\n\\n' : '') + after).trimEnd();\n\n if (!updated.trim()) {\n try { fs.unlinkSync(targetPath); } catch { /* ignore */ }\n } else {\n fs.writeFileSync(targetPath, updated + '\\n', 'utf-8');\n }\n return true;\n }\n\n /** Remove skill symlinks (canonical + agent-specific). */\n uninstallSkills(): boolean {\n const reg = this.manifest.registration;\n if (!reg?.skillsTarget) return false;\n\n const skillNames = this.listSkillDirs();\n if (skillNames.length === 0) return false;\n\n let removed = false;\n\n // Remove agent-specific symlinks\n if (reg.skillsTarget !== CANONICAL_SKILLS_DIR) {\n for (const name of skillNames) {\n const link = path.join(this.projectRoot, reg.skillsTarget, name);\n try { fs.unlinkSync(link); removed = true; } catch { /* doesn't exist */ }\n }\n // Remove agent skills dir if now empty (rmdirSync fails atomically if non-empty)\n try { fs.rmdirSync(path.join(this.projectRoot, reg.skillsTarget)); } catch { /* not empty or missing */ }\n }\n\n // Remove canonical symlinks\n const canonicalDir = path.join(this.projectRoot, CANONICAL_SKILLS_DIR);\n for (const name of skillNames) {\n const link = path.join(canonicalDir, name);\n try { fs.unlinkSync(link); removed = true; } catch { /* doesn't exist */ }\n }\n // Remove empty dirs (rmdirSync fails atomically if non-empty)\n try { fs.rmdirSync(canonicalDir); } catch { /* not empty or missing */ }\n try { fs.rmdirSync(path.join(this.projectRoot, '.agents')); } catch { /* not empty or missing */ }\n\n return removed;\n }\n\n /** Remove Myco entries from project .gitignore. */\n private cleanGitignore(): void {\n const gitignorePath = path.join(this.projectRoot, '.gitignore');\n let content = '';\n try { content = fs.readFileSync(gitignorePath, 'utf-8'); } catch { return; }\n\n const cleaned = this.stripMycoGitignoreBlock(content, this.listSkillDirs()).trim();\n if (cleaned) {\n fs.writeFileSync(gitignorePath, cleaned + '\\n', 'utf-8');\n } else {\n try { fs.unlinkSync(gitignorePath); } catch { /* ignore */ }\n }\n }\n}\n\n/**\n * Create agent-specific symlinks for a skill in `.agents/skills/<name>`.\n *\n * Reads all symbiont manifests to find skillsTarget paths that differ\n * from the canonical `.agents/skills/` directory, then creates relative\n * symlinks from each target to the canonical location.\n *\n * Called by vault_write_skill after writing a generated skill to disk.\n * Also handles removal: when `remove` is true, deletes the symlinks.\n */\nexport function syncSkillSymlinks(\n projectRoot: string,\n skillName: string,\n opts?: { remove?: boolean },\n): void {\n // Resolve manifests dir — try sibling (source layout) then dist layout\n // (tsup bundles into dist/chunk-*.js, but manifests are at dist/src/symbionts/manifests/)\n const selfDir = path.dirname(new URL(import.meta.url).pathname);\n const candidates = [\n path.join(selfDir, 'manifests'),\n path.join(selfDir, 'src', 'symbionts', 'manifests'),\n ];\n const manifestDir = candidates.find((d) => fs.existsSync(d));\n if (!manifestDir) return;\n\n const targets = new Set<string>();\n for (const file of fs.readdirSync(manifestDir).filter((f) => f.endsWith('.yaml'))) {\n try {\n const content = fs.readFileSync(path.join(manifestDir, file), 'utf-8');\n const match = content.match(/skillsTarget:\\s*(.+)/);\n if (match) targets.add(match[1].trim());\n } catch { /* skip unreadable manifests */ }\n }\n\n for (const target of targets) {\n if (target === CANONICAL_SKILLS_DIR) continue; // canonical is the source, not a link target\n\n const agentSkillsDir = path.join(projectRoot, target);\n const linkPath = path.join(agentSkillsDir, skillName);\n\n if (opts?.remove) {\n try { fs.unlinkSync(linkPath); } catch { /* doesn't exist */ }\n try { fs.rmdirSync(agentSkillsDir); } catch { /* not empty or missing */ }\n } else {\n fs.mkdirSync(agentSkillsDir, { recursive: true });\n const canonicalDir = path.join(projectRoot, CANONICAL_SKILLS_DIR);\n const relTarget = path.join(path.relative(agentSkillsDir, canonicalDir), skillName);\n ensureSymlink(linkPath, relTarget);\n // Ensure a local .gitignore ignores all symlinks in this directory.\n // Localized to the agent's skills dir — doesn't pollute the project .gitignore.\n ensureLocalSkillsGitignore(agentSkillsDir);\n }\n }\n}\n\n/** Content for the local .gitignore that ignores Myco-created symlinks. */\nconst LOCAL_SKILLS_GITIGNORE = `# Myco-managed symlinks — generated skills are symlinked here automatically.\n# The canonical location for all skills is .agents/skills/.\n#\n# To add your own skill to this directory, un-ignore it:\n# !my-skill\n*\n!.gitignore\n`;\n\n/**\n * Write a .gitignore inside an agent's skills directory that ignores all\n * symlinks Myco creates there. Idempotent — skips if already present.\n */\nfunction ensureLocalSkillsGitignore(agentSkillsDir: string): void {\n const gitignorePath = path.join(agentSkillsDir, '.gitignore');\n try {\n if (fs.readFileSync(gitignorePath, 'utf-8') === LOCAL_SKILLS_GITIGNORE) return;\n } catch { /* doesn't exist — proceed */ }\n fs.writeFileSync(gitignorePath, LOCAL_SKILLS_GITIGNORE, 'utf-8');\n}\n","/** TOML section header pattern. */\nconst TOML_SECTION_RE = /^\\[([^\\]]+)\\]/;\n\n/**\n * Find where a named TOML section ends.\n *\n * Walks forward from `searchStart` until it hits a section header that is\n * NEITHER the named section itself NOR any of its subtables (headers that\n * start with `${sectionName}.`). Returns `raw.length` if the section extends\n * to the end of the file.\n */\nexport function findTomlSectionEnd(\n raw: string,\n searchStart: number,\n sectionName: string,\n): number {\n const subsectionPrefix = `${sectionName}.`;\n const rawLines = raw.slice(searchStart).split('\\n');\n let offset = searchStart;\n for (const line of rawLines) {\n offset += line.length + 1;\n const m = line.match(TOML_SECTION_RE);\n if (m && !m[1].startsWith(subsectionPrefix) && m[1] !== sectionName) {\n return offset - line.length - 1;\n }\n }\n return raw.length;\n}\n\n/** Format a single TOML key = value line from a JS value. Skips unsupported types. */\nfunction formatTomlScalarLine(key: string, val: unknown): string | null {\n if (typeof val === 'string') return `${key} = \"${val}\"`;\n if (typeof val === 'boolean') return `${key} = ${val}`;\n if (typeof val === 'number' && Number.isFinite(val)) return `${key} = ${val}`;\n if (Array.isArray(val)) {\n return `${key} = [${val.map((v: unknown) => `\"${v}\"`).join(', ')}]`;\n }\n return null;\n}\n\n/**\n * Insert or replace a top-level TOML section with the given scalar key/value pairs.\n *\n * - Scalar values (string, boolean, number, string[]) are written as `key = value`.\n * - Nested objects are ignored — use {@link buildTomlMcpSection} or call\n * `upsertTomlSection` once per subtable if you need nested tables.\n * - Idempotent: running twice with the same inputs produces identical output.\n * - Preserves content before and after the section.\n */\nexport function upsertTomlSection(\n raw: string,\n sectionName: string,\n values: Record<string, unknown>,\n): string {\n const sectionHeader = `[${sectionName}]`;\n\n const lines: string[] = [sectionHeader];\n for (const [key, val] of Object.entries(values)) {\n const line = formatTomlScalarLine(key, val);\n if (line !== null) lines.push(line);\n }\n const block = lines.join('\\n');\n\n if (raw.includes(sectionHeader)) {\n const startIdx = raw.indexOf(sectionHeader);\n const endIdx = findTomlSectionEnd(raw, startIdx + sectionHeader.length, sectionName);\n const before = raw.slice(0, startIdx).trimEnd();\n const after = raw.slice(endIdx);\n const separator = before ? '\\n\\n' : '';\n return (before + separator + block + after).trimEnd() + '\\n';\n }\n\n const separator = raw.trim() ? '\\n\\n' : '';\n return (raw.trimEnd() + separator + block).trimEnd() + '\\n';\n}\n\n/**\n * Remove specific keys from a top-level TOML section.\n *\n * - Only the listed keys are removed. Other keys in the section are preserved.\n * - If the section ends up with no content after removal, the whole section\n * (header and body) is stripped.\n * - Returns the updated string; equal to the input if no changes were made.\n */\nexport function removeTomlSectionKeys(\n raw: string,\n sectionName: string,\n keys: string[],\n): string {\n const sectionHeader = `[${sectionName}]`;\n if (!raw.includes(sectionHeader)) return raw;\n\n const startIdx = raw.indexOf(sectionHeader);\n const endIdx = findTomlSectionEnd(raw, startIdx + sectionHeader.length, sectionName);\n const sectionBody = raw.slice(startIdx + sectionHeader.length, endIdx);\n\n const keyRes = keys.map((k) => new RegExp(`^\\\\s*${escapeRegExp(k)}\\\\s*=`));\n const bodyLines = sectionBody.split('\\n');\n const kept: string[] = [];\n let removedAny = false;\n let subtableSeen = false;\n for (const line of bodyLines) {\n // Once we hit a subtable header, everything after stays (keys belong to the parent)\n if (subtableSeen || TOML_SECTION_RE.test(line.trim())) {\n subtableSeen = true;\n kept.push(line);\n continue;\n }\n if (keyRes.some((re) => re.test(line))) {\n removedAny = true;\n continue;\n }\n kept.push(line);\n }\n if (!removedAny) return raw;\n\n // Determine whether the parent section still has any key = value lines.\n const hasRemainingKeys = kept.some((line) => {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) return false;\n if (TOML_SECTION_RE.test(trimmed)) return false;\n return /=/.test(trimmed);\n });\n\n const before = raw.slice(0, startIdx).trimEnd();\n let rebuilt: string;\n if (hasRemainingKeys) {\n const newBody = kept.join('\\n');\n const separator = before ? '\\n\\n' : '';\n rebuilt = before + separator + sectionHeader + newBody;\n } else {\n // Drop the header entirely; keep any trailing subtables we preserved above.\n const trailing = kept.join('\\n').trimStart();\n const separator = before && trailing ? '\\n\\n' : '';\n rebuilt = before + separator + trailing;\n }\n return rebuilt.trimEnd() + (rebuilt.trim() ? '\\n' : '');\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Build/update a specific mcp_servers entry in a TOML string.\n * Pure transformation — returns updated content without writing to disk.\n *\n * Handles the MCP-specific `env` subtable pattern; for plain sections use\n * {@link upsertTomlSection}.\n */\nexport function buildTomlMcpSection(\n raw: string,\n serverName: string,\n server: Record<string, unknown>,\n): string {\n const sectionName = `mcp_servers.${serverName}`;\n const sectionHeader = `[${sectionName}]`;\n\n // Build the TOML block for this server\n const lines: string[] = [sectionHeader];\n for (const [key, val] of Object.entries(server)) {\n if (key === 'env' && typeof val === 'object' && val !== null) continue; // Handle env as subtable\n const line = formatTomlScalarLine(key, val);\n if (line !== null) lines.push(line);\n }\n\n // Add env subtable if present\n const env = server.env as Record<string, string> | undefined;\n if (env && Object.keys(env).length > 0) {\n lines.push('');\n lines.push(`[${sectionName}.env]`);\n for (const [key, val] of Object.entries(env)) {\n lines.push(`${key} = \"${val}\"`);\n }\n }\n\n const block = lines.join('\\n');\n\n let updated: string;\n if (raw.includes(sectionHeader)) {\n const startIdx = raw.indexOf(sectionHeader);\n const endIdx = findTomlSectionEnd(raw, startIdx + sectionHeader.length, sectionName);\n const before = raw.slice(0, startIdx).trimEnd();\n const after = raw.slice(endIdx);\n const separator = before ? '\\n\\n' : '';\n updated = (before + separator + block + after).trimEnd() + '\\n';\n } else {\n // Append new section\n const separator = raw.trim() ? '\\n\\n' : '';\n updated = (raw.trimEnd() + separator + block).trimEnd() + '\\n';\n }\n\n return updated;\n}\n","/** Deep merge two settings objects. Arrays are appended + deduplicated; objects recurse. */\nexport function deepMergeSettings(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...target };\n for (const [key, sourceVal] of Object.entries(source)) {\n const targetVal = result[key];\n if (Array.isArray(sourceVal) && Array.isArray(targetVal)) {\n result[key] = [...new Set([...targetVal, ...sourceVal])];\n } else if (isPlainObject(sourceVal) && isPlainObject(targetVal)) {\n result[key] = deepMergeSettings(\n targetVal as Record<string, unknown>,\n sourceVal as Record<string, unknown>,\n );\n } else {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n\nexport function isPlainObject(val: unknown): val is Record<string, unknown> {\n return typeof val === 'object' && val !== null && !Array.isArray(val);\n}\n\n/**\n * Remove values from target that match the template structure.\n * Arrays: filter out values present in the template array.\n * Objects: delete keys present in the template object, recurse into nested objects.\n * Returns true if anything was removed.\n */\nexport function deepRemoveSettings(\n target: Record<string, unknown>,\n template: Record<string, unknown>,\n): boolean {\n let changed = false;\n for (const [key, templateVal] of Object.entries(template)) {\n const targetVal = target[key];\n if (targetVal === undefined) continue;\n\n if (Array.isArray(templateVal) && Array.isArray(targetVal)) {\n // Filter out values that appear in the template array\n const templateSet = new Set(templateVal.map(String));\n const filtered = targetVal.filter((v) => !templateSet.has(String(v)));\n if (filtered.length !== targetVal.length) {\n if (filtered.length > 0) {\n target[key] = filtered;\n } else {\n delete target[key];\n }\n changed = true;\n }\n } else if (isPlainObject(templateVal) && isPlainObject(targetVal)) {\n // Recurse into nested objects, then prune if empty\n if (deepRemoveSettings(targetVal, templateVal)) {\n if (Object.keys(targetVal).length === 0) {\n delete target[key];\n }\n changed = true;\n }\n } else {\n // Scalar: delete if value matches\n if (String(targetVal) === String(templateVal)) {\n delete target[key];\n changed = true;\n }\n }\n }\n return changed;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport function readJsonFile(filePath: string): Record<string, unknown> {\n try {\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function writeJsonFile(filePath: string, data: Record<string, unknown>): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n}\n\n/** Write a JSON file, or delete it if the object is empty. */\nexport function writeOrDeleteJsonFile(filePath: string, data: Record<string, unknown>): void {\n if (Object.keys(data).length === 0) {\n try { fs.unlinkSync(filePath); } catch { /* ignore */ }\n } else {\n writeJsonFile(filePath, data);\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/** Prefix used to identify Myco-owned hooks in settings files. */\nconst MYCO_HOOK_COMMAND_PREFIX = 'myco-run';\nconst MYCO_HOOK_GUARD_PREFIX = 'node .agents/myco-hook.cjs';\n\n/** Check if a command string belongs to Myco (old or new guard format). */\nexport function isMycoHookCommand(command: string): boolean {\n return command.startsWith(MYCO_HOOK_COMMAND_PREFIX) || command.startsWith(MYCO_HOOK_GUARD_PREFIX);\n}\n\n/**\n * Check if a hook group is Myco-owned.\n * Handles both nested format (Claude Code, Codex, etc.) and flat format (Windsurf).\n *\n * Nested: { hooks: [{ command: \"node .agents/myco-hook.cjs ...\" }] }\n * Flat: { command: \"node .agents/myco-hook.cjs ...\" }\n */\nexport function isMycoHookGroup(group: Record<string, unknown>): boolean {\n // Nested format: { hooks: [{ command: \"...\" }] }\n if (Array.isArray(group.hooks) && group.hooks.some((h: { command?: string }) => h.command && isMycoHookCommand(h.command))) return true;\n // Flat format: { command: \"...\" }\n if (typeof group.command === 'string' && isMycoHookCommand(group.command)) return true;\n return false;\n}\n\n/**\n * Create a starter AGENTS.md if the project doesn't have one.\n * Idempotent — skips if AGENTS.md already exists.\n */\nexport function ensureAgentsMd(projectRoot: string, packageRoot: string): void {\n const agentsMdPath = path.join(projectRoot, 'AGENTS.md');\n if (fs.existsSync(agentsMdPath)) return;\n\n const candidates = [\n path.join(packageRoot, 'src/symbionts/templates/agents-starter.md'),\n path.join(packageRoot, 'dist/src/symbionts/templates/agents-starter.md'),\n ];\n for (const p of candidates) {\n try {\n const content = fs.readFileSync(p, 'utf-8');\n fs.writeFileSync(agentsMdPath, content, 'utf-8');\n return;\n } catch { /* try next */ }\n }\n}\n\nexport function ensureSymlink(linkPath: string, target: string): void {\n try {\n if (fs.readlinkSync(linkPath) === target) return;\n } catch { /* does not exist or is not a symlink — proceed */ }\n try { fs.rmSync(linkPath, { recursive: true, force: true }); } catch { /* ignore */ }\n fs.symlinkSync(target, linkPath);\n}\n"],"mappings":"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","names":["fs","path","separator","fs","path","path","fs"]}
|
|
@@ -81,7 +81,7 @@ var POWER_DEEP_SLEEP_THRESHOLD_MS = 90 * 60 * MS_PER_SECOND;
|
|
|
81
81
|
var POWER_ACTIVE_INTERVAL_MS = 60 * MS_PER_SECOND;
|
|
82
82
|
var POWER_SLEEP_INTERVAL_MS = 5 * 60 * MS_PER_SECOND;
|
|
83
83
|
var STALE_SESSION_THRESHOLD_MS = 60 * 60 * MS_PER_SECOND;
|
|
84
|
-
var DEAD_SESSION_MAX_PROMPTS =
|
|
84
|
+
var DEAD_SESSION_MAX_PROMPTS = 0;
|
|
85
85
|
var RECOMMENDED_LOCAL_CONTEXT_WINDOW = 8192;
|
|
86
86
|
var DEFAULT_OLLAMA_EMBEDDING_MODEL = "bge-m3";
|
|
87
87
|
var DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
|
|
@@ -179,4 +179,4 @@ export {
|
|
|
179
179
|
WRANGLER_COMMAND_TIMEOUT_MS,
|
|
180
180
|
RESTART_RESPONSE_FLUSH_MS
|
|
181
181
|
};
|
|
182
|
-
//# sourceMappingURL=chunk-
|
|
182
|
+
//# sourceMappingURL=chunk-6SDC6V3N.js.map
|
|
@@ -1 +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/** 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/** Max prompt count for a session to be considered dead and auto-deleted. */\nexport const DEAD_SESSION_MAX_PROMPTS = 1;\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,8BAA8B;AAGpC,IAAM,cAAc;AAGpB,IAAM,mBAAmB;AAGzB,IAAM,8BAA8B;AAGpC,IAAM,mBAAmB,CAAC,UAAU,MAAM;AAI1C,IAAM,0BAA0C;;;ACrBhD,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;AAE7C,IAAM,2BAA2B;AAOjC,IAAM,mCAAmC;AAGzC,IAAM,iCAAiC;AAGvC,IAAM,iCAAiC;AAIvC,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":[]}
|
|
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/** 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,8BAA8B;AAGpC,IAAM,cAAc;AAGpB,IAAM,mBAAmB;AAGzB,IAAM,8BAA8B;AAGpC,IAAM,mBAAmB,CAAC,UAAU,MAAM;AAI1C,IAAM,0BAA0C;;;ACrBhD,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;AAOjC,IAAM,mCAAmC;AAGzC,IAAM,iCAAiC;AAGvC,IAAM,iCAAiC;AAIvC,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":[]}
|
|
@@ -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-
|
|
5
|
+
} from "./chunk-DKSQMH5X.js";
|
|
6
6
|
import {
|
|
7
7
|
PROVIDER_DETECT_TIMEOUT_MS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6SDC6V3N.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-
|
|
22
|
+
//# sourceMappingURL=chunk-CPL76CYD.js.map
|
|
@@ -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-
|
|
6
|
+
} from "./chunk-6SDC6V3N.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-
|
|
328
|
+
//# sourceMappingURL=chunk-DKSQMH5X.js.map
|
|
@@ -18,8 +18,28 @@ var CaptureManifestSchema = external_exports.object({
|
|
|
18
18
|
});
|
|
19
19
|
var RegistrationSchema = external_exports.object({
|
|
20
20
|
hooksTarget: external_exports.string().optional(),
|
|
21
|
+
/**
|
|
22
|
+
* Format of the hooks target.
|
|
23
|
+
* - 'json' (default): hooks template is merged into a JSON settings file.
|
|
24
|
+
* - 'plugin-file': the hooks template is a verbatim file (e.g., an opencode TS plugin)
|
|
25
|
+
* copied to hooksTarget without JSON parsing. Used for agents with plugin-based hook
|
|
26
|
+
* systems rather than JSON hook entries.
|
|
27
|
+
*/
|
|
28
|
+
hooksFormat: external_exports.enum(["json", "plugin-file"]).default("json"),
|
|
29
|
+
/**
|
|
30
|
+
* Optional file path for a plugin deps package.json. When set, the installer writes
|
|
31
|
+
* a package.json declaring the plugin SDK dependency so the agent's package manager
|
|
32
|
+
* (e.g., opencode's Bun) can install it at startup. Preserved on uninstall so
|
|
33
|
+
* contributors can keep their own deps.
|
|
34
|
+
*/
|
|
35
|
+
pluginPackageTarget: external_exports.string().optional(),
|
|
21
36
|
mcpTarget: external_exports.string().optional(),
|
|
22
37
|
mcpFormat: external_exports.enum(["json", "toml"]).default("json"),
|
|
38
|
+
/**
|
|
39
|
+
* JSON key under which MCP server entries are stored in the MCP config file.
|
|
40
|
+
* Defaults to 'mcpServers' (used by Claude Code, Cursor, etc.). opencode uses 'mcp'.
|
|
41
|
+
*/
|
|
42
|
+
mcpServersKey: external_exports.string().default("mcpServers"),
|
|
23
43
|
skillsTarget: external_exports.string().optional(),
|
|
24
44
|
settingsTarget: external_exports.string().optional(),
|
|
25
45
|
/** Format of the settings file. TOML-format agents (e.g., Codex) emit top-level template keys as TOML sections. */
|
|
@@ -107,4 +127,4 @@ export {
|
|
|
107
127
|
detectSymbionts,
|
|
108
128
|
resolvePackageRoot
|
|
109
129
|
};
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
130
|
+
//# sourceMappingURL=chunk-EBIYONNZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/symbionts/manifest-schema.ts","../src/symbionts/detect.ts"],"sourcesContent":["import { z } from 'zod';\n\nconst CaptureManifestSchema = z.object({\n planDirs: z.array(z.string()).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":"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","names":["YAML"]}
|
|
@@ -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-
|
|
4
|
+
} from "./chunk-6SDC6V3N.js";
|
|
5
5
|
import {
|
|
6
6
|
require_dist
|
|
7
7
|
} from "./chunk-D7TYRPRM.js";
|
|
@@ -404,4 +404,4 @@ export {
|
|
|
404
404
|
getEnabledSymbiontNames,
|
|
405
405
|
updateTeamConfig
|
|
406
406
|
};
|
|
407
|
-
//# sourceMappingURL=chunk-
|
|
407
|
+
//# sourceMappingURL=chunk-FEX6ALLH.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
SEARCH_PREVIEW_CHARS,
|
|
7
7
|
SEARCH_RESULTS_DEFAULT_LIMIT
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6SDC6V3N.js";
|
|
9
9
|
|
|
10
10
|
// src/db/queries/search.ts
|
|
11
11
|
function fullTextSearch(query, options = {}) {
|
|
@@ -203,4 +203,4 @@ export {
|
|
|
203
203
|
fullTextSearch,
|
|
204
204
|
hydrateSearchResults
|
|
205
205
|
};
|
|
206
|
-
//# sourceMappingURL=chunk-
|
|
206
|
+
//# sourceMappingURL=chunk-GBYLHPML.js.map
|
|
@@ -2,7 +2,7 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
|
|
|
2
2
|
import {
|
|
3
3
|
EMBEDDING_REQUEST_TIMEOUT_MS,
|
|
4
4
|
PROVIDER_DETECT_TIMEOUT_MS
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6SDC6V3N.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/providers/cloud-embedding-base.ts
|
|
8
8
|
var ERROR_BODY_PREVIEW_CHARS = 500;
|
|
@@ -63,4 +63,4 @@ var CloudEmbeddingBase = class {
|
|
|
63
63
|
export {
|
|
64
64
|
CloudEmbeddingBase
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-KGL5QSDN.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-MYX5NCRH.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_MACHINE_ID
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6SDC6V3N.js";
|
|
8
8
|
|
|
9
9
|
// src/daemon/team-context.ts
|
|
10
10
|
var teamSyncEnabled = false;
|
|
@@ -224,4 +224,4 @@ export {
|
|
|
224
224
|
markSourceRowsSynced,
|
|
225
225
|
backfillUnsynced
|
|
226
226
|
};
|
|
227
|
-
//# sourceMappingURL=chunk-
|
|
227
|
+
//# sourceMappingURL=chunk-KKEMVH6D.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-
|
|
4
|
+
} from "./chunk-4JPUC6RL.js";
|
|
5
5
|
import {
|
|
6
6
|
LmStudioBackend,
|
|
7
7
|
OllamaBackend
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DKSQMH5X.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-
|
|
16
|
+
} from "./chunk-U63GDHYJ.js";
|
|
17
17
|
|
|
18
18
|
// src/cli/shared.ts
|
|
19
19
|
import fs from "fs";
|
|
@@ -86,7 +86,8 @@ function registerSymbionts(manifests, projectRoot, packageRoot, verb) {
|
|
|
86
86
|
result.mcp && "MCP server",
|
|
87
87
|
result.skills && "skills",
|
|
88
88
|
result.settings && "settings",
|
|
89
|
-
result.instructions && "instructions"
|
|
89
|
+
result.instructions && "instructions",
|
|
90
|
+
result.pluginPackage && "plugin deps"
|
|
90
91
|
].filter(Boolean);
|
|
91
92
|
if (installed.length > 0) {
|
|
92
93
|
console.log(` \u2713 ${verb} ${manifest.displayName}: ${installed.join(", ")}`);
|
|
@@ -109,4 +110,4 @@ export {
|
|
|
109
110
|
VAULT_GITIGNORE,
|
|
110
111
|
registerSymbionts
|
|
111
112
|
};
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
113
|
+
//# sourceMappingURL=chunk-MSM775XQ.js.map
|
|
@@ -1 +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# Binary attachments — screenshots captured from transcripts\nattachments/\n\n# Team worker deployment — patched wrangler.toml + source copy\n.team-worker/\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 ].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;AAmCxB,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,
|
|
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# Binary attachments — screenshots captured from transcripts\nattachments/\n\n# Team worker deployment — patched wrangler.toml + source copy\n.team-worker/\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;AAmCxB,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,7 +2,7 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
|
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_MACHINE_ID,
|
|
4
4
|
epochSeconds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6SDC6V3N.js";
|
|
6
6
|
|
|
7
7
|
// src/db/schema-ddl.ts
|
|
8
8
|
var SCHEMA_VERSION_TABLE = `
|
|
@@ -1014,4 +1014,4 @@ export {
|
|
|
1014
1014
|
EMBEDDING_DIMENSIONS,
|
|
1015
1015
|
createSchema
|
|
1016
1016
|
};
|
|
1017
|
-
//# sourceMappingURL=chunk-
|
|
1017
|
+
//# sourceMappingURL=chunk-OGNEW5CN.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.
|
|
14
|
+
cached = "0.17.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-
|
|
35
|
+
//# sourceMappingURL=chunk-PFF4KB4O.js.map
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
normalizeHookInput,
|
|
7
7
|
readStdin
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2WRXLYG6.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveVaultDir
|
|
11
11
|
} from "./chunk-5ZT2Q6P5.js";
|
|
12
12
|
import {
|
|
13
13
|
DaemonClient
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-U63GDHYJ.js";
|
|
15
15
|
|
|
16
16
|
// src/hooks/send-event.ts
|
|
17
17
|
import fs from "fs";
|
|
@@ -39,4 +39,4 @@ async function sendEvent(hookName, buildEvent) {
|
|
|
39
39
|
export {
|
|
40
40
|
sendEvent
|
|
41
41
|
};
|
|
42
|
-
//# sourceMappingURL=chunk-
|
|
42
|
+
//# sourceMappingURL=chunk-QBB6LX57.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
OpenRouterEmbeddingProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-U3SSOSIR.js";
|
|
5
5
|
import {
|
|
6
6
|
OpenAIEmbeddingProvider
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-Y7QCKCEJ.js";
|
|
8
8
|
import {
|
|
9
9
|
LmStudioBackend,
|
|
10
10
|
OllamaBackend
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DKSQMH5X.js";
|
|
12
12
|
import {
|
|
13
13
|
LLM_REQUEST_TIMEOUT_MS
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6SDC6V3N.js";
|
|
15
15
|
|
|
16
16
|
// node_modules/@anthropic-ai/sdk/internal/tslib.mjs
|
|
17
17
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
@@ -4933,4 +4933,4 @@ export {
|
|
|
4933
4933
|
createLlmProvider,
|
|
4934
4934
|
createEmbeddingProvider
|
|
4935
4935
|
};
|
|
4936
|
-
//# sourceMappingURL=chunk-
|
|
4936
|
+
//# sourceMappingURL=chunk-QQ7CXA7Q.js.map
|