@goondocks/myco 0.4.3 → 0.5.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 (96) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +5 -1
  4. package/dist/chunk-2AMAOSRF.js +105 -0
  5. package/dist/chunk-2AMAOSRF.js.map +1 -0
  6. package/dist/{chunk-I7PNZEBO.js → chunk-6LTNFMXO.js} +12 -1
  7. package/dist/{chunk-I7PNZEBO.js.map → chunk-6LTNFMXO.js.map} +1 -1
  8. package/dist/{chunk-2GJFTIWX.js → chunk-7KQB22DP.js} +2 -2
  9. package/dist/{chunk-JBD5KP5G.js → chunk-B6WVNDA5.js} +14 -2
  10. package/dist/chunk-B6WVNDA5.js.map +1 -0
  11. package/dist/chunk-FIA5NTRH.js +159 -0
  12. package/dist/chunk-FIA5NTRH.js.map +1 -0
  13. package/dist/{chunk-GFBG73P4.js → chunk-FIRMTYFH.js} +3 -3
  14. package/dist/{chunk-XCPQHC4X.js → chunk-HJG7Z6SJ.js} +2 -2
  15. package/dist/chunk-HL2S5QZG.js +385 -0
  16. package/dist/chunk-HL2S5QZG.js.map +1 -0
  17. package/dist/{chunk-WBT5DWGC.js → chunk-IURC35BF.js} +2 -2
  18. package/dist/{chunk-67R6EMYD.js → chunk-JI6M2L2W.js} +31 -52
  19. package/dist/chunk-JI6M2L2W.js.map +1 -0
  20. package/dist/{chunk-FPEDTLQ6.js → chunk-JJL6AMDA.js} +3 -101
  21. package/dist/chunk-JJL6AMDA.js.map +1 -0
  22. package/dist/chunk-KYL67SKZ.js +150 -0
  23. package/dist/chunk-KYL67SKZ.js.map +1 -0
  24. package/dist/{chunk-ZCBL5HER.js → chunk-ND4VK6C7.js} +2 -2
  25. package/dist/{chunk-V2OWD2VV.js → chunk-R6LQT3U7.js} +24 -146
  26. package/dist/chunk-R6LQT3U7.js.map +1 -0
  27. package/dist/{chunk-IYFKPSRP.js → chunk-RCV2I4AI.js} +3 -3
  28. package/dist/{chunk-BNIYWCST.js → chunk-X6TKHO22.js} +2 -2
  29. package/dist/{chunk-OUFSLZTX.js → chunk-ZWUFTOG3.js} +21 -9
  30. package/dist/chunk-ZWUFTOG3.js.map +1 -0
  31. package/dist/{cli-PMOFCZQL.js → cli-BLYNNKGJ.js} +24 -18
  32. package/dist/cli-BLYNNKGJ.js.map +1 -0
  33. package/dist/{client-5SUO2UYH.js → client-5GB4WVXE.js} +5 -5
  34. package/dist/curate-S4HOYWXA.js +231 -0
  35. package/dist/curate-S4HOYWXA.js.map +1 -0
  36. package/dist/{detect-providers-IRL2TTLK.js → detect-providers-BIHYFK5M.js} +3 -3
  37. package/dist/digest-7NKYXM6G.js +96 -0
  38. package/dist/digest-7NKYXM6G.js.map +1 -0
  39. package/dist/{init-NUF5UBUJ.js → init-HPQ77WWF.js} +5 -5
  40. package/dist/{main-2XEBVUR6.js → main-NFQ4II75.js} +253 -576
  41. package/dist/main-NFQ4II75.js.map +1 -0
  42. package/dist/{rebuild-E6YFIRYZ.js → rebuild-KQ6G2GZM.js} +8 -7
  43. package/dist/{rebuild-E6YFIRYZ.js.map → rebuild-KQ6G2GZM.js.map} +1 -1
  44. package/dist/{reprocess-7G7KQWCN.js → reprocess-ZL4HKTSC.js} +95 -24
  45. package/dist/reprocess-ZL4HKTSC.js.map +1 -0
  46. package/dist/{restart-ABW4ZK3P.js → restart-FYW662DR.js} +6 -6
  47. package/dist/{search-MPD7SFK6.js → search-E5JQMTXV.js} +6 -6
  48. package/dist/{server-NZLZRITH.js → server-TV3D35HZ.js} +38 -15
  49. package/dist/{server-NZLZRITH.js.map → server-TV3D35HZ.js.map} +1 -1
  50. package/dist/{session-start-YB4A4PZB.js → session-start-5MFEOVQ5.js} +6 -6
  51. package/dist/{setup-digest-K732MGOJ.js → setup-digest-DZAFIBEF.js} +5 -5
  52. package/dist/{setup-llm-XCCH5LYD.js → setup-llm-4BZM33YT.js} +5 -5
  53. package/dist/src/cli.js +4 -4
  54. package/dist/src/daemon/main.js +4 -4
  55. package/dist/src/hooks/post-tool-use.js +5 -5
  56. package/dist/src/hooks/session-end.js +5 -5
  57. package/dist/src/hooks/session-start.js +4 -4
  58. package/dist/src/hooks/stop.js +6 -6
  59. package/dist/src/hooks/stop.js.map +1 -1
  60. package/dist/src/hooks/user-prompt-submit.js +5 -5
  61. package/dist/src/mcp/server.js +4 -4
  62. package/dist/src/prompts/extraction.md +1 -1
  63. package/dist/src/prompts/summary.md +1 -11
  64. package/dist/src/prompts/supersession.md +32 -0
  65. package/dist/{stats-6G7SN5YZ.js → stats-ZIIJ2GB3.js} +5 -5
  66. package/dist/{verify-JFHQH55Z.js → verify-RACBFT2P.js} +4 -4
  67. package/dist/{version-5B2TWXQJ.js → version-HJTVNPOO.js} +4 -4
  68. package/package.json +1 -1
  69. package/skills/setup/SKILL.md +56 -28
  70. package/skills/setup/references/model-recommendations.md +49 -43
  71. package/dist/chunk-67R6EMYD.js.map +0 -1
  72. package/dist/chunk-FPEDTLQ6.js.map +0 -1
  73. package/dist/chunk-JBD5KP5G.js.map +0 -1
  74. package/dist/chunk-OUFSLZTX.js.map +0 -1
  75. package/dist/chunk-V2OWD2VV.js.map +0 -1
  76. package/dist/cli-PMOFCZQL.js.map +0 -1
  77. package/dist/main-2XEBVUR6.js.map +0 -1
  78. package/dist/reprocess-7G7KQWCN.js.map +0 -1
  79. /package/dist/{chunk-2GJFTIWX.js.map → chunk-7KQB22DP.js.map} +0 -0
  80. /package/dist/{chunk-GFBG73P4.js.map → chunk-FIRMTYFH.js.map} +0 -0
  81. /package/dist/{chunk-XCPQHC4X.js.map → chunk-HJG7Z6SJ.js.map} +0 -0
  82. /package/dist/{chunk-WBT5DWGC.js.map → chunk-IURC35BF.js.map} +0 -0
  83. /package/dist/{chunk-ZCBL5HER.js.map → chunk-ND4VK6C7.js.map} +0 -0
  84. /package/dist/{chunk-IYFKPSRP.js.map → chunk-RCV2I4AI.js.map} +0 -0
  85. /package/dist/{chunk-BNIYWCST.js.map → chunk-X6TKHO22.js.map} +0 -0
  86. /package/dist/{client-5SUO2UYH.js.map → client-5GB4WVXE.js.map} +0 -0
  87. /package/dist/{detect-providers-IRL2TTLK.js.map → detect-providers-BIHYFK5M.js.map} +0 -0
  88. /package/dist/{init-NUF5UBUJ.js.map → init-HPQ77WWF.js.map} +0 -0
  89. /package/dist/{restart-ABW4ZK3P.js.map → restart-FYW662DR.js.map} +0 -0
  90. /package/dist/{search-MPD7SFK6.js.map → search-E5JQMTXV.js.map} +0 -0
  91. /package/dist/{session-start-YB4A4PZB.js.map → session-start-5MFEOVQ5.js.map} +0 -0
  92. /package/dist/{setup-digest-K732MGOJ.js.map → setup-digest-DZAFIBEF.js.map} +0 -0
  93. /package/dist/{setup-llm-XCCH5LYD.js.map → setup-llm-4BZM33YT.js.map} +0 -0
  94. /package/dist/{stats-6G7SN5YZ.js.map → stats-ZIIJ2GB3.js.map} +0 -0
  95. /package/dist/{verify-JFHQH55Z.js.map → verify-RACBFT2P.js.map} +0 -0
  96. /package/dist/{version-5B2TWXQJ.js.map → version-HJTVNPOO.js.map} +0 -0
