@goondocks/myco 0.2.13 → 0.3.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 (93) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/commands/init.md +33 -22
  4. package/dist/{chunk-BXFS4PCJ.js → chunk-2QEJKG7R.js} +2 -2
  5. package/dist/{chunk-MAFUTKOZ.js → chunk-2TKJPRZL.js} +2 -2
  6. package/dist/chunk-5EZ7QF6J.js +96 -0
  7. package/dist/chunk-5EZ7QF6J.js.map +1 -0
  8. package/dist/chunk-6FQISQNA.js +61 -0
  9. package/dist/chunk-6FQISQNA.js.map +1 -0
  10. package/dist/{chunk-S4WBXXO6.js → chunk-BMJX2IDQ.js} +2 -2
  11. package/dist/chunk-EF4JVH24.js +7299 -0
  12. package/dist/chunk-EF4JVH24.js.map +1 -0
  13. package/dist/{chunk-YXZEP5U6.js → chunk-ISCT2SI6.js} +11 -7301
  14. package/dist/chunk-ISCT2SI6.js.map +1 -0
  15. package/dist/{chunk-6C26YFOA.js → chunk-N6IAW33G.js} +248 -4306
  16. package/dist/chunk-N6IAW33G.js.map +1 -0
  17. package/dist/{chunk-C2YPBQQM.js → chunk-NTYYYC32.js} +3 -3
  18. package/dist/{chunk-NKJIZSPD.js → chunk-P2Q77C5F.js} +3 -3
  19. package/dist/chunk-PAUPHPOC.js +111 -0
  20. package/dist/chunk-PAUPHPOC.js.map +1 -0
  21. package/dist/chunk-PZUWP5VK.js +44 -0
  22. package/dist/{chunk-O5VSPHDL.js → chunk-Q7BEFSOV.js} +3 -40
  23. package/dist/{chunk-O5VSPHDL.js.map → chunk-Q7BEFSOV.js.map} +1 -1
  24. package/dist/chunk-QQWUV3TC.js +3691 -0
  25. package/dist/chunk-QQWUV3TC.js.map +1 -0
  26. package/dist/chunk-RGVBGTD6.js +21 -0
  27. package/dist/chunk-RGVBGTD6.js.map +1 -0
  28. package/dist/chunk-SAKJMNSR.js +50 -0
  29. package/dist/chunk-SAKJMNSR.js.map +1 -0
  30. package/dist/chunk-TJJRIVZ7.js +56 -0
  31. package/dist/chunk-TJJRIVZ7.js.map +1 -0
  32. package/dist/chunk-XQXXF6MU.js +96 -0
  33. package/dist/chunk-XQXXF6MU.js.map +1 -0
  34. package/dist/chunk-XW3OL55U.js +160 -0
  35. package/dist/chunk-XW3OL55U.js.map +1 -0
  36. package/dist/cli-ZHUR53CS.js +76 -0
  37. package/dist/cli-ZHUR53CS.js.map +1 -0
  38. package/dist/client-HORA3CC4.js +11 -0
  39. package/dist/client-HORA3CC4.js.map +1 -0
  40. package/dist/config-MD4XMLUS.js +101 -0
  41. package/dist/config-MD4XMLUS.js.map +1 -0
  42. package/dist/detect-providers-6RQCQZOI.js +35 -0
  43. package/dist/detect-providers-6RQCQZOI.js.map +1 -0
  44. package/dist/init-LLLHUNSY.js +120 -0
  45. package/dist/init-LLLHUNSY.js.map +1 -0
  46. package/dist/logs-BSTBZHDR.js +84 -0
  47. package/dist/logs-BSTBZHDR.js.map +1 -0
  48. package/dist/{main-ORWCEWNJ.js → main-JY6O6ZVH.js} +60 -15
  49. package/dist/{main-ORWCEWNJ.js.map → main-JY6O6ZVH.js.map} +1 -1
  50. package/dist/rebuild-YAN3TPFB.js +78 -0
  51. package/dist/rebuild-YAN3TPFB.js.map +1 -0
  52. package/dist/restart-NH5MX45I.js +50 -0
  53. package/dist/restart-NH5MX45I.js.map +1 -0
  54. package/dist/search-W3ECVSTH.js +120 -0
  55. package/dist/search-W3ECVSTH.js.map +1 -0
  56. package/dist/{server-J3AQ3YFA.js → server-DLBATUNG.js} +29 -16
  57. package/dist/{server-J3AQ3YFA.js.map → server-DLBATUNG.js.map} +1 -1
  58. package/dist/session-5GI2YU6R.js +44 -0
  59. package/dist/session-5GI2YU6R.js.map +1 -0
  60. package/dist/{session-start-BEC4JMNZ.js → session-start-DECLNJDI.js} +8 -6
  61. package/dist/{session-start-BEC4JMNZ.js.map → session-start-DECLNJDI.js.map} +1 -1
  62. package/dist/src/cli.js +8 -1
  63. package/dist/src/cli.js.map +1 -1
  64. package/dist/src/daemon/main.js +8 -1
  65. package/dist/src/daemon/main.js.map +1 -1
  66. package/dist/src/hooks/post-tool-use.js +5 -4
  67. package/dist/src/hooks/post-tool-use.js.map +1 -1
  68. package/dist/src/hooks/session-end.js +5 -4
  69. package/dist/src/hooks/session-end.js.map +1 -1
  70. package/dist/src/hooks/session-start.js +8 -1
  71. package/dist/src/hooks/session-start.js.map +1 -1
  72. package/dist/src/hooks/stop.js +7 -5
  73. package/dist/src/hooks/stop.js.map +1 -1
  74. package/dist/src/hooks/user-prompt-submit.js +5 -4
  75. package/dist/src/hooks/user-prompt-submit.js.map +1 -1
  76. package/dist/src/mcp/server.js +8 -1
  77. package/dist/src/mcp/server.js.map +1 -1
  78. package/dist/stats-7VEZN2WF.js +77 -0
  79. package/dist/stats-7VEZN2WF.js.map +1 -0
  80. package/dist/verify-HN5DWV2H.js +50 -0
  81. package/dist/verify-HN5DWV2H.js.map +1 -0
  82. package/package.json +1 -1
  83. package/dist/chunk-6C26YFOA.js.map +0 -1
  84. package/dist/chunk-YXZEP5U6.js.map +0 -1
  85. package/dist/cli-KMWJFK5Y.js +0 -623
  86. package/dist/cli-KMWJFK5Y.js.map +0 -1
  87. package/dist/client-TEUHXGOY.js +0 -10
  88. /package/dist/{chunk-BXFS4PCJ.js.map → chunk-2QEJKG7R.js.map} +0 -0
  89. /package/dist/{chunk-MAFUTKOZ.js.map → chunk-2TKJPRZL.js.map} +0 -0
  90. /package/dist/{chunk-S4WBXXO6.js.map → chunk-BMJX2IDQ.js.map} +0 -0
  91. /package/dist/{chunk-C2YPBQQM.js.map → chunk-NTYYYC32.js.map} +0 -0
  92. /package/dist/{chunk-NKJIZSPD.js.map → chunk-P2Q77C5F.js.map} +0 -0
  93. /package/dist/{client-TEUHXGOY.js.map → chunk-PZUWP5VK.js.map} +0 -0
