@massa-ai/core 1.14.0 → 1.16.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/services/search/contextual-search-rlm.d.ts +35 -14
- package/dist/services/search/contextual-search-rlm.d.ts.map +1 -1
- package/dist/services/search/contextual-search-rlm.js +274 -53
- package/dist/services/search/contextual-search-rlm.js.map +1 -1
- package/dist/services/search/graph-stream.d.ts +36 -0
- package/dist/services/search/graph-stream.d.ts.map +1 -0
- package/dist/services/search/{rlm-synapse.js → graph-stream.js} +11 -90
- package/dist/services/search/graph-stream.js.map +1 -0
- package/dist/services/search/hybrid-search.d.ts +101 -0
- package/dist/services/search/hybrid-search.d.ts.map +1 -0
- package/dist/services/search/{rlm-search.js → hybrid-search.js} +89 -46
- package/dist/services/search/hybrid-search.js.map +1 -0
- package/dist/services/search/index-admin.d.ts +130 -0
- package/dist/services/search/index-admin.d.ts.map +1 -0
- package/dist/services/search/{rlm-admin.js → index-admin.js} +34 -18
- package/dist/services/search/index-admin.js.map +1 -0
- package/dist/services/search/project-indexer.d.ts +159 -0
- package/dist/services/search/project-indexer.d.ts.map +1 -0
- package/dist/services/search/{rlm-indexing.js → project-indexer.js} +51 -79
- package/dist/services/search/project-indexer.js.map +1 -0
- package/dist/services/search/session-bias.d.ts +41 -0
- package/dist/services/search/session-bias.d.ts.map +1 -0
- package/dist/services/search/session-bias.js +76 -0
- package/dist/services/search/session-bias.js.map +1 -0
- package/package.json +2 -2
- package/dist/services/search/rlm-admin.d.ts +0 -22
- package/dist/services/search/rlm-admin.d.ts.map +0 -1
- package/dist/services/search/rlm-admin.js.map +0 -1
- package/dist/services/search/rlm-indexing.d.ts +0 -71
- package/dist/services/search/rlm-indexing.d.ts.map +0 -1
- package/dist/services/search/rlm-indexing.js.map +0 -1
- package/dist/services/search/rlm-search.d.ts +0 -27
- package/dist/services/search/rlm-search.d.ts.map +0 -1
- package/dist/services/search/rlm-search.js.map +0 -1
- package/dist/services/search/rlm-synapse.d.ts +0 -44
- package/dist/services/search/rlm-synapse.d.ts.map +0 -1
- package/dist/services/search/rlm-synapse.js.map +0 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index-admin — the index administration capability (design.md §4.1).
|
|
3
|
+
*
|
|
4
|
+
* PR-B capability module. Takes `IndexAdminDeps` — the collaborators §2.1 shows
|
|
5
|
+
* these surfaces read — in place of the facade instance they used to receive as
|
|
6
|
+
* `rlm` (GMS-03 AC-1). The file has never heard of ContextualSearchRLM, so it
|
|
7
|
+
* contributes nothing to the root's foreign reach (G-HUB, design.md §3.4).
|
|
8
|
+
*
|
|
9
|
+
* `await rlm.ensureInitialized()` is **gone from the three bodies that had it**.
|
|
10
|
+
* It was the literal first statement of `clearProjectIndex`, `getProjectStats`
|
|
11
|
+
* and `warmupCache`, and it is now the literal first statement of the three
|
|
12
|
+
* facade methods that call them — design.md §4.5(b) and the §4.3 sketch. Order is
|
|
13
|
+
* unchanged: the root awaits init, *then* assembles the deps record, so the
|
|
14
|
+
* fields this module reads are populated exactly as before. `getAnalytics` never
|
|
15
|
+
* called it and still does not; adding one would be a behavior change, not a
|
|
16
|
+
* tidy-up, and it is also the one delegate left with no `await` ahead of it,
|
|
17
|
+
* which is what makes it this task's blind-recursion mutation subject
|
|
18
|
+
* (tasks.md, "The mutation shape matters").
|
|
19
|
+
*
|
|
20
|
+
* LATE-BIND (design.md §4.3.1): the root assembles this record per call from its
|
|
21
|
+
* current field values. Nothing here captures a collaborator.
|
|
22
|
+
*
|
|
23
|
+
* Behavior is byte-preserved from rlm-admin.ts: the bodies moved verbatim with
|
|
24
|
+
* `rlm.` → `deps.` and the hoisted init statement removed.
|
|
25
|
+
*/
|
|
26
|
+
import type { SearchResult } from "@massa-ai/shared";
|
|
27
|
+
import { SearchAnalytics } from "./search-analytics.js";
|
|
28
|
+
import type { SearchAnalyticsPg } from "./search-analytics-pg.js";
|
|
29
|
+
import type { FileFilterCache } from "./file-filter-cache.js";
|
|
30
|
+
import type { getKeywordSearch } from "../../data/keyword/keyword-search-factory.js";
|
|
31
|
+
import type { getVectorStore } from "../../data/vector/vector-store-factory.js";
|
|
32
|
+
import type { getSearchCache } from "./cache-factory.js";
|
|
33
|
+
/**
|
|
34
|
+
* The narrow dependency record for this module (design.md §4.4) — exactly the
|
|
35
|
+
* collaborators §2.1 shows these surfaces read, minus `ensureInitialized`, which
|
|
36
|
+
* the root hoisted.
|
|
37
|
+
*
|
|
38
|
+
* The three stores are required and carry the root's own field types: their
|
|
39
|
+
* originals were bare `rlm.<store>.<method>` reads off definite-assigned fields
|
|
40
|
+
* with no fallback, so an absent store must keep throwing exactly where it did.
|
|
41
|
+
* They are structural (`Awaited<ReturnType<typeof …>>`), which is why they never
|
|
42
|
+
* touch the hub metric — see the two nominal fields below, which do not either,
|
|
43
|
+
* but for reasons that had to be measured rather than assumed.
|
|
44
|
+
*
|
|
45
|
+
* **`search` is a re-entrant seam, not a store.** design.md §4.1's "injected
|
|
46
|
+
* collaborators" column says "six stores + `fileFilterCache`", which is both an
|
|
47
|
+
* over-count (three stores are read, not six) and an omission: §2.1 records
|
|
48
|
+
* `warmupCacheImpl` reading the facade's `search` **method**, and §12 item 4
|
|
49
|
+
* orders index-admin *before* hybrid-search, so at T12 there is no
|
|
50
|
+
* `hybrid-search.search` to import — the collaborator is the root's own method,
|
|
51
|
+
* reached back through a per-call arrow wrapper exactly as `IndexerDeps` reaches
|
|
52
|
+
* `indexFile` / `indexProject` at T10.
|
|
53
|
+
*
|
|
54
|
+
* It is load-bearing, and the sensor for it is new rather than pre-existing.
|
|
55
|
+
* Measured: `rlm.search` is stubbed at **7 instance-method sites** —
|
|
56
|
+
* `search-facade-admin.test.ts:124,137,148` and
|
|
57
|
+
* `contextual-search-rlm-coverage.test.ts:382,395,407,416` — as bare assignments
|
|
58
|
+
* with no `as any` cast, so the established PATCHABLE regex does not find them
|
|
59
|
+
* (the same shape T10 registered for `indexFile`/`indexProject`, and `git grep
|
|
60
|
+
* -E` cannot even express the sweep: POSIX ERE has no `\s`, so the first pass
|
|
61
|
+
* silently reported zero). Every one of those 7 sites is exercised *through*
|
|
62
|
+
* `warmupCache`, and they are also the *only* 7 calls to `warmupCache` in the
|
|
63
|
+
* suite — so **no pre-existing test ever runs `warmupCache` against the real
|
|
64
|
+
* `search`**, and all 7 assign before they call. That makes a bare
|
|
65
|
+
* `search: this.search` reference or a `.bind(this)` at assembly time invisible
|
|
66
|
+
* to the entire pre-existing suite: both would still capture the stub, because a
|
|
67
|
+
* per-call assembly happens after the assignment. `index-admin-late-bind.test.ts`
|
|
68
|
+
* test 4 is the only thing in the repository that can see the difference.
|
|
69
|
+
*
|
|
70
|
+
* **Neither nominal field fires T10's seventh defect, and both reasons are
|
|
71
|
+
* measured.** That defect — a bare nominal type declared inside
|
|
72
|
+
* `services/search/` being captured as a binding by `search-hub-metric.ts:139`'s
|
|
73
|
+
* `([A-Za-z0-9_]+)\s*:\s*<Type>\b` — took `IndexManager`'s `maxForeignReach` from
|
|
74
|
+
* 0 to 4 at T10. tasks.md T12's row predicts both fields here "will" fire because
|
|
75
|
+
* they are required rather than optional (T11's `?` guard). Measured, they do not:
|
|
76
|
+
*
|
|
77
|
+
* - `analytics` cannot fire at all. `SearchAnalytics` is a **stripped re-export
|
|
78
|
+
* alias** (`search-analytics.ts` is one `export … from` line, and
|
|
79
|
+
* `stripNonCode` deletes exactly those), so it never enters `declaredIn` and
|
|
80
|
+
* never appears in the metric's output. `SearchAnalyticsPg` *is* declared, but
|
|
81
|
+
* only ever occurs here after `| `, never in `<name>:` position, so no binding
|
|
82
|
+
* is captured. And independently: `getAnalytics` returns `deps.analytics`
|
|
83
|
+
* **whole** and never dereferences it, so `perModule` gains nothing either way
|
|
84
|
+
* — the same route by which T11's `indexManager` and T7's `_rlm` contributed
|
|
85
|
+
* zero. It is therefore **deliberately not `Pick<>`-narrowed**, against the
|
|
86
|
+
* row's instruction: narrowing would also break `type-check`, because the value
|
|
87
|
+
* is returned through the root's public `getAnalytics(): SearchAnalytics |
|
|
88
|
+
* SearchAnalyticsPg`, a compatibility surface for 24 importers. Same reason the
|
|
89
|
+
* `Pick<>` decision did not generalise to T11's seam field.
|
|
90
|
+
* - `fileFilterCache` *is* captured and *is* dereferenced once
|
|
91
|
+
* (`invalidateProject`), so un-narrowed it moves `FileFilterCache` from foreign
|
|
92
|
+
* 0 / reach 0 to foreign 1 / reach **1**. That is under `MAX_FOREIGN_REACH`
|
|
93
|
+
* (3), so unlike T10's reach-4 case it produces **no second G-HUB violation**
|
|
94
|
+
* and would not have made T14's gate unclosable. The `Pick<>` below is kept
|
|
95
|
+
* because §4.4 says a record holds exactly what is read and it is the honest
|
|
96
|
+
* type — **not** because a sensor fired. Both variants were measured by scratch
|
|
97
|
+
* simulation before this file was applied.
|
|
98
|
+
*/
|
|
99
|
+
export interface IndexAdminDeps {
|
|
100
|
+
vectorStore: Awaited<ReturnType<typeof getVectorStore>>;
|
|
101
|
+
keywordSearch: Awaited<ReturnType<typeof getKeywordSearch>>;
|
|
102
|
+
searchCache: Awaited<ReturnType<typeof getSearchCache>>;
|
|
103
|
+
fileFilterCache: Pick<FileFilterCache, "invalidateProject">;
|
|
104
|
+
analytics: SearchAnalytics | SearchAnalyticsPg;
|
|
105
|
+
/**
|
|
106
|
+
* The root's own `search`, as a per-call arrow wrapper that re-reads
|
|
107
|
+
* `this.search` at **call** time. Not `.bind(this)` and not a bare method
|
|
108
|
+
* reference: both resolve the method at *assembly* time, and see the 7 stub
|
|
109
|
+
* sites above for why that is the failure this record exists to prevent.
|
|
110
|
+
* Typed with exactly the options `warmupCache` passes (§4.4), not the facade's
|
|
111
|
+
* full option bag.
|
|
112
|
+
*/
|
|
113
|
+
search: (query: string, projectId: string, options?: {
|
|
114
|
+
maxResults?: number;
|
|
115
|
+
minScore?: number;
|
|
116
|
+
}) => Promise<SearchResult[]>;
|
|
117
|
+
}
|
|
118
|
+
export declare function clearProjectIndex(deps: IndexAdminDeps, projectId: string): Promise<{
|
|
119
|
+
deleted: number;
|
|
120
|
+
}>;
|
|
121
|
+
export declare function getProjectStats(deps: IndexAdminDeps, projectId: string): Promise<{
|
|
122
|
+
totalDocuments: number;
|
|
123
|
+
totalSize: number;
|
|
124
|
+
}>;
|
|
125
|
+
export declare function warmupCache(deps: IndexAdminDeps, projectId: string, _projectPath: string, customQueries?: string[]): Promise<{
|
|
126
|
+
queriesWarmed: number;
|
|
127
|
+
errors: number;
|
|
128
|
+
}>;
|
|
129
|
+
export declare function getAnalytics(deps: IndexAdminDeps): SearchAnalytics | SearchAnalyticsPg;
|
|
130
|
+
//# sourceMappingURL=index-admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-admin.d.ts","sourceRoot":"","sources":["../../../src/services/search/index-admin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;IACxD,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;IAC5D,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;IACxD,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAC5D,SAAS,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAC/C;;;;;;;OAOG;IACH,MAAM,EAAE,CACN,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KACjD,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC9B;AAID,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB9B;AAID,wBAAsB,eAAe,CACnC,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IACT,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAED;AAID,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoDpD;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,GACnB,eAAe,GAAG,iBAAiB,CAErC"}
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* index-admin — the index administration capability (design.md §4.1).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* PR-B capability module. Takes `IndexAdminDeps` — the collaborators §2.1 shows
|
|
5
|
+
* these surfaces read — in place of the facade instance they used to receive as
|
|
6
|
+
* `rlm` (GMS-03 AC-1). The file has never heard of ContextualSearchRLM, so it
|
|
7
|
+
* contributes nothing to the root's foreign reach (G-HUB, design.md §3.4).
|
|
8
|
+
*
|
|
9
|
+
* `await rlm.ensureInitialized()` is **gone from the three bodies that had it**.
|
|
10
|
+
* It was the literal first statement of `clearProjectIndex`, `getProjectStats`
|
|
11
|
+
* and `warmupCache`, and it is now the literal first statement of the three
|
|
12
|
+
* facade methods that call them — design.md §4.5(b) and the §4.3 sketch. Order is
|
|
13
|
+
* unchanged: the root awaits init, *then* assembles the deps record, so the
|
|
14
|
+
* fields this module reads are populated exactly as before. `getAnalytics` never
|
|
15
|
+
* called it and still does not; adding one would be a behavior change, not a
|
|
16
|
+
* tidy-up, and it is also the one delegate left with no `await` ahead of it,
|
|
17
|
+
* which is what makes it this task's blind-recursion mutation subject
|
|
18
|
+
* (tasks.md, "The mutation shape matters").
|
|
19
|
+
*
|
|
20
|
+
* LATE-BIND (design.md §4.3.1): the root assembles this record per call from its
|
|
21
|
+
* current field values. Nothing here captures a collaborator.
|
|
22
|
+
*
|
|
23
|
+
* Behavior is byte-preserved from rlm-admin.ts: the bodies moved verbatim with
|
|
24
|
+
* `rlm.` → `deps.` and the hoisted init statement removed.
|
|
6
25
|
*/
|
|
7
26
|
import { logger } from "@massa-ai/shared";
|
|
8
27
|
// ── clearProjectIndex ────────────────────────────────────────────────────────
|
|
9
|
-
export async function
|
|
10
|
-
await rlm.ensureInitialized();
|
|
28
|
+
export async function clearProjectIndex(deps, projectId) {
|
|
11
29
|
try {
|
|
12
30
|
const [deleted, keywordDeleted] = await Promise.all([
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
deps.vectorStore.deleteByProject(projectId),
|
|
32
|
+
deps.keywordSearch.deleteByProject(projectId),
|
|
15
33
|
]);
|
|
16
34
|
// Clear associated caches
|
|
17
|
-
await
|
|
18
|
-
|
|
35
|
+
await deps.searchCache.invalidateProject(projectId);
|
|
36
|
+
deps.fileFilterCache.invalidateProject(projectId);
|
|
19
37
|
logger.info("Project index and caches cleared", {
|
|
20
38
|
projectId,
|
|
21
39
|
deleted,
|
|
@@ -31,13 +49,11 @@ export async function clearProjectIndexImpl(rlm, projectId) {
|
|
|
31
49
|
}
|
|
32
50
|
}
|
|
33
51
|
// ── getProjectStats ──────────────────────────────────────────────────────────
|
|
34
|
-
export async function
|
|
35
|
-
|
|
36
|
-
return rlm.vectorStore.getStats(projectId);
|
|
52
|
+
export async function getProjectStats(deps, projectId) {
|
|
53
|
+
return deps.vectorStore.getStats(projectId);
|
|
37
54
|
}
|
|
38
55
|
// ── warmupCache ──────────────────────────────────────────────────────────────
|
|
39
|
-
export async function
|
|
40
|
-
await rlm.ensureInitialized();
|
|
56
|
+
export async function warmupCache(deps, projectId, _projectPath, customQueries) {
|
|
41
57
|
logger.info("Starting cache warmup", { projectId });
|
|
42
58
|
// Common search patterns based on file types and structure
|
|
43
59
|
const commonQueries = customQueries || [
|
|
@@ -62,7 +78,7 @@ export async function warmupCacheImpl(rlm, projectId, _projectPath, customQuerie
|
|
|
62
78
|
// Run searches in background to populate cache
|
|
63
79
|
for (const query of commonQueries) {
|
|
64
80
|
try {
|
|
65
|
-
await
|
|
81
|
+
await deps.search(query, projectId, {
|
|
66
82
|
maxResults: 10,
|
|
67
83
|
minScore: 0.3,
|
|
68
84
|
});
|
|
@@ -86,7 +102,7 @@ export async function warmupCacheImpl(rlm, projectId, _projectPath, customQuerie
|
|
|
86
102
|
return { queriesWarmed, errors };
|
|
87
103
|
}
|
|
88
104
|
// ── getAnalytics ─────────────────────────────────────────────────────────────
|
|
89
|
-
export function
|
|
90
|
-
return
|
|
105
|
+
export function getAnalytics(deps) {
|
|
106
|
+
return deps.analytics;
|
|
91
107
|
}
|
|
92
|
-
//# sourceMappingURL=
|
|
108
|
+
//# sourceMappingURL=index-admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-admin.js","sourceRoot":"","sources":["../../../src/services/search/index-admin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAkG1C,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAoB,EACpB,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAClD,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC;YAC3C,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,SAAS,CAAC;SAC9C,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElD,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE;YAC9C,SAAS;YACT,OAAO;YACP,cAAc;SACf,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAc,EAAE;YAC5D,SAAS;SACV,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAoB,EACpB,SAAiB;IAKjB,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,SAAiB,EACjB,YAAoB,EACpB,aAAwB;IAExB,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAEpD,2DAA2D;IAC3D,MAAM,aAAa,GAAG,aAAa,IAAI;QACrC,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,YAAY;QACZ,OAAO;QACP,eAAe;QACf,QAAQ;QACR,UAAU;QACV,OAAO;QACP,OAAO;QACP,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,YAAY;QACZ,OAAO;KACR,CAAC;IAEF,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,+CAA+C;IAC/C,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE;gBAClC,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE,GAAG;aACd,CAAC,CAAC;YACH,aAAa,EAAE,CAAC;YAEhB,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAc,EAAE;gBAC7D,KAAK;gBACL,SAAS;aACV,CAAC,CAAC;YACH,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;QACpC,SAAS;QACT,aAAa;QACb,MAAM;QACN,YAAY,EAAE,aAAa,CAAC,MAAM;KACnC,CAAC,CAAC;IAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;AACnC,CAAC;AAED,gFAAgF;AAEhF,MAAM,UAAU,YAAY,CAC1B,IAAoB;IAEpB,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* project-indexer — the project indexing capability (design.md §4.1).
|
|
3
|
+
*
|
|
4
|
+
* PR-B capability module. Takes `IndexerDeps` — the collaborators §2.1 shows
|
|
5
|
+
* these surfaces read — in place of the facade instance they used to receive as
|
|
6
|
+
* `rlm` (GMS-03 AC-1). The file has never heard of ContextualSearchRLM, so it
|
|
7
|
+
* contributes nothing to the root's foreign reach (G-HUB, design.md §3.4).
|
|
8
|
+
*
|
|
9
|
+
* `await rlm.ensureInitialized()` is **gone from every body here**. It was the
|
|
10
|
+
* literal first statement of `checkSearchAdmission`, `indexProjectInternal` and
|
|
11
|
+
* `ensureFreshIndex`, and it is now the literal first statement of the three
|
|
12
|
+
* facade methods that call them — design.md §4.5(b) and the §4.3 sketch. Order
|
|
13
|
+
* is unchanged: the root awaits init, *then* assembles the deps record, so the
|
|
14
|
+
* fields this module reads are populated exactly as before. `indexFile` never
|
|
15
|
+
* called it and still does not; its callers init first, as they always did.
|
|
16
|
+
*
|
|
17
|
+
* `ensureInitializedImpl` did **not** come here. It read 8 facade members, and
|
|
18
|
+
* 8 > G-HUB's ceiling of 3, so anywhere outside the root it fails the gate
|
|
19
|
+
* permanently. Its body is now the content of
|
|
20
|
+
* `ContextualSearchRLM.ensureInitialized()` (tasks.md T10, design.md §4.1's
|
|
21
|
+
* omission note). That is why rlm-indexing.ts dies whole rather than surviving
|
|
22
|
+
* as a one-function husk.
|
|
23
|
+
*
|
|
24
|
+
* LATE-BIND (design.md §4.3.1): the root assembles this record per call from its
|
|
25
|
+
* current field values. Nothing here captures a collaborator.
|
|
26
|
+
*
|
|
27
|
+
* Behavior is byte-preserved from rlm-indexing.ts: the bodies moved verbatim
|
|
28
|
+
* with `rlm.` → `deps.` and the hoisted init statement removed.
|
|
29
|
+
*/
|
|
30
|
+
import type { IndexManager } from "./index-manager.js";
|
|
31
|
+
import type { getKeywordSearch } from "../../data/keyword/keyword-search-factory.js";
|
|
32
|
+
import type { getVectorStore } from "../../data/vector/vector-store-factory.js";
|
|
33
|
+
import type { getSearchCache } from "./cache-factory.js";
|
|
34
|
+
import type { getSymbolRepository } from "../../data/symbol/symbol-repository-factory.js";
|
|
35
|
+
export type IndexProjectOptions = {
|
|
36
|
+
onProgress?: (current: number, total: number) => void;
|
|
37
|
+
};
|
|
38
|
+
export type IndexProjectResult = {
|
|
39
|
+
filesIndexed: number;
|
|
40
|
+
chunksIndexed: number;
|
|
41
|
+
errors: number;
|
|
42
|
+
};
|
|
43
|
+
export type EnsureFreshIndexOptions = {
|
|
44
|
+
allowFullReindex?: boolean;
|
|
45
|
+
maxSyncFiles?: number;
|
|
46
|
+
};
|
|
47
|
+
export type EnsureFreshIndexResult = {
|
|
48
|
+
wasStale: boolean;
|
|
49
|
+
reindexed: boolean;
|
|
50
|
+
reason?: string;
|
|
51
|
+
deferred?: boolean;
|
|
52
|
+
filesPending?: number;
|
|
53
|
+
};
|
|
54
|
+
export type SearchAdmissionResult = {
|
|
55
|
+
admitted: boolean;
|
|
56
|
+
error?: string;
|
|
57
|
+
stale?: {
|
|
58
|
+
reason: string;
|
|
59
|
+
modifiedFiles?: number;
|
|
60
|
+
newFiles?: number;
|
|
61
|
+
deletedFiles?: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The narrow dependency record for this module (design.md §4.4) — exactly the
|
|
66
|
+
* collaborators §2.1 shows these surfaces read, minus the three that the root
|
|
67
|
+
* absorbed (`ensureInitialized` is hoisted; `initialized`, `injectedDeps` and
|
|
68
|
+
* `analytics` were `ensureInitializedImpl`'s alone).
|
|
69
|
+
*
|
|
70
|
+
* The five stores are required and carry the root's own field types: their
|
|
71
|
+
* originals were bare `rlm.<store>.<method>` reads off definite-assigned fields
|
|
72
|
+
* with no fallback, so an absent store must keep throwing exactly where it did.
|
|
73
|
+
* Contrast `SessionBiasDeps`, whose fields are optional because its originals
|
|
74
|
+
* read `rlm.injectedDeps?.x ?? getFactory()`.
|
|
75
|
+
*
|
|
76
|
+
* **`indexFile` and `indexProject` are re-entrant seams, not stores, and they
|
|
77
|
+
* are the part design.md §4.1's "injected collaborators" column omitted** —
|
|
78
|
+
* the same class of omission as `ensureInitializedImpl`, and §2.1 lists both
|
|
79
|
+
* members, so §4.4's rule already places them here. They are load-bearing:
|
|
80
|
+
* `search-facade-indexing.test.ts` stubs `rlm.indexFile` at :377, :402, :537, :572, :609
|
|
81
|
+
* and `rlm.indexProject` at :335 — **6 instance-method stub sites** — and every
|
|
82
|
+
* one is exercised *through* `ensureFreshIndex` or `indexProjectInternal`. A
|
|
83
|
+
* module-local call would make all six silently ineffective while the suite
|
|
84
|
+
* stayed green, which is LATE-BIND's exact failure mode. So the root supplies
|
|
85
|
+
* per-call arrow wrappers whose bodies re-read `this.<method>` at call time.
|
|
86
|
+
*
|
|
87
|
+
* `indexProject` is deliberately **not** the module function below. It is the
|
|
88
|
+
* root's public locked path — `assertParserReadyForIndexing()` then
|
|
89
|
+
* `runWithIndexLock(ContextualSearchRLM.indexingLocks, …)` — and that lock map
|
|
90
|
+
* is class state the capability modules may not import. `ensureFreshIndex`'s
|
|
91
|
+
* full-reindex branch needs the *locked* path, so calling an unlocked
|
|
92
|
+
* module-local namesake would drop the mutex silently. Hence the module
|
|
93
|
+
* function is `indexProjectInternal`, one name, one meaning, in one file.
|
|
94
|
+
*/
|
|
95
|
+
export interface IndexerDeps {
|
|
96
|
+
/**
|
|
97
|
+
* Narrowed to the four methods this module calls, and the narrowing is
|
|
98
|
+
* load-bearing rather than tidy. `IndexManager` is declared **inside** the
|
|
99
|
+
* G-HUB-gated directory, and the metric's annotation pattern is
|
|
100
|
+
* `([A-Za-z0-9_]+)\s*:\s*<Type>\b` — which matches an *interface field
|
|
101
|
+
* declaration*, not just a parameter. Typing this `indexManager: IndexManager`
|
|
102
|
+
* therefore attributed all four `deps.indexManager.<method>` reads to
|
|
103
|
+
* `IndexManager` and took its `maxForeignReach` from **0 to 4**, a second
|
|
104
|
+
* G-HUB violation where the tree had exactly one, which would have made T14's
|
|
105
|
+
* gate unclosable. Measured at T10, not predicted.
|
|
106
|
+
*
|
|
107
|
+
* `SessionBiasDeps` and `HybridSearchDeps` never hit this: their fields are
|
|
108
|
+
* `Pick<…>` / `Awaited<ReturnType<…>>`, and their collaborators are declared
|
|
109
|
+
* outside this directory. `IndexManager` is the first collaborator that is
|
|
110
|
+
* both a bare nominal type and declared under `services/search/`.
|
|
111
|
+
*
|
|
112
|
+
* **The same trap is waiting at T12 (`fileFilterCache: FileFilterCache`,
|
|
113
|
+
* `analytics: SearchAnalytics | SearchAnalyticsPg`) and T13
|
|
114
|
+
* (`queryUnderstanding: QueryUnderstandingService`)** — all three types are
|
|
115
|
+
* declared in this directory. Narrow those fields the same way.
|
|
116
|
+
*/
|
|
117
|
+
indexManager: Pick<IndexManager, "getIndexMetadata" | "isIndexStale" | "getFilesToReindex" | "updateIndexMetadata">;
|
|
118
|
+
symbolRepo: Awaited<ReturnType<typeof getSymbolRepository>>;
|
|
119
|
+
keywordSearch: Awaited<ReturnType<typeof getKeywordSearch>>;
|
|
120
|
+
vectorStore: Awaited<ReturnType<typeof getVectorStore>>;
|
|
121
|
+
searchCache: Awaited<ReturnType<typeof getSearchCache>>;
|
|
122
|
+
/** The root's `indexFile` method, re-resolved through `this` on every call. */
|
|
123
|
+
indexFile: (filePath: string, projectId: string, projectRoot: string, centralityMap?: Map<string, number>) => Promise<{
|
|
124
|
+
chunks: number;
|
|
125
|
+
}>;
|
|
126
|
+
/** The root's `indexProject` method — the *locked* path, not the body below. */
|
|
127
|
+
indexProject: (projectPath: string, projectId: string, options?: IndexProjectOptions) => Promise<IndexProjectResult>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Per-project queue mutex: serializes concurrent indexing for the same project.
|
|
131
|
+
*
|
|
132
|
+
* Pattern: each caller chains its lock after the current tail, then waits for
|
|
133
|
+
* the previous lock before proceeding. This guarantees correct ordering for any
|
|
134
|
+
* number of concurrent callers (3+), unlike a simple check-and-set.
|
|
135
|
+
*
|
|
136
|
+
* A sets map[proj] = lock_A, awaits null → starts immediately
|
|
137
|
+
* B sets map[proj] = lock_B, awaits lock_A → waits for A
|
|
138
|
+
* C sets map[proj] = lock_C, awaits lock_B → waits for B
|
|
139
|
+
* A finishes → releases lock_A → B starts
|
|
140
|
+
* B finishes → releases lock_B → C starts
|
|
141
|
+
* C finishes → map[proj] === lock_C, so we clean up the entry
|
|
142
|
+
*
|
|
143
|
+
* The `try { await work() } finally { delete-if-still-owner; releaseLock() }`
|
|
144
|
+
* shape is load-bearing: `releaseLock()` MUST run even when `work` throws, or
|
|
145
|
+
* the lock leaks and subsequent callers hang (BUG-SYN-4).
|
|
146
|
+
*
|
|
147
|
+
* `work` is `() => this._indexProjectInternal(...)` in the caller — a lambda
|
|
148
|
+
* that captures virtual dispatch through `this`, so test monkey-patches on the
|
|
149
|
+
* instance still route. Do NOT inline a direct call to a module function here.
|
|
150
|
+
*/
|
|
151
|
+
export declare function runWithIndexLock<T>(lockMap: Map<string, Promise<void>>, projectId: string, work: () => Promise<T>): Promise<T>;
|
|
152
|
+
export declare function indexProjectInternal(deps: IndexerDeps, projectPath: string, projectId: string, options?: IndexProjectOptions): Promise<IndexProjectResult>;
|
|
153
|
+
export declare function ensureFreshIndex(deps: IndexerDeps, projectId: string, projectPath: string, options?: EnsureFreshIndexOptions): Promise<EnsureFreshIndexResult>;
|
|
154
|
+
export declare function checkSearchAdmission(deps: IndexerDeps, projectId: string, projectPath?: string): Promise<SearchAdmissionResult>;
|
|
155
|
+
export declare function indexFile(deps: IndexerDeps, filePath: string, projectId: string, projectRoot: string, centralityMap?: Map<string, number>): Promise<{
|
|
156
|
+
chunks: number;
|
|
157
|
+
}>;
|
|
158
|
+
export declare function loadGitignore(projectPath: string): Promise<import("ignore").Ignore>;
|
|
159
|
+
//# sourceMappingURL=project-indexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-indexer.d.ts","sourceRoot":"","sources":["../../../src/services/search/project-indexer.ts"],"names":[],"mappings":"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"}
|