@mrc2204/agent-smart-memo 5.0.2 → 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 +122 -7
- 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 +143 -8
- 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) {
|
|
@@ -804,11 +836,20 @@ export class DefaultMemoryUseCasePort {
|
|
|
804
836
|
.filter((p) => !p.startsWith(".git/"))
|
|
805
837
|
.map((relativePath) => {
|
|
806
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
|
+
}
|
|
807
847
|
return {
|
|
808
848
|
relative_path: relativePath,
|
|
809
849
|
checksum: `git:${relativePath}`,
|
|
810
850
|
module: relativePath.split("/")[0] || undefined,
|
|
811
851
|
language: ext || undefined,
|
|
852
|
+
content,
|
|
812
853
|
};
|
|
813
854
|
});
|
|
814
855
|
}
|
|
@@ -835,12 +876,23 @@ export class DefaultMemoryUseCasePort {
|
|
|
835
876
|
catch {
|
|
836
877
|
return [];
|
|
837
878
|
}
|
|
838
|
-
return files.map((relativePath) =>
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
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
|
+
});
|
|
844
896
|
}
|
|
845
897
|
}
|
|
846
898
|
handleProjectReindexDiff(payload, req) {
|
|
@@ -853,9 +905,72 @@ export class DefaultMemoryUseCasePort {
|
|
|
853
905
|
source_rev: payload.source_rev,
|
|
854
906
|
trigger_type: payload.trigger_type,
|
|
855
907
|
index_profile: payload.index_profile,
|
|
908
|
+
full_snapshot: payload.full_snapshot === true,
|
|
856
909
|
paths: payload.paths || [],
|
|
857
910
|
});
|
|
858
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
|
+
}
|
|
859
974
|
handleProjectIndexWatchGet(payload, req) {
|
|
860
975
|
const identity = normalizePrivateIdentity(req.context);
|
|
861
976
|
if (!payload.project_id) {
|