@qtv/anchorkit 1.2.5-beta.3.1 → 1.2.6-beta.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/dist/cli.mjs +988 -935
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -143,7 +143,7 @@ var init_debugLog = __esm(() => {
|
|
|
143
143
|
init_paths();
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
// src/vault/
|
|
146
|
+
// src/core/vault/indexing/manifests.ts
|
|
147
147
|
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync } from "node:fs";
|
|
148
148
|
import { join as join7, relative } from "node:path";
|
|
149
149
|
function detectFramework(deps, devDeps) {
|
|
@@ -336,13 +336,7 @@ var init_manifests = __esm(() => {
|
|
|
336
336
|
];
|
|
337
337
|
});
|
|
338
338
|
|
|
339
|
-
// src/vault/
|
|
340
|
-
var exports_indexer = {};
|
|
341
|
-
__export(exports_indexer, {
|
|
342
|
-
indexCodebase: () => indexCodebase,
|
|
343
|
-
countFiles: () => countFiles,
|
|
344
|
-
SKIP_DIRS: () => SKIP_DIRS
|
|
345
|
-
});
|
|
339
|
+
// src/core/vault/indexing/codebase.ts
|
|
346
340
|
import { execSync } from "node:child_process";
|
|
347
341
|
import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync as readdirSync2 } from "node:fs";
|
|
348
342
|
import { extname, join as join8 } from "node:path";
|
|
@@ -659,7 +653,7 @@ async function indexCodebase(projectRoot) {
|
|
|
659
653
|
};
|
|
660
654
|
}
|
|
661
655
|
var SKIP_DIRS, LARGE_REPO_THRESHOLD = 1e4;
|
|
662
|
-
var
|
|
656
|
+
var init_codebase = __esm(() => {
|
|
663
657
|
init_manifests();
|
|
664
658
|
SKIP_DIRS = new Set([
|
|
665
659
|
"node_modules",
|
|
@@ -681,6 +675,66 @@ var init_indexer = __esm(() => {
|
|
|
681
675
|
]);
|
|
682
676
|
});
|
|
683
677
|
|
|
678
|
+
// src/core/vault/indexing/vault-walk.ts
|
|
679
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, statSync } from "node:fs";
|
|
680
|
+
import { join as join9 } from "node:path";
|
|
681
|
+
function* walkVaultNoteFiles(vaultPath) {
|
|
682
|
+
if (!existsSync8(vaultPath))
|
|
683
|
+
return;
|
|
684
|
+
for (const folder of NOTE_FOLDERS) {
|
|
685
|
+
const dir = join9(vaultPath, folder);
|
|
686
|
+
if (!existsSync8(dir))
|
|
687
|
+
continue;
|
|
688
|
+
let entries;
|
|
689
|
+
try {
|
|
690
|
+
entries = readdirSync3(dir);
|
|
691
|
+
} catch {
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
for (const name of entries) {
|
|
695
|
+
if (!name.endsWith(".md"))
|
|
696
|
+
continue;
|
|
697
|
+
if (name.startsWith("_"))
|
|
698
|
+
continue;
|
|
699
|
+
const abs = join9(dir, name);
|
|
700
|
+
try {
|
|
701
|
+
if (!statSync(abs).isFile())
|
|
702
|
+
continue;
|
|
703
|
+
} catch {
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
yield { folder, abs };
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
var NOTE_FOLDERS;
|
|
711
|
+
var init_vault_walk = __esm(() => {
|
|
712
|
+
NOTE_FOLDERS = [
|
|
713
|
+
"knowledge",
|
|
714
|
+
"maps",
|
|
715
|
+
"decisions",
|
|
716
|
+
"flows",
|
|
717
|
+
"incidents",
|
|
718
|
+
"archive"
|
|
719
|
+
];
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// src/core/vault/indexing/index.ts
|
|
723
|
+
var exports_indexing = {};
|
|
724
|
+
__export(exports_indexing, {
|
|
725
|
+
walkVaultNoteFiles: () => walkVaultNoteFiles,
|
|
726
|
+
indexCodebase: () => indexCodebase,
|
|
727
|
+
detectManifests: () => detectManifests,
|
|
728
|
+
countFiles: () => countFiles,
|
|
729
|
+
SKIP_DIRS: () => SKIP_DIRS,
|
|
730
|
+
NOTE_FOLDERS: () => NOTE_FOLDERS
|
|
731
|
+
});
|
|
732
|
+
var init_indexing = __esm(() => {
|
|
733
|
+
init_codebase();
|
|
734
|
+
init_manifests();
|
|
735
|
+
init_vault_walk();
|
|
736
|
+
});
|
|
737
|
+
|
|
684
738
|
// src/vault/mapper/analyze/edges.ts
|
|
685
739
|
import path from "node:path";
|
|
686
740
|
function buildEdges(candidates, importsByModule) {
|
|
@@ -826,8 +880,8 @@ var init_buildEdges = __esm(() => {
|
|
|
826
880
|
});
|
|
827
881
|
|
|
828
882
|
// src/vault/mapper/discover/enumerate.ts
|
|
829
|
-
import { readdirSync as
|
|
830
|
-
import { dirname as dirname5, extname as extname2, join as
|
|
883
|
+
import { readdirSync as readdirSync4 } from "node:fs";
|
|
884
|
+
import { dirname as dirname5, extname as extname2, join as join10, relative as relative2 } from "node:path";
|
|
831
885
|
function toCandidate(dir, files, sourceRoot, repoRoot) {
|
|
832
886
|
const rel = relative2(sourceRoot, dir);
|
|
833
887
|
const slug = rel ? toKebab(rel) : toKebab(relative2(repoRoot, dir));
|
|
@@ -868,14 +922,14 @@ function collectFilesViaFsWalk(sourceRoot) {
|
|
|
868
922
|
function walk(dir, acc) {
|
|
869
923
|
let entries;
|
|
870
924
|
try {
|
|
871
|
-
entries =
|
|
925
|
+
entries = readdirSync4(dir, { withFileTypes: true });
|
|
872
926
|
} catch {
|
|
873
927
|
return;
|
|
874
928
|
}
|
|
875
929
|
for (const entry of entries) {
|
|
876
930
|
if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
|
|
877
931
|
continue;
|
|
878
|
-
const full =
|
|
932
|
+
const full = join10(dir, entry.name);
|
|
879
933
|
if (entry.isDirectory()) {
|
|
880
934
|
walk(full, acc);
|
|
881
935
|
} else if (SOURCE_EXTS.has(extname2(entry.name).toLowerCase())) {
|
|
@@ -889,7 +943,7 @@ function toKebab(relPath) {
|
|
|
889
943
|
}
|
|
890
944
|
var SOURCE_EXTS;
|
|
891
945
|
var init_enumerate = __esm(() => {
|
|
892
|
-
|
|
946
|
+
init_indexing();
|
|
893
947
|
SOURCE_EXTS = new Set([
|
|
894
948
|
".ts",
|
|
895
949
|
".tsx",
|
|
@@ -913,8 +967,8 @@ var init_enumerate = __esm(() => {
|
|
|
913
967
|
});
|
|
914
968
|
|
|
915
969
|
// src/vault/mapper/discover/sourceRoot.ts
|
|
916
|
-
import { existsSync as
|
|
917
|
-
import { join as
|
|
970
|
+
import { existsSync as existsSync9, readFileSync as readFileSync6, readdirSync as readdirSync5 } from "node:fs";
|
|
971
|
+
import { join as join11, resolve } from "node:path";
|
|
918
972
|
function resolveSourceRoot(repoRoot, indexResult) {
|
|
919
973
|
const abs = resolve(repoRoot);
|
|
920
974
|
if (indexResult.structure.isMonorepo && indexResult.structure.workspaces?.length) {
|
|
@@ -927,18 +981,18 @@ function resolveSingleRoot(repoRoot) {
|
|
|
927
981
|
const fromTsconfig = readTsconfigRoot(repoRoot);
|
|
928
982
|
if (fromTsconfig) {
|
|
929
983
|
const candidate = resolve(repoRoot, fromTsconfig);
|
|
930
|
-
if (
|
|
984
|
+
if (existsSync9(candidate))
|
|
931
985
|
return candidate;
|
|
932
986
|
}
|
|
933
|
-
if (
|
|
934
|
-
return
|
|
935
|
-
if (
|
|
936
|
-
return
|
|
987
|
+
if (existsSync9(join11(repoRoot, "src")))
|
|
988
|
+
return join11(repoRoot, "src");
|
|
989
|
+
if (existsSync9(join11(repoRoot, "lib")))
|
|
990
|
+
return join11(repoRoot, "lib");
|
|
937
991
|
return repoRoot;
|
|
938
992
|
}
|
|
939
993
|
function readTsconfigRoot(repoRoot) {
|
|
940
|
-
const tsconfigPath =
|
|
941
|
-
if (!
|
|
994
|
+
const tsconfigPath = join11(repoRoot, "tsconfig.json");
|
|
995
|
+
if (!existsSync9(tsconfigPath))
|
|
942
996
|
return null;
|
|
943
997
|
try {
|
|
944
998
|
const raw = readFileSync6(tsconfigPath, "utf-8");
|
|
@@ -962,21 +1016,21 @@ function resolveMonorepoRoots(repoRoot, workspaceGlobs) {
|
|
|
962
1016
|
for (const glob of workspaceGlobs) {
|
|
963
1017
|
if (glob.endsWith("/*") || glob.endsWith("/**/")) {
|
|
964
1018
|
const base = glob.replace(/\/?\*\*?\/?$/, "");
|
|
965
|
-
const baseDir =
|
|
966
|
-
if (!
|
|
1019
|
+
const baseDir = join11(repoRoot, base);
|
|
1020
|
+
if (!existsSync9(baseDir))
|
|
967
1021
|
continue;
|
|
968
1022
|
try {
|
|
969
|
-
const entries =
|
|
1023
|
+
const entries = readdirSync5(baseDir, { withFileTypes: true });
|
|
970
1024
|
for (const entry of entries) {
|
|
971
1025
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
972
1026
|
continue;
|
|
973
|
-
const wsRoot =
|
|
1027
|
+
const wsRoot = join11(baseDir, entry.name);
|
|
974
1028
|
roots.push(resolveSingleRoot(wsRoot));
|
|
975
1029
|
}
|
|
976
1030
|
} catch {}
|
|
977
1031
|
} else {
|
|
978
|
-
const wsRoot =
|
|
979
|
-
if (
|
|
1032
|
+
const wsRoot = join11(repoRoot, glob);
|
|
1033
|
+
if (existsSync9(wsRoot)) {
|
|
980
1034
|
roots.push(resolveSingleRoot(wsRoot));
|
|
981
1035
|
}
|
|
982
1036
|
}
|
|
@@ -8436,23 +8490,15 @@ var init_dist = __esm(() => {
|
|
|
8436
8490
|
});
|
|
8437
8491
|
|
|
8438
8492
|
// src/vault/internal/utils.ts
|
|
8439
|
-
import {
|
|
8440
|
-
appendFileSync as appendFileSync2,
|
|
8441
|
-
existsSync as existsSync9,
|
|
8442
|
-
mkdirSync as mkdirSync4,
|
|
8443
|
-
readFileSync as readFileSync7,
|
|
8444
|
-
readdirSync as readdirSync5,
|
|
8445
|
-
statSync,
|
|
8446
|
-
writeFileSync as writeFileSync3
|
|
8447
|
-
} from "node:fs";
|
|
8493
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
8448
8494
|
import { homedir as homedir5 } from "node:os";
|
|
8449
|
-
import { dirname as dirname7, join as
|
|
8495
|
+
import { dirname as dirname7, join as join12, resolve as resolve2 } from "node:path";
|
|
8450
8496
|
function errorMessage(e) {
|
|
8451
8497
|
return e instanceof Error ? e.message : String(e);
|
|
8452
8498
|
}
|
|
8453
8499
|
function vaultDebugLogPath() {
|
|
8454
|
-
const home = process.env.ANCHORKIT_TEST_HOME ??
|
|
8455
|
-
return
|
|
8500
|
+
const home = process.env.ANCHORKIT_TEST_HOME ?? join12(homedir5(), ".anchorkit");
|
|
8501
|
+
return join12(home, "logs", "debug.log");
|
|
8456
8502
|
}
|
|
8457
8503
|
function ensureDebugLogReady() {
|
|
8458
8504
|
if (!process.env.ANCHORKIT_DEBUG)
|
|
@@ -8480,6 +8526,67 @@ function logForDebugging(message, opts = {}) {
|
|
|
8480
8526
|
function parseYaml(input) {
|
|
8481
8527
|
return $parse(input);
|
|
8482
8528
|
}
|
|
8529
|
+
async function runWithLimit(tasks, limit) {
|
|
8530
|
+
const results = new Array(tasks.length);
|
|
8531
|
+
let next = 0;
|
|
8532
|
+
async function worker() {
|
|
8533
|
+
while (next < tasks.length) {
|
|
8534
|
+
const idx = next++;
|
|
8535
|
+
try {
|
|
8536
|
+
const value = await tasks[idx]?.();
|
|
8537
|
+
results[idx] = { status: "fulfilled", value };
|
|
8538
|
+
} catch (reason) {
|
|
8539
|
+
results[idx] = { status: "rejected", reason };
|
|
8540
|
+
}
|
|
8541
|
+
}
|
|
8542
|
+
}
|
|
8543
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());
|
|
8544
|
+
await Promise.all(workers);
|
|
8545
|
+
return results;
|
|
8546
|
+
}
|
|
8547
|
+
function findGitRoot(startDir = process.cwd()) {
|
|
8548
|
+
let dir = resolve2(startDir);
|
|
8549
|
+
while (true) {
|
|
8550
|
+
if (existsSync10(join12(dir, ".git")))
|
|
8551
|
+
return dir;
|
|
8552
|
+
const parent = dirname7(dir);
|
|
8553
|
+
if (parent === dir)
|
|
8554
|
+
return null;
|
|
8555
|
+
dir = parent;
|
|
8556
|
+
}
|
|
8557
|
+
}
|
|
8558
|
+
function ensureIgnored(repoRoot, pattern) {
|
|
8559
|
+
const gitignorePath = join12(repoRoot, ".gitignore");
|
|
8560
|
+
const norm = (p) => p.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
8561
|
+
const normalizedTarget = norm(pattern);
|
|
8562
|
+
if (!existsSync10(gitignorePath)) {
|
|
8563
|
+
mkdirSync4(dirname7(gitignorePath), { recursive: true });
|
|
8564
|
+
writeFileSync3(gitignorePath, `${pattern}
|
|
8565
|
+
`, "utf-8");
|
|
8566
|
+
return { added: true };
|
|
8567
|
+
}
|
|
8568
|
+
const content = readFileSync7(gitignorePath, "utf-8");
|
|
8569
|
+
const lines = content.split(/\r?\n/);
|
|
8570
|
+
for (const line of lines) {
|
|
8571
|
+
if (norm(line) === normalizedTarget)
|
|
8572
|
+
return { added: false };
|
|
8573
|
+
}
|
|
8574
|
+
const needsLeadingEol = content.length > 0 && !content.endsWith(`
|
|
8575
|
+
`);
|
|
8576
|
+
const eol = content.includes(`\r
|
|
8577
|
+
`) ? `\r
|
|
8578
|
+
` : `
|
|
8579
|
+
`;
|
|
8580
|
+
const prefix = needsLeadingEol ? eol : "";
|
|
8581
|
+
writeFileSync3(gitignorePath, content + prefix + pattern + eol, "utf-8");
|
|
8582
|
+
return { added: true };
|
|
8583
|
+
}
|
|
8584
|
+
var debugLogReady = null;
|
|
8585
|
+
var init_utils = __esm(() => {
|
|
8586
|
+
init_dist();
|
|
8587
|
+
});
|
|
8588
|
+
|
|
8589
|
+
// src/core/vault/conventions/frontmatter.ts
|
|
8483
8590
|
function quoteProblematicValues(frontmatterText) {
|
|
8484
8591
|
const lines = frontmatterText.split(`
|
|
8485
8592
|
`);
|
|
@@ -8516,14 +8623,14 @@ function parseFrontmatter(markdown, sourcePath) {
|
|
|
8516
8623
|
const content = markdown.slice(match[0].length);
|
|
8517
8624
|
let frontmatter = {};
|
|
8518
8625
|
try {
|
|
8519
|
-
const parsed =
|
|
8626
|
+
const parsed = $parse(frontmatterText);
|
|
8520
8627
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8521
8628
|
frontmatter = parsed;
|
|
8522
8629
|
}
|
|
8523
8630
|
} catch {
|
|
8524
8631
|
try {
|
|
8525
8632
|
const quoted = quoteProblematicValues(frontmatterText);
|
|
8526
|
-
const parsed =
|
|
8633
|
+
const parsed = $parse(quoted);
|
|
8527
8634
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8528
8635
|
frontmatter = parsed;
|
|
8529
8636
|
}
|
|
@@ -8556,93 +8663,10 @@ function serializeFrontmatter(fm) {
|
|
|
8556
8663
|
${body}---
|
|
8557
8664
|
`;
|
|
8558
8665
|
}
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
let next = 0;
|
|
8562
|
-
async function worker() {
|
|
8563
|
-
while (next < tasks.length) {
|
|
8564
|
-
const idx = next++;
|
|
8565
|
-
try {
|
|
8566
|
-
const value = await tasks[idx]?.();
|
|
8567
|
-
results[idx] = { status: "fulfilled", value };
|
|
8568
|
-
} catch (reason) {
|
|
8569
|
-
results[idx] = { status: "rejected", reason };
|
|
8570
|
-
}
|
|
8571
|
-
}
|
|
8572
|
-
}
|
|
8573
|
-
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());
|
|
8574
|
-
await Promise.all(workers);
|
|
8575
|
-
return results;
|
|
8576
|
-
}
|
|
8577
|
-
function findGitRoot(startDir = process.cwd()) {
|
|
8578
|
-
let dir = resolve2(startDir);
|
|
8579
|
-
while (true) {
|
|
8580
|
-
if (existsSync9(join11(dir, ".git")))
|
|
8581
|
-
return dir;
|
|
8582
|
-
const parent = dirname7(dir);
|
|
8583
|
-
if (parent === dir)
|
|
8584
|
-
return null;
|
|
8585
|
-
dir = parent;
|
|
8586
|
-
}
|
|
8587
|
-
}
|
|
8588
|
-
function ensureIgnored(repoRoot, pattern) {
|
|
8589
|
-
const gitignorePath = join11(repoRoot, ".gitignore");
|
|
8590
|
-
const norm = (p) => p.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
8591
|
-
const normalizedTarget = norm(pattern);
|
|
8592
|
-
if (!existsSync9(gitignorePath)) {
|
|
8593
|
-
mkdirSync4(dirname7(gitignorePath), { recursive: true });
|
|
8594
|
-
writeFileSync3(gitignorePath, `${pattern}
|
|
8595
|
-
`, "utf-8");
|
|
8596
|
-
return { added: true };
|
|
8597
|
-
}
|
|
8598
|
-
const content = readFileSync7(gitignorePath, "utf-8");
|
|
8599
|
-
const lines = content.split(/\r?\n/);
|
|
8600
|
-
for (const line of lines) {
|
|
8601
|
-
if (norm(line) === normalizedTarget)
|
|
8602
|
-
return { added: false };
|
|
8603
|
-
}
|
|
8604
|
-
const needsLeadingEol = content.length > 0 && !content.endsWith(`
|
|
8605
|
-
`);
|
|
8606
|
-
const eol = content.includes(`\r
|
|
8607
|
-
`) ? `\r
|
|
8608
|
-
` : `
|
|
8609
|
-
`;
|
|
8610
|
-
const prefix = needsLeadingEol ? eol : "";
|
|
8611
|
-
writeFileSync3(gitignorePath, content + prefix + pattern + eol, "utf-8");
|
|
8612
|
-
return { added: true };
|
|
8613
|
-
}
|
|
8614
|
-
function* walkVaultNoteFiles(vaultPath) {
|
|
8615
|
-
if (!existsSync9(vaultPath))
|
|
8616
|
-
return;
|
|
8617
|
-
for (const folder of NOTE_FOLDERS) {
|
|
8618
|
-
const dir = join11(vaultPath, folder);
|
|
8619
|
-
if (!existsSync9(dir))
|
|
8620
|
-
continue;
|
|
8621
|
-
let entries;
|
|
8622
|
-
try {
|
|
8623
|
-
entries = readdirSync5(dir);
|
|
8624
|
-
} catch {
|
|
8625
|
-
continue;
|
|
8626
|
-
}
|
|
8627
|
-
for (const name of entries) {
|
|
8628
|
-
if (!name.endsWith(".md"))
|
|
8629
|
-
continue;
|
|
8630
|
-
if (name.startsWith("_"))
|
|
8631
|
-
continue;
|
|
8632
|
-
const abs = join11(dir, name);
|
|
8633
|
-
try {
|
|
8634
|
-
if (!statSync(abs).isFile())
|
|
8635
|
-
continue;
|
|
8636
|
-
} catch {
|
|
8637
|
-
continue;
|
|
8638
|
-
}
|
|
8639
|
-
yield { folder, abs };
|
|
8640
|
-
}
|
|
8641
|
-
}
|
|
8642
|
-
}
|
|
8643
|
-
var debugLogReady = null, FRONTMATTER_REGEX, YAML_SPECIAL_CHARS, FRONTMATTER_FIELD_ORDER, NOTE_FOLDERS;
|
|
8644
|
-
var init_utils = __esm(() => {
|
|
8666
|
+
var FRONTMATTER_REGEX, YAML_SPECIAL_CHARS, FRONTMATTER_FIELD_ORDER;
|
|
8667
|
+
var init_frontmatter = __esm(() => {
|
|
8645
8668
|
init_dist();
|
|
8669
|
+
init_utils();
|
|
8646
8670
|
FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)---\s*\n?/;
|
|
8647
8671
|
YAML_SPECIAL_CHARS = /[{}[\]*&#!|>%@`]|: /;
|
|
8648
8672
|
FRONTMATTER_FIELD_ORDER = [
|
|
@@ -8678,14 +8702,6 @@ var init_utils = __esm(() => {
|
|
|
8678
8702
|
"affected_modules",
|
|
8679
8703
|
"source"
|
|
8680
8704
|
];
|
|
8681
|
-
NOTE_FOLDERS = [
|
|
8682
|
-
"knowledge",
|
|
8683
|
-
"maps",
|
|
8684
|
-
"decisions",
|
|
8685
|
-
"flows",
|
|
8686
|
-
"incidents",
|
|
8687
|
-
"archive"
|
|
8688
|
-
];
|
|
8689
8705
|
});
|
|
8690
8706
|
|
|
8691
8707
|
// src/core/vault/conventions/parser.ts
|
|
@@ -9081,15 +9097,16 @@ var init_validator = __esm(() => {
|
|
|
9081
9097
|
// src/core/vault/conventions/index.ts
|
|
9082
9098
|
var init_conventions = __esm(() => {
|
|
9083
9099
|
init_defaults();
|
|
9100
|
+
init_frontmatter();
|
|
9084
9101
|
init_parser();
|
|
9085
9102
|
init_validator();
|
|
9086
9103
|
});
|
|
9087
9104
|
|
|
9088
9105
|
// src/core/vault/storage/writer.ts
|
|
9089
9106
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
9090
|
-
import { dirname as dirname8, join as
|
|
9107
|
+
import { dirname as dirname8, join as join13 } from "node:path";
|
|
9091
9108
|
function writeVaultDoc(vaultPath, doc) {
|
|
9092
|
-
const filePath =
|
|
9109
|
+
const filePath = join13(vaultPath, doc.filename);
|
|
9093
9110
|
mkdirSync5(dirname8(filePath), { recursive: true });
|
|
9094
9111
|
const fullContent = `# ${doc.title}
|
|
9095
9112
|
|
|
@@ -9116,22 +9133,22 @@ function writeVaultDocs(vaultPath, projectName, docs) {
|
|
|
9116
9133
|
""
|
|
9117
9134
|
].join(`
|
|
9118
9135
|
`);
|
|
9119
|
-
const indexPath =
|
|
9136
|
+
const indexPath = join13(vaultPath, "index.md");
|
|
9120
9137
|
mkdirSync5(vaultPath, { recursive: true });
|
|
9121
9138
|
writeFileSync4(indexPath, indexContent, "utf-8");
|
|
9122
9139
|
writtenFiles.push("index.md");
|
|
9123
9140
|
return writtenFiles;
|
|
9124
9141
|
}
|
|
9125
9142
|
function writeVaultFile(vaultPath, filename, content) {
|
|
9126
|
-
const filePath =
|
|
9143
|
+
const filePath = join13(vaultPath, filename);
|
|
9127
9144
|
mkdirSync5(dirname8(filePath), { recursive: true });
|
|
9128
9145
|
writeFileSync4(filePath, content, "utf-8");
|
|
9129
9146
|
}
|
|
9130
9147
|
var init_writer = () => {};
|
|
9131
9148
|
|
|
9132
9149
|
// src/vault/escapeHatch/log.ts
|
|
9133
|
-
import { existsSync as
|
|
9134
|
-
import { join as
|
|
9150
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
|
|
9151
|
+
import { join as join14 } from "node:path";
|
|
9135
9152
|
function targetVaultPath(cfg, needs) {
|
|
9136
9153
|
if (needs.affectedVault === "global" && cfg.global) {
|
|
9137
9154
|
return cfg.global.path;
|
|
@@ -9141,8 +9158,8 @@ function targetVaultPath(cfg, needs) {
|
|
|
9141
9158
|
function appendLine(vaultPath, line) {
|
|
9142
9159
|
try {
|
|
9143
9160
|
mkdirSync6(vaultPath, { recursive: true });
|
|
9144
|
-
const logPath =
|
|
9145
|
-
if (!
|
|
9161
|
+
const logPath = join14(vaultPath, "_log.md");
|
|
9162
|
+
if (!existsSync11(logPath)) {
|
|
9146
9163
|
writeFileSync5(logPath, `# Vault log
|
|
9147
9164
|
|
|
9148
9165
|
${line}
|
|
@@ -9230,15 +9247,15 @@ var init_wikiLinkParser = __esm(() => {
|
|
|
9230
9247
|
});
|
|
9231
9248
|
|
|
9232
9249
|
// src/core/vault/storage/writeNote-helpers.ts
|
|
9233
|
-
import { existsSync as
|
|
9234
|
-
import { join as
|
|
9250
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9, readdirSync as readdirSync6, statSync as statSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
9251
|
+
import { join as join15 } from "node:path";
|
|
9235
9252
|
function appendLogEntry(vaultPath, kind, target = "") {
|
|
9236
9253
|
const ts = new Date().toISOString();
|
|
9237
9254
|
const middle = target ? ` ${target}` : "";
|
|
9238
9255
|
const line = `- ${ts} ${kind}${middle} source: code-analysis
|
|
9239
9256
|
`;
|
|
9240
|
-
const logPath =
|
|
9241
|
-
if (!
|
|
9257
|
+
const logPath = join15(vaultPath, "_log.md");
|
|
9258
|
+
if (!existsSync12(logPath)) {
|
|
9242
9259
|
writeFileSync6(logPath, `# Vault log
|
|
9243
9260
|
|
|
9244
9261
|
${line}`, "utf-8");
|
|
@@ -9252,7 +9269,7 @@ ${line}`, "utf-8");
|
|
|
9252
9269
|
}
|
|
9253
9270
|
function collectNoteBasenames(dir) {
|
|
9254
9271
|
const names = new Set;
|
|
9255
|
-
if (!
|
|
9272
|
+
if (!existsSync12(dir))
|
|
9256
9273
|
return names;
|
|
9257
9274
|
const walk = (d) => {
|
|
9258
9275
|
let entries;
|
|
@@ -9262,7 +9279,7 @@ function collectNoteBasenames(dir) {
|
|
|
9262
9279
|
return;
|
|
9263
9280
|
}
|
|
9264
9281
|
for (const entry of entries) {
|
|
9265
|
-
const p =
|
|
9282
|
+
const p = join15(d, entry);
|
|
9266
9283
|
let s;
|
|
9267
9284
|
try {
|
|
9268
9285
|
s = statSync2(p);
|
|
@@ -9282,7 +9299,7 @@ function collectNoteBasenames(dir) {
|
|
|
9282
9299
|
function collectAllNoteBasenames(vaultPath) {
|
|
9283
9300
|
const names = new Set;
|
|
9284
9301
|
for (const folder of NOTE_FOLDERS) {
|
|
9285
|
-
const folderPath =
|
|
9302
|
+
const folderPath = join15(vaultPath, folder);
|
|
9286
9303
|
for (const n of collectNoteBasenames(folderPath)) {
|
|
9287
9304
|
if (!n.startsWith("_"))
|
|
9288
9305
|
names.add(n);
|
|
@@ -9348,7 +9365,7 @@ function countIncomingLinks(vaultPath, selfFilename) {
|
|
|
9348
9365
|
return;
|
|
9349
9366
|
}
|
|
9350
9367
|
for (const entry of entries) {
|
|
9351
|
-
const p =
|
|
9368
|
+
const p = join15(d, entry);
|
|
9352
9369
|
let s;
|
|
9353
9370
|
try {
|
|
9354
9371
|
s = statSync2(p);
|
|
@@ -9367,7 +9384,7 @@ function countIncomingLinks(vaultPath, selfFilename) {
|
|
|
9367
9384
|
}
|
|
9368
9385
|
};
|
|
9369
9386
|
for (const folder of NOTE_FOLDERS) {
|
|
9370
|
-
walk(
|
|
9387
|
+
walk(join15(vaultPath, folder));
|
|
9371
9388
|
}
|
|
9372
9389
|
return count;
|
|
9373
9390
|
}
|
|
@@ -9454,18 +9471,19 @@ function checkOrphan(vaultPath, filename, relPath) {
|
|
|
9454
9471
|
var WIKILINK_RE;
|
|
9455
9472
|
var init_writeNote_helpers = __esm(() => {
|
|
9456
9473
|
init_resolver();
|
|
9457
|
-
|
|
9474
|
+
init_conventions();
|
|
9475
|
+
init_indexing();
|
|
9458
9476
|
init_wikiLinkParser();
|
|
9459
9477
|
WIKILINK_RE = /\[\[([^\]]+)\]\]/g;
|
|
9460
9478
|
});
|
|
9461
9479
|
|
|
9462
9480
|
// src/core/vault/storage/writeNote.ts
|
|
9463
|
-
import { existsSync as
|
|
9464
|
-
import { join as
|
|
9481
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
|
|
9482
|
+
import { join as join16 } from "node:path";
|
|
9465
9483
|
function loadConventions(vaultPath) {
|
|
9466
9484
|
mkdirSync8(vaultPath, { recursive: true });
|
|
9467
|
-
const conventionsPath =
|
|
9468
|
-
if (!
|
|
9485
|
+
const conventionsPath = join16(vaultPath, "_conventions.md");
|
|
9486
|
+
if (!existsSync13(conventionsPath)) {
|
|
9469
9487
|
writeFileSync7(conventionsPath, CONVENTIONS_MD_DEFAULT, "utf-8");
|
|
9470
9488
|
appendLogEntry(vaultPath, "conventions-regenerated");
|
|
9471
9489
|
}
|
|
@@ -9527,12 +9545,12 @@ var init_writeNote = __esm(() => {
|
|
|
9527
9545
|
});
|
|
9528
9546
|
|
|
9529
9547
|
// src/core/vault/storage/scaffold.ts
|
|
9530
|
-
import { existsSync as
|
|
9531
|
-
import { join as
|
|
9548
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, readdirSync as readdirSync7, writeFileSync as writeFileSync8 } from "node:fs";
|
|
9549
|
+
import { join as join17 } from "node:path";
|
|
9532
9550
|
function writeIfAbsent(absPath, content) {
|
|
9533
|
-
if (
|
|
9551
|
+
if (existsSync14(absPath))
|
|
9534
9552
|
return false;
|
|
9535
|
-
mkdirSync9(
|
|
9553
|
+
mkdirSync9(join17(absPath, ".."), { recursive: true });
|
|
9536
9554
|
writeFileSync8(absPath, content, "utf-8");
|
|
9537
9555
|
return true;
|
|
9538
9556
|
}
|
|
@@ -9579,20 +9597,20 @@ async function bootstrapVault(cfg, opts) {
|
|
|
9579
9597
|
if (wrote)
|
|
9580
9598
|
filesCreated.push(relPath);
|
|
9581
9599
|
};
|
|
9582
|
-
track("_index.md", writeIfAbsent(
|
|
9583
|
-
track("_conventions.md", writeIfAbsent(
|
|
9584
|
-
track("_log.md", writeIfAbsent(
|
|
9600
|
+
track("_index.md", writeIfAbsent(join17(vp, "_index.md"), masterIndex()));
|
|
9601
|
+
track("_conventions.md", writeIfAbsent(join17(vp, "_conventions.md"), CONVENTIONS_MD_DEFAULT));
|
|
9602
|
+
track("_log.md", writeIfAbsent(join17(vp, "_log.md"), initialLog()));
|
|
9585
9603
|
for (const f of SUBFOLDERS) {
|
|
9586
|
-
track(`${f}/_index.md`, writeIfAbsent(
|
|
9604
|
+
track(`${f}/_index.md`, writeIfAbsent(join17(vp, f, "_index.md"), subfolderIndex(f)));
|
|
9587
9605
|
}
|
|
9588
9606
|
for (const type of NOTE_TYPES) {
|
|
9589
|
-
track(`meta/templates/${type}.md`, writeIfAbsent(
|
|
9607
|
+
track(`meta/templates/${type}.md`, writeIfAbsent(join17(vp, "meta", "templates", `${type}.md`), TEMPLATES[type]));
|
|
9590
9608
|
}
|
|
9591
|
-
const specsRoot =
|
|
9609
|
+
const specsRoot = join17(vp, "..", "specs");
|
|
9592
9610
|
for (const sf of SPECS_SUBFOLDERS) {
|
|
9593
|
-
const dir =
|
|
9611
|
+
const dir = join17(specsRoot, sf);
|
|
9594
9612
|
mkdirSync9(dir, { recursive: true });
|
|
9595
|
-
track(`../specs/${sf}/.gitkeep`, writeIfAbsent(
|
|
9613
|
+
track(`../specs/${sf}/.gitkeep`, writeIfAbsent(join17(dir, ".gitkeep"), ""));
|
|
9596
9614
|
}
|
|
9597
9615
|
let gitignoreUpdated = false;
|
|
9598
9616
|
if (opts.gitignore) {
|
|
@@ -9602,7 +9620,7 @@ async function bootstrapVault(cfg, opts) {
|
|
|
9602
9620
|
return { vaultPath: vp, filesCreated, gitignoreUpdated };
|
|
9603
9621
|
}
|
|
9604
9622
|
function detectVaultShape(vaultPath) {
|
|
9605
|
-
if (!
|
|
9623
|
+
if (!existsSync14(vaultPath))
|
|
9606
9624
|
return "none";
|
|
9607
9625
|
let entries;
|
|
9608
9626
|
try {
|
|
@@ -13296,21 +13314,21 @@ var init_noteAccess = __esm(() => {
|
|
|
13296
13314
|
var init_artifacts = () => {};
|
|
13297
13315
|
|
|
13298
13316
|
// src/vault/globalConfig.ts
|
|
13299
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
13317
|
+
import { chmodSync as chmodSync2, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
13300
13318
|
import { homedir as homedir6 } from "node:os";
|
|
13301
|
-
import { dirname as dirname9, join as
|
|
13319
|
+
import { dirname as dirname9, join as join18 } from "node:path";
|
|
13302
13320
|
function resolveMachineConfigPath() {
|
|
13303
13321
|
if (process.env.ANCHORKIT_TEST_MACHINE_CONFIG_PATH) {
|
|
13304
13322
|
return process.env.ANCHORKIT_TEST_MACHINE_CONFIG_PATH;
|
|
13305
13323
|
}
|
|
13306
13324
|
if (process.platform === "win32" && process.env.APPDATA) {
|
|
13307
|
-
return
|
|
13325
|
+
return join18(process.env.APPDATA, "anchorkit", "config.json");
|
|
13308
13326
|
}
|
|
13309
|
-
return
|
|
13327
|
+
return join18(homedir6(), ".anchorkit", "config.json");
|
|
13310
13328
|
}
|
|
13311
13329
|
function loadMachineConfig() {
|
|
13312
13330
|
const path2 = resolveMachineConfigPath();
|
|
13313
|
-
if (!
|
|
13331
|
+
if (!existsSync15(path2))
|
|
13314
13332
|
return {};
|
|
13315
13333
|
try {
|
|
13316
13334
|
const raw = readFileSync12(path2, "utf-8");
|
|
@@ -13327,9 +13345,9 @@ function defaultGlobalVaultPath() {
|
|
|
13327
13345
|
return process.env.ANCHORKIT_TEST_DEFAULT_GLOBAL_VAULT_PATH;
|
|
13328
13346
|
}
|
|
13329
13347
|
if (process.platform === "win32" && process.env.APPDATA) {
|
|
13330
|
-
return
|
|
13348
|
+
return join18(process.env.APPDATA, "anchorkit", "global-vault");
|
|
13331
13349
|
}
|
|
13332
|
-
return
|
|
13350
|
+
return join18(homedir6(), ".anchorkit", "global-vault");
|
|
13333
13351
|
}
|
|
13334
13352
|
function resolveGlobalVault() {
|
|
13335
13353
|
const cfg = loadMachineConfig();
|
|
@@ -13353,11 +13371,11 @@ __export(exports_config, {
|
|
|
13353
13371
|
isRepoOnboarded: () => isRepoOnboarded,
|
|
13354
13372
|
adaptLegacyConfig: () => adaptLegacyConfig
|
|
13355
13373
|
});
|
|
13356
|
-
import { existsSync as
|
|
13357
|
-
import { basename as basename2, join as
|
|
13374
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
|
|
13375
|
+
import { basename as basename2, join as join19 } from "node:path";
|
|
13358
13376
|
function resolveVaultPath(projectRoot) {
|
|
13359
|
-
const configPath =
|
|
13360
|
-
if (
|
|
13377
|
+
const configPath = join19(projectRoot, ".anchorkit", "config.json");
|
|
13378
|
+
if (existsSync16(configPath)) {
|
|
13361
13379
|
try {
|
|
13362
13380
|
const raw = readFileSync13(configPath, "utf-8");
|
|
13363
13381
|
const config = JSON.parse(raw);
|
|
@@ -13366,7 +13384,7 @@ function resolveVaultPath(projectRoot) {
|
|
|
13366
13384
|
}
|
|
13367
13385
|
} catch {}
|
|
13368
13386
|
}
|
|
13369
|
-
return
|
|
13387
|
+
return join19(projectRoot, ".anchorkit", "vault");
|
|
13370
13388
|
}
|
|
13371
13389
|
function resolveVaultConfig(projectRoot, provider = "generic") {
|
|
13372
13390
|
const vaultPath = resolveVaultPath(projectRoot);
|
|
@@ -13386,8 +13404,8 @@ function resolveGlobal() {
|
|
|
13386
13404
|
return null;
|
|
13387
13405
|
}
|
|
13388
13406
|
function loadVaultManifest(vaultPath) {
|
|
13389
|
-
const manifestPath =
|
|
13390
|
-
if (!
|
|
13407
|
+
const manifestPath = join19(vaultPath, "manifest.json");
|
|
13408
|
+
if (!existsSync16(manifestPath)) {
|
|
13391
13409
|
return null;
|
|
13392
13410
|
}
|
|
13393
13411
|
try {
|
|
@@ -13399,12 +13417,12 @@ function loadVaultManifest(vaultPath) {
|
|
|
13399
13417
|
}
|
|
13400
13418
|
function saveVaultManifest(vaultPath, manifest) {
|
|
13401
13419
|
mkdirSync11(vaultPath, { recursive: true });
|
|
13402
|
-
const manifestPath =
|
|
13420
|
+
const manifestPath = join19(vaultPath, "manifest.json");
|
|
13403
13421
|
writeFileSync10(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
13404
13422
|
}
|
|
13405
13423
|
function isRepoOnboarded(projectRoot) {
|
|
13406
13424
|
const vaultPath = resolveVaultPath(projectRoot);
|
|
13407
|
-
return
|
|
13425
|
+
return existsSync16(join19(vaultPath, "manifest.json"));
|
|
13408
13426
|
}
|
|
13409
13427
|
function adaptLegacyConfig(cfg) {
|
|
13410
13428
|
if ("local" in cfg)
|
|
@@ -14033,11 +14051,11 @@ var init_emitNotes = __esm(() => {
|
|
|
14033
14051
|
});
|
|
14034
14052
|
|
|
14035
14053
|
// src/vault/mapper/emit/orphanGate.ts
|
|
14036
|
-
import { existsSync as
|
|
14037
|
-
import { join as
|
|
14054
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, readdirSync as readdirSync8, statSync as statSync3 } from "node:fs";
|
|
14055
|
+
import { join as join20 } from "node:path";
|
|
14038
14056
|
function runOrphanGate(vaultPath) {
|
|
14039
|
-
const mapsDir =
|
|
14040
|
-
const knowledgeDir =
|
|
14057
|
+
const mapsDir = join20(vaultPath, "maps");
|
|
14058
|
+
const knowledgeDir = join20(vaultPath, "knowledge");
|
|
14041
14059
|
const linkedFromMaps = new Set;
|
|
14042
14060
|
walkMdFiles(mapsDir, (content) => {
|
|
14043
14061
|
for (const match of content.matchAll(WIKILINK_RE2)) {
|
|
@@ -14060,7 +14078,7 @@ function runOrphanGate(vaultPath) {
|
|
|
14060
14078
|
return { orphans, ok: orphans.length === 0 };
|
|
14061
14079
|
}
|
|
14062
14080
|
function walkMdFiles(dir, callback) {
|
|
14063
|
-
if (!
|
|
14081
|
+
if (!existsSync17(dir))
|
|
14064
14082
|
return;
|
|
14065
14083
|
const walk = (d) => {
|
|
14066
14084
|
let entries;
|
|
@@ -14070,7 +14088,7 @@ function walkMdFiles(dir, callback) {
|
|
|
14070
14088
|
return;
|
|
14071
14089
|
}
|
|
14072
14090
|
for (const entry of entries) {
|
|
14073
|
-
const p =
|
|
14091
|
+
const p = join20(d, entry);
|
|
14074
14092
|
let s;
|
|
14075
14093
|
try {
|
|
14076
14094
|
s = statSync3(p);
|
|
@@ -14109,7 +14127,7 @@ var init_runOrphanGate = __esm(() => {
|
|
|
14109
14127
|
});
|
|
14110
14128
|
|
|
14111
14129
|
// src/vault/mapper/analyze/tsParser.ts
|
|
14112
|
-
import { existsSync as
|
|
14130
|
+
import { existsSync as existsSync18, readFileSync as readFileSync16 } from "node:fs";
|
|
14113
14131
|
import path2 from "node:path";
|
|
14114
14132
|
import { Project, ts } from "ts-morph";
|
|
14115
14133
|
function detectScriptKind(absPath) {
|
|
@@ -14150,7 +14168,7 @@ function createTsParser(repoRoot, options2 = {}) {
|
|
|
14150
14168
|
if (project)
|
|
14151
14169
|
return project;
|
|
14152
14170
|
const candidate = options2.tsConfigFilePath ?? path2.join(absRepoRoot, "tsconfig.json");
|
|
14153
|
-
const tsConfigPath =
|
|
14171
|
+
const tsConfigPath = existsSync18(candidate) ? candidate : null;
|
|
14154
14172
|
project = new Project(buildProjectOptions(tsConfigPath));
|
|
14155
14173
|
return project;
|
|
14156
14174
|
}
|
|
@@ -15041,7 +15059,11 @@ var init_inferSemantic = __esm(() => {
|
|
|
15041
15059
|
TOOLS.inferSemantic = { fn: inferSemantic, descriptor: descriptor8 };
|
|
15042
15060
|
});
|
|
15043
15061
|
|
|
15044
|
-
// src/vault/query/embeddings.ts
|
|
15062
|
+
// src/core/vault/query/embeddings.ts
|
|
15063
|
+
function setEmbedder(embedder) {
|
|
15064
|
+
cachedEmbedder = embedder;
|
|
15065
|
+
cachedEmbedderPromise = null;
|
|
15066
|
+
}
|
|
15045
15067
|
async function loadEmbedder() {
|
|
15046
15068
|
if (cachedEmbedder)
|
|
15047
15069
|
return cachedEmbedder;
|
|
@@ -15104,19 +15126,10 @@ var init_embeddings = __esm(() => {
|
|
|
15104
15126
|
init_utils();
|
|
15105
15127
|
});
|
|
15106
15128
|
|
|
15107
|
-
// src/vault/query/
|
|
15108
|
-
var exports_query = {};
|
|
15109
|
-
__export(exports_query, {
|
|
15110
|
-
updateEntry: () => updateEntry,
|
|
15111
|
-
safeMtimeMs: () => safeMtimeMs,
|
|
15112
|
-
removeEntry: () => removeEntry,
|
|
15113
|
-
persistIndex: () => persistIndex,
|
|
15114
|
-
loadIndex: () => loadIndex,
|
|
15115
|
-
buildIndex: () => buildIndex
|
|
15116
|
-
});
|
|
15129
|
+
// src/core/vault/query/noteIndex.ts
|
|
15117
15130
|
import { createHash as createHash4 } from "node:crypto";
|
|
15118
15131
|
import {
|
|
15119
|
-
existsSync as
|
|
15132
|
+
existsSync as existsSync19,
|
|
15120
15133
|
mkdirSync as mkdirSync12,
|
|
15121
15134
|
readFileSync as readFileSync19,
|
|
15122
15135
|
readdirSync as readdirSync9,
|
|
@@ -15125,12 +15138,12 @@ import {
|
|
|
15125
15138
|
writeFileSync as writeFileSync11
|
|
15126
15139
|
} from "node:fs";
|
|
15127
15140
|
import { tmpdir } from "node:os";
|
|
15128
|
-
import { basename as basename6, extname as extname4, join as
|
|
15141
|
+
import { basename as basename6, extname as extname4, join as join21 } from "node:path";
|
|
15129
15142
|
function cacheDir(vaultPath) {
|
|
15130
|
-
return
|
|
15143
|
+
return join21(vaultPath, ".cache");
|
|
15131
15144
|
}
|
|
15132
15145
|
function indexPath(vaultPath) {
|
|
15133
|
-
return
|
|
15146
|
+
return join21(cacheDir(vaultPath), INDEX_FILENAME);
|
|
15134
15147
|
}
|
|
15135
15148
|
function emptyIndex() {
|
|
15136
15149
|
return {
|
|
@@ -15147,7 +15160,7 @@ function isValidIndex(value) {
|
|
|
15147
15160
|
}
|
|
15148
15161
|
function loadIndex(vaultPath) {
|
|
15149
15162
|
const path4 = indexPath(vaultPath);
|
|
15150
|
-
if (!
|
|
15163
|
+
if (!existsSync19(path4))
|
|
15151
15164
|
return null;
|
|
15152
15165
|
try {
|
|
15153
15166
|
const raw = JSON.parse(readFileSync19(path4, "utf-8"));
|
|
@@ -15172,8 +15185,8 @@ function loadIndex(vaultPath) {
|
|
|
15172
15185
|
function ensureCacheDir(vaultPath) {
|
|
15173
15186
|
const dir = cacheDir(vaultPath);
|
|
15174
15187
|
mkdirSync12(dir, { recursive: true });
|
|
15175
|
-
const gi =
|
|
15176
|
-
if (!
|
|
15188
|
+
const gi = join21(dir, ".gitignore");
|
|
15189
|
+
if (!existsSync19(gi)) {
|
|
15177
15190
|
try {
|
|
15178
15191
|
writeFileSync11(gi, `*
|
|
15179
15192
|
!.gitignore
|
|
@@ -15183,7 +15196,7 @@ function ensureCacheDir(vaultPath) {
|
|
|
15183
15196
|
}
|
|
15184
15197
|
function persistIndex(vaultPath, idx) {
|
|
15185
15198
|
ensureCacheDir(vaultPath);
|
|
15186
|
-
const tmp =
|
|
15199
|
+
const tmp = join21(tmpdir(), `bridgeai-index-${process.pid}-${Date.now()}.json`);
|
|
15187
15200
|
try {
|
|
15188
15201
|
writeFileSync11(tmp, JSON.stringify(idx), "utf-8");
|
|
15189
15202
|
renameSync(tmp, indexPath(vaultPath));
|
|
@@ -15196,8 +15209,8 @@ function persistIndex(vaultPath, idx) {
|
|
|
15196
15209
|
function readNotesFromVault(vaultPath, scope) {
|
|
15197
15210
|
const out = [];
|
|
15198
15211
|
for (const folder of NOTE_FOLDERS) {
|
|
15199
|
-
const dir =
|
|
15200
|
-
if (!
|
|
15212
|
+
const dir = join21(vaultPath, folder);
|
|
15213
|
+
if (!existsSync19(dir))
|
|
15201
15214
|
continue;
|
|
15202
15215
|
let entries;
|
|
15203
15216
|
try {
|
|
@@ -15210,7 +15223,7 @@ function readNotesFromVault(vaultPath, scope) {
|
|
|
15210
15223
|
continue;
|
|
15211
15224
|
if (entry.startsWith("_"))
|
|
15212
15225
|
continue;
|
|
15213
|
-
const full =
|
|
15226
|
+
const full = join21(dir, entry);
|
|
15214
15227
|
let raw;
|
|
15215
15228
|
try {
|
|
15216
15229
|
raw = readFileSync19(full, "utf-8");
|
|
@@ -15350,23 +15363,490 @@ function safeMtimeMs(path4) {
|
|
|
15350
15363
|
}
|
|
15351
15364
|
}
|
|
15352
15365
|
var SCHEMA_VERSION2 = "1", INDEX_FILENAME = "embeddings.json";
|
|
15353
|
-
var
|
|
15366
|
+
var init_noteIndex = __esm(() => {
|
|
15367
|
+
init_utils();
|
|
15368
|
+
init_conventions();
|
|
15369
|
+
init_indexing();
|
|
15370
|
+
init_embeddings();
|
|
15371
|
+
});
|
|
15372
|
+
|
|
15373
|
+
// src/core/vault/query/cacheAside.ts
|
|
15374
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
15375
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync20, renameSync as renameSync2, writeFileSync as writeFileSync12 } from "node:fs";
|
|
15376
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
15377
|
+
import { join as join22 } from "node:path";
|
|
15378
|
+
function cachePath2(vaultPath) {
|
|
15379
|
+
return join22(vaultPath, ".cache", CACHE_FILENAME);
|
|
15380
|
+
}
|
|
15381
|
+
function emptyCache() {
|
|
15382
|
+
return { schemaVersion: SCHEMA_VERSION3, entries: [] };
|
|
15383
|
+
}
|
|
15384
|
+
function isValidCache(value) {
|
|
15385
|
+
if (typeof value !== "object" || value === null)
|
|
15386
|
+
return false;
|
|
15387
|
+
const v = value;
|
|
15388
|
+
return v.schemaVersion === SCHEMA_VERSION3 && Array.isArray(v.entries);
|
|
15389
|
+
}
|
|
15390
|
+
function loadCacheFile(vaultPath) {
|
|
15391
|
+
const path4 = cachePath2(vaultPath);
|
|
15392
|
+
if (!existsSync20(path4))
|
|
15393
|
+
return emptyCache();
|
|
15394
|
+
try {
|
|
15395
|
+
const raw = JSON.parse(readFileSync20(path4, "utf-8"));
|
|
15396
|
+
if (!isValidCache(raw))
|
|
15397
|
+
return emptyCache();
|
|
15398
|
+
return raw;
|
|
15399
|
+
} catch (err) {
|
|
15400
|
+
logForDebugging(`[query/cache] load failed (resetting): ${errorMessage(err)}`, {
|
|
15401
|
+
level: "warn"
|
|
15402
|
+
});
|
|
15403
|
+
return emptyCache();
|
|
15404
|
+
}
|
|
15405
|
+
}
|
|
15406
|
+
function persistCacheFile(vaultPath, file) {
|
|
15407
|
+
const dir = join22(vaultPath, ".cache");
|
|
15408
|
+
mkdirSync13(dir, { recursive: true });
|
|
15409
|
+
const gi = join22(dir, ".gitignore");
|
|
15410
|
+
if (!existsSync20(gi)) {
|
|
15411
|
+
try {
|
|
15412
|
+
writeFileSync12(gi, `*
|
|
15413
|
+
!.gitignore
|
|
15414
|
+
`, "utf-8");
|
|
15415
|
+
} catch {}
|
|
15416
|
+
}
|
|
15417
|
+
const tmp = join22(tmpdir2(), `bridgeai-qcache-${process.pid}-${Date.now()}.json`);
|
|
15418
|
+
try {
|
|
15419
|
+
writeFileSync12(tmp, JSON.stringify(file), "utf-8");
|
|
15420
|
+
renameSync2(tmp, cachePath2(vaultPath));
|
|
15421
|
+
} catch (err) {
|
|
15422
|
+
logForDebugging(`[query/cache] persist failed: ${errorMessage(err)}`, { level: "warn" });
|
|
15423
|
+
}
|
|
15424
|
+
}
|
|
15425
|
+
function hashQuery(query) {
|
|
15426
|
+
return createHash5("sha256").update(query.trim().toLowerCase()).digest("hex");
|
|
15427
|
+
}
|
|
15428
|
+
function lookup(vaultPath, _query, vec) {
|
|
15429
|
+
if (isZeroVector(vec))
|
|
15430
|
+
return null;
|
|
15431
|
+
const file = loadCacheFile(vaultPath);
|
|
15432
|
+
if (file.entries.length === 0)
|
|
15433
|
+
return null;
|
|
15434
|
+
let best = null;
|
|
15435
|
+
for (const entry of file.entries) {
|
|
15436
|
+
const score = cosine(vec, entry.vector);
|
|
15437
|
+
if (score < CACHE_HIT_THRESHOLD)
|
|
15438
|
+
continue;
|
|
15439
|
+
if (best === null || score > best.score)
|
|
15440
|
+
best = { entry, score };
|
|
15441
|
+
}
|
|
15442
|
+
if (!best)
|
|
15443
|
+
return null;
|
|
15444
|
+
const verifiedMs = Date.parse(best.entry.lastVerified);
|
|
15445
|
+
if (!Number.isFinite(verifiedMs))
|
|
15446
|
+
return null;
|
|
15447
|
+
for (const note of best.entry.topK) {
|
|
15448
|
+
if (safeMtimeMs(note.path) > verifiedMs)
|
|
15449
|
+
return null;
|
|
15450
|
+
}
|
|
15451
|
+
return best.entry;
|
|
15452
|
+
}
|
|
15453
|
+
function fill(vaultPath, query, vec, topK) {
|
|
15454
|
+
if (isZeroVector(vec))
|
|
15455
|
+
return;
|
|
15456
|
+
const file = loadCacheFile(vaultPath);
|
|
15457
|
+
const nowMs = Date.now();
|
|
15458
|
+
const nowStr = new Date(nowMs).toISOString();
|
|
15459
|
+
const maxMtimeMs = topK.reduce((m, n) => Math.max(m, safeMtimeMs(n.path)), 0);
|
|
15460
|
+
const lastVerifiedMs = maxMtimeMs > 0 ? Math.max(nowMs, maxMtimeMs + 1) : nowMs;
|
|
15461
|
+
const lastVerifiedStr = new Date(lastVerifiedMs).toISOString();
|
|
15462
|
+
const queryHash = hashQuery(query);
|
|
15463
|
+
const existingIdx = file.entries.findIndex((e) => e.queryHash === queryHash);
|
|
15464
|
+
const entry = {
|
|
15465
|
+
queryHash,
|
|
15466
|
+
query,
|
|
15467
|
+
vector: vec,
|
|
15468
|
+
topK,
|
|
15469
|
+
lastVerified: lastVerifiedStr,
|
|
15470
|
+
lastQueried: nowStr
|
|
15471
|
+
};
|
|
15472
|
+
if (existingIdx >= 0) {
|
|
15473
|
+
file.entries[existingIdx] = entry;
|
|
15474
|
+
} else {
|
|
15475
|
+
file.entries.push(entry);
|
|
15476
|
+
}
|
|
15477
|
+
if (file.entries.length > MAX_ENTRIES) {
|
|
15478
|
+
file.entries.sort((a, b) => a.lastQueried.localeCompare(b.lastQueried));
|
|
15479
|
+
file.entries = file.entries.slice(file.entries.length - MAX_ENTRIES);
|
|
15480
|
+
}
|
|
15481
|
+
persistCacheFile(vaultPath, file);
|
|
15482
|
+
}
|
|
15483
|
+
function touch(vaultPath, queryHash) {
|
|
15484
|
+
const file = loadCacheFile(vaultPath);
|
|
15485
|
+
const idx = file.entries.findIndex((e) => e.queryHash === queryHash);
|
|
15486
|
+
if (idx < 0)
|
|
15487
|
+
return;
|
|
15488
|
+
file.entries[idx].lastQueried = new Date().toISOString();
|
|
15489
|
+
persistCacheFile(vaultPath, file);
|
|
15490
|
+
}
|
|
15491
|
+
function coalesceCall(key, factory) {
|
|
15492
|
+
const existing = inFlight.get(key);
|
|
15493
|
+
if (existing)
|
|
15494
|
+
return existing;
|
|
15495
|
+
const fresh = factory().finally(() => {
|
|
15496
|
+
inFlight.delete(key);
|
|
15497
|
+
});
|
|
15498
|
+
inFlight.set(key, fresh);
|
|
15499
|
+
return fresh;
|
|
15500
|
+
}
|
|
15501
|
+
function clearCoalescer() {
|
|
15502
|
+
inFlight.clear();
|
|
15503
|
+
}
|
|
15504
|
+
var CACHE_FILENAME = "query-cache.json", SCHEMA_VERSION3 = "1", MAX_ENTRIES = 100, inFlight;
|
|
15505
|
+
var init_cacheAside = __esm(() => {
|
|
15354
15506
|
init_utils();
|
|
15355
15507
|
init_utils();
|
|
15508
|
+
init_embeddings();
|
|
15509
|
+
init_noteIndex();
|
|
15510
|
+
inFlight = new Map;
|
|
15511
|
+
});
|
|
15512
|
+
|
|
15513
|
+
// src/core/vault/query/expansion.ts
|
|
15514
|
+
import { existsSync as existsSync21, readFileSync as readFileSync21 } from "node:fs";
|
|
15515
|
+
import { join as join23 } from "node:path";
|
|
15516
|
+
function findGlobalSlugsInBody(text) {
|
|
15517
|
+
const out = [];
|
|
15518
|
+
let match;
|
|
15519
|
+
while ((match = WIKILINK_REGEX.exec(text)) !== null) {
|
|
15520
|
+
const raw = match[1];
|
|
15521
|
+
if (!raw)
|
|
15522
|
+
continue;
|
|
15523
|
+
const target = parseWikiLinkTarget(raw);
|
|
15524
|
+
if (target.vault === "global")
|
|
15525
|
+
out.push(target.slug);
|
|
15526
|
+
}
|
|
15527
|
+
return out;
|
|
15528
|
+
}
|
|
15529
|
+
function findGlobalSlugsInRelated(related) {
|
|
15530
|
+
if (!Array.isArray(related))
|
|
15531
|
+
return [];
|
|
15532
|
+
const out = [];
|
|
15533
|
+
for (const r of related) {
|
|
15534
|
+
if (typeof r !== "string")
|
|
15535
|
+
continue;
|
|
15536
|
+
const stripped = r.replace(/^\[\[|\]\]$/g, "");
|
|
15537
|
+
const target = parseWikiLinkTarget(stripped);
|
|
15538
|
+
if (target.vault === "global")
|
|
15539
|
+
out.push(target.slug);
|
|
15540
|
+
}
|
|
15541
|
+
return out;
|
|
15542
|
+
}
|
|
15543
|
+
function readGlobalNoteBody(globalPath, slug) {
|
|
15544
|
+
for (const folder of NOTE_FOLDERS) {
|
|
15545
|
+
const p = join23(globalPath, folder, `${slug}.md`);
|
|
15546
|
+
if (!existsSync21(p))
|
|
15547
|
+
continue;
|
|
15548
|
+
try {
|
|
15549
|
+
const raw = readFileSync21(p, "utf-8");
|
|
15550
|
+
const parsed = parseFrontmatter(raw);
|
|
15551
|
+
return parsed.content ?? "";
|
|
15552
|
+
} catch (err) {
|
|
15553
|
+
logForDebugging(`[query/expansion] read failed ${p}: ${errorMessage(err)}`, {
|
|
15554
|
+
level: "warn"
|
|
15555
|
+
});
|
|
15556
|
+
return null;
|
|
15557
|
+
}
|
|
15558
|
+
}
|
|
15559
|
+
return null;
|
|
15560
|
+
}
|
|
15561
|
+
async function readGlobalNoteBodyVia(globalPath, slug, noteAccess2) {
|
|
15562
|
+
for (const folder of NOTE_FOLDERS) {
|
|
15563
|
+
const p = join23(globalPath, folder, `${slug}.md`);
|
|
15564
|
+
if (!existsSync21(p))
|
|
15565
|
+
continue;
|
|
15566
|
+
try {
|
|
15567
|
+
const raw = await noteAccess2.readUserNote(p);
|
|
15568
|
+
if (!raw)
|
|
15569
|
+
return "";
|
|
15570
|
+
const parsed = parseFrontmatter(raw);
|
|
15571
|
+
return parsed.content ?? "";
|
|
15572
|
+
} catch (err) {
|
|
15573
|
+
logForDebugging(`[query/expansion] read failed ${p}: ${errorMessage(err)}`, {
|
|
15574
|
+
level: "warn"
|
|
15575
|
+
});
|
|
15576
|
+
return null;
|
|
15577
|
+
}
|
|
15578
|
+
}
|
|
15579
|
+
return null;
|
|
15580
|
+
}
|
|
15581
|
+
function collectGlobalSlugs(note) {
|
|
15582
|
+
const fmRelated = note.related;
|
|
15583
|
+
return new Set([
|
|
15584
|
+
...findGlobalSlugsInBody(note.summary),
|
|
15585
|
+
...findGlobalSlugsInRelated(fmRelated)
|
|
15586
|
+
]);
|
|
15587
|
+
}
|
|
15588
|
+
function appendExpansion(expansions, slug, body, charsUsed) {
|
|
15589
|
+
const remaining = EXPANSION_BUDGET_CHARS - charsUsed;
|
|
15590
|
+
if (body.length <= remaining) {
|
|
15591
|
+
expansions.push({ slug, scope: "global", body, truncated: false });
|
|
15592
|
+
return { charsUsed: charsUsed + body.length, truncated: false };
|
|
15593
|
+
}
|
|
15594
|
+
expansions.push({ slug, scope: "global", body: body.slice(0, remaining), truncated: true });
|
|
15595
|
+
return { charsUsed: EXPANSION_BUDGET_CHARS, truncated: true };
|
|
15596
|
+
}
|
|
15597
|
+
function pushBudgetExceeded(expansions, slug) {
|
|
15598
|
+
expansions.push({ slug, scope: "global", body: "", truncated: true });
|
|
15599
|
+
}
|
|
15600
|
+
function expandLinks(cfg, results) {
|
|
15601
|
+
if (!cfg.global)
|
|
15602
|
+
return { results };
|
|
15603
|
+
const globalPath = cfg.global.path;
|
|
15604
|
+
let charsUsed = 0;
|
|
15605
|
+
let truncatedFlag = false;
|
|
15606
|
+
const out = [];
|
|
15607
|
+
for (const note of results) {
|
|
15608
|
+
const expansions = [];
|
|
15609
|
+
for (const slug of collectGlobalSlugs(note)) {
|
|
15610
|
+
if (charsUsed >= EXPANSION_BUDGET_CHARS) {
|
|
15611
|
+
pushBudgetExceeded(expansions, slug);
|
|
15612
|
+
truncatedFlag = true;
|
|
15613
|
+
continue;
|
|
15614
|
+
}
|
|
15615
|
+
const body = readGlobalNoteBody(globalPath, slug);
|
|
15616
|
+
if (body === null)
|
|
15617
|
+
continue;
|
|
15618
|
+
const r = appendExpansion(expansions, slug, body, charsUsed);
|
|
15619
|
+
charsUsed = r.charsUsed;
|
|
15620
|
+
if (r.truncated)
|
|
15621
|
+
truncatedFlag = true;
|
|
15622
|
+
}
|
|
15623
|
+
out.push(expansions.length > 0 ? { ...note, expanded_links: expansions } : note);
|
|
15624
|
+
}
|
|
15625
|
+
return truncatedFlag ? { results: out, warning: TRUNCATION_WARNING } : { results: out };
|
|
15626
|
+
}
|
|
15627
|
+
async function expandLinksAsync(cfg, results, noteAccess2) {
|
|
15628
|
+
if (!cfg.global)
|
|
15629
|
+
return { results };
|
|
15630
|
+
const globalPath = cfg.global.path;
|
|
15631
|
+
let charsUsed = 0;
|
|
15632
|
+
let truncatedFlag = false;
|
|
15633
|
+
const out = [];
|
|
15634
|
+
for (const note of results) {
|
|
15635
|
+
const expansions = [];
|
|
15636
|
+
for (const slug of collectGlobalSlugs(note)) {
|
|
15637
|
+
if (charsUsed >= EXPANSION_BUDGET_CHARS) {
|
|
15638
|
+
pushBudgetExceeded(expansions, slug);
|
|
15639
|
+
truncatedFlag = true;
|
|
15640
|
+
continue;
|
|
15641
|
+
}
|
|
15642
|
+
const body = await readGlobalNoteBodyVia(globalPath, slug, noteAccess2);
|
|
15643
|
+
if (body === null)
|
|
15644
|
+
continue;
|
|
15645
|
+
const r = appendExpansion(expansions, slug, body, charsUsed);
|
|
15646
|
+
charsUsed = r.charsUsed;
|
|
15647
|
+
if (r.truncated)
|
|
15648
|
+
truncatedFlag = true;
|
|
15649
|
+
}
|
|
15650
|
+
out.push(expansions.length > 0 ? { ...note, expanded_links: expansions } : note);
|
|
15651
|
+
}
|
|
15652
|
+
return truncatedFlag ? { results: out, warning: TRUNCATION_WARNING } : { results: out };
|
|
15653
|
+
}
|
|
15654
|
+
var WIKILINK_REGEX, TRUNCATION_WARNING;
|
|
15655
|
+
var init_expansion = __esm(() => {
|
|
15356
15656
|
init_utils();
|
|
15657
|
+
init_conventions();
|
|
15658
|
+
init_indexing();
|
|
15659
|
+
init_storage();
|
|
15660
|
+
init_embeddings();
|
|
15661
|
+
WIKILINK_REGEX = /\[\[([^\]]+)\]\]/g;
|
|
15662
|
+
TRUNCATION_WARNING = `Expansion budget (${EXPANSION_BUDGET_CHARS} chars) reached; some [[global:...]] references returned truncated or empty.`;
|
|
15663
|
+
});
|
|
15664
|
+
|
|
15665
|
+
// src/core/vault/query/query.ts
|
|
15666
|
+
import { existsSync as existsSync22, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "node:fs";
|
|
15667
|
+
import { join as join24 } from "node:path";
|
|
15668
|
+
function sanitize(opts) {
|
|
15669
|
+
const limit = Math.min(Math.max(1, Math.floor(opts.limit ?? DEFAULT_LIMIT2)), MAX_LIMIT);
|
|
15670
|
+
return {
|
|
15671
|
+
query: opts.query.trim(),
|
|
15672
|
+
limit,
|
|
15673
|
+
scope: opts.scope ?? "both",
|
|
15674
|
+
expand: opts.expand ?? true
|
|
15675
|
+
};
|
|
15676
|
+
}
|
|
15677
|
+
function indexEntryToResult(filename, entry, vaultLocalPath, vaultGlobalPath, score) {
|
|
15678
|
+
const root = entry.scope === "global" ? vaultGlobalPath ?? vaultLocalPath : vaultLocalPath;
|
|
15679
|
+
return {
|
|
15680
|
+
filename,
|
|
15681
|
+
folder: entry.folder,
|
|
15682
|
+
path: join24(root, entry.folder, `${filename}.md`),
|
|
15683
|
+
scope: entry.scope,
|
|
15684
|
+
score,
|
|
15685
|
+
summary: entry.summary
|
|
15686
|
+
};
|
|
15687
|
+
}
|
|
15688
|
+
function topK(index, queryVec, limit, scope, cfg) {
|
|
15689
|
+
const localPath = cfg.local.path;
|
|
15690
|
+
const globalPath = cfg.global ? cfg.global.path : null;
|
|
15691
|
+
const scored = [];
|
|
15692
|
+
for (const [filename, entry] of Object.entries(index.entries)) {
|
|
15693
|
+
if (scope !== "both" && entry.scope !== scope)
|
|
15694
|
+
continue;
|
|
15695
|
+
if (entry.vector.length !== queryVec.length)
|
|
15696
|
+
continue;
|
|
15697
|
+
const score = cosine(queryVec, entry.vector);
|
|
15698
|
+
if (!Number.isFinite(score))
|
|
15699
|
+
continue;
|
|
15700
|
+
scored.push({ filename, score, entry });
|
|
15701
|
+
}
|
|
15702
|
+
scored.sort((a, b) => b.score - a.score);
|
|
15703
|
+
return scored.slice(0, limit).map((s) => indexEntryToResult(s.filename, s.entry, localPath, globalPath, s.score));
|
|
15704
|
+
}
|
|
15705
|
+
function appendLog2(vaultPath, kind, detail = "") {
|
|
15706
|
+
const ts4 = new Date().toISOString();
|
|
15707
|
+
const line = `- ${ts4} ${kind}${detail ? ` ${detail}` : ""} source: code-analysis
|
|
15708
|
+
`;
|
|
15709
|
+
const logPath = join24(vaultPath, "_log.md");
|
|
15710
|
+
try {
|
|
15711
|
+
if (!existsSync22(logPath)) {
|
|
15712
|
+
writeFileSync13(logPath, `# Vault log
|
|
15713
|
+
|
|
15714
|
+
${line}`, "utf-8");
|
|
15715
|
+
return;
|
|
15716
|
+
}
|
|
15717
|
+
const content = readFileSync22(logPath, "utf-8");
|
|
15718
|
+
const needsNl = content.length > 0 && !content.endsWith(`
|
|
15719
|
+
`);
|
|
15720
|
+
writeFileSync13(logPath, content + (needsNl ? `
|
|
15721
|
+
` : "") + line, "utf-8");
|
|
15722
|
+
} catch (err) {
|
|
15723
|
+
logForDebugging(`[query] log append failed: ${errorMessage(err)}`, {
|
|
15724
|
+
level: "warn"
|
|
15725
|
+
});
|
|
15726
|
+
}
|
|
15727
|
+
}
|
|
15728
|
+
async function ensureIndex(cfg) {
|
|
15729
|
+
const existing = loadIndex(cfg.local.path);
|
|
15730
|
+
if (existing && Object.keys(existing.entries).length > 0)
|
|
15731
|
+
return existing;
|
|
15732
|
+
const fresh = await buildIndex(cfg);
|
|
15733
|
+
appendLog2(cfg.local.path, "embeddings-built", `${Object.keys(fresh.entries).length} notes`);
|
|
15734
|
+
return fresh;
|
|
15735
|
+
}
|
|
15736
|
+
function emptyEnvelope(error) {
|
|
15737
|
+
return {
|
|
15738
|
+
ok: error === undefined,
|
|
15739
|
+
results: [],
|
|
15740
|
+
cacheHit: false,
|
|
15741
|
+
servedAt: new Date().toISOString(),
|
|
15742
|
+
...error ? { error } : {}
|
|
15743
|
+
};
|
|
15744
|
+
}
|
|
15745
|
+
async function vaultQuery(cfg, opts, extras = {}) {
|
|
15746
|
+
try {
|
|
15747
|
+
if (!opts.query || !opts.query.trim()) {
|
|
15748
|
+
return emptyEnvelope("empty query");
|
|
15749
|
+
}
|
|
15750
|
+
const sanitized = sanitize(opts);
|
|
15751
|
+
const vaultPath = cfg.vaultPath ?? cfg.local.path;
|
|
15752
|
+
const cacheKey = hashQuery(sanitized.query);
|
|
15753
|
+
return await coalesceCall(cacheKey, async () => {
|
|
15754
|
+
const index = await ensureIndex(cfg);
|
|
15755
|
+
if (Object.keys(index.entries).length === 0) {
|
|
15756
|
+
return {
|
|
15757
|
+
...emptyEnvelope(),
|
|
15758
|
+
warnings: ["vault has no notes yet"]
|
|
15759
|
+
};
|
|
15760
|
+
}
|
|
15761
|
+
const vec = await embedText(sanitized.query);
|
|
15762
|
+
if (isZeroVector(vec))
|
|
15763
|
+
return emptyEnvelope("embedding failed");
|
|
15764
|
+
const cached = lookup(vaultPath, sanitized.query, vec);
|
|
15765
|
+
if (cached) {
|
|
15766
|
+
touch(vaultPath, cached.queryHash);
|
|
15767
|
+
const filtered = sanitized.scope === "both" ? cached.topK : cached.topK.filter((n) => n.scope === sanitized.scope);
|
|
15768
|
+
return {
|
|
15769
|
+
ok: true,
|
|
15770
|
+
results: filtered.slice(0, sanitized.limit),
|
|
15771
|
+
cacheHit: true,
|
|
15772
|
+
servedAt: new Date().toISOString()
|
|
15773
|
+
};
|
|
15774
|
+
}
|
|
15775
|
+
const k = topK(index, vec, sanitized.limit, sanitized.scope, cfg);
|
|
15776
|
+
let results = k;
|
|
15777
|
+
const warnings = [];
|
|
15778
|
+
if (sanitized.expand) {
|
|
15779
|
+
const expanded = extras.noteAccess ? await expandLinksAsync(cfg, k, extras.noteAccess) : expandLinks(cfg, k);
|
|
15780
|
+
results = expanded.results;
|
|
15781
|
+
if (expanded.warning)
|
|
15782
|
+
warnings.push(expanded.warning);
|
|
15783
|
+
}
|
|
15784
|
+
fill(vaultPath, sanitized.query, vec, results);
|
|
15785
|
+
return {
|
|
15786
|
+
ok: true,
|
|
15787
|
+
results,
|
|
15788
|
+
cacheHit: false,
|
|
15789
|
+
servedAt: new Date().toISOString(),
|
|
15790
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
15791
|
+
};
|
|
15792
|
+
});
|
|
15793
|
+
} catch (err) {
|
|
15794
|
+
logForDebugging(`[query] unexpected: ${errorMessage(err)}`, { level: "warn" });
|
|
15795
|
+
return emptyEnvelope(errorMessage(err));
|
|
15796
|
+
}
|
|
15797
|
+
}
|
|
15798
|
+
var DEFAULT_LIMIT2 = 5, MAX_LIMIT = 20;
|
|
15799
|
+
var init_query = __esm(() => {
|
|
15800
|
+
init_utils();
|
|
15801
|
+
init_cacheAside();
|
|
15802
|
+
init_embeddings();
|
|
15803
|
+
init_expansion();
|
|
15804
|
+
init_noteIndex();
|
|
15805
|
+
});
|
|
15806
|
+
|
|
15807
|
+
// src/core/vault/query/index.ts
|
|
15808
|
+
var exports_query = {};
|
|
15809
|
+
__export(exports_query, {
|
|
15810
|
+
vaultQuery: () => vaultQuery,
|
|
15811
|
+
updateEntry: () => updateEntry,
|
|
15812
|
+
setEmbedder: () => setEmbedder,
|
|
15813
|
+
safeMtimeMs: () => safeMtimeMs,
|
|
15814
|
+
removeEntry: () => removeEntry,
|
|
15815
|
+
lookup: () => lookup,
|
|
15816
|
+
loadIndex: () => loadIndex,
|
|
15817
|
+
isZeroVector: () => isZeroVector,
|
|
15818
|
+
hashQuery: () => hashQuery,
|
|
15819
|
+
fill: () => fill,
|
|
15820
|
+
expandLinksAsync: () => expandLinksAsync,
|
|
15821
|
+
expandLinks: () => expandLinks,
|
|
15822
|
+
embedText: () => embedText,
|
|
15823
|
+
cosine: () => cosine,
|
|
15824
|
+
coalesceCall: () => coalesceCall,
|
|
15825
|
+
clearCoalescer: () => clearCoalescer,
|
|
15826
|
+
buildIndex: () => buildIndex,
|
|
15827
|
+
EXPANSION_BUDGET_CHARS: () => EXPANSION_BUDGET_CHARS,
|
|
15828
|
+
EMBEDDING_MODEL: () => EMBEDDING_MODEL,
|
|
15829
|
+
EMBEDDING_DIM: () => EMBEDDING_DIM,
|
|
15830
|
+
CACHE_HIT_THRESHOLD: () => CACHE_HIT_THRESHOLD
|
|
15831
|
+
});
|
|
15832
|
+
var init_query2 = __esm(() => {
|
|
15833
|
+
init_query();
|
|
15357
15834
|
init_embeddings();
|
|
15835
|
+
init_noteIndex();
|
|
15836
|
+
init_cacheAside();
|
|
15837
|
+
init_expansion();
|
|
15358
15838
|
});
|
|
15359
15839
|
|
|
15360
15840
|
// src/vault/mapper/pipeline-phases.ts
|
|
15361
15841
|
import {
|
|
15362
|
-
existsSync as
|
|
15363
|
-
mkdirSync as
|
|
15364
|
-
readFileSync as
|
|
15842
|
+
existsSync as existsSync23,
|
|
15843
|
+
mkdirSync as mkdirSync14,
|
|
15844
|
+
readFileSync as readFileSync23,
|
|
15365
15845
|
readdirSync as readdirSync10,
|
|
15366
|
-
renameSync as
|
|
15367
|
-
writeFileSync as
|
|
15846
|
+
renameSync as renameSync3,
|
|
15847
|
+
writeFileSync as writeFileSync14
|
|
15368
15848
|
} from "node:fs";
|
|
15369
|
-
import { join as
|
|
15849
|
+
import { join as join25 } from "node:path";
|
|
15370
15850
|
async function analyzeModules(candidates, parser2, opts, report, progress) {
|
|
15371
15851
|
const exportsByModule = new Map;
|
|
15372
15852
|
const importsByModule = new Map;
|
|
@@ -15485,9 +15965,9 @@ async function embedOnEmit(cfg, opts, report) {
|
|
|
15485
15965
|
if (!embedOptIn || report.modules.emitted === 0)
|
|
15486
15966
|
return;
|
|
15487
15967
|
try {
|
|
15488
|
-
const { buildIndex: buildIndex2 } = await Promise.resolve().then(() => (
|
|
15968
|
+
const { buildIndex: buildIndex2 } = await Promise.resolve().then(() => (init_query2(), exports_query));
|
|
15489
15969
|
const idx = await buildIndex2(cfg);
|
|
15490
|
-
|
|
15970
|
+
appendLog3(cfg.vaultPath, "embeddings-updated", `${Object.keys(idx.entries).length} notes`, "code-analysis");
|
|
15491
15971
|
} catch (err) {
|
|
15492
15972
|
report.errors.push(`embed-on-emit: ${err instanceof Error ? err.message : String(err)}`);
|
|
15493
15973
|
}
|
|
@@ -15495,11 +15975,11 @@ async function embedOnEmit(cfg, opts, report) {
|
|
|
15495
15975
|
function executeArchiveOps(vaultPath, archiveOps, report) {
|
|
15496
15976
|
for (const op of archiveOps) {
|
|
15497
15977
|
try {
|
|
15498
|
-
const fromPath =
|
|
15499
|
-
const toPath =
|
|
15500
|
-
if (
|
|
15501
|
-
|
|
15502
|
-
|
|
15978
|
+
const fromPath = join25(vaultPath, op.from);
|
|
15979
|
+
const toPath = join25(vaultPath, op.to);
|
|
15980
|
+
if (existsSync23(fromPath)) {
|
|
15981
|
+
mkdirSync14(join25(vaultPath, "archive"), { recursive: true });
|
|
15982
|
+
renameSync3(fromPath, toPath);
|
|
15503
15983
|
report.modules.archived++;
|
|
15504
15984
|
}
|
|
15505
15985
|
} catch (err) {
|
|
@@ -15511,11 +15991,11 @@ function finalizeLog(vaultPath, descriptors, report) {
|
|
|
15511
15991
|
const logEntry = buildLogEntry(report);
|
|
15512
15992
|
const llmContentPersisted = descriptors.some((d) => !d.staticOnly && !d.fallback);
|
|
15513
15993
|
const logSource = llmContentPersisted ? "llm-inference" : "code-analysis";
|
|
15514
|
-
|
|
15994
|
+
appendLog3(vaultPath, report.errors.some((e) => e.startsWith("write-error:")) ? "map-aborted" : "map-complete", logEntry, logSource);
|
|
15515
15995
|
}
|
|
15516
15996
|
function readExistingModules(vaultPath) {
|
|
15517
|
-
const knowledgeDir =
|
|
15518
|
-
if (!
|
|
15997
|
+
const knowledgeDir = join25(vaultPath, "knowledge");
|
|
15998
|
+
if (!existsSync23(knowledgeDir))
|
|
15519
15999
|
return [];
|
|
15520
16000
|
const results = [];
|
|
15521
16001
|
try {
|
|
@@ -15524,7 +16004,7 @@ function readExistingModules(vaultPath) {
|
|
|
15524
16004
|
if (!file.startsWith("module-") || !file.endsWith(".md"))
|
|
15525
16005
|
continue;
|
|
15526
16006
|
try {
|
|
15527
|
-
const content =
|
|
16007
|
+
const content = readFileSync23(join25(knowledgeDir, file), "utf-8");
|
|
15528
16008
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
15529
16009
|
if (!fmMatch)
|
|
15530
16010
|
continue;
|
|
@@ -15557,22 +16037,22 @@ function extractFmArray(fm, key) {
|
|
|
15557
16037
|
}
|
|
15558
16038
|
return [];
|
|
15559
16039
|
}
|
|
15560
|
-
function
|
|
16040
|
+
function appendLog3(vaultPath, kind, detail, source = "code-analysis") {
|
|
15561
16041
|
const ts4 = new Date().toISOString();
|
|
15562
16042
|
const line = `- ${ts4} ${kind} ${detail} source: ${source}
|
|
15563
16043
|
`;
|
|
15564
|
-
const logPath =
|
|
15565
|
-
|
|
15566
|
-
if (!
|
|
15567
|
-
|
|
16044
|
+
const logPath = join25(vaultPath, "_log.md");
|
|
16045
|
+
mkdirSync14(vaultPath, { recursive: true });
|
|
16046
|
+
if (!existsSync23(logPath)) {
|
|
16047
|
+
writeFileSync14(logPath, `# Vault log
|
|
15568
16048
|
|
|
15569
16049
|
${line}`, "utf-8");
|
|
15570
16050
|
return;
|
|
15571
16051
|
}
|
|
15572
|
-
const content =
|
|
16052
|
+
const content = readFileSync23(logPath, "utf-8");
|
|
15573
16053
|
const needsNl = content.length > 0 && !content.endsWith(`
|
|
15574
16054
|
`);
|
|
15575
|
-
|
|
16055
|
+
writeFileSync14(logPath, content + (needsNl ? `
|
|
15576
16056
|
` : "") + line, "utf-8");
|
|
15577
16057
|
}
|
|
15578
16058
|
function buildLogEntry(report) {
|
|
@@ -15617,7 +16097,7 @@ async function runMapping(cfg, indexResult, opts) {
|
|
|
15617
16097
|
const candidates = discoverModules({ projectRoot: cfg.projectRoot, indexResult });
|
|
15618
16098
|
report.modules.discovered = candidates.length;
|
|
15619
16099
|
if (candidates.length === 0) {
|
|
15620
|
-
|
|
16100
|
+
appendLog3(cfg.vaultPath, "map-complete", "0 modules discovered — nothing to map");
|
|
15621
16101
|
return report;
|
|
15622
16102
|
}
|
|
15623
16103
|
progress({ phase: "analyze", current: 0, total: candidates.length });
|
|
@@ -15660,7 +16140,7 @@ async function runMapping(cfg, indexResult, opts) {
|
|
|
15660
16140
|
finalizeLog(cfg.vaultPath, descriptors, report);
|
|
15661
16141
|
} catch (err) {
|
|
15662
16142
|
report.errors.push(`pipeline-error: ${err instanceof Error ? err.message : String(err)}`);
|
|
15663
|
-
|
|
16143
|
+
appendLog3(cfg.vaultPath, "map-aborted", `pipeline-error: ${err instanceof Error ? err.message : String(err)}`);
|
|
15664
16144
|
}
|
|
15665
16145
|
return report;
|
|
15666
16146
|
}
|
|
@@ -15683,18 +16163,18 @@ var init_mapper = __esm(() => {
|
|
|
15683
16163
|
});
|
|
15684
16164
|
|
|
15685
16165
|
// src/config/settings.ts
|
|
15686
|
-
import { existsSync as
|
|
16166
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync28, writeFileSync as writeFileSync17 } from "node:fs";
|
|
15687
16167
|
import { dirname as dirname10 } from "node:path";
|
|
15688
16168
|
function defaultSettings() {
|
|
15689
16169
|
return { version: SETTINGS_VERSION };
|
|
15690
16170
|
}
|
|
15691
16171
|
function loadSettings() {
|
|
15692
16172
|
const path4 = settingsPath();
|
|
15693
|
-
if (!
|
|
16173
|
+
if (!existsSync28(path4))
|
|
15694
16174
|
return defaultSettings();
|
|
15695
16175
|
let raw;
|
|
15696
16176
|
try {
|
|
15697
|
-
raw =
|
|
16177
|
+
raw = readFileSync28(path4, "utf8");
|
|
15698
16178
|
} catch {
|
|
15699
16179
|
return defaultSettings();
|
|
15700
16180
|
}
|
|
@@ -15734,13 +16214,13 @@ function loadSettings() {
|
|
|
15734
16214
|
function saveSettings(settings) {
|
|
15735
16215
|
const path4 = settingsPath();
|
|
15736
16216
|
const dir = dirname10(path4);
|
|
15737
|
-
if (!
|
|
15738
|
-
|
|
16217
|
+
if (!existsSync28(dir)) {
|
|
16218
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
15739
16219
|
}
|
|
15740
16220
|
const toWrite = { ...settings, version: SETTINGS_VERSION };
|
|
15741
16221
|
const body = `${JSON.stringify(toWrite, null, 2)}
|
|
15742
16222
|
`;
|
|
15743
|
-
|
|
16223
|
+
writeFileSync17(path4, body, { mode: 384 });
|
|
15744
16224
|
}
|
|
15745
16225
|
var SETTINGS_VERSION = 1;
|
|
15746
16226
|
var init_settings = __esm(() => {
|
|
@@ -19714,15 +20194,15 @@ var init_zod = __esm(() => {
|
|
|
19714
20194
|
});
|
|
19715
20195
|
|
|
19716
20196
|
// src/vault/lint.ts
|
|
19717
|
-
import { existsSync as
|
|
19718
|
-
import { join as
|
|
20197
|
+
import { existsSync as existsSync38, readFileSync as readFileSync32, readdirSync as readdirSync14, statSync as statSync10, writeFileSync as writeFileSync21 } from "node:fs";
|
|
20198
|
+
import { join as join42, relative as relative6 } from "node:path";
|
|
19719
20199
|
function toPosix(p) {
|
|
19720
20200
|
return p.split("\\").join("/");
|
|
19721
20201
|
}
|
|
19722
20202
|
function walkFolder(vaultPath, folder) {
|
|
19723
20203
|
const out = [];
|
|
19724
|
-
const folderAbs =
|
|
19725
|
-
if (!
|
|
20204
|
+
const folderAbs = join42(vaultPath, folder);
|
|
20205
|
+
if (!existsSync38(folderAbs))
|
|
19726
20206
|
return out;
|
|
19727
20207
|
const walk = (dir) => {
|
|
19728
20208
|
let entries;
|
|
@@ -19732,7 +20212,7 @@ function walkFolder(vaultPath, folder) {
|
|
|
19732
20212
|
return;
|
|
19733
20213
|
}
|
|
19734
20214
|
for (const entry of entries) {
|
|
19735
|
-
const abs =
|
|
20215
|
+
const abs = join42(dir, entry);
|
|
19736
20216
|
let s;
|
|
19737
20217
|
try {
|
|
19738
20218
|
s = statSync10(abs);
|
|
@@ -19751,7 +20231,7 @@ function walkFolder(vaultPath, folder) {
|
|
|
19751
20231
|
continue;
|
|
19752
20232
|
let raw = "";
|
|
19753
20233
|
try {
|
|
19754
|
-
raw =
|
|
20234
|
+
raw = readFileSync32(abs, "utf-8");
|
|
19755
20235
|
} catch {
|
|
19756
20236
|
continue;
|
|
19757
20237
|
}
|
|
@@ -19843,8 +20323,8 @@ async function lintVault(cfg, opts = {}) {
|
|
|
19843
20323
|
for (const n of notes)
|
|
19844
20324
|
basenameSet.add(n.basename);
|
|
19845
20325
|
for (const folder of NOTE_FOLDERS) {
|
|
19846
|
-
const idx =
|
|
19847
|
-
if (!
|
|
20326
|
+
const idx = join42(vaultPath, folder, "_index.md");
|
|
20327
|
+
if (!existsSync38(idx)) {
|
|
19848
20328
|
issues.push({
|
|
19849
20329
|
kind: "missing-index",
|
|
19850
20330
|
file: `${folder}/_index.md`,
|
|
@@ -19935,8 +20415,8 @@ async function lintVault(cfg, opts = {}) {
|
|
|
19935
20415
|
const srcPath = note.frontmatter.source_path;
|
|
19936
20416
|
const lastVerified = note.frontmatter.last_verified;
|
|
19937
20417
|
if (typeof srcPath === "string" && srcPath.trim() !== "" && lastVerified != null) {
|
|
19938
|
-
const srcAbs =
|
|
19939
|
-
if (
|
|
20418
|
+
const srcAbs = join42(cfg.projectRoot, srcPath);
|
|
20419
|
+
if (existsSync38(srcAbs)) {
|
|
19940
20420
|
let srcMtime = null;
|
|
19941
20421
|
try {
|
|
19942
20422
|
srcMtime = statSync10(srcAbs).mtime;
|
|
@@ -19962,9 +20442,9 @@ async function lintVault(cfg, opts = {}) {
|
|
|
19962
20442
|
return;
|
|
19963
20443
|
if (issue.kind === "missing-index") {
|
|
19964
20444
|
const [folder] = issue.file.split("/");
|
|
19965
|
-
const dest =
|
|
20445
|
+
const dest = join42(vaultPath, folder, "_index.md");
|
|
19966
20446
|
try {
|
|
19967
|
-
|
|
20447
|
+
writeFileSync21(dest, subfolderIndexContent(folder), "utf-8");
|
|
19968
20448
|
if (!fixed.includes(issue.file))
|
|
19969
20449
|
fixed.push(issue.file);
|
|
19970
20450
|
resolvedIssueIds.add(idx);
|
|
@@ -19972,13 +20452,13 @@ async function lintVault(cfg, opts = {}) {
|
|
|
19972
20452
|
return;
|
|
19973
20453
|
}
|
|
19974
20454
|
if (issue.kind === "frontmatter") {
|
|
19975
|
-
const abs =
|
|
20455
|
+
const abs = join42(vaultPath, issue.file);
|
|
19976
20456
|
try {
|
|
19977
|
-
const raw =
|
|
20457
|
+
const raw = readFileSync32(abs, "utf-8");
|
|
19978
20458
|
const parsed = parseFrontmatter(raw);
|
|
19979
20459
|
const rewritten = `${serializeFrontmatter(parsed.frontmatter)}${parsed.content}`;
|
|
19980
20460
|
if (rewritten !== raw) {
|
|
19981
|
-
|
|
20461
|
+
writeFileSync21(abs, rewritten, "utf-8");
|
|
19982
20462
|
if (!fixed.includes(issue.file))
|
|
19983
20463
|
fixed.push(issue.file);
|
|
19984
20464
|
resolvedIssueIds.add(idx);
|
|
@@ -20003,7 +20483,8 @@ async function lintVault(cfg, opts = {}) {
|
|
|
20003
20483
|
var META_FILENAMES, WIKILINK_RE3, LINK_FRONTMATTER_FIELDS;
|
|
20004
20484
|
var init_lint = __esm(() => {
|
|
20005
20485
|
init_conventions();
|
|
20006
|
-
|
|
20486
|
+
init_conventions();
|
|
20487
|
+
init_indexing();
|
|
20007
20488
|
init_storage();
|
|
20008
20489
|
init_storage();
|
|
20009
20490
|
META_FILENAMES = new Set(["_index.md", "_log.md", "_conventions.md"]);
|
|
@@ -20024,446 +20505,16 @@ function detectProvider(explicitProvider) {
|
|
|
20024
20505
|
return "claude";
|
|
20025
20506
|
}
|
|
20026
20507
|
|
|
20027
|
-
// src/vault/query/cacheAside.ts
|
|
20028
|
-
import { createHash as createHash5 } from "node:crypto";
|
|
20029
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync19, readFileSync as readFileSync30, renameSync as renameSync4, writeFileSync as writeFileSync20 } from "node:fs";
|
|
20030
|
-
import { tmpdir as tmpdir2 } from "node:os";
|
|
20031
|
-
import { join as join39 } from "node:path";
|
|
20032
|
-
function cachePath2(vaultPath) {
|
|
20033
|
-
return join39(vaultPath, ".cache", CACHE_FILENAME);
|
|
20034
|
-
}
|
|
20035
|
-
function emptyCache() {
|
|
20036
|
-
return { schemaVersion: SCHEMA_VERSION4, entries: [] };
|
|
20037
|
-
}
|
|
20038
|
-
function isValidCache(value) {
|
|
20039
|
-
if (typeof value !== "object" || value === null)
|
|
20040
|
-
return false;
|
|
20041
|
-
const v = value;
|
|
20042
|
-
return v.schemaVersion === SCHEMA_VERSION4 && Array.isArray(v.entries);
|
|
20043
|
-
}
|
|
20044
|
-
function loadCacheFile(vaultPath) {
|
|
20045
|
-
const path4 = cachePath2(vaultPath);
|
|
20046
|
-
if (!existsSync35(path4))
|
|
20047
|
-
return emptyCache();
|
|
20048
|
-
try {
|
|
20049
|
-
const raw = JSON.parse(readFileSync30(path4, "utf-8"));
|
|
20050
|
-
if (!isValidCache(raw))
|
|
20051
|
-
return emptyCache();
|
|
20052
|
-
return raw;
|
|
20053
|
-
} catch (err) {
|
|
20054
|
-
logForDebugging(`[query/cache] load failed (resetting): ${errorMessage(err)}`, {
|
|
20055
|
-
level: "warn"
|
|
20056
|
-
});
|
|
20057
|
-
return emptyCache();
|
|
20058
|
-
}
|
|
20059
|
-
}
|
|
20060
|
-
function persistCacheFile(vaultPath, file) {
|
|
20061
|
-
const dir = join39(vaultPath, ".cache");
|
|
20062
|
-
mkdirSync19(dir, { recursive: true });
|
|
20063
|
-
const gi = join39(dir, ".gitignore");
|
|
20064
|
-
if (!existsSync35(gi)) {
|
|
20065
|
-
try {
|
|
20066
|
-
writeFileSync20(gi, `*
|
|
20067
|
-
!.gitignore
|
|
20068
|
-
`, "utf-8");
|
|
20069
|
-
} catch {}
|
|
20070
|
-
}
|
|
20071
|
-
const tmp = join39(tmpdir2(), `bridgeai-qcache-${process.pid}-${Date.now()}.json`);
|
|
20072
|
-
try {
|
|
20073
|
-
writeFileSync20(tmp, JSON.stringify(file), "utf-8");
|
|
20074
|
-
renameSync4(tmp, cachePath2(vaultPath));
|
|
20075
|
-
} catch (err) {
|
|
20076
|
-
logForDebugging(`[query/cache] persist failed: ${errorMessage(err)}`, { level: "warn" });
|
|
20077
|
-
}
|
|
20078
|
-
}
|
|
20079
|
-
function hashQuery(query) {
|
|
20080
|
-
return createHash5("sha256").update(query.trim().toLowerCase()).digest("hex");
|
|
20081
|
-
}
|
|
20082
|
-
function lookup(vaultPath, _query, vec) {
|
|
20083
|
-
if (isZeroVector(vec))
|
|
20084
|
-
return null;
|
|
20085
|
-
const file = loadCacheFile(vaultPath);
|
|
20086
|
-
if (file.entries.length === 0)
|
|
20087
|
-
return null;
|
|
20088
|
-
let best = null;
|
|
20089
|
-
for (const entry of file.entries) {
|
|
20090
|
-
const score = cosine(vec, entry.vector);
|
|
20091
|
-
if (score < CACHE_HIT_THRESHOLD)
|
|
20092
|
-
continue;
|
|
20093
|
-
if (best === null || score > best.score)
|
|
20094
|
-
best = { entry, score };
|
|
20095
|
-
}
|
|
20096
|
-
if (!best)
|
|
20097
|
-
return null;
|
|
20098
|
-
const verifiedMs = Date.parse(best.entry.lastVerified);
|
|
20099
|
-
if (!Number.isFinite(verifiedMs))
|
|
20100
|
-
return null;
|
|
20101
|
-
for (const note of best.entry.topK) {
|
|
20102
|
-
if (safeMtimeMs(note.path) > verifiedMs)
|
|
20103
|
-
return null;
|
|
20104
|
-
}
|
|
20105
|
-
return best.entry;
|
|
20106
|
-
}
|
|
20107
|
-
function fill(vaultPath, query, vec, topK) {
|
|
20108
|
-
if (isZeroVector(vec))
|
|
20109
|
-
return;
|
|
20110
|
-
const file = loadCacheFile(vaultPath);
|
|
20111
|
-
const nowMs = Date.now();
|
|
20112
|
-
const nowStr = new Date(nowMs).toISOString();
|
|
20113
|
-
const maxMtimeMs = topK.reduce((m, n) => Math.max(m, safeMtimeMs(n.path)), 0);
|
|
20114
|
-
const lastVerifiedMs = maxMtimeMs > 0 ? Math.max(nowMs, maxMtimeMs + 1) : nowMs;
|
|
20115
|
-
const lastVerifiedStr = new Date(lastVerifiedMs).toISOString();
|
|
20116
|
-
const queryHash = hashQuery(query);
|
|
20117
|
-
const existingIdx = file.entries.findIndex((e) => e.queryHash === queryHash);
|
|
20118
|
-
const entry = {
|
|
20119
|
-
queryHash,
|
|
20120
|
-
query,
|
|
20121
|
-
vector: vec,
|
|
20122
|
-
topK,
|
|
20123
|
-
lastVerified: lastVerifiedStr,
|
|
20124
|
-
lastQueried: nowStr
|
|
20125
|
-
};
|
|
20126
|
-
if (existingIdx >= 0) {
|
|
20127
|
-
file.entries[existingIdx] = entry;
|
|
20128
|
-
} else {
|
|
20129
|
-
file.entries.push(entry);
|
|
20130
|
-
}
|
|
20131
|
-
if (file.entries.length > MAX_ENTRIES) {
|
|
20132
|
-
file.entries.sort((a, b) => a.lastQueried.localeCompare(b.lastQueried));
|
|
20133
|
-
file.entries = file.entries.slice(file.entries.length - MAX_ENTRIES);
|
|
20134
|
-
}
|
|
20135
|
-
persistCacheFile(vaultPath, file);
|
|
20136
|
-
}
|
|
20137
|
-
function touch(vaultPath, queryHash) {
|
|
20138
|
-
const file = loadCacheFile(vaultPath);
|
|
20139
|
-
const idx = file.entries.findIndex((e) => e.queryHash === queryHash);
|
|
20140
|
-
if (idx < 0)
|
|
20141
|
-
return;
|
|
20142
|
-
file.entries[idx].lastQueried = new Date().toISOString();
|
|
20143
|
-
persistCacheFile(vaultPath, file);
|
|
20144
|
-
}
|
|
20145
|
-
function coalesceCall(key, factory) {
|
|
20146
|
-
const existing = inFlight.get(key);
|
|
20147
|
-
if (existing)
|
|
20148
|
-
return existing;
|
|
20149
|
-
const fresh = factory().finally(() => {
|
|
20150
|
-
inFlight.delete(key);
|
|
20151
|
-
});
|
|
20152
|
-
inFlight.set(key, fresh);
|
|
20153
|
-
return fresh;
|
|
20154
|
-
}
|
|
20155
|
-
var CACHE_FILENAME = "query-cache.json", SCHEMA_VERSION4 = "1", MAX_ENTRIES = 100, inFlight;
|
|
20156
|
-
var init_cacheAside = __esm(() => {
|
|
20157
|
-
init_utils();
|
|
20158
|
-
init_utils();
|
|
20159
|
-
init_embeddings();
|
|
20160
|
-
init_query();
|
|
20161
|
-
inFlight = new Map;
|
|
20162
|
-
});
|
|
20163
|
-
|
|
20164
|
-
// src/vault/query/expansion.ts
|
|
20165
|
-
import { existsSync as existsSync36, readFileSync as readFileSync31 } from "node:fs";
|
|
20166
|
-
import { join as join40 } from "node:path";
|
|
20167
|
-
function findGlobalSlugsInBody(text) {
|
|
20168
|
-
const out = [];
|
|
20169
|
-
let match;
|
|
20170
|
-
while ((match = WIKILINK_REGEX.exec(text)) !== null) {
|
|
20171
|
-
const raw = match[1];
|
|
20172
|
-
if (!raw)
|
|
20173
|
-
continue;
|
|
20174
|
-
const target = parseWikiLinkTarget(raw);
|
|
20175
|
-
if (target.vault === "global")
|
|
20176
|
-
out.push(target.slug);
|
|
20177
|
-
}
|
|
20178
|
-
return out;
|
|
20179
|
-
}
|
|
20180
|
-
function findGlobalSlugsInRelated(related) {
|
|
20181
|
-
if (!Array.isArray(related))
|
|
20182
|
-
return [];
|
|
20183
|
-
const out = [];
|
|
20184
|
-
for (const r of related) {
|
|
20185
|
-
if (typeof r !== "string")
|
|
20186
|
-
continue;
|
|
20187
|
-
const stripped = r.replace(/^\[\[|\]\]$/g, "");
|
|
20188
|
-
const target = parseWikiLinkTarget(stripped);
|
|
20189
|
-
if (target.vault === "global")
|
|
20190
|
-
out.push(target.slug);
|
|
20191
|
-
}
|
|
20192
|
-
return out;
|
|
20193
|
-
}
|
|
20194
|
-
function readGlobalNoteBody(globalPath, slug) {
|
|
20195
|
-
for (const folder of NOTE_FOLDERS) {
|
|
20196
|
-
const p = join40(globalPath, folder, `${slug}.md`);
|
|
20197
|
-
if (!existsSync36(p))
|
|
20198
|
-
continue;
|
|
20199
|
-
try {
|
|
20200
|
-
const raw = readFileSync31(p, "utf-8");
|
|
20201
|
-
const parsed = parseFrontmatter(raw);
|
|
20202
|
-
return parsed.content ?? "";
|
|
20203
|
-
} catch (err) {
|
|
20204
|
-
logForDebugging(`[query/expansion] read failed ${p}: ${errorMessage(err)}`, {
|
|
20205
|
-
level: "warn"
|
|
20206
|
-
});
|
|
20207
|
-
return null;
|
|
20208
|
-
}
|
|
20209
|
-
}
|
|
20210
|
-
return null;
|
|
20211
|
-
}
|
|
20212
|
-
async function readGlobalNoteBodyVia(globalPath, slug, noteAccess2) {
|
|
20213
|
-
for (const folder of NOTE_FOLDERS) {
|
|
20214
|
-
const p = join40(globalPath, folder, `${slug}.md`);
|
|
20215
|
-
if (!existsSync36(p))
|
|
20216
|
-
continue;
|
|
20217
|
-
try {
|
|
20218
|
-
const raw = await noteAccess2.readUserNote(p);
|
|
20219
|
-
if (!raw)
|
|
20220
|
-
return "";
|
|
20221
|
-
const parsed = parseFrontmatter(raw);
|
|
20222
|
-
return parsed.content ?? "";
|
|
20223
|
-
} catch (err) {
|
|
20224
|
-
logForDebugging(`[query/expansion] read failed ${p}: ${errorMessage(err)}`, {
|
|
20225
|
-
level: "warn"
|
|
20226
|
-
});
|
|
20227
|
-
return null;
|
|
20228
|
-
}
|
|
20229
|
-
}
|
|
20230
|
-
return null;
|
|
20231
|
-
}
|
|
20232
|
-
function collectGlobalSlugs(note) {
|
|
20233
|
-
const fmRelated = note.related;
|
|
20234
|
-
return new Set([
|
|
20235
|
-
...findGlobalSlugsInBody(note.summary),
|
|
20236
|
-
...findGlobalSlugsInRelated(fmRelated)
|
|
20237
|
-
]);
|
|
20238
|
-
}
|
|
20239
|
-
function appendExpansion(expansions, slug, body, charsUsed) {
|
|
20240
|
-
const remaining = EXPANSION_BUDGET_CHARS - charsUsed;
|
|
20241
|
-
if (body.length <= remaining) {
|
|
20242
|
-
expansions.push({ slug, scope: "global", body, truncated: false });
|
|
20243
|
-
return { charsUsed: charsUsed + body.length, truncated: false };
|
|
20244
|
-
}
|
|
20245
|
-
expansions.push({ slug, scope: "global", body: body.slice(0, remaining), truncated: true });
|
|
20246
|
-
return { charsUsed: EXPANSION_BUDGET_CHARS, truncated: true };
|
|
20247
|
-
}
|
|
20248
|
-
function pushBudgetExceeded(expansions, slug) {
|
|
20249
|
-
expansions.push({ slug, scope: "global", body: "", truncated: true });
|
|
20250
|
-
}
|
|
20251
|
-
function expandLinks(cfg, results) {
|
|
20252
|
-
if (!cfg.global)
|
|
20253
|
-
return { results };
|
|
20254
|
-
const globalPath = cfg.global.path;
|
|
20255
|
-
let charsUsed = 0;
|
|
20256
|
-
let truncatedFlag = false;
|
|
20257
|
-
const out = [];
|
|
20258
|
-
for (const note of results) {
|
|
20259
|
-
const expansions = [];
|
|
20260
|
-
for (const slug of collectGlobalSlugs(note)) {
|
|
20261
|
-
if (charsUsed >= EXPANSION_BUDGET_CHARS) {
|
|
20262
|
-
pushBudgetExceeded(expansions, slug);
|
|
20263
|
-
truncatedFlag = true;
|
|
20264
|
-
continue;
|
|
20265
|
-
}
|
|
20266
|
-
const body = readGlobalNoteBody(globalPath, slug);
|
|
20267
|
-
if (body === null)
|
|
20268
|
-
continue;
|
|
20269
|
-
const r = appendExpansion(expansions, slug, body, charsUsed);
|
|
20270
|
-
charsUsed = r.charsUsed;
|
|
20271
|
-
if (r.truncated)
|
|
20272
|
-
truncatedFlag = true;
|
|
20273
|
-
}
|
|
20274
|
-
out.push(expansions.length > 0 ? { ...note, expanded_links: expansions } : note);
|
|
20275
|
-
}
|
|
20276
|
-
return truncatedFlag ? { results: out, warning: TRUNCATION_WARNING } : { results: out };
|
|
20277
|
-
}
|
|
20278
|
-
async function expandLinksAsync(cfg, results, noteAccess2) {
|
|
20279
|
-
if (!cfg.global)
|
|
20280
|
-
return { results };
|
|
20281
|
-
const globalPath = cfg.global.path;
|
|
20282
|
-
let charsUsed = 0;
|
|
20283
|
-
let truncatedFlag = false;
|
|
20284
|
-
const out = [];
|
|
20285
|
-
for (const note of results) {
|
|
20286
|
-
const expansions = [];
|
|
20287
|
-
for (const slug of collectGlobalSlugs(note)) {
|
|
20288
|
-
if (charsUsed >= EXPANSION_BUDGET_CHARS) {
|
|
20289
|
-
pushBudgetExceeded(expansions, slug);
|
|
20290
|
-
truncatedFlag = true;
|
|
20291
|
-
continue;
|
|
20292
|
-
}
|
|
20293
|
-
const body = await readGlobalNoteBodyVia(globalPath, slug, noteAccess2);
|
|
20294
|
-
if (body === null)
|
|
20295
|
-
continue;
|
|
20296
|
-
const r = appendExpansion(expansions, slug, body, charsUsed);
|
|
20297
|
-
charsUsed = r.charsUsed;
|
|
20298
|
-
if (r.truncated)
|
|
20299
|
-
truncatedFlag = true;
|
|
20300
|
-
}
|
|
20301
|
-
out.push(expansions.length > 0 ? { ...note, expanded_links: expansions } : note);
|
|
20302
|
-
}
|
|
20303
|
-
return truncatedFlag ? { results: out, warning: TRUNCATION_WARNING } : { results: out };
|
|
20304
|
-
}
|
|
20305
|
-
var WIKILINK_REGEX, TRUNCATION_WARNING;
|
|
20306
|
-
var init_expansion = __esm(() => {
|
|
20307
|
-
init_utils();
|
|
20308
|
-
init_storage();
|
|
20309
|
-
init_embeddings();
|
|
20310
|
-
WIKILINK_REGEX = /\[\[([^\]]+)\]\]/g;
|
|
20311
|
-
TRUNCATION_WARNING = `Expansion budget (${EXPANSION_BUDGET_CHARS} chars) reached; some [[global:...]] references returned truncated or empty.`;
|
|
20312
|
-
});
|
|
20313
|
-
|
|
20314
|
-
// src/vault/query/query.ts
|
|
20315
|
-
import { existsSync as existsSync37, readFileSync as readFileSync32, writeFileSync as writeFileSync21 } from "node:fs";
|
|
20316
|
-
import { join as join41 } from "node:path";
|
|
20317
|
-
function sanitize(opts) {
|
|
20318
|
-
const limit = Math.min(Math.max(1, Math.floor(opts.limit ?? DEFAULT_LIMIT4)), MAX_LIMIT2);
|
|
20319
|
-
return {
|
|
20320
|
-
query: opts.query.trim(),
|
|
20321
|
-
limit,
|
|
20322
|
-
scope: opts.scope ?? "both",
|
|
20323
|
-
expand: opts.expand ?? true
|
|
20324
|
-
};
|
|
20325
|
-
}
|
|
20326
|
-
function indexEntryToResult(filename, entry, vaultLocalPath, vaultGlobalPath, score) {
|
|
20327
|
-
const root = entry.scope === "global" ? vaultGlobalPath ?? vaultLocalPath : vaultLocalPath;
|
|
20328
|
-
return {
|
|
20329
|
-
filename,
|
|
20330
|
-
folder: entry.folder,
|
|
20331
|
-
path: join41(root, entry.folder, `${filename}.md`),
|
|
20332
|
-
scope: entry.scope,
|
|
20333
|
-
score,
|
|
20334
|
-
summary: entry.summary
|
|
20335
|
-
};
|
|
20336
|
-
}
|
|
20337
|
-
function topK(index, queryVec, limit, scope, cfg) {
|
|
20338
|
-
const localPath = cfg.local.path;
|
|
20339
|
-
const globalPath = cfg.global ? cfg.global.path : null;
|
|
20340
|
-
const scored = [];
|
|
20341
|
-
for (const [filename, entry] of Object.entries(index.entries)) {
|
|
20342
|
-
if (scope !== "both" && entry.scope !== scope)
|
|
20343
|
-
continue;
|
|
20344
|
-
if (entry.vector.length !== queryVec.length)
|
|
20345
|
-
continue;
|
|
20346
|
-
const score = cosine(queryVec, entry.vector);
|
|
20347
|
-
if (!Number.isFinite(score))
|
|
20348
|
-
continue;
|
|
20349
|
-
scored.push({ filename, score, entry });
|
|
20350
|
-
}
|
|
20351
|
-
scored.sort((a, b) => b.score - a.score);
|
|
20352
|
-
return scored.slice(0, limit).map((s) => indexEntryToResult(s.filename, s.entry, localPath, globalPath, s.score));
|
|
20353
|
-
}
|
|
20354
|
-
function appendLog3(vaultPath, kind, detail = "") {
|
|
20355
|
-
const ts4 = new Date().toISOString();
|
|
20356
|
-
const line = `- ${ts4} ${kind}${detail ? ` ${detail}` : ""} source: code-analysis
|
|
20357
|
-
`;
|
|
20358
|
-
const logPath = join41(vaultPath, "_log.md");
|
|
20359
|
-
try {
|
|
20360
|
-
if (!existsSync37(logPath)) {
|
|
20361
|
-
writeFileSync21(logPath, `# Vault log
|
|
20362
|
-
|
|
20363
|
-
${line}`, "utf-8");
|
|
20364
|
-
return;
|
|
20365
|
-
}
|
|
20366
|
-
const content = readFileSync32(logPath, "utf-8");
|
|
20367
|
-
const needsNl = content.length > 0 && !content.endsWith(`
|
|
20368
|
-
`);
|
|
20369
|
-
writeFileSync21(logPath, content + (needsNl ? `
|
|
20370
|
-
` : "") + line, "utf-8");
|
|
20371
|
-
} catch (err) {
|
|
20372
|
-
logForDebugging(`[query] log append failed: ${errorMessage(err)}`, {
|
|
20373
|
-
level: "warn"
|
|
20374
|
-
});
|
|
20375
|
-
}
|
|
20376
|
-
}
|
|
20377
|
-
async function ensureIndex(cfg) {
|
|
20378
|
-
const existing = loadIndex(cfg.local.path);
|
|
20379
|
-
if (existing && Object.keys(existing.entries).length > 0)
|
|
20380
|
-
return existing;
|
|
20381
|
-
const fresh = await buildIndex(cfg);
|
|
20382
|
-
appendLog3(cfg.local.path, "embeddings-built", `${Object.keys(fresh.entries).length} notes`);
|
|
20383
|
-
return fresh;
|
|
20384
|
-
}
|
|
20385
|
-
function emptyEnvelope(error) {
|
|
20386
|
-
return {
|
|
20387
|
-
ok: error === undefined,
|
|
20388
|
-
results: [],
|
|
20389
|
-
cacheHit: false,
|
|
20390
|
-
servedAt: new Date().toISOString(),
|
|
20391
|
-
...error ? { error } : {}
|
|
20392
|
-
};
|
|
20393
|
-
}
|
|
20394
|
-
async function vaultQuery(cfg, opts, extras = {}) {
|
|
20395
|
-
try {
|
|
20396
|
-
if (!opts.query || !opts.query.trim()) {
|
|
20397
|
-
return emptyEnvelope("empty query");
|
|
20398
|
-
}
|
|
20399
|
-
const sanitized = sanitize(opts);
|
|
20400
|
-
const vaultPath = cfg.vaultPath ?? cfg.local.path;
|
|
20401
|
-
const cacheKey = hashQuery(sanitized.query);
|
|
20402
|
-
return await coalesceCall(cacheKey, async () => {
|
|
20403
|
-
const index = await ensureIndex(cfg);
|
|
20404
|
-
if (Object.keys(index.entries).length === 0) {
|
|
20405
|
-
return {
|
|
20406
|
-
...emptyEnvelope(),
|
|
20407
|
-
warnings: ["vault has no notes yet"]
|
|
20408
|
-
};
|
|
20409
|
-
}
|
|
20410
|
-
const vec = await embedText(sanitized.query);
|
|
20411
|
-
if (isZeroVector(vec))
|
|
20412
|
-
return emptyEnvelope("embedding failed");
|
|
20413
|
-
const cached = lookup(vaultPath, sanitized.query, vec);
|
|
20414
|
-
if (cached) {
|
|
20415
|
-
touch(vaultPath, cached.queryHash);
|
|
20416
|
-
const filtered = sanitized.scope === "both" ? cached.topK : cached.topK.filter((n) => n.scope === sanitized.scope);
|
|
20417
|
-
return {
|
|
20418
|
-
ok: true,
|
|
20419
|
-
results: filtered.slice(0, sanitized.limit),
|
|
20420
|
-
cacheHit: true,
|
|
20421
|
-
servedAt: new Date().toISOString()
|
|
20422
|
-
};
|
|
20423
|
-
}
|
|
20424
|
-
const k = topK(index, vec, sanitized.limit, sanitized.scope, cfg);
|
|
20425
|
-
let results = k;
|
|
20426
|
-
const warnings = [];
|
|
20427
|
-
if (sanitized.expand) {
|
|
20428
|
-
const expanded = extras.noteAccess ? await expandLinksAsync(cfg, k, extras.noteAccess) : expandLinks(cfg, k);
|
|
20429
|
-
results = expanded.results;
|
|
20430
|
-
if (expanded.warning)
|
|
20431
|
-
warnings.push(expanded.warning);
|
|
20432
|
-
}
|
|
20433
|
-
fill(vaultPath, sanitized.query, vec, results);
|
|
20434
|
-
return {
|
|
20435
|
-
ok: true,
|
|
20436
|
-
results,
|
|
20437
|
-
cacheHit: false,
|
|
20438
|
-
servedAt: new Date().toISOString(),
|
|
20439
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
20440
|
-
};
|
|
20441
|
-
});
|
|
20442
|
-
} catch (err) {
|
|
20443
|
-
logForDebugging(`[query] unexpected: ${errorMessage(err)}`, { level: "warn" });
|
|
20444
|
-
return emptyEnvelope(errorMessage(err));
|
|
20445
|
-
}
|
|
20446
|
-
}
|
|
20447
|
-
var DEFAULT_LIMIT4 = 5, MAX_LIMIT2 = 20;
|
|
20448
|
-
var init_query2 = __esm(() => {
|
|
20449
|
-
init_utils();
|
|
20450
|
-
init_utils();
|
|
20451
|
-
init_cacheAside();
|
|
20452
|
-
init_embeddings();
|
|
20453
|
-
init_expansion();
|
|
20454
|
-
init_query();
|
|
20455
|
-
});
|
|
20456
|
-
|
|
20457
20508
|
// src/vault/index.ts
|
|
20458
20509
|
import { readFileSync as readFileSync33 } from "node:fs";
|
|
20459
|
-
import { basename as basename11, join as
|
|
20510
|
+
import { basename as basename11, join as join43 } from "node:path";
|
|
20460
20511
|
function slugify(input) {
|
|
20461
20512
|
const s = input.toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
20462
20513
|
return s || "untitled";
|
|
20463
20514
|
}
|
|
20464
20515
|
function toInternal(config) {
|
|
20465
20516
|
const provider = detectProvider();
|
|
20466
|
-
const vaultPath =
|
|
20517
|
+
const vaultPath = join43(config.root, ".anchorkit", "vault");
|
|
20467
20518
|
return {
|
|
20468
20519
|
local: { path: vaultPath },
|
|
20469
20520
|
global: config.globalRoot ? { path: config.globalRoot } : null,
|
|
@@ -20541,7 +20592,7 @@ function createVault(config) {
|
|
|
20541
20592
|
if (!result.ok) {
|
|
20542
20593
|
throw new Error(`vault.write failed: ${result.violations.map((v) => `${v.field}: expected ${String(v.expected)}, got ${String(v.got)} (${v.rule})`).join("; ")}`);
|
|
20543
20594
|
}
|
|
20544
|
-
const absPath =
|
|
20595
|
+
const absPath = join43(internal.local.path, result.path);
|
|
20545
20596
|
const written = readNoteFile(absPath);
|
|
20546
20597
|
if (!written) {
|
|
20547
20598
|
throw new Error(`vault.write succeeded but cannot re-read ${absPath}`);
|
|
@@ -20597,7 +20648,8 @@ function createVault(config) {
|
|
|
20597
20648
|
};
|
|
20598
20649
|
}
|
|
20599
20650
|
var init_vault = __esm(() => {
|
|
20600
|
-
|
|
20651
|
+
init_conventions();
|
|
20652
|
+
init_indexing();
|
|
20601
20653
|
init_lint();
|
|
20602
20654
|
init_query2();
|
|
20603
20655
|
init_storage();
|
|
@@ -22492,7 +22544,7 @@ var require_core2 = __commonJS((exports, module) => {
|
|
|
22492
22544
|
return match && match.index === 0;
|
|
22493
22545
|
}
|
|
22494
22546
|
var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
|
|
22495
|
-
function
|
|
22547
|
+
function join44(regexps, separator = "|") {
|
|
22496
22548
|
let numCaptures = 0;
|
|
22497
22549
|
return regexps.map((regex) => {
|
|
22498
22550
|
numCaptures += 1;
|
|
@@ -22775,7 +22827,7 @@ var require_core2 = __commonJS((exports, module) => {
|
|
|
22775
22827
|
this.exec = () => null;
|
|
22776
22828
|
}
|
|
22777
22829
|
const terminators = this.regexes.map((el) => el[1]);
|
|
22778
|
-
this.matcherRe = langRe(
|
|
22830
|
+
this.matcherRe = langRe(join44(terminators), true);
|
|
22779
22831
|
this.lastIndex = 0;
|
|
22780
22832
|
}
|
|
22781
22833
|
exec(s) {
|
|
@@ -76984,11 +77036,11 @@ Implement when the case demands — do not invent these:
|
|
|
76984
77036
|
`;
|
|
76985
77037
|
|
|
76986
77038
|
// src/vault/provider/formatters.ts
|
|
76987
|
-
import { existsSync as
|
|
77039
|
+
import { existsSync as existsSync39, readFileSync as readFileSync34 } from "node:fs";
|
|
76988
77040
|
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync22 } from "node:fs";
|
|
76989
|
-
import { join as
|
|
77041
|
+
import { join as join44 } from "node:path";
|
|
76990
77042
|
function isBridgeAiGenerated(filePath) {
|
|
76991
|
-
if (!
|
|
77043
|
+
if (!existsSync39(filePath))
|
|
76992
77044
|
return false;
|
|
76993
77045
|
try {
|
|
76994
77046
|
const content = readFileSync34(filePath, "utf-8");
|
|
@@ -77015,8 +77067,8 @@ function buildProviderContent(vaultPath, _projectRoot) {
|
|
|
77015
77067
|
"commands.md"
|
|
77016
77068
|
];
|
|
77017
77069
|
for (const docFile of docFiles) {
|
|
77018
|
-
const docPath =
|
|
77019
|
-
if (
|
|
77070
|
+
const docPath = join44(vaultPath, docFile);
|
|
77071
|
+
if (existsSync39(docPath)) {
|
|
77020
77072
|
try {
|
|
77021
77073
|
const content = readFileSync34(docPath, "utf-8");
|
|
77022
77074
|
sections.push(content);
|
|
@@ -77029,15 +77081,15 @@ function buildProviderContent(vaultPath, _projectRoot) {
|
|
|
77029
77081
|
`);
|
|
77030
77082
|
}
|
|
77031
77083
|
function formatForClaude(vaultPath, projectRoot) {
|
|
77032
|
-
const filePath =
|
|
77084
|
+
const filePath = join44(vaultPath, "CLAUDE.md");
|
|
77033
77085
|
const content = buildProviderContent(vaultPath, projectRoot);
|
|
77034
77086
|
mkdirSync20(vaultPath, { recursive: true });
|
|
77035
77087
|
writeFileSync22(filePath, content, "utf-8");
|
|
77036
77088
|
return { filePath, skipped: false };
|
|
77037
77089
|
}
|
|
77038
77090
|
function formatForCursor(vaultPath, projectRoot) {
|
|
77039
|
-
const filePath =
|
|
77040
|
-
if (
|
|
77091
|
+
const filePath = join44(projectRoot, ".cursorrules");
|
|
77092
|
+
if (existsSync39(filePath) && !isBridgeAiGenerated(filePath)) {
|
|
77041
77093
|
return {
|
|
77042
77094
|
filePath,
|
|
77043
77095
|
skipped: true,
|
|
@@ -77049,9 +77101,9 @@ function formatForCursor(vaultPath, projectRoot) {
|
|
|
77049
77101
|
return { filePath, skipped: false };
|
|
77050
77102
|
}
|
|
77051
77103
|
function formatForGemini(vaultPath, projectRoot) {
|
|
77052
|
-
const geminiDir =
|
|
77053
|
-
const filePath =
|
|
77054
|
-
if (
|
|
77104
|
+
const geminiDir = join44(projectRoot, ".gemini");
|
|
77105
|
+
const filePath = join44(geminiDir, "rules.md");
|
|
77106
|
+
if (existsSync39(filePath) && !isBridgeAiGenerated(filePath)) {
|
|
77055
77107
|
return {
|
|
77056
77108
|
filePath,
|
|
77057
77109
|
skipped: true,
|
|
@@ -77079,10 +77131,10 @@ var BRIDGE_AI_MARKER = "<!-- bridge-ai generated -->";
|
|
|
77079
77131
|
var init_formatters = () => {};
|
|
77080
77132
|
|
|
77081
77133
|
// src/vault/state.ts
|
|
77082
|
-
import { existsSync as
|
|
77083
|
-
import { join as
|
|
77134
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync21, readFileSync as readFileSync35, writeFileSync as writeFileSync23 } from "node:fs";
|
|
77135
|
+
import { join as join45 } from "node:path";
|
|
77084
77136
|
function statePath(vaultPath) {
|
|
77085
|
-
return
|
|
77137
|
+
return join45(vaultPath, STATE_FILE);
|
|
77086
77138
|
}
|
|
77087
77139
|
function now() {
|
|
77088
77140
|
return new Date().toISOString();
|
|
@@ -77202,7 +77254,7 @@ async function runMappingForOnboarding(projectRoot, options2) {
|
|
|
77202
77254
|
var init_onboard = __esm(() => {
|
|
77203
77255
|
init_config();
|
|
77204
77256
|
init_storage();
|
|
77205
|
-
|
|
77257
|
+
init_indexing();
|
|
77206
77258
|
init_utils();
|
|
77207
77259
|
init_formatters();
|
|
77208
77260
|
init_storage();
|
|
@@ -79026,8 +79078,8 @@ var init_plan_mode = __esm(() => {
|
|
|
79026
79078
|
|
|
79027
79079
|
// src/tools/request-permission.ts
|
|
79028
79080
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
79029
|
-
import { existsSync as
|
|
79030
|
-
import { join as
|
|
79081
|
+
import { existsSync as existsSync51, mkdirSync as mkdirSync29, readFileSync as readFileSync46, unlinkSync as unlinkSync3, writeFileSync as writeFileSync32 } from "node:fs";
|
|
79082
|
+
import { join as join59 } from "node:path";
|
|
79031
79083
|
function createRequestPermissionTool(opts) {
|
|
79032
79084
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
79033
79085
|
const pollIntervalMs = opts.pollIntervalMs ?? POLL_INTERVAL_MS2;
|
|
@@ -79036,11 +79088,11 @@ function createRequestPermissionTool(opts) {
|
|
|
79036
79088
|
description: "Internal permission prompt — asks the AnchorKit user whether Claude may execute a tool. Used via claude --permission-prompt-tool.",
|
|
79037
79089
|
inputSchema: requestPermissionInputSchema,
|
|
79038
79090
|
async handler(input) {
|
|
79039
|
-
const dir =
|
|
79040
|
-
if (!
|
|
79091
|
+
const dir = join59(opts.cwd, ".anchorkit", "permissions");
|
|
79092
|
+
if (!existsSync51(dir))
|
|
79041
79093
|
mkdirSync29(dir, { recursive: true });
|
|
79042
79094
|
const id = randomUUID2();
|
|
79043
|
-
const file =
|
|
79095
|
+
const file = join59(dir, `${id}.json`);
|
|
79044
79096
|
const payload = {
|
|
79045
79097
|
id,
|
|
79046
79098
|
status: "pending",
|
|
@@ -79171,9 +79223,9 @@ var init_todo_write = __esm(() => {
|
|
|
79171
79223
|
});
|
|
79172
79224
|
|
|
79173
79225
|
// src/tools/vault-map.ts
|
|
79174
|
-
import { basename as basename14, join as
|
|
79226
|
+
import { basename as basename14, join as join60 } from "node:path";
|
|
79175
79227
|
function toInternal2(config) {
|
|
79176
|
-
const vaultPath =
|
|
79228
|
+
const vaultPath = join60(config.root, ".anchorkit", "vault");
|
|
79177
79229
|
return {
|
|
79178
79230
|
local: { path: vaultPath },
|
|
79179
79231
|
global: config.globalRoot ? { path: config.globalRoot } : null,
|
|
@@ -79211,7 +79263,7 @@ function createVaultMapTool(config) {
|
|
|
79211
79263
|
var vaultMapInputSchema, vaultMapJsonSchema;
|
|
79212
79264
|
var init_vault_map = __esm(() => {
|
|
79213
79265
|
init_zod();
|
|
79214
|
-
|
|
79266
|
+
init_indexing();
|
|
79215
79267
|
init_mapper();
|
|
79216
79268
|
vaultMapInputSchema = exports_external.object({
|
|
79217
79269
|
scope: exports_external.enum(["project", "global"]).optional(),
|
|
@@ -81013,9 +81065,9 @@ async function handler3(_args, ctx) {
|
|
|
81013
81065
|
}
|
|
81014
81066
|
|
|
81015
81067
|
// src/commands/vault-map.ts
|
|
81016
|
-
|
|
81068
|
+
init_indexing();
|
|
81017
81069
|
init_mapper();
|
|
81018
|
-
import { basename as basename7, join as
|
|
81070
|
+
import { basename as basename7, join as join26 } from "node:path";
|
|
81019
81071
|
var LEGACY_GATE_MODULE_LIMIT = 100;
|
|
81020
81072
|
function parseVaultMapFlags(args) {
|
|
81021
81073
|
const flags = {
|
|
@@ -81093,7 +81145,7 @@ async function handler4(args, ctx) {
|
|
|
81093
81145
|
}
|
|
81094
81146
|
}
|
|
81095
81147
|
function buildInternalCfg(root) {
|
|
81096
|
-
const vaultPath =
|
|
81148
|
+
const vaultPath = join26(root, ".anchorkit", "vault");
|
|
81097
81149
|
return {
|
|
81098
81150
|
local: { path: vaultPath },
|
|
81099
81151
|
global: null,
|
|
@@ -81162,14 +81214,14 @@ async function handler5(args, ctx) {
|
|
|
81162
81214
|
}
|
|
81163
81215
|
|
|
81164
81216
|
// src/commands/vault-search.ts
|
|
81165
|
-
import { existsSync as
|
|
81166
|
-
import { join as
|
|
81167
|
-
|
|
81168
|
-
var
|
|
81169
|
-
var
|
|
81217
|
+
import { existsSync as existsSync24, readFileSync as readFileSync24 } from "node:fs";
|
|
81218
|
+
import { join as join27, relative as relative4 } from "node:path";
|
|
81219
|
+
init_indexing();
|
|
81220
|
+
var DEFAULT_LIMIT3 = 20;
|
|
81221
|
+
var MAX_LIMIT2 = 500;
|
|
81170
81222
|
function parseSearchArgs(args) {
|
|
81171
81223
|
let global = false;
|
|
81172
|
-
let limit =
|
|
81224
|
+
let limit = DEFAULT_LIMIT3;
|
|
81173
81225
|
const positionals = [];
|
|
81174
81226
|
for (let i = 0;i < args.length; i++) {
|
|
81175
81227
|
const a = args[i];
|
|
@@ -81178,13 +81230,13 @@ function parseSearchArgs(args) {
|
|
|
81178
81230
|
} else if (a === "-n" || a === "--limit") {
|
|
81179
81231
|
const n = Number.parseInt(args[i + 1] ?? "", 10);
|
|
81180
81232
|
if (Number.isFinite(n) && n > 0)
|
|
81181
|
-
limit = Math.min(n,
|
|
81233
|
+
limit = Math.min(n, MAX_LIMIT2);
|
|
81182
81234
|
i++;
|
|
81183
81235
|
} else if (a.startsWith("-n=") || a.startsWith("--limit=")) {
|
|
81184
81236
|
const rhs = a.split("=")[1] ?? "";
|
|
81185
81237
|
const n = Number.parseInt(rhs, 10);
|
|
81186
81238
|
if (Number.isFinite(n) && n > 0)
|
|
81187
|
-
limit = Math.min(n,
|
|
81239
|
+
limit = Math.min(n, MAX_LIMIT2);
|
|
81188
81240
|
} else if (!a.startsWith("-")) {
|
|
81189
81241
|
positionals.push(a);
|
|
81190
81242
|
}
|
|
@@ -81211,8 +81263,8 @@ async function handler6(args, ctx) {
|
|
|
81211
81263
|
try {
|
|
81212
81264
|
const vault = await ctx.vault();
|
|
81213
81265
|
const root = vault.config.root;
|
|
81214
|
-
const vaultPath = global ? vault.config.globalRoot ??
|
|
81215
|
-
if (!
|
|
81266
|
+
const vaultPath = global ? vault.config.globalRoot ?? join27(root, ".anchorkit", "global-vault") : join27(root, ".anchorkit", "vault");
|
|
81267
|
+
if (!existsSync24(vaultPath)) {
|
|
81216
81268
|
ctx.appendOutput(source_default.dim(global ? "no global vault configured — nothing to search." : "no vault at this path — nothing to search."));
|
|
81217
81269
|
return { ok: true };
|
|
81218
81270
|
}
|
|
@@ -81223,7 +81275,7 @@ async function handler6(args, ctx) {
|
|
|
81223
81275
|
for (const abs of walkNotes(vaultPath)) {
|
|
81224
81276
|
let raw;
|
|
81225
81277
|
try {
|
|
81226
|
-
raw =
|
|
81278
|
+
raw = readFileSync24(abs, "utf-8");
|
|
81227
81279
|
} catch {
|
|
81228
81280
|
continue;
|
|
81229
81281
|
}
|
|
@@ -81262,8 +81314,8 @@ async function handler6(args, ctx) {
|
|
|
81262
81314
|
}
|
|
81263
81315
|
|
|
81264
81316
|
// src/commands/vault-stats.ts
|
|
81265
|
-
import { existsSync as
|
|
81266
|
-
import { basename as basename8, extname as extname5, join as
|
|
81317
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25, readdirSync as readdirSync11, statSync as statSync7 } from "node:fs";
|
|
81318
|
+
import { basename as basename8, extname as extname5, join as join28, relative as relative5 } from "node:path";
|
|
81267
81319
|
var NOTE_FOLDERS2 = ["knowledge", "maps", "decisions", "flows", "incidents", "archive"];
|
|
81268
81320
|
var NOTE_TYPES2 = [
|
|
81269
81321
|
"module",
|
|
@@ -81306,8 +81358,8 @@ function countByFolder(vaultPath) {
|
|
|
81306
81358
|
for (const folder of NOTE_FOLDERS2)
|
|
81307
81359
|
counts[folder] = 0;
|
|
81308
81360
|
for (const folder of NOTE_FOLDERS2) {
|
|
81309
|
-
const dir =
|
|
81310
|
-
if (!
|
|
81361
|
+
const dir = join28(vaultPath, folder);
|
|
81362
|
+
if (!existsSync25(dir))
|
|
81311
81363
|
continue;
|
|
81312
81364
|
let entries;
|
|
81313
81365
|
try {
|
|
@@ -81321,7 +81373,7 @@ function countByFolder(vaultPath) {
|
|
|
81321
81373
|
if (basename8(name).startsWith("_"))
|
|
81322
81374
|
continue;
|
|
81323
81375
|
try {
|
|
81324
|
-
const s = statSync7(
|
|
81376
|
+
const s = statSync7(join28(dir, name));
|
|
81325
81377
|
if (s.isFile())
|
|
81326
81378
|
counts[folder] = (counts[folder] ?? 0) + 1;
|
|
81327
81379
|
} catch {}
|
|
@@ -81330,13 +81382,13 @@ function countByFolder(vaultPath) {
|
|
|
81330
81382
|
return counts;
|
|
81331
81383
|
}
|
|
81332
81384
|
function countCaptures(vaultPath) {
|
|
81333
|
-
const logPath =
|
|
81385
|
+
const logPath = join28(vaultPath, "_log.md");
|
|
81334
81386
|
const summary = { live: 0, undone: 0, bySource: {} };
|
|
81335
|
-
if (!
|
|
81387
|
+
if (!existsSync25(logPath))
|
|
81336
81388
|
return summary;
|
|
81337
81389
|
let content;
|
|
81338
81390
|
try {
|
|
81339
|
-
content =
|
|
81391
|
+
content = readFileSync25(logPath, "utf-8");
|
|
81340
81392
|
} catch {
|
|
81341
81393
|
return summary;
|
|
81342
81394
|
}
|
|
@@ -81390,8 +81442,8 @@ function computeAge(notes) {
|
|
|
81390
81442
|
function countOrphans(vaultPath) {
|
|
81391
81443
|
const all = [];
|
|
81392
81444
|
for (const folder of NOTE_FOLDERS2) {
|
|
81393
|
-
const dir =
|
|
81394
|
-
if (!
|
|
81445
|
+
const dir = join28(vaultPath, folder);
|
|
81446
|
+
if (!existsSync25(dir))
|
|
81395
81447
|
continue;
|
|
81396
81448
|
let entries;
|
|
81397
81449
|
try {
|
|
@@ -81404,7 +81456,7 @@ function countOrphans(vaultPath) {
|
|
|
81404
81456
|
continue;
|
|
81405
81457
|
if (basename8(name).startsWith("_"))
|
|
81406
81458
|
continue;
|
|
81407
|
-
all.push(
|
|
81459
|
+
all.push(join28(dir, name));
|
|
81408
81460
|
}
|
|
81409
81461
|
}
|
|
81410
81462
|
if (all.length === 0)
|
|
@@ -81417,7 +81469,7 @@ function countOrphans(vaultPath) {
|
|
|
81417
81469
|
for (const abs of all) {
|
|
81418
81470
|
let raw;
|
|
81419
81471
|
try {
|
|
81420
|
-
raw =
|
|
81472
|
+
raw = readFileSync25(abs, "utf-8");
|
|
81421
81473
|
} catch {
|
|
81422
81474
|
continue;
|
|
81423
81475
|
}
|
|
@@ -81444,9 +81496,9 @@ async function handler7(args, ctx) {
|
|
|
81444
81496
|
try {
|
|
81445
81497
|
const vault = await ctx.vault();
|
|
81446
81498
|
const root = vault.config.root;
|
|
81447
|
-
const vaultPath = global ? vault.config.globalRoot ??
|
|
81499
|
+
const vaultPath = global ? vault.config.globalRoot ?? join28(root, ".anchorkit", "global-vault") : join28(root, ".anchorkit", "vault");
|
|
81448
81500
|
const label = global ? "Global vault" : "Local vault";
|
|
81449
|
-
if (global && !
|
|
81501
|
+
if (global && !existsSync25(vaultPath)) {
|
|
81450
81502
|
const msg = "no global vault configured. Run `/vault-init-global` (or set ANCHORKIT_GLOBAL_VAULT) to create one.";
|
|
81451
81503
|
ctx.appendOutput(msg);
|
|
81452
81504
|
return { ok: false, message: msg };
|
|
@@ -81496,8 +81548,8 @@ async function handler7(args, ctx) {
|
|
|
81496
81548
|
}
|
|
81497
81549
|
|
|
81498
81550
|
// src/commands/vault-undo.ts
|
|
81499
|
-
import { existsSync as
|
|
81500
|
-
import { basename as basename9, isAbsolute, join as
|
|
81551
|
+
import { existsSync as existsSync26, readFileSync as readFileSync26, rmSync, writeFileSync as writeFileSync15 } from "node:fs";
|
|
81552
|
+
import { basename as basename9, isAbsolute, join as join29, resolve as resolve3 } from "node:path";
|
|
81501
81553
|
function parseUndoCount(args, fallback = 1) {
|
|
81502
81554
|
for (const a of args) {
|
|
81503
81555
|
const n = Number.parseInt(a, 10);
|
|
@@ -81511,15 +81563,15 @@ async function handler8(args, ctx) {
|
|
|
81511
81563
|
try {
|
|
81512
81564
|
const vault = await ctx.vault();
|
|
81513
81565
|
const root = vault.config.root;
|
|
81514
|
-
const statePath =
|
|
81515
|
-
const vaultRoot =
|
|
81516
|
-
if (!
|
|
81566
|
+
const statePath = join29(root, ".anchorkit", "state.json");
|
|
81567
|
+
const vaultRoot = join29(root, ".anchorkit", "vault");
|
|
81568
|
+
if (!existsSync26(statePath)) {
|
|
81517
81569
|
ctx.appendOutput("nothing to undo (no state file yet).");
|
|
81518
81570
|
return { ok: true };
|
|
81519
81571
|
}
|
|
81520
81572
|
let raw;
|
|
81521
81573
|
try {
|
|
81522
|
-
raw =
|
|
81574
|
+
raw = readFileSync26(statePath, "utf-8");
|
|
81523
81575
|
} catch (err) {
|
|
81524
81576
|
const msg = err instanceof Error ? err.message : String(err);
|
|
81525
81577
|
ctx.appendOutput(`could not read state.json: ${msg}`);
|
|
@@ -81552,7 +81604,7 @@ async function handler8(args, ctx) {
|
|
|
81552
81604
|
continue;
|
|
81553
81605
|
}
|
|
81554
81606
|
try {
|
|
81555
|
-
if (
|
|
81607
|
+
if (existsSync26(abs))
|
|
81556
81608
|
rmSync(abs, { force: true });
|
|
81557
81609
|
removed++;
|
|
81558
81610
|
ctx.appendOutput(`undid: ${basename9(cap.filename)}`);
|
|
@@ -81562,7 +81614,7 @@ async function handler8(args, ctx) {
|
|
|
81562
81614
|
}
|
|
81563
81615
|
const next = { ...parsed, captures: remaining };
|
|
81564
81616
|
try {
|
|
81565
|
-
|
|
81617
|
+
writeFileSync15(statePath, JSON.stringify(next, null, 2), "utf-8");
|
|
81566
81618
|
} catch (err) {
|
|
81567
81619
|
const msg = err instanceof Error ? err.message : String(err);
|
|
81568
81620
|
ctx.appendOutput(`could not rewrite state.json: ${msg}`);
|
|
@@ -81578,23 +81630,24 @@ async function handler8(args, ctx) {
|
|
|
81578
81630
|
}
|
|
81579
81631
|
|
|
81580
81632
|
// src/commands/vault-upgrade.ts
|
|
81581
|
-
import { basename as basename10, join as
|
|
81633
|
+
import { basename as basename10, join as join31 } from "node:path";
|
|
81582
81634
|
|
|
81583
81635
|
// src/vault/upgrade.ts
|
|
81584
81636
|
init_config();
|
|
81585
|
-
|
|
81637
|
+
init_conventions();
|
|
81638
|
+
init_indexing();
|
|
81586
81639
|
init_storage();
|
|
81587
81640
|
init_storage();
|
|
81588
81641
|
import {
|
|
81589
|
-
existsSync as
|
|
81590
|
-
mkdirSync as
|
|
81591
|
-
readFileSync as
|
|
81642
|
+
existsSync as existsSync27,
|
|
81643
|
+
mkdirSync as mkdirSync15,
|
|
81644
|
+
readFileSync as readFileSync27,
|
|
81592
81645
|
readdirSync as readdirSync12,
|
|
81593
81646
|
statSync as statSync8,
|
|
81594
81647
|
unlinkSync,
|
|
81595
|
-
writeFileSync as
|
|
81648
|
+
writeFileSync as writeFileSync16
|
|
81596
81649
|
} from "node:fs";
|
|
81597
|
-
import { isAbsolute as isAbsolute2, join as
|
|
81650
|
+
import { isAbsolute as isAbsolute2, join as join30, resolve as resolve4 } from "node:path";
|
|
81598
81651
|
function inferNoteType(_docPath, doc, projectRoot) {
|
|
81599
81652
|
const raw = doc?.source_path;
|
|
81600
81653
|
if (typeof raw !== "string" || raw.trim().length === 0) {
|
|
@@ -81605,7 +81658,7 @@ function inferNoteType(_docPath, doc, projectRoot) {
|
|
|
81605
81658
|
if (!abs.startsWith(rootResolved))
|
|
81606
81659
|
return "concept";
|
|
81607
81660
|
try {
|
|
81608
|
-
if (
|
|
81661
|
+
if (existsSync27(abs) && statSync8(abs).isFile())
|
|
81609
81662
|
return "module";
|
|
81610
81663
|
} catch {}
|
|
81611
81664
|
return "concept";
|
|
@@ -81633,18 +81686,18 @@ function firstNonEmptyLine(body, max = 120) {
|
|
|
81633
81686
|
return "";
|
|
81634
81687
|
}
|
|
81635
81688
|
function appendLogEntry2(vaultPath, line) {
|
|
81636
|
-
const logPath =
|
|
81637
|
-
if (!
|
|
81638
|
-
|
|
81689
|
+
const logPath = join30(vaultPath, "_log.md");
|
|
81690
|
+
if (!existsSync27(logPath)) {
|
|
81691
|
+
writeFileSync16(logPath, `# Vault log
|
|
81639
81692
|
|
|
81640
81693
|
${line}
|
|
81641
81694
|
`, "utf-8");
|
|
81642
81695
|
return;
|
|
81643
81696
|
}
|
|
81644
|
-
const content =
|
|
81697
|
+
const content = readFileSync27(logPath, "utf-8");
|
|
81645
81698
|
const needsNl = content.length > 0 && !content.endsWith(`
|
|
81646
81699
|
`);
|
|
81647
|
-
|
|
81700
|
+
writeFileSync16(logPath, `${content + (needsNl ? `
|
|
81648
81701
|
` : "") + line}
|
|
81649
81702
|
`, "utf-8");
|
|
81650
81703
|
}
|
|
@@ -81683,10 +81736,10 @@ async function upgradeVault(cfg) {
|
|
|
81683
81736
|
const docRelPath = typeof docEntry === "string" ? docEntry : "";
|
|
81684
81737
|
if (!docRelPath)
|
|
81685
81738
|
continue;
|
|
81686
|
-
const srcPath =
|
|
81687
|
-
if (!
|
|
81739
|
+
const srcPath = join30(cfg.vaultPath, docRelPath);
|
|
81740
|
+
if (!existsSync27(srcPath))
|
|
81688
81741
|
continue;
|
|
81689
|
-
const raw =
|
|
81742
|
+
const raw = readFileSync27(srcPath, "utf-8");
|
|
81690
81743
|
const { frontmatter: existingFm, content: existingBody } = parseFrontmatter(raw);
|
|
81691
81744
|
const hadFrontmatter = Object.keys(existingFm).length > 0;
|
|
81692
81745
|
const body = hadFrontmatter ? existingBody : raw;
|
|
@@ -81762,8 +81815,8 @@ function addScopeToVault(cfg) {
|
|
|
81762
81815
|
};
|
|
81763
81816
|
const skippedDetails = [];
|
|
81764
81817
|
for (const folder of NOTE_FOLDERS) {
|
|
81765
|
-
const folderPath =
|
|
81766
|
-
if (!
|
|
81818
|
+
const folderPath = join30(vaultPath, folder);
|
|
81819
|
+
if (!existsSync27(folderPath))
|
|
81767
81820
|
continue;
|
|
81768
81821
|
walkAndAddScope(folderPath, folder, result, skippedDetails);
|
|
81769
81822
|
}
|
|
@@ -81783,7 +81836,7 @@ function walkAndAddScope(dir, folderRel, result, skippedDetails) {
|
|
|
81783
81836
|
return;
|
|
81784
81837
|
}
|
|
81785
81838
|
for (const entry of entries) {
|
|
81786
|
-
const full =
|
|
81839
|
+
const full = join30(dir, entry);
|
|
81787
81840
|
let s;
|
|
81788
81841
|
try {
|
|
81789
81842
|
s = statSync8(full);
|
|
@@ -81800,7 +81853,7 @@ function walkAndAddScope(dir, folderRel, result, skippedDetails) {
|
|
|
81800
81853
|
}
|
|
81801
81854
|
}
|
|
81802
81855
|
function processOneNote(absPath, relPath, result, skippedDetails) {
|
|
81803
|
-
const raw =
|
|
81856
|
+
const raw = readFileSync27(absPath, "utf-8");
|
|
81804
81857
|
const fenceMatch = raw.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
81805
81858
|
if (!fenceMatch) {
|
|
81806
81859
|
result.notesSkipped++;
|
|
@@ -81833,7 +81886,7 @@ ${newFrontmatter}
|
|
|
81833
81886
|
---
|
|
81834
81887
|
${rest.startsWith(`
|
|
81835
81888
|
`) ? rest.slice(1) : rest}`;
|
|
81836
|
-
|
|
81889
|
+
writeFileSync16(absPath, newRaw, "utf-8");
|
|
81837
81890
|
result.notesAdded++;
|
|
81838
81891
|
}
|
|
81839
81892
|
function regenerateIndex(vaultPath, movedSlugs) {
|
|
@@ -81857,8 +81910,8 @@ function regenerateIndex(vaultPath, movedSlugs) {
|
|
|
81857
81910
|
lines.push("- [[_conventions]] — vault constitution");
|
|
81858
81911
|
lines.push("- [[_log]] — append-only mutation log");
|
|
81859
81912
|
lines.push("");
|
|
81860
|
-
|
|
81861
|
-
|
|
81913
|
+
mkdirSync15(vaultPath, { recursive: true });
|
|
81914
|
+
writeFileSync16(join30(vaultPath, "_index.md"), lines.join(`
|
|
81862
81915
|
`), "utf-8");
|
|
81863
81916
|
}
|
|
81864
81917
|
|
|
@@ -81916,7 +81969,7 @@ async function handler9(args, ctx) {
|
|
|
81916
81969
|
}
|
|
81917
81970
|
}
|
|
81918
81971
|
function buildInternalCfg2(root) {
|
|
81919
|
-
const vaultPath =
|
|
81972
|
+
const vaultPath = join31(root, ".anchorkit", "vault");
|
|
81920
81973
|
return {
|
|
81921
81974
|
local: { path: vaultPath },
|
|
81922
81975
|
global: null,
|
|
@@ -82558,13 +82611,13 @@ async function handler12(_args, ctx) {
|
|
|
82558
82611
|
|
|
82559
82612
|
// src/session/store.ts
|
|
82560
82613
|
import { promises as fsp } from "node:fs";
|
|
82561
|
-
import { existsSync as
|
|
82562
|
-
import { join as
|
|
82614
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
82615
|
+
import { join as join32 } from "node:path";
|
|
82563
82616
|
function sessionsDir(cwd) {
|
|
82564
|
-
return
|
|
82617
|
+
return join32(cwd, ".anchorkit", "sessions");
|
|
82565
82618
|
}
|
|
82566
82619
|
function sessionPath(cwd, sessionId) {
|
|
82567
|
-
return
|
|
82620
|
+
return join32(sessionsDir(cwd), `${sessionId}.json`);
|
|
82568
82621
|
}
|
|
82569
82622
|
function newSessionId() {
|
|
82570
82623
|
const iso = new Date().toISOString().replace(/[:.]/g, "-");
|
|
@@ -82594,7 +82647,7 @@ async function saveSession(cwd, session) {
|
|
|
82594
82647
|
}
|
|
82595
82648
|
async function loadSession(cwd, sessionId) {
|
|
82596
82649
|
const p = sessionPath(cwd, sessionId);
|
|
82597
|
-
if (!
|
|
82650
|
+
if (!existsSync29(p))
|
|
82598
82651
|
return null;
|
|
82599
82652
|
let raw;
|
|
82600
82653
|
try {
|
|
@@ -82615,7 +82668,7 @@ async function loadSession(cwd, sessionId) {
|
|
|
82615
82668
|
}
|
|
82616
82669
|
async function listSessions(cwd) {
|
|
82617
82670
|
const dir = sessionsDir(cwd);
|
|
82618
|
-
if (!
|
|
82671
|
+
if (!existsSync29(dir))
|
|
82619
82672
|
return [];
|
|
82620
82673
|
let entries;
|
|
82621
82674
|
try {
|
|
@@ -82628,7 +82681,7 @@ async function listSessions(cwd) {
|
|
|
82628
82681
|
for (const file of files) {
|
|
82629
82682
|
const sessionId = file.replace(/\.json$/, "");
|
|
82630
82683
|
try {
|
|
82631
|
-
const raw = await fsp.readFile(
|
|
82684
|
+
const raw = await fsp.readFile(join32(dir, file), "utf-8");
|
|
82632
82685
|
const parsed = JSON.parse(raw);
|
|
82633
82686
|
if (!parsed || typeof parsed !== "object")
|
|
82634
82687
|
continue;
|
|
@@ -82661,7 +82714,7 @@ async function rotateSessions(cwd, opts = {}) {
|
|
|
82661
82714
|
const ttlDaysRaw = normalized.ttlDays ?? envNumber("ANCHORKIT_SESSIONS_TTL_DAYS") ?? DEFAULT_TTL_DAYS;
|
|
82662
82715
|
const ttlMs = ttlDaysRaw > 0 ? ttlDaysRaw * 24 * 60 * 60 * 1000 : Number.POSITIVE_INFINITY;
|
|
82663
82716
|
const dir = sessionsDir(cwd);
|
|
82664
|
-
if (!
|
|
82717
|
+
if (!existsSync29(dir))
|
|
82665
82718
|
return;
|
|
82666
82719
|
const summaries = await listSessions(cwd);
|
|
82667
82720
|
const victims = new Set;
|
|
@@ -83221,8 +83274,8 @@ ${truncated}`;
|
|
|
83221
83274
|
|
|
83222
83275
|
// src/commands/pr.ts
|
|
83223
83276
|
import { spawnSync } from "node:child_process";
|
|
83224
|
-
import { existsSync as
|
|
83225
|
-
import { join as
|
|
83277
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
83278
|
+
import { join as join33 } from "node:path";
|
|
83226
83279
|
var TITLE_MAX_LEN = 70;
|
|
83227
83280
|
function parsePrArgs(args) {
|
|
83228
83281
|
const out = { draft: false };
|
|
@@ -83296,10 +83349,10 @@ function defaultRun(cmd, args, opts) {
|
|
|
83296
83349
|
}
|
|
83297
83350
|
function createPrCommandHandler(deps = {}) {
|
|
83298
83351
|
const run = deps.run ?? defaultRun;
|
|
83299
|
-
const exists = deps.existsSync ??
|
|
83352
|
+
const exists = deps.existsSync ?? existsSync30;
|
|
83300
83353
|
return async function handler18(args, ctx) {
|
|
83301
83354
|
const { base: baseArg, draft } = parsePrArgs(args);
|
|
83302
|
-
if (!exists(
|
|
83355
|
+
if (!exists(join33(ctx.cwd, ".git"))) {
|
|
83303
83356
|
const msg = "not a git repository";
|
|
83304
83357
|
ctx.appendOutput(msg);
|
|
83305
83358
|
return { ok: false, message: msg };
|
|
@@ -83394,17 +83447,17 @@ var handler18 = createPrCommandHandler();
|
|
|
83394
83447
|
|
|
83395
83448
|
// src/skills/loader.ts
|
|
83396
83449
|
init_paths();
|
|
83397
|
-
import { existsSync as
|
|
83398
|
-
import { join as
|
|
83450
|
+
import { existsSync as existsSync31, readFileSync as readFileSync29, readdirSync as readdirSync13, statSync as statSync9 } from "node:fs";
|
|
83451
|
+
import { join as join34 } from "node:path";
|
|
83399
83452
|
var SKILL_FILENAME = "SKILL.md";
|
|
83400
83453
|
function skillsDir() {
|
|
83401
|
-
return
|
|
83454
|
+
return join34(anchorkitHomeDir(), "skills");
|
|
83402
83455
|
}
|
|
83403
83456
|
function skillDir(name) {
|
|
83404
|
-
return
|
|
83457
|
+
return join34(skillsDir(), name);
|
|
83405
83458
|
}
|
|
83406
83459
|
function skillFilePath(name) {
|
|
83407
|
-
return
|
|
83460
|
+
return join34(skillDir(name), SKILL_FILENAME);
|
|
83408
83461
|
}
|
|
83409
83462
|
function parseSkillMd(raw) {
|
|
83410
83463
|
if (!raw.startsWith(`---
|
|
@@ -83457,7 +83510,7 @@ function firstNonEmptyLine2(body) {
|
|
|
83457
83510
|
}
|
|
83458
83511
|
async function listSkills() {
|
|
83459
83512
|
const root = skillsDir();
|
|
83460
|
-
if (!
|
|
83513
|
+
if (!existsSync31(root))
|
|
83461
83514
|
return [];
|
|
83462
83515
|
let entries;
|
|
83463
83516
|
try {
|
|
@@ -83467,19 +83520,19 @@ async function listSkills() {
|
|
|
83467
83520
|
}
|
|
83468
83521
|
const out = [];
|
|
83469
83522
|
for (const entry of entries) {
|
|
83470
|
-
const dir =
|
|
83523
|
+
const dir = join34(root, entry);
|
|
83471
83524
|
try {
|
|
83472
83525
|
if (!statSync9(dir).isDirectory())
|
|
83473
83526
|
continue;
|
|
83474
83527
|
} catch {
|
|
83475
83528
|
continue;
|
|
83476
83529
|
}
|
|
83477
|
-
const file =
|
|
83478
|
-
if (!
|
|
83530
|
+
const file = join34(dir, SKILL_FILENAME);
|
|
83531
|
+
if (!existsSync31(file))
|
|
83479
83532
|
continue;
|
|
83480
83533
|
let raw;
|
|
83481
83534
|
try {
|
|
83482
|
-
raw =
|
|
83535
|
+
raw = readFileSync29(file, "utf-8");
|
|
83483
83536
|
} catch {
|
|
83484
83537
|
continue;
|
|
83485
83538
|
}
|
|
@@ -83494,11 +83547,11 @@ async function listSkills() {
|
|
|
83494
83547
|
async function loadSkill(name) {
|
|
83495
83548
|
const dir = skillDir(name);
|
|
83496
83549
|
const file = skillFilePath(name);
|
|
83497
|
-
if (!
|
|
83550
|
+
if (!existsSync31(file))
|
|
83498
83551
|
return null;
|
|
83499
83552
|
let raw;
|
|
83500
83553
|
try {
|
|
83501
|
-
raw =
|
|
83554
|
+
raw = readFileSync29(file, "utf-8");
|
|
83502
83555
|
} catch {
|
|
83503
83556
|
return null;
|
|
83504
83557
|
}
|
|
@@ -83552,30 +83605,30 @@ async function handler19(args, ctx) {
|
|
|
83552
83605
|
// src/mcp/config.ts
|
|
83553
83606
|
init_paths();
|
|
83554
83607
|
import { promises as fsp2 } from "node:fs";
|
|
83555
|
-
import { existsSync as
|
|
83608
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
83556
83609
|
import { homedir as homedir7 } from "node:os";
|
|
83557
|
-
import { dirname as dirname11, join as
|
|
83610
|
+
import { dirname as dirname11, join as join35 } from "node:path";
|
|
83558
83611
|
var NAME_RE = /^[a-z0-9_-]+$/;
|
|
83559
83612
|
function isValidServerName(name) {
|
|
83560
83613
|
return NAME_RE.test(name);
|
|
83561
83614
|
}
|
|
83562
83615
|
function projectConfigPath(cwd) {
|
|
83563
|
-
return
|
|
83616
|
+
return join35(cwd, ".anchorkit", "mcp-servers.json");
|
|
83564
83617
|
}
|
|
83565
83618
|
function globalConfigPath(homeDir) {
|
|
83566
83619
|
if (homeDir !== undefined) {
|
|
83567
|
-
return
|
|
83620
|
+
return join35(homeDir, ".anchorkit", "mcp-servers.json");
|
|
83568
83621
|
}
|
|
83569
83622
|
if (process.env.ANCHORKIT_TEST_HOME) {
|
|
83570
|
-
return
|
|
83623
|
+
return join35(anchorkitHomeDir(), "mcp-servers.json");
|
|
83571
83624
|
}
|
|
83572
|
-
return
|
|
83625
|
+
return join35(homedir7(), ".anchorkit", "mcp-servers.json");
|
|
83573
83626
|
}
|
|
83574
83627
|
function configPathForScope(scope, cwd, homeDir) {
|
|
83575
83628
|
return scope === "project" ? projectConfigPath(cwd) : globalConfigPath(homeDir);
|
|
83576
83629
|
}
|
|
83577
83630
|
async function readConfigFile(path4) {
|
|
83578
|
-
if (!
|
|
83631
|
+
if (!existsSync32(path4))
|
|
83579
83632
|
return {};
|
|
83580
83633
|
let raw;
|
|
83581
83634
|
try {
|
|
@@ -83786,8 +83839,8 @@ async function handler20(args, ctx) {
|
|
|
83786
83839
|
}
|
|
83787
83840
|
|
|
83788
83841
|
// src/hooks/config.ts
|
|
83789
|
-
import { existsSync as
|
|
83790
|
-
import { dirname as dirname12, join as
|
|
83842
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync17, readFileSync as readFileSync30, renameSync as renameSync4, writeFileSync as writeFileSync18 } from "node:fs";
|
|
83843
|
+
import { dirname as dirname12, join as join36 } from "node:path";
|
|
83791
83844
|
var KNOWN_HOOKS = [
|
|
83792
83845
|
"inject-context",
|
|
83793
83846
|
"principles-injection",
|
|
@@ -83799,15 +83852,15 @@ var KNOWN_HOOKS = [
|
|
|
83799
83852
|
"gsd-pipeline"
|
|
83800
83853
|
];
|
|
83801
83854
|
function hooksConfigPath(cwd) {
|
|
83802
|
-
return
|
|
83855
|
+
return join36(cwd, ".anchorkit", "hooks-config.json");
|
|
83803
83856
|
}
|
|
83804
83857
|
var EMPTY = { disabled: [] };
|
|
83805
83858
|
async function loadHooksConfig(cwd) {
|
|
83806
83859
|
const p = hooksConfigPath(cwd);
|
|
83807
|
-
if (!
|
|
83860
|
+
if (!existsSync33(p))
|
|
83808
83861
|
return { disabled: [] };
|
|
83809
83862
|
try {
|
|
83810
|
-
const raw =
|
|
83863
|
+
const raw = readFileSync30(p, "utf-8");
|
|
83811
83864
|
const parsed = JSON.parse(raw);
|
|
83812
83865
|
if (parsed && typeof parsed === "object" && Array.isArray(parsed.disabled)) {
|
|
83813
83866
|
const disabled = parsed.disabled.filter((x) => typeof x === "string");
|
|
@@ -83822,12 +83875,12 @@ async function loadHooksConfig(cwd) {
|
|
|
83822
83875
|
}
|
|
83823
83876
|
function writeConfigAtomic(p, cfg) {
|
|
83824
83877
|
const dir = dirname12(p);
|
|
83825
|
-
if (!
|
|
83826
|
-
|
|
83878
|
+
if (!existsSync33(dir))
|
|
83879
|
+
mkdirSync17(dir, { recursive: true });
|
|
83827
83880
|
const tmp = `${p}.tmp.${process.pid}.${Date.now()}`;
|
|
83828
|
-
|
|
83881
|
+
writeFileSync18(tmp, `${JSON.stringify(cfg, null, 2)}
|
|
83829
83882
|
`, "utf-8");
|
|
83830
|
-
|
|
83883
|
+
renameSync4(tmp, p);
|
|
83831
83884
|
}
|
|
83832
83885
|
async function setHookEnabled(cwd, name, enabled) {
|
|
83833
83886
|
const cfg = await loadHooksConfig(cwd);
|
|
@@ -84097,7 +84150,7 @@ var ErrorResponseSchema = exports_external.object({
|
|
|
84097
84150
|
init_zod();
|
|
84098
84151
|
import { promises as fs2, constants as fsConstants } from "node:fs";
|
|
84099
84152
|
import { homedir as homedir8 } from "node:os";
|
|
84100
|
-
import { join as
|
|
84153
|
+
import { join as join37 } from "node:path";
|
|
84101
84154
|
var CREDENTIALS_SCHEMA = exports_external.object({
|
|
84102
84155
|
apiUrl: exports_external.string().url(),
|
|
84103
84156
|
userId: exports_external.string().uuid(),
|
|
@@ -84109,8 +84162,8 @@ var CREDENTIALS_SCHEMA = exports_external.object({
|
|
|
84109
84162
|
});
|
|
84110
84163
|
function defaultCredentialsPaths() {
|
|
84111
84164
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? homedir8();
|
|
84112
|
-
const dir =
|
|
84113
|
-
return { file:
|
|
84165
|
+
const dir = join37(home, ".anchorkit");
|
|
84166
|
+
return { file: join37(dir, "credentials.json"), dir };
|
|
84114
84167
|
}
|
|
84115
84168
|
async function loadCredentials(paths = defaultCredentialsPaths()) {
|
|
84116
84169
|
let raw;
|
|
@@ -84136,7 +84189,7 @@ async function saveCredentials(creds, paths = defaultCredentialsPaths()) {
|
|
|
84136
84189
|
const validated = CREDENTIALS_SCHEMA.parse(creds);
|
|
84137
84190
|
await fs2.mkdir(paths.dir, { recursive: true, mode: 448 });
|
|
84138
84191
|
const tmpName = `credentials.json.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`;
|
|
84139
|
-
const tmpPath =
|
|
84192
|
+
const tmpPath = join37(paths.dir, tmpName);
|
|
84140
84193
|
const data = `${JSON.stringify(validated, null, 2)}
|
|
84141
84194
|
`;
|
|
84142
84195
|
await fs2.writeFile(tmpPath, data, { encoding: "utf8", mode: 384 });
|
|
@@ -84384,7 +84437,7 @@ function safeJsonParse(raw) {
|
|
|
84384
84437
|
init_debugLog();
|
|
84385
84438
|
|
|
84386
84439
|
// src/sync/supervisor.ts
|
|
84387
|
-
import { existsSync as
|
|
84440
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
84388
84441
|
import { dirname as dirname14, resolve as resolvePath } from "node:path";
|
|
84389
84442
|
import { Readable, Writable } from "node:stream";
|
|
84390
84443
|
import { fileURLToPath } from "node:url";
|
|
@@ -84500,10 +84553,10 @@ function defaultNodeSpawner() {
|
|
|
84500
84553
|
function defaultWorkerScript() {
|
|
84501
84554
|
const here = dirname14(fileURLToPath(import.meta.url));
|
|
84502
84555
|
const sibling = resolvePath(here, "worker.ts");
|
|
84503
|
-
if (
|
|
84556
|
+
if (existsSync34(sibling))
|
|
84504
84557
|
return sibling;
|
|
84505
84558
|
const bundled = resolvePath(here, "sync", "worker.mjs");
|
|
84506
|
-
if (
|
|
84559
|
+
if (existsSync34(bundled))
|
|
84507
84560
|
return bundled;
|
|
84508
84561
|
return sibling;
|
|
84509
84562
|
}
|
|
@@ -84975,9 +85028,9 @@ function failure(err, ctx, what) {
|
|
|
84975
85028
|
|
|
84976
85029
|
// src/cli/doctorChecks.ts
|
|
84977
85030
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
84978
|
-
import { mkdirSync as
|
|
85031
|
+
import { mkdirSync as mkdirSync18, rmSync as rmSync2, writeFileSync as writeFileSync19 } from "node:fs";
|
|
84979
85032
|
import { homedir as homedir9 } from "node:os";
|
|
84980
|
-
import { join as
|
|
85033
|
+
import { join as join38 } from "node:path";
|
|
84981
85034
|
var DEFAULT_TIMEOUT_MS2 = 2000;
|
|
84982
85035
|
function defaultSpawn(cmd, args, opts = {}) {
|
|
84983
85036
|
try {
|
|
@@ -85101,9 +85154,9 @@ function checkGit(spawn2) {
|
|
|
85101
85154
|
}
|
|
85102
85155
|
function checkWritable(name, dir) {
|
|
85103
85156
|
try {
|
|
85104
|
-
|
|
85105
|
-
const probe =
|
|
85106
|
-
|
|
85157
|
+
mkdirSync18(dir, { recursive: true });
|
|
85158
|
+
const probe = join38(dir, `.anchorkit-doctor-${process.pid}-${Date.now()}`);
|
|
85159
|
+
writeFileSync19(probe, "ok", "utf-8");
|
|
85107
85160
|
try {
|
|
85108
85161
|
rmSync2(probe, { force: true });
|
|
85109
85162
|
} catch {}
|
|
@@ -85141,8 +85194,8 @@ async function checkVault(loader) {
|
|
|
85141
85194
|
async function runAllChecks(opts) {
|
|
85142
85195
|
const spawn2 = opts.spawnFn ?? defaultSpawn;
|
|
85143
85196
|
const home = opts.homeDir ?? homedir9();
|
|
85144
|
-
const anchorHome =
|
|
85145
|
-
const anchorProject =
|
|
85197
|
+
const anchorHome = join38(home, ".anchorkit");
|
|
85198
|
+
const anchorProject = join38(opts.cwd, ".anchorkit");
|
|
85146
85199
|
const jobs = [
|
|
85147
85200
|
Promise.resolve().then(() => checkBun()),
|
|
85148
85201
|
Promise.resolve().then(() => checkClaude(spawn2)),
|
|
@@ -85225,7 +85278,7 @@ var handler22 = createDoctorCommandHandler();
|
|
|
85225
85278
|
init_zod();
|
|
85226
85279
|
import { randomUUID } from "node:crypto";
|
|
85227
85280
|
import { promises as fs3 } from "node:fs";
|
|
85228
|
-
import { dirname as dirname15, join as
|
|
85281
|
+
import { dirname as dirname15, join as join39 } from "node:path";
|
|
85229
85282
|
var SyncConflictEntrySchema = exports_external.object({
|
|
85230
85283
|
path: exports_external.string(),
|
|
85231
85284
|
noteId: exports_external.string().uuid(),
|
|
@@ -85240,7 +85293,7 @@ var SyncStateSchema = exports_external.object({
|
|
|
85240
85293
|
conflicts: exports_external.array(SyncConflictEntrySchema).default([])
|
|
85241
85294
|
});
|
|
85242
85295
|
function syncStatePath(cwd) {
|
|
85243
|
-
return
|
|
85296
|
+
return join39(cwd, ".anchorkit", "sync-state.json");
|
|
85244
85297
|
}
|
|
85245
85298
|
async function loadSyncState(cwd) {
|
|
85246
85299
|
const path4 = syncStatePath(cwd);
|
|
@@ -85394,8 +85447,8 @@ async function syncHandler(args, ctx) {
|
|
|
85394
85447
|
}
|
|
85395
85448
|
|
|
85396
85449
|
// src/commands/resolve.ts
|
|
85397
|
-
import { existsSync as
|
|
85398
|
-
import { join as
|
|
85450
|
+
import { existsSync as existsSync36 } from "node:fs";
|
|
85451
|
+
import { join as join40 } from "node:path";
|
|
85399
85452
|
|
|
85400
85453
|
// src/manifest/db.ts
|
|
85401
85454
|
import Database from "better-sqlite3";
|
|
@@ -85799,16 +85852,16 @@ class LocalResolver {
|
|
|
85799
85852
|
}
|
|
85800
85853
|
|
|
85801
85854
|
// src/commands/resolve.ts
|
|
85802
|
-
var
|
|
85855
|
+
var DEFAULT_LIMIT4 = 10;
|
|
85803
85856
|
async function resolveHandler(args, ctx) {
|
|
85804
|
-
const limit = parseLimit(args) ??
|
|
85857
|
+
const limit = parseLimit(args) ?? DEFAULT_LIMIT4;
|
|
85805
85858
|
const query = stripFlags(args).join(" ").trim();
|
|
85806
85859
|
if (!query) {
|
|
85807
85860
|
ctx.appendOutput('usage: /resolve "<query>" [-n=N]');
|
|
85808
85861
|
return { ok: false, message: "missing query" };
|
|
85809
85862
|
}
|
|
85810
85863
|
const dbPath = resolveManifestPath(ctx.cwd);
|
|
85811
|
-
if (!
|
|
85864
|
+
if (!existsSync36(dbPath)) {
|
|
85812
85865
|
ctx.appendOutput(`no manifest.db at ${dbPath} — sync has not indexed any notes yet`);
|
|
85813
85866
|
return { ok: false, message: "no manifest" };
|
|
85814
85867
|
}
|
|
@@ -85883,7 +85936,7 @@ function parseLimit(args) {
|
|
|
85883
85936
|
return null;
|
|
85884
85937
|
}
|
|
85885
85938
|
function resolveManifestPath(cwd) {
|
|
85886
|
-
return
|
|
85939
|
+
return join40(cwd, ".anchorkit", "manifest.db");
|
|
85887
85940
|
}
|
|
85888
85941
|
|
|
85889
85942
|
// src/commands/cursor-agent.ts
|
|
@@ -86641,17 +86694,17 @@ async function dispatchSlashCommand(input, ctx) {
|
|
|
86641
86694
|
|
|
86642
86695
|
// src/config/trust.ts
|
|
86643
86696
|
init_paths();
|
|
86644
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
86645
|
-
import { dirname as dirname16, join as
|
|
86697
|
+
import { chmodSync as chmodSync3, existsSync as existsSync37, mkdirSync as mkdirSync19, readFileSync as readFileSync31, writeFileSync as writeFileSync20 } from "node:fs";
|
|
86698
|
+
import { dirname as dirname16, join as join41 } from "node:path";
|
|
86646
86699
|
function trustedFoldersPath() {
|
|
86647
|
-
return
|
|
86700
|
+
return join41(anchorkitHomeDir(), "trusted-folders.json");
|
|
86648
86701
|
}
|
|
86649
86702
|
function loadTrustedFolders() {
|
|
86650
86703
|
const path4 = trustedFoldersPath();
|
|
86651
|
-
if (!
|
|
86704
|
+
if (!existsSync37(path4))
|
|
86652
86705
|
return {};
|
|
86653
86706
|
try {
|
|
86654
|
-
const raw =
|
|
86707
|
+
const raw = readFileSync31(path4, "utf-8");
|
|
86655
86708
|
const parsed = JSON.parse(raw);
|
|
86656
86709
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
86657
86710
|
return {};
|
|
@@ -86668,8 +86721,8 @@ function trustFolder(cwd) {
|
|
|
86668
86721
|
const map = loadTrustedFolders();
|
|
86669
86722
|
map[cwd] = { acceptedAt: new Date().toISOString() };
|
|
86670
86723
|
const path4 = trustedFoldersPath();
|
|
86671
|
-
|
|
86672
|
-
|
|
86724
|
+
mkdirSync19(dirname16(path4), { recursive: true, mode: 448 });
|
|
86725
|
+
writeFileSync20(path4, JSON.stringify(map, null, 2), "utf-8");
|
|
86673
86726
|
try {
|
|
86674
86727
|
chmodSync3(path4, 384);
|
|
86675
86728
|
} catch {}
|
|
@@ -92189,9 +92242,9 @@ function TrustDialog({ cwd, onDecision }) {
|
|
|
92189
92242
|
// src/repl/allowedTools.ts
|
|
92190
92243
|
import { mkdirSync as mkdirSync22, readFileSync as readFileSync36, renameSync as renameSync5, writeFileSync as writeFileSync24 } from "node:fs";
|
|
92191
92244
|
import { homedir as homedir10 } from "node:os";
|
|
92192
|
-
import { dirname as dirname18, join as
|
|
92245
|
+
import { dirname as dirname18, join as join46 } from "node:path";
|
|
92193
92246
|
function configPath(opts = {}) {
|
|
92194
|
-
return
|
|
92247
|
+
return join46(opts.homeDir ?? homedir10(), ".anchorkit", "allowed-tools.json");
|
|
92195
92248
|
}
|
|
92196
92249
|
function loadAllowedTools(opts = {}) {
|
|
92197
92250
|
const path4 = configPath(opts);
|
|
@@ -92226,7 +92279,7 @@ function writeAtomic(path4, payload) {
|
|
|
92226
92279
|
|
|
92227
92280
|
// src/repl/permissionsWatcher.ts
|
|
92228
92281
|
import {
|
|
92229
|
-
existsSync as
|
|
92282
|
+
existsSync as existsSync41,
|
|
92230
92283
|
mkdirSync as mkdirSync23,
|
|
92231
92284
|
readFileSync as readFileSync37,
|
|
92232
92285
|
readdirSync as readdirSync15,
|
|
@@ -92235,18 +92288,18 @@ import {
|
|
|
92235
92288
|
watch,
|
|
92236
92289
|
writeFileSync as writeFileSync25
|
|
92237
92290
|
} from "node:fs";
|
|
92238
|
-
import { join as
|
|
92291
|
+
import { join as join47 } from "node:path";
|
|
92239
92292
|
var STALE_FILE_MS = 60 * 60 * 1000;
|
|
92240
92293
|
function createPermissionsWatcher(cwd) {
|
|
92241
|
-
const dir =
|
|
92242
|
-
if (!
|
|
92294
|
+
const dir = join47(cwd, ".anchorkit", "permissions");
|
|
92295
|
+
if (!existsSync41(dir))
|
|
92243
92296
|
mkdirSync23(dir, { recursive: true });
|
|
92244
92297
|
try {
|
|
92245
92298
|
const now2 = Date.now();
|
|
92246
92299
|
for (const filename of readdirSync15(dir)) {
|
|
92247
92300
|
if (!filename.endsWith(".json"))
|
|
92248
92301
|
continue;
|
|
92249
|
-
const path4 =
|
|
92302
|
+
const path4 = join47(dir, filename);
|
|
92250
92303
|
try {
|
|
92251
92304
|
const age = now2 - statSync11(path4).mtimeMs;
|
|
92252
92305
|
if (age > STALE_FILE_MS)
|
|
@@ -92271,7 +92324,7 @@ function createPermissionsWatcher(cwd) {
|
|
|
92271
92324
|
continue;
|
|
92272
92325
|
let parsed;
|
|
92273
92326
|
try {
|
|
92274
|
-
const raw = readFileSync37(
|
|
92327
|
+
const raw = readFileSync37(join47(dir, filename), "utf-8");
|
|
92275
92328
|
parsed = JSON.parse(raw);
|
|
92276
92329
|
} catch {
|
|
92277
92330
|
continue;
|
|
@@ -92314,7 +92367,7 @@ function createPermissionsWatcher(cwd) {
|
|
|
92314
92367
|
return () => listeners.delete(cb);
|
|
92315
92368
|
},
|
|
92316
92369
|
respond(id, decision, message) {
|
|
92317
|
-
const file =
|
|
92370
|
+
const file = join47(dir, `${id}.json`);
|
|
92318
92371
|
try {
|
|
92319
92372
|
const raw = readFileSync37(file, "utf-8");
|
|
92320
92373
|
const parsed = JSON.parse(raw);
|
|
@@ -92353,7 +92406,7 @@ function usePlanMode() {
|
|
|
92353
92406
|
|
|
92354
92407
|
// src/repl/useSession.ts
|
|
92355
92408
|
init_detect();
|
|
92356
|
-
import { join as
|
|
92409
|
+
import { join as join58 } from "node:path";
|
|
92357
92410
|
import { useCallback, useEffect as useEffect7, useRef as useRef2, useState as useState10 } from "react";
|
|
92358
92411
|
|
|
92359
92412
|
// src/agent/runner.ts
|
|
@@ -92385,25 +92438,25 @@ async function* runTurn(prompt, opts) {
|
|
|
92385
92438
|
}
|
|
92386
92439
|
|
|
92387
92440
|
// src/claude-memory/watcher.ts
|
|
92388
|
-
import { existsSync as
|
|
92389
|
-
import { join as
|
|
92441
|
+
import { existsSync as existsSync43, watch as watch2 } from "node:fs";
|
|
92442
|
+
import { join as join50 } from "node:path";
|
|
92390
92443
|
|
|
92391
92444
|
// src/claude-memory/paths.ts
|
|
92392
92445
|
import { homedir as homedir11 } from "node:os";
|
|
92393
|
-
import { join as
|
|
92446
|
+
import { join as join48 } from "node:path";
|
|
92394
92447
|
function claudeProjectSlug(cwd) {
|
|
92395
92448
|
return cwd.replace(/\\/g, "/").replace(/\//g, "-");
|
|
92396
92449
|
}
|
|
92397
92450
|
function claudeMemoryDir(cwd) {
|
|
92398
|
-
return
|
|
92451
|
+
return join48(homedir11(), ".claude", "projects", claudeProjectSlug(cwd), "memory");
|
|
92399
92452
|
}
|
|
92400
92453
|
function claudeProjectDir(cwd) {
|
|
92401
|
-
return
|
|
92454
|
+
return join48(homedir11(), ".claude", "projects", claudeProjectSlug(cwd));
|
|
92402
92455
|
}
|
|
92403
92456
|
|
|
92404
92457
|
// src/claude-memory/sync.ts
|
|
92405
|
-
import { existsSync as
|
|
92406
|
-
import { basename as basename12, join as
|
|
92458
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync24, readFileSync as readFileSync38, readdirSync as readdirSync16, statSync as statSync12, writeFileSync as writeFileSync26 } from "node:fs";
|
|
92459
|
+
import { basename as basename12, join as join49 } from "node:path";
|
|
92407
92460
|
function parseClaudeMemoryFile(content) {
|
|
92408
92461
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
92409
92462
|
if (!match) {
|
|
@@ -92426,7 +92479,7 @@ function parseClaudeMemoryFile(content) {
|
|
|
92426
92479
|
}
|
|
92427
92480
|
function readExistingCreated(destPath) {
|
|
92428
92481
|
try {
|
|
92429
|
-
if (!
|
|
92482
|
+
if (!existsSync42(destPath))
|
|
92430
92483
|
return null;
|
|
92431
92484
|
const content = readFileSync38(destPath, "utf-8");
|
|
92432
92485
|
const m2 = content.match(/^created:\s*(.+)$/m);
|
|
@@ -92486,9 +92539,9 @@ function syncMemoryFileToVault(memoryFilePath, vaultPath) {
|
|
|
92486
92539
|
const { frontmatter: claudeFm, body } = parseClaudeMemoryFile(content);
|
|
92487
92540
|
const rawTitle = claudeFm.name ?? filename.replace(/\.md$/, "");
|
|
92488
92541
|
const title = titleCase(rawTitle);
|
|
92489
|
-
const destDir =
|
|
92542
|
+
const destDir = join49(vaultPath, "knowledge");
|
|
92490
92543
|
const destFilename = toVaultFilename(filename);
|
|
92491
|
-
const destPath =
|
|
92544
|
+
const destPath = join49(destDir, destFilename);
|
|
92492
92545
|
const created = readExistingCreated(destPath) ?? fileMtime;
|
|
92493
92546
|
const updated = fileMtime;
|
|
92494
92547
|
const fm = buildVaultFrontmatter({
|
|
@@ -92521,7 +92574,7 @@ function bulkSyncMemoryDir(memoryDir, vaultPath) {
|
|
|
92521
92574
|
return;
|
|
92522
92575
|
}
|
|
92523
92576
|
for (const f of files) {
|
|
92524
|
-
syncMemoryFileToVault(
|
|
92577
|
+
syncMemoryFileToVault(join49(memoryDir, f), vaultPath);
|
|
92525
92578
|
}
|
|
92526
92579
|
}
|
|
92527
92580
|
|
|
@@ -92537,11 +92590,11 @@ function createClaudeMemoryWatcher(cwd, vaultPath) {
|
|
|
92537
92590
|
if (!filename || !filename.endsWith(".md") || filename === "MEMORY.md")
|
|
92538
92591
|
return;
|
|
92539
92592
|
setImmediate(() => {
|
|
92540
|
-
syncMemoryFileToVault(
|
|
92593
|
+
syncMemoryFileToVault(join50(memDir, filename), vaultPath);
|
|
92541
92594
|
});
|
|
92542
92595
|
}
|
|
92543
92596
|
function startMemWatcher() {
|
|
92544
|
-
if (memWatcher || stopped || !
|
|
92597
|
+
if (memWatcher || stopped || !existsSync43(memDir))
|
|
92545
92598
|
return;
|
|
92546
92599
|
bulkSyncMemoryDir(memDir, vaultPath);
|
|
92547
92600
|
try {
|
|
@@ -92557,11 +92610,11 @@ function createClaudeMemoryWatcher(cwd, vaultPath) {
|
|
|
92557
92610
|
}
|
|
92558
92611
|
}
|
|
92559
92612
|
function startProjectWatcher() {
|
|
92560
|
-
if (projectWatcher || stopped || !
|
|
92613
|
+
if (projectWatcher || stopped || !existsSync43(projectDir))
|
|
92561
92614
|
return;
|
|
92562
92615
|
try {
|
|
92563
92616
|
projectWatcher = watch2(projectDir, (_eventType, name) => {
|
|
92564
|
-
if (name === "memory" &&
|
|
92617
|
+
if (name === "memory" && existsSync43(memDir)) {
|
|
92565
92618
|
projectWatcher?.close();
|
|
92566
92619
|
projectWatcher = null;
|
|
92567
92620
|
startMemWatcher();
|
|
@@ -92580,9 +92633,9 @@ function createClaudeMemoryWatcher(cwd, vaultPath) {
|
|
|
92580
92633
|
if (started || stopped)
|
|
92581
92634
|
return;
|
|
92582
92635
|
started = true;
|
|
92583
|
-
if (
|
|
92636
|
+
if (existsSync43(memDir)) {
|
|
92584
92637
|
startMemWatcher();
|
|
92585
|
-
} else if (
|
|
92638
|
+
} else if (existsSync43(projectDir)) {
|
|
92586
92639
|
startProjectWatcher();
|
|
92587
92640
|
}
|
|
92588
92641
|
},
|
|
@@ -92600,11 +92653,11 @@ function createClaudeMemoryWatcher(cwd, vaultPath) {
|
|
|
92600
92653
|
init_settings();
|
|
92601
92654
|
|
|
92602
92655
|
// src/hooks/anchorkit-context-injection.ts
|
|
92603
|
-
import { existsSync as
|
|
92604
|
-
import { join as
|
|
92656
|
+
import { existsSync as existsSync44, readFileSync as readFileSync39 } from "node:fs";
|
|
92657
|
+
import { join as join51 } from "node:path";
|
|
92605
92658
|
function tryRead(path4, maxChars = 8000) {
|
|
92606
92659
|
try {
|
|
92607
|
-
if (!
|
|
92660
|
+
if (!existsSync44(path4))
|
|
92608
92661
|
return null;
|
|
92609
92662
|
const content = readFileSync39(path4, "utf-8");
|
|
92610
92663
|
return content.length > maxChars ? `${content.slice(0, maxChars)}
|
|
@@ -92615,10 +92668,10 @@ function tryRead(path4, maxChars = 8000) {
|
|
|
92615
92668
|
}
|
|
92616
92669
|
}
|
|
92617
92670
|
function computeAnchorKitContext(cwd) {
|
|
92618
|
-
const vaultPath =
|
|
92619
|
-
const claudeMdPath =
|
|
92620
|
-
const projectMdPath =
|
|
92621
|
-
const stateMdPath =
|
|
92671
|
+
const vaultPath = join51(cwd, ".anchorkit", "vault");
|
|
92672
|
+
const claudeMdPath = join51(vaultPath, "CLAUDE.md");
|
|
92673
|
+
const projectMdPath = join51(cwd, "PROJECT.md");
|
|
92674
|
+
const stateMdPath = join51(vaultPath, "STATE.md");
|
|
92622
92675
|
const claudeMd = tryRead(claudeMdPath);
|
|
92623
92676
|
const projectMd = tryRead(projectMdPath);
|
|
92624
92677
|
const stateMd = tryRead(stateMdPath, 4000);
|
|
@@ -93011,8 +93064,8 @@ function createAutoCaptureAgent(ctx) {
|
|
|
93011
93064
|
};
|
|
93012
93065
|
}
|
|
93013
93066
|
// src/vault/agents/session-lifecycle-agent.ts
|
|
93014
|
-
import { existsSync as
|
|
93015
|
-
import { join as
|
|
93067
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync25, readFileSync as readFileSync40, writeFileSync as writeFileSync27 } from "node:fs";
|
|
93068
|
+
import { join as join52 } from "node:path";
|
|
93016
93069
|
var CYCLE_CLASSIFIER_PROMPT = (conversation, currentState) => `You are a session-lifecycle classifier for a software engineering AI assistant. Your job is to detect when a meaningful work cycle has completed in a conversation.
|
|
93017
93070
|
|
|
93018
93071
|
You MUST work in ANY language — classify based on MEANING, not keywords.
|
|
@@ -93076,13 +93129,13 @@ function nowIso() {
|
|
|
93076
93129
|
return new Date().toISOString();
|
|
93077
93130
|
}
|
|
93078
93131
|
function writeSessionNote(vaultPath, title, cycleType, summary, stateUpdate) {
|
|
93079
|
-
const sessionsDir2 =
|
|
93132
|
+
const sessionsDir2 = join52(vaultPath, "_sessions");
|
|
93080
93133
|
mkdirSync25(sessionsDir2, { recursive: true });
|
|
93081
93134
|
const today = todayIso2();
|
|
93082
93135
|
const slug = slugify3(title);
|
|
93083
93136
|
const filename = `${today}-${slug}.md`;
|
|
93084
|
-
const filepath =
|
|
93085
|
-
if (
|
|
93137
|
+
const filepath = join52(sessionsDir2, filename);
|
|
93138
|
+
if (existsSync45(filepath))
|
|
93086
93139
|
return filepath;
|
|
93087
93140
|
const content = `---
|
|
93088
93141
|
title: "${title.replace(/"/g, "\\\"")}"
|
|
@@ -93106,11 +93159,11 @@ ${stateUpdate}
|
|
|
93106
93159
|
return filepath;
|
|
93107
93160
|
}
|
|
93108
93161
|
function updateStateMd(vaultPath, cycleType, title, summary) {
|
|
93109
|
-
const statePath2 =
|
|
93162
|
+
const statePath2 = join52(vaultPath, "STATE.md");
|
|
93110
93163
|
const today = todayIso2();
|
|
93111
93164
|
const entry = `- **${today}** [${cycleType}] ${title}: ${summary.split(`
|
|
93112
93165
|
`)[0]}`;
|
|
93113
|
-
if (!
|
|
93166
|
+
if (!existsSync45(statePath2)) {
|
|
93114
93167
|
const content = `# Project State
|
|
93115
93168
|
|
|
93116
93169
|
> Persistent state across AnchorKit sessions. Updated automatically when work cycles complete.
|
|
@@ -93166,13 +93219,13 @@ ${entry}
|
|
|
93166
93219
|
}
|
|
93167
93220
|
}
|
|
93168
93221
|
function createSessionLifecycleAgent(ctx) {
|
|
93169
|
-
const vaultPath =
|
|
93222
|
+
const vaultPath = join52(ctx.repoRoot, ".anchorkit", "vault");
|
|
93170
93223
|
return {
|
|
93171
93224
|
async run(conversation) {
|
|
93172
|
-
const stateMdPath =
|
|
93225
|
+
const stateMdPath = join52(vaultPath, "STATE.md");
|
|
93173
93226
|
let currentState = null;
|
|
93174
93227
|
try {
|
|
93175
|
-
if (
|
|
93228
|
+
if (existsSync45(stateMdPath)) {
|
|
93176
93229
|
currentState = readFileSync40(stateMdPath, "utf-8");
|
|
93177
93230
|
}
|
|
93178
93231
|
} catch {
|
|
@@ -93200,8 +93253,8 @@ function createSessionLifecycleAgent(ctx) {
|
|
|
93200
93253
|
};
|
|
93201
93254
|
}
|
|
93202
93255
|
// src/hooks/state.ts
|
|
93203
|
-
import { existsSync as
|
|
93204
|
-
import { dirname as dirname19, join as
|
|
93256
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync26, readFileSync as readFileSync41, writeFileSync as writeFileSync28 } from "node:fs";
|
|
93257
|
+
import { dirname as dirname19, join as join53 } from "node:path";
|
|
93205
93258
|
var EMPTY_STATE = Object.freeze({
|
|
93206
93259
|
captures: [],
|
|
93207
93260
|
conversationMapEmits: [],
|
|
@@ -93210,11 +93263,11 @@ var EMPTY_STATE = Object.freeze({
|
|
|
93210
93263
|
sessionCycles: []
|
|
93211
93264
|
});
|
|
93212
93265
|
function statePath2(repoRoot) {
|
|
93213
|
-
return
|
|
93266
|
+
return join53(repoRoot, ".anchorkit", "state.json");
|
|
93214
93267
|
}
|
|
93215
93268
|
function readState(repoRoot) {
|
|
93216
93269
|
const p = statePath2(repoRoot);
|
|
93217
|
-
if (!
|
|
93270
|
+
if (!existsSync46(p))
|
|
93218
93271
|
return cloneEmpty();
|
|
93219
93272
|
try {
|
|
93220
93273
|
const raw = readFileSync41(p, "utf-8");
|
|
@@ -93339,8 +93392,8 @@ Assistant: ${assistantText}`;
|
|
|
93339
93392
|
};
|
|
93340
93393
|
|
|
93341
93394
|
// src/hooks/conversation-mapping.ts
|
|
93342
|
-
import { existsSync as
|
|
93343
|
-
import { dirname as dirname20, isAbsolute as isAbsolute3, join as
|
|
93395
|
+
import { existsSync as existsSync47, readFileSync as readFileSync42, writeFileSync as writeFileSync29 } from "node:fs";
|
|
93396
|
+
import { dirname as dirname20, isAbsolute as isAbsolute3, join as join54, relative as relative7, resolve as resolve5 } from "node:path";
|
|
93344
93397
|
var MAX_PER_TURN = 5;
|
|
93345
93398
|
var MAX_PER_SESSION2 = 10;
|
|
93346
93399
|
var MAX_PER_HOUR2 = 30;
|
|
@@ -93375,7 +93428,7 @@ function slugForDir(repoRelDir) {
|
|
|
93375
93428
|
}
|
|
93376
93429
|
var INSIGHTS_HEADING = "## Conversation Insights";
|
|
93377
93430
|
function appendConversationInsight(notePath, entry, now2 = new Date) {
|
|
93378
|
-
if (!
|
|
93431
|
+
if (!existsSync47(notePath))
|
|
93379
93432
|
return false;
|
|
93380
93433
|
let raw;
|
|
93381
93434
|
try {
|
|
@@ -93421,7 +93474,7 @@ ${newEntry}
|
|
|
93421
93474
|
async function emitFirstTouchModule(repoRoot) {
|
|
93422
93475
|
try {
|
|
93423
93476
|
const { resolveVaultConfig: resolveVaultConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
93424
|
-
const { indexCodebase: indexCodebase2 } = await Promise.resolve().then(() => (
|
|
93477
|
+
const { indexCodebase: indexCodebase2 } = await Promise.resolve().then(() => (init_indexing(), exports_indexing));
|
|
93425
93478
|
const { runMapping: runMapping2 } = await Promise.resolve().then(() => (init_mapper(), exports_mapper));
|
|
93426
93479
|
const cfg = resolveVaultConfig2(repoRoot);
|
|
93427
93480
|
const index = await indexCodebase2(repoRoot);
|
|
@@ -93499,8 +93552,8 @@ var conversationMappingHook = {
|
|
|
93499
93552
|
return;
|
|
93500
93553
|
const assistantText = assistantTextFromEvents2(events);
|
|
93501
93554
|
const substantive = assistantText.trim().length > SUBSTANTIVE_TEXT_CHARS;
|
|
93502
|
-
const vaultPath =
|
|
93503
|
-
const knowledgeDir =
|
|
93555
|
+
const vaultPath = join54(ctx.repoRoot, ".anchorkit", "vault");
|
|
93556
|
+
const knowledgeDir = join54(vaultPath, "knowledge");
|
|
93504
93557
|
const emittedFiles = [];
|
|
93505
93558
|
const turnId = turnIdFromEvents(events);
|
|
93506
93559
|
let emittedThisTurn = 0;
|
|
@@ -93513,8 +93566,8 @@ var conversationMappingHook = {
|
|
|
93513
93566
|
const slug = slugForDir(relDir);
|
|
93514
93567
|
if (!slug)
|
|
93515
93568
|
continue;
|
|
93516
|
-
const notePath =
|
|
93517
|
-
if (!
|
|
93569
|
+
const notePath = join54(knowledgeDir, `module-${slug}.md`);
|
|
93570
|
+
if (!existsSync47(notePath)) {
|
|
93518
93571
|
if (!triggeredFirstTouch) {
|
|
93519
93572
|
triggeredFirstTouch = true;
|
|
93520
93573
|
const result = await emitFirstTouchModule(ctx.repoRoot);
|
|
@@ -93524,7 +93577,7 @@ var conversationMappingHook = {
|
|
|
93524
93577
|
continue;
|
|
93525
93578
|
}
|
|
93526
93579
|
}
|
|
93527
|
-
if (!
|
|
93580
|
+
if (!existsSync47(notePath))
|
|
93528
93581
|
continue;
|
|
93529
93582
|
emittedFiles.push(notePath);
|
|
93530
93583
|
emittedThisTurn += 1;
|
|
@@ -94155,8 +94208,8 @@ var injectContextHook = {
|
|
|
94155
94208
|
};
|
|
94156
94209
|
|
|
94157
94210
|
// src/services/specManager/index.ts
|
|
94158
|
-
import { existsSync as
|
|
94159
|
-
import { join as
|
|
94211
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync27, readFileSync as readFileSync43, writeFileSync as writeFileSync30 } from "node:fs";
|
|
94212
|
+
import { join as join55 } from "node:path";
|
|
94160
94213
|
function slugify5(input) {
|
|
94161
94214
|
return input.toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "untitled";
|
|
94162
94215
|
}
|
|
@@ -94164,10 +94217,10 @@ function nowIso2() {
|
|
|
94164
94217
|
return new Date().toISOString();
|
|
94165
94218
|
}
|
|
94166
94219
|
function specsRoot(repoRoot) {
|
|
94167
|
-
return
|
|
94220
|
+
return join55(repoRoot, ".anchorkit", "specs");
|
|
94168
94221
|
}
|
|
94169
94222
|
function manifestPath(repoRoot) {
|
|
94170
|
-
return
|
|
94223
|
+
return join55(specsRoot(repoRoot), "manifest.json");
|
|
94171
94224
|
}
|
|
94172
94225
|
function emptyManifest() {
|
|
94173
94226
|
return {
|
|
@@ -94180,7 +94233,7 @@ function emptyManifest() {
|
|
|
94180
94233
|
}
|
|
94181
94234
|
function readManifest(repoRoot) {
|
|
94182
94235
|
const mp = manifestPath(repoRoot);
|
|
94183
|
-
if (!
|
|
94236
|
+
if (!existsSync48(mp))
|
|
94184
94237
|
return emptyManifest();
|
|
94185
94238
|
try {
|
|
94186
94239
|
const raw = readFileSync43(mp, "utf-8");
|
|
@@ -94200,7 +94253,7 @@ function writeManifest(repoRoot, manifest) {
|
|
|
94200
94253
|
function createFeatureSpec(repoRoot, title, opts = {}) {
|
|
94201
94254
|
const manifest = readManifest(repoRoot);
|
|
94202
94255
|
const slug = slugify5(title);
|
|
94203
|
-
const dirPath =
|
|
94256
|
+
const dirPath = join55(specsRoot(repoRoot), "features", slug);
|
|
94204
94257
|
mkdirSync27(dirPath, { recursive: true });
|
|
94205
94258
|
const now2 = nowIso2();
|
|
94206
94259
|
const spec = {
|
|
@@ -94234,7 +94287,7 @@ ${opts.summary ?? "_To be specified._"}
|
|
|
94234
94287
|
|
|
94235
94288
|
- _None identified yet_
|
|
94236
94289
|
`;
|
|
94237
|
-
writeFileSync30(
|
|
94290
|
+
writeFileSync30(join55(dirPath, "spec.md"), specMd, "utf-8");
|
|
94238
94291
|
manifest.features[slug] = spec;
|
|
94239
94292
|
manifest.activeFeature = slug;
|
|
94240
94293
|
writeManifest(repoRoot, manifest);
|
|
@@ -94266,7 +94319,7 @@ function createQuickTask(repoRoot, title) {
|
|
|
94266
94319
|
const id = manifest.nextQuickId;
|
|
94267
94320
|
const slug = slugify5(title);
|
|
94268
94321
|
const dirName = `${String(id).padStart(3, "0")}-${slug}`;
|
|
94269
|
-
const dirPath =
|
|
94322
|
+
const dirPath = join55(specsRoot(repoRoot), "quick", dirName);
|
|
94270
94323
|
mkdirSync27(dirPath, { recursive: true });
|
|
94271
94324
|
const now2 = nowIso2();
|
|
94272
94325
|
const task = {
|
|
@@ -94290,15 +94343,15 @@ _${title}_
|
|
|
94290
94343
|
|
|
94291
94344
|
- [ ] _Define completion criteria_
|
|
94292
94345
|
`;
|
|
94293
|
-
writeFileSync30(
|
|
94346
|
+
writeFileSync30(join55(dirPath, "TASK.md"), taskMd, "utf-8");
|
|
94294
94347
|
manifest.quickTasks[dirName] = task;
|
|
94295
94348
|
manifest.nextQuickId = id + 1;
|
|
94296
94349
|
writeManifest(repoRoot, manifest);
|
|
94297
94350
|
return task;
|
|
94298
94351
|
}
|
|
94299
94352
|
function readSpecFile(repoRoot, featureSlug, filename) {
|
|
94300
|
-
const filePath =
|
|
94301
|
-
if (!
|
|
94353
|
+
const filePath = join55(specsRoot(repoRoot), "features", featureSlug, filename);
|
|
94354
|
+
if (!existsSync48(filePath))
|
|
94302
94355
|
return null;
|
|
94303
94356
|
try {
|
|
94304
94357
|
return readFileSync43(filePath, "utf-8");
|
|
@@ -95371,16 +95424,16 @@ function createHookPipeline(opts = {}) {
|
|
|
95371
95424
|
init_globalConfig();
|
|
95372
95425
|
|
|
95373
95426
|
// src/vault/principles/loader.ts
|
|
95374
|
-
import { existsSync as
|
|
95375
|
-
import { join as
|
|
95427
|
+
import { existsSync as existsSync49, readFileSync as readFileSync44 } from "node:fs";
|
|
95428
|
+
import { join as join56 } from "node:path";
|
|
95376
95429
|
var PRINCIPLES_FILENAME = "_principles.md";
|
|
95377
95430
|
function resolvePrinciplesPath(ref) {
|
|
95378
|
-
return
|
|
95431
|
+
return join56(ref.path, PRINCIPLES_FILENAME);
|
|
95379
95432
|
}
|
|
95380
95433
|
function readPrinciples(ref) {
|
|
95381
95434
|
const path4 = resolvePrinciplesPath(ref);
|
|
95382
95435
|
try {
|
|
95383
|
-
if (!
|
|
95436
|
+
if (!existsSync49(path4))
|
|
95384
95437
|
return null;
|
|
95385
95438
|
return readFileSync44(path4, "utf-8");
|
|
95386
95439
|
} catch {
|
|
@@ -95470,16 +95523,16 @@ function runPrinciplesInjection() {
|
|
|
95470
95523
|
return { systemPrompt: section2 };
|
|
95471
95524
|
}
|
|
95472
95525
|
// src/mcp-config/write.ts
|
|
95473
|
-
import { existsSync as
|
|
95474
|
-
import { dirname as dirname21, join as
|
|
95526
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync28, readFileSync as readFileSync45, writeFileSync as writeFileSync31 } from "node:fs";
|
|
95527
|
+
import { dirname as dirname21, join as join57, resolve as resolve6 } from "node:path";
|
|
95475
95528
|
var ANCHORKIT_SERVER_ENTRY = Object.freeze({
|
|
95476
95529
|
command: "anchorkit",
|
|
95477
95530
|
args: ["internal-mcp-server"]
|
|
95478
95531
|
});
|
|
95479
95532
|
function ensureMcpConfig(repoRoot) {
|
|
95480
|
-
const claudeDir =
|
|
95481
|
-
const configPath2 =
|
|
95482
|
-
if (!
|
|
95533
|
+
const claudeDir = join57(repoRoot, ".claude");
|
|
95534
|
+
const configPath2 = join57(claudeDir, "mcp.json");
|
|
95535
|
+
if (!existsSync50(configPath2)) {
|
|
95483
95536
|
mkdirSync28(dirname21(configPath2), { recursive: true });
|
|
95484
95537
|
writeFileSync31(configPath2, renderFreshConfig(), "utf-8");
|
|
95485
95538
|
return resolve6(configPath2);
|
|
@@ -95707,7 +95760,7 @@ function useSession(opts = {}) {
|
|
|
95707
95760
|
memWatcherRef.current = null;
|
|
95708
95761
|
return;
|
|
95709
95762
|
}
|
|
95710
|
-
const vaultPath =
|
|
95763
|
+
const vaultPath = join58(cwd, ".anchorkit", "vault");
|
|
95711
95764
|
const w2 = createClaudeMemoryWatcher(cwd, vaultPath);
|
|
95712
95765
|
w2.start();
|
|
95713
95766
|
memWatcherRef.current = w2;
|
|
@@ -96317,7 +96370,7 @@ async function resolveTier() {
|
|
|
96317
96370
|
return "free";
|
|
96318
96371
|
}
|
|
96319
96372
|
}
|
|
96320
|
-
var VERSION = "1.2.
|
|
96373
|
+
var VERSION = "1.2.6-beta.3.1";
|
|
96321
96374
|
var args = process.argv.slice(2);
|
|
96322
96375
|
if (args.includes("--version") || args.includes("-v")) {
|
|
96323
96376
|
console.log(`anchorkit v${VERSION}`);
|
|
@@ -96377,4 +96430,4 @@ if (args[0] === "internal-mcp-server") {
|
|
|
96377
96430
|
});
|
|
96378
96431
|
}
|
|
96379
96432
|
|
|
96380
|
-
//# debugId=
|
|
96433
|
+
//# debugId=A11665494EE3CF2C64756E2164756E21
|