akm-cli 0.9.0-beta.4 → 0.9.0-beta.41
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/CHANGELOG.md +646 -0
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +6 -2
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +22 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +22 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +24 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +22 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +25 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +21 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +21 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +23 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +22 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/cli.js +14 -3
- package/dist/commands/agent/contribute-cli.js +16 -3
- package/dist/commands/feedback-cli.js +15 -6
- package/dist/commands/graph/graph.js +75 -71
- package/dist/commands/health/checks.js +48 -0
- package/dist/commands/health/html-report.js +422 -80
- package/dist/commands/health.js +381 -9
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/consolidate.js +631 -111
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill.js +163 -69
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +115 -1
- package/dist/commands/improve/extract-prompt.js +39 -2
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +403 -40
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/homeostatic.js +467 -0
- package/dist/commands/improve/improve-auto-accept.js +113 -6
- package/dist/commands/improve/improve-profiles.js +12 -0
- package/dist/commands/improve/improve.js +2042 -612
- package/dist/commands/improve/memory/memory-contradiction-detect.js +23 -28
- package/dist/commands/improve/outcome-loop.js +256 -0
- package/dist/commands/improve/proactive-maintenance.js +115 -0
- package/dist/commands/improve/procedural.js +418 -0
- package/dist/commands/improve/recombine.js +602 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +46 -4
- package/dist/commands/improve/related-sessions.js +120 -0
- package/dist/commands/improve/salience.js +438 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +34 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/proposal/drain-policies.js +5 -0
- package/dist/commands/proposal/drain.js +17 -1
- package/dist/commands/proposal/proposal.js +5 -0
- package/dist/commands/proposal/propose.js +5 -0
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +187 -57
- package/dist/commands/read/curate.js +344 -80
- package/dist/commands/read/search-cli.js +7 -0
- package/dist/commands/read/search.js +1 -0
- package/dist/commands/read/show.js +67 -2
- package/dist/commands/sources/init.js +36 -9
- package/dist/commands/sources/installed-stashes.js +5 -1
- package/dist/commands/sources/schema-repair.js +13 -1
- package/dist/commands/sources/stash-cli.js +19 -3
- package/dist/commands/sources/stash-skeleton.js +23 -8
- package/dist/core/asset/asset-registry.js +2 -0
- package/dist/core/asset/asset-spec.js +14 -0
- package/dist/core/asset/frontmatter.js +166 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +83 -0
- package/dist/core/config/config-schema.js +274 -2
- package/dist/core/config/config.js +2 -2
- package/dist/core/logs-db.js +4 -3
- package/dist/core/paths.js +3 -0
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state-db.js +691 -30
- package/dist/indexer/db/db.js +364 -38
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/ensure-index.js +152 -17
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +203 -3
- package/dist/indexer/index-writer-lock.js +99 -0
- package/dist/indexer/indexer.js +114 -111
- package/dist/indexer/passes/memory-inference.js +10 -3
- package/dist/indexer/passes/staleness-detect.js +2 -5
- package/dist/indexer/search/db-search.js +15 -4
- package/dist/indexer/search/ranking-contributors.js +22 -0
- package/dist/indexer/search/ranking.js +4 -0
- package/dist/indexer/walk/matchers.js +9 -0
- package/dist/integrations/agent/prompts.js +33 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/client.js +23 -4
- package/dist/llm/embedder.js +27 -3
- package/dist/llm/embedders/local.js +66 -2
- package/dist/llm/feature-gate.js +8 -4
- package/dist/llm/graph-extract.js +2 -1
- package/dist/llm/memory-infer.js +4 -8
- package/dist/llm/metadata-enhance.js +9 -1
- package/dist/output/renderers.js +73 -1
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/text/helpers.js +16 -1
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +1378 -599
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +479 -270
- package/dist/setup/setup.js +3 -3
- package/dist/sources/providers/git.js +71 -61
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/wiki/wiki.js +37 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/data-and-telemetry.md +1 -0
- package/package.json +8 -6
|
@@ -491,349 +491,6 @@ var init_env = __esm(() => {
|
|
|
491
491
|
ASSIGN_RE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
|
|
492
492
|
});
|
|
493
493
|
|
|
494
|
-
// src/core/asset/frontmatter.ts
|
|
495
|
-
function parseFrontmatter(raw) {
|
|
496
|
-
const parsedBlock = parseFrontmatterBlock(raw);
|
|
497
|
-
if (!parsedBlock) {
|
|
498
|
-
return { data: {}, content: raw, frontmatter: null, bodyStartLine: 1 };
|
|
499
|
-
}
|
|
500
|
-
const data = {};
|
|
501
|
-
let currentKey = null;
|
|
502
|
-
let mode = "scalar";
|
|
503
|
-
let nested = null;
|
|
504
|
-
let currentList = null;
|
|
505
|
-
let blockLines = null;
|
|
506
|
-
let blockChomping = "clip";
|
|
507
|
-
const flushPending = () => {
|
|
508
|
-
if (mode === "pending" && currentKey !== null) {
|
|
509
|
-
data[currentKey] = "";
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
const flushBlock = () => {
|
|
513
|
-
if (mode !== "block" || currentKey === null || blockLines === null)
|
|
514
|
-
return;
|
|
515
|
-
const deindented = blockLines.map((l) => l.startsWith(" ") ? l.slice(2) : l);
|
|
516
|
-
if (blockChomping === "keep") {
|
|
517
|
-
data[currentKey] = deindented.join(`
|
|
518
|
-
`);
|
|
519
|
-
} else if (blockChomping === "strip") {
|
|
520
|
-
data[currentKey] = deindented.join(`
|
|
521
|
-
`).replace(/\n+$/, "");
|
|
522
|
-
} else {
|
|
523
|
-
data[currentKey] = `${deindented.join(`
|
|
524
|
-
`).replace(/\n+$/, "")}
|
|
525
|
-
`;
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
for (const line of parsedBlock.frontmatter.split(/\r?\n/)) {
|
|
529
|
-
if (mode === "block") {
|
|
530
|
-
if (line.startsWith(" ") || line === "") {
|
|
531
|
-
blockLines.push(line);
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
flushBlock();
|
|
535
|
-
mode = "scalar";
|
|
536
|
-
blockLines = null;
|
|
537
|
-
}
|
|
538
|
-
const seqItem = line.match(/^(?: {2})?- (.*)$/);
|
|
539
|
-
if (seqItem && currentKey !== null && (mode === "list" || mode === "pending")) {
|
|
540
|
-
if (mode === "pending") {
|
|
541
|
-
currentList = [];
|
|
542
|
-
data[currentKey] = currentList;
|
|
543
|
-
mode = "list";
|
|
544
|
-
}
|
|
545
|
-
currentList.push(parseYamlScalar(seqItem[1].trim()));
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
if (mode === "scalar" && currentKey !== null && /^ {2}\S/.test(line)) {
|
|
549
|
-
data[currentKey] = `${String(data[currentKey])} ${line.trim()}`;
|
|
550
|
-
continue;
|
|
551
|
-
}
|
|
552
|
-
const indented = line.match(/^ {2}(\w[\w-]*):\s*(.+)$/);
|
|
553
|
-
if (indented && currentKey !== null && (mode === "object" || mode === "pending")) {
|
|
554
|
-
if (mode === "pending") {
|
|
555
|
-
nested = {};
|
|
556
|
-
data[currentKey] = nested;
|
|
557
|
-
mode = "object";
|
|
558
|
-
}
|
|
559
|
-
nested[indented[1]] = parseYamlScalar(indented[2].trim());
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
const top = line.match(/^(\w[\w-]*):\s*(.*)$/);
|
|
563
|
-
if (!top) {
|
|
564
|
-
continue;
|
|
565
|
-
}
|
|
566
|
-
flushPending();
|
|
567
|
-
currentKey = top[1];
|
|
568
|
-
const value = top[2].trim();
|
|
569
|
-
if (value === "|" || value === "|-" || value === "|+") {
|
|
570
|
-
mode = "block";
|
|
571
|
-
blockLines = [];
|
|
572
|
-
blockChomping = value === "|-" ? "strip" : value === "|+" ? "keep" : "clip";
|
|
573
|
-
nested = null;
|
|
574
|
-
currentList = null;
|
|
575
|
-
} else if (value === "") {
|
|
576
|
-
mode = "pending";
|
|
577
|
-
nested = null;
|
|
578
|
-
currentList = null;
|
|
579
|
-
} else if (value.startsWith("[") && value.endsWith("]")) {
|
|
580
|
-
mode = "list";
|
|
581
|
-
nested = null;
|
|
582
|
-
currentList = null;
|
|
583
|
-
currentList = parseFlowArray(value);
|
|
584
|
-
data[currentKey] = currentList;
|
|
585
|
-
} else {
|
|
586
|
-
mode = "scalar";
|
|
587
|
-
nested = null;
|
|
588
|
-
currentList = null;
|
|
589
|
-
data[currentKey] = parseYamlScalar(value);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
if (mode === "block") {
|
|
593
|
-
flushBlock();
|
|
594
|
-
}
|
|
595
|
-
flushPending();
|
|
596
|
-
return {
|
|
597
|
-
data,
|
|
598
|
-
content: parsedBlock.content,
|
|
599
|
-
frontmatter: parsedBlock.frontmatter,
|
|
600
|
-
bodyStartLine: parsedBlock.bodyStartLine
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
function parseFlowArray(value) {
|
|
604
|
-
const inner = value.slice(1, -1).trim();
|
|
605
|
-
if (!inner)
|
|
606
|
-
return [];
|
|
607
|
-
return inner.split(",").map((item) => parseYamlScalar(item.trim()));
|
|
608
|
-
}
|
|
609
|
-
function parseFrontmatterBlock(raw) {
|
|
610
|
-
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/);
|
|
611
|
-
if (!match)
|
|
612
|
-
return null;
|
|
613
|
-
const frontmatter = match[1].replace(/\r/g, "");
|
|
614
|
-
const content = match[2];
|
|
615
|
-
return {
|
|
616
|
-
frontmatter,
|
|
617
|
-
content,
|
|
618
|
-
bodyStartLine: countLines(raw.slice(0, match[0].length - match[2].length)) + 1
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
function countLines(text) {
|
|
622
|
-
if (text.length === 0)
|
|
623
|
-
return 0;
|
|
624
|
-
return text.split(/\r?\n/).length - 1;
|
|
625
|
-
}
|
|
626
|
-
function parseYamlScalar(value) {
|
|
627
|
-
if (value === "")
|
|
628
|
-
return "";
|
|
629
|
-
if (value === "true")
|
|
630
|
-
return true;
|
|
631
|
-
if (value === "false")
|
|
632
|
-
return false;
|
|
633
|
-
const asNumber = Number(value);
|
|
634
|
-
if (!Number.isNaN(asNumber))
|
|
635
|
-
return asNumber;
|
|
636
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
637
|
-
return value.slice(1, -1);
|
|
638
|
-
}
|
|
639
|
-
return value;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// src/core/asset/markdown.ts
|
|
643
|
-
function parseMarkdownToc(content) {
|
|
644
|
-
const lines = content.split(/\r?\n/);
|
|
645
|
-
const headings = [];
|
|
646
|
-
const parsed = parseFrontmatter(content);
|
|
647
|
-
const start = parsed.frontmatter ? parsed.bodyStartLine - 1 : 0;
|
|
648
|
-
for (let i = start;i < lines.length; i++) {
|
|
649
|
-
const match = lines[i].match(/^(#{1,6})\s+(.+)$/);
|
|
650
|
-
if (match) {
|
|
651
|
-
headings.push({
|
|
652
|
-
level: match[1].length,
|
|
653
|
-
text: match[2].replace(/\s+#+\s*$/, "").trim(),
|
|
654
|
-
line: i + 1
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
return { headings, totalLines: lines.length };
|
|
659
|
-
}
|
|
660
|
-
var init_markdown = () => {};
|
|
661
|
-
|
|
662
|
-
// src/core/warn.ts
|
|
663
|
-
import fs2 from "fs";
|
|
664
|
-
function isVerbose() {
|
|
665
|
-
const env = process.env.AKM_VERBOSE?.trim().toLowerCase();
|
|
666
|
-
if (env === "1" || env === "true" || env === "yes" || env === "on")
|
|
667
|
-
return true;
|
|
668
|
-
if (env === "0" || env === "false" || env === "no" || env === "off")
|
|
669
|
-
return false;
|
|
670
|
-
return verbose;
|
|
671
|
-
}
|
|
672
|
-
function appendToLogFile(level, args) {
|
|
673
|
-
if (!logFilePath)
|
|
674
|
-
return;
|
|
675
|
-
const ts = new Date().toISOString();
|
|
676
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
677
|
-
try {
|
|
678
|
-
fs2.appendFileSync(logFilePath, `[${ts}] [${level}] ${msg}
|
|
679
|
-
`);
|
|
680
|
-
} catch (e) {
|
|
681
|
-
process.stderr.write(`[akm:warn] log-file write failed (${logFilePath}): ${e}
|
|
682
|
-
`);
|
|
683
|
-
process.stderr.write(`[${ts}] [${level}] ${msg}
|
|
684
|
-
`);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
function warn(...args) {
|
|
688
|
-
appendToLogFile("WARN", args);
|
|
689
|
-
if (!quiet) {
|
|
690
|
-
console.warn(...args);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
function error(...args) {
|
|
694
|
-
appendToLogFile("ERROR", args);
|
|
695
|
-
if (!quiet) {
|
|
696
|
-
console.error(...args);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
function warnVerbose(...args) {
|
|
700
|
-
if (isVerbose()) {
|
|
701
|
-
warn(...args);
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
var quiet = false, verbose = false, logFilePath;
|
|
705
|
-
var init_warn = () => {};
|
|
706
|
-
|
|
707
|
-
// src/indexer/walk/file-context.ts
|
|
708
|
-
var renderers;
|
|
709
|
-
var init_file_context = __esm(() => {
|
|
710
|
-
init_common();
|
|
711
|
-
renderers = new Map;
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
// src/indexer/passes/metadata-contributors.ts
|
|
715
|
-
function registerMetadataContributor(contributor) {
|
|
716
|
-
contributors.push(contributor);
|
|
717
|
-
}
|
|
718
|
-
var contributors;
|
|
719
|
-
var init_metadata_contributors = __esm(() => {
|
|
720
|
-
contributors = [];
|
|
721
|
-
});
|
|
722
|
-
|
|
723
|
-
// src/indexer/passes/metadata.ts
|
|
724
|
-
import fs3 from "fs";
|
|
725
|
-
function extractDescriptionFromComments(filePath) {
|
|
726
|
-
let content;
|
|
727
|
-
try {
|
|
728
|
-
content = fs3.readFileSync(filePath, "utf8");
|
|
729
|
-
} catch {
|
|
730
|
-
return null;
|
|
731
|
-
}
|
|
732
|
-
const lines = content.split(/\r?\n/).slice(0, 50);
|
|
733
|
-
const blockStart = lines.findIndex((l) => /^\s*\/\*\*/.test(l));
|
|
734
|
-
if (blockStart >= 0) {
|
|
735
|
-
const desc = [];
|
|
736
|
-
for (let i = blockStart;i < lines.length; i++) {
|
|
737
|
-
const line = lines[i];
|
|
738
|
-
if (i > blockStart && /\*\//.test(line))
|
|
739
|
-
break;
|
|
740
|
-
const cleaned = line.replace(/^\s*\/?\*\*?\s?/, "").replace(/\*\/\s*$/, "").trim();
|
|
741
|
-
if (cleaned)
|
|
742
|
-
desc.push(cleaned);
|
|
743
|
-
}
|
|
744
|
-
if (desc.length > 0)
|
|
745
|
-
return desc.join(" ");
|
|
746
|
-
}
|
|
747
|
-
let start = 0;
|
|
748
|
-
if (lines[0]?.startsWith("#!"))
|
|
749
|
-
start = 1;
|
|
750
|
-
const hashLines = [];
|
|
751
|
-
for (let i = start;i < lines.length; i++) {
|
|
752
|
-
const line = lines[i].trim();
|
|
753
|
-
if (line.startsWith("#") && !line.startsWith("#!")) {
|
|
754
|
-
hashLines.push(line.replace(/^#+\s*/, "").trim());
|
|
755
|
-
} else if (line === "") {} else {
|
|
756
|
-
break;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
if (hashLines.length > 0)
|
|
760
|
-
return hashLines.join(" ");
|
|
761
|
-
return null;
|
|
762
|
-
}
|
|
763
|
-
var KNOWN_QUALITY_VALUES, warnedUnknownQualityValues, WIKI_INFRA_FILES;
|
|
764
|
-
var init_metadata = __esm(() => {
|
|
765
|
-
init_asset_spec();
|
|
766
|
-
init_common();
|
|
767
|
-
init_warn();
|
|
768
|
-
init_file_context();
|
|
769
|
-
init_metadata_contributors();
|
|
770
|
-
KNOWN_QUALITY_VALUES = new Set(["generated", "curated", "enriched", "proposed"]);
|
|
771
|
-
warnedUnknownQualityValues = new Set;
|
|
772
|
-
WIKI_INFRA_FILES = new Set(["schema.md", "index.md", "log.md"]);
|
|
773
|
-
});
|
|
774
|
-
|
|
775
|
-
// src/core/asset/asset-ref.ts
|
|
776
|
-
import path from "path";
|
|
777
|
-
function parseAssetRef(ref) {
|
|
778
|
-
const trimmed = ref.trim();
|
|
779
|
-
if (!trimmed)
|
|
780
|
-
throw new UsageError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
781
|
-
let origin;
|
|
782
|
-
let body = trimmed;
|
|
783
|
-
const boundary = trimmed.indexOf("//");
|
|
784
|
-
if (boundary >= 0) {
|
|
785
|
-
origin = trimmed.slice(0, boundary);
|
|
786
|
-
body = trimmed.slice(boundary + 2);
|
|
787
|
-
if (!origin)
|
|
788
|
-
throw new UsageError("Empty origin in ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
789
|
-
}
|
|
790
|
-
const colon = body.indexOf(":");
|
|
791
|
-
if (colon <= 0) {
|
|
792
|
-
throw new UsageError(`Invalid ref "${trimmed}". Expected [origin//]type:name, e.g. skill:deploy or knowledge:guide.md`, "MISSING_REQUIRED_ARGUMENT");
|
|
793
|
-
}
|
|
794
|
-
const rawType = body.slice(0, colon);
|
|
795
|
-
const rawName = body.slice(colon + 1);
|
|
796
|
-
if (rawType === "vault") {
|
|
797
|
-
throw new UsageError("The `vault` asset type was removed in 0.9.0 \u2014 use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
|
|
798
|
-
}
|
|
799
|
-
const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
|
|
800
|
-
if (!isAssetType(resolvedType)) {
|
|
801
|
-
throw new UsageError(`Invalid asset type: "${rawType}".`, "MISSING_REQUIRED_ARGUMENT");
|
|
802
|
-
}
|
|
803
|
-
validateName(rawName);
|
|
804
|
-
const name = normalizeName(rawName);
|
|
805
|
-
return { type: resolvedType, name, origin: origin || undefined };
|
|
806
|
-
}
|
|
807
|
-
function validateName(name) {
|
|
808
|
-
if (!name)
|
|
809
|
-
throw new UsageError("Empty asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
810
|
-
if (name.includes("\x00"))
|
|
811
|
-
throw new UsageError("Null byte in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
812
|
-
if (/^[A-Za-z]:/.test(name))
|
|
813
|
-
throw new UsageError("Windows drive path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
814
|
-
const normalized = path.posix.normalize(name.replace(/\\/g, "/"));
|
|
815
|
-
if (path.posix.isAbsolute(normalized))
|
|
816
|
-
throw new UsageError("Absolute path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
817
|
-
if (normalized === ".." || normalized.startsWith("../")) {
|
|
818
|
-
throw new UsageError("Path traversal in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
819
|
-
}
|
|
820
|
-
const segments = normalized.split("/");
|
|
821
|
-
if (segments.some((seg) => seg === "." || seg === "..")) {
|
|
822
|
-
throw new UsageError("Asset name cannot contain relative path segments.", "MISSING_REQUIRED_ARGUMENT");
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
function normalizeName(name) {
|
|
826
|
-
return path.posix.normalize(name.replace(/\\/g, "/"));
|
|
827
|
-
}
|
|
828
|
-
var TYPE_ALIASES;
|
|
829
|
-
var init_asset_ref = __esm(() => {
|
|
830
|
-
init_common();
|
|
831
|
-
init_errors();
|
|
832
|
-
TYPE_ALIASES = {
|
|
833
|
-
environment: "env"
|
|
834
|
-
};
|
|
835
|
-
});
|
|
836
|
-
|
|
837
494
|
// node_modules/yaml/dist/nodes/identity.js
|
|
838
495
|
var require_identity = __commonJS((exports) => {
|
|
839
496
|
var ALIAS = Symbol.for("yaml.alias");
|
|
@@ -906,17 +563,17 @@ var require_visit = __commonJS((exports) => {
|
|
|
906
563
|
visit.BREAK = BREAK;
|
|
907
564
|
visit.SKIP = SKIP;
|
|
908
565
|
visit.REMOVE = REMOVE;
|
|
909
|
-
function visit_(key, node, visitor,
|
|
910
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
566
|
+
function visit_(key, node, visitor, path) {
|
|
567
|
+
const ctrl = callVisitor(key, node, visitor, path);
|
|
911
568
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
912
|
-
replaceNode(key,
|
|
913
|
-
return visit_(key, ctrl, visitor,
|
|
569
|
+
replaceNode(key, path, ctrl);
|
|
570
|
+
return visit_(key, ctrl, visitor, path);
|
|
914
571
|
}
|
|
915
572
|
if (typeof ctrl !== "symbol") {
|
|
916
573
|
if (identity.isCollection(node)) {
|
|
917
|
-
|
|
574
|
+
path = Object.freeze(path.concat(node));
|
|
918
575
|
for (let i = 0;i < node.items.length; ++i) {
|
|
919
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
576
|
+
const ci = visit_(i, node.items[i], visitor, path);
|
|
920
577
|
if (typeof ci === "number")
|
|
921
578
|
i = ci - 1;
|
|
922
579
|
else if (ci === BREAK)
|
|
@@ -927,13 +584,13 @@ var require_visit = __commonJS((exports) => {
|
|
|
927
584
|
}
|
|
928
585
|
}
|
|
929
586
|
} else if (identity.isPair(node)) {
|
|
930
|
-
|
|
931
|
-
const ck = visit_("key", node.key, visitor,
|
|
587
|
+
path = Object.freeze(path.concat(node));
|
|
588
|
+
const ck = visit_("key", node.key, visitor, path);
|
|
932
589
|
if (ck === BREAK)
|
|
933
590
|
return BREAK;
|
|
934
591
|
else if (ck === REMOVE)
|
|
935
592
|
node.key = null;
|
|
936
|
-
const cv = visit_("value", node.value, visitor,
|
|
593
|
+
const cv = visit_("value", node.value, visitor, path);
|
|
937
594
|
if (cv === BREAK)
|
|
938
595
|
return BREAK;
|
|
939
596
|
else if (cv === REMOVE)
|
|
@@ -954,17 +611,17 @@ var require_visit = __commonJS((exports) => {
|
|
|
954
611
|
visitAsync.BREAK = BREAK;
|
|
955
612
|
visitAsync.SKIP = SKIP;
|
|
956
613
|
visitAsync.REMOVE = REMOVE;
|
|
957
|
-
async function visitAsync_(key, node, visitor,
|
|
958
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
614
|
+
async function visitAsync_(key, node, visitor, path) {
|
|
615
|
+
const ctrl = await callVisitor(key, node, visitor, path);
|
|
959
616
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
960
|
-
replaceNode(key,
|
|
961
|
-
return visitAsync_(key, ctrl, visitor,
|
|
617
|
+
replaceNode(key, path, ctrl);
|
|
618
|
+
return visitAsync_(key, ctrl, visitor, path);
|
|
962
619
|
}
|
|
963
620
|
if (typeof ctrl !== "symbol") {
|
|
964
621
|
if (identity.isCollection(node)) {
|
|
965
|
-
|
|
622
|
+
path = Object.freeze(path.concat(node));
|
|
966
623
|
for (let i = 0;i < node.items.length; ++i) {
|
|
967
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
624
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path);
|
|
968
625
|
if (typeof ci === "number")
|
|
969
626
|
i = ci - 1;
|
|
970
627
|
else if (ci === BREAK)
|
|
@@ -975,13 +632,13 @@ var require_visit = __commonJS((exports) => {
|
|
|
975
632
|
}
|
|
976
633
|
}
|
|
977
634
|
} else if (identity.isPair(node)) {
|
|
978
|
-
|
|
979
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
635
|
+
path = Object.freeze(path.concat(node));
|
|
636
|
+
const ck = await visitAsync_("key", node.key, visitor, path);
|
|
980
637
|
if (ck === BREAK)
|
|
981
638
|
return BREAK;
|
|
982
639
|
else if (ck === REMOVE)
|
|
983
640
|
node.key = null;
|
|
984
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
641
|
+
const cv = await visitAsync_("value", node.value, visitor, path);
|
|
985
642
|
if (cv === BREAK)
|
|
986
643
|
return BREAK;
|
|
987
644
|
else if (cv === REMOVE)
|
|
@@ -1008,23 +665,23 @@ var require_visit = __commonJS((exports) => {
|
|
|
1008
665
|
}
|
|
1009
666
|
return visitor;
|
|
1010
667
|
}
|
|
1011
|
-
function callVisitor(key, node, visitor,
|
|
668
|
+
function callVisitor(key, node, visitor, path) {
|
|
1012
669
|
if (typeof visitor === "function")
|
|
1013
|
-
return visitor(key, node,
|
|
670
|
+
return visitor(key, node, path);
|
|
1014
671
|
if (identity.isMap(node))
|
|
1015
|
-
return visitor.Map?.(key, node,
|
|
672
|
+
return visitor.Map?.(key, node, path);
|
|
1016
673
|
if (identity.isSeq(node))
|
|
1017
|
-
return visitor.Seq?.(key, node,
|
|
674
|
+
return visitor.Seq?.(key, node, path);
|
|
1018
675
|
if (identity.isPair(node))
|
|
1019
|
-
return visitor.Pair?.(key, node,
|
|
676
|
+
return visitor.Pair?.(key, node, path);
|
|
1020
677
|
if (identity.isScalar(node))
|
|
1021
|
-
return visitor.Scalar?.(key, node,
|
|
678
|
+
return visitor.Scalar?.(key, node, path);
|
|
1022
679
|
if (identity.isAlias(node))
|
|
1023
|
-
return visitor.Alias?.(key, node,
|
|
680
|
+
return visitor.Alias?.(key, node, path);
|
|
1024
681
|
return;
|
|
1025
682
|
}
|
|
1026
|
-
function replaceNode(key,
|
|
1027
|
-
const parent =
|
|
683
|
+
function replaceNode(key, path, node) {
|
|
684
|
+
const parent = path[path.length - 1];
|
|
1028
685
|
if (identity.isCollection(parent)) {
|
|
1029
686
|
parent.items[key] = node;
|
|
1030
687
|
} else if (identity.isPair(parent)) {
|
|
@@ -1150,8 +807,8 @@ var require_directives = __commonJS((exports) => {
|
|
|
1150
807
|
if (prefix) {
|
|
1151
808
|
try {
|
|
1152
809
|
return prefix + decodeURIComponent(suffix);
|
|
1153
|
-
} catch (
|
|
1154
|
-
onError(String(
|
|
810
|
+
} catch (error) {
|
|
811
|
+
onError(String(error));
|
|
1155
812
|
return null;
|
|
1156
813
|
}
|
|
1157
814
|
}
|
|
@@ -1242,9 +899,9 @@ var require_anchors = __commonJS((exports) => {
|
|
|
1242
899
|
if (typeof ref === "object" && ref.anchor && (identity.isScalar(ref.node) || identity.isCollection(ref.node))) {
|
|
1243
900
|
ref.node.anchor = ref.anchor;
|
|
1244
901
|
} else {
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
throw
|
|
902
|
+
const error = new Error("Failed to resolve repeated object (this should not happen)");
|
|
903
|
+
error.source = source;
|
|
904
|
+
throw error;
|
|
1248
905
|
}
|
|
1249
906
|
}
|
|
1250
907
|
},
|
|
@@ -1583,10 +1240,10 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1583
1240
|
var createNode = require_createNode();
|
|
1584
1241
|
var identity = require_identity();
|
|
1585
1242
|
var Node = require_Node();
|
|
1586
|
-
function collectionFromPath(schema,
|
|
1243
|
+
function collectionFromPath(schema, path, value) {
|
|
1587
1244
|
let v = value;
|
|
1588
|
-
for (let i =
|
|
1589
|
-
const k =
|
|
1245
|
+
for (let i = path.length - 1;i >= 0; --i) {
|
|
1246
|
+
const k = path[i];
|
|
1590
1247
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
1591
1248
|
const a = [];
|
|
1592
1249
|
a[k] = v;
|
|
@@ -1605,7 +1262,7 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1605
1262
|
sourceObjects: new Map
|
|
1606
1263
|
});
|
|
1607
1264
|
}
|
|
1608
|
-
var isEmptyPath = (
|
|
1265
|
+
var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
|
|
1609
1266
|
|
|
1610
1267
|
class Collection extends Node.NodeBase {
|
|
1611
1268
|
constructor(type, schema) {
|
|
@@ -1626,11 +1283,11 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1626
1283
|
copy.range = this.range.slice();
|
|
1627
1284
|
return copy;
|
|
1628
1285
|
}
|
|
1629
|
-
addIn(
|
|
1630
|
-
if (isEmptyPath(
|
|
1286
|
+
addIn(path, value) {
|
|
1287
|
+
if (isEmptyPath(path))
|
|
1631
1288
|
this.add(value);
|
|
1632
1289
|
else {
|
|
1633
|
-
const [key, ...rest] =
|
|
1290
|
+
const [key, ...rest] = path;
|
|
1634
1291
|
const node = this.get(key, true);
|
|
1635
1292
|
if (identity.isCollection(node))
|
|
1636
1293
|
node.addIn(rest, value);
|
|
@@ -1640,8 +1297,8 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1640
1297
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
1641
1298
|
}
|
|
1642
1299
|
}
|
|
1643
|
-
deleteIn(
|
|
1644
|
-
const [key, ...rest] =
|
|
1300
|
+
deleteIn(path) {
|
|
1301
|
+
const [key, ...rest] = path;
|
|
1645
1302
|
if (rest.length === 0)
|
|
1646
1303
|
return this.delete(key);
|
|
1647
1304
|
const node = this.get(key, true);
|
|
@@ -1650,8 +1307,8 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1650
1307
|
else
|
|
1651
1308
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
1652
1309
|
}
|
|
1653
|
-
getIn(
|
|
1654
|
-
const [key, ...rest] =
|
|
1310
|
+
getIn(path, keepScalar) {
|
|
1311
|
+
const [key, ...rest] = path;
|
|
1655
1312
|
const node = this.get(key, true);
|
|
1656
1313
|
if (rest.length === 0)
|
|
1657
1314
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -1666,15 +1323,15 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1666
1323
|
return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
|
|
1667
1324
|
});
|
|
1668
1325
|
}
|
|
1669
|
-
hasIn(
|
|
1670
|
-
const [key, ...rest] =
|
|
1326
|
+
hasIn(path) {
|
|
1327
|
+
const [key, ...rest] = path;
|
|
1671
1328
|
if (rest.length === 0)
|
|
1672
1329
|
return this.has(key);
|
|
1673
1330
|
const node = this.get(key, true);
|
|
1674
1331
|
return identity.isCollection(node) ? node.hasIn(rest) : false;
|
|
1675
1332
|
}
|
|
1676
|
-
setIn(
|
|
1677
|
-
const [key, ...rest] =
|
|
1333
|
+
setIn(path, value) {
|
|
1334
|
+
const [key, ...rest] = path;
|
|
1678
1335
|
if (rest.length === 0) {
|
|
1679
1336
|
this.set(key, value);
|
|
1680
1337
|
} else {
|
|
@@ -2409,7 +2066,7 @@ var require_log = __commonJS((exports) => {
|
|
|
2409
2066
|
if (logLevel === "debug")
|
|
2410
2067
|
console.log(...messages);
|
|
2411
2068
|
}
|
|
2412
|
-
function
|
|
2069
|
+
function warn(logLevel, warning) {
|
|
2413
2070
|
if (logLevel === "debug" || logLevel === "warn") {
|
|
2414
2071
|
if (typeof node_process.emitWarning === "function")
|
|
2415
2072
|
node_process.emitWarning(warning);
|
|
@@ -2418,7 +2075,7 @@ var require_log = __commonJS((exports) => {
|
|
|
2418
2075
|
}
|
|
2419
2076
|
}
|
|
2420
2077
|
exports.debug = debug;
|
|
2421
|
-
exports.warn =
|
|
2078
|
+
exports.warn = warn;
|
|
2422
2079
|
});
|
|
2423
2080
|
|
|
2424
2081
|
// node_modules/yaml/dist/schema/yaml-1.1/merge.js
|
|
@@ -4067,9 +3724,9 @@ var require_Document = __commonJS((exports) => {
|
|
|
4067
3724
|
if (assertCollection(this.contents))
|
|
4068
3725
|
this.contents.add(value);
|
|
4069
3726
|
}
|
|
4070
|
-
addIn(
|
|
3727
|
+
addIn(path, value) {
|
|
4071
3728
|
if (assertCollection(this.contents))
|
|
4072
|
-
this.contents.addIn(
|
|
3729
|
+
this.contents.addIn(path, value);
|
|
4073
3730
|
}
|
|
4074
3731
|
createAlias(node, name) {
|
|
4075
3732
|
if (!node.anchor) {
|
|
@@ -4118,30 +3775,30 @@ var require_Document = __commonJS((exports) => {
|
|
|
4118
3775
|
delete(key) {
|
|
4119
3776
|
return assertCollection(this.contents) ? this.contents.delete(key) : false;
|
|
4120
3777
|
}
|
|
4121
|
-
deleteIn(
|
|
4122
|
-
if (Collection.isEmptyPath(
|
|
3778
|
+
deleteIn(path) {
|
|
3779
|
+
if (Collection.isEmptyPath(path)) {
|
|
4123
3780
|
if (this.contents == null)
|
|
4124
3781
|
return false;
|
|
4125
3782
|
this.contents = null;
|
|
4126
3783
|
return true;
|
|
4127
3784
|
}
|
|
4128
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3785
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path) : false;
|
|
4129
3786
|
}
|
|
4130
3787
|
get(key, keepScalar) {
|
|
4131
3788
|
return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : undefined;
|
|
4132
3789
|
}
|
|
4133
|
-
getIn(
|
|
4134
|
-
if (Collection.isEmptyPath(
|
|
3790
|
+
getIn(path, keepScalar) {
|
|
3791
|
+
if (Collection.isEmptyPath(path))
|
|
4135
3792
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
4136
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3793
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : undefined;
|
|
4137
3794
|
}
|
|
4138
3795
|
has(key) {
|
|
4139
3796
|
return identity.isCollection(this.contents) ? this.contents.has(key) : false;
|
|
4140
3797
|
}
|
|
4141
|
-
hasIn(
|
|
4142
|
-
if (Collection.isEmptyPath(
|
|
3798
|
+
hasIn(path) {
|
|
3799
|
+
if (Collection.isEmptyPath(path))
|
|
4143
3800
|
return this.contents !== undefined;
|
|
4144
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3801
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;
|
|
4145
3802
|
}
|
|
4146
3803
|
set(key, value) {
|
|
4147
3804
|
if (this.contents == null) {
|
|
@@ -4150,13 +3807,13 @@ var require_Document = __commonJS((exports) => {
|
|
|
4150
3807
|
this.contents.set(key, value);
|
|
4151
3808
|
}
|
|
4152
3809
|
}
|
|
4153
|
-
setIn(
|
|
4154
|
-
if (Collection.isEmptyPath(
|
|
3810
|
+
setIn(path, value) {
|
|
3811
|
+
if (Collection.isEmptyPath(path)) {
|
|
4155
3812
|
this.contents = value;
|
|
4156
3813
|
} else if (this.contents == null) {
|
|
4157
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3814
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
|
|
4158
3815
|
} else if (assertCollection(this.contents)) {
|
|
4159
|
-
this.contents.setIn(
|
|
3816
|
+
this.contents.setIn(path, value);
|
|
4160
3817
|
}
|
|
4161
3818
|
}
|
|
4162
3819
|
setSchema(version, options = {}) {
|
|
@@ -4255,12 +3912,12 @@ var require_errors = __commonJS((exports) => {
|
|
|
4255
3912
|
super("YAMLWarning", pos, code, message);
|
|
4256
3913
|
}
|
|
4257
3914
|
}
|
|
4258
|
-
var prettifyError = (src, lc) => (
|
|
4259
|
-
if (
|
|
3915
|
+
var prettifyError = (src, lc) => (error) => {
|
|
3916
|
+
if (error.pos[0] === -1)
|
|
4260
3917
|
return;
|
|
4261
|
-
|
|
4262
|
-
const { line, col } =
|
|
4263
|
-
|
|
3918
|
+
error.linePos = error.pos.map((pos) => lc.linePos(pos));
|
|
3919
|
+
const { line, col } = error.linePos[0];
|
|
3920
|
+
error.message += ` at line ${line}, column ${col}`;
|
|
4264
3921
|
let ci = col - 1;
|
|
4265
3922
|
let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
|
|
4266
3923
|
if (ci >= 60 && lineStr.length > 80) {
|
|
@@ -4279,12 +3936,12 @@ var require_errors = __commonJS((exports) => {
|
|
|
4279
3936
|
}
|
|
4280
3937
|
if (/[^ ]/.test(lineStr)) {
|
|
4281
3938
|
let count = 1;
|
|
4282
|
-
const end =
|
|
3939
|
+
const end = error.linePos[1];
|
|
4283
3940
|
if (end?.line === line && end.col > col) {
|
|
4284
3941
|
count = Math.max(1, Math.min(end.col - col, 80 - ci));
|
|
4285
3942
|
}
|
|
4286
3943
|
const pointer = " ".repeat(ci) + "^".repeat(count);
|
|
4287
|
-
|
|
3944
|
+
error.message += `:
|
|
4288
3945
|
|
|
4289
3946
|
${lineStr}
|
|
4290
3947
|
${pointer}
|
|
@@ -5074,7 +4731,7 @@ var require_resolve_block_scalar = __commonJS((exports) => {
|
|
|
5074
4731
|
const mode = source[0];
|
|
5075
4732
|
let indent = 0;
|
|
5076
4733
|
let chomp = "";
|
|
5077
|
-
let
|
|
4734
|
+
let error = -1;
|
|
5078
4735
|
for (let i = 1;i < source.length; ++i) {
|
|
5079
4736
|
const ch = source[i];
|
|
5080
4737
|
if (!chomp && (ch === "-" || ch === "+"))
|
|
@@ -5083,12 +4740,12 @@ var require_resolve_block_scalar = __commonJS((exports) => {
|
|
|
5083
4740
|
const n = Number(ch);
|
|
5084
4741
|
if (!indent && n)
|
|
5085
4742
|
indent = n;
|
|
5086
|
-
else if (
|
|
5087
|
-
|
|
4743
|
+
else if (error === -1)
|
|
4744
|
+
error = offset + i;
|
|
5088
4745
|
}
|
|
5089
4746
|
}
|
|
5090
|
-
if (
|
|
5091
|
-
onError(
|
|
4747
|
+
if (error !== -1)
|
|
4748
|
+
onError(error, "UNEXPECTED_TOKEN", `Block scalar header includes extra characters: ${source}`);
|
|
5092
4749
|
let hasSpace = false;
|
|
5093
4750
|
let comment = "";
|
|
5094
4751
|
let length = source.length;
|
|
@@ -5375,8 +5032,8 @@ var require_compose_scalar = __commonJS((exports) => {
|
|
|
5375
5032
|
try {
|
|
5376
5033
|
const res = tag.resolve(value, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
|
|
5377
5034
|
scalar = identity.isScalar(res) ? res : new Scalar.Scalar(res);
|
|
5378
|
-
} catch (
|
|
5379
|
-
const msg =
|
|
5035
|
+
} catch (error) {
|
|
5036
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
5380
5037
|
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
|
|
5381
5038
|
scalar = new Scalar.Scalar(value);
|
|
5382
5039
|
}
|
|
@@ -5493,8 +5150,8 @@ var require_compose_node = __commonJS((exports) => {
|
|
|
5493
5150
|
node = composeCollection.composeCollection(CN, ctx, token, props, onError);
|
|
5494
5151
|
if (anchor)
|
|
5495
5152
|
node.anchor = anchor.source.substring(1);
|
|
5496
|
-
} catch (
|
|
5497
|
-
const message =
|
|
5153
|
+
} catch (error) {
|
|
5154
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5498
5155
|
onError(token, "RESOURCE_EXHAUSTION", message);
|
|
5499
5156
|
}
|
|
5500
5157
|
break;
|
|
@@ -5743,11 +5400,11 @@ ${cb}` : comment;
|
|
|
5743
5400
|
break;
|
|
5744
5401
|
case "error": {
|
|
5745
5402
|
const msg = token.source ? `${token.message}: ${JSON.stringify(token.source)}` : token.message;
|
|
5746
|
-
const
|
|
5403
|
+
const error = new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg);
|
|
5747
5404
|
if (this.atDirectives || !this.doc)
|
|
5748
|
-
this.errors.push(
|
|
5405
|
+
this.errors.push(error);
|
|
5749
5406
|
else
|
|
5750
|
-
this.doc.errors.push(
|
|
5407
|
+
this.doc.errors.push(error);
|
|
5751
5408
|
break;
|
|
5752
5409
|
}
|
|
5753
5410
|
case "doc-end": {
|
|
@@ -6051,9 +5708,9 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
6051
5708
|
visit.BREAK = BREAK;
|
|
6052
5709
|
visit.SKIP = SKIP;
|
|
6053
5710
|
visit.REMOVE = REMOVE;
|
|
6054
|
-
visit.itemAtPath = (cst,
|
|
5711
|
+
visit.itemAtPath = (cst, path) => {
|
|
6055
5712
|
let item = cst;
|
|
6056
|
-
for (const [field, index] of
|
|
5713
|
+
for (const [field, index] of path) {
|
|
6057
5714
|
const tok = item?.[field];
|
|
6058
5715
|
if (tok && "items" in tok) {
|
|
6059
5716
|
item = tok.items[index];
|
|
@@ -6062,23 +5719,23 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
6062
5719
|
}
|
|
6063
5720
|
return item;
|
|
6064
5721
|
};
|
|
6065
|
-
visit.parentCollection = (cst,
|
|
6066
|
-
const parent = visit.itemAtPath(cst,
|
|
6067
|
-
const field =
|
|
5722
|
+
visit.parentCollection = (cst, path) => {
|
|
5723
|
+
const parent = visit.itemAtPath(cst, path.slice(0, -1));
|
|
5724
|
+
const field = path[path.length - 1][0];
|
|
6068
5725
|
const coll = parent?.[field];
|
|
6069
5726
|
if (coll && "items" in coll)
|
|
6070
5727
|
return coll;
|
|
6071
5728
|
throw new Error("Parent collection not found");
|
|
6072
5729
|
};
|
|
6073
|
-
function _visit(
|
|
6074
|
-
let ctrl = visitor(item,
|
|
5730
|
+
function _visit(path, item, visitor) {
|
|
5731
|
+
let ctrl = visitor(item, path);
|
|
6075
5732
|
if (typeof ctrl === "symbol")
|
|
6076
5733
|
return ctrl;
|
|
6077
5734
|
for (const field of ["key", "value"]) {
|
|
6078
5735
|
const token = item[field];
|
|
6079
5736
|
if (token && "items" in token) {
|
|
6080
5737
|
for (let i = 0;i < token.items.length; ++i) {
|
|
6081
|
-
const ci = _visit(Object.freeze(
|
|
5738
|
+
const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
|
|
6082
5739
|
if (typeof ci === "number")
|
|
6083
5740
|
i = ci - 1;
|
|
6084
5741
|
else if (ci === BREAK)
|
|
@@ -6089,10 +5746,10 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
6089
5746
|
}
|
|
6090
5747
|
}
|
|
6091
5748
|
if (typeof ctrl === "function" && field === "key")
|
|
6092
|
-
ctrl = ctrl(item,
|
|
5749
|
+
ctrl = ctrl(item, path);
|
|
6093
5750
|
}
|
|
6094
5751
|
}
|
|
6095
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5752
|
+
return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
|
|
6096
5753
|
}
|
|
6097
5754
|
exports.visit = visit;
|
|
6098
5755
|
});
|
|
@@ -7020,8 +6677,8 @@ var require_parser = __commonJS((exports) => {
|
|
|
7020
6677
|
peek(n) {
|
|
7021
6678
|
return this.stack[this.stack.length - n];
|
|
7022
6679
|
}
|
|
7023
|
-
*pop(
|
|
7024
|
-
const token =
|
|
6680
|
+
*pop(error) {
|
|
6681
|
+
const token = error ?? this.stack.pop();
|
|
7025
6682
|
if (!token) {
|
|
7026
6683
|
const message = "Tried to pop an empty stack";
|
|
7027
6684
|
yield { type: "error", offset: this.offset, source: "", message };
|
|
@@ -7361,14 +7018,14 @@ var require_parser = __commonJS((exports) => {
|
|
|
7361
7018
|
case "scalar":
|
|
7362
7019
|
case "single-quoted-scalar":
|
|
7363
7020
|
case "double-quoted-scalar": {
|
|
7364
|
-
const
|
|
7021
|
+
const fs2 = this.flowScalar(this.type);
|
|
7365
7022
|
if (atNextItem || it.value) {
|
|
7366
|
-
map.items.push({ start, key:
|
|
7023
|
+
map.items.push({ start, key: fs2, sep: [] });
|
|
7367
7024
|
this.onKeyLine = true;
|
|
7368
7025
|
} else if (it.sep) {
|
|
7369
|
-
this.stack.push(
|
|
7026
|
+
this.stack.push(fs2);
|
|
7370
7027
|
} else {
|
|
7371
|
-
Object.assign(it, { key:
|
|
7028
|
+
Object.assign(it, { key: fs2, sep: [] });
|
|
7372
7029
|
this.onKeyLine = true;
|
|
7373
7030
|
}
|
|
7374
7031
|
return;
|
|
@@ -7496,13 +7153,13 @@ var require_parser = __commonJS((exports) => {
|
|
|
7496
7153
|
case "scalar":
|
|
7497
7154
|
case "single-quoted-scalar":
|
|
7498
7155
|
case "double-quoted-scalar": {
|
|
7499
|
-
const
|
|
7156
|
+
const fs2 = this.flowScalar(this.type);
|
|
7500
7157
|
if (!it || it.value)
|
|
7501
|
-
fc.items.push({ start: [], key:
|
|
7158
|
+
fc.items.push({ start: [], key: fs2, sep: [] });
|
|
7502
7159
|
else if (it.sep)
|
|
7503
|
-
this.stack.push(
|
|
7160
|
+
this.stack.push(fs2);
|
|
7504
7161
|
else
|
|
7505
|
-
Object.assign(it, { key:
|
|
7162
|
+
Object.assign(it, { key: fs2, sep: [] });
|
|
7506
7163
|
return;
|
|
7507
7164
|
}
|
|
7508
7165
|
case "flow-map-end":
|
|
@@ -7804,7 +7461,301 @@ var init_dist = __esm(() => {
|
|
|
7804
7461
|
$visitAsync = visit.visitAsync;
|
|
7805
7462
|
});
|
|
7806
7463
|
|
|
7807
|
-
// src/
|
|
7464
|
+
// src/core/asset/frontmatter.ts
|
|
7465
|
+
function parseFrontmatter(raw) {
|
|
7466
|
+
const parsedBlock = parseFrontmatterBlock(raw);
|
|
7467
|
+
if (!parsedBlock) {
|
|
7468
|
+
return { data: {}, content: raw, frontmatter: null, bodyStartLine: 1 };
|
|
7469
|
+
}
|
|
7470
|
+
let data = {};
|
|
7471
|
+
if (parsedBlock.frontmatter.trim()) {
|
|
7472
|
+
try {
|
|
7473
|
+
const parsed = $parse(parsedBlock.frontmatter);
|
|
7474
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7475
|
+
data = normalizeYamlValues(parsed);
|
|
7476
|
+
}
|
|
7477
|
+
} catch {
|
|
7478
|
+
data = parseFrontmatterLenient(parsedBlock.frontmatter);
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
return {
|
|
7482
|
+
data,
|
|
7483
|
+
content: parsedBlock.content,
|
|
7484
|
+
frontmatter: parsedBlock.frontmatter,
|
|
7485
|
+
bodyStartLine: parsedBlock.bodyStartLine
|
|
7486
|
+
};
|
|
7487
|
+
}
|
|
7488
|
+
function normalizeYamlValues(value) {
|
|
7489
|
+
if (value instanceof Date) {
|
|
7490
|
+
const y = value.getUTCFullYear();
|
|
7491
|
+
const m = String(value.getUTCMonth() + 1).padStart(2, "0");
|
|
7492
|
+
const d = String(value.getUTCDate()).padStart(2, "0");
|
|
7493
|
+
return `${y}-${m}-${d}`;
|
|
7494
|
+
}
|
|
7495
|
+
if (value === null)
|
|
7496
|
+
return "";
|
|
7497
|
+
if (Array.isArray(value))
|
|
7498
|
+
return value.map(normalizeYamlValues);
|
|
7499
|
+
if (typeof value === "object") {
|
|
7500
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, normalizeYamlValues(v)]));
|
|
7501
|
+
}
|
|
7502
|
+
return value;
|
|
7503
|
+
}
|
|
7504
|
+
function parseFrontmatterLenient(frontmatter) {
|
|
7505
|
+
const data = {};
|
|
7506
|
+
for (const line of frontmatter.split(/\r?\n/)) {
|
|
7507
|
+
const m = line.match(/^([\w][\w-]*):\s*(.*)$/);
|
|
7508
|
+
if (!m)
|
|
7509
|
+
continue;
|
|
7510
|
+
const key = m[1];
|
|
7511
|
+
const rawValue = (m[2] ?? "").trim();
|
|
7512
|
+
try {
|
|
7513
|
+
const singleEntry = $parse(`k: ${rawValue}`);
|
|
7514
|
+
if (singleEntry !== null && typeof singleEntry === "object" && !Array.isArray(singleEntry)) {
|
|
7515
|
+
const v = singleEntry.k;
|
|
7516
|
+
data[key] = v === null || v === undefined ? "" : v;
|
|
7517
|
+
} else {
|
|
7518
|
+
data[key] = rawValue;
|
|
7519
|
+
}
|
|
7520
|
+
} catch {
|
|
7521
|
+
data[key] = rawValue;
|
|
7522
|
+
}
|
|
7523
|
+
}
|
|
7524
|
+
return data;
|
|
7525
|
+
}
|
|
7526
|
+
function parseFrontmatterBlock(raw) {
|
|
7527
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/);
|
|
7528
|
+
if (match) {
|
|
7529
|
+
const frontmatter = match[1].replace(/\r/g, "");
|
|
7530
|
+
const content = match[2];
|
|
7531
|
+
return {
|
|
7532
|
+
frontmatter,
|
|
7533
|
+
content,
|
|
7534
|
+
bodyStartLine: countLines(raw.slice(0, match[0].length - match[2].length)) + 1
|
|
7535
|
+
};
|
|
7536
|
+
}
|
|
7537
|
+
const emptyMatch = raw.match(/^---\r?\n---(?:\r\n|\r|\n)([\s\S]*)$/);
|
|
7538
|
+
if (emptyMatch) {
|
|
7539
|
+
return { frontmatter: "", content: emptyMatch[1], bodyStartLine: 3 };
|
|
7540
|
+
}
|
|
7541
|
+
return null;
|
|
7542
|
+
}
|
|
7543
|
+
function countLines(text) {
|
|
7544
|
+
if (text.length === 0)
|
|
7545
|
+
return 0;
|
|
7546
|
+
return text.split(/\r?\n/).length - 1;
|
|
7547
|
+
}
|
|
7548
|
+
var init_frontmatter = __esm(() => {
|
|
7549
|
+
init_dist();
|
|
7550
|
+
});
|
|
7551
|
+
|
|
7552
|
+
// src/core/asset/markdown.ts
|
|
7553
|
+
function parseMarkdownToc(content) {
|
|
7554
|
+
const lines = content.split(/\r?\n/);
|
|
7555
|
+
const headings = [];
|
|
7556
|
+
const parsed = parseFrontmatter(content);
|
|
7557
|
+
const start = parsed.frontmatter ? parsed.bodyStartLine - 1 : 0;
|
|
7558
|
+
let inFence = false;
|
|
7559
|
+
for (let i = start;i < lines.length; i++) {
|
|
7560
|
+
if (/^\s*(`{3,}|~{3,})/.test(lines[i])) {
|
|
7561
|
+
inFence = !inFence;
|
|
7562
|
+
continue;
|
|
7563
|
+
}
|
|
7564
|
+
if (inFence)
|
|
7565
|
+
continue;
|
|
7566
|
+
const match = lines[i].match(/^(#{1,6})\s+(.+)$/);
|
|
7567
|
+
if (match) {
|
|
7568
|
+
headings.push({
|
|
7569
|
+
level: match[1].length,
|
|
7570
|
+
text: match[2].replace(/\s+#+\s*$/, "").trim(),
|
|
7571
|
+
line: i + 1
|
|
7572
|
+
});
|
|
7573
|
+
}
|
|
7574
|
+
}
|
|
7575
|
+
return { headings, totalLines: lines.length };
|
|
7576
|
+
}
|
|
7577
|
+
var init_markdown = __esm(() => {
|
|
7578
|
+
init_frontmatter();
|
|
7579
|
+
});
|
|
7580
|
+
|
|
7581
|
+
// src/core/warn.ts
|
|
7582
|
+
import fs2 from "fs";
|
|
7583
|
+
function isVerbose() {
|
|
7584
|
+
const env = process.env.AKM_VERBOSE?.trim().toLowerCase();
|
|
7585
|
+
if (env === "1" || env === "true" || env === "yes" || env === "on")
|
|
7586
|
+
return true;
|
|
7587
|
+
if (env === "0" || env === "false" || env === "no" || env === "off")
|
|
7588
|
+
return false;
|
|
7589
|
+
return verbose;
|
|
7590
|
+
}
|
|
7591
|
+
function appendToLogFile(level, args) {
|
|
7592
|
+
if (!logFilePath)
|
|
7593
|
+
return;
|
|
7594
|
+
const ts = new Date().toISOString();
|
|
7595
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
7596
|
+
try {
|
|
7597
|
+
fs2.appendFileSync(logFilePath, `[${ts}] [${level}] ${msg}
|
|
7598
|
+
`);
|
|
7599
|
+
} catch (e) {
|
|
7600
|
+
process.stderr.write(`[akm:warn] log-file write failed (${logFilePath}): ${e}
|
|
7601
|
+
`);
|
|
7602
|
+
process.stderr.write(`[${ts}] [${level}] ${msg}
|
|
7603
|
+
`);
|
|
7604
|
+
}
|
|
7605
|
+
}
|
|
7606
|
+
function warn(...args) {
|
|
7607
|
+
appendToLogFile("WARN", args);
|
|
7608
|
+
if (!quiet) {
|
|
7609
|
+
console.warn(...args);
|
|
7610
|
+
}
|
|
7611
|
+
}
|
|
7612
|
+
function error(...args) {
|
|
7613
|
+
appendToLogFile("ERROR", args);
|
|
7614
|
+
if (!quiet) {
|
|
7615
|
+
console.error(...args);
|
|
7616
|
+
}
|
|
7617
|
+
}
|
|
7618
|
+
function warnVerbose(...args) {
|
|
7619
|
+
if (isVerbose()) {
|
|
7620
|
+
warn(...args);
|
|
7621
|
+
}
|
|
7622
|
+
}
|
|
7623
|
+
var quiet = false, verbose = false, logFilePath;
|
|
7624
|
+
var init_warn = () => {};
|
|
7625
|
+
|
|
7626
|
+
// src/indexer/walk/file-context.ts
|
|
7627
|
+
var renderers;
|
|
7628
|
+
var init_file_context = __esm(() => {
|
|
7629
|
+
init_frontmatter();
|
|
7630
|
+
init_common();
|
|
7631
|
+
renderers = new Map;
|
|
7632
|
+
});
|
|
7633
|
+
|
|
7634
|
+
// src/indexer/passes/metadata-contributors.ts
|
|
7635
|
+
function registerMetadataContributor(contributor) {
|
|
7636
|
+
contributors.push(contributor);
|
|
7637
|
+
}
|
|
7638
|
+
var contributors;
|
|
7639
|
+
var init_metadata_contributors = __esm(() => {
|
|
7640
|
+
contributors = [];
|
|
7641
|
+
});
|
|
7642
|
+
|
|
7643
|
+
// src/indexer/passes/metadata.ts
|
|
7644
|
+
import fs3 from "fs";
|
|
7645
|
+
function extractDescriptionFromComments(filePath) {
|
|
7646
|
+
let content;
|
|
7647
|
+
try {
|
|
7648
|
+
content = fs3.readFileSync(filePath, "utf8");
|
|
7649
|
+
} catch {
|
|
7650
|
+
return null;
|
|
7651
|
+
}
|
|
7652
|
+
const lines = content.split(/\r?\n/).slice(0, 50);
|
|
7653
|
+
const blockStart = lines.findIndex((l) => /^\s*\/\*\*/.test(l));
|
|
7654
|
+
if (blockStart >= 0) {
|
|
7655
|
+
const desc = [];
|
|
7656
|
+
for (let i = blockStart;i < lines.length; i++) {
|
|
7657
|
+
const line = lines[i];
|
|
7658
|
+
if (i > blockStart && /\*\//.test(line))
|
|
7659
|
+
break;
|
|
7660
|
+
const cleaned = line.replace(/^\s*\/?\*\*?\s?/, "").replace(/\*\/\s*$/, "").trim();
|
|
7661
|
+
if (cleaned)
|
|
7662
|
+
desc.push(cleaned);
|
|
7663
|
+
}
|
|
7664
|
+
if (desc.length > 0)
|
|
7665
|
+
return desc.join(" ");
|
|
7666
|
+
}
|
|
7667
|
+
let start = 0;
|
|
7668
|
+
if (lines[0]?.startsWith("#!"))
|
|
7669
|
+
start = 1;
|
|
7670
|
+
const hashLines = [];
|
|
7671
|
+
for (let i = start;i < lines.length; i++) {
|
|
7672
|
+
const line = lines[i].trim();
|
|
7673
|
+
if (line.startsWith("#") && !line.startsWith("#!")) {
|
|
7674
|
+
hashLines.push(line.replace(/^#+\s*/, "").trim());
|
|
7675
|
+
} else if (line === "") {} else {
|
|
7676
|
+
break;
|
|
7677
|
+
}
|
|
7678
|
+
}
|
|
7679
|
+
if (hashLines.length > 0)
|
|
7680
|
+
return hashLines.join(" ");
|
|
7681
|
+
return null;
|
|
7682
|
+
}
|
|
7683
|
+
var KNOWN_QUALITY_VALUES, warnedUnknownQualityValues, WIKI_INFRA_FILES;
|
|
7684
|
+
var init_metadata = __esm(() => {
|
|
7685
|
+
init_asset_spec();
|
|
7686
|
+
init_frontmatter();
|
|
7687
|
+
init_common();
|
|
7688
|
+
init_warn();
|
|
7689
|
+
init_file_context();
|
|
7690
|
+
init_metadata_contributors();
|
|
7691
|
+
KNOWN_QUALITY_VALUES = new Set(["generated", "curated", "enriched", "proposed"]);
|
|
7692
|
+
warnedUnknownQualityValues = new Set;
|
|
7693
|
+
WIKI_INFRA_FILES = new Set(["schema.md", "index.md", "log.md"]);
|
|
7694
|
+
});
|
|
7695
|
+
|
|
7696
|
+
// src/core/asset/asset-ref.ts
|
|
7697
|
+
import path from "path";
|
|
7698
|
+
function parseAssetRef(ref) {
|
|
7699
|
+
const trimmed = ref.trim();
|
|
7700
|
+
if (!trimmed)
|
|
7701
|
+
throw new UsageError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
7702
|
+
let origin;
|
|
7703
|
+
let body = trimmed;
|
|
7704
|
+
const boundary = trimmed.indexOf("//");
|
|
7705
|
+
if (boundary >= 0) {
|
|
7706
|
+
origin = trimmed.slice(0, boundary);
|
|
7707
|
+
body = trimmed.slice(boundary + 2);
|
|
7708
|
+
if (!origin)
|
|
7709
|
+
throw new UsageError("Empty origin in ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
7710
|
+
}
|
|
7711
|
+
const colon = body.indexOf(":");
|
|
7712
|
+
if (colon <= 0) {
|
|
7713
|
+
throw new UsageError(`Invalid ref "${trimmed}". Expected [origin//]type:name, e.g. skill:deploy or knowledge:guide.md`, "MISSING_REQUIRED_ARGUMENT");
|
|
7714
|
+
}
|
|
7715
|
+
const rawType = body.slice(0, colon);
|
|
7716
|
+
const rawName = body.slice(colon + 1);
|
|
7717
|
+
if (rawType === "vault") {
|
|
7718
|
+
throw new UsageError("The `vault` asset type was removed in 0.9.0 \u2014 use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
|
|
7719
|
+
}
|
|
7720
|
+
const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
|
|
7721
|
+
if (!isAssetType(resolvedType)) {
|
|
7722
|
+
throw new UsageError(`Invalid asset type: "${rawType}".`, "MISSING_REQUIRED_ARGUMENT");
|
|
7723
|
+
}
|
|
7724
|
+
validateName(rawName);
|
|
7725
|
+
const name = normalizeName(rawName);
|
|
7726
|
+
return { type: resolvedType, name, origin: origin || undefined };
|
|
7727
|
+
}
|
|
7728
|
+
function validateName(name) {
|
|
7729
|
+
if (!name)
|
|
7730
|
+
throw new UsageError("Empty asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
7731
|
+
if (name.includes("\x00"))
|
|
7732
|
+
throw new UsageError("Null byte in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
7733
|
+
if (/^[A-Za-z]:/.test(name))
|
|
7734
|
+
throw new UsageError("Windows drive path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
7735
|
+
const normalized = path.posix.normalize(name.replace(/\\/g, "/"));
|
|
7736
|
+
if (path.posix.isAbsolute(normalized))
|
|
7737
|
+
throw new UsageError("Absolute path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
7738
|
+
if (normalized === ".." || normalized.startsWith("../")) {
|
|
7739
|
+
throw new UsageError("Path traversal in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
7740
|
+
}
|
|
7741
|
+
const segments = normalized.split("/");
|
|
7742
|
+
if (segments.some((seg) => seg === "." || seg === "..")) {
|
|
7743
|
+
throw new UsageError("Asset name cannot contain relative path segments.", "MISSING_REQUIRED_ARGUMENT");
|
|
7744
|
+
}
|
|
7745
|
+
}
|
|
7746
|
+
function normalizeName(name) {
|
|
7747
|
+
return path.posix.normalize(name.replace(/\\/g, "/"));
|
|
7748
|
+
}
|
|
7749
|
+
var TYPE_ALIASES;
|
|
7750
|
+
var init_asset_ref = __esm(() => {
|
|
7751
|
+
init_common();
|
|
7752
|
+
init_errors();
|
|
7753
|
+
TYPE_ALIASES = {
|
|
7754
|
+
environment: "env"
|
|
7755
|
+
};
|
|
7756
|
+
});
|
|
7757
|
+
|
|
7758
|
+
// src/workflows/schema.ts
|
|
7808
7759
|
var WORKFLOW_SCHEMA_VERSION = 1;
|
|
7809
7760
|
|
|
7810
7761
|
// src/workflows/validator.ts
|
|
@@ -8198,6 +8149,7 @@ function sortErrors(errors2) {
|
|
|
8198
8149
|
var WORKFLOW_TITLE_PREFIX = "Workflow:", STEP_PREFIX = "Step:", STEP_ID_LINE, BULLET_LINE, SUBSECTION_INSTRUCTIONS = "Instructions", SUBSECTION_COMPLETION_CRITERIA = "Completion Criteria";
|
|
8199
8150
|
var init_parser = __esm(() => {
|
|
8200
8151
|
init_dist();
|
|
8152
|
+
init_frontmatter();
|
|
8201
8153
|
init_markdown();
|
|
8202
8154
|
init_validator();
|
|
8203
8155
|
STEP_ID_LINE = /^Step ID:\s+(.+?)\s*$/;
|
|
@@ -8288,6 +8240,25 @@ function applyTocMetadata(entry, ctx) {
|
|
|
8288
8240
|
entry.toc = toc.headings;
|
|
8289
8241
|
} catch {}
|
|
8290
8242
|
}
|
|
8243
|
+
function applyFactMetadata(entry, ctx) {
|
|
8244
|
+
try {
|
|
8245
|
+
const fm = applyFrontmatterDescriptionAndTags(entry, ctx);
|
|
8246
|
+
const tags = new Set([...entry.tags ?? [], "fact"]);
|
|
8247
|
+
const hints = new Set(entry.searchHints ?? []);
|
|
8248
|
+
const category = asNonEmptyString(fm.category);
|
|
8249
|
+
if (category) {
|
|
8250
|
+
tags.add(category);
|
|
8251
|
+
hints.add(`category:${category}`);
|
|
8252
|
+
}
|
|
8253
|
+
if (fm.pinned === true) {
|
|
8254
|
+
tags.add("pinned");
|
|
8255
|
+
hints.add("pinned");
|
|
8256
|
+
}
|
|
8257
|
+
entry.tags = Array.from(tags).filter(Boolean);
|
|
8258
|
+
if (hints.size > 0)
|
|
8259
|
+
entry.searchHints = Array.from(hints).filter(Boolean);
|
|
8260
|
+
} catch {}
|
|
8261
|
+
}
|
|
8291
8262
|
function applyFrontmatterDescriptionAndTags(entry, ctx) {
|
|
8292
8263
|
const parsed = parseFrontmatter(ctx.content());
|
|
8293
8264
|
const fm = parsed.data;
|
|
@@ -8387,6 +8358,7 @@ function applyTaskMetadata(entry, ctx) {
|
|
|
8387
8358
|
}
|
|
8388
8359
|
var init_renderers = __esm(() => {
|
|
8389
8360
|
init_env();
|
|
8361
|
+
init_frontmatter();
|
|
8390
8362
|
init_markdown();
|
|
8391
8363
|
init_common();
|
|
8392
8364
|
init_metadata();
|
|
@@ -8433,6 +8405,11 @@ var init_renderers = __esm(() => {
|
|
|
8433
8405
|
appliesTo: ({ rendererName }) => rendererName === "session-md",
|
|
8434
8406
|
contribute: (entry, ctx) => applySessionMetadata(entry, ctx.renderContext)
|
|
8435
8407
|
});
|
|
8408
|
+
registerMetadataContributor({
|
|
8409
|
+
name: "fact-md-metadata",
|
|
8410
|
+
appliesTo: ({ rendererName }) => rendererName === "fact-md",
|
|
8411
|
+
contribute: (entry, ctx) => applyFactMetadata(entry, ctx.renderContext)
|
|
8412
|
+
});
|
|
8436
8413
|
});
|
|
8437
8414
|
|
|
8438
8415
|
// src/core/asset/asset-registry.ts
|
|
@@ -8567,6 +8544,12 @@ var init_asset_spec = __esm(() => {
|
|
|
8567
8544
|
...markdownSpec,
|
|
8568
8545
|
rendererName: "session-md",
|
|
8569
8546
|
actionBuilder: (ref) => `akm show ${ref} -> read the session summary; follow the \`access\` frontmatter to open the raw log at \`log_path\``
|
|
8547
|
+
},
|
|
8548
|
+
fact: {
|
|
8549
|
+
stashDir: "facts",
|
|
8550
|
+
...markdownSpec,
|
|
8551
|
+
rendererName: "fact-md",
|
|
8552
|
+
actionBuilder: (ref) => `akm show ${ref} -> read the stash fact and apply it as durable context`
|
|
8570
8553
|
}
|
|
8571
8554
|
};
|
|
8572
8555
|
TYPE_DIRS = Object.fromEntries(Object.entries(ASSET_SPECS_INTERNAL).map(([type, spec]) => [type, spec.stashDir]));
|
|
@@ -8840,6 +8823,103 @@ function runMigrations(db, migrations, opts) {
|
|
|
8840
8823
|
}
|
|
8841
8824
|
}
|
|
8842
8825
|
|
|
8826
|
+
// src/runtime.ts
|
|
8827
|
+
import { createHash } from "crypto";
|
|
8828
|
+
import { createWriteStream, statfsSync } from "fs";
|
|
8829
|
+
import { createRequire as createRequire2 } from "module";
|
|
8830
|
+
function sha256Hex(data) {
|
|
8831
|
+
return createHash("sha256").update(data).digest("hex");
|
|
8832
|
+
}
|
|
8833
|
+
function statfsType(path5) {
|
|
8834
|
+
try {
|
|
8835
|
+
return statfsSync(path5).type;
|
|
8836
|
+
} catch {
|
|
8837
|
+
return;
|
|
8838
|
+
}
|
|
8839
|
+
}
|
|
8840
|
+
function sleepSync(ms) {
|
|
8841
|
+
if (isBun2) {
|
|
8842
|
+
bunGlobal().sleepSync(ms);
|
|
8843
|
+
return;
|
|
8844
|
+
}
|
|
8845
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
8846
|
+
}
|
|
8847
|
+
function bunGlobal() {
|
|
8848
|
+
return globalThis.Bun;
|
|
8849
|
+
}
|
|
8850
|
+
var isBun2, nodeRequire2, mainPath;
|
|
8851
|
+
var init_runtime = __esm(() => {
|
|
8852
|
+
isBun2 = !!process.versions?.bun;
|
|
8853
|
+
nodeRequire2 = createRequire2(import.meta.url);
|
|
8854
|
+
mainPath = isBun2 ? bunGlobal().main : process.argv[1];
|
|
8855
|
+
});
|
|
8856
|
+
|
|
8857
|
+
// src/storage/sqlite-pragmas.ts
|
|
8858
|
+
function resolveJournalMode(raw) {
|
|
8859
|
+
if (raw === undefined)
|
|
8860
|
+
return "WAL";
|
|
8861
|
+
const normalized = raw.trim().toUpperCase();
|
|
8862
|
+
if (normalized === "")
|
|
8863
|
+
return "WAL";
|
|
8864
|
+
if (VALID_MODES.has(normalized)) {
|
|
8865
|
+
return normalized;
|
|
8866
|
+
}
|
|
8867
|
+
warnInvalidJournalModeOnce(raw);
|
|
8868
|
+
return "WAL";
|
|
8869
|
+
}
|
|
8870
|
+
function resolveConfiguredJournalMode() {
|
|
8871
|
+
return resolveJournalMode(process.env.AKM_SQLITE_JOURNAL_MODE);
|
|
8872
|
+
}
|
|
8873
|
+
function warnInvalidJournalModeOnce(raw) {
|
|
8874
|
+
if (warnedInvalid)
|
|
8875
|
+
return;
|
|
8876
|
+
warnedInvalid = true;
|
|
8877
|
+
warn(`[akm] invalid AKM_SQLITE_JOURNAL_MODE=${JSON.stringify(raw)} \u2014 using WAL (valid: WAL, DELETE, TRUNCATE)`);
|
|
8878
|
+
}
|
|
8879
|
+
function isNetworkFilesystem(fsType) {
|
|
8880
|
+
if (fsType === undefined)
|
|
8881
|
+
return false;
|
|
8882
|
+
return NETWORK_FS_MAGICS.has(fsType);
|
|
8883
|
+
}
|
|
8884
|
+
function applyStandardPragmas(db, opts = {}) {
|
|
8885
|
+
let mode = resolveConfiguredJournalMode();
|
|
8886
|
+
if (mode === "WAL" && opts.dataDir) {
|
|
8887
|
+
const probe = opts.fsTypeProbe ?? statfsType;
|
|
8888
|
+
if (isNetworkFilesystem(probe(opts.dataDir))) {
|
|
8889
|
+
mode = "DELETE";
|
|
8890
|
+
warnNetworkFallbackOnce(opts.dataDir);
|
|
8891
|
+
}
|
|
8892
|
+
}
|
|
8893
|
+
db.exec("PRAGMA busy_timeout = 30000");
|
|
8894
|
+
db.exec(`PRAGMA journal_mode = ${mode}`);
|
|
8895
|
+
if (opts.foreignKeys !== false) {
|
|
8896
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
8897
|
+
}
|
|
8898
|
+
if (mode !== "WAL") {
|
|
8899
|
+
db.exec("PRAGMA synchronous = FULL");
|
|
8900
|
+
}
|
|
8901
|
+
return mode;
|
|
8902
|
+
}
|
|
8903
|
+
function warnNetworkFallbackOnce(dataDir) {
|
|
8904
|
+
if (warnedNetworkFallback)
|
|
8905
|
+
return;
|
|
8906
|
+
warnedNetworkFallback = true;
|
|
8907
|
+
warn(`[akm] network filesystem detected at ${dataDir} \u2014 WAL unsupported, using DELETE journal mode`);
|
|
8908
|
+
}
|
|
8909
|
+
var VALID_MODES, warnedInvalid = false, warnedNetworkFallback = false, FS_MAGIC_NFS = 26985, FS_MAGIC_SMB = 20859, FS_MAGIC_CIFS = 4283649346, FS_MAGIC_SMB2 = 4266872130, FS_MAGIC_FUSE = 1702057286, NETWORK_FS_MAGICS;
|
|
8910
|
+
var init_sqlite_pragmas = __esm(() => {
|
|
8911
|
+
init_warn();
|
|
8912
|
+
init_runtime();
|
|
8913
|
+
VALID_MODES = new Set(["WAL", "DELETE", "TRUNCATE"]);
|
|
8914
|
+
NETWORK_FS_MAGICS = new Set([
|
|
8915
|
+
FS_MAGIC_NFS,
|
|
8916
|
+
FS_MAGIC_SMB,
|
|
8917
|
+
FS_MAGIC_CIFS,
|
|
8918
|
+
FS_MAGIC_SMB2,
|
|
8919
|
+
FS_MAGIC_FUSE
|
|
8920
|
+
]);
|
|
8921
|
+
});
|
|
8922
|
+
|
|
8843
8923
|
// src/core/assert.ts
|
|
8844
8924
|
function assertNever(x, context) {
|
|
8845
8925
|
let serialized;
|
|
@@ -8882,11 +8962,15 @@ var init_improve_types = () => {};
|
|
|
8882
8962
|
// src/core/state-db.ts
|
|
8883
8963
|
var exports_state_db = {};
|
|
8884
8964
|
__export(exports_state_db, {
|
|
8965
|
+
withImmediateTransaction: () => withImmediateTransaction,
|
|
8885
8966
|
upsertTaskHistory: () => upsertTaskHistory,
|
|
8886
8967
|
upsertProposal: () => upsertProposal,
|
|
8887
8968
|
upsertExtractedSession: () => upsertExtractedSession,
|
|
8969
|
+
upsertConsolidationJudged: () => upsertConsolidationJudged,
|
|
8970
|
+
upsertBodyEmbeddings: () => upsertBodyEmbeddings,
|
|
8888
8971
|
shouldSkipAlreadyExtractedSession: () => shouldSkipAlreadyExtractedSession,
|
|
8889
8972
|
runMigrations: () => runMigrations2,
|
|
8973
|
+
recordRecombineInduction: () => recordRecombineInduction,
|
|
8890
8974
|
recordImproveRun: () => recordImproveRun,
|
|
8891
8975
|
recordFsProposalsImport: () => recordFsProposalsImport,
|
|
8892
8976
|
readStateEvents: () => readStateEvents,
|
|
@@ -8897,9 +8981,12 @@ __export(exports_state_db, {
|
|
|
8897
8981
|
purgeOldEvents: () => purgeOldEvents,
|
|
8898
8982
|
proposalToRowValues: () => proposalToRowValues,
|
|
8899
8983
|
proposalRowToProposal: () => proposalRowToProposal,
|
|
8984
|
+
persistPhaseThreshold: () => persistPhaseThreshold,
|
|
8900
8985
|
openStateDatabase: () => openStateDatabase,
|
|
8986
|
+
markRecombineHypothesisPromoted: () => markRecombineHypothesisPromoted,
|
|
8901
8987
|
listStateProposals: () => listStateProposals,
|
|
8902
8988
|
listStateProposalIdsByPrefix: () => listStateProposalIdsByPrefix,
|
|
8989
|
+
listProposalGateDecisions: () => listProposalGateDecisions,
|
|
8903
8990
|
listExistingTableNames: () => listExistingTableNames,
|
|
8904
8991
|
insertProposalIfAbsent: () => insertProposalIfAbsent,
|
|
8905
8992
|
insertEvent: () => insertEvent,
|
|
@@ -8909,10 +8996,19 @@ __export(exports_state_db, {
|
|
|
8909
8996
|
getTaskHistory: () => getTaskHistory,
|
|
8910
8997
|
getStateProposal: () => getStateProposal,
|
|
8911
8998
|
getStateDbPath: () => getStateDbPath,
|
|
8999
|
+
getRecombineHypothesis: () => getRecombineHypothesis,
|
|
9000
|
+
getPhaseThreshold: () => getPhaseThreshold,
|
|
9001
|
+
getLastExtractRunAt: () => getLastExtractRunAt,
|
|
8912
9002
|
getExtractedSessionsMap: () => getExtractedSessionsMap,
|
|
8913
9003
|
getExtractedSession: () => getExtractedSession,
|
|
9004
|
+
getConsolidationJudgedMap: () => getConsolidationJudgedMap,
|
|
9005
|
+
getBodyEmbeddings: () => getBodyEmbeddings,
|
|
9006
|
+
findMatchingRecombineHypothesis: () => findMatchingRecombineHypothesis,
|
|
8914
9007
|
eventRowToEnvelope: () => eventRowToEnvelope,
|
|
9008
|
+
embeddingToBlob: () => embeddingToBlob,
|
|
9009
|
+
decayUnseenRecombineHypotheses: () => decayUnseenRecombineHypotheses,
|
|
8915
9010
|
computeImproveRunMetrics: () => computeImproveRunMetrics,
|
|
9011
|
+
blobToEmbedding: () => blobToEmbedding,
|
|
8916
9012
|
REGISTRY_INDEX_CACHE_DDL: () => REGISTRY_INDEX_CACHE_DDL
|
|
8917
9013
|
});
|
|
8918
9014
|
import fs5 from "fs";
|
|
@@ -8927,9 +9023,7 @@ function openStateDatabase(dbPath) {
|
|
|
8927
9023
|
fs5.mkdirSync(dir, { recursive: true });
|
|
8928
9024
|
}
|
|
8929
9025
|
const db = openDatabase(resolvedPath);
|
|
8930
|
-
db
|
|
8931
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
8932
|
-
db.exec("PRAGMA busy_timeout = 30000");
|
|
9026
|
+
applyStandardPragmas(db, { dataDir: dir });
|
|
8933
9027
|
runMigrations2(db);
|
|
8934
9028
|
return db;
|
|
8935
9029
|
}
|
|
@@ -8979,7 +9073,8 @@ function proposalRowToProposal(row) {
|
|
|
8979
9073
|
...meta.review !== undefined ? { review: meta.review } : {},
|
|
8980
9074
|
...typeof meta.confidence === "number" ? { confidence: meta.confidence } : {},
|
|
8981
9075
|
...meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {},
|
|
8982
|
-
...typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}
|
|
9076
|
+
...typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {},
|
|
9077
|
+
...typeof meta.eligibilitySource === "string" ? { eligibilitySource: meta.eligibilitySource } : {}
|
|
8983
9078
|
};
|
|
8984
9079
|
}
|
|
8985
9080
|
function proposalToRowValues(proposal, stashDir) {
|
|
@@ -8994,6 +9089,8 @@ function proposalToRowValues(proposal, stashDir) {
|
|
|
8994
9089
|
metaObj.gateDecision = proposal.gateDecision;
|
|
8995
9090
|
if (proposal.backupContent !== undefined)
|
|
8996
9091
|
metaObj.backupContent = proposal.backupContent;
|
|
9092
|
+
if (proposal.eligibilitySource !== undefined)
|
|
9093
|
+
metaObj.eligibilitySource = proposal.eligibilitySource;
|
|
8997
9094
|
return {
|
|
8998
9095
|
id: proposal.id,
|
|
8999
9096
|
stash_dir: stashDir,
|
|
@@ -9090,6 +9187,32 @@ function listStateProposals(db, options = {}) {
|
|
|
9090
9187
|
FROM proposals ${where} ORDER BY created_at ASC, rowid ASC`).all(...params);
|
|
9091
9188
|
return rows.map(proposalRowToProposal);
|
|
9092
9189
|
}
|
|
9190
|
+
function listProposalGateDecisions(db) {
|
|
9191
|
+
const rows = db.prepare("SELECT metadata_json FROM proposals ORDER BY created_at ASC, rowid ASC").all();
|
|
9192
|
+
const decisions = [];
|
|
9193
|
+
for (const row of rows) {
|
|
9194
|
+
let meta;
|
|
9195
|
+
try {
|
|
9196
|
+
meta = JSON.parse(row.metadata_json);
|
|
9197
|
+
} catch {
|
|
9198
|
+
continue;
|
|
9199
|
+
}
|
|
9200
|
+
const decision = meta.gateDecision;
|
|
9201
|
+
if (decision && typeof decision === "object" && typeof decision.outcome === "string") {
|
|
9202
|
+
decisions.push(decision);
|
|
9203
|
+
}
|
|
9204
|
+
}
|
|
9205
|
+
decisions.sort((a, b) => new Date(a.decidedAt).getTime() - new Date(b.decidedAt).getTime());
|
|
9206
|
+
return decisions;
|
|
9207
|
+
}
|
|
9208
|
+
function getPhaseThreshold(db, phase) {
|
|
9209
|
+
const row = db.prepare("SELECT threshold FROM improve_gate_thresholds WHERE phase = ?").get(phase);
|
|
9210
|
+
return row?.threshold;
|
|
9211
|
+
}
|
|
9212
|
+
function persistPhaseThreshold(db, phase, threshold) {
|
|
9213
|
+
db.prepare(`INSERT OR REPLACE INTO improve_gate_thresholds (phase, threshold, updated_at)
|
|
9214
|
+
VALUES (?, ?, ?)`).run(phase, Math.round(threshold), Date.now());
|
|
9215
|
+
}
|
|
9093
9216
|
function getStateProposal(db, id, stashDir) {
|
|
9094
9217
|
const sql = `SELECT id, stash_dir, ref, status, source, created_at, updated_at,
|
|
9095
9218
|
content, frontmatter_json, metadata_json
|
|
@@ -9120,6 +9243,19 @@ function insertProposalIfAbsent(db, proposal, stashDir) {
|
|
|
9120
9243
|
const changes = result.changes ?? 0;
|
|
9121
9244
|
return Number(changes) > 0;
|
|
9122
9245
|
}
|
|
9246
|
+
function withImmediateTransaction(db, fn) {
|
|
9247
|
+
db.exec("BEGIN IMMEDIATE");
|
|
9248
|
+
try {
|
|
9249
|
+
const result = fn();
|
|
9250
|
+
db.exec("COMMIT");
|
|
9251
|
+
return result;
|
|
9252
|
+
} catch (err) {
|
|
9253
|
+
try {
|
|
9254
|
+
db.exec("ROLLBACK");
|
|
9255
|
+
} catch {}
|
|
9256
|
+
throw err;
|
|
9257
|
+
}
|
|
9258
|
+
}
|
|
9123
9259
|
function upsertTaskHistory(db, row) {
|
|
9124
9260
|
db.prepare(`
|
|
9125
9261
|
INSERT OR IGNORE INTO task_history
|
|
@@ -9273,44 +9409,175 @@ function purgeOldImproveRuns(db, retentionDays = 90) {
|
|
|
9273
9409
|
const changes = result.changes ?? 0;
|
|
9274
9410
|
return typeof changes === "bigint" ? Number(changes) : changes;
|
|
9275
9411
|
}
|
|
9276
|
-
function upsertExtractedSession(db, input) {
|
|
9277
|
-
const endedAtIso = typeof input.sessionEndedAt === "number" && Number.isFinite(input.sessionEndedAt) ? new Date(input.sessionEndedAt).toISOString() : null;
|
|
9412
|
+
function upsertExtractedSession(db, input) {
|
|
9413
|
+
const endedAtIso = typeof input.sessionEndedAt === "number" && Number.isFinite(input.sessionEndedAt) ? new Date(input.sessionEndedAt).toISOString() : null;
|
|
9414
|
+
db.prepare(`
|
|
9415
|
+
INSERT OR REPLACE INTO extract_sessions_seen
|
|
9416
|
+
(harness, session_id, processed_at, session_ended_at, outcome,
|
|
9417
|
+
candidate_count, proposal_count, rationale, source_run, metadata_json,
|
|
9418
|
+
content_hash)
|
|
9419
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
9420
|
+
`).run(input.harness, input.sessionId, input.processedAt, endedAtIso, input.outcome, input.candidateCount, input.proposalCount, input.rationale ?? null, input.sourceRun ?? null, JSON.stringify(input.metadata ?? {}), input.contentHash);
|
|
9421
|
+
}
|
|
9422
|
+
function getExtractedSession(db, harness, sessionId) {
|
|
9423
|
+
const row = db.prepare("SELECT * FROM extract_sessions_seen WHERE harness = ? AND session_id = ?").get(harness, sessionId);
|
|
9424
|
+
return row ?? undefined;
|
|
9425
|
+
}
|
|
9426
|
+
function getExtractedSessionsMap(db, harness, sessionIds) {
|
|
9427
|
+
const out = new Map;
|
|
9428
|
+
if (sessionIds.length === 0)
|
|
9429
|
+
return out;
|
|
9430
|
+
const CHUNK = 500;
|
|
9431
|
+
for (let i = 0;i < sessionIds.length; i += CHUNK) {
|
|
9432
|
+
const chunk = sessionIds.slice(i, i + CHUNK);
|
|
9433
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
9434
|
+
const rows = db.prepare(`SELECT * FROM extract_sessions_seen
|
|
9435
|
+
WHERE harness = ? AND session_id IN (${placeholders})`).all(harness, ...chunk);
|
|
9436
|
+
for (const row of rows)
|
|
9437
|
+
out.set(row.session_id, row);
|
|
9438
|
+
}
|
|
9439
|
+
return out;
|
|
9440
|
+
}
|
|
9441
|
+
function getLastExtractRunAt(db, harness) {
|
|
9442
|
+
const row = db.prepare("SELECT MAX(processed_at) AS last FROM extract_sessions_seen WHERE harness = ?").get(harness);
|
|
9443
|
+
if (!row?.last)
|
|
9444
|
+
return null;
|
|
9445
|
+
const ms = Date.parse(row.last);
|
|
9446
|
+
return Number.isFinite(ms) ? ms : null;
|
|
9447
|
+
}
|
|
9448
|
+
function shouldSkipAlreadyExtractedSession(prior, currentContentHash) {
|
|
9449
|
+
if (!prior)
|
|
9450
|
+
return false;
|
|
9451
|
+
if (prior.content_hash == null)
|
|
9452
|
+
return false;
|
|
9453
|
+
return prior.content_hash === currentContentHash;
|
|
9454
|
+
}
|
|
9455
|
+
function getConsolidationJudgedMap(db, entryKeys) {
|
|
9456
|
+
const out = new Map;
|
|
9457
|
+
if (entryKeys.length === 0)
|
|
9458
|
+
return out;
|
|
9459
|
+
const CHUNK = 500;
|
|
9460
|
+
for (let i = 0;i < entryKeys.length; i += CHUNK) {
|
|
9461
|
+
const chunk = entryKeys.slice(i, i + CHUNK);
|
|
9462
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
9463
|
+
const rows = db.prepare(`SELECT * FROM consolidation_judged WHERE entry_key IN (${placeholders})`).all(...chunk);
|
|
9464
|
+
for (const row of rows)
|
|
9465
|
+
out.set(row.entry_key, row);
|
|
9466
|
+
}
|
|
9467
|
+
return out;
|
|
9468
|
+
}
|
|
9469
|
+
function upsertConsolidationJudged(db, input) {
|
|
9278
9470
|
db.prepare(`
|
|
9279
|
-
INSERT OR REPLACE INTO
|
|
9280
|
-
(
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9471
|
+
INSERT OR REPLACE INTO consolidation_judged
|
|
9472
|
+
(entry_key, content_hash, judged_at, outcome)
|
|
9473
|
+
VALUES (?, ?, ?, ?)
|
|
9474
|
+
`).run(input.entryKey, input.contentHash, input.judgedAt, input.outcome);
|
|
9475
|
+
}
|
|
9476
|
+
function recordRecombineInduction(db, input) {
|
|
9477
|
+
const row = db.prepare(`
|
|
9478
|
+
INSERT INTO recombine_hypotheses
|
|
9479
|
+
(hypothesis_ref, signature, member_key, consecutive_count, first_seen_at, last_seen_at, last_run)
|
|
9480
|
+
VALUES (?, ?, ?, 1, ?, ?, ?)
|
|
9481
|
+
ON CONFLICT(hypothesis_ref) DO UPDATE SET
|
|
9482
|
+
consecutive_count = consecutive_count + (CASE WHEN last_run IS excluded.last_run THEN 0 ELSE 1 END),
|
|
9483
|
+
last_seen_at = excluded.last_seen_at,
|
|
9484
|
+
last_run = excluded.last_run,
|
|
9485
|
+
signature = excluded.signature,
|
|
9486
|
+
member_key = excluded.member_key
|
|
9487
|
+
RETURNING consecutive_count
|
|
9488
|
+
`).get(input.hypothesisRef, input.signature, input.memberKey, input.seenAt, input.seenAt, input.run);
|
|
9489
|
+
return row?.consecutive_count ?? 0;
|
|
9490
|
+
}
|
|
9491
|
+
function findMatchingRecombineHypothesis(db, input) {
|
|
9492
|
+
const candidateMembers = new Set(input.memberKey.split("|").filter((m) => m.length > 0));
|
|
9493
|
+
if (candidateMembers.size === 0)
|
|
9494
|
+
return;
|
|
9495
|
+
const rows = db.prepare("SELECT * FROM recombine_hypotheses WHERE signature = ? AND promoted_at IS NULL ORDER BY last_seen_at DESC").all(input.signature);
|
|
9496
|
+
let best;
|
|
9497
|
+
let bestOverlap = -1;
|
|
9498
|
+
for (const row of rows) {
|
|
9499
|
+
const rowMembers = row.member_key.split("|").filter((m) => m.length > 0);
|
|
9500
|
+
if (rowMembers.length === 0)
|
|
9501
|
+
continue;
|
|
9502
|
+
let intersection = 0;
|
|
9503
|
+
for (const m of rowMembers) {
|
|
9504
|
+
if (candidateMembers.has(m))
|
|
9505
|
+
intersection += 1;
|
|
9506
|
+
}
|
|
9507
|
+
const union = candidateMembers.size + rowMembers.length - intersection;
|
|
9508
|
+
const overlap = union === 0 ? 0 : intersection / union;
|
|
9509
|
+
if (overlap >= input.minOverlap && overlap > bestOverlap) {
|
|
9510
|
+
best = row;
|
|
9511
|
+
bestOverlap = overlap;
|
|
9512
|
+
}
|
|
9513
|
+
}
|
|
9514
|
+
return best;
|
|
9284
9515
|
}
|
|
9285
|
-
function
|
|
9286
|
-
const row = db.prepare("SELECT * FROM
|
|
9516
|
+
function getRecombineHypothesis(db, hypothesisRef) {
|
|
9517
|
+
const row = db.prepare("SELECT * FROM recombine_hypotheses WHERE hypothesis_ref = ?").get(hypothesisRef);
|
|
9287
9518
|
return row ?? undefined;
|
|
9288
9519
|
}
|
|
9289
|
-
function
|
|
9520
|
+
function markRecombineHypothesisPromoted(db, hypothesisRef, promotedAt) {
|
|
9521
|
+
db.prepare("UPDATE recombine_hypotheses SET promoted_at = ?, consecutive_count = 0 WHERE hypothesis_ref = ?").run(promotedAt, hypothesisRef);
|
|
9522
|
+
}
|
|
9523
|
+
function decayUnseenRecombineHypotheses(db, currentRun, seenRefs) {
|
|
9524
|
+
if (seenRefs.length === 0) {
|
|
9525
|
+
const res2 = db.prepare("UPDATE recombine_hypotheses SET consecutive_count = 0 WHERE promoted_at IS NULL AND (last_run IS NULL OR last_run != ?) AND consecutive_count != 0").run(currentRun);
|
|
9526
|
+
return Number(res2.changes);
|
|
9527
|
+
}
|
|
9528
|
+
if (seenRefs.length > 900) {
|
|
9529
|
+
const res2 = db.prepare("UPDATE recombine_hypotheses SET consecutive_count = 0 WHERE promoted_at IS NULL AND (last_run IS NULL OR last_run != ?) AND consecutive_count != 0").run(currentRun);
|
|
9530
|
+
return Number(res2.changes);
|
|
9531
|
+
}
|
|
9532
|
+
const placeholders = seenRefs.map(() => "?").join(",");
|
|
9533
|
+
const res = db.prepare(`UPDATE recombine_hypotheses SET consecutive_count = 0
|
|
9534
|
+
WHERE promoted_at IS NULL
|
|
9535
|
+
AND (last_run IS NULL OR last_run != ?)
|
|
9536
|
+
AND consecutive_count != 0
|
|
9537
|
+
AND hypothesis_ref NOT IN (${placeholders})`).run(currentRun, ...seenRefs);
|
|
9538
|
+
return Number(res.changes);
|
|
9539
|
+
}
|
|
9540
|
+
function embeddingToBlob(vec) {
|
|
9541
|
+
const f32 = new Float32Array(vec);
|
|
9542
|
+
return new Uint8Array(f32.buffer);
|
|
9543
|
+
}
|
|
9544
|
+
function blobToEmbedding(blob) {
|
|
9545
|
+
const f32 = new Float32Array(blob.buffer, blob.byteOffset, blob.byteLength / 4);
|
|
9546
|
+
return Array.from(f32);
|
|
9547
|
+
}
|
|
9548
|
+
function getBodyEmbeddings(db, contentHashes, expectedModelId) {
|
|
9290
9549
|
const out = new Map;
|
|
9291
|
-
if (
|
|
9550
|
+
if (contentHashes.length === 0)
|
|
9551
|
+
return out;
|
|
9552
|
+
const firstRow = db.prepare("SELECT model_id FROM body_embeddings LIMIT 1").get();
|
|
9553
|
+
if (firstRow && firstRow.model_id !== expectedModelId) {
|
|
9554
|
+
db.exec("DELETE FROM body_embeddings");
|
|
9292
9555
|
return out;
|
|
9556
|
+
}
|
|
9293
9557
|
const CHUNK = 500;
|
|
9294
|
-
for (let i = 0;i <
|
|
9295
|
-
const chunk =
|
|
9558
|
+
for (let i = 0;i < contentHashes.length; i += CHUNK) {
|
|
9559
|
+
const chunk = contentHashes.slice(i, i + CHUNK);
|
|
9296
9560
|
const placeholders = chunk.map(() => "?").join(",");
|
|
9297
|
-
const rows = db.prepare(`SELECT
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9561
|
+
const rows = db.prepare(`SELECT content_hash, embedding FROM body_embeddings WHERE content_hash IN (${placeholders})`).all(...chunk);
|
|
9562
|
+
for (const row of rows) {
|
|
9563
|
+
out.set(row.content_hash, blobToEmbedding(row.embedding));
|
|
9564
|
+
}
|
|
9301
9565
|
}
|
|
9302
9566
|
return out;
|
|
9303
9567
|
}
|
|
9304
|
-
function
|
|
9305
|
-
if (
|
|
9306
|
-
return
|
|
9307
|
-
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9568
|
+
function upsertBodyEmbeddings(db, entries) {
|
|
9569
|
+
if (entries.length === 0)
|
|
9570
|
+
return;
|
|
9571
|
+
const now = Date.now();
|
|
9572
|
+
const stmt = db.prepare(`
|
|
9573
|
+
INSERT OR REPLACE INTO body_embeddings (content_hash, embedding, model_id, created_at)
|
|
9574
|
+
VALUES (?, ?, ?, ?)
|
|
9575
|
+
`);
|
|
9576
|
+
db.transaction(() => {
|
|
9577
|
+
for (const { contentHash, embedding, modelId } of entries) {
|
|
9578
|
+
stmt.run(contentHash, embeddingToBlob(embedding), modelId, now);
|
|
9579
|
+
}
|
|
9580
|
+
})();
|
|
9314
9581
|
}
|
|
9315
9582
|
var MIGRATIONS, REGISTRY_INDEX_CACHE_DDL = `
|
|
9316
9583
|
CREATE TABLE IF NOT EXISTS registry_index_cache (
|
|
@@ -9326,6 +9593,7 @@ var MIGRATIONS, REGISTRY_INDEX_CACHE_DDL = `
|
|
|
9326
9593
|
`;
|
|
9327
9594
|
var init_state_db = __esm(() => {
|
|
9328
9595
|
init_database();
|
|
9596
|
+
init_sqlite_pragmas();
|
|
9329
9597
|
init_improve_types();
|
|
9330
9598
|
init_paths();
|
|
9331
9599
|
init_warn();
|
|
@@ -9402,7 +9670,7 @@ var init_state_db = __esm(() => {
|
|
|
9402
9670
|
-- metadata_json TEXT \u2014 JSON object for future proposal fields.
|
|
9403
9671
|
-- Current fields stored here: sourceRun,
|
|
9404
9672
|
-- review, confidence, gateDecision (#577),
|
|
9405
|
-
-- backupContent.
|
|
9673
|
+
-- backupContent, eligibilitySource.
|
|
9406
9674
|
--
|
|
9407
9675
|
-- ADD COLUMN extension points (future migrations):
|
|
9408
9676
|
-- ALTER TABLE proposals ADD COLUMN source_run TEXT DEFAULT NULL;
|
|
@@ -9599,6 +9867,123 @@ var init_state_db = __esm(() => {
|
|
|
9599
9867
|
imported_count INTEGER NOT NULL DEFAULT 0
|
|
9600
9868
|
);
|
|
9601
9869
|
`
|
|
9870
|
+
},
|
|
9871
|
+
{
|
|
9872
|
+
id: "006-proposals-pending-ref-source",
|
|
9873
|
+
up: `
|
|
9874
|
+
CREATE INDEX IF NOT EXISTS idx_proposals_stash_status_ref_source
|
|
9875
|
+
ON proposals(stash_dir, status, ref, source);
|
|
9876
|
+
`
|
|
9877
|
+
},
|
|
9878
|
+
{
|
|
9879
|
+
id: "007-consolidation-judged",
|
|
9880
|
+
up: `
|
|
9881
|
+
CREATE TABLE IF NOT EXISTS consolidation_judged (
|
|
9882
|
+
entry_key TEXT PRIMARY KEY,
|
|
9883
|
+
content_hash TEXT NOT NULL,
|
|
9884
|
+
judged_at TEXT NOT NULL,
|
|
9885
|
+
outcome TEXT NOT NULL
|
|
9886
|
+
);
|
|
9887
|
+
`
|
|
9888
|
+
},
|
|
9889
|
+
{
|
|
9890
|
+
id: "008-body-embeddings",
|
|
9891
|
+
up: `
|
|
9892
|
+
CREATE TABLE IF NOT EXISTS body_embeddings (
|
|
9893
|
+
content_hash TEXT PRIMARY KEY,
|
|
9894
|
+
embedding BLOB NOT NULL,
|
|
9895
|
+
model_id TEXT NOT NULL,
|
|
9896
|
+
created_at INTEGER NOT NULL
|
|
9897
|
+
);
|
|
9898
|
+
`
|
|
9899
|
+
},
|
|
9900
|
+
{
|
|
9901
|
+
id: "009-asset-salience",
|
|
9902
|
+
up: `
|
|
9903
|
+
CREATE TABLE IF NOT EXISTS asset_salience (
|
|
9904
|
+
asset_ref TEXT PRIMARY KEY,
|
|
9905
|
+
encoding_salience REAL NOT NULL DEFAULT 0.5,
|
|
9906
|
+
outcome_salience REAL NOT NULL DEFAULT 0.0,
|
|
9907
|
+
retrieval_salience REAL NOT NULL DEFAULT 0.0,
|
|
9908
|
+
rank_score REAL NOT NULL DEFAULT 0.0,
|
|
9909
|
+
consecutive_no_ops INTEGER NOT NULL DEFAULT 0,
|
|
9910
|
+
updated_at INTEGER NOT NULL DEFAULT 0
|
|
9911
|
+
);
|
|
9912
|
+
|
|
9913
|
+
-- Hot path: sort / filter by rank_score for selector queries.
|
|
9914
|
+
CREATE INDEX IF NOT EXISTS idx_asset_salience_rank
|
|
9915
|
+
ON asset_salience(rank_score DESC);
|
|
9916
|
+
`
|
|
9917
|
+
},
|
|
9918
|
+
{
|
|
9919
|
+
id: "010-asset-outcome",
|
|
9920
|
+
up: `
|
|
9921
|
+
CREATE TABLE IF NOT EXISTS asset_outcome (
|
|
9922
|
+
asset_ref TEXT PRIMARY KEY,
|
|
9923
|
+
last_retrieved_at INTEGER NOT NULL DEFAULT 0,
|
|
9924
|
+
retrieval_count INTEGER NOT NULL DEFAULT 0,
|
|
9925
|
+
expected_retrieval_rate REAL NOT NULL DEFAULT 0.0,
|
|
9926
|
+
negative_feedback_count INTEGER NOT NULL DEFAULT 0,
|
|
9927
|
+
accepted_change_count INTEGER NOT NULL DEFAULT 0,
|
|
9928
|
+
review_pressure INTEGER NOT NULL DEFAULT 0,
|
|
9929
|
+
outcome_score REAL NOT NULL DEFAULT 0.0,
|
|
9930
|
+
updated_at INTEGER NOT NULL DEFAULT 0
|
|
9931
|
+
);
|
|
9932
|
+
|
|
9933
|
+
-- Hot path: sort assets by review_pressure DESC for #613 admission.
|
|
9934
|
+
CREATE INDEX IF NOT EXISTS idx_asset_outcome_review_pressure
|
|
9935
|
+
ON asset_outcome(review_pressure DESC);
|
|
9936
|
+
|
|
9937
|
+
-- Secondary: sort by outcome_score DESC for outcomeSalience reads.
|
|
9938
|
+
CREATE INDEX IF NOT EXISTS idx_asset_outcome_score
|
|
9939
|
+
ON asset_outcome(outcome_score DESC);
|
|
9940
|
+
`
|
|
9941
|
+
},
|
|
9942
|
+
{
|
|
9943
|
+
id: "011-asset-salience-homeostatic-demoted-at",
|
|
9944
|
+
up: `
|
|
9945
|
+
ALTER TABLE asset_salience ADD COLUMN homeostatic_demoted_at INTEGER DEFAULT NULL;
|
|
9946
|
+
`
|
|
9947
|
+
},
|
|
9948
|
+
{
|
|
9949
|
+
id: "012-improve-gate-thresholds",
|
|
9950
|
+
up: `
|
|
9951
|
+
CREATE TABLE IF NOT EXISTS improve_gate_thresholds (
|
|
9952
|
+
phase TEXT NOT NULL PRIMARY KEY,
|
|
9953
|
+
threshold INTEGER NOT NULL,
|
|
9954
|
+
updated_at INTEGER NOT NULL
|
|
9955
|
+
);
|
|
9956
|
+
`
|
|
9957
|
+
},
|
|
9958
|
+
{
|
|
9959
|
+
id: "013-extract-sessions-content-hash",
|
|
9960
|
+
up: `
|
|
9961
|
+
ALTER TABLE extract_sessions_seen ADD COLUMN content_hash TEXT DEFAULT NULL;
|
|
9962
|
+
`
|
|
9963
|
+
},
|
|
9964
|
+
{
|
|
9965
|
+
id: "014-recombine-hypotheses",
|
|
9966
|
+
up: `
|
|
9967
|
+
CREATE TABLE IF NOT EXISTS recombine_hypotheses (
|
|
9968
|
+
hypothesis_ref TEXT PRIMARY KEY,
|
|
9969
|
+
signature TEXT NOT NULL,
|
|
9970
|
+
member_key TEXT NOT NULL,
|
|
9971
|
+
consecutive_count INTEGER NOT NULL DEFAULT 0,
|
|
9972
|
+
first_seen_at TEXT NOT NULL,
|
|
9973
|
+
last_seen_at TEXT NOT NULL,
|
|
9974
|
+
last_run TEXT,
|
|
9975
|
+
promoted_at TEXT,
|
|
9976
|
+
metadata_json TEXT NOT NULL DEFAULT '{}'
|
|
9977
|
+
);
|
|
9978
|
+
CREATE INDEX IF NOT EXISTS idx_recombine_hypotheses_last_seen
|
|
9979
|
+
ON recombine_hypotheses(last_seen_at);
|
|
9980
|
+
`
|
|
9981
|
+
},
|
|
9982
|
+
{
|
|
9983
|
+
id: "015-asset-salience-encoding-source",
|
|
9984
|
+
up: `
|
|
9985
|
+
ALTER TABLE asset_salience ADD COLUMN encoding_source TEXT DEFAULT NULL;
|
|
9986
|
+
`
|
|
9602
9987
|
}
|
|
9603
9988
|
];
|
|
9604
9989
|
});
|
|
@@ -9642,29 +10027,6 @@ var init_types = __esm(() => {
|
|
|
9642
10027
|
init_warn();
|
|
9643
10028
|
});
|
|
9644
10029
|
|
|
9645
|
-
// src/runtime.ts
|
|
9646
|
-
import { createHash } from "crypto";
|
|
9647
|
-
import { createRequire as createRequire2 } from "module";
|
|
9648
|
-
function sha256Hex(data) {
|
|
9649
|
-
return createHash("sha256").update(data).digest("hex");
|
|
9650
|
-
}
|
|
9651
|
-
function sleepSync(ms) {
|
|
9652
|
-
if (isBun2) {
|
|
9653
|
-
bunGlobal().sleepSync(ms);
|
|
9654
|
-
return;
|
|
9655
|
-
}
|
|
9656
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
9657
|
-
}
|
|
9658
|
-
function bunGlobal() {
|
|
9659
|
-
return globalThis.Bun;
|
|
9660
|
-
}
|
|
9661
|
-
var isBun2, nodeRequire2, mainPath;
|
|
9662
|
-
var init_runtime = __esm(() => {
|
|
9663
|
-
isBun2 = !!process.versions?.bun;
|
|
9664
|
-
nodeRequire2 = createRequire2(import.meta.url);
|
|
9665
|
-
mainPath = isBun2 ? bunGlobal().main : process.argv[1];
|
|
9666
|
-
});
|
|
9667
|
-
|
|
9668
10030
|
// src/indexer/search/search-fields.ts
|
|
9669
10031
|
function buildSearchFields(entry) {
|
|
9670
10032
|
const name = entry.name.replace(/[-_]/g, " ").toLowerCase();
|
|
@@ -10348,6 +10710,10 @@ class ClaudeCodeProvider {
|
|
|
10348
10710
|
isAvailable() {
|
|
10349
10711
|
return fs9.existsSync(claudeProjectsDir());
|
|
10350
10712
|
}
|
|
10713
|
+
watchRoots() {
|
|
10714
|
+
const dir = claudeProjectsDir();
|
|
10715
|
+
return fs9.existsSync(dir) ? [dir] : [];
|
|
10716
|
+
}
|
|
10351
10717
|
*readEvents(input) {
|
|
10352
10718
|
try {
|
|
10353
10719
|
for (const jsonlPath of this.#walkJsonl(claudeProjectsDir())) {
|
|
@@ -10512,7 +10878,7 @@ class ClaudeCodeProvider {
|
|
|
10512
10878
|
const full = path8.join(dir, entry.name);
|
|
10513
10879
|
if (entry.isDirectory())
|
|
10514
10880
|
yield* this.#walkJsonl(full);
|
|
10515
|
-
else if (entry.name.endsWith(".jsonl"))
|
|
10881
|
+
else if (entry.name.endsWith(".jsonl") && entry.name !== "journal.jsonl")
|
|
10516
10882
|
yield full;
|
|
10517
10883
|
}
|
|
10518
10884
|
} catch {}
|
|
@@ -10582,6 +10948,18 @@ class OpenCodeProvider {
|
|
|
10582
10948
|
isAvailable() {
|
|
10583
10949
|
return fs10.existsSync(this.#baseDir);
|
|
10584
10950
|
}
|
|
10951
|
+
#dbPath(base) {
|
|
10952
|
+
return path9.join(base, OPENCODE_DB_FILENAME);
|
|
10953
|
+
}
|
|
10954
|
+
watchRoots() {
|
|
10955
|
+
const roots = [];
|
|
10956
|
+
if (fs10.existsSync(this.#dbPath(this.#baseDir)))
|
|
10957
|
+
roots.push(this.#baseDir);
|
|
10958
|
+
const sessionRoot = path9.join(this.#baseDir, "storage", "session");
|
|
10959
|
+
if (fs10.existsSync(sessionRoot))
|
|
10960
|
+
roots.push(sessionRoot);
|
|
10961
|
+
return roots;
|
|
10962
|
+
}
|
|
10585
10963
|
*readEvents(input) {
|
|
10586
10964
|
const candidates = [this.#baseDir, path9.join(this.#baseDir, "log")];
|
|
10587
10965
|
for (const dir of candidates) {
|
|
@@ -10629,6 +11007,9 @@ class OpenCodeProvider {
|
|
|
10629
11007
|
listSessions(input = {}) {
|
|
10630
11008
|
const base = input.location ?? this.#baseDir;
|
|
10631
11009
|
const sinceMs = input.sinceMs ?? 0;
|
|
11010
|
+
const dbPath = this.#dbPath(base);
|
|
11011
|
+
if (fs10.existsSync(dbPath))
|
|
11012
|
+
return this.#listSessionsFromDb(dbPath, sinceMs);
|
|
10632
11013
|
const sessionRoot = path9.join(base, "storage", "session");
|
|
10633
11014
|
if (!fs10.existsSync(sessionRoot))
|
|
10634
11015
|
return [];
|
|
@@ -10683,6 +11064,8 @@ class OpenCodeProvider {
|
|
|
10683
11064
|
return summaries.sort((a, b) => (b.endedAt ?? 0) - (a.endedAt ?? 0));
|
|
10684
11065
|
}
|
|
10685
11066
|
readSession(ref) {
|
|
11067
|
+
if (path9.basename(ref.filePath) === OPENCODE_DB_FILENAME)
|
|
11068
|
+
return this.#readSessionFromDb(ref);
|
|
10686
11069
|
let meta = {};
|
|
10687
11070
|
try {
|
|
10688
11071
|
meta = JSON.parse(fs10.readFileSync(ref.filePath, "utf8"));
|
|
@@ -10732,6 +11115,106 @@ class OpenCodeProvider {
|
|
|
10732
11115
|
inlineRefs
|
|
10733
11116
|
};
|
|
10734
11117
|
}
|
|
11118
|
+
#listSessionsFromDb(dbPath, sinceMs) {
|
|
11119
|
+
let db;
|
|
11120
|
+
try {
|
|
11121
|
+
db = openDatabase(dbPath, { readonly: true, create: false });
|
|
11122
|
+
} catch {
|
|
11123
|
+
return [];
|
|
11124
|
+
}
|
|
11125
|
+
try {
|
|
11126
|
+
const rows = db.prepare("SELECT id, title, directory, time_created, time_updated FROM session WHERE time_updated >= ? ORDER BY time_updated DESC").all(sinceMs);
|
|
11127
|
+
return rows.map((r) => {
|
|
11128
|
+
const startedAt = typeof r.time_created === "number" ? r.time_created : undefined;
|
|
11129
|
+
const endedAt = typeof r.time_updated === "number" ? r.time_updated : undefined;
|
|
11130
|
+
const title = typeof r.title === "string" && r.title.length > 0 ? r.title : undefined;
|
|
11131
|
+
const projectHint = typeof r.directory === "string" && r.directory.length > 0 ? r.directory : undefined;
|
|
11132
|
+
return {
|
|
11133
|
+
harness: this.name,
|
|
11134
|
+
sessionId: r.id,
|
|
11135
|
+
filePath: dbPath,
|
|
11136
|
+
...startedAt !== undefined ? { startedAt } : {},
|
|
11137
|
+
...endedAt !== undefined ? { endedAt } : {},
|
|
11138
|
+
...projectHint ? { projectHint } : {},
|
|
11139
|
+
...title ? { title } : {}
|
|
11140
|
+
};
|
|
11141
|
+
});
|
|
11142
|
+
} catch {
|
|
11143
|
+
return [];
|
|
11144
|
+
} finally {
|
|
11145
|
+
db.close();
|
|
11146
|
+
}
|
|
11147
|
+
}
|
|
11148
|
+
#readSessionFromDb(ref) {
|
|
11149
|
+
const emptyRef = { harness: this.name, sessionId: ref.sessionId, filePath: ref.filePath };
|
|
11150
|
+
let db;
|
|
11151
|
+
try {
|
|
11152
|
+
db = openDatabase(ref.filePath, { readonly: true, create: false });
|
|
11153
|
+
} catch {
|
|
11154
|
+
return { ref: emptyRef, events: [], inlineRefs: [] };
|
|
11155
|
+
}
|
|
11156
|
+
try {
|
|
11157
|
+
const meta = db.prepare("SELECT title, directory, time_created, time_updated FROM session WHERE id = ?").get(ref.sessionId);
|
|
11158
|
+
const startedAt = typeof meta?.time_created === "number" ? meta.time_created : undefined;
|
|
11159
|
+
const endedAt = typeof meta?.time_updated === "number" ? meta.time_updated : undefined;
|
|
11160
|
+
const title = typeof meta?.title === "string" && meta.title.length > 0 ? meta.title : undefined;
|
|
11161
|
+
const projectHint = typeof meta?.directory === "string" && meta.directory.length > 0 ? meta.directory : undefined;
|
|
11162
|
+
const messages = db.prepare("SELECT id, data, time_created FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(ref.sessionId);
|
|
11163
|
+
const parts = db.prepare("SELECT message_id, data FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(ref.sessionId);
|
|
11164
|
+
const textByMessage = new Map;
|
|
11165
|
+
for (const part of parts) {
|
|
11166
|
+
let parsed;
|
|
11167
|
+
try {
|
|
11168
|
+
parsed = JSON.parse(part.data);
|
|
11169
|
+
} catch {
|
|
11170
|
+
continue;
|
|
11171
|
+
}
|
|
11172
|
+
if (parsed?.type !== "text")
|
|
11173
|
+
continue;
|
|
11174
|
+
const text = parsed.text;
|
|
11175
|
+
if (typeof text !== "string" || text.length < 1)
|
|
11176
|
+
continue;
|
|
11177
|
+
const bucket = textByMessage.get(part.message_id) ?? [];
|
|
11178
|
+
bucket.push(text);
|
|
11179
|
+
textByMessage.set(part.message_id, bucket);
|
|
11180
|
+
}
|
|
11181
|
+
const events = [];
|
|
11182
|
+
const inlineRefs = [];
|
|
11183
|
+
for (const message of messages) {
|
|
11184
|
+
let mdata = {};
|
|
11185
|
+
try {
|
|
11186
|
+
mdata = JSON.parse(message.data);
|
|
11187
|
+
} catch {}
|
|
11188
|
+
const role = typeof mdata.role === "string" ? mdata.role : "unknown";
|
|
11189
|
+
const mtime = mdata.time?.created;
|
|
11190
|
+
const ts = typeof mtime === "number" ? mtime : typeof message.time_created === "number" ? message.time_created : undefined;
|
|
11191
|
+
const text = (textByMessage.get(message.id) ?? []).join(`
|
|
11192
|
+
`).trim();
|
|
11193
|
+
if (text.length < 1)
|
|
11194
|
+
continue;
|
|
11195
|
+
events.push({ harness: this.name, text, ts, sessionId: ref.sessionId, role, filePath: ref.filePath });
|
|
11196
|
+
inlineRefs.push(...extractInlineRefMentions(text, ts));
|
|
11197
|
+
}
|
|
11198
|
+
events.sort((a, b) => (a.ts ?? 0) - (b.ts ?? 0));
|
|
11199
|
+
return {
|
|
11200
|
+
ref: {
|
|
11201
|
+
harness: this.name,
|
|
11202
|
+
sessionId: ref.sessionId,
|
|
11203
|
+
filePath: ref.filePath,
|
|
11204
|
+
...startedAt !== undefined ? { startedAt } : {},
|
|
11205
|
+
...endedAt !== undefined ? { endedAt } : {},
|
|
11206
|
+
...projectHint ? { projectHint } : {},
|
|
11207
|
+
...title ? { title } : {}
|
|
11208
|
+
},
|
|
11209
|
+
events,
|
|
11210
|
+
inlineRefs
|
|
11211
|
+
};
|
|
11212
|
+
} catch {
|
|
11213
|
+
return { ref: emptyRef, events: [], inlineRefs: [] };
|
|
11214
|
+
} finally {
|
|
11215
|
+
db.close();
|
|
11216
|
+
}
|
|
11217
|
+
}
|
|
10735
11218
|
#inferBaseFromSessionPath(filePath) {
|
|
10736
11219
|
const dir = path9.dirname(filePath);
|
|
10737
11220
|
const parts = dir.split(path9.sep);
|
|
@@ -10779,7 +11262,9 @@ class OpenCodeProvider {
|
|
|
10779
11262
|
};
|
|
10780
11263
|
}
|
|
10781
11264
|
}
|
|
11265
|
+
var OPENCODE_DB_FILENAME = "opencode.db";
|
|
10782
11266
|
var init_session_log2 = __esm(() => {
|
|
11267
|
+
init_database();
|
|
10783
11268
|
init_inline_refs();
|
|
10784
11269
|
});
|
|
10785
11270
|
|
|
@@ -15442,7 +15927,7 @@ var init_config_types = __esm(() => {
|
|
|
15442
15927
|
});
|
|
15443
15928
|
|
|
15444
15929
|
// src/core/config/config-schema.ts
|
|
15445
|
-
var positiveInt, nonNegativeNumber, nonEmptyString, httpUrl, LlmCapabilitiesSchema, LlmConnectionConfigSchema, LlmProfileConfigSchema, EmbeddingOllamaOptionsSchema, EmbeddingConnectionConfigSchema, AgentPlatformSchema, AgentProfileConfigSchema, ImproveProcessConfigSchema, ImproveProfileProcessesSchema, ImproveProfileConfigSchema, ProfilesSchema, DefaultsSchema, SourceConfigEntryOptionsSchema, SourceConfigEntrySchema, RegistryConfigEntrySchema, KitSourceSchema, InstalledStashEntrySchema, OutputConfigSchema, SearchGraphBoostSchema, SearchConfigSchema, FeedbackConfigSchema, ImproveUtilityDecaySchema, ImproveConfigSchema, GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED, INDEX_PASS_PROVIDER_KEYS, INDEX_PASS_KNOWN_KEYS, IndexPassConfigSchema, MetadataEnhanceSchema, StalenessDetectionSchema, IndexConfigSchema, SetupTaskSchedulesSchema, SetupConfigSchema, AkmConfigShape, AkmConfigBaseSchema, AkmConfigSchema;
|
|
15930
|
+
var positiveInt, nonNegativeNumber, nonEmptyString, httpUrl, LlmCapabilitiesSchema, LlmConnectionConfigSchema, LlmProfileConfigSchema, EmbeddingOllamaOptionsSchema, EmbeddingConnectionConfigSchema, AgentPlatformSchema, AgentProfileConfigSchema, ImproveProcessConfigSchema, ImproveProfileProcessesSchema, ImproveProfileConfigSchema, ProfilesSchema, DefaultsSchema, SourceConfigEntryOptionsSchema, SourceConfigEntrySchema, RegistryConfigEntrySchema, KitSourceSchema, InstalledStashEntrySchema, OutputConfigSchema, SearchGraphBoostSchema, SearchConfigSchema, FeedbackConfigSchema, ImproveUtilityDecaySchema, ImproveCalibrationSchema, ImproveExplorationSchema, ImproveSalienceSchema, ImproveConfigSchema, GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED, INDEX_PASS_PROVIDER_KEYS, INDEX_PASS_KNOWN_KEYS, IndexPassConfigSchema, MetadataEnhanceSchema, StalenessDetectionSchema, IndexConfigSchema, SetupTaskSchedulesSchema, SetupConfigSchema, AkmConfigShape, AkmConfigBaseSchema, AkmConfigSchema;
|
|
15446
15931
|
var init_config_schema = __esm(() => {
|
|
15447
15932
|
init_zod();
|
|
15448
15933
|
init_config_types();
|
|
@@ -15504,15 +15989,68 @@ var init_config_schema = __esm(() => {
|
|
|
15504
15989
|
timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
|
|
15505
15990
|
allowedTypes: exports_external.array(exports_external.string().min(1)).optional(),
|
|
15506
15991
|
minPoolSize: exports_external.number().int().min(0).optional(),
|
|
15992
|
+
dedup: exports_external.object({
|
|
15993
|
+
enabled: exports_external.boolean().optional(),
|
|
15994
|
+
cosineThreshold: exports_external.number().min(0).max(1).optional(),
|
|
15995
|
+
cosineCandidateLimit: exports_external.number().int().positive().optional()
|
|
15996
|
+
}).strict().optional(),
|
|
15997
|
+
judgedCache: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
|
|
15507
15998
|
qualityGate: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
|
|
15508
15999
|
contradictionDetection: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
|
|
15509
16000
|
defaultSince: exports_external.string().min(1).optional(),
|
|
15510
16001
|
maxTotalChars: positiveInt.optional(),
|
|
15511
16002
|
minContentChars: exports_external.number().int().min(0).optional(),
|
|
15512
16003
|
maxChunkSize: exports_external.number().int().min(1).max(50).optional(),
|
|
16004
|
+
incrementalSince: exports_external.string().optional(),
|
|
16005
|
+
limit: positiveInt.optional(),
|
|
16006
|
+
neighborsPerChanged: exports_external.number().int().min(1).optional(),
|
|
16007
|
+
requirePlannedRefs: exports_external.boolean().optional(),
|
|
16008
|
+
dueDays: exports_external.number().int().min(0).optional(),
|
|
16009
|
+
maxPerRun: positiveInt.optional(),
|
|
16010
|
+
topN: positiveInt.optional(),
|
|
16011
|
+
minPendingCount: exports_external.number().int().min(0).optional(),
|
|
15513
16012
|
minNewSessions: exports_external.number().int().min(0).optional(),
|
|
16013
|
+
maxSessionsPerRun: exports_external.number().int().min(0).optional(),
|
|
15514
16014
|
indexSessions: exports_external.boolean().optional(),
|
|
15515
16015
|
minSessionDuration: exports_external.number().min(0).optional(),
|
|
16016
|
+
p90ChunkSecondsDefault: exports_external.number().finite().positive().optional(),
|
|
16017
|
+
homeostaticDemotion: exports_external.object({
|
|
16018
|
+
enabled: exports_external.boolean().optional(),
|
|
16019
|
+
staleDays: exports_external.number().int().min(0).optional(),
|
|
16020
|
+
demotionFactor: exports_external.number().min(0).max(1).optional()
|
|
16021
|
+
}).strict().optional(),
|
|
16022
|
+
schemaSimilarity: exports_external.object({
|
|
16023
|
+
enabled: exports_external.boolean().optional(),
|
|
16024
|
+
epsilon: exports_external.number().min(0).max(1).optional(),
|
|
16025
|
+
confidencePenalty: exports_external.number().min(0).max(1).optional()
|
|
16026
|
+
}).strict().optional(),
|
|
16027
|
+
hotProbation: exports_external.object({
|
|
16028
|
+
enabled: exports_external.boolean().optional()
|
|
16029
|
+
}).strict().optional(),
|
|
16030
|
+
antiCollapse: exports_external.object({
|
|
16031
|
+
enabled: exports_external.boolean().optional(),
|
|
16032
|
+
maxGeneration: exports_external.number().int().min(1).optional(),
|
|
16033
|
+
lexicalDiversityCheck: exports_external.boolean().optional(),
|
|
16034
|
+
randomClusterFraction: exports_external.number().min(0).max(1).optional()
|
|
16035
|
+
}).strict().optional(),
|
|
16036
|
+
cls: exports_external.object({
|
|
16037
|
+
enabled: exports_external.boolean().optional(),
|
|
16038
|
+
adjacentCount: exports_external.number().int().min(1).optional()
|
|
16039
|
+
}).strict().optional(),
|
|
16040
|
+
fidelityCheck: exports_external.object({
|
|
16041
|
+
enabled: exports_external.boolean().optional()
|
|
16042
|
+
}).strict().optional(),
|
|
16043
|
+
minClusterSize: exports_external.number().int().min(2).optional(),
|
|
16044
|
+
maxClustersPerRun: positiveInt.optional(),
|
|
16045
|
+
maxClusterSize: positiveInt.optional(),
|
|
16046
|
+
excludeTags: exports_external.array(exports_external.string().min(1)).optional(),
|
|
16047
|
+
relatednessSource: exports_external.enum(["tags", "graph", "both"]).optional(),
|
|
16048
|
+
confirmThreshold: exports_external.number().int().min(1).optional(),
|
|
16049
|
+
minRecurrence: exports_external.number().int().min(2).optional(),
|
|
16050
|
+
maxProposalsPerRun: positiveInt.optional(),
|
|
16051
|
+
emitAs: exports_external.enum(["workflow", "skill"]).optional(),
|
|
16052
|
+
lowValueFilter: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
|
|
16053
|
+
proceduralAwareFloor: exports_external.boolean().optional(),
|
|
15516
16054
|
applyMode: exports_external.enum(["queue", "promote"]).optional(),
|
|
15517
16055
|
policy: exports_external.string().min(1).optional(),
|
|
15518
16056
|
maxAcceptsPerRun: positiveInt.optional(),
|
|
@@ -15531,7 +16069,10 @@ var init_config_schema = __esm(() => {
|
|
|
15531
16069
|
memoryInference: ImproveProcessConfigSchema.optional(),
|
|
15532
16070
|
graphExtraction: ImproveProcessConfigSchema.optional(),
|
|
15533
16071
|
validation: ImproveProcessConfigSchema.optional(),
|
|
15534
|
-
triage: ImproveProcessConfigSchema.optional()
|
|
16072
|
+
triage: ImproveProcessConfigSchema.optional(),
|
|
16073
|
+
proactiveMaintenance: ImproveProcessConfigSchema.optional(),
|
|
16074
|
+
recombine: ImproveProcessConfigSchema.optional(),
|
|
16075
|
+
procedural: ImproveProcessConfigSchema.optional()
|
|
15535
16076
|
}).passthrough().superRefine((val, ctx) => {
|
|
15536
16077
|
const raw = val;
|
|
15537
16078
|
if ("feedbackDistillation" in raw) {
|
|
@@ -15549,7 +16090,10 @@ var init_config_schema = __esm(() => {
|
|
|
15549
16090
|
"graphExtraction",
|
|
15550
16091
|
"validation",
|
|
15551
16092
|
"extract",
|
|
15552
|
-
"triage"
|
|
16093
|
+
"triage",
|
|
16094
|
+
"proactiveMaintenance",
|
|
16095
|
+
"recombine",
|
|
16096
|
+
"procedural"
|
|
15553
16097
|
]);
|
|
15554
16098
|
for (const k of Object.keys(raw)) {
|
|
15555
16099
|
if (!allowed.has(k)) {
|
|
@@ -15566,6 +16110,8 @@ var init_config_schema = __esm(() => {
|
|
|
15566
16110
|
processes: ImproveProfileProcessesSchema.optional(),
|
|
15567
16111
|
autoAccept: nonNegativeNumber.optional(),
|
|
15568
16112
|
limit: positiveInt.optional(),
|
|
16113
|
+
maxCycles: positiveInt.optional(),
|
|
16114
|
+
symmetricValence: exports_external.boolean().optional(),
|
|
15569
16115
|
sync: exports_external.object({
|
|
15570
16116
|
enabled: exports_external.boolean().optional(),
|
|
15571
16117
|
push: exports_external.boolean().optional(),
|
|
@@ -15646,6 +16192,7 @@ var init_config_schema = __esm(() => {
|
|
|
15646
16192
|
}).strict();
|
|
15647
16193
|
SearchConfigSchema = exports_external.object({
|
|
15648
16194
|
minScore: nonNegativeNumber.optional(),
|
|
16195
|
+
defaultExcludeTypes: exports_external.array(nonEmptyString).optional(),
|
|
15649
16196
|
curateRerank: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
|
|
15650
16197
|
graphBoost: SearchGraphBoostSchema.optional()
|
|
15651
16198
|
}).strict();
|
|
@@ -15657,9 +16204,29 @@ var init_config_schema = __esm(() => {
|
|
|
15657
16204
|
halfLifeDays: exports_external.number().finite().min(0.1).optional(),
|
|
15658
16205
|
feedbackStabilityBoost: exports_external.number().finite().min(1).optional()
|
|
15659
16206
|
}).strict();
|
|
16207
|
+
ImproveCalibrationSchema = exports_external.object({
|
|
16208
|
+
autoTune: exports_external.boolean().optional(),
|
|
16209
|
+
minThreshold: exports_external.number().int().min(0).max(100).optional(),
|
|
16210
|
+
maxThreshold: exports_external.number().int().min(0).max(100).optional(),
|
|
16211
|
+
maxStep: positiveInt.optional(),
|
|
16212
|
+
minSamples: nonNegativeNumber.optional(),
|
|
16213
|
+
targetAcceptRate: exports_external.number().finite().min(0).max(1).optional()
|
|
16214
|
+
}).strict();
|
|
16215
|
+
ImproveExplorationSchema = exports_external.object({
|
|
16216
|
+
enabled: exports_external.boolean().optional(),
|
|
16217
|
+
budgetFraction: exports_external.number().finite().min(0).max(1).optional()
|
|
16218
|
+
}).strict();
|
|
16219
|
+
ImproveSalienceSchema = exports_external.object({
|
|
16220
|
+
outcomeWeightEnabled: exports_external.boolean().optional(),
|
|
16221
|
+
salienceThreshold: exports_external.number().min(0).max(1).optional(),
|
|
16222
|
+
replayBudget: exports_external.number().int().min(0).optional()
|
|
16223
|
+
}).strict();
|
|
15660
16224
|
ImproveConfigSchema = exports_external.object({
|
|
15661
16225
|
utilityDecay: ImproveUtilityDecaySchema.optional(),
|
|
15662
|
-
eventRetentionDays: nonNegativeNumber.optional()
|
|
16226
|
+
eventRetentionDays: nonNegativeNumber.optional(),
|
|
16227
|
+
calibration: ImproveCalibrationSchema.optional(),
|
|
16228
|
+
exploration: ImproveExplorationSchema.optional(),
|
|
16229
|
+
salience: ImproveSalienceSchema.optional()
|
|
15663
16230
|
}).strict();
|
|
15664
16231
|
GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED = [
|
|
15665
16232
|
"memory",
|
|
@@ -15670,7 +16237,8 @@ var init_config_schema = __esm(() => {
|
|
|
15670
16237
|
"workflow",
|
|
15671
16238
|
"lesson",
|
|
15672
16239
|
"task",
|
|
15673
|
-
"wiki"
|
|
16240
|
+
"wiki",
|
|
16241
|
+
"fact"
|
|
15674
16242
|
];
|
|
15675
16243
|
INDEX_PASS_PROVIDER_KEYS = new Set([
|
|
15676
16244
|
"endpoint",
|
|
@@ -15686,7 +16254,8 @@ var init_config_schema = __esm(() => {
|
|
|
15686
16254
|
"llm",
|
|
15687
16255
|
"graphExtractionBatchSize",
|
|
15688
16256
|
"graphExtractionIncludeTypes",
|
|
15689
|
-
"memoryInferenceBatchSize"
|
|
16257
|
+
"memoryInferenceBatchSize",
|
|
16258
|
+
"lazyGraphExtraction"
|
|
15690
16259
|
]);
|
|
15691
16260
|
IndexPassConfigSchema = exports_external.preprocess((raw, ctx) => {
|
|
15692
16261
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
@@ -15704,7 +16273,7 @@ var init_config_schema = __esm(() => {
|
|
|
15704
16273
|
if (!INDEX_PASS_KNOWN_KEYS.has(key)) {
|
|
15705
16274
|
ctx.addIssue({
|
|
15706
16275
|
code: exports_external.ZodIssueCode.custom,
|
|
15707
|
-
message: `Unknown key \`${[...ctx.path ?? [], key].join(".")}\`. Per-pass entries support \`llm\` ` + "(boolean opt-out), `graphExtractionBatchSize`, `graphExtractionIncludeTypes`,
|
|
16276
|
+
message: `Unknown key \`${[...ctx.path ?? [], key].join(".")}\`. Per-pass entries support \`llm\` ` + "(boolean opt-out), `graphExtractionBatchSize`, `graphExtractionIncludeTypes`, " + "`memoryInferenceBatchSize`, and `lazyGraphExtraction`."
|
|
15708
16277
|
});
|
|
15709
16278
|
return raw;
|
|
15710
16279
|
}
|
|
@@ -15721,7 +16290,8 @@ var init_config_schema = __esm(() => {
|
|
|
15721
16290
|
llm: exports_external.boolean().optional(),
|
|
15722
16291
|
graphExtractionBatchSize: positiveInt.optional(),
|
|
15723
16292
|
graphExtractionIncludeTypes: exports_external.array(exports_external.enum(GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED)).nonempty().optional(),
|
|
15724
|
-
memoryInferenceBatchSize: positiveInt.optional()
|
|
16293
|
+
memoryInferenceBatchSize: positiveInt.optional(),
|
|
16294
|
+
lazyGraphExtraction: exports_external.boolean().optional()
|
|
15725
16295
|
}).passthrough());
|
|
15726
16296
|
MetadataEnhanceSchema = exports_external.object({ enabled: exports_external.boolean().optional() }).strict();
|
|
15727
16297
|
StalenessDetectionSchema = exports_external.object({
|
|
@@ -16042,9 +16612,9 @@ function maybeAutoMigrateConfigFile(configPath, text) {
|
|
|
16042
16612
|
"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
16043
16613
|
].join(`
|
|
16044
16614
|
`);
|
|
16045
|
-
process.stderr
|
|
16615
|
+
process.stderr?.write?.(`${banner}
|
|
16046
16616
|
`);
|
|
16047
|
-
process.stdout
|
|
16617
|
+
process.stdout?.write?.(`${banner}
|
|
16048
16618
|
`);
|
|
16049
16619
|
} catch (err) {
|
|
16050
16620
|
throw new ConfigError(`Failed to write migrated config to ${configPath}: ${err instanceof Error ? err.message : String(err)}`, "INVALID_CONFIG_FILE", "Check filesystem permissions, free space, and disk health. To skip auto-migration, set AKM_NO_AUTO_MIGRATE=1.");
|
|
@@ -16288,6 +16858,7 @@ __export(exports_db, {
|
|
|
16288
16858
|
getMeta: () => getMeta,
|
|
16289
16859
|
getLlmCacheEntry: () => getLlmCacheEntry,
|
|
16290
16860
|
getLlmCacheEntriesByRefs: () => getLlmCacheEntriesByRefs,
|
|
16861
|
+
getIndexedFilePaths: () => getIndexedFilePaths,
|
|
16291
16862
|
getIndexDirState: () => getIndexDirState,
|
|
16292
16863
|
getEntryRefRowsForStashRoot: () => getEntryRefRowsForStashRoot,
|
|
16293
16864
|
getEntryIdByFilePath: () => getEntryIdByFilePath,
|
|
@@ -16296,6 +16867,7 @@ __export(exports_db, {
|
|
|
16296
16867
|
getEntryByRef: () => getEntryByRef,
|
|
16297
16868
|
getEntryById: () => getEntryById,
|
|
16298
16869
|
getEntriesByDir: () => getEntriesByDir,
|
|
16870
|
+
getEntitiesByEntryIds: () => getEntitiesByEntryIds,
|
|
16299
16871
|
getEmbeddingCount: () => getEmbeddingCount,
|
|
16300
16872
|
getEmbeddableEntryCount: () => getEmbeddableEntryCount,
|
|
16301
16873
|
getDerivedForParent: () => getDerivedForParent,
|
|
@@ -16330,9 +16902,7 @@ function openDatabase2(dbPath, options) {
|
|
|
16330
16902
|
fs12.mkdirSync(dir, { recursive: true });
|
|
16331
16903
|
}
|
|
16332
16904
|
const db = openDatabase(resolvedPath);
|
|
16333
|
-
db
|
|
16334
|
-
db.exec("PRAGMA busy_timeout = 30000");
|
|
16335
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
16905
|
+
applyStandardPragmas(db, { dataDir: dir });
|
|
16336
16906
|
loadVecExtension(db);
|
|
16337
16907
|
const resolvedDim = options?.embeddingDim ?? resolveConfiguredEmbeddingDim();
|
|
16338
16908
|
ensureSchema(db, resolvedDim, { dataDir: dir });
|
|
@@ -16353,10 +16923,9 @@ function resolveConfiguredEmbeddingDim() {
|
|
|
16353
16923
|
}
|
|
16354
16924
|
function openExistingDatabase(dbPath) {
|
|
16355
16925
|
const resolvedPath = dbPath ?? getDbPath();
|
|
16926
|
+
const dir = path11.dirname(resolvedPath);
|
|
16356
16927
|
const db = openDatabase(resolvedPath);
|
|
16357
|
-
db
|
|
16358
|
-
db.exec("PRAGMA busy_timeout = 30000");
|
|
16359
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
16928
|
+
applyStandardPragmas(db, { dataDir: dir });
|
|
16360
16929
|
loadVecExtension(db);
|
|
16361
16930
|
return db;
|
|
16362
16931
|
}
|
|
@@ -16521,6 +17090,7 @@ function ensureSchema(db, embeddingDim, options) {
|
|
|
16521
17090
|
CREATE INDEX IF NOT EXISTS idx_llm_cache_updated
|
|
16522
17091
|
ON llm_enrichment_cache(updated_at);
|
|
16523
17092
|
`);
|
|
17093
|
+
migrateGraphFilesSchema(db);
|
|
16524
17094
|
db.exec(`
|
|
16525
17095
|
CREATE TABLE IF NOT EXISTS graph_meta (
|
|
16526
17096
|
stash_root TEXT PRIMARY KEY,
|
|
@@ -16544,7 +17114,6 @@ function ensureSchema(db, embeddingDim, options) {
|
|
|
16544
17114
|
);
|
|
16545
17115
|
|
|
16546
17116
|
CREATE TABLE IF NOT EXISTS graph_files (
|
|
16547
|
-
entry_id INTEGER PRIMARY KEY REFERENCES entries(id) ON DELETE CASCADE,
|
|
16548
17117
|
stash_root TEXT NOT NULL,
|
|
16549
17118
|
file_path TEXT NOT NULL,
|
|
16550
17119
|
file_order INTEGER NOT NULL,
|
|
@@ -16554,26 +17123,34 @@ function ensureSchema(db, embeddingDim, options) {
|
|
|
16554
17123
|
status TEXT NOT NULL DEFAULT 'extracted',
|
|
16555
17124
|
reason TEXT,
|
|
16556
17125
|
extraction_run_id TEXT,
|
|
16557
|
-
|
|
17126
|
+
PRIMARY KEY (stash_root, file_path, body_hash)
|
|
16558
17127
|
);
|
|
16559
17128
|
|
|
17129
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_graph_files_path
|
|
17130
|
+
ON graph_files(stash_root, file_path);
|
|
17131
|
+
|
|
16560
17132
|
CREATE INDEX IF NOT EXISTS idx_graph_files_stash_order
|
|
16561
17133
|
ON graph_files(stash_root, file_order);
|
|
16562
17134
|
|
|
16563
17135
|
CREATE TABLE IF NOT EXISTS graph_file_entities (
|
|
16564
|
-
entry_id INTEGER NOT NULL REFERENCES graph_files(entry_id) ON DELETE CASCADE,
|
|
16565
|
-
entity_order INTEGER NOT NULL,
|
|
16566
17136
|
stash_root TEXT NOT NULL,
|
|
17137
|
+
file_path TEXT NOT NULL,
|
|
17138
|
+
body_hash TEXT NOT NULL,
|
|
17139
|
+
entity_order INTEGER NOT NULL,
|
|
16567
17140
|
entity_norm TEXT NOT NULL,
|
|
16568
17141
|
entity TEXT NOT NULL,
|
|
16569
|
-
PRIMARY KEY (
|
|
17142
|
+
PRIMARY KEY (stash_root, file_path, body_hash, entity_order),
|
|
17143
|
+
FOREIGN KEY (stash_root, file_path, body_hash)
|
|
17144
|
+
REFERENCES graph_files(stash_root, file_path, body_hash) ON DELETE CASCADE
|
|
16570
17145
|
);
|
|
16571
17146
|
|
|
16572
17147
|
CREATE INDEX IF NOT EXISTS idx_graph_file_entities_entity_norm
|
|
16573
17148
|
ON graph_file_entities(stash_root, entity_norm);
|
|
16574
17149
|
|
|
16575
17150
|
CREATE TABLE IF NOT EXISTS graph_file_relations (
|
|
16576
|
-
|
|
17151
|
+
stash_root TEXT NOT NULL,
|
|
17152
|
+
file_path TEXT NOT NULL,
|
|
17153
|
+
body_hash TEXT NOT NULL,
|
|
16577
17154
|
relation_order INTEGER NOT NULL,
|
|
16578
17155
|
from_entity_norm TEXT NOT NULL,
|
|
16579
17156
|
from_entity TEXT NOT NULL,
|
|
@@ -16581,9 +17158,28 @@ function ensureSchema(db, embeddingDim, options) {
|
|
|
16581
17158
|
to_entity TEXT NOT NULL,
|
|
16582
17159
|
relation_type TEXT,
|
|
16583
17160
|
confidence REAL,
|
|
16584
|
-
PRIMARY KEY (
|
|
17161
|
+
PRIMARY KEY (stash_root, file_path, body_hash, relation_order),
|
|
17162
|
+
FOREIGN KEY (stash_root, file_path, body_hash)
|
|
17163
|
+
REFERENCES graph_files(stash_root, file_path, body_hash) ON DELETE CASCADE
|
|
17164
|
+
);
|
|
17165
|
+
|
|
17166
|
+
-- #624-P3: lazy graph-extraction queue. Standalone table (NO FK to
|
|
17167
|
+
-- graph_files \u2014 a queued file by definition has no graph row yet).
|
|
17168
|
+
-- Idempotent on (stash_root, file_path); drained highest-priority-first.
|
|
17169
|
+
-- CREATE TABLE IF NOT EXISTS is the forward migration (no DB_VERSION bump).
|
|
17170
|
+
CREATE TABLE IF NOT EXISTS graph_extraction_queue (
|
|
17171
|
+
stash_root TEXT NOT NULL,
|
|
17172
|
+
file_path TEXT NOT NULL,
|
|
17173
|
+
body_hash TEXT NOT NULL,
|
|
17174
|
+
queued_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
17175
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
17176
|
+
PRIMARY KEY (stash_root, file_path)
|
|
16585
17177
|
);
|
|
17178
|
+
|
|
17179
|
+
CREATE INDEX IF NOT EXISTS idx_graph_extraction_queue_drain
|
|
17180
|
+
ON graph_extraction_queue(stash_root, priority DESC, queued_at);
|
|
16586
17181
|
`);
|
|
17182
|
+
migrateGraphDataFromLegacy(db);
|
|
16587
17183
|
db.exec(`
|
|
16588
17184
|
CREATE TABLE IF NOT EXISTS entries_fts_dirty (
|
|
16589
17185
|
entry_id INTEGER PRIMARY KEY
|
|
@@ -16649,6 +17245,7 @@ function handleVersionUpgrade(db) {
|
|
|
16649
17245
|
db.exec("DROP TABLE IF EXISTS index_dir_state");
|
|
16650
17246
|
db.exec("DROP TABLE IF EXISTS llm_enrichment_cache");
|
|
16651
17247
|
db.exec("DROP INDEX IF EXISTS idx_llm_cache_updated");
|
|
17248
|
+
db.exec("DROP TABLE IF EXISTS graph_extraction_queue");
|
|
16652
17249
|
db.exec("DROP TABLE IF EXISTS graph_file_relations");
|
|
16653
17250
|
db.exec("DROP TABLE IF EXISTS graph_file_entities");
|
|
16654
17251
|
db.exec("DROP TABLE IF EXISTS graph_files");
|
|
@@ -16799,6 +17396,67 @@ function ensureDerivedFromColumn(db) {
|
|
|
16799
17396
|
db.exec("CREATE INDEX IF NOT EXISTS idx_entries_derived_from ON entries(derived_from)");
|
|
16800
17397
|
}, "entries table may not exist on a brand-new DB before CREATE \u2014 caller is responsible");
|
|
16801
17398
|
}
|
|
17399
|
+
function tableExists(db, name) {
|
|
17400
|
+
const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1").get(name);
|
|
17401
|
+
return row !== undefined && row !== null;
|
|
17402
|
+
}
|
|
17403
|
+
function migrateGraphFilesSchema(db) {
|
|
17404
|
+
bestEffort(() => {
|
|
17405
|
+
const cols = db.prepare("PRAGMA table_info(graph_files)").all();
|
|
17406
|
+
const isLegacyShape = cols.some((c) => c.name === "entry_id");
|
|
17407
|
+
if (!isLegacyShape)
|
|
17408
|
+
return;
|
|
17409
|
+
db.exec("DROP TABLE IF EXISTS graph_file_relations_legacy");
|
|
17410
|
+
db.exec("DROP TABLE IF EXISTS graph_file_entities_legacy");
|
|
17411
|
+
db.exec("DROP TABLE IF EXISTS graph_files_legacy");
|
|
17412
|
+
db.exec("ALTER TABLE graph_files RENAME TO graph_files_legacy");
|
|
17413
|
+
if (tableExists(db, "graph_file_entities")) {
|
|
17414
|
+
db.exec("ALTER TABLE graph_file_entities RENAME TO graph_file_entities_legacy");
|
|
17415
|
+
}
|
|
17416
|
+
if (tableExists(db, "graph_file_relations")) {
|
|
17417
|
+
db.exec("ALTER TABLE graph_file_relations RENAME TO graph_file_relations_legacy");
|
|
17418
|
+
}
|
|
17419
|
+
}, "graph_files may not exist on a brand-new DB before CREATE \u2014 caller is responsible");
|
|
17420
|
+
}
|
|
17421
|
+
function migrateGraphDataFromLegacy(db) {
|
|
17422
|
+
if (!tableExists(db, "graph_files_legacy"))
|
|
17423
|
+
return;
|
|
17424
|
+
let migratedFiles = 0;
|
|
17425
|
+
bestEffort(() => {
|
|
17426
|
+
db.transaction(() => {
|
|
17427
|
+
const res = db.prepare(`INSERT OR IGNORE INTO graph_files
|
|
17428
|
+
(stash_root, file_path, body_hash, file_order, file_type, confidence, status, reason, extraction_run_id)
|
|
17429
|
+
SELECT stash_root, file_path, body_hash, file_order, file_type, confidence, status, reason, extraction_run_id
|
|
17430
|
+
FROM graph_files_legacy
|
|
17431
|
+
WHERE body_hash IS NOT NULL AND body_hash != ''`).run();
|
|
17432
|
+
migratedFiles = Number(res.changes);
|
|
17433
|
+
if (tableExists(db, "graph_file_entities_legacy")) {
|
|
17434
|
+
db.exec(`INSERT OR IGNORE INTO graph_file_entities
|
|
17435
|
+
(stash_root, file_path, body_hash, entity_order, entity_norm, entity)
|
|
17436
|
+
SELECT gf.stash_root, gf.file_path, gf.body_hash, e.entity_order, e.entity_norm, e.entity
|
|
17437
|
+
FROM graph_file_entities_legacy e
|
|
17438
|
+
JOIN graph_files_legacy gf ON gf.entry_id = e.entry_id
|
|
17439
|
+
WHERE gf.body_hash IS NOT NULL AND gf.body_hash != ''`);
|
|
17440
|
+
}
|
|
17441
|
+
if (tableExists(db, "graph_file_relations_legacy")) {
|
|
17442
|
+
db.exec(`INSERT OR IGNORE INTO graph_file_relations
|
|
17443
|
+
(stash_root, file_path, body_hash, relation_order, from_entity_norm, from_entity, to_entity_norm, to_entity, relation_type, confidence)
|
|
17444
|
+
SELECT gf.stash_root, gf.file_path, gf.body_hash, r.relation_order, r.from_entity_norm, r.from_entity, r.to_entity_norm, r.to_entity, r.relation_type, r.confidence
|
|
17445
|
+
FROM graph_file_relations_legacy r
|
|
17446
|
+
JOIN graph_files_legacy gf ON gf.entry_id = r.entry_id
|
|
17447
|
+
WHERE gf.body_hash IS NOT NULL AND gf.body_hash != ''`);
|
|
17448
|
+
}
|
|
17449
|
+
})();
|
|
17450
|
+
}, "graph data migration is best-effort; legacy tables are dropped regardless below");
|
|
17451
|
+
bestEffort(() => {
|
|
17452
|
+
db.exec("DROP TABLE IF EXISTS graph_file_relations_legacy");
|
|
17453
|
+
db.exec("DROP TABLE IF EXISTS graph_file_entities_legacy");
|
|
17454
|
+
db.exec("DROP TABLE IF EXISTS graph_files_legacy");
|
|
17455
|
+
}, "drop legacy graph tables after migration");
|
|
17456
|
+
if (migratedFiles > 0) {
|
|
17457
|
+
warn(`[akm] graph index re-keyed (#624): migrated ${migratedFiles} extracted file(s) to the new schema \u2014 no re-extraction needed. Index + embeddings untouched.`);
|
|
17458
|
+
}
|
|
17459
|
+
}
|
|
16802
17460
|
function getDerivedForParent(db, parentRef) {
|
|
16803
17461
|
if (!parentRef)
|
|
16804
17462
|
return null;
|
|
@@ -16888,6 +17546,25 @@ function deleteRelatedRows(db, ids) {
|
|
|
16888
17546
|
bestEffort(() => db.prepare(`DELETE FROM utility_scores_scoped WHERE entry_id IN (${placeholders})`).run(...chunk), "delete utility_scores_scoped for entries");
|
|
16889
17547
|
bestEffort(() => db.prepare(`DELETE FROM usage_events WHERE entry_id IN (${placeholders})`).run(...chunk), "delete usage_events for entries");
|
|
16890
17548
|
}
|
|
17549
|
+
const affectedStashRoots = new Set;
|
|
17550
|
+
for (let i = 0;i < numericIds.length; i += SQLITE_CHUNK_SIZE) {
|
|
17551
|
+
const chunk = numericIds.slice(i, i + SQLITE_CHUNK_SIZE);
|
|
17552
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
17553
|
+
bestEffort(() => {
|
|
17554
|
+
const rows = db.prepare(`SELECT DISTINCT stash_dir FROM entries WHERE id IN (${placeholders})`).all(...chunk);
|
|
17555
|
+
for (const row of rows) {
|
|
17556
|
+
if (row.stash_dir)
|
|
17557
|
+
affectedStashRoots.add(row.stash_dir);
|
|
17558
|
+
}
|
|
17559
|
+
}, "resolve stash roots for graph_meta recompute");
|
|
17560
|
+
}
|
|
17561
|
+
for (const stashRoot of affectedStashRoots) {
|
|
17562
|
+
bestEffort(() => db.prepare(`UPDATE graph_meta
|
|
17563
|
+
SET extracted_files = (SELECT COUNT(*) FROM graph_files WHERE stash_root = ?),
|
|
17564
|
+
entity_count = (SELECT COUNT(*) FROM graph_file_entities WHERE stash_root = ?),
|
|
17565
|
+
relation_count = (SELECT COUNT(*) FROM graph_file_relations WHERE stash_root = ?)
|
|
17566
|
+
WHERE stash_root = ?`).run(stashRoot, stashRoot, stashRoot, stashRoot), "sync graph_meta counts after entries delete");
|
|
17567
|
+
}
|
|
16891
17568
|
}
|
|
16892
17569
|
function deleteEntriesByIds(db, ids) {
|
|
16893
17570
|
if (ids.length === 0)
|
|
@@ -17017,17 +17694,17 @@ function searchBlobVec(db, queryEmbedding, k) {
|
|
|
17017
17694
|
return [];
|
|
17018
17695
|
}
|
|
17019
17696
|
}
|
|
17020
|
-
function searchFts(db, query, limit, entryType) {
|
|
17697
|
+
function searchFts(db, query, limit, entryType, excludeTypes) {
|
|
17021
17698
|
const ftsQuery = sanitizeFtsQuery(query);
|
|
17022
17699
|
if (!ftsQuery)
|
|
17023
17700
|
return [];
|
|
17024
|
-
const exactResults = runFtsQuery(db, ftsQuery, limit, entryType);
|
|
17701
|
+
const exactResults = runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes);
|
|
17025
17702
|
if (exactResults.length > 0)
|
|
17026
17703
|
return exactResults;
|
|
17027
17704
|
const prefixQuery = buildPrefixQuery(ftsQuery);
|
|
17028
17705
|
if (!prefixQuery)
|
|
17029
17706
|
return [];
|
|
17030
|
-
return runFtsQuery(db, prefixQuery, limit, entryType);
|
|
17707
|
+
return runFtsQuery(db, prefixQuery, limit, entryType, excludeTypes);
|
|
17031
17708
|
}
|
|
17032
17709
|
function buildPrefixQuery(ftsQuery) {
|
|
17033
17710
|
const tokens = ftsQuery.split(/\s+/).filter(Boolean);
|
|
@@ -17043,9 +17720,10 @@ function buildPrefixQuery(ftsQuery) {
|
|
|
17043
17720
|
return null;
|
|
17044
17721
|
return prefixTokens.join(" ");
|
|
17045
17722
|
}
|
|
17046
|
-
function runFtsQuery(db, ftsQuery, limit, entryType) {
|
|
17723
|
+
function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
|
|
17047
17724
|
let sql;
|
|
17048
17725
|
let params;
|
|
17726
|
+
const excludes = excludeTypes && excludeTypes.length > 0 ? excludeTypes : [];
|
|
17049
17727
|
if (entryType && entryType !== "any") {
|
|
17050
17728
|
sql = `
|
|
17051
17729
|
SELECT e.id, e.file_path AS filePath, e.entry_json, e.search_text AS searchText,
|
|
@@ -17059,16 +17737,18 @@ function runFtsQuery(db, ftsQuery, limit, entryType) {
|
|
|
17059
17737
|
`;
|
|
17060
17738
|
params = [ftsQuery, entryType, limit];
|
|
17061
17739
|
} else {
|
|
17740
|
+
const excludeClause = excludes.length > 0 ? `AND e.entry_type NOT IN (${excludes.map(() => "?").join(", ")})` : "";
|
|
17062
17741
|
sql = `
|
|
17063
17742
|
SELECT e.id, e.file_path AS filePath, e.entry_json, e.search_text AS searchText,
|
|
17064
17743
|
bm25(entries_fts, 0, 10.0, 5.0, 3.0, 2.0, 1.0) AS bm25Score
|
|
17065
17744
|
FROM entries_fts f
|
|
17066
17745
|
JOIN entries e ON e.id = f.entry_id
|
|
17067
17746
|
WHERE entries_fts MATCH ?
|
|
17747
|
+
${excludeClause}
|
|
17068
17748
|
ORDER BY bm25Score, e.id ASC
|
|
17069
17749
|
LIMIT ?
|
|
17070
17750
|
`;
|
|
17071
|
-
params = [ftsQuery, limit];
|
|
17751
|
+
params = [ftsQuery, ...excludes, limit];
|
|
17072
17752
|
}
|
|
17073
17753
|
try {
|
|
17074
17754
|
const rows = db.prepare(sql).all(...params);
|
|
@@ -17124,12 +17804,16 @@ function parseEntryRows(rows, context) {
|
|
|
17124
17804
|
}
|
|
17125
17805
|
return entries;
|
|
17126
17806
|
}
|
|
17127
|
-
function getAllEntries(db, entryType) {
|
|
17807
|
+
function getAllEntries(db, entryType, excludeTypes) {
|
|
17128
17808
|
let sql;
|
|
17129
17809
|
let params;
|
|
17810
|
+
const excludes = excludeTypes && excludeTypes.length > 0 ? excludeTypes : [];
|
|
17130
17811
|
if (entryType && entryType !== "any") {
|
|
17131
17812
|
sql = "SELECT id, entry_key, dir_path, file_path, stash_dir, entry_json, search_text FROM entries WHERE entry_type = ?";
|
|
17132
17813
|
params = [entryType];
|
|
17814
|
+
} else if (excludes.length > 0) {
|
|
17815
|
+
sql = `SELECT id, entry_key, dir_path, file_path, stash_dir, entry_json, search_text FROM entries WHERE entry_type NOT IN (${excludes.map(() => "?").join(", ")})`;
|
|
17816
|
+
params = [...excludes];
|
|
17133
17817
|
} else {
|
|
17134
17818
|
sql = "SELECT id, entry_key, dir_path, file_path, stash_dir, entry_json, search_text FROM entries";
|
|
17135
17819
|
params = [];
|
|
@@ -17137,6 +17821,33 @@ function getAllEntries(db, entryType) {
|
|
|
17137
17821
|
const rows = db.prepare(sql).all(...params);
|
|
17138
17822
|
return parseEntryRows(rows, "getAllEntries");
|
|
17139
17823
|
}
|
|
17824
|
+
function getEntitiesByEntryIds(db, entryIds) {
|
|
17825
|
+
const result = new Map;
|
|
17826
|
+
if (entryIds.length === 0)
|
|
17827
|
+
return result;
|
|
17828
|
+
for (let i = 0;i < entryIds.length; i += SQLITE_CHUNK_SIZE) {
|
|
17829
|
+
const chunk = entryIds.slice(i, i + SQLITE_CHUNK_SIZE);
|
|
17830
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
17831
|
+
const rows = db.prepare(`SELECT e.id AS entry_id, gfe.entity_norm AS entity_norm
|
|
17832
|
+
FROM entries e
|
|
17833
|
+
JOIN graph_files gf
|
|
17834
|
+
ON gf.stash_root = e.stash_dir AND gf.file_path = e.file_path
|
|
17835
|
+
JOIN graph_file_entities gfe
|
|
17836
|
+
ON gfe.stash_root = gf.stash_root
|
|
17837
|
+
AND gfe.file_path = gf.file_path
|
|
17838
|
+
AND gfe.body_hash = gf.body_hash
|
|
17839
|
+
WHERE e.id IN (${placeholders})
|
|
17840
|
+
ORDER BY e.id, gfe.entity_order`).all(...chunk);
|
|
17841
|
+
for (const row of rows) {
|
|
17842
|
+
const list = result.get(row.entry_id);
|
|
17843
|
+
if (list)
|
|
17844
|
+
list.push(row.entity_norm);
|
|
17845
|
+
else
|
|
17846
|
+
result.set(row.entry_id, [row.entity_norm]);
|
|
17847
|
+
}
|
|
17848
|
+
}
|
|
17849
|
+
return result;
|
|
17850
|
+
}
|
|
17140
17851
|
function findEntryIdByRef(db, ref) {
|
|
17141
17852
|
const parsed = parseAssetRef(ref);
|
|
17142
17853
|
const nameVariants = [parsed.name];
|
|
@@ -17187,6 +17898,10 @@ function getEntryIdByFilePath(db, filePath) {
|
|
|
17187
17898
|
const row = db.prepare("SELECT id FROM entries WHERE file_path = ? LIMIT 1").get(filePath);
|
|
17188
17899
|
return row?.id;
|
|
17189
17900
|
}
|
|
17901
|
+
function getIndexedFilePaths(db) {
|
|
17902
|
+
const rows = db.prepare("SELECT DISTINCT file_path FROM entries WHERE file_path IS NOT NULL AND file_path <> ''").all();
|
|
17903
|
+
return new Set(rows.map((r) => r.file_path));
|
|
17904
|
+
}
|
|
17190
17905
|
function getEntryFilePathById(db, id) {
|
|
17191
17906
|
const row = db.prepare("SELECT file_path FROM entries WHERE id = ?").get(id);
|
|
17192
17907
|
return row?.file_path;
|
|
@@ -17314,18 +18029,56 @@ function clearStaleCacheEntries(db) {
|
|
|
17314
18029
|
function computeBodyHash(body) {
|
|
17315
18030
|
return sha256Hex(body);
|
|
17316
18031
|
}
|
|
18032
|
+
function bareRef(ref) {
|
|
18033
|
+
try {
|
|
18034
|
+
const parsed = parseAssetRef(ref);
|
|
18035
|
+
return `${parsed.type}:${parsed.name}`;
|
|
18036
|
+
} catch {
|
|
18037
|
+
return ref;
|
|
18038
|
+
}
|
|
18039
|
+
}
|
|
17317
18040
|
function getRetrievalCounts(db, refs) {
|
|
17318
18041
|
if (refs.length === 0)
|
|
17319
18042
|
return new Map;
|
|
17320
|
-
const
|
|
17321
|
-
for (
|
|
17322
|
-
const
|
|
18043
|
+
const bareToInputs = new Map;
|
|
18044
|
+
for (const ref of refs) {
|
|
18045
|
+
const bare = bareRef(ref);
|
|
18046
|
+
const existing = bareToInputs.get(bare);
|
|
18047
|
+
if (existing)
|
|
18048
|
+
existing.push(ref);
|
|
18049
|
+
else
|
|
18050
|
+
bareToInputs.set(bare, [ref]);
|
|
18051
|
+
}
|
|
18052
|
+
const bareForms = [...bareToInputs.keys()];
|
|
18053
|
+
const countsByBare = new Map;
|
|
18054
|
+
for (let i = 0;i < bareForms.length; i += SQLITE_CHUNK_SIZE) {
|
|
18055
|
+
const chunk = bareForms.slice(i, i + SQLITE_CHUNK_SIZE);
|
|
17323
18056
|
const placeholders = chunk.map(() => "?").join(", ");
|
|
17324
|
-
const rows = db.prepare(`SELECT
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
|
|
17328
|
-
|
|
18057
|
+
const rows = db.prepare(`SELECT
|
|
18058
|
+
CASE
|
|
18059
|
+
WHEN instr(entry_ref, '//') > 0
|
|
18060
|
+
THEN substr(entry_ref, instr(entry_ref, '//') + 2)
|
|
18061
|
+
ELSE entry_ref
|
|
18062
|
+
END AS bare_ref,
|
|
18063
|
+
COUNT(*) AS cnt
|
|
18064
|
+
FROM usage_events
|
|
18065
|
+
WHERE event_type IN ('search','show','curate')
|
|
18066
|
+
AND entry_ref IS NOT NULL
|
|
18067
|
+
AND CASE
|
|
18068
|
+
WHEN instr(entry_ref, '//') > 0
|
|
18069
|
+
THEN substr(entry_ref, instr(entry_ref, '//') + 2)
|
|
18070
|
+
ELSE entry_ref
|
|
18071
|
+
END IN (${placeholders})
|
|
18072
|
+
GROUP BY bare_ref`).all(...chunk);
|
|
18073
|
+
for (const r of rows) {
|
|
18074
|
+
countsByBare.set(r.bare_ref, (countsByBare.get(r.bare_ref) ?? 0) + r.cnt);
|
|
18075
|
+
}
|
|
18076
|
+
}
|
|
18077
|
+
const result = new Map;
|
|
18078
|
+
for (const [bare, count] of countsByBare) {
|
|
18079
|
+
for (const input of bareToInputs.get(bare) ?? []) {
|
|
18080
|
+
result.set(input, count);
|
|
18081
|
+
}
|
|
17329
18082
|
}
|
|
17330
18083
|
return result;
|
|
17331
18084
|
}
|
|
@@ -17489,7 +18242,7 @@ function collectTagSetFromEntries(db, entryType) {
|
|
|
17489
18242
|
}
|
|
17490
18243
|
return tags;
|
|
17491
18244
|
}
|
|
17492
|
-
var DB_VERSION = 17, EMBEDDING_DIM = 384, GRAPH_SCHEMA_VERSION =
|
|
18245
|
+
var DB_VERSION = 17, EMBEDDING_DIM = 384, GRAPH_SCHEMA_VERSION = 4, vecStatus, VEC_DOCS_URL = "https://github.com/itlackey/akm/blob/main/docs/configuration.md#sqlite-vec-extension", VEC_FALLBACK_THRESHOLD = 1e4, vecInitWarnedDbs, SQLITE_CHUNK_SIZE = 500, upsertStmtsByDb, FEEDBACK_LR = 0.1, FEEDBACK_REWARD_POSITIVE = 1, FEEDBACK_REWARD_NEGATIVE = 0, MAX_NEG_DELTA_PER_CALL = 0.15, UTILITY_REVIEW_THRESHOLD = 0.5, HIGH_UTILITY_THRESHOLD = 0.5;
|
|
17493
18246
|
var init_db = __esm(() => {
|
|
17494
18247
|
init_asset_ref();
|
|
17495
18248
|
init_best_effort();
|
|
@@ -17499,6 +18252,7 @@ var init_db = __esm(() => {
|
|
|
17499
18252
|
init_types();
|
|
17500
18253
|
init_runtime();
|
|
17501
18254
|
init_database();
|
|
18255
|
+
init_sqlite_pragmas();
|
|
17502
18256
|
init_db_backup();
|
|
17503
18257
|
vecStatus = new WeakMap;
|
|
17504
18258
|
vecInitWarnedDbs = new WeakSet;
|
|
@@ -17508,13 +18262,15 @@ var init_db = __esm(() => {
|
|
|
17508
18262
|
// src/indexer/db/graph-db.ts
|
|
17509
18263
|
var exports_graph_db = {};
|
|
17510
18264
|
__export(exports_graph_db, {
|
|
17511
|
-
resolveEntryIdForPath: () => resolveEntryIdForPath,
|
|
17512
18265
|
replaceStoredGraph: () => replaceStoredGraph,
|
|
17513
18266
|
loadStoredGraphSnapshot: () => loadStoredGraphSnapshot,
|
|
17514
18267
|
loadStoredGraphMeta: () => loadStoredGraphMeta,
|
|
17515
18268
|
loadGraphMetaOnly: () => loadGraphMetaOnly,
|
|
17516
18269
|
loadGraphFilesOnly: () => loadGraphFilesOnly,
|
|
17517
|
-
|
|
18270
|
+
loadGraphEntitiesByPath: () => loadGraphEntitiesByPath,
|
|
18271
|
+
hasGraphData: () => hasGraphData,
|
|
18272
|
+
enqueueGraphExtraction: () => enqueueGraphExtraction,
|
|
18273
|
+
drainExtractionQueue: () => drainExtractionQueue,
|
|
17518
18274
|
deleteStoredGraph: () => deleteStoredGraph
|
|
17519
18275
|
});
|
|
17520
18276
|
import fs13 from "fs";
|
|
@@ -17537,17 +18293,6 @@ function uniqueSorted(values) {
|
|
|
17537
18293
|
function normalizeEntity(value) {
|
|
17538
18294
|
return value.trim().toLowerCase();
|
|
17539
18295
|
}
|
|
17540
|
-
function resolveEntryIdForPath(db, stashRoot, filePath) {
|
|
17541
|
-
try {
|
|
17542
|
-
const row = db.prepare("SELECT id FROM entries WHERE stash_dir = ? AND file_path = ? LIMIT 1").get(stashRoot, filePath);
|
|
17543
|
-
if (row)
|
|
17544
|
-
return row.id;
|
|
17545
|
-
const fallback = db.prepare("SELECT id FROM entries WHERE file_path = ? LIMIT 1").get(filePath);
|
|
17546
|
-
return fallback?.id ?? null;
|
|
17547
|
-
} catch {
|
|
17548
|
-
return null;
|
|
17549
|
-
}
|
|
17550
|
-
}
|
|
17551
18296
|
function replaceStoredGraph(db, graph) {
|
|
17552
18297
|
const upsertMeta = db.prepare(`INSERT INTO graph_meta (
|
|
17553
18298
|
stash_root,
|
|
@@ -17587,21 +18332,21 @@ function replaceStoredGraph(db, graph) {
|
|
|
17587
18332
|
cache_misses = excluded.cache_misses,
|
|
17588
18333
|
truncation_count = excluded.truncation_count,
|
|
17589
18334
|
failure_count = excluded.failure_count`);
|
|
17590
|
-
const selectExisting = db.prepare("SELECT
|
|
17591
|
-
const deleteFile = db.prepare("DELETE FROM graph_files WHERE
|
|
17592
|
-
const deleteEntities = db.prepare("DELETE FROM graph_file_entities WHERE
|
|
17593
|
-
const deleteRelations = db.prepare("DELETE FROM graph_file_relations WHERE
|
|
18335
|
+
const selectExisting = db.prepare("SELECT file_path, body_hash, file_order FROM graph_files WHERE stash_root = ?");
|
|
18336
|
+
const deleteFile = db.prepare("DELETE FROM graph_files WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
18337
|
+
const deleteEntities = db.prepare("DELETE FROM graph_file_entities WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
18338
|
+
const deleteRelations = db.prepare("DELETE FROM graph_file_relations WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
17594
18339
|
const insertFile = db.prepare(`INSERT INTO graph_files (
|
|
17595
|
-
|
|
17596
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
|
|
18340
|
+
stash_root, file_path, file_order, file_type, body_hash, confidence, status, reason, extraction_run_id
|
|
18341
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
17597
18342
|
const updateFileMeta = db.prepare(`UPDATE graph_files
|
|
17598
18343
|
SET file_order = ?, file_type = ?, confidence = ?, status = ?, reason = ?, extraction_run_id = ?
|
|
17599
|
-
WHERE
|
|
17600
|
-
const insertEntity = db.prepare(`INSERT INTO graph_file_entities (
|
|
17601
|
-
VALUES (?, ?, ?, ?, ?)`);
|
|
18344
|
+
WHERE stash_root = ? AND file_path = ? AND body_hash = ?`);
|
|
18345
|
+
const insertEntity = db.prepare(`INSERT INTO graph_file_entities (stash_root, file_path, body_hash, entity_order, entity_norm, entity)
|
|
18346
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
17602
18347
|
const insertRelation = db.prepare(`INSERT INTO graph_file_relations (
|
|
17603
|
-
|
|
17604
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
18348
|
+
stash_root, file_path, body_hash, relation_order, from_entity_norm, from_entity, to_entity_norm, to_entity, relation_type, confidence
|
|
18349
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
17605
18350
|
const quality = graph.quality;
|
|
17606
18351
|
const telemetry = graph.telemetry;
|
|
17607
18352
|
db.transaction(() => {
|
|
@@ -17610,44 +18355,35 @@ function replaceStoredGraph(db, graph) {
|
|
|
17610
18355
|
const existingByPath = new Map;
|
|
17611
18356
|
for (const row of existingRows)
|
|
17612
18357
|
existingByPath.set(row.file_path, row);
|
|
17613
|
-
|
|
17614
|
-
const presentEntryIds = new Set;
|
|
18358
|
+
const presentPaths = new Set;
|
|
17615
18359
|
for (const [fileOrder, node] of graph.files.entries()) {
|
|
17616
18360
|
const bodyHash = node.bodyHash && node.bodyHash.length > 0 ? node.bodyHash : "";
|
|
17617
|
-
|
|
17618
|
-
if (entryId == null) {
|
|
17619
|
-
orphanCount += 1;
|
|
17620
|
-
continue;
|
|
17621
|
-
}
|
|
17622
|
-
presentEntryIds.add(entryId);
|
|
18361
|
+
presentPaths.add(node.path);
|
|
17623
18362
|
const existing = existingByPath.get(node.path);
|
|
17624
|
-
if (existing && existing.
|
|
17625
|
-
updateFileMeta.run(fileOrder, node.type, node.confidence ?? null, node.status ?? (node.entities.length > 0 ? "extracted" : "empty"), node.reason ?? (node.entities.length > 0 ? "none" : "no_graph_content"), node.extractionRunId ?? telemetry?.extractionRunId ?? null,
|
|
18363
|
+
if (existing && existing.body_hash === bodyHash) {
|
|
18364
|
+
updateFileMeta.run(fileOrder, node.type, node.confidence ?? null, node.status ?? (node.entities.length > 0 ? "extracted" : "empty"), node.reason ?? (node.entities.length > 0 ? "none" : "no_graph_content"), node.extractionRunId ?? telemetry?.extractionRunId ?? null, graph.stashRoot, node.path, bodyHash);
|
|
17626
18365
|
continue;
|
|
17627
18366
|
}
|
|
17628
18367
|
if (existing) {
|
|
17629
|
-
deleteEntities.run(existing.
|
|
17630
|
-
deleteRelations.run(existing.
|
|
17631
|
-
deleteFile.run(existing.
|
|
18368
|
+
deleteEntities.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
18369
|
+
deleteRelations.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
18370
|
+
deleteFile.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
17632
18371
|
}
|
|
17633
|
-
insertFile.run(
|
|
18372
|
+
insertFile.run(graph.stashRoot, node.path, fileOrder, node.type, bodyHash, node.confidence ?? null, node.status ?? (node.entities.length > 0 ? "extracted" : "empty"), node.reason ?? (node.entities.length > 0 ? "none" : "no_graph_content"), node.extractionRunId ?? telemetry?.extractionRunId ?? null);
|
|
17634
18373
|
for (const [entityOrder, entity] of node.entities.entries()) {
|
|
17635
|
-
insertEntity.run(
|
|
18374
|
+
insertEntity.run(graph.stashRoot, node.path, bodyHash, entityOrder, normalizeEntity(entity), entity);
|
|
17636
18375
|
}
|
|
17637
18376
|
for (const [relationOrder, relation] of node.relations.entries()) {
|
|
17638
|
-
insertRelation.run(
|
|
18377
|
+
insertRelation.run(graph.stashRoot, node.path, bodyHash, relationOrder, normalizeEntity(relation.from), relation.from, normalizeEntity(relation.to), relation.to, relation.type ?? null, relation.confidence ?? null);
|
|
17639
18378
|
}
|
|
17640
18379
|
}
|
|
17641
18380
|
for (const row of existingRows) {
|
|
17642
|
-
if (!
|
|
17643
|
-
deleteEntities.run(row.
|
|
17644
|
-
deleteRelations.run(row.
|
|
17645
|
-
deleteFile.run(row.
|
|
18381
|
+
if (!presentPaths.has(row.file_path)) {
|
|
18382
|
+
deleteEntities.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
18383
|
+
deleteRelations.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
18384
|
+
deleteFile.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
17646
18385
|
}
|
|
17647
18386
|
}
|
|
17648
|
-
if (orphanCount > 0) {
|
|
17649
|
-
warn(`[graph] replaceStoredGraph: skipped ${orphanCount} file(s) with no resolvable entry under ${graph.stashRoot}.`);
|
|
17650
|
-
}
|
|
17651
18387
|
})();
|
|
17652
18388
|
}
|
|
17653
18389
|
function deleteStoredGraph(db, stashPath) {
|
|
@@ -17656,6 +18392,44 @@ function deleteStoredGraph(db, stashPath) {
|
|
|
17656
18392
|
db.prepare("DELETE FROM graph_meta WHERE stash_root = ?").run(stashPath);
|
|
17657
18393
|
})();
|
|
17658
18394
|
}
|
|
18395
|
+
function hasGraphData(db, stashRoot, filePath) {
|
|
18396
|
+
try {
|
|
18397
|
+
const row = db.prepare("SELECT 1 AS present FROM graph_files WHERE stash_root = ? AND file_path = ? LIMIT 1").get(stashRoot, filePath);
|
|
18398
|
+
return row !== undefined;
|
|
18399
|
+
} catch {
|
|
18400
|
+
return false;
|
|
18401
|
+
}
|
|
18402
|
+
}
|
|
18403
|
+
function enqueueGraphExtraction(db, stashRoot, filePath, bodyHash, priority = 0) {
|
|
18404
|
+
try {
|
|
18405
|
+
db.prepare(`INSERT INTO graph_extraction_queue (stash_root, file_path, body_hash, priority)
|
|
18406
|
+
VALUES (?, ?, ?, ?)
|
|
18407
|
+
ON CONFLICT(stash_root, file_path) DO UPDATE SET
|
|
18408
|
+
body_hash = excluded.body_hash,
|
|
18409
|
+
priority = MAX(graph_extraction_queue.priority, excluded.priority),
|
|
18410
|
+
queued_at = datetime('now')`).run(stashRoot, filePath, bodyHash, priority);
|
|
18411
|
+
} catch (err) {
|
|
18412
|
+
rethrowIfTestIsolationError(err);
|
|
18413
|
+
}
|
|
18414
|
+
}
|
|
18415
|
+
function drainExtractionQueue(db, stashRoot, limit) {
|
|
18416
|
+
try {
|
|
18417
|
+
return db.transaction(() => {
|
|
18418
|
+
const rows = db.prepare(`SELECT file_path, body_hash, priority
|
|
18419
|
+
FROM graph_extraction_queue
|
|
18420
|
+
WHERE stash_root = ?
|
|
18421
|
+
ORDER BY priority DESC, queued_at ASC
|
|
18422
|
+
LIMIT ?`).all(stashRoot, limit);
|
|
18423
|
+
const del = db.prepare("DELETE FROM graph_extraction_queue WHERE stash_root = ? AND file_path = ?");
|
|
18424
|
+
for (const row of rows)
|
|
18425
|
+
del.run(stashRoot, row.file_path);
|
|
18426
|
+
return rows.map((row) => ({ filePath: row.file_path, bodyHash: row.body_hash, priority: row.priority }));
|
|
18427
|
+
})();
|
|
18428
|
+
} catch (err) {
|
|
18429
|
+
rethrowIfTestIsolationError(err);
|
|
18430
|
+
return [];
|
|
18431
|
+
}
|
|
18432
|
+
}
|
|
17659
18433
|
function loadGraphMetaOnly(stashPath, db) {
|
|
17660
18434
|
return loadStoredGraphMeta(stashPath, db);
|
|
17661
18435
|
}
|
|
@@ -17663,12 +18437,11 @@ function loadGraphFilesOnly(stashPath, db) {
|
|
|
17663
18437
|
try {
|
|
17664
18438
|
return withReadableGraphDb(db, (readDb) => {
|
|
17665
18439
|
try {
|
|
17666
|
-
const rows = readDb.prepare(`SELECT
|
|
18440
|
+
const rows = readDb.prepare(`SELECT file_path, file_type, body_hash, confidence, status, reason
|
|
17667
18441
|
FROM graph_files
|
|
17668
18442
|
WHERE stash_root = ?
|
|
17669
18443
|
ORDER BY file_order`).all(stashPath);
|
|
17670
18444
|
return rows.map((row) => ({
|
|
17671
|
-
entryId: row.entry_id,
|
|
17672
18445
|
path: row.file_path,
|
|
17673
18446
|
type: row.file_type,
|
|
17674
18447
|
bodyHash: row.body_hash,
|
|
@@ -17685,9 +18458,11 @@ function loadGraphFilesOnly(stashPath, db) {
|
|
|
17685
18458
|
return [];
|
|
17686
18459
|
}
|
|
17687
18460
|
}
|
|
17688
|
-
function
|
|
18461
|
+
function loadGraphEntitiesByPath(db, stashRoot, filePath, bodyHash) {
|
|
17689
18462
|
try {
|
|
17690
|
-
const rows = db.prepare(
|
|
18463
|
+
const rows = db.prepare(`SELECT entity FROM graph_file_entities
|
|
18464
|
+
WHERE stash_root = ? AND file_path = ? AND body_hash = ?
|
|
18465
|
+
ORDER BY entity_order`).all(stashRoot, filePath, bodyHash);
|
|
17691
18466
|
return rows.map((r) => r.entity);
|
|
17692
18467
|
} catch {
|
|
17693
18468
|
return [];
|
|
@@ -17762,23 +18537,28 @@ function loadStoredGraphSnapshot(stashPath, db) {
|
|
|
17762
18537
|
if (!meta)
|
|
17763
18538
|
return null;
|
|
17764
18539
|
try {
|
|
17765
|
-
const fileRows = readDb.prepare(`SELECT
|
|
18540
|
+
const fileRows = readDb.prepare(`SELECT file_path, file_type, body_hash, confidence, status, reason, extraction_run_id
|
|
17766
18541
|
FROM graph_files
|
|
17767
18542
|
WHERE stash_root = ?
|
|
17768
18543
|
ORDER BY file_order`).all(stashPath);
|
|
17769
|
-
const entityRows = readDb.prepare(`SELECT
|
|
18544
|
+
const entityRows = readDb.prepare(`SELECT gf.file_path AS file_path, gfe.entity AS entity
|
|
17770
18545
|
FROM graph_file_entities gfe
|
|
17771
|
-
JOIN graph_files gf
|
|
18546
|
+
JOIN graph_files gf
|
|
18547
|
+
ON gf.stash_root = gfe.stash_root
|
|
18548
|
+
AND gf.file_path = gfe.file_path
|
|
18549
|
+
AND gf.body_hash = gfe.body_hash
|
|
17772
18550
|
WHERE gf.stash_root = ?
|
|
17773
18551
|
ORDER BY gf.file_order, gfe.entity_order`).all(stashPath);
|
|
17774
|
-
const relationRows = readDb.prepare(`SELECT
|
|
17775
|
-
gf.file_path AS file_path,
|
|
18552
|
+
const relationRows = readDb.prepare(`SELECT gf.file_path AS file_path,
|
|
17776
18553
|
gfr.from_entity AS from_entity,
|
|
17777
18554
|
gfr.to_entity AS to_entity,
|
|
17778
18555
|
gfr.relation_type AS relation_type,
|
|
17779
18556
|
gfr.confidence AS confidence
|
|
17780
18557
|
FROM graph_file_relations gfr
|
|
17781
|
-
JOIN graph_files gf
|
|
18558
|
+
JOIN graph_files gf
|
|
18559
|
+
ON gf.stash_root = gfr.stash_root
|
|
18560
|
+
AND gf.file_path = gfr.file_path
|
|
18561
|
+
AND gf.body_hash = gfr.body_hash
|
|
17782
18562
|
WHERE gf.stash_root = ?
|
|
17783
18563
|
ORDER BY gf.file_order, gfr.relation_order`).all(stashPath);
|
|
17784
18564
|
const entitiesByPath = new Map;
|
|
@@ -17837,7 +18617,6 @@ function loadStoredGraphSnapshot(stashPath, db) {
|
|
|
17837
18617
|
var init_graph_db = __esm(() => {
|
|
17838
18618
|
init_errors();
|
|
17839
18619
|
init_paths();
|
|
17840
|
-
init_warn();
|
|
17841
18620
|
init_db();
|
|
17842
18621
|
});
|
|
17843
18622
|
|