@@ -1,623 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
3
- import {
4
- DEFAULT_LOG_TAIL,
5
- matchesFilter,
6
- queryLogs
7
- } from "./chunk-S4WBXXO6.js";
8
- import {
9
- LEVEL_ORDER,
10
- VectorIndex,
11
- createEmbeddingProvider,
12
- generateEmbedding,
13
- initFts,
14
- rebuildIndex,
15
- searchFts
16
- } from "./chunk-6C26YFOA.js";
17
- import {
18
- MycoIndex
19
- } from "./chunk-PA3VMINE.js";
20
- import {
21
- loadConfig,
22
- require_dist
23
- } from "./chunk-YXZEP5U6.js";
24
- import {
25
- resolveVaultDir
26
- } from "./chunk-N33KUCFP.js";
27
- import {
28
- AgentRegistry
29
- } from "./chunk-BXFS4PCJ.js";
30
- import {
31
- EMBEDDING_INPUT_LIMIT,
32
- __toESM
33
- } from "./chunk-O5VSPHDL.js";
34
-
35
- // src/cli.ts
36
- import fs from "fs";
37
- import path from "path";
38
- import os from "os";
39
-
40
- // src/logs/format.ts
41
- var LOG_VALUE_MAX_DISPLAY = 80;
42
- var CORE_FIELDS = ["timestamp", "level", "component", "message"];
43
- function formatLogLine(entry) {
44
- const time = formatLocalTime(entry.timestamp);
45
- const lvl = entry.level.toUpperCase().padEnd(5);
46
- const comp = `[${entry.component}]`.padEnd(14);
47
- const extras = [];
48
- for (const [key, value] of Object.entries(entry)) {
49
- if (CORE_FIELDS.includes(key)) continue;
50
- const str = String(value);
51
- const display = str.length > LOG_VALUE_MAX_DISPLAY ? str.slice(0, LOG_VALUE_MAX_DISPLAY) + "..." : str;
52
- extras.push(`${key}=${display}`);
53
- }
54
- const extraStr = extras.length > 0 ? " " + extras.join(" ") : "";
55
- return `${time} ${lvl} ${comp} ${entry.message}${extraStr}`;
56
- }
57
- function formatLocalTime(iso) {
58
- const d = new Date(iso);
59
- const hh = String(d.getHours()).padStart(2, "0");
60
- const mm = String(d.getMinutes()).padStart(2, "0");
61
- const ss = String(d.getSeconds()).padStart(2, "0");
62
- return `${hh}:${mm}:${ss}`;
63
- }
64
- function parseIntFlag(args, long, short) {
65
- for (let i = 0; i < args.length; i++) {
66
- if (args[i] === long || short && args[i] === short) {
67
- const val = parseInt(args[i + 1], 10);
68
- return isNaN(val) ? void 0 : val;
69
- }
70
- }
71
- return void 0;
72
- }
73
- function parseStringFlag(args, long, short) {
74
- for (let i = 0; i < args.length; i++) {
75
- if (args[i] === long || short && args[i] === short) {
76
- return args[i + 1];
77
- }
78
- }
79
- return void 0;
80
- }
81
-
82
- // src/cli.ts
83
- var import_yaml = __toESM(require_dist(), 1);
84
- function loadEnv() {
85
- const envPath = path.resolve(process.cwd(), ".env");
86
- if (!fs.existsSync(envPath)) return;
87
- for (const line of fs.readFileSync(envPath, "utf-8").split("\n")) {
88
- const match = line.match(/^\s*([^#=]+?)\s*=\s*(.*?)\s*$/);
89
- if (match && !process.env[match[1]]) {
90
- process.env[match[1]] = match[2];
91
- }
92
- }
93
- }
94
- loadEnv();
95
- var USAGE = `Usage: myco <command> [args]
96
-
97
- Commands:
98
- init [options] Initialize a new vault
99
- stats Vault health, index counts, vector count
100
- search <query> Combined FTS + vector search with scores
101
- vectors <query> Raw vector search with similarity scores
102
- session [id|latest] Show a session note
103
- logs [options] View daemon logs (--tail N, --follow, --level, --component)
104
- restart Restart the daemon with current code
105
- rebuild Reindex the entire vault
106
-
107
- Init options:
108
- --vault <path> Vault directory (default: .myco/ in project root)
109
- --llm-provider <name> LLM provider: ollama, lm-studio, anthropic
110
- --llm-model <name> LLM model name (e.g., gpt-oss)
111
- --llm-url <url> LLM base URL (default per provider)
112
- --embedding-provider <name> Embedding provider: ollama, lm-studio
113
- --embedding-model <name> Embedding model name (e.g., bge-m3)
114
- --embedding-url <url> Embedding base URL (default per provider)
115
- --user <name> Team username
116
- --team Enable team mode
117
- `;
118
- async function main() {
119
- const [cmd, ...args] = process.argv.slice(2);
120
- if (!cmd || cmd === "--help" || cmd === "-h") {
121
- process.stdout.write(USAGE);
122
- return;
123
- }
124
- if (cmd === "init") return initVault(args);
125
- const vaultDir = resolveVaultDir();
126
- if (!fs.existsSync(path.join(vaultDir, "myco.yaml"))) {
127
- console.error(`No myco.yaml found in ${vaultDir}. Run 'myco init' first.`);
128
- process.exit(1);
129
- }
130
- switch (cmd) {
131
- case "stats":
132
- return stats(vaultDir);
133
- case "search":
134
- return search(vaultDir, args.join(" "));
135
- case "vectors":
136
- return vectors(vaultDir, args.join(" "));
137
- case "session":
138
- return session(vaultDir, args[0]);
139
- case "restart":
140
- return restart(vaultDir);
141
- case "rebuild":
142
- return rebuild(vaultDir);
143
- case "logs":
144
- return logs(vaultDir, args);
145
- default:
146
- console.error(`Unknown command: ${cmd}`);
147
- process.stdout.write(USAGE);
148
- process.exit(1);
149
- }
150
- }
151
- function stats(vaultDir) {
152
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
153
- const sessions = index.query({ type: "session" });
154
- const memories = index.query({ type: "memory" });
155
- const plans = index.query({ type: "plan" });
156
- console.log("=== Myco Vault ===");
157
- console.log(`Path: ${vaultDir}`);
158
- console.log();
159
- console.log("--- Index ---");
160
- console.log(`Sessions: ${sessions.length}`);
161
- console.log(`Memories: ${memories.length}`);
162
- console.log(`Plans: ${plans.length}`);
163
- const types = {};
164
- for (const m of memories) {
165
- const t = m.frontmatter?.observation_type || "unknown";
166
- types[t] = (types[t] || 0) + 1;
167
- }
168
- if (Object.keys(types).length > 0) {
169
- console.log("\n--- Memories by Type ---");
170
- for (const [t, c] of Object.entries(types).sort((a, b) => b[1] - a[1])) {
171
- console.log(` ${t}: ${c}`);
172
- }
173
- }
174
- const vecDb = path.join(vaultDir, "vectors.db");
175
- if (fs.existsSync(vecDb)) {
176
- try {
177
- const vec = new VectorIndex(vecDb, 1024);
178
- console.log(`
179
- --- Vectors ---`);
180
- console.log(`Embeddings: ${vec.count()}`);
181
- vec.close();
182
- } catch (e) {
183
- console.log(`
184
- Vectors: error \u2014 ${e.message}`);
185
- }
186
- } else {
187
- console.log("\nVectors: not initialized");
188
- }
189
- const daemonPath = path.join(vaultDir, "daemon.json");
190
- if (fs.existsSync(daemonPath)) {
191
- try {
192
- const daemon = JSON.parse(fs.readFileSync(daemonPath, "utf-8"));
193
- const alive = isProcessAlive(daemon.pid);
194
- console.log(`
195
- --- Daemon ---`);
196
- console.log(`PID: ${daemon.pid} (${alive ? "running" : "dead"})`);
197
- console.log(`Port: ${daemon.port}`);
198
- console.log(`Started: ${daemon.started}`);
199
- console.log(`Sessions: ${(daemon.sessions || []).length}`);
200
- } catch {
201
- }
202
- }
203
- index.close();
204
- }
205
- async function search(vaultDir, query) {
206
- if (!query) {
207
- console.error("Usage: myco search <query>");
208
- process.exit(1);
209
- }
210
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
211
- const vecDb = path.join(vaultDir, "vectors.db");
212
- if (fs.existsSync(vecDb)) {
213
- try {
214
- const config = loadConfig(vaultDir);
215
- const embeddingProvider = createEmbeddingProvider(config.intelligence.embedding);
216
- const emb = await generateEmbedding(embeddingProvider, query);
217
- const vec = new VectorIndex(vecDb, emb.dimensions);
218
- console.log(`=== Semantic Search: "${query}" ===`);
219
- const results = vec.search(emb.embedding, { limit: 10 });
220
- if (results.length === 0) {
221
- console.log(" (no results)");
222
- } else {
223
- const noteMap = new Map(
224
- index.queryByIds(results.map((r) => r.id)).map((n) => [n.id, n])
225
- );
226
- for (const r of results) {
227
- const title = noteMap.get(r.id)?.title || r.id;
228
- console.log(` sim: ${r.similarity.toFixed(3)} | [${r.metadata.type}] ${title.slice(0, 60)}`);
229
- }
230
- }
231
- vec.close();
232
- } catch (e) {
233
- console.log(`Semantic search unavailable: ${e.message}`);
234
- }
235
- }
236
- console.log(`
237
- === FTS Search: "${query}" ===`);
238
- const ftsResults = searchFts(index, query, { limit: 10 });
239
- if (ftsResults.length === 0) {
240
- console.log(" (no results)");
241
- } else {
242
- for (const r of ftsResults) {
243
- console.log(` [${r.type}] ${r.title?.slice(0, 70)}`);
244
- if (r.snippet) console.log(` ${r.snippet.slice(0, 100)}`);
245
- }
246
- }
247
- index.close();
248
- }
249
- async function vectors(vaultDir, query) {
250
- if (!query) {
251
- console.error("Usage: myco vectors <query>");
252
- process.exit(1);
253
- }
254
- const config = loadConfig(vaultDir);
255
- const embeddingProvider = createEmbeddingProvider(config.intelligence.embedding);
256
- const emb = await generateEmbedding(embeddingProvider, query);
257
- const vecDb = path.join(vaultDir, "vectors.db");
258
- if (!fs.existsSync(vecDb)) {
259
- console.error("No vector index found");
260
- process.exit(1);
261
- }
262
- const vec = new VectorIndex(vecDb, emb.dimensions);
263
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
264
- const results = vec.search(emb.embedding, { limit: 20, relativeThreshold: 0 });
265
- console.log(`Query: "${query}"`);
266
- console.log(`Dimensions: ${emb.dimensions}`);
267
- console.log(`Total vectors: ${vec.count()}`);
268
- console.log();
269
- if (results.length === 0) {
270
- console.log("(no results)");
271
- } else {
272
- const noteMap = new Map(
273
- index.queryByIds(results.map((r) => r.id)).map((n) => [n.id, n])
274
- );
275
- const topScore = results[0].similarity;
276
- console.log(`Top score: ${topScore.toFixed(4)}`);
277
- console.log(`Default threshold (0.5x): ${(topScore * 0.5).toFixed(4)}`);
278
- console.log();
279
- console.log(" Sim Ratio Type ID / Title");
280
- console.log(" ------ ----- --------- " + "-".repeat(50));
281
- for (const r of results) {
282
- const title = noteMap.get(r.id)?.title || r.id;
283
- const ratio = (r.similarity / topScore).toFixed(2);
284
- const pass = r.similarity >= topScore * 0.5 ? "\u2713" : " ";
285
- console.log(`${pass} ${r.similarity.toFixed(4)} ${ratio} ${r.metadata.type.padEnd(9)} ${title.slice(0, 50)}`);
286
- }
287
- }
288
- vec.close();
289
- index.close();
290
- }
291
- function session(vaultDir, idOrLatest) {
292
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
293
- const sessions = index.query({ type: "session" });
294
- if (sessions.length === 0) {
295
- console.log("No sessions found");
296
- index.close();
297
- return;
298
- }
299
- let target;
300
- if (!idOrLatest || idOrLatest === "latest") {
301
- target = sessions[sessions.length - 1];
302
- } else {
303
- target = sessions.find((s) => s.id.includes(idOrLatest));
304
- }
305
- if (!target) {
306
- console.error(`Session not found: ${idOrLatest}`);
307
- console.log("Available:", sessions.map((s) => s.id).join(", "));
308
- index.close();
309
- return;
310
- }
311
- const fullPath = path.join(vaultDir, target.path);
312
- if (fs.existsSync(fullPath)) {
313
- console.log(fs.readFileSync(fullPath, "utf-8"));
314
- } else {
315
- console.log(`Title: ${target.title}`);
316
- console.log(`Content:
317
- ${target.content?.slice(0, 2e3)}`);
318
- }
319
- index.close();
320
- }
321
- async function restart(vaultDir) {
322
- const daemonPath = path.join(vaultDir, "daemon.json");
323
- if (fs.existsSync(daemonPath)) {
324
- try {
325
- const daemon = JSON.parse(fs.readFileSync(daemonPath, "utf-8"));
326
- if (isProcessAlive(daemon.pid)) {
327
- process.kill(daemon.pid, "SIGTERM");
328
- console.log(`Stopped daemon (pid ${daemon.pid})`);
329
- } else {
330
- console.log(`Daemon pid ${daemon.pid} was already dead`);
331
- }
332
- } catch {
333
- }
334
- try {
335
- fs.unlinkSync(daemonPath);
336
- } catch {
337
- }
338
- }
339
- const { DaemonClient } = await import("./client-TEUHXGOY.js");
340
- const client = new DaemonClient(vaultDir);
341
- console.log("Waiting for health check...");
342
- const healthy = await client.ensureRunning();
343
- if (healthy) {
344
- try {
345
- const info = JSON.parse(fs.readFileSync(daemonPath, "utf-8"));
346
- console.log(`Daemon healthy on port ${info.port}`);
347
- } catch {
348
- console.log("Daemon healthy");
349
- }
350
- } else {
351
- console.error("Daemon failed to become healthy");
352
- }
353
- }
354
- async function rebuild(vaultDir) {
355
- console.log(`Rebuilding index for ${vaultDir}...`);
356
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
357
- initFts(index);
358
- const count = rebuildIndex(index, vaultDir);
359
- console.log(`Indexed ${count} notes (FTS)`);
360
- const vecDb = path.join(vaultDir, "vectors.db");
361
- try {
362
- const config = loadConfig(vaultDir);
363
- const embeddingProvider = createEmbeddingProvider(config.intelligence.embedding);
364
- const testEmbed = await embeddingProvider.embed("test");
365
- const vec = new VectorIndex(vecDb, testEmbed.dimensions);
366
- const allNotes = index.query({});
367
- const activeNotes = allNotes.filter((n) => {
368
- const status = n.frontmatter?.status;
369
- return status !== "superseded" && status !== "archived";
370
- });
371
- let embedded = 0;
372
- for (const note of activeNotes) {
373
- const text = `${note.title}
374
- ${note.content}`.slice(0, EMBEDDING_INPUT_LIMIT);
375
- try {
376
- const emb = await generateEmbedding(embeddingProvider, text);
377
- vec.upsert(note.id, emb.embedding, {
378
- type: note.type,
379
- session_id: note.frontmatter?.session ?? ""
380
- });
381
- embedded++;
382
- process.stdout.write(`\rEmbedded ${embedded}/${activeNotes.length}`);
383
- } catch (e) {
384
- console.error(`
385
- Failed to embed ${note.id}: ${e.message}`);
386
- }
387
- }
388
- console.log(`
389
- Embedded ${embedded} notes (vectors)
390
- Skipped ${allNotes.length - activeNotes.length} superseded/archived`);
391
- vec.close();
392
- } catch (e) {
393
- console.log(`Vector rebuild skipped: ${e.message}`);
394
- }
395
- index.close();
396
- }
397
- var FOLLOW_POLL_INTERVAL_MS = 500;
398
- function logs(vaultDir, args) {
399
- const logDir = path.join(vaultDir, "logs");
400
- const follow = args.includes("--follow") || args.includes("-f");
401
- const limit = parseIntFlag(args, "--tail", "-n") ?? DEFAULT_LOG_TAIL;
402
- const rawLevel = parseStringFlag(args, "--level", "-l");
403
- if (rawLevel && !(rawLevel in LEVEL_ORDER)) {
404
- console.error(`Invalid level: ${rawLevel}. Valid levels: ${Object.keys(LEVEL_ORDER).join(", ")}`);
405
- process.exit(1);
406
- }
407
- const level = rawLevel;
408
- const component = parseStringFlag(args, "--component", "-c");
409
- const since = parseStringFlag(args, "--since");
410
- const until = parseStringFlag(args, "--until");
411
- const result = queryLogs(logDir, { limit, level, component, since, until });
412
- for (const e of result.entries) {
413
- process.stdout.write(formatLogLine(e) + "\n");
414
- }
415
- if (result.truncated) {
416
- process.stdout.write(` ... ${result.total - result.entries.length} earlier entries omitted
417
- `);
418
- }
419
- if (!follow) return;
420
- const followFilter = { level, component, until };
421
- const logPath = path.join(logDir, "daemon.log");
422
- let offset = 0;
423
- try {
424
- offset = fs.statSync(logPath).size;
425
- } catch {
426
- }
427
- fs.watchFile(logPath, { interval: FOLLOW_POLL_INTERVAL_MS }, (curr, prev) => {
428
- if (curr.size < prev.size || curr.ino !== prev.ino) {
429
- offset = 0;
430
- }
431
- if (curr.size <= offset) return;
432
- try {
433
- const fd = fs.openSync(logPath, "r");
434
- const buf = Buffer.alloc(curr.size - offset);
435
- fs.readSync(fd, buf, 0, buf.length, offset);
436
- fs.closeSync(fd);
437
- const text = buf.toString("utf-8");
438
- const lastNewline = text.lastIndexOf("\n");
439
- if (lastNewline < 0) return;
440
- offset += Buffer.byteLength(text.slice(0, lastNewline + 1));
441
- for (const line of text.slice(0, lastNewline).split("\n")) {
442
- if (!line.trim()) continue;
443
- try {
444
- const e = JSON.parse(line);
445
- if (!matchesFilter(e, followFilter)) continue;
446
- process.stdout.write(formatLogLine(e) + "\n");
447
- } catch {
448
- }
449
- }
450
- } catch {
451
- }
452
- });
453
- process.on("SIGINT", () => {
454
- fs.unwatchFile(logPath);
455
- process.exit(0);
456
- });
457
- }
458
- function isProcessAlive(pid) {
459
- try {
460
- process.kill(pid, 0);
461
- return true;
462
- } catch {
463
- return false;
464
- }
465
- }
466
- var PROVIDER_DEFAULTS = {
467
- ollama: { base_url: "http://localhost:11434" },
468
- "lm-studio": { base_url: "http://localhost:1234" }
469
- };
470
- var DASHBOARD_CONTENT = `# Myco Vault
471
-
472
- ## Active Plans
473
- \`\`\`dataview
474
- TABLE status, tags FROM #type/plan
475
- WHERE status = "active" OR status = "in_progress"
476
- SORT created DESC
477
- \`\`\`
478
-
479
- ## Recent Sessions
480
- \`\`\`dataview
481
- TABLE user, started, tools_used FROM #type/session
482
- SORT started DESC LIMIT 10
483
- \`\`\`
484
-
485
- ## Recent Memories
486
- \`\`\`dataview
487
- TABLE observation_type AS "Type", created FROM #type/memory
488
- SORT created DESC LIMIT 15
489
- \`\`\`
490
-
491
- ## Memories by Type
492
- \`\`\`dataview
493
- TABLE WITHOUT ID observation_type AS "Type", length(rows) AS "Count"
494
- FROM #type/memory GROUP BY observation_type
495
- SORT length(rows) DESC
496
- \`\`\`
497
-
498
- ## Gotchas
499
- \`\`\`dataview
500
- LIST FROM #memory/gotcha SORT created DESC LIMIT 10
501
- \`\`\`
502
- `;
503
- var VAULT_GITIGNORE = `# Runtime \u2014 rebuilt on daemon startup
504
- index.db
505
- index.db-wal
506
- index.db-shm
507
- vectors.db
508
-
509
- # Daemon state \u2014 per-machine, ephemeral
510
- daemon.json
511
- buffer/
512
- logs/
513
-
514
- # Obsidian \u2014 per-user workspace config
515
- .obsidian/
516
- `;
517
- function configureVaultEnv(projectRoot, vaultDir) {
518
- const registry = new AgentRegistry();
519
- const active = registry.detectActiveAgent();
520
- if (active) {
521
- if (active.configureVaultEnv(projectRoot, vaultDir)) {
522
- console.log(`Set MYCO_VAULT_DIR for ${active.displayName}`);
523
- }
524
- } else {
525
- for (const name of registry.adapterNames) {
526
- const adapter = registry.getAdapter(name);
527
- if (adapter?.configureVaultEnv(projectRoot, vaultDir)) {
528
- console.log(`Set MYCO_VAULT_DIR for ${adapter.displayName}`);
529
- }
530
- }
531
- }
532
- console.log(`
533
- For other agents, add to your shell profile:`);
534
- console.log(` export MYCO_VAULT_DIR="${vaultDir}"
535
- `);
536
- }
537
- async function initVault(args) {
538
- const vaultPath = parseStringFlag(args, "--vault");
539
- const llmProvider = parseStringFlag(args, "--llm-provider") ?? "ollama";
540
- const llmModel = parseStringFlag(args, "--llm-model") ?? "gpt-oss";
541
- const llmUrl = parseStringFlag(args, "--llm-url") ?? PROVIDER_DEFAULTS[llmProvider]?.base_url;
542
- const embeddingProvider = parseStringFlag(args, "--embedding-provider") ?? "ollama";
543
- const embeddingModel = parseStringFlag(args, "--embedding-model") ?? "bge-m3";
544
- const embeddingUrl = parseStringFlag(args, "--embedding-url") ?? PROVIDER_DEFAULTS[embeddingProvider]?.base_url;
545
- const user = parseStringFlag(args, "--user") ?? "";
546
- const teamEnabled = args.includes("--team");
547
- const vaultDir = vaultPath ? vaultPath.startsWith("~/") ? path.join(os.homedir(), vaultPath.slice(2)) : path.resolve(vaultPath) : path.join(resolveVaultDir());
548
- if (fs.existsSync(path.join(vaultDir, "myco.yaml"))) {
549
- console.log(`Vault already initialized at ${vaultDir}`);
550
- return;
551
- }
552
- console.log(`Initializing Myco vault at ${vaultDir}`);
553
- const dirs = ["sessions", "plans", "memories", "artifacts", "team", "buffer", "logs"];
554
- for (const dir of dirs) {
555
- fs.mkdirSync(path.join(vaultDir, dir), { recursive: true });
556
- }
557
- const config = {
558
- version: 2,
559
- intelligence: {
560
- llm: {
561
- provider: llmProvider,
562
- model: llmModel,
563
- ...llmUrl ? { base_url: llmUrl } : {},
564
- context_window: 8192,
565
- max_tokens: 1024
566
- },
567
- embedding: {
568
- provider: embeddingProvider,
569
- model: embeddingModel,
570
- ...embeddingUrl ? { base_url: embeddingUrl } : {}
571
- }
572
- },
573
- daemon: {
574
- log_level: "info",
575
- grace_period: 30,
576
- max_log_size: 5242880
577
- },
578
- capture: {
579
- transcript_paths: [],
580
- artifact_watch: [".claude/plans/", ".cursor/plans/"],
581
- artifact_extensions: [".md"],
582
- buffer_max_events: 500
583
- },
584
- context: {
585
- max_tokens: 1200,
586
- layers: { plans: 200, sessions: 500, memories: 300, team: 200 }
587
- },
588
- team: {
589
- enabled: teamEnabled,
590
- user,
591
- sync: "git"
592
- }
593
- };
594
- fs.writeFileSync(
595
- path.join(vaultDir, "myco.yaml"),
596
- import_yaml.default.stringify(config),
597
- "utf-8"
598
- );
599
- fs.writeFileSync(path.join(vaultDir, ".gitignore"), VAULT_GITIGNORE, "utf-8");
600
- fs.writeFileSync(path.join(vaultDir, "_dashboard.md"), DASHBOARD_CONTENT, "utf-8");
601
- const index = new MycoIndex(path.join(vaultDir, "index.db"));
602
- initFts(index);
603
- index.close();
604
- console.log("");
605
- console.log("=== Myco Vault Initialized ===");
606
- console.log(`Path: ${vaultDir}`);
607
- console.log(`LLM provider: ${llmProvider} / ${llmModel}`);
608
- console.log(`Embedding provider: ${embeddingProvider} / ${embeddingModel}`);
609
- console.log(`Team mode: ${teamEnabled ? "enabled" : "disabled"}`);
610
- if (user) console.log(`User: ${user}`);
611
- console.log("");
612
- const projectRoot = path.resolve(".");
613
- const isProjectLocal = vaultDir.startsWith(projectRoot);
614
- if (!isProjectLocal) {
615
- configureVaultEnv(projectRoot, vaultDir);
616
- }
617
- console.log("Next: start a coding session \u2014 Myco will begin capturing automatically.");
618
- }
619
- main().catch((err) => {
620
- console.error(`myco: ${err.message}`);
621
- process.exit(1);
622
- });
623
- //# sourceMappingURL=cli-KMWJFK5Y.js.map