@goondocks/myco 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +9 -4
  4. package/commands/init.md +63 -39
  5. package/commands/setup-llm.md +69 -44
  6. package/commands/status.md +28 -10
  7. package/dist/{chunk-YFG2O5HR.js → chunk-2GJFTIWX.js} +2 -2
  8. package/dist/chunk-4FCFRJIQ.js +147 -0
  9. package/dist/chunk-4FCFRJIQ.js.map +1 -0
  10. package/dist/{chunk-PA3VMINE.js → chunk-AK6GNLPV.js} +6 -1
  11. package/dist/chunk-AK6GNLPV.js.map +1 -0
  12. package/dist/{chunk-JKOALBZC.js → chunk-BNIYWCST.js} +2 -2
  13. package/dist/{chunk-ISCT2SI6.js → chunk-G6ZMTQMJ.js} +7357 -60
  14. package/dist/chunk-G6ZMTQMJ.js.map +1 -0
  15. package/dist/{chunk-7WNE22W7.js → chunk-IVS5MYBL.js} +3 -3
  16. package/dist/{chunk-7WNE22W7.js.map → chunk-IVS5MYBL.js.map} +1 -1
  17. package/dist/{chunk-7VPJK56U.js → chunk-JBD5KP5G.js} +31 -16
  18. package/dist/chunk-JBD5KP5G.js.map +1 -0
  19. package/dist/chunk-NUA7UTIY.js +37 -0
  20. package/dist/chunk-NUA7UTIY.js.map +1 -0
  21. package/dist/{chunk-NYAWCMRZ.js → chunk-OUFSLZTX.js} +4 -4
  22. package/dist/chunk-P7RNAYU7.js +242 -0
  23. package/dist/chunk-P7RNAYU7.js.map +1 -0
  24. package/dist/chunk-QQ36XEJP.js +38 -0
  25. package/dist/chunk-QQ36XEJP.js.map +1 -0
  26. package/dist/chunk-RDXTQ436.js +49 -0
  27. package/dist/chunk-RDXTQ436.js.map +1 -0
  28. package/dist/{chunk-AWF3M57N.js → chunk-S7EIHYE7.js} +8 -8
  29. package/dist/{chunk-AWF3M57N.js.map → chunk-S7EIHYE7.js.map} +1 -1
  30. package/dist/{chunk-QWU7QLZI.js → chunk-TZDDXRHG.js} +10 -10
  31. package/dist/chunk-TZDDXRHG.js.map +1 -0
  32. package/dist/chunk-VYV5IFD6.js +99 -0
  33. package/dist/chunk-VYV5IFD6.js.map +1 -0
  34. package/dist/{chunk-LR7RQCOB.js → chunk-XCPQHC4X.js} +2 -2
  35. package/dist/{chunk-CCIV47S4.js → chunk-XHWIIU5D.js} +8 -9
  36. package/dist/chunk-XHWIIU5D.js.map +1 -0
  37. package/dist/{chunk-FFQNE6CT.js → chunk-YZO22BBI.js} +45 -31
  38. package/dist/chunk-YZO22BBI.js.map +1 -0
  39. package/dist/{chunk-ZBNT6E22.js → chunk-ZCBL5HER.js} +2 -2
  40. package/dist/{cli-3WQSDSW6.js → cli-ZN6VBA7V.js} +23 -17
  41. package/dist/cli-ZN6VBA7V.js.map +1 -0
  42. package/dist/{client-5T4M42UQ.js → client-5SUO2UYH.js} +5 -5
  43. package/dist/{config-MD4XMLUS.js → config-4GGMWGAF.js} +4 -4
  44. package/dist/{detect-providers-LNOLBICR.js → detect-providers-5FU3BN5Q.js} +3 -3
  45. package/dist/{init-RALMQKOQ.js → init-7UXGDOFS.js} +51 -60
  46. package/dist/init-7UXGDOFS.js.map +1 -0
  47. package/dist/{main-S3WSUF5T.js → main-6UPAIDGS.js} +648 -228
  48. package/dist/main-6UPAIDGS.js.map +1 -0
  49. package/dist/{rebuild-JW6BCHHZ.js → rebuild-QDSYYCS7.js} +10 -10
  50. package/dist/rebuild-QDSYYCS7.js.map +1 -0
  51. package/dist/{reprocess-SNXFNKBN.js → reprocess-ZNUQCIS3.js} +18 -18
  52. package/dist/reprocess-ZNUQCIS3.js.map +1 -0
  53. package/dist/{restart-YE2IGOYT.js → restart-5UY2KV54.js} +6 -6
  54. package/dist/{search-2HMG3ON7.js → search-2VEN3XIG.js} +9 -9
  55. package/dist/{server-JM3TM7D2.js → server-OR5B4B7K.js} +77 -54
  56. package/dist/{server-JM3TM7D2.js.map → server-OR5B4B7K.js.map} +1 -1
  57. package/dist/{session-5GI2YU6R.js → session-QF6MILAC.js} +2 -2
  58. package/dist/{session-start-2UEEEO52.js → session-start-TUITIUMB.js} +29 -28
  59. package/dist/session-start-TUITIUMB.js.map +1 -0
  60. package/dist/setup-digest-ETCZAUIU.js +15 -0
  61. package/dist/setup-llm-DWEJE3JE.js +15 -0
  62. package/dist/setup-llm-DWEJE3JE.js.map +1 -0
  63. package/dist/src/cli.js +4 -4
  64. package/dist/src/daemon/main.js +4 -4
  65. package/dist/src/hooks/post-tool-use.js +5 -5
  66. package/dist/src/hooks/session-end.js +5 -5
  67. package/dist/src/hooks/session-start.js +4 -4
  68. package/dist/src/hooks/stop.js +7 -7
  69. package/dist/src/hooks/user-prompt-submit.js +5 -5
  70. package/dist/src/hooks/user-prompt-submit.js.map +1 -1
  71. package/dist/src/mcp/server.js +4 -4
  72. package/dist/src/prompts/classification.md +1 -0
  73. package/dist/src/prompts/digest-10000.md +74 -0
  74. package/dist/src/prompts/digest-1500.md +25 -0
  75. package/dist/src/prompts/digest-3000.md +32 -0
  76. package/dist/src/prompts/digest-5000.md +43 -0
  77. package/dist/src/prompts/digest-system.md +32 -0
  78. package/dist/src/prompts/extraction.md +11 -10
  79. package/dist/src/prompts/summary.md +11 -1
  80. package/dist/src/prompts/title.md +1 -1
  81. package/dist/{stats-IOWXG576.js → stats-IVIXIKTS.js} +12 -12
  82. package/dist/stats-IVIXIKTS.js.map +1 -0
  83. package/dist/{verify-7MWOV72E.js → verify-4H6CEE5T.js} +6 -6
  84. package/dist/{version-S7MHLD5P.js → version-5B2TWXQJ.js} +4 -4
  85. package/dist/version-5B2TWXQJ.js.map +1 -0
  86. package/package.json +1 -1
  87. package/skills/myco/SKILL.md +20 -20
  88. package/skills/myco/references/wisdom.md +14 -14
  89. package/skills/rules/SKILL.md +4 -4
  90. package/dist/chunk-7VPJK56U.js.map +0 -1
  91. package/dist/chunk-BA23DROX.js +0 -160
  92. package/dist/chunk-BA23DROX.js.map +0 -1
  93. package/dist/chunk-CCIV47S4.js.map +0 -1
  94. package/dist/chunk-EF4JVH24.js +0 -7299
  95. package/dist/chunk-EF4JVH24.js.map +0 -1
  96. package/dist/chunk-FFQNE6CT.js.map +0 -1
  97. package/dist/chunk-ISCT2SI6.js.map +0 -1
  98. package/dist/chunk-PA3VMINE.js.map +0 -1
  99. package/dist/chunk-QWU7QLZI.js.map +0 -1
  100. package/dist/chunk-YMYJ7FNH.js +0 -19
  101. package/dist/chunk-YMYJ7FNH.js.map +0 -1
  102. package/dist/cli-3WQSDSW6.js.map +0 -1
  103. package/dist/init-RALMQKOQ.js.map +0 -1
  104. package/dist/main-S3WSUF5T.js.map +0 -1
  105. package/dist/rebuild-JW6BCHHZ.js.map +0 -1
  106. package/dist/reprocess-SNXFNKBN.js.map +0 -1
  107. package/dist/session-start-2UEEEO52.js.map +0 -1
  108. package/dist/stats-IOWXG576.js.map +0 -1
  109. /package/dist/{chunk-YFG2O5HR.js.map → chunk-2GJFTIWX.js.map} +0 -0
  110. /package/dist/{chunk-JKOALBZC.js.map → chunk-BNIYWCST.js.map} +0 -0
  111. /package/dist/{chunk-NYAWCMRZ.js.map → chunk-OUFSLZTX.js.map} +0 -0
  112. /package/dist/{chunk-LR7RQCOB.js.map → chunk-XCPQHC4X.js.map} +0 -0
  113. /package/dist/{chunk-ZBNT6E22.js.map → chunk-ZCBL5HER.js.map} +0 -0
  114. /package/dist/{client-5T4M42UQ.js.map → client-5SUO2UYH.js.map} +0 -0
  115. /package/dist/{config-MD4XMLUS.js.map → config-4GGMWGAF.js.map} +0 -0
  116. /package/dist/{detect-providers-LNOLBICR.js.map → detect-providers-5FU3BN5Q.js.map} +0 -0
  117. /package/dist/{restart-YE2IGOYT.js.map → restart-5UY2KV54.js.map} +0 -0
  118. /package/dist/{search-2HMG3ON7.js.map → search-2VEN3XIG.js.map} +0 -0
  119. /package/dist/{session-5GI2YU6R.js.map → session-QF6MILAC.js.map} +0 -0
  120. /package/dist/{version-S7MHLD5P.js.map → setup-digest-ETCZAUIU.js.map} +0 -0
  121. /package/dist/{verify-7MWOV72E.js.map → verify-4H6CEE5T.js.map} +0 -0