@@ -2,14 +2,14 @@
2
2
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
3
3
  import {
4
4
  loadEnv
5
- } from "./chunk-GFBG73P4.js";
5
+ } from "./chunk-FIRMTYFH.js";
6
6
  import "./chunk-SAKJMNSR.js";
7
- import "./chunk-67R6EMYD.js";
7
+ import "./chunk-JI6M2L2W.js";
8
8
  import {
9
9
  resolveVaultDir
10
10
  } from "./chunk-N33KUCFP.js";
11
- import "./chunk-BNIYWCST.js";
12
- import "./chunk-JBD5KP5G.js";
11
+ import "./chunk-X6TKHO22.js";
12
+ import "./chunk-B6WVNDA5.js";
13
13
  import "./chunk-PZUWP5VK.js";
14
14
 
15
15
  // src/cli.ts
@@ -21,6 +21,7 @@ var USAGE = `Usage: myco <command> [args]
21
21
  Commands:
22
22
  init [options] Initialize a new vault
23
23
  config <get|set> [args] Get or set vault config values
24
+ curate [options] Scan vault and supersede stale spores (--dry-run)
24
25
  detect-providers Detect available LLM/embedding providers (JSON)
25
26
  verify Test LLM and embedding connectivity
26
27
  stats Vault health, index counts, vector count
@@ -30,9 +31,10 @@ Commands:
30
31
  logs [options] View daemon logs
31
32
  setup-llm [options] Configure LLM and embedding providers
32
33
  setup-digest [options] Configure digest and capture settings
34
+ digest [options] Run a digest cycle (--tier N, --full)
33
35
  restart Restart the daemon
34
36
  rebuild Reindex the entire vault
35
- reprocess [options] Re-extract observations and re-index sessions
37
+ reprocess [options] Re-extract observations, regenerate summaries, re-index
36
38
  version Show plugin version
37
39
  `;
