@goondocks/myco 0.2.14 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/commands/init.md +33 -22
- package/dist/{chunk-BXFS4PCJ.js → chunk-2QEJKG7R.js} +2 -2
- package/dist/{chunk-MAFUTKOZ.js → chunk-2TKJPRZL.js} +2 -2
- package/dist/chunk-3JCXYLHD.js +33 -0
- package/dist/chunk-3JCXYLHD.js.map +1 -0
- package/dist/chunk-5EZ7QF6J.js +96 -0
- package/dist/chunk-5EZ7QF6J.js.map +1 -0
- package/dist/chunk-6FQISQNA.js +61 -0
- package/dist/chunk-6FQISQNA.js.map +1 -0
- package/dist/chunk-72OAG4SF.js +3692 -0
- package/dist/chunk-72OAG4SF.js.map +1 -0
- package/dist/{chunk-S4WBXXO6.js → chunk-BMJX2IDQ.js} +2 -2
- package/dist/chunk-EF4JVH24.js +7299 -0
- package/dist/chunk-EF4JVH24.js.map +1 -0
- package/dist/{chunk-YXZEP5U6.js → chunk-ISCT2SI6.js} +11 -7301
- package/dist/chunk-ISCT2SI6.js.map +1 -0
- package/dist/chunk-JIQISBPI.js +362 -0
- package/dist/chunk-JIQISBPI.js.map +1 -0
- package/dist/{chunk-6C26YFOA.js → chunk-N6IAW33G.js} +248 -4306
- package/dist/chunk-N6IAW33G.js.map +1 -0
- package/dist/{chunk-C2YPBQQM.js → chunk-NTYYYC32.js} +3 -3
- package/dist/{chunk-NKJIZSPD.js → chunk-P2Q77C5F.js} +3 -3
- package/dist/chunk-PAUPHPOC.js +111 -0
- package/dist/chunk-PAUPHPOC.js.map +1 -0
- package/dist/chunk-PZUWP5VK.js +44 -0
- package/dist/{chunk-O5VSPHDL.js → chunk-Q7BEFSOV.js} +3 -40
- package/dist/{chunk-O5VSPHDL.js.map → chunk-Q7BEFSOV.js.map} +1 -1
- package/dist/chunk-RGVBGTD6.js +21 -0
- package/dist/chunk-RGVBGTD6.js.map +1 -0
- package/dist/chunk-SAKJMNSR.js +50 -0
- package/dist/chunk-SAKJMNSR.js.map +1 -0
- package/dist/{chunk-UUFDD2FB.js → chunk-TJJRIVZ7.js} +2 -2
- package/dist/chunk-XQXXF6MU.js +96 -0
- package/dist/chunk-XQXXF6MU.js.map +1 -0
- package/dist/chunk-XW3OL55U.js +160 -0
- package/dist/chunk-XW3OL55U.js.map +1 -0
- package/dist/cli-ERAS5H43.js +79 -0
- package/dist/cli-ERAS5H43.js.map +1 -0
- package/dist/client-HORA3CC4.js +11 -0
- package/dist/client-HORA3CC4.js.map +1 -0
- package/dist/config-MD4XMLUS.js +101 -0
- package/dist/config-MD4XMLUS.js.map +1 -0
- package/dist/detect-providers-6RQCQZOI.js +35 -0
- package/dist/detect-providers-6RQCQZOI.js.map +1 -0
- package/dist/init-LLLHUNSY.js +120 -0
- package/dist/init-LLLHUNSY.js.map +1 -0
- package/dist/logs-BSTBZHDR.js +84 -0
- package/dist/logs-BSTBZHDR.js.map +1 -0
- package/dist/{main-UJAXPP6S.js → main-D4X6XWRT.js} +241 -542
- package/dist/main-D4X6XWRT.js.map +1 -0
- package/dist/rebuild-3367GP5R.js +85 -0
- package/dist/rebuild-3367GP5R.js.map +1 -0
- package/dist/reprocess-EM5RIRH4.js +199 -0
- package/dist/reprocess-EM5RIRH4.js.map +1 -0
- package/dist/restart-NH5MX45I.js +50 -0
- package/dist/restart-NH5MX45I.js.map +1 -0
- package/dist/search-W3ECVSTH.js +120 -0
- package/dist/search-W3ECVSTH.js.map +1 -0
- package/dist/{server-J3AQ3YFA.js → server-I7MRMIOP.js} +41 -21
- package/dist/{server-J3AQ3YFA.js.map → server-I7MRMIOP.js.map} +1 -1
- package/dist/session-5GI2YU6R.js +44 -0
- package/dist/session-5GI2YU6R.js.map +1 -0
- package/dist/{session-start-BEC4JMNZ.js → session-start-DECLNJDI.js} +8 -6
- package/dist/{session-start-BEC4JMNZ.js.map → session-start-DECLNJDI.js.map} +1 -1
- package/dist/src/cli.js +5 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/daemon/main.js +5 -4
- package/dist/src/daemon/main.js.map +1 -1
- package/dist/src/hooks/post-tool-use.js +5 -4
- package/dist/src/hooks/post-tool-use.js.map +1 -1
- package/dist/src/hooks/session-end.js +5 -4
- package/dist/src/hooks/session-end.js.map +1 -1
- package/dist/src/hooks/session-start.js +5 -4
- package/dist/src/hooks/session-start.js.map +1 -1
- package/dist/src/hooks/stop.js +7 -5
- package/dist/src/hooks/stop.js.map +1 -1
- package/dist/src/hooks/user-prompt-submit.js +5 -4
- package/dist/src/hooks/user-prompt-submit.js.map +1 -1
- package/dist/src/mcp/server.js +5 -4
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/stats-7VEZN2WF.js +77 -0
- package/dist/stats-7VEZN2WF.js.map +1 -0
- package/dist/verify-HN5DWV2H.js +50 -0
- package/dist/verify-HN5DWV2H.js.map +1 -0
- package/package.json +1 -1
- package/skills/myco/SKILL.md +33 -0
- package/dist/chunk-6C26YFOA.js.map +0 -1
- package/dist/chunk-YXZEP5U6.js.map +0 -1
- package/dist/cli-KMWJFK5Y.js +0 -623
- package/dist/cli-KMWJFK5Y.js.map +0 -1
- package/dist/client-TEUHXGOY.js +0 -10
- package/dist/main-UJAXPP6S.js.map +0 -1
- /package/dist/{chunk-BXFS4PCJ.js.map → chunk-2QEJKG7R.js.map} +0 -0
- /package/dist/{chunk-MAFUTKOZ.js.map → chunk-2TKJPRZL.js.map} +0 -0
- /package/dist/{chunk-S4WBXXO6.js.map → chunk-BMJX2IDQ.js.map} +0 -0
- /package/dist/{chunk-C2YPBQQM.js.map → chunk-NTYYYC32.js.map} +0 -0
- /package/dist/{chunk-NKJIZSPD.js.map → chunk-P2Q77C5F.js.map} +0 -0
- /package/dist/{client-TEUHXGOY.js.map → chunk-PZUWP5VK.js.map} +0 -0
- /package/dist/{chunk-UUFDD2FB.js.map → chunk-TJJRIVZ7.js.map} +0 -0
|
@@ -1,65 +1,77 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
BufferProcessor,
|
|
4
|
+
TranscriptMiner,
|
|
5
|
+
buildSimilarityPrompt,
|
|
6
|
+
extractNumber,
|
|
7
|
+
extractTurnsFromBuffer,
|
|
8
|
+
writeObservationNotes
|
|
9
|
+
} from "./chunk-JIQISBPI.js";
|
|
2
10
|
import {
|
|
3
11
|
VaultWriter,
|
|
4
12
|
bareSessionId,
|
|
5
|
-
formatMemoryBody,
|
|
6
13
|
formatSessionBody,
|
|
7
14
|
sessionNoteId,
|
|
8
15
|
sessionRelativePath,
|
|
9
16
|
sessionWikilink
|
|
10
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-P2Q77C5F.js";
|
|
11
18
|
import {
|
|
12
|
-
ARTIFACT_TYPES,
|
|
13
|
-
DaemonLogger,
|
|
14
|
-
VectorIndex,
|
|
15
|
-
createEmbeddingProvider,
|
|
16
|
-
createLlmProvider,
|
|
17
|
-
generateEmbedding,
|
|
18
19
|
indexNote,
|
|
19
|
-
initFts,
|
|
20
20
|
rebuildIndex
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-72OAG4SF.js";
|
|
22
|
+
import {
|
|
23
|
+
generateEmbedding
|
|
24
|
+
} from "./chunk-RGVBGTD6.js";
|
|
25
|
+
import {
|
|
26
|
+
DaemonLogger
|
|
27
|
+
} from "./chunk-5EZ7QF6J.js";
|
|
28
|
+
import {
|
|
29
|
+
initFts
|
|
30
|
+
} from "./chunk-6FQISQNA.js";
|
|
31
|
+
import {
|
|
32
|
+
createEmbeddingProvider,
|
|
33
|
+
createLlmProvider
|
|
34
|
+
} from "./chunk-N6IAW33G.js";
|
|
35
|
+
import {
|
|
36
|
+
VectorIndex
|
|
37
|
+
} from "./chunk-XQXXF6MU.js";
|
|
22
38
|
import {
|
|
23
39
|
MycoIndex
|
|
24
40
|
} from "./chunk-PA3VMINE.js";
|
|
41
|
+
import "./chunk-XW3OL55U.js";
|
|
25
42
|
import {
|
|
26
43
|
external_exports,
|
|
27
|
-
loadConfig
|
|
44
|
+
loadConfig
|
|
45
|
+
} from "./chunk-ISCT2SI6.js";
|
|
46
|
+
import {
|
|
28
47
|
require_dist
|
|
29
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-EF4JVH24.js";
|
|
30
49
|
import {
|
|
31
50
|
EventBuffer
|
|
32
51
|
} from "./chunk-I7PMGO6S.js";
|
|
33
52
|
import {
|
|
34
|
-
AgentRegistry,
|
|
35
53
|
claudeCodeAdapter,
|
|
36
54
|
createPerProjectAdapter,
|
|
37
55
|
extensionForMimeType
|
|
38
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-2QEJKG7R.js";
|
|
39
57
|
import {
|
|
40
|
-
AI_RESPONSE_PREVIEW_CHARS,
|
|
41
58
|
CANDIDATE_CONTENT_PREVIEW,
|
|
42
|
-
CHARS_PER_TOKEN,
|
|
43
|
-
CLASSIFICATION_MAX_TOKENS,
|
|
44
|
-
COMMAND_PREVIEW_CHARS,
|
|
45
59
|
CONTENT_SNIPPET_CHARS,
|
|
46
60
|
CONTEXT_SESSION_PREVIEW_CHARS,
|
|
47
61
|
EMBEDDING_INPUT_LIMIT,
|
|
48
|
-
EXTRACTION_MAX_TOKENS,
|
|
49
62
|
FILE_WATCH_STABILITY_MS,
|
|
50
63
|
LINEAGE_RECENT_SESSIONS_LIMIT,
|
|
51
64
|
MAX_SLUG_LENGTH,
|
|
52
65
|
PROMPT_CONTEXT_MAX_MEMORIES,
|
|
53
66
|
PROMPT_CONTEXT_MIN_LENGTH,
|
|
54
67
|
PROMPT_CONTEXT_MIN_SIMILARITY,
|
|
55
|
-
PROMPT_PREVIEW_CHARS,
|
|
56
68
|
RELATED_MEMORIES_LIMIT,
|
|
57
69
|
SESSION_CONTEXT_MAX_PLANS,
|
|
58
|
-
STALE_BUFFER_MAX_AGE_MS
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
STALE_BUFFER_MAX_AGE_MS
|
|
71
|
+
} from "./chunk-Q7BEFSOV.js";
|
|
72
|
+
import {
|
|
61
73
|
__toESM
|
|
62
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-PZUWP5VK.js";
|
|
63
75
|
|
|
64
76
|
// src/daemon/server.ts
|
|
65
77
|
import http from "http";
|
|
@@ -265,244 +277,9 @@ var BatchManager = class {
|
|
|
265
277
|
}
|
|
266
278
|
};
|
|
267
279
|
|
|
268
|
-
// src/
|
|
280
|
+
// src/daemon/lineage.ts
|
|
269
281
|
import fs2 from "fs";
|
|
270
282
|
import path2 from "path";
|
|
271
|
-
import { fileURLToPath } from "url";
|
|
272
|
-
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
273
|
-
var promptCache = /* @__PURE__ */ new Map();
|
|
274
|
-
function loadPrompt(name) {
|
|
275
|
-
let cached = promptCache.get(name);
|
|
276
|
-
if (!cached) {
|
|
277
|
-
cached = fs2.readFileSync(path2.join(__dirname, `${name}.md`), "utf-8").trim();
|
|
278
|
-
promptCache.set(name, cached);
|
|
279
|
-
}
|
|
280
|
-
return cached;
|
|
281
|
-
}
|
|
282
|
-
function interpolate(template, vars) {
|
|
283
|
-
let result = template;
|
|
284
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
285
|
-
result = result.replaceAll(`{{${key}}}`, value);
|
|
286
|
-
}
|
|
287
|
-
return result;
|
|
288
|
-
}
|
|
289
|
-
function buildExtractionPrompt(sessionId, eventCount, toolSummary) {
|
|
290
|
-
return interpolate(loadPrompt("extraction"), {
|
|
291
|
-
sessionId,
|
|
292
|
-
eventCount: String(eventCount),
|
|
293
|
-
toolSummary
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
function buildSummaryPrompt(sessionId, user, content) {
|
|
297
|
-
return interpolate(loadPrompt("summary"), {
|
|
298
|
-
sessionId,
|
|
299
|
-
user,
|
|
300
|
-
content
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
function buildTitlePrompt(summary, sessionId) {
|
|
304
|
-
return interpolate(loadPrompt("title"), {
|
|
305
|
-
summary,
|
|
306
|
-
sessionId
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
var ARTIFACT_TYPE_DESCRIPTIONS = [
|
|
310
|
-
'"spec" \u2014 Design specifications, architecture documents',
|
|
311
|
-
'"plan" \u2014 Implementation plans, roadmaps',
|
|
312
|
-
'"rfc" \u2014 Requests for comment, proposals',
|
|
313
|
-
'"doc" \u2014 Documentation, guides, READMEs',
|
|
314
|
-
'"other" \u2014 Other substantive documents'
|
|
315
|
-
];
|
|
316
|
-
function buildSimilarityPrompt(currentSummary, candidateSummary) {
|
|
317
|
-
return interpolate(loadPrompt("session-similarity"), {
|
|
318
|
-
currentSummary,
|
|
319
|
-
candidateSummary
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
function buildClassificationPrompt(sessionId, candidates) {
|
|
323
|
-
const fileList = candidates.map((c) => {
|
|
324
|
-
const truncated = c.content.slice(0, CANDIDATE_CONTENT_PREVIEW);
|
|
325
|
-
return `### ${c.path}
|
|
326
|
-
\`\`\`
|
|
327
|
-
${truncated}
|
|
328
|
-
\`\`\``;
|
|
329
|
-
}).join("\n\n");
|
|
330
|
-
return interpolate(loadPrompt("classification"), {
|
|
331
|
-
sessionId,
|
|
332
|
-
fileList,
|
|
333
|
-
artifactTypes: ARTIFACT_TYPE_DESCRIPTIONS.map((d) => `- ${d}`).join("\n"),
|
|
334
|
-
validTypes: ARTIFACT_TYPES.join("|")
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// src/intelligence/response.ts
|
|
339
|
-
var REASONING_PATTERNS = [
|
|
340
|
-
// <think>...</think>answer (DeepSeek, Qwen, GLM, many others)
|
|
341
|
-
/<think>[\s\S]*?<\/think>\s*/gi,
|
|
342
|
-
// Implicit opening: reasoning...</think>answer (GLM-4.7 observed)
|
|
343
|
-
/^[\s\S]*?<\/think>\s*/i,
|
|
344
|
-
// <reasoning>...</reasoning>answer
|
|
345
|
-
/<reasoning>[\s\S]*?<\/reasoning>\s*/gi,
|
|
346
|
-
// <|thinking|>...<|/thinking|>answer
|
|
347
|
-
/<\|thinking\|>[\s\S]*?<\|\/thinking\|>\s*/gi
|
|
348
|
-
];
|
|
349
|
-
function stripReasoningTokens(text) {
|
|
350
|
-
if (!text) return text;
|
|
351
|
-
for (const pattern of REASONING_PATTERNS) {
|
|
352
|
-
const stripped = text.replace(pattern, "").trim();
|
|
353
|
-
if (stripped && stripped !== text.trim()) {
|
|
354
|
-
return stripped;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return text;
|
|
358
|
-
}
|
|
359
|
-
function extractJson(text) {
|
|
360
|
-
const cleaned = stripReasoningTokens(text);
|
|
361
|
-
const fenceMatch = cleaned.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
362
|
-
if (fenceMatch) {
|
|
363
|
-
return JSON.parse(fenceMatch[1].trim());
|
|
364
|
-
}
|
|
365
|
-
const objectMatch = cleaned.match(/\{[\s\S]*\}/);
|
|
366
|
-
if (objectMatch) {
|
|
367
|
-
return JSON.parse(objectMatch[0]);
|
|
368
|
-
}
|
|
369
|
-
return JSON.parse(cleaned);
|
|
370
|
-
}
|
|
371
|
-
function extractNumber(text) {
|
|
372
|
-
const cleaned = stripReasoningTokens(text).trim();
|
|
373
|
-
const match = cleaned.match(/(\d+\.?\d*)/);
|
|
374
|
-
if (match) return parseFloat(match[1]);
|
|
375
|
-
return parseFloat(cleaned);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// src/daemon/processor.ts
|
|
379
|
-
var ClassificationResponseSchema = external_exports.object({
|
|
380
|
-
artifacts: external_exports.array(external_exports.object({
|
|
381
|
-
source_path: external_exports.string(),
|
|
382
|
-
artifact_type: external_exports.enum(ARTIFACT_TYPES),
|
|
383
|
-
title: external_exports.string(),
|
|
384
|
-
tags: external_exports.array(external_exports.string()).default([])
|
|
385
|
-
})).default([])
|
|
386
|
-
});
|
|
387
|
-
var BufferProcessor = class {
|
|
388
|
-
constructor(backend, contextWindow = 8192) {
|
|
389
|
-
this.backend = backend;
|
|
390
|
-
this.contextWindow = contextWindow;
|
|
391
|
-
}
|
|
392
|
-
truncateForContext(data, maxTokens) {
|
|
393
|
-
const available = this.contextWindow - maxTokens;
|
|
394
|
-
const dataTokens = Math.ceil(data.length / CHARS_PER_TOKEN);
|
|
395
|
-
if (dataTokens <= available) return data;
|
|
396
|
-
const charBudget = available * CHARS_PER_TOKEN;
|
|
397
|
-
return data.slice(0, charBudget);
|
|
398
|
-
}
|
|
399
|
-
async process(events, sessionId) {
|
|
400
|
-
const rawPrompt = this.buildPromptForExtraction(events, sessionId);
|
|
401
|
-
const prompt = this.truncateForContext(rawPrompt, EXTRACTION_MAX_TOKENS);
|
|
402
|
-
try {
|
|
403
|
-
const response = await this.backend.summarize(prompt, { maxTokens: EXTRACTION_MAX_TOKENS });
|
|
404
|
-
const parsed = extractJson(response.text);
|
|
405
|
-
return {
|
|
406
|
-
summary: parsed.summary,
|
|
407
|
-
observations: parsed.observations ?? [],
|
|
408
|
-
degraded: false
|
|
409
|
-
};
|
|
410
|
-
} catch (error) {
|
|
411
|
-
return {
|
|
412
|
-
summary: `LLM processing failed for session ${sessionId}. ${events.length} events captured. Error: ${error.message}`,
|
|
413
|
-
observations: [],
|
|
414
|
-
degraded: true
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
buildPromptForExtraction(events, sessionId) {
|
|
419
|
-
const toolSummary = this.summarizeEvents(events);
|
|
420
|
-
return buildExtractionPrompt(sessionId, events.length, toolSummary);
|
|
421
|
-
}
|
|
422
|
-
async summarizeSession(conversationMarkdown, sessionId, user) {
|
|
423
|
-
const truncatedContent = this.truncateForContext(conversationMarkdown, SUMMARY_MAX_TOKENS);
|
|
424
|
-
const summaryPrompt = buildSummaryPrompt(sessionId, user ?? "unknown", truncatedContent);
|
|
425
|
-
let summaryText;
|
|
426
|
-
try {
|
|
427
|
-
const response = await this.backend.summarize(summaryPrompt, { maxTokens: SUMMARY_MAX_TOKENS });
|
|
428
|
-
summaryText = stripReasoningTokens(response.text);
|
|
429
|
-
} catch (error) {
|
|
430
|
-
summaryText = `Session ${sessionId} \u2014 summarization failed: ${error.message}`;
|
|
431
|
-
}
|
|
432
|
-
const titlePrompt = buildTitlePrompt(summaryText, sessionId);
|
|
433
|
-
let title;
|
|
434
|
-
try {
|
|
435
|
-
const response = await this.backend.summarize(titlePrompt, { maxTokens: TITLE_MAX_TOKENS });
|
|
436
|
-
title = stripReasoningTokens(response.text).trim();
|
|
437
|
-
} catch {
|
|
438
|
-
title = `Session ${sessionId}`;
|
|
439
|
-
}
|
|
440
|
-
return { summary: summaryText, title };
|
|
441
|
-
}
|
|
442
|
-
async classifyArtifacts(candidates, sessionId) {
|
|
443
|
-
if (candidates.length === 0) return [];
|
|
444
|
-
const prompt = this.buildPromptForClassification(candidates, sessionId);
|
|
445
|
-
const response = await this.backend.summarize(prompt, { maxTokens: CLASSIFICATION_MAX_TOKENS });
|
|
446
|
-
const raw = extractJson(response.text);
|
|
447
|
-
const parsed = ClassificationResponseSchema.parse(raw);
|
|
448
|
-
return parsed.artifacts;
|
|
449
|
-
}
|
|
450
|
-
buildPromptForClassification(candidates, sessionId) {
|
|
451
|
-
return buildClassificationPrompt(sessionId, candidates);
|
|
452
|
-
}
|
|
453
|
-
summarizeEvents(events) {
|
|
454
|
-
const toolCounts = /* @__PURE__ */ new Map();
|
|
455
|
-
const filesAccessed = /* @__PURE__ */ new Set();
|
|
456
|
-
const prompts = [];
|
|
457
|
-
const aiResponses = [];
|
|
458
|
-
for (const event of events) {
|
|
459
|
-
if (event.type === "user_prompt") {
|
|
460
|
-
const prompt = String(event.prompt ?? "");
|
|
461
|
-
if (prompt) prompts.push(prompt.slice(0, PROMPT_PREVIEW_CHARS));
|
|
462
|
-
continue;
|
|
463
|
-
}
|
|
464
|
-
if (event.type === "ai_response") {
|
|
465
|
-
const content = String(event.content ?? "");
|
|
466
|
-
if (content) aiResponses.push(content.slice(0, AI_RESPONSE_PREVIEW_CHARS));
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
const tool = String(event.tool_name ?? event.tool ?? "unknown");
|
|
470
|
-
toolCounts.set(tool, (toolCounts.get(tool) ?? 0) + 1);
|
|
471
|
-
const input = event.tool_input ?? event.input;
|
|
472
|
-
if (input?.path) filesAccessed.add(String(input.path));
|
|
473
|
-
if (input?.file_path) filesAccessed.add(String(input.file_path));
|
|
474
|
-
if (input?.command) filesAccessed.add(`[cmd] ${String(input.command).slice(0, COMMAND_PREVIEW_CHARS)}`);
|
|
475
|
-
}
|
|
476
|
-
const lines = [];
|
|
477
|
-
if (prompts.length > 0) {
|
|
478
|
-
lines.push("### User Prompts");
|
|
479
|
-
for (const p of prompts) {
|
|
480
|
-
lines.push(`- "${p}"`);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
lines.push("\n### Tool Usage");
|
|
484
|
-
for (const [tool, count] of toolCounts) {
|
|
485
|
-
lines.push(`- ${tool}: ${count} calls`);
|
|
486
|
-
}
|
|
487
|
-
if (filesAccessed.size > 0) {
|
|
488
|
-
lines.push("\n### Files Accessed");
|
|
489
|
-
for (const file of filesAccessed) {
|
|
490
|
-
lines.push(`- ${file}`);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
if (aiResponses.length > 0) {
|
|
494
|
-
lines.push("\n### AI Responses");
|
|
495
|
-
for (const r of aiResponses) {
|
|
496
|
-
lines.push(`- "${r}"`);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
return lines.join("\n");
|
|
500
|
-
}
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
// src/daemon/lineage.ts
|
|
504
|
-
import fs3 from "fs";
|
|
505
|
-
import path3 from "path";
|
|
506
283
|
var LINEAGE_IMMEDIATE_GAP_SECONDS = 5;
|
|
507
284
|
var LINEAGE_FALLBACK_MAX_HOURS = 24;
|
|
508
285
|
var LINEAGE_SIMILARITY_THRESHOLD = 0.7;
|
|
@@ -515,8 +292,8 @@ var LineageGraph = class {
|
|
|
515
292
|
state;
|
|
516
293
|
filePath;
|
|
517
294
|
constructor(vaultDir) {
|
|
518
|
-
this.filePath =
|
|
519
|
-
|
|
295
|
+
this.filePath = path2.join(vaultDir, "lineage.json");
|
|
296
|
+
fs2.mkdirSync(path2.dirname(this.filePath), { recursive: true });
|
|
520
297
|
this.state = this.load();
|
|
521
298
|
}
|
|
522
299
|
addLink(link) {
|
|
@@ -596,7 +373,7 @@ var LineageGraph = class {
|
|
|
596
373
|
}
|
|
597
374
|
load() {
|
|
598
375
|
try {
|
|
599
|
-
const raw = JSON.parse(
|
|
376
|
+
const raw = JSON.parse(fs2.readFileSync(this.filePath, "utf-8"));
|
|
600
377
|
const sessionArtifacts = raw.sessionArtifacts ?? raw.sessionPlans ?? {};
|
|
601
378
|
return { links: raw.links ?? [], sessionArtifacts };
|
|
602
379
|
} catch {
|
|
@@ -605,8 +382,8 @@ var LineageGraph = class {
|
|
|
605
382
|
}
|
|
606
383
|
persist() {
|
|
607
384
|
const tmp = this.filePath + ".tmp";
|
|
608
|
-
|
|
609
|
-
|
|
385
|
+
fs2.writeFileSync(tmp, JSON.stringify(this.state, null, 2));
|
|
386
|
+
fs2.renameSync(tmp, this.filePath);
|
|
610
387
|
}
|
|
611
388
|
};
|
|
612
389
|
|
|
@@ -700,7 +477,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
700
477
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
701
478
|
const statMethod = opts.lstat ? lstat : stat;
|
|
702
479
|
if (wantBigintFsStats) {
|
|
703
|
-
this._stat = (
|
|
480
|
+
this._stat = (path7) => statMethod(path7, { bigint: true });
|
|
704
481
|
} else {
|
|
705
482
|
this._stat = statMethod;
|
|
706
483
|
}
|
|
@@ -725,8 +502,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
725
502
|
const par = this.parent;
|
|
726
503
|
const fil = par && par.files;
|
|
727
504
|
if (fil && fil.length > 0) {
|
|
728
|
-
const { path:
|
|
729
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
505
|
+
const { path: path7, depth } = par;
|
|
506
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
|
|
730
507
|
const awaited = await Promise.all(slice);
|
|
731
508
|
for (const entry of awaited) {
|
|
732
509
|
if (!entry)
|
|
@@ -766,20 +543,20 @@ var ReaddirpStream = class extends Readable {
|
|
|
766
543
|
this.reading = false;
|
|
767
544
|
}
|
|
768
545
|
}
|
|
769
|
-
async _exploreDir(
|
|
546
|
+
async _exploreDir(path7, depth) {
|
|
770
547
|
let files;
|
|
771
548
|
try {
|
|
772
|
-
files = await readdir(
|
|
549
|
+
files = await readdir(path7, this._rdOptions);
|
|
773
550
|
} catch (error) {
|
|
774
551
|
this._onError(error);
|
|
775
552
|
}
|
|
776
|
-
return { files, depth, path:
|
|
553
|
+
return { files, depth, path: path7 };
|
|
777
554
|
}
|
|
778
|
-
async _formatEntry(dirent,
|
|
555
|
+
async _formatEntry(dirent, path7) {
|
|
779
556
|
let entry;
|
|
780
557
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
781
558
|
try {
|
|
782
|
-
const fullPath = presolve(pjoin(
|
|
559
|
+
const fullPath = presolve(pjoin(path7, basename3));
|
|
783
560
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
|
|
784
561
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
785
562
|
} catch (err) {
|
|
@@ -1179,16 +956,16 @@ var delFromSet = (main2, prop, item) => {
|
|
|
1179
956
|
};
|
|
1180
957
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
1181
958
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
1182
|
-
function createFsWatchInstance(
|
|
959
|
+
function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
|
|
1183
960
|
const handleEvent = (rawEvent, evPath) => {
|
|
1184
|
-
listener(
|
|
1185
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
1186
|
-
if (evPath &&
|
|
1187
|
-
fsWatchBroadcast(sp.resolve(
|
|
961
|
+
listener(path7);
|
|
962
|
+
emitRaw(rawEvent, evPath, { watchedPath: path7 });
|
|
963
|
+
if (evPath && path7 !== evPath) {
|
|
964
|
+
fsWatchBroadcast(sp.resolve(path7, evPath), KEY_LISTENERS, sp.join(path7, evPath));
|
|
1188
965
|
}
|
|
1189
966
|
};
|
|
1190
967
|
try {
|
|
1191
|
-
return fs_watch(
|
|
968
|
+
return fs_watch(path7, {
|
|
1192
969
|
persistent: options.persistent
|
|
1193
970
|
}, handleEvent);
|
|
1194
971
|
} catch (error) {
|
|
@@ -1204,12 +981,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
1204
981
|
listener(val1, val2, val3);
|
|
1205
982
|
});
|
|
1206
983
|
};
|
|
1207
|
-
var setFsWatchListener = (
|
|
984
|
+
var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
1208
985
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
1209
986
|
let cont = FsWatchInstances.get(fullPath);
|
|
1210
987
|
let watcher;
|
|
1211
988
|
if (!options.persistent) {
|
|
1212
|
-
watcher = createFsWatchInstance(
|
|
989
|
+
watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
|
|
1213
990
|
if (!watcher)
|
|
1214
991
|
return;
|
|
1215
992
|
return watcher.close.bind(watcher);
|
|
@@ -1220,7 +997,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1220
997
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
1221
998
|
} else {
|
|
1222
999
|
watcher = createFsWatchInstance(
|
|
1223
|
-
|
|
1000
|
+
path7,
|
|
1224
1001
|
options,
|
|
1225
1002
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
1226
1003
|
errHandler,
|
|
@@ -1235,7 +1012,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1235
1012
|
cont.watcherUnusable = true;
|
|
1236
1013
|
if (isWindows && error.code === "EPERM") {
|
|
1237
1014
|
try {
|
|
1238
|
-
const fd = await open(
|
|
1015
|
+
const fd = await open(path7, "r");
|
|
1239
1016
|
await fd.close();
|
|
1240
1017
|
broadcastErr(error);
|
|
1241
1018
|
} catch (err) {
|
|
@@ -1266,7 +1043,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1266
1043
|
};
|
|
1267
1044
|
};
|
|
1268
1045
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
1269
|
-
var setFsWatchFileListener = (
|
|
1046
|
+
var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
1270
1047
|
const { listener, rawEmitter } = handlers;
|
|
1271
1048
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
1272
1049
|
const copts = cont && cont.options;
|
|
@@ -1288,7 +1065,7 @@ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
|
|
|
1288
1065
|
});
|
|
1289
1066
|
const currmtime = curr.mtimeMs;
|
|
1290
1067
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
1291
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
1068
|
+
foreach(cont.listeners, (listener2) => listener2(path7, curr));
|
|
1292
1069
|
}
|
|
1293
1070
|
})
|
|
1294
1071
|
};
|
|
@@ -1318,13 +1095,13 @@ var NodeFsHandler = class {
|
|
|
1318
1095
|
* @param listener on fs change
|
|
1319
1096
|
* @returns closer for the watcher instance
|
|
1320
1097
|
*/
|
|
1321
|
-
_watchWithNodeFs(
|
|
1098
|
+
_watchWithNodeFs(path7, listener) {
|
|
1322
1099
|
const opts = this.fsw.options;
|
|
1323
|
-
const directory = sp.dirname(
|
|
1324
|
-
const basename3 = sp.basename(
|
|
1100
|
+
const directory = sp.dirname(path7);
|
|
1101
|
+
const basename3 = sp.basename(path7);
|
|
1325
1102
|
const parent = this.fsw._getWatchedDir(directory);
|
|
1326
1103
|
parent.add(basename3);
|
|
1327
|
-
const absolutePath = sp.resolve(
|
|
1104
|
+
const absolutePath = sp.resolve(path7);
|
|
1328
1105
|
const options = {
|
|
1329
1106
|
persistent: opts.persistent
|
|
1330
1107
|
};
|
|
@@ -1334,12 +1111,12 @@ var NodeFsHandler = class {
|
|
|
1334
1111
|
if (opts.usePolling) {
|
|
1335
1112
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
1336
1113
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
1337
|
-
closer = setFsWatchFileListener(
|
|
1114
|
+
closer = setFsWatchFileListener(path7, absolutePath, options, {
|
|
1338
1115
|
listener,
|
|
1339
1116
|
rawEmitter: this.fsw._emitRaw
|
|
1340
1117
|
});
|
|
1341
1118
|
} else {
|
|
1342
|
-
closer = setFsWatchListener(
|
|
1119
|
+
closer = setFsWatchListener(path7, absolutePath, options, {
|
|
1343
1120
|
listener,
|
|
1344
1121
|
errHandler: this._boundHandleError,
|
|
1345
1122
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -1361,7 +1138,7 @@ var NodeFsHandler = class {
|
|
|
1361
1138
|
let prevStats = stats;
|
|
1362
1139
|
if (parent.has(basename3))
|
|
1363
1140
|
return;
|
|
1364
|
-
const listener = async (
|
|
1141
|
+
const listener = async (path7, newStats) => {
|
|
1365
1142
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
1366
1143
|
return;
|
|
1367
1144
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -1375,11 +1152,11 @@ var NodeFsHandler = class {
|
|
|
1375
1152
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
1376
1153
|
}
|
|
1377
1154
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
1378
|
-
this.fsw._closeFile(
|
|
1155
|
+
this.fsw._closeFile(path7);
|
|
1379
1156
|
prevStats = newStats2;
|
|
1380
1157
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
1381
1158
|
if (closer2)
|
|
1382
|
-
this.fsw._addPathCloser(
|
|
1159
|
+
this.fsw._addPathCloser(path7, closer2);
|
|
1383
1160
|
} else {
|
|
1384
1161
|
prevStats = newStats2;
|
|
1385
1162
|
}
|
|
@@ -1411,7 +1188,7 @@ var NodeFsHandler = class {
|
|
|
1411
1188
|
* @param item basename of this item
|
|
1412
1189
|
* @returns true if no more processing is needed for this entry.
|
|
1413
1190
|
*/
|
|
1414
|
-
async _handleSymlink(entry, directory,
|
|
1191
|
+
async _handleSymlink(entry, directory, path7, item) {
|
|
1415
1192
|
if (this.fsw.closed) {
|
|
1416
1193
|
return;
|
|
1417
1194
|
}
|
|
@@ -1421,7 +1198,7 @@ var NodeFsHandler = class {
|
|
|
1421
1198
|
this.fsw._incrReadyCount();
|
|
1422
1199
|
let linkPath;
|
|
1423
1200
|
try {
|
|
1424
|
-
linkPath = await fsrealpath(
|
|
1201
|
+
linkPath = await fsrealpath(path7);
|
|
1425
1202
|
} catch (e) {
|
|
1426
1203
|
this.fsw._emitReady();
|
|
1427
1204
|
return true;
|
|
@@ -1431,12 +1208,12 @@ var NodeFsHandler = class {
|
|
|
1431
1208
|
if (dir.has(item)) {
|
|
1432
1209
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
1433
1210
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
1434
|
-
this.fsw._emit(EV.CHANGE,
|
|
1211
|
+
this.fsw._emit(EV.CHANGE, path7, entry.stats);
|
|
1435
1212
|
}
|
|
1436
1213
|
} else {
|
|
1437
1214
|
dir.add(item);
|
|
1438
1215
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
1439
|
-
this.fsw._emit(EV.ADD,
|
|
1216
|
+
this.fsw._emit(EV.ADD, path7, entry.stats);
|
|
1440
1217
|
}
|
|
1441
1218
|
this.fsw._emitReady();
|
|
1442
1219
|
return true;
|
|
@@ -1466,9 +1243,9 @@ var NodeFsHandler = class {
|
|
|
1466
1243
|
return;
|
|
1467
1244
|
}
|
|
1468
1245
|
const item = entry.path;
|
|
1469
|
-
let
|
|
1246
|
+
let path7 = sp.join(directory, item);
|
|
1470
1247
|
current.add(item);
|
|
1471
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
1248
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
|
|
1472
1249
|
return;
|
|
1473
1250
|
}
|
|
1474
1251
|
if (this.fsw.closed) {
|
|
@@ -1477,8 +1254,8 @@ var NodeFsHandler = class {
|
|
|
1477
1254
|
}
|
|
1478
1255
|
if (item === target || !target && !previous.has(item)) {
|
|
1479
1256
|
this.fsw._incrReadyCount();
|
|
1480
|
-
|
|
1481
|
-
this._addToNodeFs(
|
|
1257
|
+
path7 = sp.join(dir, sp.relative(dir, path7));
|
|
1258
|
+
this._addToNodeFs(path7, initialAdd, wh, depth + 1);
|
|
1482
1259
|
}
|
|
1483
1260
|
}).on(EV.ERROR, this._boundHandleError);
|
|
1484
1261
|
return new Promise((resolve3, reject) => {
|
|
@@ -1547,13 +1324,13 @@ var NodeFsHandler = class {
|
|
|
1547
1324
|
* @param depth Child path actually targeted for watch
|
|
1548
1325
|
* @param target Child path actually targeted for watch
|
|
1549
1326
|
*/
|
|
1550
|
-
async _addToNodeFs(
|
|
1327
|
+
async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
|
|
1551
1328
|
const ready = this.fsw._emitReady;
|
|
1552
|
-
if (this.fsw._isIgnored(
|
|
1329
|
+
if (this.fsw._isIgnored(path7) || this.fsw.closed) {
|
|
1553
1330
|
ready();
|
|
1554
1331
|
return false;
|
|
1555
1332
|
}
|
|
1556
|
-
const wh = this.fsw._getWatchHelpers(
|
|
1333
|
+
const wh = this.fsw._getWatchHelpers(path7);
|
|
1557
1334
|
if (priorWh) {
|
|
1558
1335
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
1559
1336
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -1569,8 +1346,8 @@ var NodeFsHandler = class {
|
|
|
1569
1346
|
const follow = this.fsw.options.followSymlinks;
|
|
1570
1347
|
let closer;
|
|
1571
1348
|
if (stats.isDirectory()) {
|
|
1572
|
-
const absPath = sp.resolve(
|
|
1573
|
-
const targetPath = follow ? await fsrealpath(
|
|
1349
|
+
const absPath = sp.resolve(path7);
|
|
1350
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
1574
1351
|
if (this.fsw.closed)
|
|
1575
1352
|
return;
|
|
1576
1353
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -1580,29 +1357,29 @@ var NodeFsHandler = class {
|
|
|
1580
1357
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
1581
1358
|
}
|
|
1582
1359
|
} else if (stats.isSymbolicLink()) {
|
|
1583
|
-
const targetPath = follow ? await fsrealpath(
|
|
1360
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
1584
1361
|
if (this.fsw.closed)
|
|
1585
1362
|
return;
|
|
1586
1363
|
const parent = sp.dirname(wh.watchPath);
|
|
1587
1364
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
1588
1365
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
1589
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
1366
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
|
|
1590
1367
|
if (this.fsw.closed)
|
|
1591
1368
|
return;
|
|
1592
1369
|
if (targetPath !== void 0) {
|
|
1593
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
1370
|
+
this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
|
|
1594
1371
|
}
|
|
1595
1372
|
} else {
|
|
1596
1373
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
1597
1374
|
}
|
|
1598
1375
|
ready();
|
|
1599
1376
|
if (closer)
|
|
1600
|
-
this.fsw._addPathCloser(
|
|
1377
|
+
this.fsw._addPathCloser(path7, closer);
|
|
1601
1378
|
return false;
|
|
1602
1379
|
} catch (error) {
|
|
1603
1380
|
if (this.fsw._handleError(error)) {
|
|
1604
1381
|
ready();
|
|
1605
|
-
return
|
|
1382
|
+
return path7;
|
|
1606
1383
|
}
|
|
1607
1384
|
}
|
|
1608
1385
|
}
|
|
@@ -1645,24 +1422,24 @@ function createPattern(matcher) {
|
|
|
1645
1422
|
}
|
|
1646
1423
|
return () => false;
|
|
1647
1424
|
}
|
|
1648
|
-
function normalizePath(
|
|
1649
|
-
if (typeof
|
|
1425
|
+
function normalizePath(path7) {
|
|
1426
|
+
if (typeof path7 !== "string")
|
|
1650
1427
|
throw new Error("string expected");
|
|
1651
|
-
|
|
1652
|
-
|
|
1428
|
+
path7 = sp2.normalize(path7);
|
|
1429
|
+
path7 = path7.replace(/\\/g, "/");
|
|
1653
1430
|
let prepend = false;
|
|
1654
|
-
if (
|
|
1431
|
+
if (path7.startsWith("//"))
|
|
1655
1432
|
prepend = true;
|
|
1656
|
-
|
|
1433
|
+
path7 = path7.replace(DOUBLE_SLASH_RE, "/");
|
|
1657
1434
|
if (prepend)
|
|
1658
|
-
|
|
1659
|
-
return
|
|
1435
|
+
path7 = "/" + path7;
|
|
1436
|
+
return path7;
|
|
1660
1437
|
}
|
|
1661
1438
|
function matchPatterns(patterns, testString, stats) {
|
|
1662
|
-
const
|
|
1439
|
+
const path7 = normalizePath(testString);
|
|
1663
1440
|
for (let index = 0; index < patterns.length; index++) {
|
|
1664
1441
|
const pattern = patterns[index];
|
|
1665
|
-
if (pattern(
|
|
1442
|
+
if (pattern(path7, stats)) {
|
|
1666
1443
|
return true;
|
|
1667
1444
|
}
|
|
1668
1445
|
}
|
|
@@ -1700,19 +1477,19 @@ var toUnix = (string) => {
|
|
|
1700
1477
|
}
|
|
1701
1478
|
return str;
|
|
1702
1479
|
};
|
|
1703
|
-
var normalizePathToUnix = (
|
|
1704
|
-
var normalizeIgnored = (cwd = "") => (
|
|
1705
|
-
if (typeof
|
|
1706
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
1480
|
+
var normalizePathToUnix = (path7) => toUnix(sp2.normalize(toUnix(path7)));
|
|
1481
|
+
var normalizeIgnored = (cwd = "") => (path7) => {
|
|
1482
|
+
if (typeof path7 === "string") {
|
|
1483
|
+
return normalizePathToUnix(sp2.isAbsolute(path7) ? path7 : sp2.join(cwd, path7));
|
|
1707
1484
|
} else {
|
|
1708
|
-
return
|
|
1485
|
+
return path7;
|
|
1709
1486
|
}
|
|
1710
1487
|
};
|
|
1711
|
-
var getAbsolutePath = (
|
|
1712
|
-
if (sp2.isAbsolute(
|
|
1713
|
-
return
|
|
1488
|
+
var getAbsolutePath = (path7, cwd) => {
|
|
1489
|
+
if (sp2.isAbsolute(path7)) {
|
|
1490
|
+
return path7;
|
|
1714
1491
|
}
|
|
1715
|
-
return sp2.join(cwd,
|
|
1492
|
+
return sp2.join(cwd, path7);
|
|
1716
1493
|
};
|
|
1717
1494
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
1718
1495
|
var DirEntry = class {
|
|
@@ -1777,10 +1554,10 @@ var WatchHelper = class {
|
|
|
1777
1554
|
dirParts;
|
|
1778
1555
|
followSymlinks;
|
|
1779
1556
|
statMethod;
|
|
1780
|
-
constructor(
|
|
1557
|
+
constructor(path7, follow, fsw) {
|
|
1781
1558
|
this.fsw = fsw;
|
|
1782
|
-
const watchPath =
|
|
1783
|
-
this.path =
|
|
1559
|
+
const watchPath = path7;
|
|
1560
|
+
this.path = path7 = path7.replace(REPLACER_RE, "");
|
|
1784
1561
|
this.watchPath = watchPath;
|
|
1785
1562
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
1786
1563
|
this.dirParts = [];
|
|
@@ -1920,20 +1697,20 @@ var FSWatcher = class extends EventEmitter {
|
|
|
1920
1697
|
this._closePromise = void 0;
|
|
1921
1698
|
let paths = unifyPaths(paths_);
|
|
1922
1699
|
if (cwd) {
|
|
1923
|
-
paths = paths.map((
|
|
1924
|
-
const absPath = getAbsolutePath(
|
|
1700
|
+
paths = paths.map((path7) => {
|
|
1701
|
+
const absPath = getAbsolutePath(path7, cwd);
|
|
1925
1702
|
return absPath;
|
|
1926
1703
|
});
|
|
1927
1704
|
}
|
|
1928
|
-
paths.forEach((
|
|
1929
|
-
this._removeIgnoredPath(
|
|
1705
|
+
paths.forEach((path7) => {
|
|
1706
|
+
this._removeIgnoredPath(path7);
|
|
1930
1707
|
});
|
|
1931
1708
|
this._userIgnored = void 0;
|
|
1932
1709
|
if (!this._readyCount)
|
|
1933
1710
|
this._readyCount = 0;
|
|
1934
1711
|
this._readyCount += paths.length;
|
|
1935
|
-
Promise.all(paths.map(async (
|
|
1936
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
1712
|
+
Promise.all(paths.map(async (path7) => {
|
|
1713
|
+
const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, void 0, 0, _origAdd);
|
|
1937
1714
|
if (res)
|
|
1938
1715
|
this._emitReady();
|
|
1939
1716
|
return res;
|
|
@@ -1955,17 +1732,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
1955
1732
|
return this;
|
|
1956
1733
|
const paths = unifyPaths(paths_);
|
|
1957
1734
|
const { cwd } = this.options;
|
|
1958
|
-
paths.forEach((
|
|
1959
|
-
if (!sp2.isAbsolute(
|
|
1735
|
+
paths.forEach((path7) => {
|
|
1736
|
+
if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
|
|
1960
1737
|
if (cwd)
|
|
1961
|
-
|
|
1962
|
-
|
|
1738
|
+
path7 = sp2.join(cwd, path7);
|
|
1739
|
+
path7 = sp2.resolve(path7);
|
|
1963
1740
|
}
|
|
1964
|
-
this._closePath(
|
|
1965
|
-
this._addIgnoredPath(
|
|
1966
|
-
if (this._watched.has(
|
|
1741
|
+
this._closePath(path7);
|
|
1742
|
+
this._addIgnoredPath(path7);
|
|
1743
|
+
if (this._watched.has(path7)) {
|
|
1967
1744
|
this._addIgnoredPath({
|
|
1968
|
-
path:
|
|
1745
|
+
path: path7,
|
|
1969
1746
|
recursive: true
|
|
1970
1747
|
});
|
|
1971
1748
|
}
|
|
@@ -2029,38 +1806,38 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2029
1806
|
* @param stats arguments to be passed with event
|
|
2030
1807
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
2031
1808
|
*/
|
|
2032
|
-
async _emit(event,
|
|
1809
|
+
async _emit(event, path7, stats) {
|
|
2033
1810
|
if (this.closed)
|
|
2034
1811
|
return;
|
|
2035
1812
|
const opts = this.options;
|
|
2036
1813
|
if (isWindows)
|
|
2037
|
-
|
|
1814
|
+
path7 = sp2.normalize(path7);
|
|
2038
1815
|
if (opts.cwd)
|
|
2039
|
-
|
|
2040
|
-
const args = [
|
|
1816
|
+
path7 = sp2.relative(opts.cwd, path7);
|
|
1817
|
+
const args = [path7];
|
|
2041
1818
|
if (stats != null)
|
|
2042
1819
|
args.push(stats);
|
|
2043
1820
|
const awf = opts.awaitWriteFinish;
|
|
2044
1821
|
let pw;
|
|
2045
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
1822
|
+
if (awf && (pw = this._pendingWrites.get(path7))) {
|
|
2046
1823
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
2047
1824
|
return this;
|
|
2048
1825
|
}
|
|
2049
1826
|
if (opts.atomic) {
|
|
2050
1827
|
if (event === EVENTS.UNLINK) {
|
|
2051
|
-
this._pendingUnlinks.set(
|
|
1828
|
+
this._pendingUnlinks.set(path7, [event, ...args]);
|
|
2052
1829
|
setTimeout(() => {
|
|
2053
|
-
this._pendingUnlinks.forEach((entry,
|
|
1830
|
+
this._pendingUnlinks.forEach((entry, path8) => {
|
|
2054
1831
|
this.emit(...entry);
|
|
2055
1832
|
this.emit(EVENTS.ALL, ...entry);
|
|
2056
|
-
this._pendingUnlinks.delete(
|
|
1833
|
+
this._pendingUnlinks.delete(path8);
|
|
2057
1834
|
});
|
|
2058
1835
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
2059
1836
|
return this;
|
|
2060
1837
|
}
|
|
2061
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
1838
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
|
|
2062
1839
|
event = EVENTS.CHANGE;
|
|
2063
|
-
this._pendingUnlinks.delete(
|
|
1840
|
+
this._pendingUnlinks.delete(path7);
|
|
2064
1841
|
}
|
|
2065
1842
|
}
|
|
2066
1843
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -2078,16 +1855,16 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2078
1855
|
this.emitWithAll(event, args);
|
|
2079
1856
|
}
|
|
2080
1857
|
};
|
|
2081
|
-
this._awaitWriteFinish(
|
|
1858
|
+
this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
|
|
2082
1859
|
return this;
|
|
2083
1860
|
}
|
|
2084
1861
|
if (event === EVENTS.CHANGE) {
|
|
2085
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
1862
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
|
|
2086
1863
|
if (isThrottled)
|
|
2087
1864
|
return this;
|
|
2088
1865
|
}
|
|
2089
1866
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
2090
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
1867
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
|
|
2091
1868
|
let stats2;
|
|
2092
1869
|
try {
|
|
2093
1870
|
stats2 = await stat3(fullPath);
|
|
@@ -2118,23 +1895,23 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2118
1895
|
* @param timeout duration of time to suppress duplicate actions
|
|
2119
1896
|
* @returns tracking object or false if action should be suppressed
|
|
2120
1897
|
*/
|
|
2121
|
-
_throttle(actionType,
|
|
1898
|
+
_throttle(actionType, path7, timeout) {
|
|
2122
1899
|
if (!this._throttled.has(actionType)) {
|
|
2123
1900
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
2124
1901
|
}
|
|
2125
1902
|
const action = this._throttled.get(actionType);
|
|
2126
1903
|
if (!action)
|
|
2127
1904
|
throw new Error("invalid throttle");
|
|
2128
|
-
const actionPath = action.get(
|
|
1905
|
+
const actionPath = action.get(path7);
|
|
2129
1906
|
if (actionPath) {
|
|
2130
1907
|
actionPath.count++;
|
|
2131
1908
|
return false;
|
|
2132
1909
|
}
|
|
2133
1910
|
let timeoutObject;
|
|
2134
1911
|
const clear = () => {
|
|
2135
|
-
const item = action.get(
|
|
1912
|
+
const item = action.get(path7);
|
|
2136
1913
|
const count = item ? item.count : 0;
|
|
2137
|
-
action.delete(
|
|
1914
|
+
action.delete(path7);
|
|
2138
1915
|
clearTimeout(timeoutObject);
|
|
2139
1916
|
if (item)
|
|
2140
1917
|
clearTimeout(item.timeoutObject);
|
|
@@ -2142,7 +1919,7 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2142
1919
|
};
|
|
2143
1920
|
timeoutObject = setTimeout(clear, timeout);
|
|
2144
1921
|
const thr = { timeoutObject, clear, count: 0 };
|
|
2145
|
-
action.set(
|
|
1922
|
+
action.set(path7, thr);
|
|
2146
1923
|
return thr;
|
|
2147
1924
|
}
|
|
2148
1925
|
_incrReadyCount() {
|
|
@@ -2156,44 +1933,44 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2156
1933
|
* @param event
|
|
2157
1934
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
2158
1935
|
*/
|
|
2159
|
-
_awaitWriteFinish(
|
|
1936
|
+
_awaitWriteFinish(path7, threshold, event, awfEmit) {
|
|
2160
1937
|
const awf = this.options.awaitWriteFinish;
|
|
2161
1938
|
if (typeof awf !== "object")
|
|
2162
1939
|
return;
|
|
2163
1940
|
const pollInterval = awf.pollInterval;
|
|
2164
1941
|
let timeoutHandler;
|
|
2165
|
-
let fullPath =
|
|
2166
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
2167
|
-
fullPath = sp2.join(this.options.cwd,
|
|
1942
|
+
let fullPath = path7;
|
|
1943
|
+
if (this.options.cwd && !sp2.isAbsolute(path7)) {
|
|
1944
|
+
fullPath = sp2.join(this.options.cwd, path7);
|
|
2168
1945
|
}
|
|
2169
1946
|
const now = /* @__PURE__ */ new Date();
|
|
2170
1947
|
const writes = this._pendingWrites;
|
|
2171
1948
|
function awaitWriteFinishFn(prevStat) {
|
|
2172
1949
|
statcb(fullPath, (err, curStat) => {
|
|
2173
|
-
if (err || !writes.has(
|
|
1950
|
+
if (err || !writes.has(path7)) {
|
|
2174
1951
|
if (err && err.code !== "ENOENT")
|
|
2175
1952
|
awfEmit(err);
|
|
2176
1953
|
return;
|
|
2177
1954
|
}
|
|
2178
1955
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
2179
1956
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
2180
|
-
writes.get(
|
|
1957
|
+
writes.get(path7).lastChange = now2;
|
|
2181
1958
|
}
|
|
2182
|
-
const pw = writes.get(
|
|
1959
|
+
const pw = writes.get(path7);
|
|
2183
1960
|
const df = now2 - pw.lastChange;
|
|
2184
1961
|
if (df >= threshold) {
|
|
2185
|
-
writes.delete(
|
|
1962
|
+
writes.delete(path7);
|
|
2186
1963
|
awfEmit(void 0, curStat);
|
|
2187
1964
|
} else {
|
|
2188
1965
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
2189
1966
|
}
|
|
2190
1967
|
});
|
|
2191
1968
|
}
|
|
2192
|
-
if (!writes.has(
|
|
2193
|
-
writes.set(
|
|
1969
|
+
if (!writes.has(path7)) {
|
|
1970
|
+
writes.set(path7, {
|
|
2194
1971
|
lastChange: now,
|
|
2195
1972
|
cancelWait: () => {
|
|
2196
|
-
writes.delete(
|
|
1973
|
+
writes.delete(path7);
|
|
2197
1974
|
clearTimeout(timeoutHandler);
|
|
2198
1975
|
return event;
|
|
2199
1976
|
}
|
|
@@ -2204,8 +1981,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2204
1981
|
/**
|
|
2205
1982
|
* Determines whether user has asked to ignore this path.
|
|
2206
1983
|
*/
|
|
2207
|
-
_isIgnored(
|
|
2208
|
-
if (this.options.atomic && DOT_RE.test(
|
|
1984
|
+
_isIgnored(path7, stats) {
|
|
1985
|
+
if (this.options.atomic && DOT_RE.test(path7))
|
|
2209
1986
|
return true;
|
|
2210
1987
|
if (!this._userIgnored) {
|
|
2211
1988
|
const { cwd } = this.options;
|
|
@@ -2215,17 +1992,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2215
1992
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
2216
1993
|
this._userIgnored = anymatch(list, void 0);
|
|
2217
1994
|
}
|
|
2218
|
-
return this._userIgnored(
|
|
1995
|
+
return this._userIgnored(path7, stats);
|
|
2219
1996
|
}
|
|
2220
|
-
_isntIgnored(
|
|
2221
|
-
return !this._isIgnored(
|
|
1997
|
+
_isntIgnored(path7, stat4) {
|
|
1998
|
+
return !this._isIgnored(path7, stat4);
|
|
2222
1999
|
}
|
|
2223
2000
|
/**
|
|
2224
2001
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
2225
2002
|
* @param path file or directory pattern being watched
|
|
2226
2003
|
*/
|
|
2227
|
-
_getWatchHelpers(
|
|
2228
|
-
return new WatchHelper(
|
|
2004
|
+
_getWatchHelpers(path7) {
|
|
2005
|
+
return new WatchHelper(path7, this.options.followSymlinks, this);
|
|
2229
2006
|
}
|
|
2230
2007
|
// Directory helpers
|
|
2231
2008
|
// -----------------
|
|
@@ -2257,63 +2034,63 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2257
2034
|
* @param item base path of item/directory
|
|
2258
2035
|
*/
|
|
2259
2036
|
_remove(directory, item, isDirectory) {
|
|
2260
|
-
const
|
|
2261
|
-
const fullPath = sp2.resolve(
|
|
2262
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
2263
|
-
if (!this._throttle("remove",
|
|
2037
|
+
const path7 = sp2.join(directory, item);
|
|
2038
|
+
const fullPath = sp2.resolve(path7);
|
|
2039
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
|
|
2040
|
+
if (!this._throttle("remove", path7, 100))
|
|
2264
2041
|
return;
|
|
2265
2042
|
if (!isDirectory && this._watched.size === 1) {
|
|
2266
2043
|
this.add(directory, item, true);
|
|
2267
2044
|
}
|
|
2268
|
-
const wp = this._getWatchedDir(
|
|
2045
|
+
const wp = this._getWatchedDir(path7);
|
|
2269
2046
|
const nestedDirectoryChildren = wp.getChildren();
|
|
2270
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
2047
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
|
|
2271
2048
|
const parent = this._getWatchedDir(directory);
|
|
2272
2049
|
const wasTracked = parent.has(item);
|
|
2273
2050
|
parent.remove(item);
|
|
2274
2051
|
if (this._symlinkPaths.has(fullPath)) {
|
|
2275
2052
|
this._symlinkPaths.delete(fullPath);
|
|
2276
2053
|
}
|
|
2277
|
-
let relPath =
|
|
2054
|
+
let relPath = path7;
|
|
2278
2055
|
if (this.options.cwd)
|
|
2279
|
-
relPath = sp2.relative(this.options.cwd,
|
|
2056
|
+
relPath = sp2.relative(this.options.cwd, path7);
|
|
2280
2057
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
2281
2058
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
2282
2059
|
if (event === EVENTS.ADD)
|
|
2283
2060
|
return;
|
|
2284
2061
|
}
|
|
2285
|
-
this._watched.delete(
|
|
2062
|
+
this._watched.delete(path7);
|
|
2286
2063
|
this._watched.delete(fullPath);
|
|
2287
2064
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
2288
|
-
if (wasTracked && !this._isIgnored(
|
|
2289
|
-
this._emit(eventName,
|
|
2290
|
-
this._closePath(
|
|
2065
|
+
if (wasTracked && !this._isIgnored(path7))
|
|
2066
|
+
this._emit(eventName, path7);
|
|
2067
|
+
this._closePath(path7);
|
|
2291
2068
|
}
|
|
2292
2069
|
/**
|
|
2293
2070
|
* Closes all watchers for a path
|
|
2294
2071
|
*/
|
|
2295
|
-
_closePath(
|
|
2296
|
-
this._closeFile(
|
|
2297
|
-
const dir = sp2.dirname(
|
|
2298
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
2072
|
+
_closePath(path7) {
|
|
2073
|
+
this._closeFile(path7);
|
|
2074
|
+
const dir = sp2.dirname(path7);
|
|
2075
|
+
this._getWatchedDir(dir).remove(sp2.basename(path7));
|
|
2299
2076
|
}
|
|
2300
2077
|
/**
|
|
2301
2078
|
* Closes only file-specific watchers
|
|
2302
2079
|
*/
|
|
2303
|
-
_closeFile(
|
|
2304
|
-
const closers = this._closers.get(
|
|
2080
|
+
_closeFile(path7) {
|
|
2081
|
+
const closers = this._closers.get(path7);
|
|
2305
2082
|
if (!closers)
|
|
2306
2083
|
return;
|
|
2307
2084
|
closers.forEach((closer) => closer());
|
|
2308
|
-
this._closers.delete(
|
|
2085
|
+
this._closers.delete(path7);
|
|
2309
2086
|
}
|
|
2310
|
-
_addPathCloser(
|
|
2087
|
+
_addPathCloser(path7, closer) {
|
|
2311
2088
|
if (!closer)
|
|
2312
2089
|
return;
|
|
2313
|
-
let list = this._closers.get(
|
|
2090
|
+
let list = this._closers.get(path7);
|
|
2314
2091
|
if (!list) {
|
|
2315
2092
|
list = [];
|
|
2316
|
-
this._closers.set(
|
|
2093
|
+
this._closers.set(path7, list);
|
|
2317
2094
|
}
|
|
2318
2095
|
list.push(closer);
|
|
2319
2096
|
}
|
|
@@ -2342,7 +2119,7 @@ function watch(paths, options = {}) {
|
|
|
2342
2119
|
}
|
|
2343
2120
|
|
|
2344
2121
|
// src/daemon/watcher.ts
|
|
2345
|
-
import
|
|
2122
|
+
import path3 from "path";
|
|
2346
2123
|
var PlanWatcher = class {
|
|
2347
2124
|
config;
|
|
2348
2125
|
fsWatcher = null;
|
|
@@ -2368,7 +2145,7 @@ var PlanWatcher = class {
|
|
|
2368
2145
|
source: "tool",
|
|
2369
2146
|
filePath,
|
|
2370
2147
|
sessionId: event.session_id,
|
|
2371
|
-
detail: `${event.tool_name} on plan file: ${
|
|
2148
|
+
detail: `${event.tool_name} on plan file: ${path3.basename(filePath)}`,
|
|
2372
2149
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2373
2150
|
});
|
|
2374
2151
|
}
|
|
@@ -2376,7 +2153,7 @@ var PlanWatcher = class {
|
|
|
2376
2153
|
}
|
|
2377
2154
|
startFileWatcher() {
|
|
2378
2155
|
const absPaths = this.config.watchPaths.map(
|
|
2379
|
-
(p) =>
|
|
2156
|
+
(p) => path3.resolve(this.config.projectRoot, p)
|
|
2380
2157
|
);
|
|
2381
2158
|
this.fsWatcher = watch(absPaths, {
|
|
2382
2159
|
ignoreInitial: true,
|
|
@@ -2392,7 +2169,7 @@ var PlanWatcher = class {
|
|
|
2392
2169
|
this.fsWatcher = null;
|
|
2393
2170
|
}
|
|
2394
2171
|
onFileChange(absolutePath, action) {
|
|
2395
|
-
const rel =
|
|
2172
|
+
const rel = path3.relative(this.config.projectRoot, absolutePath);
|
|
2396
2173
|
this.knownPlans.add(absolutePath);
|
|
2397
2174
|
this.config.onPlan({
|
|
2398
2175
|
source: "filesystem",
|
|
@@ -2402,95 +2179,17 @@ var PlanWatcher = class {
|
|
|
2402
2179
|
});
|
|
2403
2180
|
}
|
|
2404
2181
|
isInPlanDirectory(filePath) {
|
|
2405
|
-
const abs =
|
|
2182
|
+
const abs = path3.isAbsolute(filePath) ? filePath : path3.resolve(this.config.projectRoot, filePath);
|
|
2406
2183
|
return this.config.watchPaths.some(
|
|
2407
|
-
(wp) => abs.startsWith(
|
|
2184
|
+
(wp) => abs.startsWith(path3.resolve(this.config.projectRoot, wp))
|
|
2408
2185
|
);
|
|
2409
2186
|
}
|
|
2410
2187
|
};
|
|
2411
2188
|
|
|
2412
|
-
// src/capture/transcript-miner.ts
|
|
2413
|
-
var TranscriptMiner = class {
|
|
2414
|
-
registry;
|
|
2415
|
-
constructor(config) {
|
|
2416
|
-
this.registry = new AgentRegistry(config?.additionalAdapters);
|
|
2417
|
-
}
|
|
2418
|
-
/**
|
|
2419
|
-
* Extract all conversation turns for a session.
|
|
2420
|
-
* Convenience wrapper — delegates to getAllTurnsWithSource.
|
|
2421
|
-
*/
|
|
2422
|
-
getAllTurns(sessionId) {
|
|
2423
|
-
return this.getAllTurnsWithSource(sessionId).turns;
|
|
2424
|
-
}
|
|
2425
|
-
/**
|
|
2426
|
-
* Extract turns using the hook-provided transcript path first (fast, no scanning),
|
|
2427
|
-
* then fall back to adapter registry scanning if the path isn't provided.
|
|
2428
|
-
*/
|
|
2429
|
-
getAllTurnsWithSource(sessionId, transcriptPath) {
|
|
2430
|
-
if (transcriptPath) {
|
|
2431
|
-
const result2 = this.registry.parseTurnsFromPath(transcriptPath);
|
|
2432
|
-
if (result2) return result2;
|
|
2433
|
-
}
|
|
2434
|
-
const result = this.registry.getTranscriptTurns(sessionId);
|
|
2435
|
-
if (result) return result;
|
|
2436
|
-
return { turns: [], source: "none" };
|
|
2437
|
-
}
|
|
2438
|
-
};
|
|
2439
|
-
function extractTurnsFromBuffer(events) {
|
|
2440
|
-
const turns = [];
|
|
2441
|
-
let current = null;
|
|
2442
|
-
for (const event of events) {
|
|
2443
|
-
const type = event.type;
|
|
2444
|
-
if (type === "user_prompt") {
|
|
2445
|
-
if (current) turns.push(current);
|
|
2446
|
-
current = {
|
|
2447
|
-
prompt: String(event.prompt ?? "").slice(0, PROMPT_PREVIEW_CHARS),
|
|
2448
|
-
toolCount: 0,
|
|
2449
|
-
timestamp: String(event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString())
|
|
2450
|
-
};
|
|
2451
|
-
} else if (type === "tool_use") {
|
|
2452
|
-
if (current) current.toolCount++;
|
|
2453
|
-
}
|
|
2454
|
-
}
|
|
2455
|
-
if (current) turns.push(current);
|
|
2456
|
-
return turns;
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
// src/vault/observations.ts
|
|
2460
|
-
function writeObservationNotes(observations, sessionId, writer, index, vaultDir) {
|
|
2461
|
-
const results = [];
|
|
2462
|
-
for (const obs of observations) {
|
|
2463
|
-
const obsId = `${obs.type}-${sessionId.slice(-6)}-${Date.now()}`;
|
|
2464
|
-
const body = formatMemoryBody({
|
|
2465
|
-
title: obs.title,
|
|
2466
|
-
observationType: obs.type,
|
|
2467
|
-
content: obs.content,
|
|
2468
|
-
sessionId,
|
|
2469
|
-
root_cause: obs.root_cause,
|
|
2470
|
-
fix: obs.fix,
|
|
2471
|
-
rationale: obs.rationale,
|
|
2472
|
-
alternatives_rejected: obs.alternatives_rejected,
|
|
2473
|
-
gained: obs.gained,
|
|
2474
|
-
sacrificed: obs.sacrificed,
|
|
2475
|
-
tags: obs.tags
|
|
2476
|
-
});
|
|
2477
|
-
const relativePath = writer.writeMemory({
|
|
2478
|
-
id: obsId,
|
|
2479
|
-
observation_type: obs.type,
|
|
2480
|
-
session: sessionNoteId(sessionId),
|
|
2481
|
-
tags: obs.tags,
|
|
2482
|
-
content: body
|
|
2483
|
-
});
|
|
2484
|
-
indexNote(index, vaultDir, relativePath);
|
|
2485
|
-
results.push({ id: obsId, path: relativePath, observation: obs });
|
|
2486
|
-
}
|
|
2487
|
-
return results;
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
2189
|
// src/artifacts/candidates.ts
|
|
2491
2190
|
import { execFileSync } from "child_process";
|
|
2492
|
-
import
|
|
2493
|
-
import
|
|
2191
|
+
import fs3 from "fs";
|
|
2192
|
+
import path4 from "path";
|
|
2494
2193
|
var EXCLUDED_FILENAMES = /* @__PURE__ */ new Set([
|
|
2495
2194
|
"claude.md",
|
|
2496
2195
|
"agents.md",
|
|
@@ -2511,7 +2210,7 @@ var EXCLUDED_PREFIXES = [
|
|
|
2511
2210
|
".github/"
|
|
2512
2211
|
];
|
|
2513
2212
|
function isExcludedPath(relativePath) {
|
|
2514
|
-
const basename3 =
|
|
2213
|
+
const basename3 = path4.basename(relativePath).toLowerCase();
|
|
2515
2214
|
if (EXCLUDED_FILENAMES.has(basename3)) return true;
|
|
2516
2215
|
const normalized = relativePath.replace(/\\/g, "/");
|
|
2517
2216
|
return EXCLUDED_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
|
@@ -2519,7 +2218,7 @@ function isExcludedPath(relativePath) {
|
|
|
2519
2218
|
function collectArtifactCandidates(filePaths, config, projectRoot) {
|
|
2520
2219
|
if (filePaths.size === 0) return [];
|
|
2521
2220
|
const extFiltered = [...filePaths].filter(
|
|
2522
|
-
(absPath) => config.artifact_extensions.includes(
|
|
2221
|
+
(absPath) => config.artifact_extensions.includes(path4.extname(absPath))
|
|
2523
2222
|
);
|
|
2524
2223
|
if (extFiltered.length === 0) return [];
|
|
2525
2224
|
const ignoredSet = getGitIgnored(extFiltered, projectRoot);
|
|
@@ -2527,8 +2226,8 @@ function collectArtifactCandidates(filePaths, config, projectRoot) {
|
|
|
2527
2226
|
for (const absPath of extFiltered) {
|
|
2528
2227
|
if (ignoredSet.has(absPath)) continue;
|
|
2529
2228
|
try {
|
|
2530
|
-
const content =
|
|
2531
|
-
const relativePath =
|
|
2229
|
+
const content = fs3.readFileSync(absPath, "utf-8");
|
|
2230
|
+
const relativePath = path4.relative(projectRoot, absPath);
|
|
2532
2231
|
if (isExcludedPath(relativePath)) continue;
|
|
2533
2232
|
candidates.push({ path: relativePath, content });
|
|
2534
2233
|
} catch {
|
|
@@ -2551,9 +2250,9 @@ function getGitIgnored(filePaths, cwd) {
|
|
|
2551
2250
|
|
|
2552
2251
|
// src/artifacts/slugify.ts
|
|
2553
2252
|
import crypto from "crypto";
|
|
2554
|
-
import
|
|
2253
|
+
import path5 from "path";
|
|
2555
2254
|
function slugifyPath(relativePath) {
|
|
2556
|
-
const ext =
|
|
2255
|
+
const ext = path5.extname(relativePath);
|
|
2557
2256
|
const withoutExt = ext ? relativePath.slice(0, -ext.length) : relativePath;
|
|
2558
2257
|
let slug = withoutExt.replace(/[/\\]/g, "-").toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
2559
2258
|
if (slug.length > MAX_SLUG_LENGTH) {
|
|
@@ -2565,8 +2264,8 @@ function slugifyPath(relativePath) {
|
|
|
2565
2264
|
|
|
2566
2265
|
// src/daemon/main.ts
|
|
2567
2266
|
var import_yaml = __toESM(require_dist(), 1);
|
|
2568
|
-
import
|
|
2569
|
-
import
|
|
2267
|
+
import fs4 from "fs";
|
|
2268
|
+
import path6 from "path";
|
|
2570
2269
|
function indexAndEmbed(relativePath, noteId, embeddingText, metadata, deps) {
|
|
2571
2270
|
indexNote(deps.index, deps.vaultDir, relativePath);
|
|
2572
2271
|
if (deps.vectorIndex && embeddingText) {
|
|
@@ -2619,28 +2318,28 @@ ${candidate.content}`,
|
|
|
2619
2318
|
}
|
|
2620
2319
|
}
|
|
2621
2320
|
function migrateMemoryFiles(vaultDir) {
|
|
2622
|
-
const memoriesDir =
|
|
2623
|
-
if (!
|
|
2321
|
+
const memoriesDir = path6.join(vaultDir, "memories");
|
|
2322
|
+
if (!fs4.existsSync(memoriesDir)) return 0;
|
|
2624
2323
|
let moved = 0;
|
|
2625
|
-
const entries =
|
|
2324
|
+
const entries = fs4.readdirSync(memoriesDir);
|
|
2626
2325
|
for (const entry of entries) {
|
|
2627
|
-
const fullPath =
|
|
2326
|
+
const fullPath = path6.join(memoriesDir, entry);
|
|
2628
2327
|
if (!entry.endsWith(".md")) continue;
|
|
2629
|
-
if (
|
|
2328
|
+
if (fs4.statSync(fullPath).isDirectory()) continue;
|
|
2630
2329
|
try {
|
|
2631
|
-
const content =
|
|
2330
|
+
const content = fs4.readFileSync(fullPath, "utf-8");
|
|
2632
2331
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2633
2332
|
if (!fmMatch) continue;
|
|
2634
2333
|
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
2635
2334
|
const obsType = parsed.observation_type;
|
|
2636
2335
|
if (!obsType) continue;
|
|
2637
2336
|
const normalizedType = obsType.replace(/_/g, "-");
|
|
2638
|
-
const targetDir =
|
|
2639
|
-
|
|
2640
|
-
const targetPath =
|
|
2641
|
-
|
|
2337
|
+
const targetDir = path6.join(memoriesDir, normalizedType);
|
|
2338
|
+
fs4.mkdirSync(targetDir, { recursive: true });
|
|
2339
|
+
const targetPath = path6.join(targetDir, entry);
|
|
2340
|
+
fs4.renameSync(fullPath, targetPath);
|
|
2642
2341
|
const now = /* @__PURE__ */ new Date();
|
|
2643
|
-
|
|
2342
|
+
fs4.utimesSync(targetPath, now, now);
|
|
2644
2343
|
moved++;
|
|
2645
2344
|
} catch {
|
|
2646
2345
|
}
|
|
@@ -2653,9 +2352,9 @@ async function main() {
|
|
|
2653
2352
|
process.stderr.write("Usage: mycod --vault <path>\n");
|
|
2654
2353
|
process.exit(1);
|
|
2655
2354
|
}
|
|
2656
|
-
const vaultDir =
|
|
2355
|
+
const vaultDir = path6.resolve(vaultArg);
|
|
2657
2356
|
const config = loadConfig(vaultDir);
|
|
2658
|
-
const logger = new DaemonLogger(
|
|
2357
|
+
const logger = new DaemonLogger(path6.join(vaultDir, "logs"), {
|
|
2659
2358
|
level: config.daemon.log_level,
|
|
2660
2359
|
maxSize: config.daemon.max_log_size
|
|
2661
2360
|
});
|
|
@@ -2677,14 +2376,14 @@ async function main() {
|
|
|
2677
2376
|
let vectorIndex = null;
|
|
2678
2377
|
try {
|
|
2679
2378
|
const testEmbed = await embeddingProvider.embed("test");
|
|
2680
|
-
vectorIndex = new VectorIndex(
|
|
2379
|
+
vectorIndex = new VectorIndex(path6.join(vaultDir, "vectors.db"), testEmbed.dimensions);
|
|
2681
2380
|
logger.info("embeddings", "Vector index initialized", { dimensions: testEmbed.dimensions });
|
|
2682
2381
|
} catch (error) {
|
|
2683
2382
|
logger.warn("embeddings", "Vector index unavailable", { error: error.message });
|
|
2684
2383
|
}
|
|
2685
2384
|
const processor = new BufferProcessor(llmProvider, config.intelligence.llm.context_window);
|
|
2686
2385
|
const vault = new VaultWriter(vaultDir);
|
|
2687
|
-
const index = new MycoIndex(
|
|
2386
|
+
const index = new MycoIndex(path6.join(vaultDir, "index.db"));
|
|
2688
2387
|
const lineageGraph = new LineageGraph(vaultDir);
|
|
2689
2388
|
const transcriptMiner = new TranscriptMiner({
|
|
2690
2389
|
additionalAdapters: config.capture.transcript_paths.map(
|
|
@@ -2693,17 +2392,17 @@ async function main() {
|
|
|
2693
2392
|
});
|
|
2694
2393
|
let activeStopProcessing = null;
|
|
2695
2394
|
const indexDeps = { index, vaultDir, vectorIndex, embeddingProvider, logger };
|
|
2696
|
-
const bufferDir =
|
|
2395
|
+
const bufferDir = path6.join(vaultDir, "buffer");
|
|
2697
2396
|
const sessionBuffers = /* @__PURE__ */ new Map();
|
|
2698
2397
|
const sessionFilePaths = /* @__PURE__ */ new Map();
|
|
2699
2398
|
const capturedArtifactPaths = /* @__PURE__ */ new Map();
|
|
2700
|
-
if (
|
|
2399
|
+
if (fs4.existsSync(bufferDir)) {
|
|
2701
2400
|
const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
|
|
2702
|
-
for (const file of
|
|
2703
|
-
const filePath =
|
|
2704
|
-
const stat4 =
|
|
2401
|
+
for (const file of fs4.readdirSync(bufferDir)) {
|
|
2402
|
+
const filePath = path6.join(bufferDir, file);
|
|
2403
|
+
const stat4 = fs4.statSync(filePath);
|
|
2705
2404
|
if (stat4.mtimeMs < cutoff) {
|
|
2706
|
-
|
|
2405
|
+
fs4.unlinkSync(filePath);
|
|
2707
2406
|
logger.debug("daemon", "Cleaned stale buffer", { file });
|
|
2708
2407
|
}
|
|
2709
2408
|
}
|
|
@@ -2739,10 +2438,10 @@ async function main() {
|
|
|
2739
2438
|
logger.info("watcher", "Plan detected", { source: event.source, file: event.filePath });
|
|
2740
2439
|
if (event.filePath) {
|
|
2741
2440
|
try {
|
|
2742
|
-
const content =
|
|
2743
|
-
const relativePath =
|
|
2744
|
-
const title = content.match(/^#\s+(.+)$/m)?.[1] ??
|
|
2745
|
-
const planId = `plan-${
|
|
2441
|
+
const content = fs4.readFileSync(event.filePath, "utf-8");
|
|
2442
|
+
const relativePath = path6.relative(vaultDir, event.filePath);
|
|
2443
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] ?? path6.basename(event.filePath);
|
|
2444
|
+
const planId = `plan-${path6.basename(event.filePath, ".md")}`;
|
|
2746
2445
|
indexAndEmbed(
|
|
2747
2446
|
relativePath,
|
|
2748
2447
|
planId,
|
|
@@ -2793,7 +2492,7 @@ ${content}`,
|
|
|
2793
2492
|
}
|
|
2794
2493
|
const captured = capturedArtifactPaths.get(sessionId);
|
|
2795
2494
|
for (const c of candidates) {
|
|
2796
|
-
const absPath =
|
|
2495
|
+
const absPath = path6.resolve(process.cwd(), c.path);
|
|
2797
2496
|
captured.add(absPath);
|
|
2798
2497
|
}
|
|
2799
2498
|
}).catch((err) => logger.warn("processor", "Incremental artifact capture failed", {
|
|
@@ -2832,14 +2531,14 @@ ${content}`,
|
|
|
2832
2531
|
registry.unregister(session_id);
|
|
2833
2532
|
try {
|
|
2834
2533
|
const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
|
|
2835
|
-
for (const file of
|
|
2534
|
+
for (const file of fs4.readdirSync(bufferDir)) {
|
|
2836
2535
|
if (!file.endsWith(".jsonl")) continue;
|
|
2837
2536
|
const bufferSessionId = file.replace(".jsonl", "");
|
|
2838
2537
|
if (bufferSessionId === session_id) continue;
|
|
2839
|
-
const filePath =
|
|
2840
|
-
const stat4 =
|
|
2538
|
+
const filePath = path6.join(bufferDir, file);
|
|
2539
|
+
const stat4 = fs4.statSync(filePath);
|
|
2841
2540
|
if (stat4.mtimeMs < cutoff) {
|
|
2842
|
-
|
|
2541
|
+
fs4.unlinkSync(filePath);
|
|
2843
2542
|
logger.debug("daemon", "Cleaned stale buffer", { file });
|
|
2844
2543
|
}
|
|
2845
2544
|
}
|
|
@@ -2934,15 +2633,15 @@ ${content}`,
|
|
|
2934
2633
|
}
|
|
2935
2634
|
const ended = (/* @__PURE__ */ new Date()).toISOString();
|
|
2936
2635
|
let started = allTurns.length > 0 && allTurns[0].timestamp ? allTurns[0].timestamp : ended;
|
|
2937
|
-
const sessionsDir =
|
|
2636
|
+
const sessionsDir = path6.join(vaultDir, "sessions");
|
|
2938
2637
|
const sessionFileName = `${sessionNoteId(sessionId)}.md`;
|
|
2939
2638
|
let existingContent;
|
|
2940
2639
|
const duplicatePaths = [];
|
|
2941
2640
|
try {
|
|
2942
|
-
for (const dateDir of
|
|
2943
|
-
const candidate =
|
|
2641
|
+
for (const dateDir of fs4.readdirSync(sessionsDir)) {
|
|
2642
|
+
const candidate = path6.join(sessionsDir, dateDir, sessionFileName);
|
|
2944
2643
|
try {
|
|
2945
|
-
const content =
|
|
2644
|
+
const content = fs4.readFileSync(candidate, "utf-8");
|
|
2946
2645
|
if (!existingContent || content.length > existingContent.length) {
|
|
2947
2646
|
existingContent = content;
|
|
2948
2647
|
}
|
|
@@ -3002,20 +2701,20 @@ ${conversationText}`;
|
|
|
3002
2701
|
}
|
|
3003
2702
|
const date = started.slice(0, 10);
|
|
3004
2703
|
const relativePath = sessionRelativePath(sessionId, date);
|
|
3005
|
-
const targetFullPath =
|
|
2704
|
+
const targetFullPath = path6.join(vaultDir, relativePath);
|
|
3006
2705
|
for (const dup of duplicatePaths) {
|
|
3007
2706
|
if (dup !== targetFullPath) {
|
|
3008
2707
|
try {
|
|
3009
|
-
|
|
2708
|
+
fs4.unlinkSync(dup);
|
|
3010
2709
|
logger.debug("lifecycle", "Removed duplicate session file", { path: dup });
|
|
3011
2710
|
} catch {
|
|
3012
2711
|
}
|
|
3013
2712
|
}
|
|
3014
2713
|
}
|
|
3015
|
-
const attachmentsDir =
|
|
2714
|
+
const attachmentsDir = path6.join(vaultDir, "attachments");
|
|
3016
2715
|
const hasImages = allTurns.some((t) => t.images?.length);
|
|
3017
2716
|
if (hasImages) {
|
|
3018
|
-
|
|
2717
|
+
fs4.mkdirSync(attachmentsDir, { recursive: true });
|
|
3019
2718
|
}
|
|
3020
2719
|
const turnImageNames = /* @__PURE__ */ new Map();
|
|
3021
2720
|
for (let i = 0; i < allTurns.length; i++) {
|
|
@@ -3026,9 +2725,9 @@ ${conversationText}`;
|
|
|
3026
2725
|
const img = turn.images[j];
|
|
3027
2726
|
const ext = extensionForMimeType(img.mediaType);
|
|
3028
2727
|
const filename = `${bareSessionId(sessionId)}-t${i + 1}-${j + 1}.${ext}`;
|
|
3029
|
-
const filePath =
|
|
3030
|
-
if (!
|
|
3031
|
-
|
|
2728
|
+
const filePath = path6.join(attachmentsDir, filename);
|
|
2729
|
+
if (!fs4.existsSync(filePath)) {
|
|
2730
|
+
fs4.writeFileSync(filePath, Buffer.from(img.data, "base64"));
|
|
3032
2731
|
logger.debug("processor", "Image saved", { filename, turn: i + 1 });
|
|
3033
2732
|
}
|
|
3034
2733
|
names.push(filename);
|
|
@@ -3241,4 +2940,4 @@ export {
|
|
|
3241
2940
|
chokidar/index.js:
|
|
3242
2941
|
(*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
|
|
3243
2942
|
*/
|
|
3244
|
-
//# sourceMappingURL=main-
|
|
2943
|
+
//# sourceMappingURL=main-D4X6XWRT.js.map
|