@goondocks/myco 0.3.0 → 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/dist/chunk-3JCXYLHD.js +33 -0
- package/dist/chunk-3JCXYLHD.js.map +1 -0
- package/dist/{chunk-QQWUV3TC.js → chunk-72OAG4SF.js} +2 -1
- package/dist/chunk-JIQISBPI.js +362 -0
- package/dist/chunk-JIQISBPI.js.map +1 -0
- package/dist/{cli-ZHUR53CS.js → cli-ERAS5H43.js} +5 -2
- package/dist/cli-ERAS5H43.js.map +1 -0
- package/dist/{main-JY6O6ZVH.js → main-D4X6XWRT.js} +215 -531
- package/dist/main-D4X6XWRT.js.map +1 -0
- package/dist/{rebuild-YAN3TPFB.js → rebuild-3367GP5R.js} +21 -14
- 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/{server-DLBATUNG.js → server-I7MRMIOP.js} +14 -7
- package/dist/{server-DLBATUNG.js.map → server-I7MRMIOP.js.map} +1 -1
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/package.json +1 -1
- package/skills/myco/SKILL.md +33 -0
- package/dist/cli-ZHUR53CS.js.map +0 -1
- package/dist/main-JY6O6ZVH.js.map +0 -1
- package/dist/rebuild-YAN3TPFB.js.map +0 -1
- /package/dist/{chunk-QQWUV3TC.js.map → chunk-72OAG4SF.js.map} +0 -0
|
@@ -1,18 +1,24 @@
|
|
|
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
17
|
} from "./chunk-P2Q77C5F.js";
|
|
11
18
|
import {
|
|
12
|
-
ARTIFACT_TYPES,
|
|
13
19
|
indexNote,
|
|
14
20
|
rebuildIndex
|
|
15
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-72OAG4SF.js";
|
|
16
22
|
import {
|
|
17
23
|
generateEmbedding
|
|
18
24
|
} from "./chunk-RGVBGTD6.js";
|
|
@@ -44,33 +50,24 @@ import {
|
|
|
44
50
|
EventBuffer
|
|
45
51
|
} from "./chunk-I7PMGO6S.js";
|
|
46
52
|
import {
|
|
47
|
-
AgentRegistry,
|
|
48
53
|
claudeCodeAdapter,
|
|
49
54
|
createPerProjectAdapter,
|
|
50
55
|
extensionForMimeType
|
|
51
56
|
} from "./chunk-2QEJKG7R.js";
|
|
52
57
|
import {
|
|
53
|
-
AI_RESPONSE_PREVIEW_CHARS,
|
|
54
58
|
CANDIDATE_CONTENT_PREVIEW,
|
|
55
|
-
CHARS_PER_TOKEN,
|
|
56
|
-
CLASSIFICATION_MAX_TOKENS,
|
|
57
|
-
COMMAND_PREVIEW_CHARS,
|
|
58
59
|
CONTENT_SNIPPET_CHARS,
|
|
59
60
|
CONTEXT_SESSION_PREVIEW_CHARS,
|
|
60
61
|
EMBEDDING_INPUT_LIMIT,
|
|
61
|
-
EXTRACTION_MAX_TOKENS,
|
|
62
62
|
FILE_WATCH_STABILITY_MS,
|
|
63
63
|
LINEAGE_RECENT_SESSIONS_LIMIT,
|
|
64
64
|
MAX_SLUG_LENGTH,
|
|
65
65
|
PROMPT_CONTEXT_MAX_MEMORIES,
|
|
66
66
|
PROMPT_CONTEXT_MIN_LENGTH,
|
|
67
67
|
PROMPT_CONTEXT_MIN_SIMILARITY,
|
|
68
|
-
PROMPT_PREVIEW_CHARS,
|
|
69
68
|
RELATED_MEMORIES_LIMIT,
|
|
70
69
|
SESSION_CONTEXT_MAX_PLANS,
|
|
71
|
-
STALE_BUFFER_MAX_AGE_MS
|
|
72
|
-
SUMMARY_MAX_TOKENS,
|
|
73
|
-
TITLE_MAX_TOKENS
|
|
70
|
+
STALE_BUFFER_MAX_AGE_MS
|
|
74
71
|
} from "./chunk-Q7BEFSOV.js";
|
|
75
72
|
import {
|
|
76
73
|
__toESM
|
|
@@ -280,244 +277,9 @@ var BatchManager = class {
|
|
|
280
277
|
}
|
|
281
278
|
};
|
|
282
279
|
|
|
283
|
-
// src/
|
|
280
|
+
// src/daemon/lineage.ts
|
|
284
281
|
import fs2 from "fs";
|
|
285
282
|
import path2 from "path";
|
|
286
|
-
import { fileURLToPath } from "url";
|
|
287
|
-
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
288
|
-
var promptCache = /* @__PURE__ */ new Map();
|
|
289
|
-
function loadPrompt(name) {
|
|
290
|
-
let cached = promptCache.get(name);
|
|
291
|
-
if (!cached) {
|
|
292
|
-
cached = fs2.readFileSync(path2.join(__dirname, `${name}.md`), "utf-8").trim();
|
|
293
|
-
promptCache.set(name, cached);
|
|
294
|
-
}
|
|
295
|
-
return cached;
|
|
296
|
-
}
|
|
297
|
-
function interpolate(template, vars) {
|
|
298
|
-
let result = template;
|
|
299
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
300
|
-
result = result.replaceAll(`{{${key}}}`, value);
|
|
301
|
-
}
|
|
302
|
-
return result;
|
|
303
|
-
}
|
|
304
|
-
function buildExtractionPrompt(sessionId, eventCount, toolSummary) {
|
|
305
|
-
return interpolate(loadPrompt("extraction"), {
|
|
306
|
-
sessionId,
|
|
307
|
-
eventCount: String(eventCount),
|
|
308
|
-
toolSummary
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
function buildSummaryPrompt(sessionId, user, content) {
|
|
312
|
-
return interpolate(loadPrompt("summary"), {
|
|
313
|
-
sessionId,
|
|
314
|
-
user,
|
|
315
|
-
content
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
function buildTitlePrompt(summary, sessionId) {
|
|
319
|
-
return interpolate(loadPrompt("title"), {
|
|
320
|
-
summary,
|
|
321
|
-
sessionId
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
var ARTIFACT_TYPE_DESCRIPTIONS = [
|
|
325
|
-
'"spec" \u2014 Design specifications, architecture documents',
|
|
326
|
-
'"plan" \u2014 Implementation plans, roadmaps',
|
|
327
|
-
'"rfc" \u2014 Requests for comment, proposals',
|
|
328
|
-
'"doc" \u2014 Documentation, guides, READMEs',
|
|
329
|
-
'"other" \u2014 Other substantive documents'
|
|
330
|
-
];
|
|
331
|
-
function buildSimilarityPrompt(currentSummary, candidateSummary) {
|
|
332
|
-
return interpolate(loadPrompt("session-similarity"), {
|
|
333
|
-
currentSummary,
|
|
334
|
-
candidateSummary
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
function buildClassificationPrompt(sessionId, candidates) {
|
|
338
|
-
const fileList = candidates.map((c) => {
|
|
339
|
-
const truncated = c.content.slice(0, CANDIDATE_CONTENT_PREVIEW);
|
|
340
|
-
return `### ${c.path}
|
|
341
|
-
\`\`\`
|
|
342
|
-
${truncated}
|
|
343
|
-
\`\`\``;
|
|
344
|
-
}).join("\n\n");
|
|
345
|
-
return interpolate(loadPrompt("classification"), {
|
|
346
|
-
sessionId,
|
|
347
|
-
fileList,
|
|
348
|
-
artifactTypes: ARTIFACT_TYPE_DESCRIPTIONS.map((d) => `- ${d}`).join("\n"),
|
|
349
|
-
validTypes: ARTIFACT_TYPES.join("|")
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// src/intelligence/response.ts
|
|
354
|
-
var REASONING_PATTERNS = [
|
|
355
|
-
// <think>...</think>answer (DeepSeek, Qwen, GLM, many others)
|
|
356
|
-
/<think>[\s\S]*?<\/think>\s*/gi,
|
|
357
|
-
// Implicit opening: reasoning...</think>answer (GLM-4.7 observed)
|
|
358
|
-
/^[\s\S]*?<\/think>\s*/i,
|
|
359
|
-
// <reasoning>...</reasoning>answer
|
|
360
|
-
/<reasoning>[\s\S]*?<\/reasoning>\s*/gi,
|
|
361
|
-
// <|thinking|>...<|/thinking|>answer
|
|
362
|
-
/<\|thinking\|>[\s\S]*?<\|\/thinking\|>\s*/gi
|
|
363
|
-
];
|
|
364
|
-
function stripReasoningTokens(text) {
|
|
365
|
-
if (!text) return text;
|
|
366
|
-
for (const pattern of REASONING_PATTERNS) {
|
|
367
|
-
const stripped = text.replace(pattern, "").trim();
|
|
368
|
-
if (stripped && stripped !== text.trim()) {
|
|
369
|
-
return stripped;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
return text;
|
|
373
|
-
}
|
|
374
|
-
function extractJson(text) {
|
|
375
|
-
const cleaned = stripReasoningTokens(text);
|
|
376
|
-
const fenceMatch = cleaned.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
377
|
-
if (fenceMatch) {
|
|
378
|
-
return JSON.parse(fenceMatch[1].trim());
|
|
379
|
-
}
|
|
380
|
-
const objectMatch = cleaned.match(/\{[\s\S]*\}/);
|
|
381
|
-
if (objectMatch) {
|
|
382
|
-
return JSON.parse(objectMatch[0]);
|
|
383
|
-
}
|
|
384
|
-
return JSON.parse(cleaned);
|
|
385
|
-
}
|
|
386
|
-
function extractNumber(text) {
|
|
387
|
-
const cleaned = stripReasoningTokens(text).trim();
|
|
388
|
-
const match = cleaned.match(/(\d+\.?\d*)/);
|
|
389
|
-
if (match) return parseFloat(match[1]);
|
|
390
|
-
return parseFloat(cleaned);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// src/daemon/processor.ts
|
|
394
|
-
var ClassificationResponseSchema = external_exports.object({
|
|
395
|
-
artifacts: external_exports.array(external_exports.object({
|
|
396
|
-
source_path: external_exports.string(),
|
|
397
|
-
artifact_type: external_exports.enum(ARTIFACT_TYPES),
|
|
398
|
-
title: external_exports.string(),
|
|
399
|
-
tags: external_exports.array(external_exports.string()).default([])
|
|
400
|
-
})).default([])
|
|
401
|
-
});
|
|
402
|
-
var BufferProcessor = class {
|
|
403
|
-
constructor(backend, contextWindow = 8192) {
|
|
404
|
-
this.backend = backend;
|
|
405
|
-
this.contextWindow = contextWindow;
|
|
406
|
-
}
|
|
407
|
-
truncateForContext(data, maxTokens) {
|
|
408
|
-
const available = this.contextWindow - maxTokens;
|
|
409
|
-
const dataTokens = Math.ceil(data.length / CHARS_PER_TOKEN);
|
|
410
|
-
if (dataTokens <= available) return data;
|
|
411
|
-
const charBudget = available * CHARS_PER_TOKEN;
|
|
412
|
-
return data.slice(0, charBudget);
|
|
413
|
-
}
|
|
414
|
-
async process(events, sessionId) {
|
|
415
|
-
const rawPrompt = this.buildPromptForExtraction(events, sessionId);
|
|
416
|
-
const prompt = this.truncateForContext(rawPrompt, EXTRACTION_MAX_TOKENS);
|
|
417
|
-
try {
|
|
418
|
-
const response = await this.backend.summarize(prompt, { maxTokens: EXTRACTION_MAX_TOKENS });
|
|
419
|
-
const parsed = extractJson(response.text);
|
|
420
|
-
return {
|
|
421
|
-
summary: parsed.summary,
|
|
422
|
-
observations: parsed.observations ?? [],
|
|
423
|
-
degraded: false
|
|
424
|
-
};
|
|
425
|
-
} catch (error) {
|
|
426
|
-
return {
|
|
427
|
-
summary: `LLM processing failed for session ${sessionId}. ${events.length} events captured. Error: ${error.message}`,
|
|
428
|
-
observations: [],
|
|
429
|
-
degraded: true
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
buildPromptForExtraction(events, sessionId) {
|
|
434
|
-
const toolSummary = this.summarizeEvents(events);
|
|
435
|
-
return buildExtractionPrompt(sessionId, events.length, toolSummary);
|
|
436
|
-
}
|
|
437
|
-
async summarizeSession(conversationMarkdown, sessionId, user) {
|
|
438
|
-
const truncatedContent = this.truncateForContext(conversationMarkdown, SUMMARY_MAX_TOKENS);
|
|
439
|
-
const summaryPrompt = buildSummaryPrompt(sessionId, user ?? "unknown", truncatedContent);
|
|
440
|
-
let summaryText;
|
|
441
|
-
try {
|
|
442
|
-
const response = await this.backend.summarize(summaryPrompt, { maxTokens: SUMMARY_MAX_TOKENS });
|
|
443
|
-
summaryText = stripReasoningTokens(response.text);
|
|
444
|
-
} catch (error) {
|
|
445
|
-
summaryText = `Session ${sessionId} \u2014 summarization failed: ${error.message}`;
|
|
446
|
-
}
|
|
447
|
-
const titlePrompt = buildTitlePrompt(summaryText, sessionId);
|
|
448
|
-
let title;
|
|
449
|
-
try {
|
|
450
|
-
const response = await this.backend.summarize(titlePrompt, { maxTokens: TITLE_MAX_TOKENS });
|
|
451
|
-
title = stripReasoningTokens(response.text).trim();
|
|
452
|
-
} catch {
|
|
453
|
-
title = `Session ${sessionId}`;
|
|
454
|
-
}
|
|
455
|
-
return { summary: summaryText, title };
|
|
456
|
-
}
|
|
457
|
-
async classifyArtifacts(candidates, sessionId) {
|
|
458
|
-
if (candidates.length === 0) return [];
|
|
459
|
-
const prompt = this.buildPromptForClassification(candidates, sessionId);
|
|
460
|
-
const response = await this.backend.summarize(prompt, { maxTokens: CLASSIFICATION_MAX_TOKENS });
|
|
461
|
-
const raw = extractJson(response.text);
|
|
462
|
-
const parsed = ClassificationResponseSchema.parse(raw);
|
|
463
|
-
return parsed.artifacts;
|
|
464
|
-
}
|
|
465
|
-
buildPromptForClassification(candidates, sessionId) {
|
|
466
|
-
return buildClassificationPrompt(sessionId, candidates);
|
|
467
|
-
}
|
|
468
|
-
summarizeEvents(events) {
|
|
469
|
-
const toolCounts = /* @__PURE__ */ new Map();
|
|
470
|
-
const filesAccessed = /* @__PURE__ */ new Set();
|
|
471
|
-
const prompts = [];
|
|
472
|
-
const aiResponses = [];
|
|
473
|
-
for (const event of events) {
|
|
474
|
-
if (event.type === "user_prompt") {
|
|
475
|
-
const prompt = String(event.prompt ?? "");
|
|
476
|
-
if (prompt) prompts.push(prompt.slice(0, PROMPT_PREVIEW_CHARS));
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
if (event.type === "ai_response") {
|
|
480
|
-
const content = String(event.content ?? "");
|
|
481
|
-
if (content) aiResponses.push(content.slice(0, AI_RESPONSE_PREVIEW_CHARS));
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
const tool = String(event.tool_name ?? event.tool ?? "unknown");
|
|
485
|
-
toolCounts.set(tool, (toolCounts.get(tool) ?? 0) + 1);
|
|
486
|
-
const input = event.tool_input ?? event.input;
|
|
487
|
-
if (input?.path) filesAccessed.add(String(input.path));
|
|
488
|
-
if (input?.file_path) filesAccessed.add(String(input.file_path));
|
|
489
|
-
if (input?.command) filesAccessed.add(`[cmd] ${String(input.command).slice(0, COMMAND_PREVIEW_CHARS)}`);
|
|
490
|
-
}
|
|
491
|
-
const lines = [];
|
|
492
|
-
if (prompts.length > 0) {
|
|
493
|
-
lines.push("### User Prompts");
|
|
494
|
-
for (const p of prompts) {
|
|
495
|
-
lines.push(`- "${p}"`);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
lines.push("\n### Tool Usage");
|
|
499
|
-
for (const [tool, count] of toolCounts) {
|
|
500
|
-
lines.push(`- ${tool}: ${count} calls`);
|
|
501
|
-
}
|
|
502
|
-
if (filesAccessed.size > 0) {
|
|
503
|
-
lines.push("\n### Files Accessed");
|
|
504
|
-
for (const file of filesAccessed) {
|
|
505
|
-
lines.push(`- ${file}`);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
if (aiResponses.length > 0) {
|
|
509
|
-
lines.push("\n### AI Responses");
|
|
510
|
-
for (const r of aiResponses) {
|
|
511
|
-
lines.push(`- "${r}"`);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return lines.join("\n");
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
// src/daemon/lineage.ts
|
|
519
|
-
import fs3 from "fs";
|
|
520
|
-
import path3 from "path";
|
|
521
283
|
var LINEAGE_IMMEDIATE_GAP_SECONDS = 5;
|
|
522
284
|
var LINEAGE_FALLBACK_MAX_HOURS = 24;
|
|
523
285
|
var LINEAGE_SIMILARITY_THRESHOLD = 0.7;
|
|
@@ -530,8 +292,8 @@ var LineageGraph = class {
|
|
|
530
292
|
state;
|
|
531
293
|
filePath;
|
|
532
294
|
constructor(vaultDir) {
|
|
533
|
-
this.filePath =
|
|
534
|
-
|
|
295
|
+
this.filePath = path2.join(vaultDir, "lineage.json");
|
|
296
|
+
fs2.mkdirSync(path2.dirname(this.filePath), { recursive: true });
|
|
535
297
|
this.state = this.load();
|
|
536
298
|
}
|
|
537
299
|
addLink(link) {
|
|
@@ -611,7 +373,7 @@ var LineageGraph = class {
|
|
|
611
373
|
}
|
|
612
374
|
load() {
|
|
613
375
|
try {
|
|
614
|
-
const raw = JSON.parse(
|
|
376
|
+
const raw = JSON.parse(fs2.readFileSync(this.filePath, "utf-8"));
|
|
615
377
|
const sessionArtifacts = raw.sessionArtifacts ?? raw.sessionPlans ?? {};
|
|
616
378
|
return { links: raw.links ?? [], sessionArtifacts };
|
|
617
379
|
} catch {
|
|
@@ -620,8 +382,8 @@ var LineageGraph = class {
|
|
|
620
382
|
}
|
|
621
383
|
persist() {
|
|
622
384
|
const tmp = this.filePath + ".tmp";
|
|
623
|
-
|
|
624
|
-
|
|
385
|
+
fs2.writeFileSync(tmp, JSON.stringify(this.state, null, 2));
|
|
386
|
+
fs2.renameSync(tmp, this.filePath);
|
|
625
387
|
}
|
|
626
388
|
};
|
|
627
389
|
|
|
@@ -715,7 +477,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
715
477
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
716
478
|
const statMethod = opts.lstat ? lstat : stat;
|
|
717
479
|
if (wantBigintFsStats) {
|
|
718
|
-
this._stat = (
|
|
480
|
+
this._stat = (path7) => statMethod(path7, { bigint: true });
|
|
719
481
|
} else {
|
|
720
482
|
this._stat = statMethod;
|
|
721
483
|
}
|
|
@@ -740,8 +502,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
740
502
|
const par = this.parent;
|
|
741
503
|
const fil = par && par.files;
|
|
742
504
|
if (fil && fil.length > 0) {
|
|
743
|
-
const { path:
|
|
744
|
-
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));
|
|
745
507
|
const awaited = await Promise.all(slice);
|
|
746
508
|
for (const entry of awaited) {
|
|
747
509
|
if (!entry)
|
|
@@ -781,20 +543,20 @@ var ReaddirpStream = class extends Readable {
|
|
|
781
543
|
this.reading = false;
|
|
782
544
|
}
|
|
783
545
|
}
|
|
784
|
-
async _exploreDir(
|
|
546
|
+
async _exploreDir(path7, depth) {
|
|
785
547
|
let files;
|
|
786
548
|
try {
|
|
787
|
-
files = await readdir(
|
|
549
|
+
files = await readdir(path7, this._rdOptions);
|
|
788
550
|
} catch (error) {
|
|
789
551
|
this._onError(error);
|
|
790
552
|
}
|
|
791
|
-
return { files, depth, path:
|
|
553
|
+
return { files, depth, path: path7 };
|
|
792
554
|
}
|
|
793
|
-
async _formatEntry(dirent,
|
|
555
|
+
async _formatEntry(dirent, path7) {
|
|
794
556
|
let entry;
|
|
795
557
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
796
558
|
try {
|
|
797
|
-
const fullPath = presolve(pjoin(
|
|
559
|
+
const fullPath = presolve(pjoin(path7, basename3));
|
|
798
560
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
|
|
799
561
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
800
562
|
} catch (err) {
|
|
@@ -1194,16 +956,16 @@ var delFromSet = (main2, prop, item) => {
|
|
|
1194
956
|
};
|
|
1195
957
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
1196
958
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
1197
|
-
function createFsWatchInstance(
|
|
959
|
+
function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
|
|
1198
960
|
const handleEvent = (rawEvent, evPath) => {
|
|
1199
|
-
listener(
|
|
1200
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
1201
|
-
if (evPath &&
|
|
1202
|
-
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));
|
|
1203
965
|
}
|
|
1204
966
|
};
|
|
1205
967
|
try {
|
|
1206
|
-
return fs_watch(
|
|
968
|
+
return fs_watch(path7, {
|
|
1207
969
|
persistent: options.persistent
|
|
1208
970
|
}, handleEvent);
|
|
1209
971
|
} catch (error) {
|
|
@@ -1219,12 +981,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
1219
981
|
listener(val1, val2, val3);
|
|
1220
982
|
});
|
|
1221
983
|
};
|
|
1222
|
-
var setFsWatchListener = (
|
|
984
|
+
var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
1223
985
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
1224
986
|
let cont = FsWatchInstances.get(fullPath);
|
|
1225
987
|
let watcher;
|
|
1226
988
|
if (!options.persistent) {
|
|
1227
|
-
watcher = createFsWatchInstance(
|
|
989
|
+
watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
|
|
1228
990
|
if (!watcher)
|
|
1229
991
|
return;
|
|
1230
992
|
return watcher.close.bind(watcher);
|
|
@@ -1235,7 +997,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1235
997
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
1236
998
|
} else {
|
|
1237
999
|
watcher = createFsWatchInstance(
|
|
1238
|
-
|
|
1000
|
+
path7,
|
|
1239
1001
|
options,
|
|
1240
1002
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
1241
1003
|
errHandler,
|
|
@@ -1250,7 +1012,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1250
1012
|
cont.watcherUnusable = true;
|
|
1251
1013
|
if (isWindows && error.code === "EPERM") {
|
|
1252
1014
|
try {
|
|
1253
|
-
const fd = await open(
|
|
1015
|
+
const fd = await open(path7, "r");
|
|
1254
1016
|
await fd.close();
|
|
1255
1017
|
broadcastErr(error);
|
|
1256
1018
|
} catch (err) {
|
|
@@ -1281,7 +1043,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
1281
1043
|
};
|
|
1282
1044
|
};
|
|
1283
1045
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
1284
|
-
var setFsWatchFileListener = (
|
|
1046
|
+
var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
1285
1047
|
const { listener, rawEmitter } = handlers;
|
|
1286
1048
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
1287
1049
|
const copts = cont && cont.options;
|
|
@@ -1303,7 +1065,7 @@ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
|
|
|
1303
1065
|
});
|
|
1304
1066
|
const currmtime = curr.mtimeMs;
|
|
1305
1067
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
1306
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
1068
|
+
foreach(cont.listeners, (listener2) => listener2(path7, curr));
|
|
1307
1069
|
}
|
|
1308
1070
|
})
|
|
1309
1071
|
};
|
|
@@ -1333,13 +1095,13 @@ var NodeFsHandler = class {
|
|
|
1333
1095
|
* @param listener on fs change
|
|
1334
1096
|
* @returns closer for the watcher instance
|
|
1335
1097
|
*/
|
|
1336
|
-
_watchWithNodeFs(
|
|
1098
|
+
_watchWithNodeFs(path7, listener) {
|
|
1337
1099
|
const opts = this.fsw.options;
|
|
1338
|
-
const directory = sp.dirname(
|
|
1339
|
-
const basename3 = sp.basename(
|
|
1100
|
+
const directory = sp.dirname(path7);
|
|
1101
|
+
const basename3 = sp.basename(path7);
|
|
1340
1102
|
const parent = this.fsw._getWatchedDir(directory);
|
|
1341
1103
|
parent.add(basename3);
|
|
1342
|
-
const absolutePath = sp.resolve(
|
|
1104
|
+
const absolutePath = sp.resolve(path7);
|
|
1343
1105
|
const options = {
|
|
1344
1106
|
persistent: opts.persistent
|
|
1345
1107
|
};
|
|
@@ -1349,12 +1111,12 @@ var NodeFsHandler = class {
|
|
|
1349
1111
|
if (opts.usePolling) {
|
|
1350
1112
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
1351
1113
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
1352
|
-
closer = setFsWatchFileListener(
|
|
1114
|
+
closer = setFsWatchFileListener(path7, absolutePath, options, {
|
|
1353
1115
|
listener,
|
|
1354
1116
|
rawEmitter: this.fsw._emitRaw
|
|
1355
1117
|
});
|
|
1356
1118
|
} else {
|
|
1357
|
-
closer = setFsWatchListener(
|
|
1119
|
+
closer = setFsWatchListener(path7, absolutePath, options, {
|
|
1358
1120
|
listener,
|
|
1359
1121
|
errHandler: this._boundHandleError,
|
|
1360
1122
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -1376,7 +1138,7 @@ var NodeFsHandler = class {
|
|
|
1376
1138
|
let prevStats = stats;
|
|
1377
1139
|
if (parent.has(basename3))
|
|
1378
1140
|
return;
|
|
1379
|
-
const listener = async (
|
|
1141
|
+
const listener = async (path7, newStats) => {
|
|
1380
1142
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
1381
1143
|
return;
|
|
1382
1144
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -1390,11 +1152,11 @@ var NodeFsHandler = class {
|
|
|
1390
1152
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
1391
1153
|
}
|
|
1392
1154
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
1393
|
-
this.fsw._closeFile(
|
|
1155
|
+
this.fsw._closeFile(path7);
|
|
1394
1156
|
prevStats = newStats2;
|
|
1395
1157
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
1396
1158
|
if (closer2)
|
|
1397
|
-
this.fsw._addPathCloser(
|
|
1159
|
+
this.fsw._addPathCloser(path7, closer2);
|
|
1398
1160
|
} else {
|
|
1399
1161
|
prevStats = newStats2;
|
|
1400
1162
|
}
|
|
@@ -1426,7 +1188,7 @@ var NodeFsHandler = class {
|
|
|
1426
1188
|
* @param item basename of this item
|
|
1427
1189
|
* @returns true if no more processing is needed for this entry.
|
|
1428
1190
|
*/
|
|
1429
|
-
async _handleSymlink(entry, directory,
|
|
1191
|
+
async _handleSymlink(entry, directory, path7, item) {
|
|
1430
1192
|
if (this.fsw.closed) {
|
|
1431
1193
|
return;
|
|
1432
1194
|
}
|
|
@@ -1436,7 +1198,7 @@ var NodeFsHandler = class {
|
|
|
1436
1198
|
this.fsw._incrReadyCount();
|
|
1437
1199
|
let linkPath;
|
|
1438
1200
|
try {
|
|
1439
|
-
linkPath = await fsrealpath(
|
|
1201
|
+
linkPath = await fsrealpath(path7);
|
|
1440
1202
|
} catch (e) {
|
|
1441
1203
|
this.fsw._emitReady();
|
|
1442
1204
|
return true;
|
|
@@ -1446,12 +1208,12 @@ var NodeFsHandler = class {
|
|
|
1446
1208
|
if (dir.has(item)) {
|
|
1447
1209
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
1448
1210
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
1449
|
-
this.fsw._emit(EV.CHANGE,
|
|
1211
|
+
this.fsw._emit(EV.CHANGE, path7, entry.stats);
|
|
1450
1212
|
}
|
|
1451
1213
|
} else {
|
|
1452
1214
|
dir.add(item);
|
|
1453
1215
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
1454
|
-
this.fsw._emit(EV.ADD,
|
|
1216
|
+
this.fsw._emit(EV.ADD, path7, entry.stats);
|
|
1455
1217
|
}
|
|
1456
1218
|
this.fsw._emitReady();
|
|
1457
1219
|
return true;
|
|
@@ -1481,9 +1243,9 @@ var NodeFsHandler = class {
|
|
|
1481
1243
|
return;
|
|
1482
1244
|
}
|
|
1483
1245
|
const item = entry.path;
|
|
1484
|
-
let
|
|
1246
|
+
let path7 = sp.join(directory, item);
|
|
1485
1247
|
current.add(item);
|
|
1486
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
1248
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
|
|
1487
1249
|
return;
|
|
1488
1250
|
}
|
|
1489
1251
|
if (this.fsw.closed) {
|
|
@@ -1492,8 +1254,8 @@ var NodeFsHandler = class {
|
|
|
1492
1254
|
}
|
|
1493
1255
|
if (item === target || !target && !previous.has(item)) {
|
|
1494
1256
|
this.fsw._incrReadyCount();
|
|
1495
|
-
|
|
1496
|
-
this._addToNodeFs(
|
|
1257
|
+
path7 = sp.join(dir, sp.relative(dir, path7));
|
|
1258
|
+
this._addToNodeFs(path7, initialAdd, wh, depth + 1);
|
|
1497
1259
|
}
|
|
1498
1260
|
}).on(EV.ERROR, this._boundHandleError);
|
|
1499
1261
|
return new Promise((resolve3, reject) => {
|
|
@@ -1562,13 +1324,13 @@ var NodeFsHandler = class {
|
|
|
1562
1324
|
* @param depth Child path actually targeted for watch
|
|
1563
1325
|
* @param target Child path actually targeted for watch
|
|
1564
1326
|
*/
|
|
1565
|
-
async _addToNodeFs(
|
|
1327
|
+
async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
|
|
1566
1328
|
const ready = this.fsw._emitReady;
|
|
1567
|
-
if (this.fsw._isIgnored(
|
|
1329
|
+
if (this.fsw._isIgnored(path7) || this.fsw.closed) {
|
|
1568
1330
|
ready();
|
|
1569
1331
|
return false;
|
|
1570
1332
|
}
|
|
1571
|
-
const wh = this.fsw._getWatchHelpers(
|
|
1333
|
+
const wh = this.fsw._getWatchHelpers(path7);
|
|
1572
1334
|
if (priorWh) {
|
|
1573
1335
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
1574
1336
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -1584,8 +1346,8 @@ var NodeFsHandler = class {
|
|
|
1584
1346
|
const follow = this.fsw.options.followSymlinks;
|
|
1585
1347
|
let closer;
|
|
1586
1348
|
if (stats.isDirectory()) {
|
|
1587
|
-
const absPath = sp.resolve(
|
|
1588
|
-
const targetPath = follow ? await fsrealpath(
|
|
1349
|
+
const absPath = sp.resolve(path7);
|
|
1350
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
1589
1351
|
if (this.fsw.closed)
|
|
1590
1352
|
return;
|
|
1591
1353
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -1595,29 +1357,29 @@ var NodeFsHandler = class {
|
|
|
1595
1357
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
1596
1358
|
}
|
|
1597
1359
|
} else if (stats.isSymbolicLink()) {
|
|
1598
|
-
const targetPath = follow ? await fsrealpath(
|
|
1360
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
1599
1361
|
if (this.fsw.closed)
|
|
1600
1362
|
return;
|
|
1601
1363
|
const parent = sp.dirname(wh.watchPath);
|
|
1602
1364
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
1603
1365
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
1604
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
1366
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
|
|
1605
1367
|
if (this.fsw.closed)
|
|
1606
1368
|
return;
|
|
1607
1369
|
if (targetPath !== void 0) {
|
|
1608
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
1370
|
+
this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
|
|
1609
1371
|
}
|
|
1610
1372
|
} else {
|
|
1611
1373
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
1612
1374
|
}
|
|
1613
1375
|
ready();
|
|
1614
1376
|
if (closer)
|
|
1615
|
-
this.fsw._addPathCloser(
|
|
1377
|
+
this.fsw._addPathCloser(path7, closer);
|
|
1616
1378
|
return false;
|
|
1617
1379
|
} catch (error) {
|
|
1618
1380
|
if (this.fsw._handleError(error)) {
|
|
1619
1381
|
ready();
|
|
1620
|
-
return
|
|
1382
|
+
return path7;
|
|
1621
1383
|
}
|
|
1622
1384
|
}
|
|
1623
1385
|
}
|
|
@@ -1660,24 +1422,24 @@ function createPattern(matcher) {
|
|
|
1660
1422
|
}
|
|
1661
1423
|
return () => false;
|
|
1662
1424
|
}
|
|
1663
|
-
function normalizePath(
|
|
1664
|
-
if (typeof
|
|
1425
|
+
function normalizePath(path7) {
|
|
1426
|
+
if (typeof path7 !== "string")
|
|
1665
1427
|
throw new Error("string expected");
|
|
1666
|
-
|
|
1667
|
-
|
|
1428
|
+
path7 = sp2.normalize(path7);
|
|
1429
|
+
path7 = path7.replace(/\\/g, "/");
|
|
1668
1430
|
let prepend = false;
|
|
1669
|
-
if (
|
|
1431
|
+
if (path7.startsWith("//"))
|
|
1670
1432
|
prepend = true;
|
|
1671
|
-
|
|
1433
|
+
path7 = path7.replace(DOUBLE_SLASH_RE, "/");
|
|
1672
1434
|
if (prepend)
|
|
1673
|
-
|
|
1674
|
-
return
|
|
1435
|
+
path7 = "/" + path7;
|
|
1436
|
+
return path7;
|
|
1675
1437
|
}
|
|
1676
1438
|
function matchPatterns(patterns, testString, stats) {
|
|
1677
|
-
const
|
|
1439
|
+
const path7 = normalizePath(testString);
|
|
1678
1440
|
for (let index = 0; index < patterns.length; index++) {
|
|
1679
1441
|
const pattern = patterns[index];
|
|
1680
|
-
if (pattern(
|
|
1442
|
+
if (pattern(path7, stats)) {
|
|
1681
1443
|
return true;
|
|
1682
1444
|
}
|
|
1683
1445
|
}
|
|
@@ -1715,19 +1477,19 @@ var toUnix = (string) => {
|
|
|
1715
1477
|
}
|
|
1716
1478
|
return str;
|
|
1717
1479
|
};
|
|
1718
|
-
var normalizePathToUnix = (
|
|
1719
|
-
var normalizeIgnored = (cwd = "") => (
|
|
1720
|
-
if (typeof
|
|
1721
|
-
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));
|
|
1722
1484
|
} else {
|
|
1723
|
-
return
|
|
1485
|
+
return path7;
|
|
1724
1486
|
}
|
|
1725
1487
|
};
|
|
1726
|
-
var getAbsolutePath = (
|
|
1727
|
-
if (sp2.isAbsolute(
|
|
1728
|
-
return
|
|
1488
|
+
var getAbsolutePath = (path7, cwd) => {
|
|
1489
|
+
if (sp2.isAbsolute(path7)) {
|
|
1490
|
+
return path7;
|
|
1729
1491
|
}
|
|
1730
|
-
return sp2.join(cwd,
|
|
1492
|
+
return sp2.join(cwd, path7);
|
|
1731
1493
|
};
|
|
1732
1494
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
1733
1495
|
var DirEntry = class {
|
|
@@ -1792,10 +1554,10 @@ var WatchHelper = class {
|
|
|
1792
1554
|
dirParts;
|
|
1793
1555
|
followSymlinks;
|
|
1794
1556
|
statMethod;
|
|
1795
|
-
constructor(
|
|
1557
|
+
constructor(path7, follow, fsw) {
|
|
1796
1558
|
this.fsw = fsw;
|
|
1797
|
-
const watchPath =
|
|
1798
|
-
this.path =
|
|
1559
|
+
const watchPath = path7;
|
|
1560
|
+
this.path = path7 = path7.replace(REPLACER_RE, "");
|
|
1799
1561
|
this.watchPath = watchPath;
|
|
1800
1562
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
1801
1563
|
this.dirParts = [];
|
|
@@ -1935,20 +1697,20 @@ var FSWatcher = class extends EventEmitter {
|
|
|
1935
1697
|
this._closePromise = void 0;
|
|
1936
1698
|
let paths = unifyPaths(paths_);
|
|
1937
1699
|
if (cwd) {
|
|
1938
|
-
paths = paths.map((
|
|
1939
|
-
const absPath = getAbsolutePath(
|
|
1700
|
+
paths = paths.map((path7) => {
|
|
1701
|
+
const absPath = getAbsolutePath(path7, cwd);
|
|
1940
1702
|
return absPath;
|
|
1941
1703
|
});
|
|
1942
1704
|
}
|
|
1943
|
-
paths.forEach((
|
|
1944
|
-
this._removeIgnoredPath(
|
|
1705
|
+
paths.forEach((path7) => {
|
|
1706
|
+
this._removeIgnoredPath(path7);
|
|
1945
1707
|
});
|
|
1946
1708
|
this._userIgnored = void 0;
|
|
1947
1709
|
if (!this._readyCount)
|
|
1948
1710
|
this._readyCount = 0;
|
|
1949
1711
|
this._readyCount += paths.length;
|
|
1950
|
-
Promise.all(paths.map(async (
|
|
1951
|
-
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);
|
|
1952
1714
|
if (res)
|
|
1953
1715
|
this._emitReady();
|
|
1954
1716
|
return res;
|
|
@@ -1970,17 +1732,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
1970
1732
|
return this;
|
|
1971
1733
|
const paths = unifyPaths(paths_);
|
|
1972
1734
|
const { cwd } = this.options;
|
|
1973
|
-
paths.forEach((
|
|
1974
|
-
if (!sp2.isAbsolute(
|
|
1735
|
+
paths.forEach((path7) => {
|
|
1736
|
+
if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
|
|
1975
1737
|
if (cwd)
|
|
1976
|
-
|
|
1977
|
-
|
|
1738
|
+
path7 = sp2.join(cwd, path7);
|
|
1739
|
+
path7 = sp2.resolve(path7);
|
|
1978
1740
|
}
|
|
1979
|
-
this._closePath(
|
|
1980
|
-
this._addIgnoredPath(
|
|
1981
|
-
if (this._watched.has(
|
|
1741
|
+
this._closePath(path7);
|
|
1742
|
+
this._addIgnoredPath(path7);
|
|
1743
|
+
if (this._watched.has(path7)) {
|
|
1982
1744
|
this._addIgnoredPath({
|
|
1983
|
-
path:
|
|
1745
|
+
path: path7,
|
|
1984
1746
|
recursive: true
|
|
1985
1747
|
});
|
|
1986
1748
|
}
|
|
@@ -2044,38 +1806,38 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2044
1806
|
* @param stats arguments to be passed with event
|
|
2045
1807
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
2046
1808
|
*/
|
|
2047
|
-
async _emit(event,
|
|
1809
|
+
async _emit(event, path7, stats) {
|
|
2048
1810
|
if (this.closed)
|
|
2049
1811
|
return;
|
|
2050
1812
|
const opts = this.options;
|
|
2051
1813
|
if (isWindows)
|
|
2052
|
-
|
|
1814
|
+
path7 = sp2.normalize(path7);
|
|
2053
1815
|
if (opts.cwd)
|
|
2054
|
-
|
|
2055
|
-
const args = [
|
|
1816
|
+
path7 = sp2.relative(opts.cwd, path7);
|
|
1817
|
+
const args = [path7];
|
|
2056
1818
|
if (stats != null)
|
|
2057
1819
|
args.push(stats);
|
|
2058
1820
|
const awf = opts.awaitWriteFinish;
|
|
2059
1821
|
let pw;
|
|
2060
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
1822
|
+
if (awf && (pw = this._pendingWrites.get(path7))) {
|
|
2061
1823
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
2062
1824
|
return this;
|
|
2063
1825
|
}
|
|
2064
1826
|
if (opts.atomic) {
|
|
2065
1827
|
if (event === EVENTS.UNLINK) {
|
|
2066
|
-
this._pendingUnlinks.set(
|
|
1828
|
+
this._pendingUnlinks.set(path7, [event, ...args]);
|
|
2067
1829
|
setTimeout(() => {
|
|
2068
|
-
this._pendingUnlinks.forEach((entry,
|
|
1830
|
+
this._pendingUnlinks.forEach((entry, path8) => {
|
|
2069
1831
|
this.emit(...entry);
|
|
2070
1832
|
this.emit(EVENTS.ALL, ...entry);
|
|
2071
|
-
this._pendingUnlinks.delete(
|
|
1833
|
+
this._pendingUnlinks.delete(path8);
|
|
2072
1834
|
});
|
|
2073
1835
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
2074
1836
|
return this;
|
|
2075
1837
|
}
|
|
2076
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
1838
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
|
|
2077
1839
|
event = EVENTS.CHANGE;
|
|
2078
|
-
this._pendingUnlinks.delete(
|
|
1840
|
+
this._pendingUnlinks.delete(path7);
|
|
2079
1841
|
}
|
|
2080
1842
|
}
|
|
2081
1843
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -2093,16 +1855,16 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2093
1855
|
this.emitWithAll(event, args);
|
|
2094
1856
|
}
|
|
2095
1857
|
};
|
|
2096
|
-
this._awaitWriteFinish(
|
|
1858
|
+
this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
|
|
2097
1859
|
return this;
|
|
2098
1860
|
}
|
|
2099
1861
|
if (event === EVENTS.CHANGE) {
|
|
2100
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
1862
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
|
|
2101
1863
|
if (isThrottled)
|
|
2102
1864
|
return this;
|
|
2103
1865
|
}
|
|
2104
1866
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
2105
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
1867
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
|
|
2106
1868
|
let stats2;
|
|
2107
1869
|
try {
|
|
2108
1870
|
stats2 = await stat3(fullPath);
|
|
@@ -2133,23 +1895,23 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2133
1895
|
* @param timeout duration of time to suppress duplicate actions
|
|
2134
1896
|
* @returns tracking object or false if action should be suppressed
|
|
2135
1897
|
*/
|
|
2136
|
-
_throttle(actionType,
|
|
1898
|
+
_throttle(actionType, path7, timeout) {
|
|
2137
1899
|
if (!this._throttled.has(actionType)) {
|
|
2138
1900
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
2139
1901
|
}
|
|
2140
1902
|
const action = this._throttled.get(actionType);
|
|
2141
1903
|
if (!action)
|
|
2142
1904
|
throw new Error("invalid throttle");
|
|
2143
|
-
const actionPath = action.get(
|
|
1905
|
+
const actionPath = action.get(path7);
|
|
2144
1906
|
if (actionPath) {
|
|
2145
1907
|
actionPath.count++;
|
|
2146
1908
|
return false;
|
|
2147
1909
|
}
|
|
2148
1910
|
let timeoutObject;
|
|
2149
1911
|
const clear = () => {
|
|
2150
|
-
const item = action.get(
|
|
1912
|
+
const item = action.get(path7);
|
|
2151
1913
|
const count = item ? item.count : 0;
|
|
2152
|
-
action.delete(
|
|
1914
|
+
action.delete(path7);
|
|
2153
1915
|
clearTimeout(timeoutObject);
|
|
2154
1916
|
if (item)
|
|
2155
1917
|
clearTimeout(item.timeoutObject);
|
|
@@ -2157,7 +1919,7 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2157
1919
|
};
|
|
2158
1920
|
timeoutObject = setTimeout(clear, timeout);
|
|
2159
1921
|
const thr = { timeoutObject, clear, count: 0 };
|
|
2160
|
-
action.set(
|
|
1922
|
+
action.set(path7, thr);
|
|
2161
1923
|
return thr;
|
|
2162
1924
|
}
|
|
2163
1925
|
_incrReadyCount() {
|
|
@@ -2171,44 +1933,44 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2171
1933
|
* @param event
|
|
2172
1934
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
2173
1935
|
*/
|
|
2174
|
-
_awaitWriteFinish(
|
|
1936
|
+
_awaitWriteFinish(path7, threshold, event, awfEmit) {
|
|
2175
1937
|
const awf = this.options.awaitWriteFinish;
|
|
2176
1938
|
if (typeof awf !== "object")
|
|
2177
1939
|
return;
|
|
2178
1940
|
const pollInterval = awf.pollInterval;
|
|
2179
1941
|
let timeoutHandler;
|
|
2180
|
-
let fullPath =
|
|
2181
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
2182
|
-
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);
|
|
2183
1945
|
}
|
|
2184
1946
|
const now = /* @__PURE__ */ new Date();
|
|
2185
1947
|
const writes = this._pendingWrites;
|
|
2186
1948
|
function awaitWriteFinishFn(prevStat) {
|
|
2187
1949
|
statcb(fullPath, (err, curStat) => {
|
|
2188
|
-
if (err || !writes.has(
|
|
1950
|
+
if (err || !writes.has(path7)) {
|
|
2189
1951
|
if (err && err.code !== "ENOENT")
|
|
2190
1952
|
awfEmit(err);
|
|
2191
1953
|
return;
|
|
2192
1954
|
}
|
|
2193
1955
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
2194
1956
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
2195
|
-
writes.get(
|
|
1957
|
+
writes.get(path7).lastChange = now2;
|
|
2196
1958
|
}
|
|
2197
|
-
const pw = writes.get(
|
|
1959
|
+
const pw = writes.get(path7);
|
|
2198
1960
|
const df = now2 - pw.lastChange;
|
|
2199
1961
|
if (df >= threshold) {
|
|
2200
|
-
writes.delete(
|
|
1962
|
+
writes.delete(path7);
|
|
2201
1963
|
awfEmit(void 0, curStat);
|
|
2202
1964
|
} else {
|
|
2203
1965
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
2204
1966
|
}
|
|
2205
1967
|
});
|
|
2206
1968
|
}
|
|
2207
|
-
if (!writes.has(
|
|
2208
|
-
writes.set(
|
|
1969
|
+
if (!writes.has(path7)) {
|
|
1970
|
+
writes.set(path7, {
|
|
2209
1971
|
lastChange: now,
|
|
2210
1972
|
cancelWait: () => {
|
|
2211
|
-
writes.delete(
|
|
1973
|
+
writes.delete(path7);
|
|
2212
1974
|
clearTimeout(timeoutHandler);
|
|
2213
1975
|
return event;
|
|
2214
1976
|
}
|
|
@@ -2219,8 +1981,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2219
1981
|
/**
|
|
2220
1982
|
* Determines whether user has asked to ignore this path.
|
|
2221
1983
|
*/
|
|
2222
|
-
_isIgnored(
|
|
2223
|
-
if (this.options.atomic && DOT_RE.test(
|
|
1984
|
+
_isIgnored(path7, stats) {
|
|
1985
|
+
if (this.options.atomic && DOT_RE.test(path7))
|
|
2224
1986
|
return true;
|
|
2225
1987
|
if (!this._userIgnored) {
|
|
2226
1988
|
const { cwd } = this.options;
|
|
@@ -2230,17 +1992,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2230
1992
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
2231
1993
|
this._userIgnored = anymatch(list, void 0);
|
|
2232
1994
|
}
|
|
2233
|
-
return this._userIgnored(
|
|
1995
|
+
return this._userIgnored(path7, stats);
|
|
2234
1996
|
}
|
|
2235
|
-
_isntIgnored(
|
|
2236
|
-
return !this._isIgnored(
|
|
1997
|
+
_isntIgnored(path7, stat4) {
|
|
1998
|
+
return !this._isIgnored(path7, stat4);
|
|
2237
1999
|
}
|
|
2238
2000
|
/**
|
|
2239
2001
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
2240
2002
|
* @param path file or directory pattern being watched
|
|
2241
2003
|
*/
|
|
2242
|
-
_getWatchHelpers(
|
|
2243
|
-
return new WatchHelper(
|
|
2004
|
+
_getWatchHelpers(path7) {
|
|
2005
|
+
return new WatchHelper(path7, this.options.followSymlinks, this);
|
|
2244
2006
|
}
|
|
2245
2007
|
// Directory helpers
|
|
2246
2008
|
// -----------------
|
|
@@ -2272,63 +2034,63 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2272
2034
|
* @param item base path of item/directory
|
|
2273
2035
|
*/
|
|
2274
2036
|
_remove(directory, item, isDirectory) {
|
|
2275
|
-
const
|
|
2276
|
-
const fullPath = sp2.resolve(
|
|
2277
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
2278
|
-
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))
|
|
2279
2041
|
return;
|
|
2280
2042
|
if (!isDirectory && this._watched.size === 1) {
|
|
2281
2043
|
this.add(directory, item, true);
|
|
2282
2044
|
}
|
|
2283
|
-
const wp = this._getWatchedDir(
|
|
2045
|
+
const wp = this._getWatchedDir(path7);
|
|
2284
2046
|
const nestedDirectoryChildren = wp.getChildren();
|
|
2285
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
2047
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
|
|
2286
2048
|
const parent = this._getWatchedDir(directory);
|
|
2287
2049
|
const wasTracked = parent.has(item);
|
|
2288
2050
|
parent.remove(item);
|
|
2289
2051
|
if (this._symlinkPaths.has(fullPath)) {
|
|
2290
2052
|
this._symlinkPaths.delete(fullPath);
|
|
2291
2053
|
}
|
|
2292
|
-
let relPath =
|
|
2054
|
+
let relPath = path7;
|
|
2293
2055
|
if (this.options.cwd)
|
|
2294
|
-
relPath = sp2.relative(this.options.cwd,
|
|
2056
|
+
relPath = sp2.relative(this.options.cwd, path7);
|
|
2295
2057
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
2296
2058
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
2297
2059
|
if (event === EVENTS.ADD)
|
|
2298
2060
|
return;
|
|
2299
2061
|
}
|
|
2300
|
-
this._watched.delete(
|
|
2062
|
+
this._watched.delete(path7);
|
|
2301
2063
|
this._watched.delete(fullPath);
|
|
2302
2064
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
2303
|
-
if (wasTracked && !this._isIgnored(
|
|
2304
|
-
this._emit(eventName,
|
|
2305
|
-
this._closePath(
|
|
2065
|
+
if (wasTracked && !this._isIgnored(path7))
|
|
2066
|
+
this._emit(eventName, path7);
|
|
2067
|
+
this._closePath(path7);
|
|
2306
2068
|
}
|
|
2307
2069
|
/**
|
|
2308
2070
|
* Closes all watchers for a path
|
|
2309
2071
|
*/
|
|
2310
|
-
_closePath(
|
|
2311
|
-
this._closeFile(
|
|
2312
|
-
const dir = sp2.dirname(
|
|
2313
|
-
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));
|
|
2314
2076
|
}
|
|
2315
2077
|
/**
|
|
2316
2078
|
* Closes only file-specific watchers
|
|
2317
2079
|
*/
|
|
2318
|
-
_closeFile(
|
|
2319
|
-
const closers = this._closers.get(
|
|
2080
|
+
_closeFile(path7) {
|
|
2081
|
+
const closers = this._closers.get(path7);
|
|
2320
2082
|
if (!closers)
|
|
2321
2083
|
return;
|
|
2322
2084
|
closers.forEach((closer) => closer());
|
|
2323
|
-
this._closers.delete(
|
|
2085
|
+
this._closers.delete(path7);
|
|
2324
2086
|
}
|
|
2325
|
-
_addPathCloser(
|
|
2087
|
+
_addPathCloser(path7, closer) {
|
|
2326
2088
|
if (!closer)
|
|
2327
2089
|
return;
|
|
2328
|
-
let list = this._closers.get(
|
|
2090
|
+
let list = this._closers.get(path7);
|
|
2329
2091
|
if (!list) {
|
|
2330
2092
|
list = [];
|
|
2331
|
-
this._closers.set(
|
|
2093
|
+
this._closers.set(path7, list);
|
|
2332
2094
|
}
|
|
2333
2095
|
list.push(closer);
|
|
2334
2096
|
}
|
|
@@ -2357,7 +2119,7 @@ function watch(paths, options = {}) {
|
|
|
2357
2119
|
}
|
|
2358
2120
|
|
|
2359
2121
|
// src/daemon/watcher.ts
|
|
2360
|
-
import
|
|
2122
|
+
import path3 from "path";
|
|
2361
2123
|
var PlanWatcher = class {
|
|
2362
2124
|
config;
|
|
2363
2125
|
fsWatcher = null;
|
|
@@ -2383,7 +2145,7 @@ var PlanWatcher = class {
|
|
|
2383
2145
|
source: "tool",
|
|
2384
2146
|
filePath,
|
|
2385
2147
|
sessionId: event.session_id,
|
|
2386
|
-
detail: `${event.tool_name} on plan file: ${
|
|
2148
|
+
detail: `${event.tool_name} on plan file: ${path3.basename(filePath)}`,
|
|
2387
2149
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2388
2150
|
});
|
|
2389
2151
|
}
|
|
@@ -2391,7 +2153,7 @@ var PlanWatcher = class {
|
|
|
2391
2153
|
}
|
|
2392
2154
|
startFileWatcher() {
|
|
2393
2155
|
const absPaths = this.config.watchPaths.map(
|
|
2394
|
-
(p) =>
|
|
2156
|
+
(p) => path3.resolve(this.config.projectRoot, p)
|
|
2395
2157
|
);
|
|
2396
2158
|
this.fsWatcher = watch(absPaths, {
|
|
2397
2159
|
ignoreInitial: true,
|
|
@@ -2407,7 +2169,7 @@ var PlanWatcher = class {
|
|
|
2407
2169
|
this.fsWatcher = null;
|
|
2408
2170
|
}
|
|
2409
2171
|
onFileChange(absolutePath, action) {
|
|
2410
|
-
const rel =
|
|
2172
|
+
const rel = path3.relative(this.config.projectRoot, absolutePath);
|
|
2411
2173
|
this.knownPlans.add(absolutePath);
|
|
2412
2174
|
this.config.onPlan({
|
|
2413
2175
|
source: "filesystem",
|
|
@@ -2417,95 +2179,17 @@ var PlanWatcher = class {
|
|
|
2417
2179
|
});
|
|
2418
2180
|
}
|
|
2419
2181
|
isInPlanDirectory(filePath) {
|
|
2420
|
-
const abs =
|
|
2182
|
+
const abs = path3.isAbsolute(filePath) ? filePath : path3.resolve(this.config.projectRoot, filePath);
|
|
2421
2183
|
return this.config.watchPaths.some(
|
|
2422
|
-
(wp) => abs.startsWith(
|
|
2184
|
+
(wp) => abs.startsWith(path3.resolve(this.config.projectRoot, wp))
|
|
2423
2185
|
);
|
|
2424
2186
|
}
|
|
2425
2187
|
};
|
|
2426
2188
|
|
|
2427
|
-
// src/capture/transcript-miner.ts
|
|
2428
|
-
var TranscriptMiner = class {
|
|
2429
|
-
registry;
|
|
2430
|
-
constructor(config) {
|
|
2431
|
-
this.registry = new AgentRegistry(config?.additionalAdapters);
|
|
2432
|
-
}
|
|
2433
|
-
/**
|
|
2434
|
-
* Extract all conversation turns for a session.
|
|
2435
|
-
* Convenience wrapper — delegates to getAllTurnsWithSource.
|
|
2436
|
-
*/
|
|
2437
|
-
getAllTurns(sessionId) {
|
|
2438
|
-
return this.getAllTurnsWithSource(sessionId).turns;
|
|
2439
|
-
}
|
|
2440
|
-
/**
|
|
2441
|
-
* Extract turns using the hook-provided transcript path first (fast, no scanning),
|
|
2442
|
-
* then fall back to adapter registry scanning if the path isn't provided.
|
|
2443
|
-
*/
|
|
2444
|
-
getAllTurnsWithSource(sessionId, transcriptPath) {
|
|
2445
|
-
if (transcriptPath) {
|
|
2446
|
-
const result2 = this.registry.parseTurnsFromPath(transcriptPath);
|
|
2447
|
-
if (result2) return result2;
|
|
2448
|
-
}
|
|
2449
|
-
const result = this.registry.getTranscriptTurns(sessionId);
|
|
2450
|
-
if (result) return result;
|
|
2451
|
-
return { turns: [], source: "none" };
|
|
2452
|
-
}
|
|
2453
|
-
};
|
|
2454
|
-
function extractTurnsFromBuffer(events) {
|
|
2455
|
-
const turns = [];
|
|
2456
|
-
let current = null;
|
|
2457
|
-
for (const event of events) {
|
|
2458
|
-
const type = event.type;
|
|
2459
|
-
if (type === "user_prompt") {
|
|
2460
|
-
if (current) turns.push(current);
|
|
2461
|
-
current = {
|
|
2462
|
-
prompt: String(event.prompt ?? "").slice(0, PROMPT_PREVIEW_CHARS),
|
|
2463
|
-
toolCount: 0,
|
|
2464
|
-
timestamp: String(event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString())
|
|
2465
|
-
};
|
|
2466
|
-
} else if (type === "tool_use") {
|
|
2467
|
-
if (current) current.toolCount++;
|
|
2468
|
-
}
|
|
2469
|
-
}
|
|
2470
|
-
if (current) turns.push(current);
|
|
2471
|
-
return turns;
|
|
2472
|
-
}
|
|
2473
|
-
|
|
2474
|
-
// src/vault/observations.ts
|
|
2475
|
-
function writeObservationNotes(observations, sessionId, writer, index, vaultDir) {
|
|
2476
|
-
const results = [];
|
|
2477
|
-
for (const obs of observations) {
|
|
2478
|
-
const obsId = `${obs.type}-${sessionId.slice(-6)}-${Date.now()}`;
|
|
2479
|
-
const body = formatMemoryBody({
|
|
2480
|
-
title: obs.title,
|
|
2481
|
-
observationType: obs.type,
|
|
2482
|
-
content: obs.content,
|
|
2483
|
-
sessionId,
|
|
2484
|
-
root_cause: obs.root_cause,
|
|
2485
|
-
fix: obs.fix,
|
|
2486
|
-
rationale: obs.rationale,
|
|
2487
|
-
alternatives_rejected: obs.alternatives_rejected,
|
|
2488
|
-
gained: obs.gained,
|
|
2489
|
-
sacrificed: obs.sacrificed,
|
|
2490
|
-
tags: obs.tags
|
|
2491
|
-
});
|
|
2492
|
-
const relativePath = writer.writeMemory({
|
|
2493
|
-
id: obsId,
|
|
2494
|
-
observation_type: obs.type,
|
|
2495
|
-
session: sessionNoteId(sessionId),
|
|
2496
|
-
tags: obs.tags,
|
|
2497
|
-
content: body
|
|
2498
|
-
});
|
|
2499
|
-
indexNote(index, vaultDir, relativePath);
|
|
2500
|
-
results.push({ id: obsId, path: relativePath, observation: obs });
|
|
2501
|
-
}
|
|
2502
|
-
return results;
|
|
2503
|
-
}
|
|
2504
|
-
|
|
2505
2189
|
// src/artifacts/candidates.ts
|
|
2506
2190
|
import { execFileSync } from "child_process";
|
|
2507
|
-
import
|
|
2508
|
-
import
|
|
2191
|
+
import fs3 from "fs";
|
|
2192
|
+
import path4 from "path";
|
|
2509
2193
|
var EXCLUDED_FILENAMES = /* @__PURE__ */ new Set([
|
|
2510
2194
|
"claude.md",
|
|
2511
2195
|
"agents.md",
|
|
@@ -2526,7 +2210,7 @@ var EXCLUDED_PREFIXES = [
|
|
|
2526
2210
|
".github/"
|
|
2527
2211
|
];
|
|
2528
2212
|
function isExcludedPath(relativePath) {
|
|
2529
|
-
const basename3 =
|
|
2213
|
+
const basename3 = path4.basename(relativePath).toLowerCase();
|
|
2530
2214
|
if (EXCLUDED_FILENAMES.has(basename3)) return true;
|
|
2531
2215
|
const normalized = relativePath.replace(/\\/g, "/");
|
|
2532
2216
|
return EXCLUDED_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
|
@@ -2534,7 +2218,7 @@ function isExcludedPath(relativePath) {
|
|
|
2534
2218
|
function collectArtifactCandidates(filePaths, config, projectRoot) {
|
|
2535
2219
|
if (filePaths.size === 0) return [];
|
|
2536
2220
|
const extFiltered = [...filePaths].filter(
|
|
2537
|
-
(absPath) => config.artifact_extensions.includes(
|
|
2221
|
+
(absPath) => config.artifact_extensions.includes(path4.extname(absPath))
|
|
2538
2222
|
);
|
|
2539
2223
|
if (extFiltered.length === 0) return [];
|
|
2540
2224
|
const ignoredSet = getGitIgnored(extFiltered, projectRoot);
|
|
@@ -2542,8 +2226,8 @@ function collectArtifactCandidates(filePaths, config, projectRoot) {
|
|
|
2542
2226
|
for (const absPath of extFiltered) {
|
|
2543
2227
|
if (ignoredSet.has(absPath)) continue;
|
|
2544
2228
|
try {
|
|
2545
|
-
const content =
|
|
2546
|
-
const relativePath =
|
|
2229
|
+
const content = fs3.readFileSync(absPath, "utf-8");
|
|
2230
|
+
const relativePath = path4.relative(projectRoot, absPath);
|
|
2547
2231
|
if (isExcludedPath(relativePath)) continue;
|
|
2548
2232
|
candidates.push({ path: relativePath, content });
|
|
2549
2233
|
} catch {
|
|
@@ -2566,9 +2250,9 @@ function getGitIgnored(filePaths, cwd) {
|
|
|
2566
2250
|
|
|
2567
2251
|
// src/artifacts/slugify.ts
|
|
2568
2252
|
import crypto from "crypto";
|
|
2569
|
-
import
|
|
2253
|
+
import path5 from "path";
|
|
2570
2254
|
function slugifyPath(relativePath) {
|
|
2571
|
-
const ext =
|
|
2255
|
+
const ext = path5.extname(relativePath);
|
|
2572
2256
|
const withoutExt = ext ? relativePath.slice(0, -ext.length) : relativePath;
|
|
2573
2257
|
let slug = withoutExt.replace(/[/\\]/g, "-").toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
2574
2258
|
if (slug.length > MAX_SLUG_LENGTH) {
|
|
@@ -2580,8 +2264,8 @@ function slugifyPath(relativePath) {
|
|
|
2580
2264
|
|
|
2581
2265
|
// src/daemon/main.ts
|
|
2582
2266
|
var import_yaml = __toESM(require_dist(), 1);
|
|
2583
|
-
import
|
|
2584
|
-
import
|
|
2267
|
+
import fs4 from "fs";
|
|
2268
|
+
import path6 from "path";
|
|
2585
2269
|
function indexAndEmbed(relativePath, noteId, embeddingText, metadata, deps) {
|
|
2586
2270
|
indexNote(deps.index, deps.vaultDir, relativePath);
|
|
2587
2271
|
if (deps.vectorIndex && embeddingText) {
|
|
@@ -2634,28 +2318,28 @@ ${candidate.content}`,
|
|
|
2634
2318
|
}
|
|
2635
2319
|
}
|
|
2636
2320
|
function migrateMemoryFiles(vaultDir) {
|
|
2637
|
-
const memoriesDir =
|
|
2638
|
-
if (!
|
|
2321
|
+
const memoriesDir = path6.join(vaultDir, "memories");
|
|
2322
|
+
if (!fs4.existsSync(memoriesDir)) return 0;
|
|
2639
2323
|
let moved = 0;
|
|
2640
|
-
const entries =
|
|
2324
|
+
const entries = fs4.readdirSync(memoriesDir);
|
|
2641
2325
|
for (const entry of entries) {
|
|
2642
|
-
const fullPath =
|
|
2326
|
+
const fullPath = path6.join(memoriesDir, entry);
|
|
2643
2327
|
if (!entry.endsWith(".md")) continue;
|
|
2644
|
-
if (
|
|
2328
|
+
if (fs4.statSync(fullPath).isDirectory()) continue;
|
|
2645
2329
|
try {
|
|
2646
|
-
const content =
|
|
2330
|
+
const content = fs4.readFileSync(fullPath, "utf-8");
|
|
2647
2331
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2648
2332
|
if (!fmMatch) continue;
|
|
2649
2333
|
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
2650
2334
|
const obsType = parsed.observation_type;
|
|
2651
2335
|
if (!obsType) continue;
|
|
2652
2336
|
const normalizedType = obsType.replace(/_/g, "-");
|
|
2653
|
-
const targetDir =
|
|
2654
|
-
|
|
2655
|
-
const targetPath =
|
|
2656
|
-
|
|
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);
|
|
2657
2341
|
const now = /* @__PURE__ */ new Date();
|
|
2658
|
-
|
|
2342
|
+
fs4.utimesSync(targetPath, now, now);
|
|
2659
2343
|
moved++;
|
|
2660
2344
|
} catch {
|
|
2661
2345
|
}
|
|
@@ -2668,9 +2352,9 @@ async function main() {
|
|
|
2668
2352
|
process.stderr.write("Usage: mycod --vault <path>\n");
|
|
2669
2353
|
process.exit(1);
|
|
2670
2354
|
}
|
|
2671
|
-
const vaultDir =
|
|
2355
|
+
const vaultDir = path6.resolve(vaultArg);
|
|
2672
2356
|
const config = loadConfig(vaultDir);
|
|
2673
|
-
const logger = new DaemonLogger(
|
|
2357
|
+
const logger = new DaemonLogger(path6.join(vaultDir, "logs"), {
|
|
2674
2358
|
level: config.daemon.log_level,
|
|
2675
2359
|
maxSize: config.daemon.max_log_size
|
|
2676
2360
|
});
|
|
@@ -2692,14 +2376,14 @@ async function main() {
|
|
|
2692
2376
|
let vectorIndex = null;
|
|
2693
2377
|
try {
|
|
2694
2378
|
const testEmbed = await embeddingProvider.embed("test");
|
|
2695
|
-
vectorIndex = new VectorIndex(
|
|
2379
|
+
vectorIndex = new VectorIndex(path6.join(vaultDir, "vectors.db"), testEmbed.dimensions);
|
|
2696
2380
|
logger.info("embeddings", "Vector index initialized", { dimensions: testEmbed.dimensions });
|
|
2697
2381
|
} catch (error) {
|
|
2698
2382
|
logger.warn("embeddings", "Vector index unavailable", { error: error.message });
|
|
2699
2383
|
}
|
|
2700
2384
|
const processor = new BufferProcessor(llmProvider, config.intelligence.llm.context_window);
|
|
2701
2385
|
const vault = new VaultWriter(vaultDir);
|
|
2702
|
-
const index = new MycoIndex(
|
|
2386
|
+
const index = new MycoIndex(path6.join(vaultDir, "index.db"));
|
|
2703
2387
|
const lineageGraph = new LineageGraph(vaultDir);
|
|
2704
2388
|
const transcriptMiner = new TranscriptMiner({
|
|
2705
2389
|
additionalAdapters: config.capture.transcript_paths.map(
|
|
@@ -2708,17 +2392,17 @@ async function main() {
|
|
|
2708
2392
|
});
|
|
2709
2393
|
let activeStopProcessing = null;
|
|
2710
2394
|
const indexDeps = { index, vaultDir, vectorIndex, embeddingProvider, logger };
|
|
2711
|
-
const bufferDir =
|
|
2395
|
+
const bufferDir = path6.join(vaultDir, "buffer");
|
|
2712
2396
|
const sessionBuffers = /* @__PURE__ */ new Map();
|
|
2713
2397
|
const sessionFilePaths = /* @__PURE__ */ new Map();
|
|
2714
2398
|
const capturedArtifactPaths = /* @__PURE__ */ new Map();
|
|
2715
|
-
if (
|
|
2399
|
+
if (fs4.existsSync(bufferDir)) {
|
|
2716
2400
|
const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
|
|
2717
|
-
for (const file of
|
|
2718
|
-
const filePath =
|
|
2719
|
-
const stat4 =
|
|
2401
|
+
for (const file of fs4.readdirSync(bufferDir)) {
|
|
2402
|
+
const filePath = path6.join(bufferDir, file);
|
|
2403
|
+
const stat4 = fs4.statSync(filePath);
|
|
2720
2404
|
if (stat4.mtimeMs < cutoff) {
|
|
2721
|
-
|
|
2405
|
+
fs4.unlinkSync(filePath);
|
|
2722
2406
|
logger.debug("daemon", "Cleaned stale buffer", { file });
|
|
2723
2407
|
}
|
|
2724
2408
|
}
|
|
@@ -2754,10 +2438,10 @@ async function main() {
|
|
|
2754
2438
|
logger.info("watcher", "Plan detected", { source: event.source, file: event.filePath });
|
|
2755
2439
|
if (event.filePath) {
|
|
2756
2440
|
try {
|
|
2757
|
-
const content =
|
|
2758
|
-
const relativePath =
|
|
2759
|
-
const title = content.match(/^#\s+(.+)$/m)?.[1] ??
|
|
2760
|
-
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")}`;
|
|
2761
2445
|
indexAndEmbed(
|
|
2762
2446
|
relativePath,
|
|
2763
2447
|
planId,
|
|
@@ -2808,7 +2492,7 @@ ${content}`,
|
|
|
2808
2492
|
}
|
|
2809
2493
|
const captured = capturedArtifactPaths.get(sessionId);
|
|
2810
2494
|
for (const c of candidates) {
|
|
2811
|
-
const absPath =
|
|
2495
|
+
const absPath = path6.resolve(process.cwd(), c.path);
|
|
2812
2496
|
captured.add(absPath);
|
|
2813
2497
|
}
|
|
2814
2498
|
}).catch((err) => logger.warn("processor", "Incremental artifact capture failed", {
|
|
@@ -2847,14 +2531,14 @@ ${content}`,
|
|
|
2847
2531
|
registry.unregister(session_id);
|
|
2848
2532
|
try {
|
|
2849
2533
|
const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
|
|
2850
|
-
for (const file of
|
|
2534
|
+
for (const file of fs4.readdirSync(bufferDir)) {
|
|
2851
2535
|
if (!file.endsWith(".jsonl")) continue;
|
|
2852
2536
|
const bufferSessionId = file.replace(".jsonl", "");
|
|
2853
2537
|
if (bufferSessionId === session_id) continue;
|
|
2854
|
-
const filePath =
|
|
2855
|
-
const stat4 =
|
|
2538
|
+
const filePath = path6.join(bufferDir, file);
|
|
2539
|
+
const stat4 = fs4.statSync(filePath);
|
|
2856
2540
|
if (stat4.mtimeMs < cutoff) {
|
|
2857
|
-
|
|
2541
|
+
fs4.unlinkSync(filePath);
|
|
2858
2542
|
logger.debug("daemon", "Cleaned stale buffer", { file });
|
|
2859
2543
|
}
|
|
2860
2544
|
}
|
|
@@ -2949,15 +2633,15 @@ ${content}`,
|
|
|
2949
2633
|
}
|
|
2950
2634
|
const ended = (/* @__PURE__ */ new Date()).toISOString();
|
|
2951
2635
|
let started = allTurns.length > 0 && allTurns[0].timestamp ? allTurns[0].timestamp : ended;
|
|
2952
|
-
const sessionsDir =
|
|
2636
|
+
const sessionsDir = path6.join(vaultDir, "sessions");
|
|
2953
2637
|
const sessionFileName = `${sessionNoteId(sessionId)}.md`;
|
|
2954
2638
|
let existingContent;
|
|
2955
2639
|
const duplicatePaths = [];
|
|
2956
2640
|
try {
|
|
2957
|
-
for (const dateDir of
|
|
2958
|
-
const candidate =
|
|
2641
|
+
for (const dateDir of fs4.readdirSync(sessionsDir)) {
|
|
2642
|
+
const candidate = path6.join(sessionsDir, dateDir, sessionFileName);
|
|
2959
2643
|
try {
|
|
2960
|
-
const content =
|
|
2644
|
+
const content = fs4.readFileSync(candidate, "utf-8");
|
|
2961
2645
|
if (!existingContent || content.length > existingContent.length) {
|
|
2962
2646
|
existingContent = content;
|
|
2963
2647
|
}
|
|
@@ -3017,20 +2701,20 @@ ${conversationText}`;
|
|
|
3017
2701
|
}
|
|
3018
2702
|
const date = started.slice(0, 10);
|
|
3019
2703
|
const relativePath = sessionRelativePath(sessionId, date);
|
|
3020
|
-
const targetFullPath =
|
|
2704
|
+
const targetFullPath = path6.join(vaultDir, relativePath);
|
|
3021
2705
|
for (const dup of duplicatePaths) {
|
|
3022
2706
|
if (dup !== targetFullPath) {
|
|
3023
2707
|
try {
|
|
3024
|
-
|
|
2708
|
+
fs4.unlinkSync(dup);
|
|
3025
2709
|
logger.debug("lifecycle", "Removed duplicate session file", { path: dup });
|
|
3026
2710
|
} catch {
|
|
3027
2711
|
}
|
|
3028
2712
|
}
|
|
3029
2713
|
}
|
|
3030
|
-
const attachmentsDir =
|
|
2714
|
+
const attachmentsDir = path6.join(vaultDir, "attachments");
|
|
3031
2715
|
const hasImages = allTurns.some((t) => t.images?.length);
|
|
3032
2716
|
if (hasImages) {
|
|
3033
|
-
|
|
2717
|
+
fs4.mkdirSync(attachmentsDir, { recursive: true });
|
|
3034
2718
|
}
|
|
3035
2719
|
const turnImageNames = /* @__PURE__ */ new Map();
|
|
3036
2720
|
for (let i = 0; i < allTurns.length; i++) {
|
|
@@ -3041,9 +2725,9 @@ ${conversationText}`;
|
|
|
3041
2725
|
const img = turn.images[j];
|
|
3042
2726
|
const ext = extensionForMimeType(img.mediaType);
|
|
3043
2727
|
const filename = `${bareSessionId(sessionId)}-t${i + 1}-${j + 1}.${ext}`;
|
|
3044
|
-
const filePath =
|
|
3045
|
-
if (!
|
|
3046
|
-
|
|
2728
|
+
const filePath = path6.join(attachmentsDir, filename);
|
|
2729
|
+
if (!fs4.existsSync(filePath)) {
|
|
2730
|
+
fs4.writeFileSync(filePath, Buffer.from(img.data, "base64"));
|
|
3047
2731
|
logger.debug("processor", "Image saved", { filename, turn: i + 1 });
|
|
3048
2732
|
}
|
|
3049
2733
|
names.push(filename);
|
|
@@ -3256,4 +2940,4 @@ export {
|
|
|
3256
2940
|
chokidar/index.js:
|
|
3257
2941
|
(*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
|
|
3258
2942
|
*/
|
|
3259
|
-
//# sourceMappingURL=main-
|
|
2943
|
+
//# sourceMappingURL=main-D4X6XWRT.js.map
|