@@ -2,6 +2,9 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
2
2
 
3
3
  // src/constants.ts
4
4
  var CHARS_PER_TOKEN = 4;
5
+ function estimateTokens(text) {
6
+ return Math.ceil(text.length / CHARS_PER_TOKEN);
7
+ }
5
8
  var EMBEDDING_INPUT_LIMIT = 8e3;
6
9
  var PROMPT_PREVIEW_CHARS = 300;
7
10
  var AI_RESPONSE_PREVIEW_CHARS = 500;
@@ -12,15 +15,12 @@ var SESSION_SUMMARY_PREVIEW_CHARS = 300;
12
15
  var RECALL_SUMMARY_PREVIEW_CHARS = 200;
13
16
  var CONTEXT_PLAN_PREVIEW_CHARS = 100;
14
17
  var CONTEXT_SESSION_PREVIEW_CHARS = 80;
15
- var CONTEXT_MEMORY_PREVIEW_CHARS = 80;
16
- var EXTRACTION_MAX_TOKENS = 2048;
17
- var SUMMARY_MAX_TOKENS = 512;
18
- var TITLE_MAX_TOKENS = 32;
19
- var CLASSIFICATION_MAX_TOKENS = 1024;
18
+ var CONTEXT_SPORE_PREVIEW_CHARS = 80;
20
19
  var DAEMON_CLIENT_TIMEOUT_MS = 2e3;
21
20
  var DAEMON_HEALTH_CHECK_TIMEOUT_MS = 500;
22
21
  var LLM_REQUEST_TIMEOUT_MS = 18e4;
23
22
  var EMBEDDING_REQUEST_TIMEOUT_MS = 6e4;
23
+ var DIGEST_LLM_REQUEST_TIMEOUT_MS = 6e5;
24
24
  var STDIN_TIMEOUT_MS = 100;
25
25
  var FILE_WATCH_STABILITY_MS = 1e3;
26
26
  var PROVIDER_DETECT_TIMEOUT_MS = 3e3;
@@ -29,17 +29,32 @@ var DAEMON_HEALTH_RETRY_DELAYS = [100, 200, 400, 800, 1500];
29
29
  var MAX_SLUG_LENGTH = 100;
30
30
  var CANDIDATE_CONTENT_PREVIEW = 2e3;
31
31
  var LINEAGE_RECENT_SESSIONS_LIMIT = 5;
32
- var RELATED_MEMORIES_LIMIT = 50;
32
+ var RELATED_SPORES_LIMIT = 50;
33
33
  var SESSION_CONTEXT_MAX_PLANS = 3;
34
- var PROMPT_CONTEXT_MAX_MEMORIES = 3;
34
+ var PROMPT_CONTEXT_MAX_SPORES = 3;
35
35
  var PROMPT_CONTEXT_MIN_SIMILARITY = 0.3;
36
36
  var PROMPT_CONTEXT_MIN_LENGTH = 10;
37
37
  var MCP_SEARCH_DEFAULT_LIMIT = 10;
38
38
  var MCP_SESSIONS_DEFAULT_LIMIT = 20;
39
39
  var MCP_LOGS_DEFAULT_LIMIT = 50;
40
+ var DIGEST_TIERS = [1500, 3e3, 5e3, 1e4];
41
+ var DIGEST_TIER_MIN_CONTEXT = {
42
+ 1500: 6500,
43
+ 3e3: 11500,
44
+ 5e3: 18500,
45
+ 1e4: 30500
46
+ };
47
+ var DIGEST_SUBSTRATE_TYPE_WEIGHTS = {
48
+ session: 3,
49
+ spore: 3,
50
+ plan: 2,
51
+ artifact: 1,
52
+ team: 1
53
+ };
40
54
 