38
40
  async function main() {
@@ -41,10 +43,10 @@ async function main() {
41
43
  process.stdout.write(USAGE);
42
44
  return;
43
45
  }
44
- if (cmd === "init") return (await import("./init-NUF5UBUJ.js")).run(args);
45
- if (cmd === "detect-providers") return (await import("./detect-providers-IRL2TTLK.js")).run(args);
46
+ if (cmd === "init") return (await import("./init-HPQ77WWF.js")).run(args);
47
+ if (cmd === "detect-providers") return (await import("./detect-providers-BIHYFK5M.js")).run(args);
46
48
  if (cmd === "version" || cmd === "--version" || cmd === "-v") {
47
- const { getPluginVersion } = await import("./version-5B2TWXQJ.js");
49
+ const { getPluginVersion } = await import("./version-HJTVNPOO.js");
48
50
  console.log(getPluginVersion());
49
51
  return;
50
52
  }
@@ -56,26 +58,30 @@ async function main() {
56
58
  switch (cmd) {
57
59
  case "config":
58
60
  return (await import("./config-5FGLQGCW.js")).run(args, vaultDir);
61
+ case "curate":
62
+ return (await import("./curate-S4HOYWXA.js")).run(args, vaultDir);
59
63
  case "verify":
60
- return (await import("./verify-JFHQH55Z.js")).run(args, vaultDir);
64
+ return (await import("./verify-RACBFT2P.js")).run(args, vaultDir);
61
65
  case "stats":
62
- return (await import("./stats-6G7SN5YZ.js")).run(args, vaultDir);
66
+ return (await import("./stats-ZIIJ2GB3.js")).run(args, vaultDir);
63
67
  case "search":
64
- return (await import("./search-MPD7SFK6.js")).run(args, vaultDir);
68
+ return (await import("./search-E5JQMTXV.js")).run(args, vaultDir);
65
69
  case "vectors":
66
- return (await import("./search-MPD7SFK6.js")).runVectors(args, vaultDir);
70
+ return (await import("./search-E5JQMTXV.js")).runVectors(args, vaultDir);
67
71
  case "session":
68
72
  return (await import("./session-QF6MILAC.js")).run(args, vaultDir);
69
73
  case "setup-llm":
70
- return (await import("./setup-llm-XCCH5LYD.js")).run(args, vaultDir);
74
+ return (await import("./setup-llm-4BZM33YT.js")).run(args, vaultDir);
71
75
  case "setup-digest":
72
- return (await import("./setup-digest-K732MGOJ.js")).run(args, vaultDir);
76
+ return (await import("./setup-digest-DZAFIBEF.js")).run(args, vaultDir);
77
+ case "digest":
78
+ return (await import("./digest-7NKYXM6G.js")).run(args, vaultDir);
73
79
  case "restart":
74
- return (await import("./restart-ABW4ZK3P.js")).run(args, vaultDir);
80
+ return (await import("./restart-FYW662DR.js")).run(args, vaultDir);
75
81
  case "rebuild":
76
- return (await import("./rebuild-E6YFIRYZ.js")).run(args, vaultDir);
82
+ return (await import("./rebuild-KQ6G2GZM.js")).run(args, vaultDir);
77
83
  case "reprocess":
78
- return (await import("./reprocess-7G7KQWCN.js")).run(args, vaultDir);
84
+ return (await import("./reprocess-ZL4HKTSC.js")).run(args, vaultDir);
79
85
  case "logs":
80
86
  return (await import("./logs-BSTBZHDR.js")).run(args, vaultDir);
81
87
  default:
@@ -88,4 +94,4 @@ main().catch((err) => {
88
94
  console.error(`myco: ${err.message}`);
89
95
  process.exit(1);
90
96
  });
91
- //# sourceMappingURL=cli-PMOFCZQL.js.map
97
+ //# sourceMappingURL=cli-BLYNNKGJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { loadEnv } from './cli/shared.js';\nimport { resolveVaultDir } from './vault/resolve.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nloadEnv();\n\nconst USAGE = `Usage: myco <command> [args]\n\nCommands:\n init [options] Initialize a new vault\n config <get|set> [args] Get or set vault config values\n curate [options] Scan vault and supersede stale spores (--dry-run)\n detect-providers Detect available LLM/embedding providers (JSON)\n verify Test LLM and embedding connectivity\n stats Vault health, index counts, vector count\n search <query> Combined FTS + vector search with scores\n vectors <query> Raw vector search with similarity scores\n session [id|latest] Show a session note\n logs [options] View daemon logs\n setup-llm [options] Configure LLM and embedding providers\n setup-digest [options] Configure digest and capture settings\n digest [options] Run a digest cycle (--tier N, --full)\n restart Restart the daemon\n rebuild Reindex the entire vault\n reprocess [options] Re-extract observations, regenerate summaries, re-index\n version Show plugin version\n`;\n\nasync function main(): Promise<void> {\n const [cmd, ...args] = process.argv.slice(2);\n if (!cmd || cmd === '--help' || cmd === '-h') {\n process.stdout.write(USAGE);\n return;\n }\n\n if (cmd === 'init') return (await import('./cli/init.js')).run(args);\n if (cmd === 'detect-providers') return (await import('./cli/detect-providers.js')).run(args);\n if (cmd === 'version' || cmd === '--version' || cmd === '-v') {\n const { getPluginVersion } = await import('./version.js');\n console.log(getPluginVersion());\n return;\n }\n\n const vaultDir = resolveVaultDir();\n if (!fs.existsSync(path.join(vaultDir, 'myco.yaml'))) {\n console.error(`No myco.yaml found in ${vaultDir}. Run 'myco init' first.`);\n process.exit(1);\n }\n\n switch (cmd) {\n case 'config': return (await import('./cli/config.js')).run(args, vaultDir);\n case 'curate': return (await import('./cli/curate.js')).run(args, vaultDir);\n case 'verify': return (await import('./cli/verify.js')).run(args, vaultDir);\n case 'stats': return (await import('./cli/stats.js')).run(args, vaultDir);\n case 'search': return (await import('./cli/search.js')).run(args, vaultDir);\n case 'vectors': return (await import('./cli/search.js')).runVectors(args, vaultDir);\n case 'session': return (await import('./cli/session.js')).run(args, vaultDir);\n case 'setup-llm': return (await import('./cli/setup-llm.js')).run(args, vaultDir);\n case 'setup-digest': return (await import('./cli/setup-digest.js')).run(args, vaultDir);\n case 'digest': return (await import('./cli/digest.js')).run(args, vaultDir);\n case 'restart': return (await import('./cli/restart.js')).run(args, vaultDir);\n case 'rebuild': return (await import('./cli/rebuild.js')).run(args, vaultDir);\n case 'reprocess': return (await import('./cli/reprocess.js')).run(args, vaultDir);\n case 'logs': return (await import('./cli/logs.js')).run(args, vaultDir);\n default:\n console.error(`Unknown command: ${cmd}`);\n process.stdout.write(USAGE);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error(`myco: ${(err as Error).message}`);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;AAGA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,QAAQ;AAER,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBd,eAAe,OAAsB;AACnC,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC;AAC3C,MAAI,CAAC,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC5C,YAAQ,OAAO,MAAM,KAAK;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,OAAQ,SAAQ,MAAM,OAAO,oBAAe,GAAG,IAAI,IAAI;AACnE,MAAI,QAAQ,mBAAoB,SAAQ,MAAM,OAAO,gCAA2B,GAAG,IAAI,IAAI;AAC3F,MAAI,QAAQ,aAAa,QAAQ,eAAe,QAAQ,MAAM;AAC5D,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,uBAAc;AACxD,YAAQ,IAAI,iBAAiB,CAAC;AAC9B;AAAA,EACF;AAEA,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,GAAG,WAAW,KAAK,KAAK,UAAU,WAAW,CAAC,GAAG;AACpD,YAAQ,MAAM,yBAAyB,QAAQ,0BAA0B;AACzE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,KAAK;AAAA,IACX,KAAK;AAAU,cAAQ,MAAM,OAAO,sBAAiB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC1E,KAAK;AAAU,cAAQ,MAAM,OAAO,sBAAiB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC1E,KAAK;AAAU,cAAQ,MAAM,OAAO,sBAAiB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC1E,KAAK;AAAS,cAAQ,MAAM,OAAO,qBAAgB,GAAG,IAAI,MAAM,QAAQ;AAAA,IACxE,KAAK;AAAU,cAAQ,MAAM,OAAO,sBAAiB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC1E,KAAK;AAAW,cAAQ,MAAM,OAAO,sBAAiB,GAAG,WAAW,MAAM,QAAQ;AAAA,IAClF,KAAK;AAAW,cAAQ,MAAM,OAAO,uBAAkB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC5E,KAAK;AAAa,cAAQ,MAAM,OAAO,yBAAoB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAChF,KAAK;AAAgB,cAAQ,MAAM,OAAO,4BAAuB,GAAG,IAAI,MAAM,QAAQ;AAAA,IACtF,KAAK;AAAU,cAAQ,MAAM,OAAO,sBAAiB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC1E,KAAK;AAAW,cAAQ,MAAM,OAAO,uBAAkB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC5E,KAAK;AAAW,cAAQ,MAAM,OAAO,uBAAkB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAC5E,KAAK;AAAa,cAAQ,MAAM,OAAO,yBAAoB,GAAG,IAAI,MAAM,QAAQ;AAAA,IAChF,KAAK;AAAQ,cAAQ,MAAM,OAAO,oBAAe,GAAG,IAAI,MAAM,QAAQ;AAAA,IACtE;AACE,cAAQ,MAAM,oBAAoB,GAAG,EAAE;AACvC,cAAQ,OAAO,MAAM,KAAK;AAC1B,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,SAAU,IAAc,OAAO,EAAE;AAC/C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -1,12 +1,12 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
2
  import {
3
3
  DaemonClient
4
- } from "./chunk-OUFSLZTX.js";
5
- import "./chunk-2GJFTIWX.js";
6
- import "./chunk-BNIYWCST.js";
7
- import "./chunk-JBD5KP5G.js";
4
+ } from "./chunk-ZWUFTOG3.js";
5
+ import "./chunk-7KQB22DP.js";
6
+ import "./chunk-X6TKHO22.js";
7
+ import "./chunk-B6WVNDA5.js";
8
8
  import "./chunk-PZUWP5VK.js";
9
9
  export {
10
10
  DaemonClient
11
11
  };
12
- //# sourceMappingURL=client-5SUO2UYH.js.map
12
+ //# sourceMappingURL=client-5GB4WVXE.js.map
@@ -0,0 +1,231 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ isActiveSpore,
4
+ supersedeSpore,
5
+ supersededIdsSchema
6
+ } from "./chunk-FIA5NTRH.js";
7
+ import "./chunk-JJL6AMDA.js";
8
+ import {
9
+ generateEmbedding
10
+ } from "./chunk-RGVBGTD6.js";
11
+ import {
12
+ VectorIndex
13
+ } from "./chunk-XQXXF6MU.js";
14
+ import {
15
+ loadPrompt,
16
+ stripReasoningTokens
17
+ } from "./chunk-KYL67SKZ.js";
18
+ import "./chunk-2AMAOSRF.js";
19
+ import {
20
+ createEmbeddingProvider,
21
+ createLlmProvider
22
+ } from "./chunk-RCV2I4AI.js";
23
+ import {
24
+ MycoIndex
25
+ } from "./chunk-AK6GNLPV.js";
26
+ import "./chunk-JI6M2L2W.js";
27
+ import {
28
+ loadConfig
29
+ } from "./chunk-TBRZAJ7W.js";
30
+ import "./chunk-6UJWI4IW.js";
31
+ import {
32
+ CURATION_CLUSTER_SIMILARITY,
33
+ EMBEDDING_INPUT_LIMIT,
34
+ LLM_REASONING_MODE,
35
+ SUPERSESSION_MAX_TOKENS
36
+ } from "./chunk-B6WVNDA5.js";
37
+ import "./chunk-PZUWP5VK.js";
38
+
39
+ // src/cli/curate.ts
40
+ import path from "path";
41
+ var EMBEDDING_BATCH_SIZE = 10;
42
+ function cosineSimilarity(a, b) {
43
+ let dot = 0, normA = 0, normB = 0;
44
+ for (let i = 0; i < a.length; i++) {
45
+ dot += a[i] * b[i];
46
+ normA += a[i] * a[i];
47
+ normB += b[i] * b[i];
48
+ }
49
+ return dot / (Math.sqrt(normA) * Math.sqrt(normB));
50
+ }
51
+ function updateCentroid(spores) {
52
+ if (spores.length === 0) return [];
53
+ const dim = spores[0].embedding.length;
54
+ const centroid = new Array(dim).fill(0);
55
+ for (const s of spores) {
56
+ for (let i = 0; i < dim; i++) {
57
+ centroid[i] += s.embedding[i];
58
+ }
59
+ }
60
+ for (let i = 0; i < dim; i++) {
61
+ centroid[i] /= spores.length;
62
+ }
63
+ return centroid;
64
+ }
65
+ function clusterSpores(spores) {
66
+ const clusters = [];
67
+ for (const spore of spores) {
68
+ let bestCluster = null;
69
+ let bestSimilarity = -1;
70
+ for (const cluster of clusters) {
71
+ const sim = cosineSimilarity(spore.embedding, cluster.centroid);
72
+ if (sim > bestSimilarity) {
73
+ bestSimilarity = sim;
74
+ bestCluster = cluster;
75
+ }
76
+ }
77
+ if (bestCluster !== null && bestSimilarity >= CURATION_CLUSTER_SIMILARITY) {
78
+ bestCluster.spores.push(spore);
79
+ bestCluster.centroid = updateCentroid(bestCluster.spores);
80
+ } else {
81
+ clusters.push({ spores: [spore], centroid: [...spore.embedding] });
82
+ }
83
+ }
84
+ return clusters;
85
+ }
86
+ async function run(args, vaultDir) {
87
+ const isDryRun = args.includes("--dry-run");
88
+ const config = loadConfig(vaultDir);
89
+ const index = new MycoIndex(path.join(vaultDir, "index.db"));
90
+ const llmProvider = createLlmProvider(config.intelligence.llm);
91
+ const embeddingProvider = createEmbeddingProvider(config.intelligence.embedding);
92
+ let vectorIndex = null;
93
+ try {
94
+ const testEmbed = await embeddingProvider.embed("test");
95
+ vectorIndex = new VectorIndex(path.join(vaultDir, "vectors.db"), testEmbed.dimensions);
96
+ } catch (e) {
97
+ console.error(`Vector index unavailable: ${e.message}`);
98
+ console.error("Curate requires a working embedding provider.");
99
+ index.close();
100
+ process.exit(1);
101
+ }
102
+ try {
103
+ if (isDryRun) {
104
+ console.log("Dry run \u2014 no changes will be written.\n");
105
+ }
106
+ const allSpores = index.query({ type: "spore" });
107
+ const activeSpores = allSpores.filter((n) => isActiveSpore(n.frontmatter));
108
+ console.log(`Scanning ${activeSpores.length} active spores...`);
109
+ if (activeSpores.length === 0) {
110
+ console.log("No active spores found.");
111
+ return;
112
+ }
113
+ const sporesWithEmbeddings = [];
114
+ let embedFailures = 0;
115
+ for (let i = 0; i < activeSpores.length; i += EMBEDDING_BATCH_SIZE) {
116
+ const batch = activeSpores.slice(i, i + EMBEDDING_BATCH_SIZE);
117
+ const results = await Promise.allSettled(
118
+ batch.map(async (spore) => {
119
+ const text = spore.content.slice(0, EMBEDDING_INPUT_LIMIT);
120
+ const result = await generateEmbedding(embeddingProvider, text);
121
+ return { spore, embedding: result.embedding };
122
+ })
123
+ );
124
+ for (const result of results) {
125
+ if (result.status === "fulfilled") {
126
+ const { spore, embedding } = result.value;
127
+ sporesWithEmbeddings.push({
128
+ id: spore.id,
129
+ path: spore.path,
130
+ title: spore.title,
131
+ content: spore.content,
132
+ created: spore.created,
133
+ frontmatter: spore.frontmatter,
134
+ embedding
135
+ });
136
+ } else {
137
+ embedFailures++;
138
+ }
139
+ }
140
+ }
141
+ if (embedFailures > 0) {
142
+ console.log(`Warning: ${embedFailures} spore(s) could not be embedded and were skipped.`);
143
+ }
144
+ const byType = /* @__PURE__ */ new Map();
145
+ for (const spore of sporesWithEmbeddings) {
146
+ const obsType = spore.frontmatter["observation_type"] ?? "unknown";
147
+ if (!byType.has(obsType)) byType.set(obsType, []);
148
+ byType.get(obsType).push(spore);
149
+ }
150
+ const template = loadPrompt("supersession");
151
+ let totalClusters = 0;
152
+ let totalSuperseded = 0;
153
+ for (const [obsType, typeSpores] of byType) {
154
+ const clusters = clusterSpores(typeSpores);
155
+ const multiSpore = clusters.filter((c) => c.spores.length >= 2);
156
+ if (multiSpore.length === 0) continue;
157
+ console.log(`
158
+ Type: ${obsType} \u2014 ${typeSpores.length} spores, ${multiSpore.length} cluster(s) to evaluate`);
159
+ totalClusters += multiSpore.length;
160
+ for (const cluster of multiSpore) {
161
+ const sorted = [...cluster.spores].sort((a, b) => a.created.localeCompare(b.created));
162
+ const newest = sorted[sorted.length - 1];
163
+ const candidates = sorted.slice(0, sorted.length - 1);
164
+ const newSporeText = `[${newest.id}] ${newest.title}
165
+ ${newest.content}`;
166
+ const candidatesText = candidates.map((c) => `[${c.id}] ${c.title}
167
+ ${c.content}`).join("\n\n");
168
+ const prompt = template.replace("{{new_spore}}", newSporeText).replace("{{candidates}}", candidatesText);
169
+ let responseText;
170
+ try {
171
+ const response = await llmProvider.summarize(prompt, {
172
+ maxTokens: SUPERSESSION_MAX_TOKENS,
173
+ reasoning: LLM_REASONING_MODE
174
+ });
175
+ responseText = stripReasoningTokens(response.text);
176
+ } catch (err) {
177
+ console.log(` Warning: LLM call failed for cluster in ${obsType}: ${String(err)}`);
178
+ continue;
179
+ }
180
+ let rawIds;
181
+ try {
182
+ rawIds = JSON.parse(responseText);
183
+ } catch {
184
+ console.log(` Warning: Could not parse LLM response for cluster in ${obsType}`);
185
+ continue;
186
+ }
187
+ const parsed = supersededIdsSchema.safeParse(rawIds);
188
+ if (!parsed.success) {
189
+ console.log(` Warning: LLM response schema invalid for cluster in ${obsType}`);
190
+ continue;
191
+ }
192
+ const candidateMap = new Map(candidates.map((c) => [c.id, c]));
193
+ const validIds = parsed.data.filter((id) => candidateMap.has(id));
194
+ if (validIds.length === 0) continue;
195
+ for (const id of validIds) {
196
+ const candidate = candidateMap.get(id);
197
+ if (isDryRun) {
198
+ console.log(` [dry-run] Would supersede: ${candidate.title} (${id})`);
199
+ console.log(` Superseded by: ${newest.title} (${newest.id})`);
200
+ totalSuperseded++;
201
+ continue;
202
+ }
203
+ const wrote = supersedeSpore(id, newest.id, candidate.path, { index, vectorIndex, vaultDir });
204
+ if (!wrote) {
205
+ console.log(` Warning: file not found for ${id}, skipping write`);
206
+ continue;
207
+ }
208
+ console.log(` Superseded: ${candidate.title} (${id})`);
209
+ console.log(` By: ${newest.title} (${newest.id})`);
210
+ totalSuperseded++;
211
+ }
212
+ }
213
+ }
214
+ console.log(`
215
+ Curation complete:`);
216
+ console.log(` Scanned: ${activeSpores.length} active spores`);
217
+ console.log(` Clusters evaluated: ${totalClusters}`);
218
+ if (isDryRun) {
219
+ console.log(` Would supersede: ${totalSuperseded}`);
220
+ } else {
221
+ console.log(` Superseded: ${totalSuperseded}`);
222
+ }
223
+ } finally {
224
+ index.close();
225
+ vectorIndex?.close();
226
+ }
227
+ }
228
+ export {
229
+ run
230
+ };
231
+ //# sourceMappingURL=curate-S4HOYWXA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/curate.ts"],"sourcesContent":["/**\n * myco curate — scan the vault for stale spores and supersede them.\n *\n * Usage:\n * myco curate Scan and supersede stale spores\n * myco curate --dry-run Show what would be superseded without writing\n *\n * Algorithm:\n * 1. Load all active spores from the index\n * 2. Group by observation_type\n * 3. Within each group, embed spores and cluster by cosine similarity\n * 4. For each cluster with 2+ members, ask the LLM which are outdated\n * 5. Mark superseded: update frontmatter, append notice, re-index, remove vector\n */\nimport path from 'node:path';\nimport { loadConfig } from '../config/loader.js';\nimport { MycoIndex } from '../index/sqlite.js';\nimport { VectorIndex } from '../index/vectors.js';\nimport { createLlmProvider, createEmbeddingProvider } from '../intelligence/llm.js';\nimport { generateEmbedding } from '../intelligence/embeddings.js';\nimport { stripReasoningTokens } from '../intelligence/response.js';\nimport { loadPrompt } from '../prompts/index.js';\nimport { supersedeSpore, supersededIdsSchema, isActiveSpore } from '../vault/curation.js';\nimport {\n CURATION_CLUSTER_SIMILARITY,\n EMBEDDING_INPUT_LIMIT,\n SUPERSESSION_MAX_TOKENS,\n LLM_REASONING_MODE,\n} from '../constants.js';\n\n/** Max concurrent embedding requests to avoid overwhelming the provider. */\nconst EMBEDDING_BATCH_SIZE = 10;\n\nfunction cosineSimilarity(a: number[], b: number[]): number {\n let dot = 0, normA = 0, normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n return dot / (Math.sqrt(normA) * Math.sqrt(normB));\n}\n\ninterface SporeWithEmbedding {\n id: string;\n path: string;\n title: string;\n content: string;\n created: string;\n frontmatter: Record<string, unknown>;\n embedding: number[];\n}\n\ninterface Cluster {\n spores: SporeWithEmbedding[];\n centroid: number[];\n}\n\nfunction updateCentroid(spores: SporeWithEmbedding[]): number[] {\n if (spores.length === 0) return [];\n const dim = spores[0].embedding.length;\n const centroid = new Array<number>(dim).fill(0);\n for (const s of spores) {\n for (let i = 0; i < dim; i++) {\n centroid[i] += s.embedding[i];\n }\n }\n for (let i = 0; i < dim; i++) {\n centroid[i] /= spores.length;\n }\n return centroid;\n}\n\nfunction clusterSpores(spores: SporeWithEmbedding[]): Cluster[] {\n const clusters: Cluster[] = [];\n\n for (const spore of spores) {\n let bestCluster: Cluster | null = null;\n let bestSimilarity = -1;\n\n for (const cluster of clusters) {\n const sim = cosineSimilarity(spore.embedding, cluster.centroid);\n if (sim > bestSimilarity) {\n bestSimilarity = sim;\n bestCluster = cluster;\n }\n }\n\n if (bestCluster !== null && bestSimilarity >= CURATION_CLUSTER_SIMILARITY) {\n bestCluster.spores.push(spore);\n bestCluster.centroid = updateCentroid(bestCluster.spores);\n } else {\n clusters.push({ spores: [spore], centroid: [...spore.embedding] });\n }\n }\n\n return clusters;\n}\n\nexport async function run(args: string[], vaultDir: string): Promise<void> {\n const isDryRun = args.includes('--dry-run');\n\n const config = loadConfig(vaultDir);\n const index = new MycoIndex(path.join(vaultDir, 'index.db'));\n\n const llmProvider = createLlmProvider(config.intelligence.llm);\n const embeddingProvider = createEmbeddingProvider(config.intelligence.embedding);\n\n let vectorIndex: VectorIndex | null = null;\n try {\n const testEmbed = await embeddingProvider.embed('test');\n vectorIndex = new VectorIndex(path.join(vaultDir, 'vectors.db'), testEmbed.dimensions);\n } catch (e) {\n console.error(`Vector index unavailable: ${(e as Error).message}`);\n console.error('Curate requires a working embedding provider.');\n index.close();\n process.exit(1);\n }\n\n try {\n if (isDryRun) {\n console.log('Dry run — no changes will be written.\\n');\n }\n\n // 1. Query all spores and filter for active ones\n const allSpores = index.query({ type: 'spore' });\n const activeSpores = allSpores.filter((n) => isActiveSpore(n.frontmatter));\n\n console.log(`Scanning ${activeSpores.length} active spores...`);\n\n if (activeSpores.length === 0) {\n console.log('No active spores found.');\n return;\n }\n\n // 2. Embed all active spores (batched for concurrency)\n const sporesWithEmbeddings: SporeWithEmbedding[] = [];\n let embedFailures = 0;\n\n for (let i = 0; i < activeSpores.length; i += EMBEDDING_BATCH_SIZE) {\n const batch = activeSpores.slice(i, i + EMBEDDING_BATCH_SIZE);\n const results = await Promise.allSettled(\n batch.map(async (spore) => {\n const text = spore.content.slice(0, EMBEDDING_INPUT_LIMIT);\n const result = await generateEmbedding(embeddingProvider, text);\n return { spore, embedding: result.embedding };\n }),\n );\n\n for (const result of results) {\n if (result.status === 'fulfilled') {\n const { spore, embedding } = result.value;\n sporesWithEmbeddings.push({\n id: spore.id,\n path: spore.path,\n title: spore.title,\n content: spore.content,\n created: spore.created,\n frontmatter: spore.frontmatter,\n embedding,\n });\n } else {\n embedFailures++;\n }\n }\n }\n\n if (embedFailures > 0) {\n console.log(`Warning: ${embedFailures} spore(s) could not be embedded and were skipped.`);\n }\n\n // 3. Group by observation_type\n const byType = new Map<string, SporeWithEmbedding[]>();\n for (const spore of sporesWithEmbeddings) {\n const obsType = (spore.frontmatter['observation_type'] as string | undefined) ?? 'unknown';\n if (!byType.has(obsType)) byType.set(obsType, []);\n byType.get(obsType)!.push(spore);\n }\n\n // 4. Cluster within each type group\n const template = loadPrompt('supersession');\n let totalClusters = 0;\n let totalSuperseded = 0;\n\n for (const [obsType, typeSpores] of byType) {\n const clusters = clusterSpores(typeSpores);\n const multiSpore = clusters.filter((c) => c.spores.length >= 2);\n\n if (multiSpore.length === 0) continue;\n\n console.log(`\\nType: ${obsType} — ${typeSpores.length} spores, ${multiSpore.length} cluster(s) to evaluate`);\n totalClusters += multiSpore.length;\n\n for (const cluster of multiSpore) {\n // Sort by created date ascending; newest is last\n const sorted = [...cluster.spores].sort((a, b) => a.created.localeCompare(b.created));\n const newest = sorted[sorted.length - 1];\n const candidates = sorted.slice(0, sorted.length - 1);\n\n // 5. Build supersession prompt\n const newSporeText = `[${newest.id}] ${newest.title}\\n${newest.content}`;\n const candidatesText = candidates\n .map((c) => `[${c.id}] ${c.title}\\n${c.content}`)\n .join('\\n\\n');\n\n const prompt = template\n .replace('{{new_spore}}', newSporeText)\n .replace('{{candidates}}', candidatesText);\n\n // 6. Ask LLM which candidates are outdated\n let responseText: string;\n try {\n const response = await llmProvider.summarize(prompt, {\n maxTokens: SUPERSESSION_MAX_TOKENS,\n reasoning: LLM_REASONING_MODE,\n });\n responseText = stripReasoningTokens(response.text);\n } catch (err) {\n console.log(` Warning: LLM call failed for cluster in ${obsType}: ${String(err)}`);\n continue;\n }\n\n // Parse response\n let rawIds: unknown;\n try {\n rawIds = JSON.parse(responseText);\n } catch {\n console.log(` Warning: Could not parse LLM response for cluster in ${obsType}`);\n continue;\n }\n\n const parsed = supersededIdsSchema.safeParse(rawIds);\n if (!parsed.success) {\n console.log(` Warning: LLM response schema invalid for cluster in ${obsType}`);\n continue;\n }\n\n // Validate IDs against actual candidates\n const candidateMap = new Map(candidates.map((c) => [c.id, c]));\n const validIds = parsed.data.filter((id) => candidateMap.has(id));\n\n if (validIds.length === 0) continue;\n\n for (const id of validIds) {\n const candidate = candidateMap.get(id)!;\n\n if (isDryRun) {\n console.log(` [dry-run] Would supersede: ${candidate.title} (${id})`);\n console.log(` Superseded by: ${newest.title} (${newest.id})`);\n totalSuperseded++;\n continue;\n }\n\n const wrote = supersedeSpore(id, newest.id, candidate.path, { index, vectorIndex, vaultDir });\n\n if (!wrote) {\n console.log(` Warning: file not found for ${id}, skipping write`);\n continue;\n }\n\n console.log(` Superseded: ${candidate.title} (${id})`);\n console.log(` By: ${newest.title} (${newest.id})`);\n totalSuperseded++;\n }\n }\n }\n\n // 8. Summary\n console.log(`\\nCuration complete:`);\n console.log(` Scanned: ${activeSpores.length} active spores`);\n console.log(` Clusters evaluated: ${totalClusters}`);\n if (isDryRun) {\n console.log(` Would supersede: ${totalSuperseded}`);\n } else {\n console.log(` Superseded: ${totalSuperseded}`);\n }\n } finally {\n index.close();\n vectorIndex?.close();\n }\n}\n"],"mappings":"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","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-67R6EMYD.js";
5
+ } from "./chunk-JI6M2L2W.js";
6
6
  import {
7
7
  PROVIDER_DETECT_TIMEOUT_MS
8
- } from "./chunk-JBD5KP5G.js";
8
+ } from "./chunk-B6WVNDA5.js";
9
9
  import "./chunk-PZUWP5VK.js";
