claude-memory-layer 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +15 -0
- package/.history/package_20260201114632.json +46 -0
- package/dist/cli/index.js +360 -154
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +337 -161
- package/dist/core/index.js.map +3 -3
- package/dist/hooks/session-end.js +320 -130
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +331 -138
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +320 -130
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +320 -130
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/services/memory-service.js +349 -128
- package/dist/services/memory-service.js.map +4 -4
- package/package.json +1 -1
- package/src/cli/index.ts +84 -23
- package/src/core/consolidated-store.ts +33 -18
- package/src/core/continuity-manager.ts +12 -7
- package/src/core/db-wrapper.ts +112 -0
- package/src/core/edge-repo.ts +22 -13
- package/src/core/entity-repo.ts +23 -14
- package/src/core/event-store.ts +98 -72
- package/src/core/task/blocker-resolver.ts +17 -9
- package/src/core/task/task-matcher.ts +8 -6
- package/src/core/task/task-projector.ts +29 -16
- package/src/core/task/task-resolver.ts +17 -9
- package/src/core/vector-outbox.ts +29 -16
- package/src/core/vector-store.ts +23 -12
- package/src/core/vector-worker.ts +7 -4
- package/src/core/working-set-store.ts +31 -18
- package/src/hooks/session-end.ts +3 -2
- package/src/hooks/session-start.ts +12 -8
- package/src/hooks/stop.ts +3 -2
- package/src/hooks/user-prompt-submit.ts +3 -2
- package/src/services/memory-service.ts +158 -6
package/dist/core/index.js
CHANGED
|
@@ -572,12 +572,94 @@ function parseEntityCanonicalKey(canonicalKey) {
|
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
// src/core/event-store.ts
|
|
575
|
-
import { Database } from "duckdb";
|
|
576
575
|
import { randomUUID } from "crypto";
|
|
576
|
+
|
|
577
|
+
// src/core/db-wrapper.ts
|
|
578
|
+
import duckdb from "duckdb";
|
|
579
|
+
function convertBigInts(obj) {
|
|
580
|
+
if (obj === null || obj === void 0)
|
|
581
|
+
return obj;
|
|
582
|
+
if (typeof obj === "bigint")
|
|
583
|
+
return Number(obj);
|
|
584
|
+
if (obj instanceof Date)
|
|
585
|
+
return obj;
|
|
586
|
+
if (Array.isArray(obj))
|
|
587
|
+
return obj.map(convertBigInts);
|
|
588
|
+
if (typeof obj === "object") {
|
|
589
|
+
const result = {};
|
|
590
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
591
|
+
result[key] = convertBigInts(value);
|
|
592
|
+
}
|
|
593
|
+
return result;
|
|
594
|
+
}
|
|
595
|
+
return obj;
|
|
596
|
+
}
|
|
597
|
+
function toDate(value) {
|
|
598
|
+
if (value instanceof Date)
|
|
599
|
+
return value;
|
|
600
|
+
if (typeof value === "string")
|
|
601
|
+
return new Date(value);
|
|
602
|
+
if (typeof value === "number")
|
|
603
|
+
return new Date(value);
|
|
604
|
+
return new Date(String(value));
|
|
605
|
+
}
|
|
606
|
+
function createDatabase(path) {
|
|
607
|
+
return new duckdb.Database(path);
|
|
608
|
+
}
|
|
609
|
+
function dbRun(db, sql, params = []) {
|
|
610
|
+
return new Promise((resolve, reject) => {
|
|
611
|
+
if (params.length === 0) {
|
|
612
|
+
db.run(sql, (err) => {
|
|
613
|
+
if (err)
|
|
614
|
+
reject(err);
|
|
615
|
+
else
|
|
616
|
+
resolve();
|
|
617
|
+
});
|
|
618
|
+
} else {
|
|
619
|
+
db.run(sql, ...params, (err) => {
|
|
620
|
+
if (err)
|
|
621
|
+
reject(err);
|
|
622
|
+
else
|
|
623
|
+
resolve();
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
function dbAll(db, sql, params = []) {
|
|
629
|
+
return new Promise((resolve, reject) => {
|
|
630
|
+
if (params.length === 0) {
|
|
631
|
+
db.all(sql, (err, rows) => {
|
|
632
|
+
if (err)
|
|
633
|
+
reject(err);
|
|
634
|
+
else
|
|
635
|
+
resolve(convertBigInts(rows || []));
|
|
636
|
+
});
|
|
637
|
+
} else {
|
|
638
|
+
db.all(sql, ...params, (err, rows) => {
|
|
639
|
+
if (err)
|
|
640
|
+
reject(err);
|
|
641
|
+
else
|
|
642
|
+
resolve(convertBigInts(rows || []));
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
function dbClose(db) {
|
|
648
|
+
return new Promise((resolve, reject) => {
|
|
649
|
+
db.close((err) => {
|
|
650
|
+
if (err)
|
|
651
|
+
reject(err);
|
|
652
|
+
else
|
|
653
|
+
resolve();
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/core/event-store.ts
|
|
577
659
|
var EventStore = class {
|
|
578
660
|
constructor(dbPath) {
|
|
579
661
|
this.dbPath = dbPath;
|
|
580
|
-
this.db =
|
|
662
|
+
this.db = createDatabase(dbPath);
|
|
581
663
|
}
|
|
582
664
|
db;
|
|
583
665
|
initialized = false;
|
|
@@ -587,7 +669,7 @@ var EventStore = class {
|
|
|
587
669
|
async initialize() {
|
|
588
670
|
if (this.initialized)
|
|
589
671
|
return;
|
|
590
|
-
await this.db
|
|
672
|
+
await dbRun(this.db, `
|
|
591
673
|
CREATE TABLE IF NOT EXISTS events (
|
|
592
674
|
id VARCHAR PRIMARY KEY,
|
|
593
675
|
event_type VARCHAR NOT NULL,
|
|
@@ -599,14 +681,14 @@ var EventStore = class {
|
|
|
599
681
|
metadata JSON
|
|
600
682
|
)
|
|
601
683
|
`);
|
|
602
|
-
await this.db
|
|
684
|
+
await dbRun(this.db, `
|
|
603
685
|
CREATE TABLE IF NOT EXISTS event_dedup (
|
|
604
686
|
dedupe_key VARCHAR PRIMARY KEY,
|
|
605
687
|
event_id VARCHAR NOT NULL,
|
|
606
688
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
607
689
|
)
|
|
608
690
|
`);
|
|
609
|
-
await this.db
|
|
691
|
+
await dbRun(this.db, `
|
|
610
692
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
611
693
|
id VARCHAR PRIMARY KEY,
|
|
612
694
|
started_at TIMESTAMP NOT NULL,
|
|
@@ -616,7 +698,7 @@ var EventStore = class {
|
|
|
616
698
|
tags JSON
|
|
617
699
|
)
|
|
618
700
|
`);
|
|
619
|
-
await this.db
|
|
701
|
+
await dbRun(this.db, `
|
|
620
702
|
CREATE TABLE IF NOT EXISTS insights (
|
|
621
703
|
id VARCHAR PRIMARY KEY,
|
|
622
704
|
insight_type VARCHAR NOT NULL,
|
|
@@ -628,7 +710,7 @@ var EventStore = class {
|
|
|
628
710
|
last_updated TIMESTAMP
|
|
629
711
|
)
|
|
630
712
|
`);
|
|
631
|
-
await this.db
|
|
713
|
+
await dbRun(this.db, `
|
|
632
714
|
CREATE TABLE IF NOT EXISTS embedding_outbox (
|
|
633
715
|
id VARCHAR PRIMARY KEY,
|
|
634
716
|
event_id VARCHAR NOT NULL,
|
|
@@ -640,7 +722,7 @@ var EventStore = class {
|
|
|
640
722
|
error_message TEXT
|
|
641
723
|
)
|
|
642
724
|
`);
|
|
643
|
-
await this.db
|
|
725
|
+
await dbRun(this.db, `
|
|
644
726
|
CREATE TABLE IF NOT EXISTS projection_offsets (
|
|
645
727
|
projection_name VARCHAR PRIMARY KEY,
|
|
646
728
|
last_event_id VARCHAR,
|
|
@@ -648,14 +730,14 @@ var EventStore = class {
|
|
|
648
730
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
649
731
|
)
|
|
650
732
|
`);
|
|
651
|
-
await this.db
|
|
733
|
+
await dbRun(this.db, `
|
|
652
734
|
CREATE TABLE IF NOT EXISTS memory_levels (
|
|
653
735
|
event_id VARCHAR PRIMARY KEY,
|
|
654
736
|
level VARCHAR NOT NULL DEFAULT 'L0',
|
|
655
737
|
promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
656
738
|
)
|
|
657
739
|
`);
|
|
658
|
-
await this.db
|
|
740
|
+
await dbRun(this.db, `
|
|
659
741
|
CREATE TABLE IF NOT EXISTS entries (
|
|
660
742
|
entry_id VARCHAR PRIMARY KEY,
|
|
661
743
|
created_ts TIMESTAMP NOT NULL,
|
|
@@ -671,7 +753,7 @@ var EventStore = class {
|
|
|
671
753
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
672
754
|
)
|
|
673
755
|
`);
|
|
674
|
-
await this.db
|
|
756
|
+
await dbRun(this.db, `
|
|
675
757
|
CREATE TABLE IF NOT EXISTS entities (
|
|
676
758
|
entity_id VARCHAR PRIMARY KEY,
|
|
677
759
|
entity_type VARCHAR NOT NULL,
|
|
@@ -686,7 +768,7 @@ var EventStore = class {
|
|
|
686
768
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
687
769
|
)
|
|
688
770
|
`);
|
|
689
|
-
await this.db
|
|
771
|
+
await dbRun(this.db, `
|
|
690
772
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
691
773
|
entity_type VARCHAR NOT NULL,
|
|
692
774
|
canonical_key VARCHAR NOT NULL,
|
|
@@ -696,7 +778,7 @@ var EventStore = class {
|
|
|
696
778
|
PRIMARY KEY(entity_type, canonical_key)
|
|
697
779
|
)
|
|
698
780
|
`);
|
|
699
|
-
await this.db
|
|
781
|
+
await dbRun(this.db, `
|
|
700
782
|
CREATE TABLE IF NOT EXISTS edges (
|
|
701
783
|
edge_id VARCHAR PRIMARY KEY,
|
|
702
784
|
src_type VARCHAR NOT NULL,
|
|
@@ -708,7 +790,7 @@ var EventStore = class {
|
|
|
708
790
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
709
791
|
)
|
|
710
792
|
`);
|
|
711
|
-
await this.db
|
|
793
|
+
await dbRun(this.db, `
|
|
712
794
|
CREATE TABLE IF NOT EXISTS vector_outbox (
|
|
713
795
|
job_id VARCHAR PRIMARY KEY,
|
|
714
796
|
item_kind VARCHAR NOT NULL,
|
|
@@ -722,7 +804,7 @@ var EventStore = class {
|
|
|
722
804
|
UNIQUE(item_kind, item_id, embedding_version)
|
|
723
805
|
)
|
|
724
806
|
`);
|
|
725
|
-
await this.db
|
|
807
|
+
await dbRun(this.db, `
|
|
726
808
|
CREATE TABLE IF NOT EXISTS build_runs (
|
|
727
809
|
build_id VARCHAR PRIMARY KEY,
|
|
728
810
|
started_at TIMESTAMP NOT NULL,
|
|
@@ -737,7 +819,7 @@ var EventStore = class {
|
|
|
737
819
|
error VARCHAR
|
|
738
820
|
)
|
|
739
821
|
`);
|
|
740
|
-
await this.db
|
|
822
|
+
await dbRun(this.db, `
|
|
741
823
|
CREATE TABLE IF NOT EXISTS pipeline_metrics (
|
|
742
824
|
id VARCHAR PRIMARY KEY,
|
|
743
825
|
ts TIMESTAMP NOT NULL,
|
|
@@ -748,7 +830,7 @@ var EventStore = class {
|
|
|
748
830
|
session_id VARCHAR
|
|
749
831
|
)
|
|
750
832
|
`);
|
|
751
|
-
await this.db
|
|
833
|
+
await dbRun(this.db, `
|
|
752
834
|
CREATE TABLE IF NOT EXISTS working_set (
|
|
753
835
|
id VARCHAR PRIMARY KEY,
|
|
754
836
|
event_id VARCHAR NOT NULL,
|
|
@@ -758,7 +840,7 @@ var EventStore = class {
|
|
|
758
840
|
expires_at TIMESTAMP
|
|
759
841
|
)
|
|
760
842
|
`);
|
|
761
|
-
await this.db
|
|
843
|
+
await dbRun(this.db, `
|
|
762
844
|
CREATE TABLE IF NOT EXISTS consolidated_memories (
|
|
763
845
|
memory_id VARCHAR PRIMARY KEY,
|
|
764
846
|
summary TEXT NOT NULL,
|
|
@@ -770,7 +852,7 @@ var EventStore = class {
|
|
|
770
852
|
access_count INTEGER DEFAULT 0
|
|
771
853
|
)
|
|
772
854
|
`);
|
|
773
|
-
await this.db
|
|
855
|
+
await dbRun(this.db, `
|
|
774
856
|
CREATE TABLE IF NOT EXISTS continuity_log (
|
|
775
857
|
log_id VARCHAR PRIMARY KEY,
|
|
776
858
|
from_context_id VARCHAR,
|
|
@@ -780,26 +862,26 @@ var EventStore = class {
|
|
|
780
862
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
781
863
|
)
|
|
782
864
|
`);
|
|
783
|
-
await this.db
|
|
865
|
+
await dbRun(this.db, `
|
|
784
866
|
CREATE TABLE IF NOT EXISTS endless_config (
|
|
785
867
|
key VARCHAR PRIMARY KEY,
|
|
786
868
|
value JSON,
|
|
787
869
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
788
870
|
)
|
|
789
871
|
`);
|
|
790
|
-
await this.db
|
|
791
|
-
await this.db
|
|
792
|
-
await this.db
|
|
793
|
-
await this.db
|
|
794
|
-
await this.db
|
|
795
|
-
await this.db
|
|
796
|
-
await this.db
|
|
797
|
-
await this.db
|
|
798
|
-
await this.db
|
|
799
|
-
await this.db
|
|
800
|
-
await this.db
|
|
801
|
-
await this.db
|
|
802
|
-
await this.db
|
|
872
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(entry_type)`);
|
|
873
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_stage ON entries(stage)`);
|
|
874
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_canonical ON entries(canonical_key)`);
|
|
875
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_type_key ON entities(entity_type, canonical_key)`);
|
|
876
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status)`);
|
|
877
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src_id, rel_type)`);
|
|
878
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst_id, rel_type)`);
|
|
879
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_rel ON edges(rel_type)`);
|
|
880
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_outbox_status ON vector_outbox(status)`);
|
|
881
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_expires ON working_set(expires_at)`);
|
|
882
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_relevance ON working_set(relevance_score DESC)`);
|
|
883
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence DESC)`);
|
|
884
|
+
await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at)`);
|
|
803
885
|
this.initialized = true;
|
|
804
886
|
}
|
|
805
887
|
/**
|
|
@@ -810,7 +892,8 @@ var EventStore = class {
|
|
|
810
892
|
await this.initialize();
|
|
811
893
|
const canonicalKey = makeCanonicalKey(input.content);
|
|
812
894
|
const dedupeKey = makeDedupeKey(input.content, input.sessionId);
|
|
813
|
-
const existing = await
|
|
895
|
+
const existing = await dbAll(
|
|
896
|
+
this.db,
|
|
814
897
|
`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,
|
|
815
898
|
[dedupeKey]
|
|
816
899
|
);
|
|
@@ -824,7 +907,8 @@ var EventStore = class {
|
|
|
824
907
|
const id = randomUUID();
|
|
825
908
|
const timestamp = input.timestamp.toISOString();
|
|
826
909
|
try {
|
|
827
|
-
await
|
|
910
|
+
await dbRun(
|
|
911
|
+
this.db,
|
|
828
912
|
`INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata)
|
|
829
913
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
830
914
|
[
|
|
@@ -838,11 +922,13 @@ var EventStore = class {
|
|
|
838
922
|
JSON.stringify(input.metadata || {})
|
|
839
923
|
]
|
|
840
924
|
);
|
|
841
|
-
await
|
|
925
|
+
await dbRun(
|
|
926
|
+
this.db,
|
|
842
927
|
`INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)`,
|
|
843
928
|
[dedupeKey, id]
|
|
844
929
|
);
|
|
845
|
-
await
|
|
930
|
+
await dbRun(
|
|
931
|
+
this.db,
|
|
846
932
|
`INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')`,
|
|
847
933
|
[id]
|
|
848
934
|
);
|
|
@@ -859,7 +945,8 @@ var EventStore = class {
|
|
|
859
945
|
*/
|
|
860
946
|
async getSessionEvents(sessionId) {
|
|
861
947
|
await this.initialize();
|
|
862
|
-
const rows = await
|
|
948
|
+
const rows = await dbAll(
|
|
949
|
+
this.db,
|
|
863
950
|
`SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
|
|
864
951
|
[sessionId]
|
|
865
952
|
);
|
|
@@ -870,7 +957,8 @@ var EventStore = class {
|
|
|
870
957
|
*/
|
|
871
958
|
async getRecentEvents(limit = 100) {
|
|
872
959
|
await this.initialize();
|
|
873
|
-
const rows = await
|
|
960
|
+
const rows = await dbAll(
|
|
961
|
+
this.db,
|
|
874
962
|
`SELECT * FROM events ORDER BY timestamp DESC LIMIT ?`,
|
|
875
963
|
[limit]
|
|
876
964
|
);
|
|
@@ -881,7 +969,8 @@ var EventStore = class {
|
|
|
881
969
|
*/
|
|
882
970
|
async getEvent(id) {
|
|
883
971
|
await this.initialize();
|
|
884
|
-
const rows = await
|
|
972
|
+
const rows = await dbAll(
|
|
973
|
+
this.db,
|
|
885
974
|
`SELECT * FROM events WHERE id = ?`,
|
|
886
975
|
[id]
|
|
887
976
|
);
|
|
@@ -894,12 +983,14 @@ var EventStore = class {
|
|
|
894
983
|
*/
|
|
895
984
|
async upsertSession(session) {
|
|
896
985
|
await this.initialize();
|
|
897
|
-
const existing = await
|
|
986
|
+
const existing = await dbAll(
|
|
987
|
+
this.db,
|
|
898
988
|
`SELECT id FROM sessions WHERE id = ?`,
|
|
899
989
|
[session.id]
|
|
900
990
|
);
|
|
901
991
|
if (existing.length === 0) {
|
|
902
|
-
await
|
|
992
|
+
await dbRun(
|
|
993
|
+
this.db,
|
|
903
994
|
`INSERT INTO sessions (id, started_at, project_path, tags)
|
|
904
995
|
VALUES (?, ?, ?, ?)`,
|
|
905
996
|
[
|
|
@@ -926,7 +1017,8 @@ var EventStore = class {
|
|
|
926
1017
|
}
|
|
927
1018
|
if (updates.length > 0) {
|
|
928
1019
|
values.push(session.id);
|
|
929
|
-
await
|
|
1020
|
+
await dbRun(
|
|
1021
|
+
this.db,
|
|
930
1022
|
`UPDATE sessions SET ${updates.join(", ")} WHERE id = ?`,
|
|
931
1023
|
values
|
|
932
1024
|
);
|
|
@@ -938,7 +1030,8 @@ var EventStore = class {
|
|
|
938
1030
|
*/
|
|
939
1031
|
async getSession(id) {
|
|
940
1032
|
await this.initialize();
|
|
941
|
-
const rows = await
|
|
1033
|
+
const rows = await dbAll(
|
|
1034
|
+
this.db,
|
|
942
1035
|
`SELECT * FROM sessions WHERE id = ?`,
|
|
943
1036
|
[id]
|
|
944
1037
|
);
|
|
@@ -947,8 +1040,8 @@ var EventStore = class {
|
|
|
947
1040
|
const row = rows[0];
|
|
948
1041
|
return {
|
|
949
1042
|
id: row.id,
|
|
950
|
-
startedAt:
|
|
951
|
-
endedAt: row.ended_at ?
|
|
1043
|
+
startedAt: toDate(row.started_at),
|
|
1044
|
+
endedAt: row.ended_at ? toDate(row.ended_at) : void 0,
|
|
952
1045
|
projectPath: row.project_path,
|
|
953
1046
|
summary: row.summary,
|
|
954
1047
|
tags: row.tags ? JSON.parse(row.tags) : void 0
|
|
@@ -960,7 +1053,8 @@ var EventStore = class {
|
|
|
960
1053
|
async enqueueForEmbedding(eventId, content) {
|
|
961
1054
|
await this.initialize();
|
|
962
1055
|
const id = randomUUID();
|
|
963
|
-
await
|
|
1056
|
+
await dbRun(
|
|
1057
|
+
this.db,
|
|
964
1058
|
`INSERT INTO embedding_outbox (id, event_id, content, status, retry_count)
|
|
965
1059
|
VALUES (?, ?, ?, 'pending', 0)`,
|
|
966
1060
|
[id, eventId, content]
|
|
@@ -972,25 +1066,30 @@ var EventStore = class {
|
|
|
972
1066
|
*/
|
|
973
1067
|
async getPendingOutboxItems(limit = 32) {
|
|
974
1068
|
await this.initialize();
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
WHERE
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
ORDER BY created_at
|
|
982
|
-
LIMIT ?
|
|
983
|
-
)
|
|
984
|
-
RETURNING *`,
|
|
1069
|
+
const pending = await dbAll(
|
|
1070
|
+
this.db,
|
|
1071
|
+
`SELECT * FROM embedding_outbox
|
|
1072
|
+
WHERE status = 'pending'
|
|
1073
|
+
ORDER BY created_at
|
|
1074
|
+
LIMIT ?`,
|
|
985
1075
|
[limit]
|
|
986
1076
|
);
|
|
987
|
-
|
|
1077
|
+
if (pending.length === 0)
|
|
1078
|
+
return [];
|
|
1079
|
+
const ids = pending.map((r) => r.id);
|
|
1080
|
+
const placeholders = ids.map(() => "?").join(",");
|
|
1081
|
+
await dbRun(
|
|
1082
|
+
this.db,
|
|
1083
|
+
`UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,
|
|
1084
|
+
ids
|
|
1085
|
+
);
|
|
1086
|
+
return pending.map((row) => ({
|
|
988
1087
|
id: row.id,
|
|
989
1088
|
eventId: row.event_id,
|
|
990
1089
|
content: row.content,
|
|
991
|
-
status:
|
|
1090
|
+
status: "processing",
|
|
992
1091
|
retryCount: row.retry_count,
|
|
993
|
-
createdAt:
|
|
1092
|
+
createdAt: toDate(row.created_at),
|
|
994
1093
|
errorMessage: row.error_message
|
|
995
1094
|
}));
|
|
996
1095
|
}
|
|
@@ -1001,7 +1100,8 @@ var EventStore = class {
|
|
|
1001
1100
|
if (ids.length === 0)
|
|
1002
1101
|
return;
|
|
1003
1102
|
const placeholders = ids.map(() => "?").join(",");
|
|
1004
|
-
await
|
|
1103
|
+
await dbRun(
|
|
1104
|
+
this.db,
|
|
1005
1105
|
`DELETE FROM embedding_outbox WHERE id IN (${placeholders})`,
|
|
1006
1106
|
ids
|
|
1007
1107
|
);
|
|
@@ -1013,7 +1113,8 @@ var EventStore = class {
|
|
|
1013
1113
|
if (ids.length === 0)
|
|
1014
1114
|
return;
|
|
1015
1115
|
const placeholders = ids.map(() => "?").join(",");
|
|
1016
|
-
await
|
|
1116
|
+
await dbRun(
|
|
1117
|
+
this.db,
|
|
1017
1118
|
`UPDATE embedding_outbox
|
|
1018
1119
|
SET status = CASE WHEN retry_count >= 3 THEN 'failed' ELSE 'pending' END,
|
|
1019
1120
|
retry_count = retry_count + 1,
|
|
@@ -1027,7 +1128,8 @@ var EventStore = class {
|
|
|
1027
1128
|
*/
|
|
1028
1129
|
async updateMemoryLevel(eventId, level) {
|
|
1029
1130
|
await this.initialize();
|
|
1030
|
-
await
|
|
1131
|
+
await dbRun(
|
|
1132
|
+
this.db,
|
|
1031
1133
|
`UPDATE memory_levels SET level = ?, promoted_at = CURRENT_TIMESTAMP WHERE event_id = ?`,
|
|
1032
1134
|
[level, eventId]
|
|
1033
1135
|
);
|
|
@@ -1037,7 +1139,8 @@ var EventStore = class {
|
|
|
1037
1139
|
*/
|
|
1038
1140
|
async getLevelStats() {
|
|
1039
1141
|
await this.initialize();
|
|
1040
|
-
const rows = await
|
|
1142
|
+
const rows = await dbAll(
|
|
1143
|
+
this.db,
|
|
1041
1144
|
`SELECT level, COUNT(*) as count FROM memory_levels GROUP BY level`
|
|
1042
1145
|
);
|
|
1043
1146
|
return rows;
|
|
@@ -1056,7 +1159,8 @@ var EventStore = class {
|
|
|
1056
1159
|
*/
|
|
1057
1160
|
async getEndlessConfig(key) {
|
|
1058
1161
|
await this.initialize();
|
|
1059
|
-
const rows = await
|
|
1162
|
+
const rows = await dbAll(
|
|
1163
|
+
this.db,
|
|
1060
1164
|
`SELECT value FROM endless_config WHERE key = ?`,
|
|
1061
1165
|
[key]
|
|
1062
1166
|
);
|
|
@@ -1069,7 +1173,8 @@ var EventStore = class {
|
|
|
1069
1173
|
*/
|
|
1070
1174
|
async setEndlessConfig(key, value) {
|
|
1071
1175
|
await this.initialize();
|
|
1072
|
-
await
|
|
1176
|
+
await dbRun(
|
|
1177
|
+
this.db,
|
|
1073
1178
|
`INSERT OR REPLACE INTO endless_config (key, value, updated_at)
|
|
1074
1179
|
VALUES (?, ?, CURRENT_TIMESTAMP)`,
|
|
1075
1180
|
[key, JSON.stringify(value)]
|
|
@@ -1080,13 +1185,14 @@ var EventStore = class {
|
|
|
1080
1185
|
*/
|
|
1081
1186
|
async getAllSessions() {
|
|
1082
1187
|
await this.initialize();
|
|
1083
|
-
const rows = await
|
|
1188
|
+
const rows = await dbAll(
|
|
1189
|
+
this.db,
|
|
1084
1190
|
`SELECT * FROM sessions ORDER BY started_at DESC`
|
|
1085
1191
|
);
|
|
1086
1192
|
return rows.map((row) => ({
|
|
1087
1193
|
id: row.id,
|
|
1088
|
-
startedAt:
|
|
1089
|
-
endedAt: row.ended_at ?
|
|
1194
|
+
startedAt: toDate(row.started_at),
|
|
1195
|
+
endedAt: row.ended_at ? toDate(row.ended_at) : void 0,
|
|
1090
1196
|
projectPath: row.project_path,
|
|
1091
1197
|
summary: row.summary,
|
|
1092
1198
|
tags: row.tags ? JSON.parse(row.tags) : void 0
|
|
@@ -1096,7 +1202,7 @@ var EventStore = class {
|
|
|
1096
1202
|
* Close database connection
|
|
1097
1203
|
*/
|
|
1098
1204
|
async close() {
|
|
1099
|
-
await this.db
|
|
1205
|
+
await dbClose(this.db);
|
|
1100
1206
|
}
|
|
1101
1207
|
/**
|
|
1102
1208
|
* Convert database row to MemoryEvent
|
|
@@ -1106,7 +1212,7 @@ var EventStore = class {
|
|
|
1106
1212
|
id: row.id,
|
|
1107
1213
|
eventType: row.event_type,
|
|
1108
1214
|
sessionId: row.session_id,
|
|
1109
|
-
timestamp:
|
|
1215
|
+
timestamp: toDate(row.timestamp),
|
|
1110
1216
|
content: row.content,
|
|
1111
1217
|
canonicalKey: row.canonical_key,
|
|
1112
1218
|
dedupeKey: row.dedupe_key,
|
|
@@ -1132,7 +1238,8 @@ var EntityRepo = class {
|
|
|
1132
1238
|
const titleNorm = input.title.toLowerCase().trim();
|
|
1133
1239
|
const searchText = `${input.title} ${JSON.stringify(input.currentJson)}`;
|
|
1134
1240
|
const now = /* @__PURE__ */ new Date();
|
|
1135
|
-
await
|
|
1241
|
+
await dbRun(
|
|
1242
|
+
this.db,
|
|
1136
1243
|
`INSERT INTO entities (
|
|
1137
1244
|
entity_id, entity_type, canonical_key, title, stage, status,
|
|
1138
1245
|
current_json, title_norm, search_text, created_at, updated_at
|
|
@@ -1151,7 +1258,8 @@ var EntityRepo = class {
|
|
|
1151
1258
|
now.toISOString()
|
|
1152
1259
|
]
|
|
1153
1260
|
);
|
|
1154
|
-
await
|
|
1261
|
+
await dbRun(
|
|
1262
|
+
this.db,
|
|
1155
1263
|
`INSERT INTO entity_aliases (entity_type, canonical_key, entity_id, is_primary)
|
|
1156
1264
|
VALUES (?, ?, ?, TRUE)
|
|
1157
1265
|
ON CONFLICT (entity_type, canonical_key) DO NOTHING`,
|
|
@@ -1175,7 +1283,8 @@ var EntityRepo = class {
|
|
|
1175
1283
|
* Find entity by ID
|
|
1176
1284
|
*/
|
|
1177
1285
|
async findById(entityId) {
|
|
1178
|
-
const rows = await
|
|
1286
|
+
const rows = await dbAll(
|
|
1287
|
+
this.db,
|
|
1179
1288
|
`SELECT * FROM entities WHERE entity_id = ?`,
|
|
1180
1289
|
[entityId]
|
|
1181
1290
|
);
|
|
@@ -1187,7 +1296,8 @@ var EntityRepo = class {
|
|
|
1187
1296
|
* Find entity by canonical key
|
|
1188
1297
|
*/
|
|
1189
1298
|
async findByCanonicalKey(entityType, canonicalKey) {
|
|
1190
|
-
const rows = await
|
|
1299
|
+
const rows = await dbAll(
|
|
1300
|
+
this.db,
|
|
1191
1301
|
`SELECT * FROM entities
|
|
1192
1302
|
WHERE entity_type = ? AND canonical_key = ?`,
|
|
1193
1303
|
[entityType, canonicalKey]
|
|
@@ -1238,7 +1348,8 @@ var EntityRepo = class {
|
|
|
1238
1348
|
updates.push("updated_at = ?");
|
|
1239
1349
|
values.push((/* @__PURE__ */ new Date()).toISOString());
|
|
1240
1350
|
values.push(entityId);
|
|
1241
|
-
await
|
|
1351
|
+
await dbRun(
|
|
1352
|
+
this.db,
|
|
1242
1353
|
`UPDATE entities SET ${updates.join(", ")} WHERE entity_id = ?`,
|
|
1243
1354
|
values
|
|
1244
1355
|
);
|
|
@@ -1263,7 +1374,7 @@ var EntityRepo = class {
|
|
|
1263
1374
|
query += ` OFFSET ?`;
|
|
1264
1375
|
params.push(options.offset);
|
|
1265
1376
|
}
|
|
1266
|
-
const rows = await this.db
|
|
1377
|
+
const rows = await dbAll(this.db, query, params);
|
|
1267
1378
|
return rows.map((row) => this.rowToEntity(row));
|
|
1268
1379
|
}
|
|
1269
1380
|
/**
|
|
@@ -1282,14 +1393,15 @@ var EntityRepo = class {
|
|
|
1282
1393
|
sql += ` LIMIT ?`;
|
|
1283
1394
|
params.push(options.limit);
|
|
1284
1395
|
}
|
|
1285
|
-
const rows = await this.db
|
|
1396
|
+
const rows = await dbAll(this.db, sql, params);
|
|
1286
1397
|
return rows.map((row) => this.rowToEntity(row));
|
|
1287
1398
|
}
|
|
1288
1399
|
/**
|
|
1289
1400
|
* Get tasks by status
|
|
1290
1401
|
*/
|
|
1291
1402
|
async getTasksByStatus(status) {
|
|
1292
|
-
const rows = await
|
|
1403
|
+
const rows = await dbAll(
|
|
1404
|
+
this.db,
|
|
1293
1405
|
`SELECT * FROM entities
|
|
1294
1406
|
WHERE entity_type = 'task'
|
|
1295
1407
|
AND json_extract(current_json, '$.status') = ?
|
|
@@ -1306,7 +1418,8 @@ var EntityRepo = class {
|
|
|
1306
1418
|
const tasks = await this.getTasksByStatus("blocked");
|
|
1307
1419
|
const results = [];
|
|
1308
1420
|
for (const task of tasks) {
|
|
1309
|
-
const blockerEdges = await
|
|
1421
|
+
const blockerEdges = await dbAll(
|
|
1422
|
+
this.db,
|
|
1310
1423
|
`SELECT e.dst_id, ent.entity_type, ent.title
|
|
1311
1424
|
FROM edges e
|
|
1312
1425
|
JOIN entities ent ON ent.entity_id = e.dst_id
|
|
@@ -1328,7 +1441,8 @@ var EntityRepo = class {
|
|
|
1328
1441
|
* Add alias for entity
|
|
1329
1442
|
*/
|
|
1330
1443
|
async addAlias(entityType, canonicalKey, entityId) {
|
|
1331
|
-
await
|
|
1444
|
+
await dbRun(
|
|
1445
|
+
this.db,
|
|
1332
1446
|
`INSERT INTO entity_aliases (entity_type, canonical_key, entity_id, is_primary)
|
|
1333
1447
|
VALUES (?, ?, ?, FALSE)
|
|
1334
1448
|
ON CONFLICT (entity_type, canonical_key) DO NOTHING`,
|
|
@@ -1339,7 +1453,8 @@ var EntityRepo = class {
|
|
|
1339
1453
|
* Find entity by alias
|
|
1340
1454
|
*/
|
|
1341
1455
|
async findByAlias(entityType, canonicalKey) {
|
|
1342
|
-
const rows = await
|
|
1456
|
+
const rows = await dbAll(
|
|
1457
|
+
this.db,
|
|
1343
1458
|
`SELECT e.* FROM entities e
|
|
1344
1459
|
JOIN entity_aliases a ON e.entity_id = a.entity_id
|
|
1345
1460
|
WHERE a.entity_type = ? AND a.canonical_key = ?`,
|
|
@@ -1363,8 +1478,8 @@ var EntityRepo = class {
|
|
|
1363
1478
|
currentJson: typeof row.current_json === "string" ? JSON.parse(row.current_json) : row.current_json,
|
|
1364
1479
|
titleNorm: row.title_norm,
|
|
1365
1480
|
searchText: row.search_text,
|
|
1366
|
-
createdAt:
|
|
1367
|
-
updatedAt:
|
|
1481
|
+
createdAt: toDate(row.created_at),
|
|
1482
|
+
updatedAt: toDate(row.updated_at)
|
|
1368
1483
|
};
|
|
1369
1484
|
}
|
|
1370
1485
|
};
|
|
@@ -1381,7 +1496,8 @@ var EdgeRepo = class {
|
|
|
1381
1496
|
async create(input) {
|
|
1382
1497
|
const edgeId = randomUUID3();
|
|
1383
1498
|
const now = /* @__PURE__ */ new Date();
|
|
1384
|
-
await
|
|
1499
|
+
await dbRun(
|
|
1500
|
+
this.db,
|
|
1385
1501
|
`INSERT INTO edges (edge_id, src_type, src_id, rel_type, dst_type, dst_id, meta_json, created_at)
|
|
1386
1502
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1387
1503
|
ON CONFLICT DO NOTHING`,
|
|
@@ -1419,7 +1535,8 @@ var EdgeRepo = class {
|
|
|
1419
1535
|
input.dstId
|
|
1420
1536
|
);
|
|
1421
1537
|
if (existing) {
|
|
1422
|
-
await
|
|
1538
|
+
await dbRun(
|
|
1539
|
+
this.db,
|
|
1423
1540
|
`UPDATE edges SET meta_json = ? WHERE edge_id = ?`,
|
|
1424
1541
|
[JSON.stringify(input.metaJson ?? {}), existing.edgeId]
|
|
1425
1542
|
);
|
|
@@ -1431,7 +1548,8 @@ var EdgeRepo = class {
|
|
|
1431
1548
|
* Find edge by endpoints
|
|
1432
1549
|
*/
|
|
1433
1550
|
async findByEndpoints(srcType, srcId, relType, dstType, dstId) {
|
|
1434
|
-
const rows = await
|
|
1551
|
+
const rows = await dbAll(
|
|
1552
|
+
this.db,
|
|
1435
1553
|
`SELECT * FROM edges
|
|
1436
1554
|
WHERE src_type = ? AND src_id = ? AND rel_type = ?
|
|
1437
1555
|
AND dst_type = ? AND dst_id = ?`,
|
|
@@ -1452,7 +1570,7 @@ var EdgeRepo = class {
|
|
|
1452
1570
|
params.push(relType);
|
|
1453
1571
|
}
|
|
1454
1572
|
query += ` ORDER BY created_at DESC`;
|
|
1455
|
-
const rows = await this.db
|
|
1573
|
+
const rows = await dbAll(this.db, query, params);
|
|
1456
1574
|
return rows.map((row) => this.rowToEdge(row));
|
|
1457
1575
|
}
|
|
1458
1576
|
/**
|
|
@@ -1466,7 +1584,7 @@ var EdgeRepo = class {
|
|
|
1466
1584
|
params.push(relType);
|
|
1467
1585
|
}
|
|
1468
1586
|
query += ` ORDER BY created_at DESC`;
|
|
1469
|
-
const rows = await this.db
|
|
1587
|
+
const rows = await dbAll(this.db, query, params);
|
|
1470
1588
|
return rows.map((row) => this.rowToEdge(row));
|
|
1471
1589
|
}
|
|
1472
1590
|
/**
|
|
@@ -1481,7 +1599,8 @@ var EdgeRepo = class {
|
|
|
1481
1599
|
* Delete edge by ID
|
|
1482
1600
|
*/
|
|
1483
1601
|
async delete(edgeId) {
|
|
1484
|
-
|
|
1602
|
+
await dbRun(
|
|
1603
|
+
this.db,
|
|
1485
1604
|
`DELETE FROM edges WHERE edge_id = ?`,
|
|
1486
1605
|
[edgeId]
|
|
1487
1606
|
);
|
|
@@ -1491,7 +1610,8 @@ var EdgeRepo = class {
|
|
|
1491
1610
|
* Delete edges by source and relation type
|
|
1492
1611
|
*/
|
|
1493
1612
|
async deleteBySrcAndRel(srcId, relType) {
|
|
1494
|
-
await
|
|
1613
|
+
await dbRun(
|
|
1614
|
+
this.db,
|
|
1495
1615
|
`DELETE FROM edges WHERE src_id = ? AND rel_type = ?`,
|
|
1496
1616
|
[srcId, relType]
|
|
1497
1617
|
);
|
|
@@ -1501,7 +1621,8 @@ var EdgeRepo = class {
|
|
|
1501
1621
|
* Delete edges by destination and relation type
|
|
1502
1622
|
*/
|
|
1503
1623
|
async deleteByDstAndRel(dstId, relType) {
|
|
1504
|
-
await
|
|
1624
|
+
await dbRun(
|
|
1625
|
+
this.db,
|
|
1505
1626
|
`DELETE FROM edges WHERE dst_id = ? AND rel_type = ?`,
|
|
1506
1627
|
[dstId, relType]
|
|
1507
1628
|
);
|
|
@@ -1535,7 +1656,8 @@ var EdgeRepo = class {
|
|
|
1535
1656
|
const blockerEdges = await this.findBySrc(taskId, "blocked_by");
|
|
1536
1657
|
const results = [];
|
|
1537
1658
|
for (const edge of blockerEdges) {
|
|
1538
|
-
const resolvesTo = await
|
|
1659
|
+
const resolvesTo = await dbAll(
|
|
1660
|
+
this.db,
|
|
1539
1661
|
`SELECT dst_id FROM edges
|
|
1540
1662
|
WHERE src_id = ? AND rel_type = 'resolves_to'
|
|
1541
1663
|
LIMIT 1`,
|
|
@@ -1561,7 +1683,8 @@ var EdgeRepo = class {
|
|
|
1561
1683
|
* Find 2-hop related entries (Entry → Entity → Entry)
|
|
1562
1684
|
*/
|
|
1563
1685
|
async findRelatedEntries(entryId) {
|
|
1564
|
-
const rows = await
|
|
1686
|
+
const rows = await dbAll(
|
|
1687
|
+
this.db,
|
|
1565
1688
|
`WITH first_hop AS (
|
|
1566
1689
|
SELECT e1.dst_id AS entity_id
|
|
1567
1690
|
FROM edges e1
|
|
@@ -1590,7 +1713,8 @@ var EdgeRepo = class {
|
|
|
1590
1713
|
* Count edges by relation type
|
|
1591
1714
|
*/
|
|
1592
1715
|
async countByRelType() {
|
|
1593
|
-
const rows = await
|
|
1716
|
+
const rows = await dbAll(
|
|
1717
|
+
this.db,
|
|
1594
1718
|
`SELECT rel_type, COUNT(*) as count FROM edges GROUP BY rel_type`
|
|
1595
1719
|
);
|
|
1596
1720
|
return rows.map((row) => ({
|
|
@@ -1610,7 +1734,7 @@ var EdgeRepo = class {
|
|
|
1610
1734
|
dstType: row.dst_type,
|
|
1611
1735
|
dstId: row.dst_id,
|
|
1612
1736
|
metaJson: typeof row.meta_json === "string" ? JSON.parse(row.meta_json) : row.meta_json,
|
|
1613
|
-
createdAt:
|
|
1737
|
+
createdAt: toDate(row.created_at)
|
|
1614
1738
|
};
|
|
1615
1739
|
}
|
|
1616
1740
|
};
|
|
@@ -1699,23 +1823,28 @@ var VectorStore = class {
|
|
|
1699
1823
|
return [];
|
|
1700
1824
|
}
|
|
1701
1825
|
const { limit = 5, minScore = 0.7, sessionId } = options;
|
|
1702
|
-
let query = this.table.search(queryVector).limit(limit * 2);
|
|
1826
|
+
let query = this.table.search(queryVector).distanceType("cosine").limit(limit * 2);
|
|
1703
1827
|
if (sessionId) {
|
|
1704
1828
|
query = query.where(`sessionId = '${sessionId}'`);
|
|
1705
1829
|
}
|
|
1706
1830
|
const results = await query.toArray();
|
|
1707
1831
|
return results.filter((r) => {
|
|
1708
|
-
const
|
|
1832
|
+
const distance = r._distance || 0;
|
|
1833
|
+
const score = 1 - distance / 2;
|
|
1709
1834
|
return score >= minScore;
|
|
1710
|
-
}).slice(0, limit).map((r) =>
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1835
|
+
}).slice(0, limit).map((r) => {
|
|
1836
|
+
const distance = r._distance || 0;
|
|
1837
|
+
const score = 1 - distance / 2;
|
|
1838
|
+
return {
|
|
1839
|
+
id: r.id,
|
|
1840
|
+
eventId: r.eventId,
|
|
1841
|
+
content: r.content,
|
|
1842
|
+
score,
|
|
1843
|
+
sessionId: r.sessionId,
|
|
1844
|
+
eventType: r.eventType,
|
|
1845
|
+
timestamp: r.timestamp
|
|
1846
|
+
};
|
|
1847
|
+
});
|
|
1719
1848
|
}
|
|
1720
1849
|
/**
|
|
1721
1850
|
* Delete vector by event ID
|
|
@@ -1859,7 +1988,8 @@ var VectorOutbox = class {
|
|
|
1859
1988
|
const version = embeddingVersion ?? this.config.embeddingVersion;
|
|
1860
1989
|
const jobId = randomUUID4();
|
|
1861
1990
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1862
|
-
await
|
|
1991
|
+
await dbRun(
|
|
1992
|
+
this.db,
|
|
1863
1993
|
`INSERT INTO vector_outbox (
|
|
1864
1994
|
job_id, item_kind, item_id, embedding_version, status, retry_count, created_at, updated_at
|
|
1865
1995
|
) VALUES (?, ?, ?, ?, 'pending', 0, ?, ?)
|
|
@@ -1873,7 +2003,8 @@ var VectorOutbox = class {
|
|
|
1873
2003
|
*/
|
|
1874
2004
|
async claimJobs(limit = 32) {
|
|
1875
2005
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1876
|
-
const rows = await
|
|
2006
|
+
const rows = await dbAll(
|
|
2007
|
+
this.db,
|
|
1877
2008
|
`UPDATE vector_outbox
|
|
1878
2009
|
SET status = 'processing', updated_at = ?
|
|
1879
2010
|
WHERE job_id IN (
|
|
@@ -1891,7 +2022,8 @@ var VectorOutbox = class {
|
|
|
1891
2022
|
* Mark job as done
|
|
1892
2023
|
*/
|
|
1893
2024
|
async markDone(jobId) {
|
|
1894
|
-
await
|
|
2025
|
+
await dbRun(
|
|
2026
|
+
this.db,
|
|
1895
2027
|
`UPDATE vector_outbox
|
|
1896
2028
|
SET status = 'done', updated_at = ?
|
|
1897
2029
|
WHERE job_id = ?`,
|
|
@@ -1903,7 +2035,8 @@ var VectorOutbox = class {
|
|
|
1903
2035
|
*/
|
|
1904
2036
|
async markFailed(jobId, error) {
|
|
1905
2037
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1906
|
-
const rows = await
|
|
2038
|
+
const rows = await dbAll(
|
|
2039
|
+
this.db,
|
|
1907
2040
|
`SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
|
|
1908
2041
|
[jobId]
|
|
1909
2042
|
);
|
|
@@ -1911,7 +2044,8 @@ var VectorOutbox = class {
|
|
|
1911
2044
|
return;
|
|
1912
2045
|
const retryCount = rows[0].retry_count;
|
|
1913
2046
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
1914
|
-
await
|
|
2047
|
+
await dbRun(
|
|
2048
|
+
this.db,
|
|
1915
2049
|
`UPDATE vector_outbox
|
|
1916
2050
|
SET status = ?, error = ?, retry_count = retry_count + 1, updated_at = ?
|
|
1917
2051
|
WHERE job_id = ?`,
|
|
@@ -1922,7 +2056,8 @@ var VectorOutbox = class {
|
|
|
1922
2056
|
* Get job by ID
|
|
1923
2057
|
*/
|
|
1924
2058
|
async getJob(jobId) {
|
|
1925
|
-
const rows = await
|
|
2059
|
+
const rows = await dbAll(
|
|
2060
|
+
this.db,
|
|
1926
2061
|
`SELECT * FROM vector_outbox WHERE job_id = ?`,
|
|
1927
2062
|
[jobId]
|
|
1928
2063
|
);
|
|
@@ -1934,7 +2069,8 @@ var VectorOutbox = class {
|
|
|
1934
2069
|
* Get jobs by status
|
|
1935
2070
|
*/
|
|
1936
2071
|
async getJobsByStatus(status, limit = 100) {
|
|
1937
|
-
const rows = await
|
|
2072
|
+
const rows = await dbAll(
|
|
2073
|
+
this.db,
|
|
1938
2074
|
`SELECT * FROM vector_outbox
|
|
1939
2075
|
WHERE status = ?
|
|
1940
2076
|
ORDER BY created_at ASC
|
|
@@ -1949,21 +2085,24 @@ var VectorOutbox = class {
|
|
|
1949
2085
|
async reconcile() {
|
|
1950
2086
|
const now = /* @__PURE__ */ new Date();
|
|
1951
2087
|
const stuckThreshold = new Date(now.getTime() - this.config.stuckThresholdMs);
|
|
1952
|
-
|
|
2088
|
+
await dbRun(
|
|
2089
|
+
this.db,
|
|
1953
2090
|
`UPDATE vector_outbox
|
|
1954
2091
|
SET status = 'pending', updated_at = ?
|
|
1955
2092
|
WHERE status = 'processing'
|
|
1956
2093
|
AND updated_at < ?`,
|
|
1957
2094
|
[now.toISOString(), stuckThreshold.toISOString()]
|
|
1958
2095
|
);
|
|
1959
|
-
|
|
2096
|
+
await dbRun(
|
|
2097
|
+
this.db,
|
|
1960
2098
|
`UPDATE vector_outbox
|
|
1961
2099
|
SET status = 'pending', updated_at = ?
|
|
1962
2100
|
WHERE status = 'failed'
|
|
1963
2101
|
AND retry_count < ?`,
|
|
1964
2102
|
[now.toISOString(), this.config.maxRetries]
|
|
1965
2103
|
);
|
|
1966
|
-
const recoveredRows = await
|
|
2104
|
+
const recoveredRows = await dbAll(
|
|
2105
|
+
this.db,
|
|
1967
2106
|
`SELECT COUNT(*) as count FROM vector_outbox
|
|
1968
2107
|
WHERE status = 'pending' AND updated_at = ?`,
|
|
1969
2108
|
[now.toISOString()]
|
|
@@ -1981,7 +2120,8 @@ var VectorOutbox = class {
|
|
|
1981
2120
|
async cleanup() {
|
|
1982
2121
|
const threshold = /* @__PURE__ */ new Date();
|
|
1983
2122
|
threshold.setDate(threshold.getDate() - this.config.cleanupDays);
|
|
1984
|
-
await
|
|
2123
|
+
await dbRun(
|
|
2124
|
+
this.db,
|
|
1985
2125
|
`DELETE FROM vector_outbox
|
|
1986
2126
|
WHERE status = 'done'
|
|
1987
2127
|
AND updated_at < ?`,
|
|
@@ -1993,12 +2133,14 @@ var VectorOutbox = class {
|
|
|
1993
2133
|
* Get metrics
|
|
1994
2134
|
*/
|
|
1995
2135
|
async getMetrics() {
|
|
1996
|
-
const statusCounts = await
|
|
2136
|
+
const statusCounts = await dbAll(
|
|
2137
|
+
this.db,
|
|
1997
2138
|
`SELECT status, COUNT(*) as count
|
|
1998
2139
|
FROM vector_outbox
|
|
1999
2140
|
GROUP BY status`
|
|
2000
2141
|
);
|
|
2001
|
-
const oldestPending = await
|
|
2142
|
+
const oldestPending = await dbAll(
|
|
2143
|
+
this.db,
|
|
2002
2144
|
`SELECT created_at FROM vector_outbox
|
|
2003
2145
|
WHERE status = 'pending'
|
|
2004
2146
|
ORDER BY created_at ASC
|
|
@@ -2057,8 +2199,8 @@ var VectorOutbox = class {
|
|
|
2057
2199
|
status: row.status,
|
|
2058
2200
|
retryCount: row.retry_count,
|
|
2059
2201
|
error: row.error,
|
|
2060
|
-
createdAt:
|
|
2061
|
-
updatedAt:
|
|
2202
|
+
createdAt: toDate(row.created_at),
|
|
2203
|
+
updatedAt: toDate(row.updated_at)
|
|
2062
2204
|
};
|
|
2063
2205
|
}
|
|
2064
2206
|
};
|
|
@@ -2210,7 +2352,8 @@ var DefaultContentProvider = class {
|
|
|
2210
2352
|
}
|
|
2211
2353
|
}
|
|
2212
2354
|
async getEntryContent(entryId) {
|
|
2213
|
-
const rows = await
|
|
2355
|
+
const rows = await dbAll(
|
|
2356
|
+
this.db,
|
|
2214
2357
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
2215
2358
|
[entryId]
|
|
2216
2359
|
);
|
|
@@ -2228,7 +2371,8 @@ ${JSON.stringify(contentJson)}`,
|
|
|
2228
2371
|
};
|
|
2229
2372
|
}
|
|
2230
2373
|
async getTaskTitleContent(taskId) {
|
|
2231
|
-
const rows = await
|
|
2374
|
+
const rows = await dbAll(
|
|
2375
|
+
this.db,
|
|
2232
2376
|
`SELECT title, search_text, current_json FROM entities
|
|
2233
2377
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
2234
2378
|
[taskId]
|
|
@@ -2245,7 +2389,8 @@ ${JSON.stringify(contentJson)}`,
|
|
|
2245
2389
|
};
|
|
2246
2390
|
}
|
|
2247
2391
|
async getEventContent(eventId) {
|
|
2248
|
-
const rows = await
|
|
2392
|
+
const rows = await dbAll(
|
|
2393
|
+
this.db,
|
|
2249
2394
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
2250
2395
|
[eventId]
|
|
2251
2396
|
);
|
|
@@ -3388,7 +3533,8 @@ var TaskMatcher = class {
|
|
|
3388
3533
|
*/
|
|
3389
3534
|
async findExact(title, project) {
|
|
3390
3535
|
const canonicalKey = makeEntityCanonicalKey("task", title, { project });
|
|
3391
|
-
const rows = await
|
|
3536
|
+
const rows = await dbAll(
|
|
3537
|
+
this.db,
|
|
3392
3538
|
`SELECT * FROM entities
|
|
3393
3539
|
WHERE entity_type = 'task' AND canonical_key = ?
|
|
3394
3540
|
AND status = 'active'`,
|
|
@@ -3403,7 +3549,8 @@ var TaskMatcher = class {
|
|
|
3403
3549
|
*/
|
|
3404
3550
|
async findByAlias(title, project) {
|
|
3405
3551
|
const canonicalKey = makeEntityCanonicalKey("task", title, { project });
|
|
3406
|
-
const rows = await
|
|
3552
|
+
const rows = await dbAll(
|
|
3553
|
+
this.db,
|
|
3407
3554
|
`SELECT e.* FROM entities e
|
|
3408
3555
|
JOIN entity_aliases a ON e.entity_id = a.entity_id
|
|
3409
3556
|
WHERE a.entity_type = 'task' AND a.canonical_key = ?
|
|
@@ -3439,7 +3586,7 @@ var TaskMatcher = class {
|
|
|
3439
3586
|
}
|
|
3440
3587
|
sql += ` ORDER BY match_score DESC, updated_at DESC LIMIT ?`;
|
|
3441
3588
|
params.push(this.config.maxCandidates);
|
|
3442
|
-
const rows = await this.db
|
|
3589
|
+
const rows = await dbAll(this.db, sql, params);
|
|
3443
3590
|
return rows.map((row) => ({
|
|
3444
3591
|
entity: this.rowToEntity(row),
|
|
3445
3592
|
score: row.match_score
|
|
@@ -3535,8 +3682,8 @@ var TaskMatcher = class {
|
|
|
3535
3682
|
currentJson: typeof row.current_json === "string" ? JSON.parse(row.current_json) : row.current_json,
|
|
3536
3683
|
titleNorm: row.title_norm,
|
|
3537
3684
|
searchText: row.search_text,
|
|
3538
|
-
createdAt:
|
|
3539
|
-
updatedAt:
|
|
3685
|
+
createdAt: toDate(row.created_at),
|
|
3686
|
+
updatedAt: toDate(row.updated_at)
|
|
3540
3687
|
};
|
|
3541
3688
|
}
|
|
3542
3689
|
};
|
|
@@ -3608,7 +3755,8 @@ var BlockerResolver = class {
|
|
|
3608
3755
|
return null;
|
|
3609
3756
|
}
|
|
3610
3757
|
const canonicalKey = makeArtifactKey(text);
|
|
3611
|
-
const existing = await
|
|
3758
|
+
const existing = await dbAll(
|
|
3759
|
+
this.db,
|
|
3612
3760
|
`SELECT entity_id FROM entities
|
|
3613
3761
|
WHERE entity_type = 'artifact' AND canonical_key = ?`,
|
|
3614
3762
|
[canonicalKey]
|
|
@@ -3630,7 +3778,8 @@ var BlockerResolver = class {
|
|
|
3630
3778
|
* Try to resolve as explicit task ID
|
|
3631
3779
|
*/
|
|
3632
3780
|
async tryResolveAsTaskId(taskId) {
|
|
3633
|
-
const rows = await
|
|
3781
|
+
const rows = await dbAll(
|
|
3782
|
+
this.db,
|
|
3634
3783
|
`SELECT entity_id FROM entities
|
|
3635
3784
|
WHERE entity_type = 'task' AND canonical_key = ?
|
|
3636
3785
|
AND status = 'active'`,
|
|
@@ -3653,7 +3802,8 @@ var BlockerResolver = class {
|
|
|
3653
3802
|
const canonicalKey = makeEntityCanonicalKey("condition", text, {
|
|
3654
3803
|
project: this.config.project
|
|
3655
3804
|
});
|
|
3656
|
-
const existing = await
|
|
3805
|
+
const existing = await dbAll(
|
|
3806
|
+
this.db,
|
|
3657
3807
|
`SELECT entity_id FROM entities
|
|
3658
3808
|
WHERE entity_type = 'condition' AND canonical_key = ?`,
|
|
3659
3809
|
[canonicalKey]
|
|
@@ -3686,7 +3836,8 @@ var BlockerResolver = class {
|
|
|
3686
3836
|
title: c.title
|
|
3687
3837
|
}))
|
|
3688
3838
|
};
|
|
3689
|
-
await
|
|
3839
|
+
await dbRun(
|
|
3840
|
+
this.db,
|
|
3690
3841
|
`INSERT INTO entities (
|
|
3691
3842
|
entity_id, entity_type, canonical_key, title, stage, status,
|
|
3692
3843
|
current_json, title_norm, search_text, created_at, updated_at
|
|
@@ -3705,7 +3856,8 @@ var BlockerResolver = class {
|
|
|
3705
3856
|
now
|
|
3706
3857
|
]
|
|
3707
3858
|
);
|
|
3708
|
-
await
|
|
3859
|
+
await dbRun(
|
|
3860
|
+
this.db,
|
|
3709
3861
|
`INSERT INTO entity_aliases (entity_type, canonical_key, entity_id, is_primary)
|
|
3710
3862
|
VALUES (?, ?, ?, TRUE)
|
|
3711
3863
|
ON CONFLICT (entity_type, canonical_key) DO NOTHING`,
|
|
@@ -3731,7 +3883,8 @@ var BlockerResolver = class {
|
|
|
3731
3883
|
identifier,
|
|
3732
3884
|
artifactType
|
|
3733
3885
|
};
|
|
3734
|
-
await
|
|
3886
|
+
await dbRun(
|
|
3887
|
+
this.db,
|
|
3735
3888
|
`INSERT INTO entities (
|
|
3736
3889
|
entity_id, entity_type, canonical_key, title, stage, status,
|
|
3737
3890
|
current_json, title_norm, search_text, created_at, updated_at
|
|
@@ -3750,7 +3903,8 @@ var BlockerResolver = class {
|
|
|
3750
3903
|
now
|
|
3751
3904
|
]
|
|
3752
3905
|
);
|
|
3753
|
-
await
|
|
3906
|
+
await dbRun(
|
|
3907
|
+
this.db,
|
|
3754
3908
|
`INSERT INTO entity_aliases (entity_type, canonical_key, entity_id, is_primary)
|
|
3755
3909
|
VALUES (?, ?, ?, TRUE)
|
|
3756
3910
|
ON CONFLICT (entity_type, canonical_key) DO NOTHING`,
|
|
@@ -3765,7 +3919,8 @@ var BlockerResolver = class {
|
|
|
3765
3919
|
async createUnknownPlaceholder(taskTitle) {
|
|
3766
3920
|
const text = `Unknown blocker for: ${taskTitle}`;
|
|
3767
3921
|
const ref = await this.createConditionBlocker(text);
|
|
3768
|
-
await
|
|
3922
|
+
await dbRun(
|
|
3923
|
+
this.db,
|
|
3769
3924
|
`UPDATE entities
|
|
3770
3925
|
SET current_json = json_set(current_json, '$.auto_placeholder', true)
|
|
3771
3926
|
WHERE entity_id = ?`,
|
|
@@ -3869,7 +4024,8 @@ var TaskResolver = class {
|
|
|
3869
4024
|
description: extracted.description,
|
|
3870
4025
|
project: extracted.project ?? this.config.project
|
|
3871
4026
|
};
|
|
3872
|
-
await
|
|
4027
|
+
await dbRun(
|
|
4028
|
+
this.db,
|
|
3873
4029
|
`INSERT INTO entities (
|
|
3874
4030
|
entity_id, entity_type, canonical_key, title, stage, status,
|
|
3875
4031
|
current_json, title_norm, search_text, created_at, updated_at
|
|
@@ -3888,7 +4044,8 @@ var TaskResolver = class {
|
|
|
3888
4044
|
now.toISOString()
|
|
3889
4045
|
]
|
|
3890
4046
|
);
|
|
3891
|
-
await
|
|
4047
|
+
await dbRun(
|
|
4048
|
+
this.db,
|
|
3892
4049
|
`INSERT INTO entity_aliases (entity_type, canonical_key, entity_id, is_primary)
|
|
3893
4050
|
VALUES (?, ?, ?, TRUE)
|
|
3894
4051
|
ON CONFLICT (entity_type, canonical_key) DO NOTHING`,
|
|
@@ -3941,7 +4098,8 @@ var TaskResolver = class {
|
|
|
3941
4098
|
fromStatus: currentStatus,
|
|
3942
4099
|
toStatus: newStatus
|
|
3943
4100
|
});
|
|
3944
|
-
await
|
|
4101
|
+
await dbRun(
|
|
4102
|
+
this.db,
|
|
3945
4103
|
`UPDATE entities
|
|
3946
4104
|
SET current_json = json_set(current_json, '$.status', ?),
|
|
3947
4105
|
updated_at = ?
|
|
@@ -3964,7 +4122,8 @@ var TaskResolver = class {
|
|
|
3964
4122
|
fromPriority: currentPriority,
|
|
3965
4123
|
toPriority: newPriority
|
|
3966
4124
|
});
|
|
3967
|
-
await
|
|
4125
|
+
await dbRun(
|
|
4126
|
+
this.db,
|
|
3968
4127
|
`UPDATE entities
|
|
3969
4128
|
SET current_json = json_set(current_json, '$.priority', ?),
|
|
3970
4129
|
updated_at = ?
|
|
@@ -4011,14 +4170,16 @@ var TaskResolver = class {
|
|
|
4011
4170
|
this.config.sessionId,
|
|
4012
4171
|
JSON.stringify(payload)
|
|
4013
4172
|
);
|
|
4014
|
-
const existing = await
|
|
4173
|
+
const existing = await dbAll(
|
|
4174
|
+
this.db,
|
|
4015
4175
|
`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,
|
|
4016
4176
|
[dedupeKey]
|
|
4017
4177
|
);
|
|
4018
4178
|
if (existing.length > 0) {
|
|
4019
4179
|
return existing[0].event_id;
|
|
4020
4180
|
}
|
|
4021
|
-
await
|
|
4181
|
+
await dbRun(
|
|
4182
|
+
this.db,
|
|
4022
4183
|
`INSERT INTO events (
|
|
4023
4184
|
id, event_type, session_id, timestamp, content,
|
|
4024
4185
|
canonical_key, dedupe_key, metadata
|
|
@@ -4034,7 +4195,8 @@ var TaskResolver = class {
|
|
|
4034
4195
|
JSON.stringify({ source: "task_resolver" })
|
|
4035
4196
|
]
|
|
4036
4197
|
);
|
|
4037
|
-
await
|
|
4198
|
+
await dbRun(
|
|
4199
|
+
this.db,
|
|
4038
4200
|
`INSERT INTO event_dedup (dedupe_key, event_id)
|
|
4039
4201
|
VALUES (?, ?)
|
|
4040
4202
|
ON CONFLICT DO NOTHING`,
|
|
@@ -4053,7 +4215,8 @@ var TaskResolver = class {
|
|
|
4053
4215
|
entityId: taskId
|
|
4054
4216
|
}
|
|
4055
4217
|
});
|
|
4056
|
-
await
|
|
4218
|
+
await dbRun(
|
|
4219
|
+
this.db,
|
|
4057
4220
|
`INSERT INTO edges (edge_id, src_type, src_id, rel_type, dst_type, dst_id, meta_json)
|
|
4058
4221
|
VALUES (?, 'entity', ?, 'resolves_to', 'entity', ?, ?)
|
|
4059
4222
|
ON CONFLICT DO NOTHING`,
|
|
@@ -4082,7 +4245,8 @@ var TaskProjector = class {
|
|
|
4082
4245
|
* Get current projection offset
|
|
4083
4246
|
*/
|
|
4084
4247
|
async getOffset() {
|
|
4085
|
-
const rows = await
|
|
4248
|
+
const rows = await dbAll(
|
|
4249
|
+
this.db,
|
|
4086
4250
|
`SELECT last_event_id, last_timestamp
|
|
4087
4251
|
FROM projection_offsets
|
|
4088
4252
|
WHERE projection_name = ?`,
|
|
@@ -4100,7 +4264,8 @@ var TaskProjector = class {
|
|
|
4100
4264
|
* Update projection offset
|
|
4101
4265
|
*/
|
|
4102
4266
|
async updateOffset(eventId, timestamp) {
|
|
4103
|
-
await
|
|
4267
|
+
await dbRun(
|
|
4268
|
+
this.db,
|
|
4104
4269
|
`INSERT INTO projection_offsets (projection_name, last_event_id, last_timestamp, updated_at)
|
|
4105
4270
|
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
|
|
4106
4271
|
ON CONFLICT (projection_name) DO UPDATE SET
|
|
@@ -4130,12 +4295,12 @@ var TaskProjector = class {
|
|
|
4130
4295
|
}
|
|
4131
4296
|
query += ` ORDER BY timestamp ASC, id ASC LIMIT ?`;
|
|
4132
4297
|
params.push(limit);
|
|
4133
|
-
const rows = await this.db
|
|
4298
|
+
const rows = await dbAll(this.db, query, params);
|
|
4134
4299
|
return rows.map((row) => ({
|
|
4135
4300
|
id: row.id,
|
|
4136
4301
|
eventType: row.event_type,
|
|
4137
4302
|
sessionId: row.session_id,
|
|
4138
|
-
timestamp:
|
|
4303
|
+
timestamp: toDate(row.timestamp),
|
|
4139
4304
|
content: typeof row.content === "string" ? JSON.parse(row.content) : row.content
|
|
4140
4305
|
}));
|
|
4141
4306
|
}
|
|
@@ -4195,12 +4360,14 @@ var TaskProjector = class {
|
|
|
4195
4360
|
async handleStatusChanged(event) {
|
|
4196
4361
|
const { taskId, toStatus } = event.content;
|
|
4197
4362
|
if (toStatus === "done") {
|
|
4198
|
-
await
|
|
4363
|
+
await dbRun(
|
|
4364
|
+
this.db,
|
|
4199
4365
|
`DELETE FROM edges
|
|
4200
4366
|
WHERE src_id = ? AND rel_type IN ('blocked_by', 'blocked_by_suggested')`,
|
|
4201
4367
|
[taskId]
|
|
4202
4368
|
);
|
|
4203
|
-
await
|
|
4369
|
+
await dbRun(
|
|
4370
|
+
this.db,
|
|
4204
4371
|
`UPDATE entities
|
|
4205
4372
|
SET current_json = json_remove(json_remove(current_json, '$.blockers'), '$.blockerSuggestions'),
|
|
4206
4373
|
updated_at = CURRENT_TIMESTAMP
|
|
@@ -4215,7 +4382,8 @@ var TaskProjector = class {
|
|
|
4215
4382
|
async handleBlockersSet(event) {
|
|
4216
4383
|
const { taskId, mode, blockers } = event.content;
|
|
4217
4384
|
if (mode === "replace") {
|
|
4218
|
-
await
|
|
4385
|
+
await dbRun(
|
|
4386
|
+
this.db,
|
|
4219
4387
|
`DELETE FROM edges WHERE src_id = ? AND rel_type = 'blocked_by'`,
|
|
4220
4388
|
[taskId]
|
|
4221
4389
|
);
|
|
@@ -4223,7 +4391,8 @@ var TaskProjector = class {
|
|
|
4223
4391
|
await this.createBlockerEdge(taskId, blocker, "blocked_by");
|
|
4224
4392
|
}
|
|
4225
4393
|
const blockerIds = blockers.map((b) => b.entityId);
|
|
4226
|
-
await
|
|
4394
|
+
await dbRun(
|
|
4395
|
+
this.db,
|
|
4227
4396
|
`UPDATE entities
|
|
4228
4397
|
SET current_json = json_set(current_json, '$.blockers', ?),
|
|
4229
4398
|
updated_at = CURRENT_TIMESTAMP
|
|
@@ -4231,7 +4400,8 @@ var TaskProjector = class {
|
|
|
4231
4400
|
[JSON.stringify(blockerIds), taskId]
|
|
4232
4401
|
);
|
|
4233
4402
|
} else {
|
|
4234
|
-
await
|
|
4403
|
+
await dbRun(
|
|
4404
|
+
this.db,
|
|
4235
4405
|
`DELETE FROM edges WHERE src_id = ? AND rel_type = 'blocked_by_suggested'`,
|
|
4236
4406
|
[taskId]
|
|
4237
4407
|
);
|
|
@@ -4239,7 +4409,8 @@ var TaskProjector = class {
|
|
|
4239
4409
|
await this.createBlockerEdge(taskId, blocker, "blocked_by_suggested");
|
|
4240
4410
|
}
|
|
4241
4411
|
const suggestionIds = blockers.map((b) => b.entityId);
|
|
4242
|
-
await
|
|
4412
|
+
await dbRun(
|
|
4413
|
+
this.db,
|
|
4243
4414
|
`UPDATE entities
|
|
4244
4415
|
SET current_json = json_set(current_json, '$.blockerSuggestions', ?),
|
|
4245
4416
|
updated_at = CURRENT_TIMESTAMP
|
|
@@ -4253,7 +4424,8 @@ var TaskProjector = class {
|
|
|
4253
4424
|
*/
|
|
4254
4425
|
async createBlockerEdge(taskId, blocker, relType) {
|
|
4255
4426
|
const edgeId = randomUUID7();
|
|
4256
|
-
await
|
|
4427
|
+
await dbRun(
|
|
4428
|
+
this.db,
|
|
4257
4429
|
`INSERT INTO edges (edge_id, src_type, src_id, rel_type, dst_type, dst_id, meta_json, created_at)
|
|
4258
4430
|
VALUES (?, 'entity', ?, ?, 'entity', ?, ?, CURRENT_TIMESTAMP)
|
|
4259
4431
|
ON CONFLICT DO NOTHING`,
|
|
@@ -4276,7 +4448,8 @@ var TaskProjector = class {
|
|
|
4276
4448
|
*/
|
|
4277
4449
|
async handleConditionResolved(event) {
|
|
4278
4450
|
const { conditionId, resolvedTo } = event.content;
|
|
4279
|
-
await
|
|
4451
|
+
await dbRun(
|
|
4452
|
+
this.db,
|
|
4280
4453
|
`UPDATE entities
|
|
4281
4454
|
SET current_json = json_set(json_set(current_json, '$.resolved', true), '$.resolvedTo', ?),
|
|
4282
4455
|
updated_at = CURRENT_TIMESTAMP
|
|
@@ -4290,7 +4463,8 @@ var TaskProjector = class {
|
|
|
4290
4463
|
async enqueueForVectorization(itemId, itemKind) {
|
|
4291
4464
|
const jobId = randomUUID7();
|
|
4292
4465
|
const embeddingVersion = "v1";
|
|
4293
|
-
await
|
|
4466
|
+
await dbRun(
|
|
4467
|
+
this.db,
|
|
4294
4468
|
`INSERT INTO vector_outbox (job_id, item_kind, item_id, embedding_version, status, retry_count)
|
|
4295
4469
|
VALUES (?, ?, ?, ?, 'pending', 0)
|
|
4296
4470
|
ON CONFLICT (item_kind, item_id, embedding_version) DO NOTHING`,
|
|
@@ -4302,10 +4476,12 @@ var TaskProjector = class {
|
|
|
4302
4476
|
* WARNING: This clears all edges and rebuilds from events
|
|
4303
4477
|
*/
|
|
4304
4478
|
async rebuild() {
|
|
4305
|
-
await
|
|
4479
|
+
await dbRun(
|
|
4480
|
+
this.db,
|
|
4306
4481
|
`DELETE FROM edges WHERE rel_type IN ('blocked_by', 'blocked_by_suggested', 'resolves_to')`
|
|
4307
4482
|
);
|
|
4308
|
-
await
|
|
4483
|
+
await dbRun(
|
|
4484
|
+
this.db,
|
|
4309
4485
|
`DELETE FROM projection_offsets WHERE projection_name = ?`,
|
|
4310
4486
|
[PROJECTOR_NAME]
|
|
4311
4487
|
);
|