41
55
  export {
42
56
  CHARS_PER_TOKEN,
57
+ estimateTokens,
43
58
  EMBEDDING_INPUT_LIMIT,
44
59
  PROMPT_PREVIEW_CHARS,
45
60
  AI_RESPONSE_PREVIEW_CHARS,
@@ -50,15 +65,12 @@ export {
50
65
  RECALL_SUMMARY_PREVIEW_CHARS,
51
66
  CONTEXT_PLAN_PREVIEW_CHARS,
52
67
  CONTEXT_SESSION_PREVIEW_CHARS,
53
- CONTEXT_MEMORY_PREVIEW_CHARS,
54
- EXTRACTION_MAX_TOKENS,
55
- SUMMARY_MAX_TOKENS,
56
- TITLE_MAX_TOKENS,
57
- CLASSIFICATION_MAX_TOKENS,
68
+ CONTEXT_SPORE_PREVIEW_CHARS,
58
69
  DAEMON_CLIENT_TIMEOUT_MS,
59
70
  DAEMON_HEALTH_CHECK_TIMEOUT_MS,
60
71
  LLM_REQUEST_TIMEOUT_MS,
61
72
  EMBEDDING_REQUEST_TIMEOUT_MS,
73
+ DIGEST_LLM_REQUEST_TIMEOUT_MS,
62
74
  STDIN_TIMEOUT_MS,
63
75
  FILE_WATCH_STABILITY_MS,
64
76
  PROVIDER_DETECT_TIMEOUT_MS,
@@ -67,13 +79,16 @@ export {
67
79
  MAX_SLUG_LENGTH,
68
80
  CANDIDATE_CONTENT_PREVIEW,
69
81
  LINEAGE_RECENT_SESSIONS_LIMIT,
70
- RELATED_MEMORIES_LIMIT,
82
+ RELATED_SPORES_LIMIT,
71
83
  SESSION_CONTEXT_MAX_PLANS,
72
- PROMPT_CONTEXT_MAX_MEMORIES,
84
+ PROMPT_CONTEXT_MAX_SPORES,
73
85
  PROMPT_CONTEXT_MIN_SIMILARITY,
74
86
  PROMPT_CONTEXT_MIN_LENGTH,
75
87
  MCP_SEARCH_DEFAULT_LIMIT,
76
88
  MCP_SESSIONS_DEFAULT_LIMIT,
77
- MCP_LOGS_DEFAULT_LIMIT
89
+ MCP_LOGS_DEFAULT_LIMIT,
90
+ DIGEST_TIERS,
91
+ DIGEST_TIER_MIN_CONTEXT,
92
+ DIGEST_SUBSTRATE_TYPE_WEIGHTS
78
93
  };
79
- //# sourceMappingURL=chunk-7VPJK56U.js.map
94
+ //# sourceMappingURL=chunk-JBD5KP5G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\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\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// --- Embedding ---\n/** Max characters of text sent to the embedding model. */\nexport const EMBEDDING_INPUT_LIMIT = 8000;\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\n// --- Context injection layer budgets (chars, not tokens — used with .slice()) ---\nexport const CONTEXT_PLAN_PREVIEW_CHARS = 100;\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/** Response token budget for artifact classification. */\nexport const CLASSIFICATION_MAX_TOKENS = 1024;\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/** Chokidar write stability threshold (ms). */\nexport const FILE_WATCH_STABILITY_MS = 1000;\n/** Provider detection timeout for detect-providers CLI command (ms). */\nexport const PROVIDER_DETECT_TIMEOUT_MS = 3000;\n\n// --- Buffer cleanup ---\n/** Max age for stale buffer files before cleanup (ms). */\nexport const STALE_BUFFER_MAX_AGE_MS = 24 * 60 * 60 * 1000;\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// --- Slug limits ---\n/** Max length for slugified artifact IDs. */\nexport const MAX_SLUG_LENGTH = 100;\n\n// --- Content preview for classification prompt ---\n/** Max chars of file content per candidate in classification prompt. */\nexport const CANDIDATE_CONTENT_PREVIEW = 2000;\n\n// --- Transcript mining ---\n/** Minimum content length to consider a transcript entry meaningful. */\nexport const MIN_TRANSCRIPT_CONTENT_LENGTH = 10;\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 active plans to inject at session start. */\nexport const SESSION_CONTEXT_MAX_PLANS = 3;\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// --- 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\n// --- Digest — Tiers ---\n/** Available token-budget tiers for digest synthesis. */\nexport const DIGEST_TIERS = [1500, 3000, 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 3000: 11500,\n 5000: 18500,\n 10000: 30500,\n};\n\n// --- Digest — Substrate ---\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// --- Digest — System prompt overhead estimate ---\n"],"mappings":";;;AAQO,IAAM,kBAAkB;AAGxB,SAAS,eAAe,MAAsB;AACnD,SAAO,KAAK,KAAK,KAAK,SAAS,eAAe;AAChD;AAIO,IAAM,wBAAwB;AAI9B,IAAM,uBAAuB;AAE7B,IAAM,4BAA4B;AAElC,IAAM,wBAAwB;AAE9B,IAAM,wBAAwB;AAE9B,IAAM,4BAA4B;AAElC,IAAM,gCAAgC;AAEtC,IAAM,+BAA+B;AAGrC,IAAM,6BAA6B;AACnC,IAAM,gCAAgC;AACtC,IAAM,8BAA8B;AAcpC,IAAM,2BAA2B;AAEjC,IAAM,iCAAiC;AAEvC,IAAM,yBAAyB;AAE/B,IAAM,+BAA+B;AAErC,IAAM,gCAAgC;AAEtC,IAAM,mBAAmB;AAEzB,IAAM,0BAA0B;AAEhC,IAAM,6BAA6B;AAInC,IAAM,0BAA0B,KAAK,KAAK,KAAK;AAI/C,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI;AAI5D,IAAM,kBAAkB;AAIxB,IAAM,4BAA4B;AAQlC,IAAM,gCAAgC;AAEtC,IAAM,uBAAuB;AAI7B,IAAM,4BAA4B;AAElC,IAAM,4BAA4B;AAElC,IAAM,gCAAgC;AAMtC,IAAM,4BAA4B;AAIlC,IAAM,2BAA2B;AAEjC,IAAM,6BAA6B;AAEnC,IAAM,yBAAyB;AAI/B,IAAM,eAAe,CAAC,MAAM,KAAM,KAAM,GAAK;AAK7C,IAAM,0BAAkD;AAAA,EAC7D,MAAM;AAAA,EACN,KAAM;AAAA,EACN,KAAM;AAAA,EACN,KAAO;AACT;AAIO,IAAM,gCAAwD;AAAA,EACnE,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AACR;","names":[]}
@@ -0,0 +1,37 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ require_dist
4
+ } from "./chunk-G6ZMTQMJ.js";
5
+ import {
6
+ __toESM
7
+ } from "./chunk-PZUWP5VK.js";
8
+
9
+ // src/vault/frontmatter.ts
10
+ var import_yaml = __toESM(require_dist(), 1);
11
+ function stripFrontmatter(raw) {
12
+ const match = raw.match(/^---\n([\s\S]*?)\n---\n*/);
13
+ if (!match) return { body: raw.trim(), frontmatter: {} };
14
+ let frontmatter = {};
15
+ try {
16
+ frontmatter = import_yaml.default.parse(match[1]);
17
+ } catch {
18
+ }
19
+ return { body: raw.slice(match[0].length).trim(), frontmatter };
20
+ }
21
+ function planFm(note) {
22
+ return note.frontmatter;
23
+ }
24
+ function sessionFm(note) {
25
+ return note.frontmatter;
26
+ }
27
+ function sporeFm(note) {
28
+ return note.frontmatter;
29
+ }
30
+
31
+ export {
32
+ stripFrontmatter,
33
+ planFm,
34
+ sessionFm,
35
+ sporeFm
36
+ };
37
+ //# sourceMappingURL=chunk-NUA7UTIY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vault/frontmatter.ts"],"sourcesContent":["import YAML from 'yaml';\nimport type { IndexedNote } from '../index/sqlite.js';\nimport type { PlanFrontmatter, SessionFrontmatter, SporeFrontmatter } from './types.js';\n\n/** Strip YAML frontmatter from a markdown string, returning the body and parsed frontmatter. */\nexport function stripFrontmatter(raw: string): { body: string; frontmatter: Record<string, unknown> } {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n*/);\n if (!match) return { body: raw.trim(), frontmatter: {} };\n\n let frontmatter: Record<string, unknown> = {};\n try {\n frontmatter = YAML.parse(match[1]) as Record<string, unknown>;\n } catch { /* malformed frontmatter */ }\n\n return { body: raw.slice(match[0].length).trim(), frontmatter };\n}\n\nexport function planFm(note: IndexedNote): PlanFrontmatter {\n return note.frontmatter as unknown as PlanFrontmatter;\n}\n\nexport function sessionFm(note: IndexedNote): SessionFrontmatter {\n return note.frontmatter as unknown as SessionFrontmatter;\n}\n\nexport function sporeFm(note: IndexedNote): SporeFrontmatter {\n return note.frontmatter as unknown as SporeFrontmatter;\n}\n"],"mappings":";;;;;;;;;AAAA,kBAAiB;AAKV,SAAS,iBAAiB,KAAqE;AACpG,QAAM,QAAQ,IAAI,MAAM,0BAA0B;AAClD,MAAI,CAAC,MAAO,QAAO,EAAE,MAAM,IAAI,KAAK,GAAG,aAAa,CAAC,EAAE;AAEvD,MAAI,cAAuC,CAAC;AAC5C,MAAI;AACF,kBAAc,YAAAA,QAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EACnC,QAAQ;AAAA,EAA8B;AAEtC,SAAO,EAAE,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,YAAY;AAChE;AAEO,SAAS,OAAO,MAAoC;AACzD,SAAO,KAAK;AACd;AAEO,SAAS,UAAU,MAAuC;AAC/D,SAAO,KAAK;AACd;AAEO,SAAS,QAAQ,MAAqC;AAC3D,SAAO,KAAK;AACd;","names":["YAML"]}
@@ -1,15 +1,15 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  getPluginVersion
4
- } from "./chunk-YFG2O5HR.js";
4
+ } from "./chunk-2GJFTIWX.js";
5
5
  import {
6
6
  AgentRegistry
7
- } from "./chunk-JKOALBZC.js";
7
+ } from "./chunk-BNIYWCST.js";
8
8
  import {
9
9
  DAEMON_CLIENT_TIMEOUT_MS,
10
10
  DAEMON_HEALTH_CHECK_TIMEOUT_MS,
11
11
  DAEMON_HEALTH_RETRY_DELAYS
12
- } from "./chunk-7VPJK56U.js";
12
+ } from "./chunk-JBD5KP5G.js";
13
13
 