10
10
 
11
11
  // src/cli/detect-providers.ts
@@ -32,4 +32,4 @@ async function run(_args) {
32
32
  export {
33
33
  run
34
34
  };
35
- //# sourceMappingURL=detect-providers-IRL2TTLK.js.map
35
+ //# sourceMappingURL=detect-providers-BIHYFK5M.js.map
@@ -0,0 +1,96 @@
1
+ import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ DigestEngine
4
+ } from "./chunk-HL2S5QZG.js";
5
+ import "./chunk-KYL67SKZ.js";
6
+ import "./chunk-2AMAOSRF.js";
7
+ import {
8
+ createLlmProvider
9
+ } from "./chunk-RCV2I4AI.js";
10
+ import "./chunk-MIU3DKLN.js";
11
+ import {
12
+ MycoIndex
13
+ } from "./chunk-AK6GNLPV.js";
14
+ import "./chunk-FIRMTYFH.js";
15
+ import {
16
+ parseIntFlag
17
+ } from "./chunk-SAKJMNSR.js";
18
+ import "./chunk-JI6M2L2W.js";
19
+ import {
20
+ loadConfig
21
+ } from "./chunk-TBRZAJ7W.js";
22
+ import "./chunk-6UJWI4IW.js";
23
+ import "./chunk-X6TKHO22.js";
24
+ import "./chunk-B6WVNDA5.js";
25
+ import "./chunk-PZUWP5VK.js";
26
+
27
+ // src/cli/digest.ts
28
+ import path from "path";
29
+ async function run(args, vaultDir) {
30
+ const config = loadConfig(vaultDir);
31
+ if (!config.digest.enabled) {
32
+ console.error("Digest is not enabled. Set digest.enabled: true in myco.yaml.");
33
+ process.exit(1);
34
+ }
35
+ const tierArg = parseIntFlag(args, "--tier");
36
+ const isFull = args.includes("--full");
37
+ const isReprocess = isFull || tierArg !== void 0;
38
+ const digestLlmConfig = {
39
+ provider: config.digest.intelligence.provider ?? config.intelligence.llm.provider,
40
+ model: config.digest.intelligence.model ?? config.intelligence.llm.model,
41
+ base_url: config.digest.intelligence.base_url ?? config.intelligence.llm.base_url,
42
+ context_window: config.digest.intelligence.context_window
43
+ };
44
+ const llmProvider = createLlmProvider(digestLlmConfig);
45
+ const index = new MycoIndex(path.join(vaultDir, "index.db"));
46
+ const engine = new DigestEngine({
47
+ vaultDir,
48
+ index,
49
+ llmProvider,
50
+ config,
51
+ log: (level, message, data) => {
52
+ const prefix = level === "warn" ? "\u26A0" : level === "info" ? "\u2192" : " ";
53
+ const suffix = data ? ` ${JSON.stringify(data)}` : "";
54
+ console.log(`${prefix} ${message}${suffix}`);
55
+ }
56
+ });
57
+ const opts = {};
58
+ if (isReprocess) {
59
+ opts.fullReprocess = true;
60
+ opts.cleanSlate = true;
61
+ }
62
+ if (tierArg !== void 0) {
63
+ const eligible = engine.getEligibleTiers();
64
+ if (!eligible.includes(tierArg)) {
65
+ console.error(`Tier ${tierArg} is not eligible. Eligible tiers: [${eligible.join(", ")}]`);
66
+ index.close();
67
+ process.exit(1);
68
+ }
69
+ opts.tiers = [tierArg];
70
+ }
71
+ if (isReprocess) {
72
+ const tierLabel = tierArg ? `tier ${tierArg}` : "all tiers";
73
+ console.log(`Full reprocess of ${tierLabel} \u2014 clean slate, all substrate`);
74
+ } else {
75
+ console.log("Running incremental digest cycle");
76
+ }
77
+ try {
78
+ const result = await engine.runCycle(opts);
79
+ if (!result) {
80
+ console.log("No substrate found \u2014 nothing to digest.");
81
+ return;
82
+ }
83
+ console.log(`
84
+ Digest cycle complete:`);
85
+ console.log(` Tiers generated: [${result.tiersGenerated.join(", ")}]`);
86
+ console.log(` Substrate: ${Object.values(result.substrate).flat().length} notes`);
87
+ console.log(` Duration: ${(result.durationMs / 1e3).toFixed(1)}s`);
88
+ console.log(` Model: ${result.model}`);
89
+ } finally {
90
+ index.close();
91
+ }
92
+ }
93
+ export {
94
+ run
95
+ };
96
+ //# sourceMappingURL=digest-7NKYXM6G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/digest.ts"],"sourcesContent":["/**\n * myco digest — run a digest cycle from the CLI.\n *\n * Usage:\n * myco digest Incremental cycle (only new substrate)\n * myco digest --full Full reprocess of all tiers from clean slate\n * myco digest --tier 3000 Reprocess a specific tier from clean slate\n *\n * When --tier or --full is used, the cycle processes ALL vault notes (not just\n * new ones) and ignores previous extracts, producing a clean synthesis.\n */\nimport { loadConfig } from '../config/loader.js';\nimport { MycoIndex } from '../index/sqlite.js';\nimport { createLlmProvider } from '../intelligence/llm.js';\nimport { DigestEngine } from '../daemon/digest.js';\nimport type { DigestCycleOptions } from '../daemon/digest.js';\nimport { parseIntFlag } from './shared.js';\nimport path from 'node:path';\n\nexport async function run(args: string[], vaultDir: string): Promise<void> {\n const config = loadConfig(vaultDir);\n\n if (!config.digest.enabled) {\n console.error('Digest is not enabled. Set digest.enabled: true in myco.yaml.');\n process.exit(1);\n }\n\n const tierArg = parseIntFlag(args, '--tier');\n const isFull = args.includes('--full');\n const isReprocess = isFull || tierArg !== undefined;\n\n // Resolve the digest LLM provider\n const digestLlmConfig = {\n provider: config.digest.intelligence.provider ?? config.intelligence.llm.provider,\n model: config.digest.intelligence.model ?? config.intelligence.llm.model,\n base_url: config.digest.intelligence.base_url ?? config.intelligence.llm.base_url,\n context_window: config.digest.intelligence.context_window,\n };\n const llmProvider = createLlmProvider(digestLlmConfig);\n\n const index = new MycoIndex(path.join(vaultDir, 'index.db'));\n\n const engine = new DigestEngine({\n vaultDir,\n index,\n llmProvider,\n config,\n log: (level, message, data) => {\n const prefix = level === 'warn' ? '⚠' : level === 'info' ? '→' : ' ';\n const suffix = data ? ` ${JSON.stringify(data)}` : '';\n console.log(`${prefix} ${message}${suffix}`);\n },\n });\n\n const opts: DigestCycleOptions = {};\n if (isReprocess) {\n opts.fullReprocess = true;\n opts.cleanSlate = true;\n }\n if (tierArg !== undefined) {\n const eligible = engine.getEligibleTiers();\n if (!eligible.includes(tierArg)) {\n console.error(`Tier ${tierArg} is not eligible. Eligible tiers: [${eligible.join(', ')}]`);\n index.close();\n process.exit(1);\n }\n opts.tiers = [tierArg];\n }\n\n if (isReprocess) {\n const tierLabel = tierArg ? `tier ${tierArg}` : 'all tiers';\n console.log(`Full reprocess of ${tierLabel} — clean slate, all substrate`);\n } else {\n console.log('Running incremental digest cycle');\n }\n\n try {\n const result = await engine.runCycle(opts);\n\n if (!result) {\n console.log('No substrate found — nothing to digest.');\n return;\n }\n\n console.log(`\\nDigest cycle complete:`);\n console.log(` Tiers generated: [${result.tiersGenerated.join(', ')}]`);\n console.log(` Substrate: ${Object.values(result.substrate).flat().length} notes`);\n console.log(` Duration: ${(result.durationMs / 1000).toFixed(1)}s`);\n console.log(` Model: ${result.model}`);\n } finally {\n index.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,OAAO,UAAU;AAEjB,eAAsB,IAAI,MAAgB,UAAiC;AACzE,QAAM,SAAS,WAAW,QAAQ;AAElC,MAAI,CAAC,OAAO,OAAO,SAAS;AAC1B,YAAQ,MAAM,+DAA+D;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,aAAa,MAAM,QAAQ;AAC3C,QAAM,SAAS,KAAK,SAAS,QAAQ;AACrC,QAAM,cAAc,UAAU,YAAY;AAG1C,QAAM,kBAAkB;AAAA,IACtB,UAAU,OAAO,OAAO,aAAa,YAAY,OAAO,aAAa,IAAI;AAAA,IACzE,OAAO,OAAO,OAAO,aAAa,SAAS,OAAO,aAAa,IAAI;AAAA,IACnE,UAAU,OAAO,OAAO,aAAa,YAAY,OAAO,aAAa,IAAI;AAAA,IACzE,gBAAgB,OAAO,OAAO,aAAa;AAAA,EAC7C;AACA,QAAM,cAAc,kBAAkB,eAAe;AAErD,QAAM,QAAQ,IAAI,UAAU,KAAK,KAAK,UAAU,UAAU,CAAC;AAE3D,QAAM,SAAS,IAAI,aAAa;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,CAAC,OAAO,SAAS,SAAS;AAC7B,YAAM,SAAS,UAAU,SAAS,WAAM,UAAU,SAAS,WAAM;AACjE,YAAM,SAAS,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK;AACnD,cAAQ,IAAI,GAAG,MAAM,IAAI,OAAO,GAAG,MAAM,EAAE;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,QAAM,OAA2B,CAAC;AAClC,MAAI,aAAa;AACf,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAAA,EACpB;AACA,MAAI,YAAY,QAAW;AACzB,UAAM,WAAW,OAAO,iBAAiB;AACzC,QAAI,CAAC,SAAS,SAAS,OAAO,GAAG;AAC/B,cAAQ,MAAM,QAAQ,OAAO,sCAAsC,SAAS,KAAK,IAAI,CAAC,GAAG;AACzF,YAAM,MAAM;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,SAAK,QAAQ,CAAC,OAAO;AAAA,EACvB;AAEA,MAAI,aAAa;AACf,UAAM,YAAY,UAAU,QAAQ,OAAO,KAAK;AAChD,YAAQ,IAAI,qBAAqB,SAAS,oCAA+B;AAAA,EAC3E,OAAO;AACL,YAAQ,IAAI,kCAAkC;AAAA,EAChD;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,SAAS,IAAI;AAEzC,QAAI,CAAC,QAAQ;AACX,cAAQ,IAAI,8CAAyC;AACrD;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,uBAA0B;AACtC,YAAQ,IAAI,uBAAuB,OAAO,eAAe,KAAK,IAAI,CAAC,GAAG;AACtE,YAAQ,IAAI,gBAAgB,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,EAAE,MAAM,QAAQ;AACjF,YAAQ,IAAI,gBAAgB,OAAO,aAAa,KAAM,QAAQ,CAAC,CAAC,GAAG;AACnE,YAAQ,IAAI,YAAY,OAAO,KAAK,EAAE;AAAA,EACxC,UAAE;AACA,UAAM,MAAM;AAAA,EACd;AACF;","names":[]}
@@ -15,11 +15,11 @@ import {
15
15
  DASHBOARD_CONTENT,
16
16
  VAULT_GITIGNORE,
17
17
  configureVaultEnv
18
- } from "./chunk-GFBG73P4.js";
18
+ } from "./chunk-FIRMTYFH.js";
19
19
  import {
20
20
  parseStringFlag
21
21
  } from "./chunk-SAKJMNSR.js";
22
- import "./chunk-67R6EMYD.js";
22
+ import "./chunk-JI6M2L2W.js";
23
23
  import {
24
24
  MycoConfigSchema,
25
25
  require_dist
@@ -27,8 +27,8 @@ import {
27
27
  import {
28
28
  resolveVaultDir
29
29
  } from "./chunk-N33KUCFP.js";
30
- import "./chunk-BNIYWCST.js";
31
- import "./chunk-JBD5KP5G.js";
30
+ import "./chunk-X6TKHO22.js";
31
+ import "./chunk-B6WVNDA5.js";
32
32
  import {
33
33
  __toESM
34
34
  } from "./chunk-PZUWP5VK.js";
@@ -108,4 +108,4 @@ async function run3(args) {
108
108
  export {
109
109
  run3 as run
110
110
  };
111
- //# sourceMappingURL=init-NUF5UBUJ.js.map
111
+ //# sourceMappingURL=init-HPQ77WWF.js.map