@mrc2204/agent-smart-memo 5.0.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/contracts/adapter-contracts.d.ts +1 -1
- package/dist/core/contracts/adapter-contracts.d.ts.map +1 -1
- package/dist/core/ingest/contracts.d.ts +44 -0
- package/dist/core/ingest/contracts.d.ts.map +1 -0
- package/dist/core/ingest/contracts.js +2 -0
- package/dist/core/ingest/contracts.js.map +1 -0
- package/dist/core/ingest/ids.d.ts +5 -0
- package/dist/core/ingest/ids.d.ts.map +1 -0
- package/dist/core/ingest/ids.js +17 -0
- package/dist/core/ingest/ids.js.map +1 -0
- package/dist/core/ingest/ingest-pipeline.d.ts +4 -0
- package/dist/core/ingest/ingest-pipeline.d.ts.map +1 -0
- package/dist/core/ingest/ingest-pipeline.js +105 -0
- package/dist/core/ingest/ingest-pipeline.js.map +1 -0
- package/dist/core/ingest/semantic-block-extractor.d.ts +9 -0
- package/dist/core/ingest/semantic-block-extractor.d.ts.map +1 -0
- package/dist/core/ingest/semantic-block-extractor.js +135 -0
- package/dist/core/ingest/semantic-block-extractor.js.map +1 -0
- package/dist/core/usecases/default-memory-usecase-port.d.ts +3 -0
- package/dist/core/usecases/default-memory-usecase-port.d.ts.map +1 -1
- package/dist/core/usecases/default-memory-usecase-port.js +124 -12
- package/dist/core/usecases/default-memory-usecase-port.js.map +1 -1
- package/dist/db/slot-db.d.ts +8 -1
- package/dist/db/slot-db.d.ts.map +1 -1
- package/dist/db/slot-db.js +132 -22
- package/dist/db/slot-db.js.map +1 -1
- package/dist/tools/project-tools.d.ts.map +1 -1
- package/dist/tools/project-tools.js +68 -0
- package/dist/tools/project-tools.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ export interface CoreRequestEnvelope<TPayload> {
|
|
|
17
17
|
requestId?: string;
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
export type MemoryUseCaseName = "slot.get" | "slot.set" | "slot.list" | "slot.delete" | "project.register" | "project.get" | "project.list" | "project.set_registration_state" | "project.set_tracker_mapping" | "project.register_command" | "project.link_tracker" | "project.trigger_index" | "project.reindex_diff" | "project.index_watch_get" | "project.task_registry_upsert" | "project.task_lineage_context" | "project.hybrid_search" | "project.legacy_backfill" | "project.telegram_onboarding" | "memory.capture" | "memory.search" | "graph.entity.get" | "graph.entity.set" | "graph.rel.add" | "graph.rel.remove" | "graph.search";
|
|
20
|
+
export type MemoryUseCaseName = "slot.get" | "slot.set" | "slot.list" | "slot.delete" | "project.register" | "project.get" | "project.list" | "project.set_registration_state" | "project.set_tracker_mapping" | "project.register_command" | "project.link_tracker" | "project.trigger_index" | "project.reindex_diff" | "project.index_event" | "project.install_hooks" | "project.index_watch_get" | "project.task_registry_upsert" | "project.task_lineage_context" | "project.hybrid_search" | "project.legacy_backfill" | "project.telegram_onboarding" | "memory.capture" | "memory.search" | "graph.entity.get" | "graph.entity.set" | "graph.rel.add" | "graph.rel.remove" | "graph.search";
|
|
21
21
|
export interface MemoryUseCasePort {
|
|
22
22
|
run<TReq, TRes>(useCase: MemoryUseCaseName, req: CoreRequestEnvelope<TReq>): Promise<TRes>;
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-contracts.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/adapter-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB,CAAC,QAAQ;IAC3C,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;QAClD,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,UAAU,GACV,WAAW,GACX,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,gCAAgC,GAChC,6BAA6B,GAC7B,0BAA0B,GAC1B,sBAAsB,GACtB,uBAAuB,GACvB,sBAAsB,GACtB,yBAAyB,GACzB,8BAA8B,GAC9B,8BAA8B,GAC9B,uBAAuB,GACvB,yBAAyB,GACzB,6BAA6B,GAC7B,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAClB,cAAc,CAAC;AAEnB,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,IAAI,EAAE,IAAI,EACZ,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB,CAAC,WAAW;IAC/C,eAAe,CAAC,UAAU,EAAE,WAAW,GAAG,aAAa,CAAC;IACxD,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,qBAAqB,CAAC,WAAW;IAChD,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC;CAC9C"}
|
|
1
|
+
{"version":3,"file":"adapter-contracts.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/adapter-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB,CAAC,QAAQ;IAC3C,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;QAClD,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,UAAU,GACV,WAAW,GACX,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,gCAAgC,GAChC,6BAA6B,GAC7B,0BAA0B,GAC1B,sBAAsB,GACtB,uBAAuB,GACvB,sBAAsB,GACtB,qBAAqB,GACrB,uBAAuB,GACvB,yBAAyB,GACzB,8BAA8B,GAC9B,8BAA8B,GAC9B,uBAAuB,GACvB,yBAAyB,GACzB,6BAA6B,GAC7B,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAClB,cAAc,CAAC;AAEnB,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,IAAI,EAAE,IAAI,EACZ,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB,CAAC,WAAW;IAC/C,eAAe,CAAC,UAAU,EAAE,WAAW,GAAG,aAAa,CAAC;IACxD,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,qBAAqB,CAAC,WAAW;IAChD,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC;CAC9C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type IngestTriggerType = "bootstrap" | "incremental" | "manual" | "repair";
|
|
2
|
+
export interface IngestPlanInput {
|
|
3
|
+
project_id: string;
|
|
4
|
+
source_rev: string;
|
|
5
|
+
trigger_type: IngestTriggerType;
|
|
6
|
+
index_profile: string;
|
|
7
|
+
include_overrides?: string[];
|
|
8
|
+
max_file_bytes?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface FileCandidateInput {
|
|
11
|
+
relative_path: string;
|
|
12
|
+
content: string;
|
|
13
|
+
bytes?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface FilePlanEntry {
|
|
16
|
+
relative_path: string;
|
|
17
|
+
file_id: string;
|
|
18
|
+
include: boolean;
|
|
19
|
+
reason: "included" | "ignored_path" | "binary_ext" | "oversized";
|
|
20
|
+
checksum: string;
|
|
21
|
+
bytes: number;
|
|
22
|
+
}
|
|
23
|
+
export type SemanticBlockKind = "function" | "class" | "method" | "doc_section" | "doc_paragraph";
|
|
24
|
+
export interface SemanticBlock {
|
|
25
|
+
kind: SemanticBlockKind;
|
|
26
|
+
symbol_name: string;
|
|
27
|
+
semantic_path: string;
|
|
28
|
+
start_line: number;
|
|
29
|
+
end_line: number;
|
|
30
|
+
ordinal: number;
|
|
31
|
+
text: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ChunkArtifact {
|
|
34
|
+
chunk_id: string;
|
|
35
|
+
file_id: string;
|
|
36
|
+
relative_path: string;
|
|
37
|
+
chunk_kind: SemanticBlockKind;
|
|
38
|
+
symbol_id: string | null;
|
|
39
|
+
checksum: string;
|
|
40
|
+
semantic_path: string;
|
|
41
|
+
ordinal: number;
|
|
42
|
+
text: string;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/core/ingest/contracts.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,iBAAiB,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/core/ingest/contracts.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function buildFileId(projectId: string, relativePath: string): string;
|
|
2
|
+
export declare function buildChunkId(fileId: string, chunkKind: string, semanticPath: string, ordinal: number): string;
|
|
3
|
+
export declare function buildSymbolId(projectId: string, relativePath: string, symbolFqn: string): string;
|
|
4
|
+
export declare function checksumOf(raw: string): string;
|
|
5
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../../src/core/ingest/ids.ts"],"names":[],"mappings":"AAMA,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhG;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
function sha1(raw) {
|
|
3
|
+
return createHash("sha1").update(raw).digest("hex");
|
|
4
|
+
}
|
|
5
|
+
export function buildFileId(projectId, relativePath) {
|
|
6
|
+
return sha1(`${projectId}:${relativePath}`);
|
|
7
|
+
}
|
|
8
|
+
export function buildChunkId(fileId, chunkKind, semanticPath, ordinal) {
|
|
9
|
+
return sha1(`${fileId}:${chunkKind}:${semanticPath}:${ordinal}`);
|
|
10
|
+
}
|
|
11
|
+
export function buildSymbolId(projectId, relativePath, symbolFqn) {
|
|
12
|
+
return sha1(`${projectId}:${relativePath}:${symbolFqn}`);
|
|
13
|
+
}
|
|
14
|
+
export function checksumOf(raw) {
|
|
15
|
+
return sha1(raw);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../../src/core/ingest/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,YAAoB;IACjE,OAAO,IAAI,CAAC,GAAG,SAAS,IAAI,YAAY,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,SAAiB,EACjB,YAAoB,EACpB,OAAe;IAEf,OAAO,IAAI,CAAC,GAAG,MAAM,IAAI,SAAS,IAAI,YAAY,IAAI,OAAO,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,YAAoB,EAAE,SAAiB;IACtF,OAAO,IAAI,CAAC,GAAG,SAAS,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ChunkArtifact, FileCandidateInput, FilePlanEntry, IngestPlanInput, SemanticBlock } from "./contracts.js";
|
|
2
|
+
export declare function planIngestFiles(input: IngestPlanInput, files: FileCandidateInput[]): FilePlanEntry[];
|
|
3
|
+
export declare function buildChunkArtifacts(projectId: string, fileId: string, relativePath: string, blocks: SemanticBlock[]): ChunkArtifact[];
|
|
4
|
+
//# sourceMappingURL=ingest-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest-pipeline.d.ts","sourceRoot":"","sources":["../../../src/core/ingest/ingest-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,aAAa,EACd,MAAM,gBAAgB,CAAC;AAoCxB,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,aAAa,EAAE,CA8DpG;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,aAAa,EAAE,GACtB,aAAa,EAAE,CAkBjB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { buildChunkId, buildFileId, buildSymbolId, checksumOf } from "./ids.js";
|
|
2
|
+
const DEFAULT_MAX_FILE_BYTES = 256 * 1024;
|
|
3
|
+
const IGNORED_DIRS = [
|
|
4
|
+
"node_modules",
|
|
5
|
+
".venv",
|
|
6
|
+
"vendor",
|
|
7
|
+
"dist",
|
|
8
|
+
"build",
|
|
9
|
+
"coverage",
|
|
10
|
+
".next",
|
|
11
|
+
".git",
|
|
12
|
+
];
|
|
13
|
+
const BINARY_EXT = [
|
|
14
|
+
"png", "jpg", "jpeg", "gif", "webp", "pdf", "zip", "gz", "tar", "mp4", "mov", "mp3", "wav", "ico", "lockb",
|
|
15
|
+
];
|
|
16
|
+
function isIgnoredPath(relativePath) {
|
|
17
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
18
|
+
return IGNORED_DIRS.some((dir) => normalized.split("/").includes(dir));
|
|
19
|
+
}
|
|
20
|
+
function hasBinaryExt(relativePath) {
|
|
21
|
+
const idx = relativePath.lastIndexOf(".");
|
|
22
|
+
if (idx < 0)
|
|
23
|
+
return false;
|
|
24
|
+
const ext = relativePath.slice(idx + 1).toLowerCase();
|
|
25
|
+
return BINARY_EXT.includes(ext);
|
|
26
|
+
}
|
|
27
|
+
function isIncludeOverride(relativePath, includeOverrides) {
|
|
28
|
+
return includeOverrides.some((prefix) => relativePath.startsWith(prefix));
|
|
29
|
+
}
|
|
30
|
+
export function planIngestFiles(input, files) {
|
|
31
|
+
const includeOverrides = input.include_overrides ?? [];
|
|
32
|
+
const maxFileBytes = input.max_file_bytes ?? DEFAULT_MAX_FILE_BYTES;
|
|
33
|
+
return files.map((file) => {
|
|
34
|
+
const bytes = file.bytes ?? Buffer.byteLength(file.content, "utf8");
|
|
35
|
+
const fileId = buildFileId(input.project_id, file.relative_path);
|
|
36
|
+
const checksum = checksumOf(file.content);
|
|
37
|
+
if (isIncludeOverride(file.relative_path, includeOverrides)) {
|
|
38
|
+
return {
|
|
39
|
+
relative_path: file.relative_path,
|
|
40
|
+
file_id: fileId,
|
|
41
|
+
include: true,
|
|
42
|
+
reason: "included",
|
|
43
|
+
checksum,
|
|
44
|
+
bytes,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (isIgnoredPath(file.relative_path)) {
|
|
48
|
+
return {
|
|
49
|
+
relative_path: file.relative_path,
|
|
50
|
+
file_id: fileId,
|
|
51
|
+
include: false,
|
|
52
|
+
reason: "ignored_path",
|
|
53
|
+
checksum,
|
|
54
|
+
bytes,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (hasBinaryExt(file.relative_path)) {
|
|
58
|
+
return {
|
|
59
|
+
relative_path: file.relative_path,
|
|
60
|
+
file_id: fileId,
|
|
61
|
+
include: false,
|
|
62
|
+
reason: "binary_ext",
|
|
63
|
+
checksum,
|
|
64
|
+
bytes,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (bytes > maxFileBytes) {
|
|
68
|
+
return {
|
|
69
|
+
relative_path: file.relative_path,
|
|
70
|
+
file_id: fileId,
|
|
71
|
+
include: false,
|
|
72
|
+
reason: "oversized",
|
|
73
|
+
checksum,
|
|
74
|
+
bytes,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
relative_path: file.relative_path,
|
|
79
|
+
file_id: fileId,
|
|
80
|
+
include: true,
|
|
81
|
+
reason: "included",
|
|
82
|
+
checksum,
|
|
83
|
+
bytes,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
export function buildChunkArtifacts(projectId, fileId, relativePath, blocks) {
|
|
88
|
+
return blocks.map((block, ordinal) => {
|
|
89
|
+
const symbolId = ["function", "class", "method"].includes(block.kind)
|
|
90
|
+
? buildSymbolId(projectId, relativePath, block.semantic_path)
|
|
91
|
+
: null;
|
|
92
|
+
return {
|
|
93
|
+
chunk_id: buildChunkId(fileId, block.kind, block.semantic_path, ordinal),
|
|
94
|
+
file_id: fileId,
|
|
95
|
+
relative_path: relativePath,
|
|
96
|
+
chunk_kind: block.kind,
|
|
97
|
+
symbol_id: symbolId,
|
|
98
|
+
checksum: checksumOf(block.text),
|
|
99
|
+
semantic_path: block.semantic_path,
|
|
100
|
+
ordinal,
|
|
101
|
+
text: block.text,
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=ingest-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest-pipeline.js","sourceRoot":"","sources":["../../../src/core/ingest/ingest-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SemanticBlock } from "./contracts.js";
|
|
2
|
+
interface ExtractInput {
|
|
3
|
+
relativePath: string;
|
|
4
|
+
content: string;
|
|
5
|
+
maxDocChunkChars?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function extractSemanticBlocks(input: ExtractInput): SemanticBlock[];
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=semantic-block-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-block-extractor.d.ts","sourceRoot":"","sources":["../../../src/core/ingest/semantic-block-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,UAAU,YAAY;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA8ID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,EAAE,CAS1E"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const DEFAULT_MAX_DOC_CHUNK = 1400;
|
|
2
|
+
function ext(path) {
|
|
3
|
+
const idx = path.lastIndexOf(".");
|
|
4
|
+
return idx >= 0 ? path.slice(idx + 1).toLowerCase() : "";
|
|
5
|
+
}
|
|
6
|
+
function isCodeLike(path) {
|
|
7
|
+
return ["ts", "tsx", "js", "jsx", "mjs", "cjs", "py", "go", "java", "rs"].includes(ext(path));
|
|
8
|
+
}
|
|
9
|
+
function lineOf(content, offset) {
|
|
10
|
+
return content.slice(0, offset).split("\n").length;
|
|
11
|
+
}
|
|
12
|
+
function findBalancedBlock(content, startOffset) {
|
|
13
|
+
const firstBrace = content.indexOf("{", startOffset);
|
|
14
|
+
if (firstBrace < 0) {
|
|
15
|
+
const lineEnd = content.indexOf("\n", startOffset);
|
|
16
|
+
const endOffset = lineEnd >= 0 ? lineEnd : content.length;
|
|
17
|
+
return { text: content.slice(startOffset, endOffset), endOffset };
|
|
18
|
+
}
|
|
19
|
+
let depth = 0;
|
|
20
|
+
for (let i = firstBrace; i < content.length; i++) {
|
|
21
|
+
const ch = content[i];
|
|
22
|
+
if (ch === "{")
|
|
23
|
+
depth += 1;
|
|
24
|
+
else if (ch === "}") {
|
|
25
|
+
depth -= 1;
|
|
26
|
+
if (depth === 0) {
|
|
27
|
+
return { text: content.slice(startOffset, i + 1), endOffset: i + 1 };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { text: content.slice(startOffset), endOffset: content.length };
|
|
32
|
+
}
|
|
33
|
+
function extractCodeBlocks(relativePath, content) {
|
|
34
|
+
const blocks = [];
|
|
35
|
+
const classRegex = /^\s*(?:export\s+)?class\s+([A-Za-z_][\w$]*)/gm;
|
|
36
|
+
const functionRegex = /^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_][\w$]*)\s*\(/gm;
|
|
37
|
+
const methodRegex = /^\s{2,}(?:public\s+|private\s+|protected\s+|static\s+|async\s+)*(?!if\b|for\b|while\b|switch\b|catch\b|return\b|throw\b|else\b)([A-Za-z_][\w$]*)\s*\([^\)]*\)\s*\{/gm;
|
|
38
|
+
const disallowedMethodNames = new Set(["if", "for", "while", "switch", "catch", "return", "throw", "else"]);
|
|
39
|
+
let match;
|
|
40
|
+
while ((match = classRegex.exec(content))) {
|
|
41
|
+
const symbolName = match[1];
|
|
42
|
+
const start = match.index;
|
|
43
|
+
const block = findBalancedBlock(content, start);
|
|
44
|
+
blocks.push({
|
|
45
|
+
kind: "class",
|
|
46
|
+
symbol_name: symbolName,
|
|
47
|
+
semantic_path: `class:${symbolName}`,
|
|
48
|
+
start_line: lineOf(content, start),
|
|
49
|
+
end_line: lineOf(content, block.endOffset),
|
|
50
|
+
ordinal: blocks.length,
|
|
51
|
+
text: block.text,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
while ((match = functionRegex.exec(content))) {
|
|
55
|
+
const symbolName = match[1];
|
|
56
|
+
const start = match.index;
|
|
57
|
+
const block = findBalancedBlock(content, start);
|
|
58
|
+
blocks.push({
|
|
59
|
+
kind: "function",
|
|
60
|
+
symbol_name: symbolName,
|
|
61
|
+
semantic_path: `function:${symbolName}`,
|
|
62
|
+
start_line: lineOf(content, start),
|
|
63
|
+
end_line: lineOf(content, block.endOffset),
|
|
64
|
+
ordinal: blocks.length,
|
|
65
|
+
text: block.text,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
while ((match = methodRegex.exec(content))) {
|
|
69
|
+
const symbolName = match[1];
|
|
70
|
+
if (disallowedMethodNames.has(symbolName))
|
|
71
|
+
continue;
|
|
72
|
+
const start = match.index;
|
|
73
|
+
const block = findBalancedBlock(content, start);
|
|
74
|
+
blocks.push({
|
|
75
|
+
kind: "method",
|
|
76
|
+
symbol_name: symbolName,
|
|
77
|
+
semantic_path: `method:${symbolName}`,
|
|
78
|
+
start_line: lineOf(content, start),
|
|
79
|
+
end_line: lineOf(content, block.endOffset),
|
|
80
|
+
ordinal: blocks.length,
|
|
81
|
+
text: block.text,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return blocks
|
|
85
|
+
.filter((b, idx, arr) => arr.findIndex((x) => x.semantic_path === b.semantic_path && x.start_line === b.start_line) === idx)
|
|
86
|
+
.sort((a, b) => a.start_line - b.start_line)
|
|
87
|
+
.map((b, i) => ({ ...b, ordinal: i }));
|
|
88
|
+
}
|
|
89
|
+
function extractDocBlocks(content, maxDocChunkChars) {
|
|
90
|
+
const blocks = [];
|
|
91
|
+
const sections = content
|
|
92
|
+
.split(/\n(?=#{1,3}\s+)/g)
|
|
93
|
+
.map((s) => s.trim())
|
|
94
|
+
.filter(Boolean);
|
|
95
|
+
const sourceSections = sections.length > 0 ? sections : [content];
|
|
96
|
+
for (const section of sourceSections) {
|
|
97
|
+
if (section.length <= maxDocChunkChars) {
|
|
98
|
+
blocks.push({
|
|
99
|
+
kind: section.startsWith("#") ? "doc_section" : "doc_paragraph",
|
|
100
|
+
symbol_name: "doc",
|
|
101
|
+
semantic_path: section.startsWith("#") ? "doc:section" : "doc:paragraph",
|
|
102
|
+
start_line: 1,
|
|
103
|
+
end_line: section.split("\n").length,
|
|
104
|
+
ordinal: blocks.length,
|
|
105
|
+
text: section,
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
let cursor = 0;
|
|
110
|
+
while (cursor < section.length) {
|
|
111
|
+
const slice = section.slice(cursor, cursor + maxDocChunkChars);
|
|
112
|
+
blocks.push({
|
|
113
|
+
kind: "doc_paragraph",
|
|
114
|
+
symbol_name: "doc",
|
|
115
|
+
semantic_path: "doc:paragraph",
|
|
116
|
+
start_line: 1,
|
|
117
|
+
end_line: slice.split("\n").length,
|
|
118
|
+
ordinal: blocks.length,
|
|
119
|
+
text: slice,
|
|
120
|
+
});
|
|
121
|
+
cursor += maxDocChunkChars;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return blocks.map((b, i) => ({ ...b, ordinal: i }));
|
|
125
|
+
}
|
|
126
|
+
export function extractSemanticBlocks(input) {
|
|
127
|
+
const maxDocChunkChars = Math.max(300, input.maxDocChunkChars ?? DEFAULT_MAX_DOC_CHUNK);
|
|
128
|
+
if (isCodeLike(input.relativePath)) {
|
|
129
|
+
const codeBlocks = extractCodeBlocks(input.relativePath, input.content);
|
|
130
|
+
if (codeBlocks.length > 0)
|
|
131
|
+
return codeBlocks;
|
|
132
|
+
}
|
|
133
|
+
return extractDocBlocks(input.content, maxDocChunkChars);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=semantic-block-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-block-extractor.js","sourceRoot":"","sources":["../../../src/core/ingest/semantic-block-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ export declare class DefaultMemoryUseCasePort implements MemoryUseCasePort {
|
|
|
20
20
|
private handleProjectTriggerIndex;
|
|
21
21
|
private scheduleProjectReindexJob;
|
|
22
22
|
private resolveProjectRef;
|
|
23
|
+
private installProjectGitHooks;
|
|
23
24
|
private validateJiraTrackerFields;
|
|
24
25
|
private tryResolveRepoRootFromCwd;
|
|
25
26
|
private resolveWorkspaceRoot;
|
|
@@ -37,6 +38,8 @@ export declare class DefaultMemoryUseCasePort implements MemoryUseCasePort {
|
|
|
37
38
|
private tryReadGitRemote;
|
|
38
39
|
private collectGitTrackedPaths;
|
|
39
40
|
private handleProjectReindexDiff;
|
|
41
|
+
private handleProjectIndexEvent;
|
|
42
|
+
private handleProjectInstallHooks;
|
|
40
43
|
private handleProjectIndexWatchGet;
|
|
41
44
|
private handleProjectTaskRegistryUpsert;
|
|
42
45
|
private handleProjectTaskLineageContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-memory-usecase-port.d.ts","sourceRoot":"","sources":["../../../src/core/usecases/default-memory-usecase-port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"default-memory-usecase-port.d.ts","sourceRoot":"","sources":["../../../src/core/usecases/default-memory-usecase-port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mCAAmC,CAAC;AAO3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AA4U1E,qBAAa,wBAAyB,YAAW,iBAAiB;IAE9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;gBADhB,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,qBAAqB,YAAA;IAGpD,GAAG,CAAC,IAAI,EAAE,IAAI,EAClB,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC;IAiEhB,OAAO,CAAC,aAAa;IAqDrB,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,iCAAiC;IAkBzC,OAAO,CAAC,8BAA8B;IAuBtC,OAAO,CAAC,4BAA4B;IAiHpC,OAAO,CAAC,wBAAwB;IAyChC,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,yBAAyB;IA0CjC,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,0BAA0B;IAgGlC,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,6BAA6B;IAuBrC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,gBAAgB;IAmDxB,OAAO,CAAC,0BAA0B;IAkBlC,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,sBAAsB;IA+E9B,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,uBAAuB;IAyD/B,OAAO,CAAC,yBAAyB;IAYjC,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,+BAA+B;IAwBvC,OAAO,CAAC,+BAA+B;IAqBvC,OAAO,CAAC,yBAAyB;IAoBjC,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,+BAA+B;IAmIvC,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,oBAAoB;IA0B5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,oBAAoB;YAuBd,mBAAmB;YAOnB,kBAAkB;IAOhC,OAAO,CAAC,iBAAiB;CAmB1B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { existsSync, mkdirSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { basename, dirname, isAbsolute, resolve } from "node:path";
|
|
5
5
|
function asRecord(value) {
|
|
6
6
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
@@ -75,6 +75,10 @@ export class DefaultMemoryUseCasePort {
|
|
|
75
75
|
return this.handleProjectTriggerIndex(payload, req);
|
|
76
76
|
case "project.reindex_diff":
|
|
77
77
|
return this.handleProjectReindexDiff(payload, req);
|
|
78
|
+
case "project.index_event":
|
|
79
|
+
return this.handleProjectIndexEvent(payload, req);
|
|
80
|
+
case "project.install_hooks":
|
|
81
|
+
return this.handleProjectInstallHooks(payload, req);
|
|
78
82
|
case "project.index_watch_get":
|
|
79
83
|
return this.handleProjectIndexWatchGet(payload, req);
|
|
80
84
|
case "project.task_registry_upsert":
|
|
@@ -349,6 +353,7 @@ export class DefaultMemoryUseCasePort {
|
|
|
349
353
|
note: triggerResult?.note || null,
|
|
350
354
|
};
|
|
351
355
|
}
|
|
356
|
+
const autoIndexHook = this.installProjectGitHooks(registered.project.project_id, registered.project.repo_root);
|
|
352
357
|
return {
|
|
353
358
|
project_id: registered.project.project_id,
|
|
354
359
|
project_alias: registered.alias.project_alias,
|
|
@@ -356,6 +361,7 @@ export class DefaultMemoryUseCasePort {
|
|
|
356
361
|
validation_status: registered.registration.validation_status,
|
|
357
362
|
completeness_score: Number((registered.registration.completeness_score / 100).toFixed(2)),
|
|
358
363
|
warnings: [],
|
|
364
|
+
auto_index_hook: autoIndexHook,
|
|
359
365
|
repo_resolution: {
|
|
360
366
|
resolution: selection.resolution,
|
|
361
367
|
clone_policy: selection.clone_policy || "not_applicable",
|
|
@@ -460,6 +466,7 @@ export class DefaultMemoryUseCasePort {
|
|
|
460
466
|
source_rev: input.sourceRev,
|
|
461
467
|
trigger_type: input.triggerType,
|
|
462
468
|
index_profile: input.indexProfile,
|
|
469
|
+
full_snapshot: input.triggerType === "bootstrap",
|
|
463
470
|
paths,
|
|
464
471
|
});
|
|
465
472
|
}
|
|
@@ -483,6 +490,31 @@ export class DefaultMemoryUseCasePort {
|
|
|
483
490
|
}
|
|
484
491
|
throw new Error("project reference requires project_id or project_alias");
|
|
485
492
|
}
|
|
493
|
+
installProjectGitHooks(projectId, repoRoot) {
|
|
494
|
+
if (!repoRoot)
|
|
495
|
+
return { installed: false, hooks: [], note: 'repo_root_missing' };
|
|
496
|
+
const gitDir = resolve(repoRoot, '.git');
|
|
497
|
+
const hooksDir = resolve(gitDir, 'hooks');
|
|
498
|
+
if (!existsSync(gitDir))
|
|
499
|
+
return { installed: false, hooks: [], note: 'git_dir_missing' };
|
|
500
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
501
|
+
const writeHook = (name, eventType) => {
|
|
502
|
+
const hookPath = resolve(hooksDir, name);
|
|
503
|
+
const script = `#!/bin/sh
|
|
504
|
+
PROJECT_ID="${projectId}"
|
|
505
|
+
REPO_ROOT="${repoRoot}"
|
|
506
|
+
SOURCE_REV="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
|
507
|
+
CHANGED_FILES="$(git diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null | paste -sd, -)"
|
|
508
|
+
DELETED_FILES="$(git diff-tree --no-commit-id --name-only --diff-filter=D -r HEAD 2>/dev/null | paste -sd, -)"
|
|
509
|
+
asm project-event --project-id "$PROJECT_ID" --repo-root "$REPO_ROOT" --event-type ${eventType} --source-rev "$SOURCE_REV" --changed-files "$CHANGED_FILES" --deleted-files "$DELETED_FILES" >/dev/null 2>&1 || true
|
|
510
|
+
`;
|
|
511
|
+
writeFileSync(hookPath, script, 'utf8');
|
|
512
|
+
chmodSync(hookPath, 0o755);
|
|
513
|
+
return hookPath;
|
|
514
|
+
};
|
|
515
|
+
const hooks = [writeHook('post-commit', 'post_commit'), writeHook('post-merge', 'post_merge')];
|
|
516
|
+
return { installed: true, hooks };
|
|
517
|
+
}
|
|
486
518
|
validateJiraTrackerFields(trackerSpaceKey, defaultEpicKey) {
|
|
487
519
|
const space = String(trackerSpaceKey || "").trim();
|
|
488
520
|
if (!space) {
|
|
@@ -800,18 +832,24 @@ export class DefaultMemoryUseCasePort {
|
|
|
800
832
|
.split("\n")
|
|
801
833
|
.map((line) => line.trim())
|
|
802
834
|
.filter(Boolean);
|
|
803
|
-
|
|
804
|
-
.filter((rel) => existsSync(resolve(repoRoot, rel)));
|
|
805
|
-
const merged = Array.from(new Set([...paths, ...supplemental]));
|
|
806
|
-
return merged
|
|
835
|
+
return paths
|
|
807
836
|
.filter((p) => !p.startsWith(".git/"))
|
|
808
837
|
.map((relativePath) => {
|
|
809
838
|
const ext = relativePath.includes(".") ? relativePath.split(".").pop() || "" : "";
|
|
839
|
+
const abs = resolve(repoRoot, relativePath);
|
|
840
|
+
let content;
|
|
841
|
+
try {
|
|
842
|
+
content = readFileSync(abs, "utf8");
|
|
843
|
+
}
|
|
844
|
+
catch {
|
|
845
|
+
content = undefined;
|
|
846
|
+
}
|
|
810
847
|
return {
|
|
811
848
|
relative_path: relativePath,
|
|
812
|
-
checksum:
|
|
849
|
+
checksum: `git:${relativePath}`,
|
|
813
850
|
module: relativePath.split("/")[0] || undefined,
|
|
814
851
|
language: ext || undefined,
|
|
852
|
+
content,
|
|
815
853
|
};
|
|
816
854
|
});
|
|
817
855
|
}
|
|
@@ -838,12 +876,23 @@ export class DefaultMemoryUseCasePort {
|
|
|
838
876
|
catch {
|
|
839
877
|
return [];
|
|
840
878
|
}
|
|
841
|
-
return files.map((relativePath) =>
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
879
|
+
return files.map((relativePath) => {
|
|
880
|
+
const abs = resolve(repoRoot, relativePath);
|
|
881
|
+
let content;
|
|
882
|
+
try {
|
|
883
|
+
content = readFileSync(abs, "utf8");
|
|
884
|
+
}
|
|
885
|
+
catch {
|
|
886
|
+
content = undefined;
|
|
887
|
+
}
|
|
888
|
+
return {
|
|
889
|
+
relative_path: relativePath,
|
|
890
|
+
checksum: `fs:${relativePath}`,
|
|
891
|
+
module: relativePath.split("/")[0] || undefined,
|
|
892
|
+
language: relativePath.includes(".") ? relativePath.split(".").pop() || undefined : undefined,
|
|
893
|
+
content,
|
|
894
|
+
};
|
|
895
|
+
});
|
|
847
896
|
}
|
|
848
897
|
}
|
|
849
898
|
handleProjectReindexDiff(payload, req) {
|
|
@@ -856,9 +905,72 @@ export class DefaultMemoryUseCasePort {
|
|
|
856
905
|
source_rev: payload.source_rev,
|
|
857
906
|
trigger_type: payload.trigger_type,
|
|
858
907
|
index_profile: payload.index_profile,
|
|
908
|
+
full_snapshot: payload.full_snapshot === true,
|
|
859
909
|
paths: payload.paths || [],
|
|
860
910
|
});
|
|
861
911
|
}
|
|
912
|
+
handleProjectIndexEvent(payload, req) {
|
|
913
|
+
const identity = normalizePrivateIdentity(req.context);
|
|
914
|
+
if (!payload.project_id) {
|
|
915
|
+
throw new Error("project.index_event requires payload.project_id");
|
|
916
|
+
}
|
|
917
|
+
const project = this.slotDb.getProjectById(identity.userId, identity.agentId, payload.project_id);
|
|
918
|
+
if (!project || !project.repo_root) {
|
|
919
|
+
throw new Error("project.index_event requires a registered project with repo_root");
|
|
920
|
+
}
|
|
921
|
+
const changedFiles = Array.from(new Set((payload.changed_files || []).map((x) => String(x || "").trim()).filter(Boolean)));
|
|
922
|
+
const deletedFiles = Array.from(new Set((payload.deleted_files || []).map((x) => String(x || "").trim()).filter(Boolean)));
|
|
923
|
+
const paths = changedFiles.map((relativePath) => {
|
|
924
|
+
const abs = resolve(project.repo_root, relativePath);
|
|
925
|
+
let content = null;
|
|
926
|
+
try {
|
|
927
|
+
content = readFileSync(abs, "utf8");
|
|
928
|
+
}
|
|
929
|
+
catch {
|
|
930
|
+
content = null;
|
|
931
|
+
}
|
|
932
|
+
return {
|
|
933
|
+
relative_path: relativePath,
|
|
934
|
+
checksum: `event:${relativePath}:${payload.source_rev || "unknown"}`,
|
|
935
|
+
module: relativePath.split("/")[0] || undefined,
|
|
936
|
+
language: relativePath.includes(".") ? relativePath.split(".").pop() || undefined : undefined,
|
|
937
|
+
content,
|
|
938
|
+
};
|
|
939
|
+
});
|
|
940
|
+
const reindex = this.slotDb.reindexProjectByDiff(identity.userId, identity.agentId, {
|
|
941
|
+
project_id: payload.project_id,
|
|
942
|
+
source_rev: payload.source_rev || null,
|
|
943
|
+
trigger_type: "incremental",
|
|
944
|
+
index_profile: "default",
|
|
945
|
+
full_snapshot: false,
|
|
946
|
+
paths,
|
|
947
|
+
});
|
|
948
|
+
if (deletedFiles.length > 0) {
|
|
949
|
+
const tombstoneAt = new Date().toISOString();
|
|
950
|
+
for (const relativePath of deletedFiles) {
|
|
951
|
+
this.slotDb.markProjectFileDeletedForEvent(identity.userId, identity.agentId, payload.project_id, relativePath, tombstoneAt);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
return {
|
|
955
|
+
project_id: payload.project_id,
|
|
956
|
+
event_type: payload.event_type || "manual",
|
|
957
|
+
source_rev: payload.source_rev || null,
|
|
958
|
+
changed_files: changedFiles,
|
|
959
|
+
deleted_files: deletedFiles,
|
|
960
|
+
reindex,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
handleProjectInstallHooks(payload, req) {
|
|
964
|
+
const identity = normalizePrivateIdentity(req.context);
|
|
965
|
+
if (!payload.project_id) {
|
|
966
|
+
throw new Error("project.install_hooks requires payload.project_id");
|
|
967
|
+
}
|
|
968
|
+
const project = this.slotDb.getProjectById(identity.userId, identity.agentId, payload.project_id);
|
|
969
|
+
if (!project) {
|
|
970
|
+
throw new Error("project.install_hooks requires a registered project");
|
|
971
|
+
}
|
|
972
|
+
return this.installProjectGitHooks(project.project_id, project.repo_root);
|
|
973
|
+
}
|
|
862
974
|
handleProjectIndexWatchGet(payload, req) {
|
|
863
975
|
const identity = normalizePrivateIdentity(req.context);
|
|
864
976
|
if (!payload.project_id) {
|