14
14
  // src/hooks/client.ts
15
15
  import fs from "fs";
@@ -166,4 +166,4 @@ var DaemonClient = class {
166
166
  export {
167
167
  DaemonClient
168
168
  };
169
- //# sourceMappingURL=chunk-NYAWCMRZ.js.map
169
+ //# sourceMappingURL=chunk-OUFSLZTX.js.map
@@ -0,0 +1,242 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ DAEMON_CLIENT_TIMEOUT_MS,
4
+ EMBEDDING_REQUEST_TIMEOUT_MS,
5
+ LLM_REQUEST_TIMEOUT_MS,
6
+ estimateTokens
7
+ } from "./chunk-JBD5KP5G.js";
8
+
9
+ // src/intelligence/ollama.ts
10
+ var ENDPOINT_GENERATE = "/api/generate";
11
+ var ENDPOINT_EMBED = "/api/embed";
12
+ var ENDPOINT_TAGS = "/api/tags";
13
+ var OllamaBackend = class _OllamaBackend {
14
+ static DEFAULT_BASE_URL = "http://localhost:11434";
15
+ name = "ollama";
16
+ baseUrl;
17
+ model;
18
+ contextWindow;
19
+ defaultMaxTokens;
20
+ constructor(config) {
21
+ this.baseUrl = config?.base_url ?? _OllamaBackend.DEFAULT_BASE_URL;
22
+ this.model = config?.model ?? config?.summary_model ?? "llama3.2";
23
+ this.contextWindow = config?.context_window ?? 8192;
24
+ this.defaultMaxTokens = config?.max_tokens ?? 1024;
25
+ }
26
+ async summarize(prompt, opts) {
27
+ const maxTokens = opts?.maxTokens ?? this.defaultMaxTokens;
28
+ const contextLength = opts?.contextLength ?? this.contextWindow;
29
+ const promptTokens = estimateTokens(prompt);
30
+ const numCtx = Math.max(promptTokens + maxTokens, contextLength);
31
+ const body = {
32
+ model: this.model,
33
+ prompt,
34
+ stream: false,
35
+ options: {
36
+ num_ctx: numCtx,
37
+ num_predict: maxTokens
38
+ }
39
+ };
40
+ if (opts?.systemPrompt) {
41
+ body.system = opts.systemPrompt;
42
+ }
43
+ if (opts?.reasoning) {
44
+ body.think = opts.reasoning === "off" ? false : opts.reasoning;
45
+ }
46
+ if (opts?.keepAlive) {
47
+ body.keep_alive = opts.keepAlive;
48
+ }
49
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_GENERATE}`, {
50
+ method: "POST",
51
+ headers: { "Content-Type": "application/json" },
52
+ body: JSON.stringify(body),
53
+ signal: AbortSignal.timeout(opts?.timeoutMs ?? LLM_REQUEST_TIMEOUT_MS)
54
+ });
55
+ if (!response.ok) {
56
+ const errorBody = await response.text().catch(() => "");
57
+ throw new Error(`Ollama summarize failed: ${response.status} ${errorBody.slice(0, 500)}`);
58
+ }
59
+ const data = await response.json();
60
+ return { text: data.response, model: data.model };
61
+ }
62
+ async embed(text) {
63
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_EMBED}`, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({
67
+ model: this.model,
68
+ input: text
69
+ }),
70
+ signal: AbortSignal.timeout(EMBEDDING_REQUEST_TIMEOUT_MS)
71
+ });
72
+ if (!response.ok) {
73
+ throw new Error(`Ollama embed failed: ${response.status} ${response.statusText}`);
74
+ }
75
+ const data = await response.json();
76
+ const embedding = data.embeddings[0];
77
+ return { embedding, model: data.model, dimensions: embedding.length };
78
+ }
79
+ async isAvailable() {
80
+ try {
81
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_TAGS}`, {
82
+ signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS)
83
+ });
84
+ return response.ok;
85
+ } catch {
86
+ return false;
87
+ }
88
+ }
89
+ /** List available models on this Ollama instance. */
90
+ async listModels(timeoutMs) {
91
+ try {
92
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_TAGS}`, {
93
+ signal: AbortSignal.timeout(timeoutMs ?? DAEMON_CLIENT_TIMEOUT_MS)
94
+ });
95
+ const data = await response.json();
96
+ return data.models.map((m) => m.name);
97
+ } catch {
98
+ return [];
99
+ }
100
+ }
101
+ };
102
+
103
+ // src/intelligence/lm-studio.ts
104
+ var ENDPOINT_CHAT = "/api/v1/chat";
105
+ var ENDPOINT_MODELS_LOAD = "/api/v1/models/load";
106
+ var ENDPOINT_MODELS_LIST = "/v1/models";
107
+ var ENDPOINT_EMBEDDINGS = "/v1/embeddings";
108
+ var LmStudioBackend = class _LmStudioBackend {
109
+ static DEFAULT_BASE_URL = "http://localhost:1234";
110
+ name = "lm-studio";
111
+ baseUrl;
112
+ model;
113
+ loadedInstanceId = null;
114
+ contextWindow;
115
+ defaultMaxTokens;
116
+ constructor(config) {
117
+ this.baseUrl = config?.base_url ?? _LmStudioBackend.DEFAULT_BASE_URL;
118
+ this.model = config?.model ?? config?.summary_model ?? "llama3.2";
119
+ this.contextWindow = config?.context_window;
120
+ this.defaultMaxTokens = config?.max_tokens ?? 1024;
121
+ }
122
+ /**
123
+ * Generate text using LM Studio's native REST API (/api/v1/chat).
124
+ * Supports per-request context_length, reasoning control, and system_prompt.
125
+ */
126
+ async summarize(prompt, opts) {
127
+ const maxTokens = opts?.maxTokens ?? this.defaultMaxTokens;
128
+ const body = {
129
+ model: this.loadedInstanceId ?? this.model,
130
+ input: prompt,
131
+ max_output_tokens: maxTokens,
132
+ store: false
133
+ };
134
+ if (!this.loadedInstanceId) {
135
+ const contextLength = opts?.contextLength ?? this.contextWindow;
136
+ if (contextLength) {
137
+ body.context_length = contextLength;
138
+ }
139
+ }
140
+ if (opts?.systemPrompt) {
141
+ body.system_prompt = opts.systemPrompt;
142
+ }
143
+ if (opts?.reasoning) {
144
+ body.reasoning = opts.reasoning;
145
+ }
146
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_CHAT}`, {
147
+ method: "POST",
148
+ headers: { "Content-Type": "application/json" },
149
+ body: JSON.stringify(body),
150
+ signal: AbortSignal.timeout(opts?.timeoutMs ?? LLM_REQUEST_TIMEOUT_MS)
151
+ });
152
+ if (!response.ok) {
153
+ const errorBody = await response.text().catch(() => "");
154
+ throw new Error(`LM Studio summarize failed: ${response.status} ${errorBody.slice(0, 500)}`);
155
+ }
156
+ const data = await response.json();
157
+ const messageOutput = data.output.find((o) => o.type === "message");
158
+ const text = messageOutput?.content ?? "";
159
+ return { text, model: data.model_instance_id };
160
+ }
161
+ /**
162
+ * Generate embeddings using LM Studio's OpenAI-compatible endpoint.
163
+ * (The native API doesn't have an embedding endpoint — OpenAI-compat is fine here.)
164
+ */
165
+ async embed(text) {
166
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_EMBEDDINGS}`, {
167
+ method: "POST",
168
+ headers: { "Content-Type": "application/json" },
169
+ body: JSON.stringify({
170
+ model: this.model,
171
+ input: text
172
+ }),
173
+ signal: AbortSignal.timeout(EMBEDDING_REQUEST_TIMEOUT_MS)
174
+ });
175
+ if (!response.ok) {
176
+ throw new Error(`LM Studio embed failed: ${response.status}`);
177
+ }
178
+ const data = await response.json();
179
+ const embedding = data.data[0].embedding;
180
+ return { embedding, model: data.model, dimensions: embedding.length };
181
+ }
182
+ /**
183
+ * Load the model with specific settings for digest operations.
184
+ * Creates a dedicated instance and captures the instance_id so subsequent
185
+ * chat requests target it directly (avoiding auto-load side effects).
186
+ * Does not unload other instances — hooks and other providers may be
187
+ * using the same model with different settings.
188
+ */
189
+ async ensureLoaded(contextLength, gpuKvCache) {
190
+ const ctx = contextLength ?? this.contextWindow;
191
+ const body = {
192
+ model: this.model,
193
+ flash_attention: true,
194
+ offload_kv_cache_to_gpu: gpuKvCache ?? false
195
+ };
196
+ if (ctx) {
197
+ body.context_length = ctx;
198
+ }
199
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LOAD}`, {
200
+ method: "POST",
201
+ headers: { "Content-Type": "application/json" },
202
+ body: JSON.stringify(body),
203
+ signal: AbortSignal.timeout(LLM_REQUEST_TIMEOUT_MS)
204
+ });
205
+ if (!response.ok) {
206
+ const errorBody = await response.text().catch(() => "");
207
+ throw new Error(`LM Studio model load failed: ${response.status} ${errorBody.slice(0, 200)}`);
208
+ }
209
+ const loadResult = await response.json();
210
+ if (loadResult.instance_id) {
211
+ this.loadedInstanceId = loadResult.instance_id;
212
+ }
213
+ }
214
+ async isAvailable() {
215
+ try {
216
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LIST}`, {
217
+ signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS)
218
+ });
219
+ return response.ok;
220
+ } catch {
221
+ return false;
222
+ }
223
+ }
224
+ /** List available models on this LM Studio instance. */
225
+ async listModels(timeoutMs) {
226
+ try {
227
+ const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LIST}`, {
228
+ signal: AbortSignal.timeout(timeoutMs ?? DAEMON_CLIENT_TIMEOUT_MS)
229
+ });
230
+ const data = await response.json();
231
+ return data.data.map((m) => m.id);
232
+ } catch {
233
+ return [];
234
+ }
235
+ }
236
+ };
237
+
238
+ export {
239
+ OllamaBackend,
240
+ LmStudioBackend
241
+ };
242
+ //# sourceMappingURL=chunk-P7RNAYU7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/intelligence/ollama.ts","../src/intelligence/lm-studio.ts"],"sourcesContent":["import type { LlmProvider, EmbeddingProvider, LlmResponse, EmbeddingResponse, LlmRequestOptions } from './llm.js';\nimport { estimateTokens, LLM_REQUEST_TIMEOUT_MS, EMBEDDING_REQUEST_TIMEOUT_MS, DAEMON_CLIENT_TIMEOUT_MS } from '../constants.js';\n\ninterface OllamaConfig {\n model?: string;\n base_url?: string;\n context_window?: number;\n max_tokens?: number;\n // Legacy fields (ignored, kept for backward compat during migration)\n embedding_model?: string;\n summary_model?: string;\n}\n\n// Ollama API endpoints\nconst ENDPOINT_GENERATE = '/api/generate';\nconst ENDPOINT_EMBED = '/api/embed';\nconst ENDPOINT_TAGS = '/api/tags';\n\nexport class OllamaBackend implements LlmProvider, EmbeddingProvider {\n static readonly DEFAULT_BASE_URL = 'http://localhost:11434';\n readonly name = 'ollama';\n private baseUrl: string;\n private model: string;\n private contextWindow: number;\n private defaultMaxTokens: number;\n\n constructor(config?: OllamaConfig) {\n this.baseUrl = config?.base_url ?? OllamaBackend.DEFAULT_BASE_URL;\n this.model = config?.model ?? config?.summary_model ?? 'llama3.2';\n this.contextWindow = config?.context_window ?? 8192;\n this.defaultMaxTokens = config?.max_tokens ?? 1024;\n }\n\n async summarize(prompt: string, opts?: LlmRequestOptions): Promise<LlmResponse> {\n const maxTokens = opts?.maxTokens ?? this.defaultMaxTokens;\n const contextLength = opts?.contextLength ?? this.contextWindow;\n const promptTokens = estimateTokens(prompt);\n const numCtx = Math.max(promptTokens + maxTokens, contextLength);\n\n const body: Record<string, unknown> = {\n model: this.model,\n prompt,\n stream: false,\n options: {\n num_ctx: numCtx,\n num_predict: maxTokens,\n },\n };\n\n // System prompt — sent as a separate field instead of concatenated into prompt\n if (opts?.systemPrompt) {\n body.system = opts.systemPrompt;\n }\n\n // Thinking control — false suppresses chain-of-thought for reasoning models\n if (opts?.reasoning) {\n body.think = opts.reasoning === 'off' ? false : opts.reasoning;\n }\n\n // Keep model loaded between requests (useful for digest cycles)\n if (opts?.keepAlive) {\n body.keep_alive = opts.keepAlive;\n }\n\n const response = await fetch(`${this.baseUrl}${ENDPOINT_GENERATE}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(opts?.timeoutMs ?? LLM_REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw new Error(`Ollama summarize failed: ${response.status} ${errorBody.slice(0, 500)}`);\n }\n\n const data = await response.json() as { response: string; model: string };\n return { text: data.response, model: data.model };\n }\n\n async embed(text: string): Promise<EmbeddingResponse> {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_EMBED}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.model,\n input: text,\n }),\n signal: AbortSignal.timeout(EMBEDDING_REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama embed failed: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json() as { embeddings: number[][]; model: string };\n const embedding = data.embeddings[0];\n return { embedding, model: data.model, dimensions: embedding.length };\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_TAGS}`, {\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /** List available models on this Ollama instance. */\n async listModels(timeoutMs?: number): Promise<string[]> {\n try {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_TAGS}`, {\n signal: AbortSignal.timeout(timeoutMs ?? DAEMON_CLIENT_TIMEOUT_MS),\n });\n const data = await response.json() as { models: Array<{ name: string }> };\n return data.models.map((m) => m.name);\n } catch {\n return [];\n }\n }\n}\n","import type { LlmProvider, EmbeddingProvider, LlmResponse, EmbeddingResponse, LlmRequestOptions } from './llm.js';\nimport { LLM_REQUEST_TIMEOUT_MS, EMBEDDING_REQUEST_TIMEOUT_MS, DAEMON_CLIENT_TIMEOUT_MS } from '../constants.js';\n\ninterface LmStudioConfig {\n model?: string;\n base_url?: string;\n context_window?: number;\n max_tokens?: number;\n // Legacy fields\n embedding_model?: string;\n summary_model?: string;\n}\n\n// LM Studio API endpoints\nconst ENDPOINT_CHAT = '/api/v1/chat';\nconst ENDPOINT_MODELS_LOAD = '/api/v1/models/load';\nconst ENDPOINT_MODELS_UNLOAD = '/api/v1/models/unload';\nconst ENDPOINT_MODELS_LIST = '/v1/models';\nconst ENDPOINT_EMBEDDINGS = '/v1/embeddings';\n\nexport class LmStudioBackend implements LlmProvider, EmbeddingProvider {\n static readonly DEFAULT_BASE_URL = 'http://localhost:1234';\n readonly name = 'lm-studio';\n private baseUrl: string;\n private model: string;\n private loadedInstanceId: string | null = null;\n private contextWindow: number | undefined;\n private defaultMaxTokens: number;\n\n constructor(config?: LmStudioConfig) {\n this.baseUrl = config?.base_url ?? LmStudioBackend.DEFAULT_BASE_URL;\n this.model = config?.model ?? config?.summary_model ?? 'llama3.2';\n this.contextWindow = config?.context_window;\n this.defaultMaxTokens = config?.max_tokens ?? 1024;\n }\n\n /**\n * Generate text using LM Studio's native REST API (/api/v1/chat).\n * Supports per-request context_length, reasoning control, and system_prompt.\n */\n async summarize(prompt: string, opts?: LlmRequestOptions): Promise<LlmResponse> {\n const maxTokens = opts?.maxTokens ?? this.defaultMaxTokens;\n\n const body: Record<string, unknown> = {\n model: this.loadedInstanceId ?? this.model,\n input: prompt,\n max_output_tokens: maxTokens,\n store: false,\n };\n\n // Only set context_length if we haven't pre-loaded the model\n // (pre-loaded models already have the correct context via ensureLoaded)\n if (!this.loadedInstanceId) {\n const contextLength = opts?.contextLength ?? this.contextWindow;\n if (contextLength) {\n body.context_length = contextLength;\n }\n }\n\n // System prompt — sent separately from user content\n if (opts?.systemPrompt) {\n body.system_prompt = opts.systemPrompt;\n }\n\n // Reasoning control — 'off' suppresses chain-of-thought for reasoning models\n if (opts?.reasoning) {\n body.reasoning = opts.reasoning;\n }\n\n const response = await fetch(`${this.baseUrl}${ENDPOINT_CHAT}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(opts?.timeoutMs ?? LLM_REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw new Error(`LM Studio summarize failed: ${response.status} ${errorBody.slice(0, 500)}`);\n }\n\n const data = await response.json() as {\n model_instance_id: string;\n output: Array<{ type: string; content: string }>;\n };\n const messageOutput = data.output.find((o) => o.type === 'message');\n const text = messageOutput?.content ?? '';\n return { text, model: data.model_instance_id };\n }\n\n /**\n * Generate embeddings using LM Studio's OpenAI-compatible endpoint.\n * (The native API doesn't have an embedding endpoint — OpenAI-compat is fine here.)\n */\n async embed(text: string): Promise<EmbeddingResponse> {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_EMBEDDINGS}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.model,\n input: text,\n }),\n signal: AbortSignal.timeout(EMBEDDING_REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n throw new Error(`LM Studio embed failed: ${response.status}`);\n }\n\n const data = await response.json() as {\n data: Array<{ embedding: number[] }>;\n model: string;\n };\n const embedding = data.data[0].embedding;\n return { embedding, model: data.model, dimensions: embedding.length };\n }\n\n /**\n * Load the model with specific settings for digest operations.\n * Creates a dedicated instance and captures the instance_id so subsequent\n * chat requests target it directly (avoiding auto-load side effects).\n * Does not unload other instances — hooks and other providers may be\n * using the same model with different settings.\n */\n async ensureLoaded(contextLength?: number, gpuKvCache?: boolean): Promise<void> {\n\n const ctx = contextLength ?? this.contextWindow;\n const body: Record<string, unknown> = {\n model: this.model,\n flash_attention: true,\n offload_kv_cache_to_gpu: gpuKvCache ?? false,\n };\n if (ctx) {\n body.context_length = ctx;\n }\n\n const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LOAD}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(LLM_REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw new Error(`LM Studio model load failed: ${response.status} ${errorBody.slice(0, 200)}`);\n }\n\n // Capture the instance ID so chat requests target this specific loaded instance\n const loadResult = await response.json() as { instance_id?: string };\n if (loadResult.instance_id) {\n this.loadedInstanceId = loadResult.instance_id;\n }\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LIST}`, {\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /** List available models on this LM Studio instance. */\n async listModels(timeoutMs?: number): Promise<string[]> {\n try {\n const response = await fetch(`${this.baseUrl}${ENDPOINT_MODELS_LIST}`, {\n signal: AbortSignal.timeout(timeoutMs ?? DAEMON_CLIENT_TIMEOUT_MS),\n });\n const data = await response.json() as { data: Array<{ id: string }> };\n return data.data.map((m) => m.id);\n } catch {\n return [];\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,38 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ MycoConfigSchema,
4
+ require_dist
5
+ } from "./chunk-G6ZMTQMJ.js";
6
+ import {
7
+ __toESM
8
+ } from "./chunk-PZUWP5VK.js";
9
+
10
+ // src/config/loader.ts
11
+ var import_yaml = __toESM(require_dist(), 1);
12
+ import fs from "fs";
13
+ import path from "path";
14
+ var CONFIG_FILENAME = "myco.yaml";
15
+ function loadConfig(vaultDir) {
16
+ const configPath = path.join(vaultDir, CONFIG_FILENAME);
17
+ if (!fs.existsSync(configPath)) {
18
+ throw new Error(`myco.yaml not found in ${vaultDir}`);
19
+ }
20
+ const raw = fs.readFileSync(configPath, "utf-8");
21
+ const parsed = import_yaml.default.parse(raw);
22
+ if (parsed.version === 1 || parsed.intelligence?.backend) {
23
+ throw new Error(
24
+ "Myco config uses v1 format. Run /myco:setup-llm to reconfigure for v2."
25
+ );
26
+ }
27
+ const intel = parsed.intelligence;
28
+ const llm = intel?.llm;
29
+ if (llm?.provider === "haiku") {
30
+ llm.provider = "anthropic";
31
+ }
32
+ return MycoConfigSchema.parse(parsed);
33
+ }
34
+
35
+ export {
36
+ loadConfig
37
+ };
38
+ //# sourceMappingURL=chunk-QQ36XEJP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/loader.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\nimport { MycoConfigSchema, type MycoConfig } from './schema.js';\n\nconst CONFIG_FILENAME = 'myco.yaml';\n\nexport function loadConfig(vaultDir: string): MycoConfig {\n const configPath = path.join(vaultDir, CONFIG_FILENAME);\n\n if (!fs.existsSync(configPath)) {\n throw new Error(`myco.yaml not found in ${vaultDir}`);\n }\n\n const raw = fs.readFileSync(configPath, 'utf-8');\n const parsed = YAML.parse(raw) as Record<string, unknown>;\n\n // Detect v1 config and guide migration\n if (parsed.version === 1 || (parsed.intelligence as Record<string, unknown>)?.backend) {\n throw new Error(\n 'Myco config uses v1 format. Run /myco:setup-llm to reconfigure for v2.',\n );\n }\n\n // Auto-map legacy 'haiku' provider name to 'anthropic'\n const intel = parsed.intelligence as Record<string, unknown> | undefined;\n const llm = intel?.llm as Record<string, unknown> | undefined;\n if (llm?.provider === 'haiku') {\n llm.provider = 'anthropic';\n }\n\n return MycoConfigSchema.parse(parsed);\n}\n\nexport function saveConfig(vaultDir: string, config: MycoConfig): void {\n // Validate before writing — OAK lesson: validate on write, not just read\n const validated = MycoConfigSchema.parse(config);\n\n const configPath = path.join(vaultDir, CONFIG_FILENAME);\n fs.mkdirSync(vaultDir, { recursive: true });\n fs.writeFileSync(configPath, YAML.stringify(validated), 'utf-8');\n}\n"],"mappings":";;;;;;;;;;AAEA,kBAAiB;AAFjB,OAAO,QAAQ;AACf,OAAO,UAAU;AAIjB,IAAM,kBAAkB;AAEjB,SAAS,WAAW,UAA8B;AACvD,QAAM,aAAa,KAAK,KAAK,UAAU,eAAe;AAEtD,MAAI,CAAC,GAAG,WAAW,UAAU,GAAG;AAC9B,UAAM,IAAI,MAAM,0BAA0B,QAAQ,EAAE;AAAA,EACtD;AAEA,QAAM,MAAM,GAAG,aAAa,YAAY,OAAO;AAC/C,QAAM,SAAS,YAAAA,QAAK,MAAM,GAAG;AAG7B,MAAI,OAAO,YAAY,KAAM,OAAO,cAA0C,SAAS;AACrF,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,QAAQ,OAAO;AACrB,QAAM,MAAM,OAAO;AACnB,MAAI,KAAK,aAAa,SAAS;AAC7B,QAAI,WAAW;AAAA,EACjB;AAEA,SAAO,iBAAiB,MAAM,MAAM;AACtC;","names":["YAML"]}
@@ -0,0 +1,49 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ stripFrontmatter
4
+ } from "./chunk-NUA7UTIY.js";
5
+ import {
6
+ DIGEST_TIERS
7
+ } from "./chunk-JBD5KP5G.js";
8
+
9
+ // src/mcp/tools/context.ts
10
+ import fs from "fs";
11
+ import path from "path";
12
+ var DEFAULT_CONTEXT_TIER = 3e3;
13
+ function tryReadExtract(filePath, tier, fallback) {
14
+ let raw;
15
+ try {
16
+ raw = fs.readFileSync(filePath, "utf-8");
17
+ } catch {
18
+ return null;
19
+ }
20
+ const { body, frontmatter } = stripFrontmatter(raw);
21
+ const generated = frontmatter.generated;
22
+ return {
23
+ content: body,
24
+ tier,
25
+ fallback,
26
+ generated
27
+ };
28
+ }
29
+ function handleMycoContext(vaultDir, input) {
30
+ const requestedTier = input.tier ?? DEFAULT_CONTEXT_TIER;
31
+ const digestDir = path.join(vaultDir, "digest");
32
+ const exact = tryReadExtract(path.join(digestDir, `extract-${requestedTier}.md`), requestedTier, false);
33
+ if (exact) return exact;
34
+ const candidates = [...DIGEST_TIERS].sort((a, b) => Math.abs(a - requestedTier) - Math.abs(b - requestedTier));
35
+ for (const tier of candidates) {
36
+ const result = tryReadExtract(path.join(digestDir, `extract-${tier}.md`), tier, true);
37
+ if (result) return result;
38
+ }
39
+ return {
40
+ content: "Digest context is not yet available. The first digest cycle has not completed.",
41
+ tier: requestedTier,
42
+ fallback: false
43
+ };
44
+ }
45
+
46
+ export {
47
+ handleMycoContext
48
+ };
49
+ //# sourceMappingURL=chunk-RDXTQ436.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/tools/context.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { stripFrontmatter } from '../../vault/frontmatter.js';\nimport { DIGEST_TIERS } from '../../constants.js';\n\n/** Default tier when none is requested. */\nconst DEFAULT_CONTEXT_TIER = 3000;\n\ninterface ContextInput {\n tier?: number;\n}\n\nexport interface ContextResult {\n content: string;\n tier: number;\n fallback: boolean;\n generated?: string;\n}\n\n/**\n * Try to read a digest extract file. Returns null if the file doesn't exist.\n * Strips YAML frontmatter and extracts the generated timestamp.\n */\nfunction tryReadExtract(filePath: string, tier: number, fallback: boolean): ContextResult | null {\n let raw: string;\n try {\n raw = fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n\n const { body, frontmatter } = stripFrontmatter(raw);\n const generated = frontmatter.generated as string | undefined;\n\n return {\n content: body,\n tier,\n fallback,\n generated,\n };\n}\n\nexport function handleMycoContext(vaultDir: string, input: ContextInput): ContextResult {\n const requestedTier = input.tier ?? DEFAULT_CONTEXT_TIER;\n const digestDir = path.join(vaultDir, 'digest');\n\n // Try exact tier first\n const exact = tryReadExtract(path.join(digestDir, `extract-${requestedTier}.md`), requestedTier, false);\n if (exact) return exact;\n\n // Fall back to nearest available tier\n const candidates = [...DIGEST_TIERS]\n .sort((a, b) => Math.abs(a - requestedTier) - Math.abs(b - requestedTier));\n\n for (const tier of candidates) {\n const result = tryReadExtract(path.join(digestDir, `extract-${tier}.md`), tier, true);\n if (result) return result;\n }\n\n return {\n content: 'Digest context is not yet available. The first digest cycle has not completed.',\n tier: requestedTier,\n fallback: false,\n };\n}\n"],"mappings":";;;;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAKjB,IAAM,uBAAuB;AAiB7B,SAAS,eAAe,UAAkB,MAAc,UAAyC;AAC/F,MAAI;AACJ,MAAI;AACF,UAAM,GAAG,aAAa,UAAU,OAAO;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,MAAM,YAAY,IAAI,iBAAiB,GAAG;AAClD,QAAM,YAAY,YAAY;AAE9B,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,UAAkB,OAAoC;AACtF,QAAM,gBAAgB,MAAM,QAAQ;AACpC,QAAM,YAAY,KAAK,KAAK,UAAU,QAAQ;AAG9C,QAAM,QAAQ,eAAe,KAAK,KAAK,WAAW,WAAW,aAAa,KAAK,GAAG,eAAe,KAAK;AACtG,MAAI,MAAO,QAAO;AAGlB,QAAM,aAAa,CAAC,GAAG,YAAY,EAChC,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,aAAa,IAAI,KAAK,IAAI,IAAI,aAAa,CAAC;AAE3E,aAAW,QAAQ,YAAY;AAC7B,UAAM,SAAS,eAAe,KAAK,KAAK,WAAW,WAAW,IAAI,KAAK,GAAG,MAAM,IAAI;AACpF,QAAI,OAAQ,QAAO;AAAA,EACrB;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  external_exports
4
- } from "./chunk-ISCT2SI6.js";
4
+ } from "./chunk-G6ZMTQMJ.js";
5
5
  import {
6
6
  __commonJS,
7
7
  __require,
@@ -3526,12 +3526,12 @@ var PlanFrontmatterSchema = external_exports.object({
3526
3526
  tags: external_exports.array(external_exports.string()).default([])
3527
3527
  });
3528
3528
  var OBSERVATION_TYPES = ["gotcha", "bug_fix", "decision", "discovery", "trade_off", "cross-cutting"];
3529
- var MEMORY_STATUSES = ["active", "superseded", "archived"];
3530
- var MemoryFrontmatterSchema = external_exports.object({
3531
- type: external_exports.literal("memory"),
3529
+ var SPORE_STATUSES = ["active", "superseded", "archived"];
3530
+ var SporeFrontmatterSchema = external_exports.object({
3531
+ type: external_exports.literal("spore"),
3532
3532
  id: external_exports.string(),
3533
3533
  observation_type: external_exports.string(),
3534
- status: external_exports.enum(MEMORY_STATUSES).default("active"),
3534
+ status: external_exports.enum(SPORE_STATUSES).default("active"),
3535
3535
  session: external_exports.string().optional(),
3536
3536
  plan: external_exports.string().optional(),
3537
3537
  superseded_by: external_exports.string().optional(),
@@ -3561,7 +3561,7 @@ var TeamMemberFrontmatterSchema = external_exports.object({
3561
3561
  var schemasByType = {
3562
3562
  session: SessionFrontmatterSchema,
3563
3563
  plan: PlanFrontmatterSchema,
3564
- memory: MemoryFrontmatterSchema,
3564
+ spore: SporeFrontmatterSchema,
3565
3565
  artifact: ArtifactFrontmatterSchema,
3566
3566
  "team-member": TeamMemberFrontmatterSchema
3567
3567
  };
@@ -3591,7 +3591,7 @@ function coerceDatesToStrings(obj) {
3591
3591
  }
3592
3592
 
3593
3593
  // src/vault/reader.ts
3594
- var VAULT_SUBDIRS = ["sessions", "plans", "memories", "artifacts", "team"];
3594
+ var VAULT_SUBDIRS = ["sessions", "plans", "spores", "artifacts", "team"];
3595
3595
  var VaultReader = class {
3596
3596
  constructor(vaultDir) {
3597
3597
  this.vaultDir = vaultDir;
@@ -3694,4 +3694,4 @@ strip-bom-string/index.js:
3694
3694
  * Released under the MIT License.
3695
3695
  *)
3696
3696
  */
3697
- //# sourceMappingURL=chunk-AWF3M57N.js.map
3697
+ //# sourceMappingURL=chunk-S7EIHYE7.js.map