@devflow-tools/context-engine 0.17.1 → 0.17.3

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.
Files changed (37) hide show
  1. package/dist/artifact-identity-resolver.d.ts +39 -0
  2. package/dist/artifact-identity-resolver.d.ts.map +1 -0
  3. package/dist/artifact-identity-resolver.js +58 -0
  4. package/dist/artifact-identity-resolver.js.map +1 -0
  5. package/dist/artifact-inventory.d.ts +39 -0
  6. package/dist/artifact-inventory.d.ts.map +1 -0
  7. package/dist/artifact-inventory.js +224 -0
  8. package/dist/artifact-inventory.js.map +1 -0
  9. package/dist/context-engine.d.ts.map +1 -1
  10. package/dist/context-engine.js +102 -4
  11. package/dist/context-engine.js.map +1 -1
  12. package/dist/context-file-roles.d.ts +2 -1
  13. package/dist/context-file-roles.d.ts.map +1 -1
  14. package/dist/context-file-roles.js +6 -0
  15. package/dist/context-file-roles.js.map +1 -1
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +2 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/intent-parser.d.ts +5 -2
  21. package/dist/intent-parser.d.ts.map +1 -1
  22. package/dist/intent-parser.js +4 -4
  23. package/dist/intent-parser.js.map +1 -1
  24. package/dist/retrieval-handlers.d.ts +2 -0
  25. package/dist/retrieval-handlers.d.ts.map +1 -1
  26. package/dist/retrieval-handlers.js +61 -1
  27. package/dist/retrieval-handlers.js.map +1 -1
  28. package/dist/retrieval-ledger.d.ts.map +1 -1
  29. package/dist/retrieval-ledger.js +9 -0
  30. package/dist/retrieval-ledger.js.map +1 -1
  31. package/dist/retrieval-task-plan.js +21 -14
  32. package/dist/retrieval-task-plan.js.map +1 -1
  33. package/dist/task-retrieval-orchestrator.d.ts +2 -1
  34. package/dist/task-retrieval-orchestrator.d.ts.map +1 -1
  35. package/dist/task-retrieval-orchestrator.js +72 -8
  36. package/dist/task-retrieval-orchestrator.js.map +1 -1
  37. package/package.json +7 -7
@@ -0,0 +1,39 @@
1
+ export interface ArtifactIdentityV1 {
2
+ schemaVersion: 'artifact-identity.v1';
3
+ identityId: string;
4
+ projectId: string;
5
+ canonicalPath: string;
6
+ kind: string;
7
+ contentHash?: string;
8
+ aliases: string[];
9
+ relations: Array<{
10
+ kind: 'renamed_from';
11
+ identityId: string;
12
+ path: string;
13
+ }>;
14
+ }
15
+ export interface ArtifactIdentityCandidate {
16
+ path: string;
17
+ kind: string;
18
+ contentHash?: string;
19
+ symbols?: string[];
20
+ exports?: string[];
21
+ routes?: string[];
22
+ imports?: string[];
23
+ renamedFrom?: string[];
24
+ score?: number;
25
+ }
26
+ export interface ArtifactIdentityResolution {
27
+ identities: ArtifactIdentityV1[];
28
+ selected?: ArtifactIdentityV1;
29
+ ambiguous: boolean;
30
+ candidates: ArtifactIdentityV1[];
31
+ }
32
+ export declare function resolveArtifactIdentity(input: {
33
+ projectId: string;
34
+ candidates: ArtifactIdentityCandidate[];
35
+ query?: string;
36
+ explicitPath?: string;
37
+ }): ArtifactIdentityResolution;
38
+ export declare function artifactIdentity(projectId: string, candidate: ArtifactIdentityCandidate): ArtifactIdentityV1;
39
+ //# sourceMappingURL=artifact-identity-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-identity-resolver.d.ts","sourceRoot":"","sources":["../src/artifact-identity-resolver.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,sBAAsB,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,kBAAkB,EAAE,CAAC;CAClC;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,0BAA0B,CAoB7B;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,yBAAyB,GAAG,kBAAkB,CAoB5G"}
@@ -0,0 +1,58 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { normalize } from 'node:path';
3
+ export function resolveArtifactIdentity(input) {
4
+ const identities = input.candidates.map(candidate => artifactIdentity(input.projectId, candidate));
5
+ const explicit = input.explicitPath ? canonicalPath(input.explicitPath) : undefined;
6
+ const queryAliases = aliasTerms(input.query ?? '');
7
+ const scored = identities.map((identity, index) => {
8
+ const candidate = input.candidates[index];
9
+ const explicitScore = explicit === identity.canonicalPath ? 10 : 0;
10
+ const aliasScore = identity.aliases.filter(alias => [...queryAliases].some(queryAlias => queryAlias.includes(alias) || alias.includes(queryAlias))).length;
11
+ return { identity, score: explicitScore + aliasScore + (candidate.score ?? 0) };
12
+ }).filter(item => item.score > 0).sort((a, b) => b.score - a.score
13
+ || a.identity.canonicalPath.localeCompare(b.identity.canonicalPath));
14
+ const top = scored[0]?.score;
15
+ const candidates = top === undefined ? [] : scored.filter(item => item.score === top).map(item => item.identity);
16
+ return {
17
+ identities,
18
+ ...(candidates.length === 1 ? { selected: candidates[0] } : {}),
19
+ ambiguous: candidates.length > 1,
20
+ candidates,
21
+ };
22
+ }
23
+ export function artifactIdentity(projectId, candidate) {
24
+ const path = canonicalPath(candidate.path);
25
+ const identityId = stableId(projectId, path, candidate.kind);
26
+ const aliases = new Set([
27
+ path,
28
+ path.split('/').at(-1)?.replace(/\.[^.]+$/u, '') ?? '',
29
+ ...(candidate.symbols ?? []), ...(candidate.exports ?? []),
30
+ ...(candidate.routes ?? []), ...(candidate.imports ?? []),
31
+ ].flatMap(value => [...aliasTerms(value)]));
32
+ return {
33
+ schemaVersion: 'artifact-identity.v1', identityId, projectId,
34
+ canonicalPath: path, kind: candidate.kind,
35
+ ...(candidate.contentHash ? { contentHash: candidate.contentHash } : {}),
36
+ aliases: [...aliases].filter(Boolean).sort(),
37
+ relations: (candidate.renamedFrom ?? []).map(previousPath => ({
38
+ kind: 'renamed_from',
39
+ identityId: stableId(projectId, canonicalPath(previousPath), candidate.kind),
40
+ path: canonicalPath(previousPath),
41
+ })),
42
+ };
43
+ }
44
+ function stableId(projectId, path, kind) {
45
+ return `artifact:${createHash('sha256').update(`${projectId}\0${path}\0${kind}`).digest('hex')}`;
46
+ }
47
+ function canonicalPath(value) {
48
+ return normalize(value.normalize('NFKC')).replaceAll('\\', '/').replace(/^\.\//u, '');
49
+ }
50
+ function aliasTerms(value) {
51
+ const normalized = value.normalize('NFKC').toLocaleLowerCase('en-US');
52
+ return new Set([
53
+ normalized.replace(/[^\p{Letter}\p{Number}_$]+/gu, ''),
54
+ ...(normalized.match(/[\p{Letter}\p{Number}_$-]{2,}/gu) ?? [])
55
+ .map(item => item.replace(/[^\p{Letter}\p{Number}_$]+/gu, '')),
56
+ ].filter(Boolean));
57
+ }
58
+ //# sourceMappingURL=artifact-identity-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-identity-resolver.js","sourceRoot":"","sources":["../src/artifact-identity-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { CodeGraph } from '@colbymchenry/codegraph';
2
+ import type { ArtifactContextRole, RetrievalTaskAction } from '@devflow-tools/sdk';
3
+ import type { IndexedFileFreshness, IndexerAdapter } from './indexer-adapter.js';
4
+ import { type ArtifactIdentityV1 } from './artifact-identity-resolver.js';
5
+ export type ArtifactMatchMode = 'explicit_path' | 'artifact_name' | 'exported_symbol' | 'route_registration' | 'lexical_support' | 'missing_explicit_path';
6
+ export interface ArtifactInventoryEntry {
7
+ identity: ArtifactIdentityV1;
8
+ path: string;
9
+ artifactRole: ArtifactContextRole;
10
+ score: number;
11
+ matchMode: ArtifactMatchMode;
12
+ artifactKind: 'component' | 'page' | 'route' | 'module' | 'test' | 'config' | 'resource' | 'source';
13
+ symbols: string[];
14
+ evidence: string[];
15
+ freshness: IndexedFileFreshness;
16
+ }
17
+ export interface ArtifactInventoryResult {
18
+ entries: ArtifactInventoryEntry[];
19
+ operationTargets: ArtifactInventoryEntry[];
20
+ missingExplicitTargets: ArtifactInventoryEntry[];
21
+ ambiguous: boolean;
22
+ }
23
+ export declare function buildArtifactInventory(input: {
24
+ codegraph: CodeGraph;
25
+ indexer: IndexerAdapter;
26
+ query: string;
27
+ explicitTargetAnchors: string[];
28
+ action: RetrievalTaskAction;
29
+ identity?: {
30
+ projectRoot: string;
31
+ sessionId?: string;
32
+ turnId?: string;
33
+ requestId?: string;
34
+ executionId?: string;
35
+ intentArtifactHash?: string;
36
+ queryPlanHash?: string;
37
+ };
38
+ }): ArtifactInventoryResult;
39
+ //# sourceMappingURL=artifact-inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-inventory.d.ts","sourceRoot":"","sources":["../src/artifact-inventory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GACzB,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,oBAAoB,GACpB,iBAAiB,GACjB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,mBAAmB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,iBAAiB,CAAC;IAC7B,YAAY,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACpG,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,oBAAoB,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAClC,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,sBAAsB,EAAE,sBAAsB,EAAE,CAAC;IACjD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,GAAG,uBAAuB,CAkH1B"}
@@ -0,0 +1,224 @@
1
+ import { extname, normalize } from 'node:path';
2
+ import { emitSemanticControlLog } from '@devflow-tools/telemetry';
3
+ import { expandQuery } from './intent-parser.js';
4
+ import { artifactIdentity } from './artifact-identity-resolver.js';
5
+ export function buildArtifactInventory(input) {
6
+ const files = input.codegraph.getFiles().map(file => normalizeProjectPath(file.path));
7
+ const indexedFiles = new Set(files);
8
+ const explicitAnchors = [...new Set(input.explicitTargetAnchors.map(normalizeProjectPath).filter(Boolean))];
9
+ const terms = artifactTerms(input.query, explicitAnchors);
10
+ const requestedKinds = inferRequestedArtifactKinds(input.query);
11
+ const candidates = new Map();
12
+ for (const anchor of explicitAnchors) {
13
+ const exact = resolveExplicitAnchor(anchor, files);
14
+ if (exact) {
15
+ setCandidate(candidates, inventoryEntry(input, exact, 'operation_target', 1, 'explicit_path', [
16
+ `explicit target anchor resolved to ${exact}`,
17
+ ]));
18
+ continue;
19
+ }
20
+ const freshness = input.indexer.getFileFreshness(anchor);
21
+ setCandidate(candidates, {
22
+ identity: artifactIdentity(input.identity?.projectRoot ?? 'project:unknown', {
23
+ path: anchor, kind: artifactKind(anchor), contentHash: freshness.currentHash,
24
+ }),
25
+ path: anchor,
26
+ artifactRole: 'operation_target',
27
+ score: 1,
28
+ matchMode: 'missing_explicit_path',
29
+ artifactKind: artifactKind(anchor),
30
+ symbols: [],
31
+ evidence: [`explicit target anchor ${anchor} does not resolve to a current project file`],
32
+ freshness,
33
+ });
34
+ }
35
+ for (const path of files) {
36
+ if (!isInventoryFile(path))
37
+ continue;
38
+ const nodes = input.codegraph.getNodesInFile(path)
39
+ .filter(node => node.kind !== 'file' && node.kind !== 'import');
40
+ const symbols = [...new Set(nodes.map(node => String(node.name)).filter(Boolean))];
41
+ const normalizedBase = normalizeIdentity(path.split('/').at(-1)?.replace(/\.[^.]+$/u, '') ?? '');
42
+ const normalizedPath = normalizeIdentity(path);
43
+ const symbolIdentities = symbols.map(normalizeIdentity);
44
+ const exactName = terms.find(term => normalizedBase === term || symbolIdentities.includes(term));
45
+ const partialName = terms.find(term => term.length >= 4
46
+ && (normalizedBase.includes(term) || symbolIdentities.some(symbol => symbol.includes(term))));
47
+ const routeMatch = artifactKind(path) === 'route' && terms.some(term => normalizedPath.includes(term));
48
+ if (!exactName && !partialName && !routeMatch)
49
+ continue;
50
+ const kind = artifactKind(path);
51
+ const kindAdjustment = requestedKinds.size === 0
52
+ ? 0
53
+ : requestedKinds.has(kind) ? 0.08
54
+ : kind === 'route' || kind === 'source' || kind === 'module' ? -0.12 : -0.04;
55
+ const score = clampScore((exactName ? 0.97 : routeMatch ? 0.91 : 0.88) + kindAdjustment);
56
+ const mode = exactName
57
+ ? symbolIdentities.includes(exactName) ? 'exported_symbol' : 'artifact_name'
58
+ : routeMatch ? 'route_registration' : 'artifact_name';
59
+ const strongArtifactMatch = score >= 0.88 && !isSupportOnlyPath(path)
60
+ && (requestedKinds.size === 0 || requestedKinds.has(kind));
61
+ const artifactRole = strongArtifactMatch
62
+ ? 'operation_target'
63
+ : 'supporting_file';
64
+ setCandidate(candidates, inventoryEntry(input, path, artifactRole, score, mode, [
65
+ `${mode} matched ${exactName ?? partialName ?? 'route'} in ${path}`,
66
+ ], symbols));
67
+ }
68
+ const entries = [...candidates.values()]
69
+ .filter(entry => entry.matchMode === 'missing_explicit_path' || entry.freshness.exists)
70
+ .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));
71
+ const explicitTargets = entries.filter(entry => entry.matchMode === 'explicit_path'
72
+ || entry.matchMode === 'missing_explicit_path');
73
+ let operationTargets = explicitTargets.length > 0
74
+ ? explicitTargets
75
+ : entries.filter(entry => entry.artifactRole === 'operation_target' && entry.score >= 0.88);
76
+ if (operationTargets.length > 1 && explicitTargets.length === 0) {
77
+ const top = operationTargets[0].score;
78
+ operationTargets = operationTargets.filter(entry => top - entry.score <= 0.03).slice(0, 5);
79
+ }
80
+ else {
81
+ operationTargets = operationTargets.slice(0, explicitTargets.length > 0 ? 16 : 3);
82
+ }
83
+ const operationPaths = new Set(operationTargets.map(entry => entry.path));
84
+ for (const entry of entries) {
85
+ if (!operationPaths.has(entry.path) && entry.artifactRole === 'operation_target') {
86
+ entry.artifactRole = input.action === 'create' ? 'reference_pattern' : 'supporting_file';
87
+ }
88
+ }
89
+ const ambiguous = explicitTargets.length === 0 && operationTargets.length > 1;
90
+ const result = {
91
+ entries: entries.slice(0, 40),
92
+ operationTargets,
93
+ missingExplicitTargets: entries.filter(entry => entry.matchMode === 'missing_explicit_path'),
94
+ ambiguous,
95
+ };
96
+ if (input.identity) {
97
+ try {
98
+ emitSemanticControlLog({
99
+ event: 'artifact.inventory.completed',
100
+ identity: input.identity,
101
+ level: result.missingExplicitTargets.length > 0 || ambiguous ? 'warn' : 'info',
102
+ timestamp: Date.now(),
103
+ data: {
104
+ action: input.action,
105
+ explicitAnchorCount: explicitAnchors.length,
106
+ candidateCount: result.entries.length,
107
+ operationTargets: operationTargets.map(entry => entry.path),
108
+ missingExplicitTargets: result.missingExplicitTargets.map(entry => entry.path),
109
+ ambiguous,
110
+ },
111
+ });
112
+ }
113
+ catch {
114
+ // Inventory observability cannot alter context selection.
115
+ }
116
+ }
117
+ return result;
118
+ }
119
+ function inventoryEntry(input, path, artifactRole, score, matchMode, evidence, symbols = []) {
120
+ return {
121
+ identity: artifactIdentity(input.identity?.projectRoot ?? 'project:unknown', {
122
+ path, kind: artifactKind(path), symbols,
123
+ contentHash: input.indexer.getFileFreshness(path).currentHash,
124
+ }),
125
+ path,
126
+ artifactRole,
127
+ score,
128
+ matchMode,
129
+ artifactKind: artifactKind(path),
130
+ symbols,
131
+ evidence,
132
+ freshness: input.indexer.getFileFreshness(path),
133
+ };
134
+ }
135
+ function setCandidate(candidates, candidate) {
136
+ const existing = candidates.get(candidate.path);
137
+ if (!existing || candidate.score > existing.score
138
+ || candidate.matchMode === 'explicit_path' || candidate.matchMode === 'missing_explicit_path') {
139
+ candidates.set(candidate.path, candidate);
140
+ }
141
+ }
142
+ function resolveExplicitAnchor(anchor, files) {
143
+ if (files.includes(anchor))
144
+ return anchor;
145
+ const caseInsensitive = files.filter(path => path.toLocaleLowerCase('en-US') === anchor.toLocaleLowerCase('en-US'));
146
+ if (caseInsensitive.length === 1)
147
+ return caseInsensitive[0];
148
+ const withoutExtension = anchor.replace(/\.[^.]+$/u, '');
149
+ const candidates = files.filter(path => path.replace(/\.[^.]+$/u, '') === withoutExtension
150
+ || path.startsWith(`${withoutExtension}/index.`));
151
+ return candidates.length === 1 ? candidates[0] : undefined;
152
+ }
153
+ function inferRequestedArtifactKinds(query) {
154
+ const kinds = new Set();
155
+ if (/component|组件/iu.test(query)) {
156
+ kinds.add('component');
157
+ kinds.add('page');
158
+ }
159
+ if (/\bpage\b|页面/iu.test(query)) {
160
+ kinds.add('page');
161
+ kinds.add('component');
162
+ }
163
+ if (/\broute\b|routing|路由/iu.test(query))
164
+ kinds.add('route');
165
+ if (/\bmodule\b|模块/iu.test(query))
166
+ kinds.add('module');
167
+ if (/\btests?\b|测试/iu.test(query))
168
+ kinds.add('test');
169
+ if (/\bconfig\b|配置/iu.test(query))
170
+ kinds.add('config');
171
+ return kinds;
172
+ }
173
+ function clampScore(value) {
174
+ return Math.max(0, Math.min(1, value));
175
+ }
176
+ function artifactTerms(query, anchors) {
177
+ const expanded = expandQuery(query, { segmentation: 'regex' });
178
+ const normalized = expanded.normalize('NFKC').replace(/([a-z0-9])([A-Z])/gu, '$1 $2').toLocaleLowerCase('en-US');
179
+ const raw = [
180
+ ...(normalized.match(/[a-z_$][a-z0-9_$-]{2,}/gu) ?? []),
181
+ ...(query.normalize('NFKC').match(/\p{Script=Han}{2,}/gu) ?? []),
182
+ ...anchors.flatMap(anchor => anchor.split(/[/.\\_-]+/u)),
183
+ ];
184
+ const stop = new Set([
185
+ 'component', 'components', 'page', 'pages', 'module', 'file', 'files', 'src',
186
+ 'create', 'modify', 'update', 'build', 'review', 'analyze', 'performance',
187
+ 'add', 'new', 'feature', 'implement', 'props', 'jsx', 'react', 'tsx',
188
+ 'typescript', 'javascript', 'help', 'please', 'using', 'current', 'project',
189
+ '组件', '页面', '模块', '文件', '路由', '测试', '配置', '创建', '生成',
190
+ '修改', '分析', '实现', '项目', '符合', '一个', '当前',
191
+ ]);
192
+ return [...new Set(raw.map(normalizeIdentity).filter(term => (term.length >= 3 || /\p{Script=Han}{2,}/u.test(term)) && !stop.has(term)))];
193
+ }
194
+ function normalizeIdentity(value) {
195
+ return value.normalize('NFKC').toLocaleLowerCase('en-US').replace(/[^\p{Letter}\p{Number}_$]+/gu, '');
196
+ }
197
+ function artifactKind(path) {
198
+ if (/(?:^|\/)routes?(?:\/|\.)|\.route\.[cm]?[jt]sx?$/iu.test(path))
199
+ return 'route';
200
+ if (/(?:^|\/)pages?(?:\/|\.)|page\.[cm]?[jt]sx?$/iu.test(path))
201
+ return 'page';
202
+ if (/(?:^|\/)components?(?:\/|\.)|\.[jt]sx$/iu.test(path))
203
+ return 'component';
204
+ if (/\.(?:test|spec)\.[cm]?[jt]sx?$/iu.test(path))
205
+ return 'test';
206
+ if (/(?:^|\/)config|\.config\.[cm]?[jt]s$/iu.test(path))
207
+ return 'config';
208
+ if (/\.(?:css|scss|sass|less|svg|png|jpe?g|webp)$/iu.test(path))
209
+ return 'resource';
210
+ if (/(?:^|\/)modules?(?:\/|\.)/iu.test(path))
211
+ return 'module';
212
+ return 'source';
213
+ }
214
+ function isSupportOnlyPath(path) {
215
+ return artifactKind(path) === 'test' || artifactKind(path) === 'config'
216
+ || artifactKind(path) === 'resource';
217
+ }
218
+ function isInventoryFile(path) {
219
+ return ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts'].includes(extname(path).toLocaleLowerCase('en-US'));
220
+ }
221
+ function normalizeProjectPath(value) {
222
+ return normalize(value).replaceAll('\\', '/').replace(/^\.\//u, '');
223
+ }
224
+ //# sourceMappingURL=artifact-inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-inventory.js","sourceRoot":"","sources":["../src/artifact-inventory.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-engine.d.ts","sourceRoot":"","sources":["../src/context-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEb,WAAW,EACX,aAAa,EAOb,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,iCAAiC,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAwB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,OAAO,KAAK,EAKV,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AA0SpB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAoCD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,WAAW,CAAC,CAAoB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAE5B,IAAI,EAAE,iBAAiB;IAYnC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,UAAU,CAAkD;IAE9D,gCAAgC,CAAC,KAAK,EAAE;QAC5C,OAAO,EAAE,sBAAsB,EAAE,CAAC;QAClC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIX,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,OAAO,CAAC,yBAAyB;YAoCnB,yBAAyB;IAiCvC,OAAO,CAAC,eAAe;IAKjB,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAkRtD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,+BAA+B,CAAC;YA8nB/F,sBAAsB;IAsWpC,OAAO,CAAC,yBAAyB;YAgBnB,2BAA2B;YA4B3B,6BAA6B;IAkB3C,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,2BAA2B;IAOnC,SAAS,IAAI,WAAW;CASzB"}
1
+ {"version":3,"file":"context-engine.d.ts","sourceRoot":"","sources":["../src/context-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEb,WAAW,EACX,aAAa,EAOb,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,iCAAiC,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAwB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,OAAO,KAAK,EAKV,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AA2SpB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAoCD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,WAAW,CAAC,CAAoB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAE5B,IAAI,EAAE,iBAAiB;IAYnC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,UAAU,CAAkD;IAE9D,gCAAgC,CAAC,KAAK,EAAE;QAC5C,OAAO,EAAE,sBAAsB,EAAE,CAAC;QAClC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIX,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,OAAO,CAAC,yBAAyB;YAqCnB,yBAAyB;IAiCvC,OAAO,CAAC,eAAe;IAKjB,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAkRtD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,+BAA+B,CAAC;YAutB/F,sBAAsB;IAsWpC,OAAO,CAAC,yBAAyB;YAgBnB,2BAA2B;YA4B3B,6BAA6B;IAkB3C,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,2BAA2B;IAOnC,SAAS,IAAI,WAAW;CASzB"}
@@ -9,6 +9,7 @@ import { rankOptionalContextFiles, } from "./ranker.js";
9
9
  import { describeLayerEvidence, detectLanguageFromPath, } from "./layer-rules.js";
10
10
  import { reachableCodeGraphNodeIds, sanitizeCodeGraphEdges, } from './graph-edge-quality.js';
11
11
  import { assembleContextFileRoles } from './context-file-roles.js';
12
+ import { buildArtifactInventory } from './artifact-inventory.js';
12
13
  import { buildTaskContextEnvelope } from './task-retrieval-orchestrator.js';
13
14
  import { recordTaskEnvelopeLedger } from './retrieval-ledger.js';
14
15
  import { selectGraphEvidence } from './graph-evidence-selector.js';
@@ -315,6 +316,7 @@ export class ContextEngine {
315
316
  const languages = Object.keys(stats.filesByLanguage ?? {});
316
317
  return {
317
318
  limit,
319
+ retrievalIntent: 'automatic_context',
318
320
  budgetTokens: Math.max(0, Math.floor(totalBudget * 0.25)),
319
321
  activeSkill: options.activeSkill,
320
322
  relevantFiles: options.relevantFiles,
@@ -633,11 +635,11 @@ export class ContextEngine {
633
635
  const taskType = intent.intent;
634
636
  const combinedQuery = options?.queryPlan?.code[0]?.query
635
637
  ?? mergeQueries(query, expandQuery(query), options?.expandedTerms);
636
- const targetAnchors = options?.intentArtifact?.targetAnchors ?? extractTargetAnchors(query);
637
- const retrievalTaskPlan = buildRetrievalTaskPlan({
638
+ const explicitTargetAnchors = options?.intentArtifact?.targetAnchors ?? extractTargetAnchors(query);
639
+ const initialTaskPlan = buildRetrievalTaskPlan({
638
640
  query,
639
641
  parsedIntent: intent,
640
- targetAnchors,
642
+ targetAnchors: explicitTargetAnchors,
641
643
  activeSkill: options?.activeSkill,
642
644
  command: options?.command,
643
645
  authoritativeArtifact: options?.intentArtifact,
@@ -652,6 +654,49 @@ export class ContextEngine {
652
654
  intentArtifactHash: options?.intentArtifact?.artifactHash,
653
655
  queryPlanHash: options?.queryPlan?.planHash,
654
656
  };
657
+ let artifactInventory = this.indexer
658
+ ? buildArtifactInventory({
659
+ codegraph: this.cg,
660
+ indexer: this.indexer,
661
+ query: combinedQuery,
662
+ explicitTargetAnchors,
663
+ action: initialTaskPlan.action,
664
+ identity: logIdentity,
665
+ })
666
+ : { entries: [], operationTargets: [], missingExplicitTargets: [], ambiguous: false };
667
+ const staleInventoryTargets = artifactInventory.operationTargets
668
+ .filter(entry => entry.freshness.exists && !entry.freshness.current)
669
+ .map(entry => entry.path);
670
+ if (this.indexer && staleInventoryTargets.length > 0) {
671
+ await this.indexer.ensureFilesCurrent(staleInventoryTargets, { refresh: true, timeoutMs: 5_000 });
672
+ artifactInventory = buildArtifactInventory({
673
+ codegraph: this.cg,
674
+ indexer: this.indexer,
675
+ query: combinedQuery,
676
+ explicitTargetAnchors,
677
+ action: initialTaskPlan.action,
678
+ identity: logIdentity,
679
+ });
680
+ }
681
+ const targetAnchors = [...new Set([
682
+ ...explicitTargetAnchors,
683
+ ...artifactInventory.operationTargets
684
+ .filter(entry => entry.freshness.current)
685
+ .map(entry => entry.path),
686
+ ])];
687
+ const retrievalTaskPlan = buildRetrievalTaskPlan({
688
+ query,
689
+ parsedIntent: intent,
690
+ targetAnchors,
691
+ activeSkill: options?.activeSkill,
692
+ command: options?.command,
693
+ authoritativeArtifact: options?.intentArtifact,
694
+ });
695
+ if (artifactInventory.missingExplicitTargets.length > 0) {
696
+ warnings.push(`explicit-target-missing:${artifactInventory.missingExplicitTargets.length}`);
697
+ }
698
+ if (artifactInventory.ambiguous)
699
+ warnings.push('artifact-target-ambiguous');
655
700
  const timing = {};
656
701
  const t0 = Date.now();
657
702
  const [cgResult, knowledgeResult, memoryHits] = await Promise.all([
@@ -735,6 +780,20 @@ export class ContextEngine {
735
780
  }
736
781
  ctx.nodes = Array.isArray(ctx.nodes) ? ctx.nodes : [];
737
782
  ctx.entryPoints = Array.isArray(ctx.entryPoints) ? ctx.entryPoints : [];
783
+ const inventoryNodeIds = new Set(ctx.nodes.map((node) => String(node.id ?? '')));
784
+ for (const target of artifactInventory.operationTargets.filter(entry => entry.freshness.current)) {
785
+ const nodes = this.cg.getNodesInFile(target.path)
786
+ .filter(node => node.kind !== 'file' && node.kind !== 'import');
787
+ for (const node of nodes) {
788
+ if (!inventoryNodeIds.has(node.id)) {
789
+ ctx.nodes.push(node);
790
+ inventoryNodeIds.add(node.id);
791
+ }
792
+ }
793
+ const root = nodes.find(node => target.symbols.includes(node.name)) ?? nodes[0];
794
+ if (root && !ctx.entryPoints.some((entry) => entry.id === root.id))
795
+ ctx.entryPoints.unshift(root);
796
+ }
738
797
  await this.applyTaskSymbolVectorRecall(ctx, combinedQuery, warnings);
739
798
  this.clearRecoveredSymbolWarning(warnings);
740
799
  // Fallback: direct searchNodes for query terms that buildContext may have missed
@@ -797,6 +856,22 @@ export class ContextEngine {
797
856
  ctx.edges = edgeQuality.accepted;
798
857
  if (edgeQuality.rejected.length > 0) {
799
858
  warnings.push(`codegraph-relations-rejected:${edgeQuality.rejected.length}`);
859
+ emitSemanticControlLog({
860
+ event: 'codegraph.edge.rejected',
861
+ identity: logIdentity,
862
+ level: 'warn',
863
+ timestamp: Date.now(),
864
+ data: {
865
+ rejectedCount: edgeQuality.rejected.length,
866
+ reasons: countValues(edgeQuality.rejected.map(edge => edge.reason)),
867
+ examples: edgeQuality.rejected.slice(0, 8).map(edge => ({
868
+ kind: edge.kind,
869
+ sourceFile: edge.sourceFile,
870
+ targetFile: edge.targetFile,
871
+ reason: edge.reason,
872
+ })),
873
+ },
874
+ });
800
875
  }
801
876
  const tSnippet = Date.now();
802
877
  let allNodes = ctx.nodes ?? [];
@@ -845,6 +920,10 @@ export class ContextEngine {
845
920
  const optionalCandidates = new Map();
846
921
  const graphOptionalPaths = new Set();
847
922
  const queryTerms = combinedQuery.split(/\s+/).map(term => term.toLowerCase()).filter(term => term.length >= 3);
923
+ for (const target of artifactInventory.operationTargets) {
924
+ if (target.freshness.current)
925
+ requiredFileSet.add(target.path);
926
+ }
848
927
  for (const node of allNodes) {
849
928
  // Skip file wrappers and import edges — they're not actionable symbols
850
929
  if (node.kind === "file" || node.kind === "import")
@@ -899,6 +978,16 @@ export class ContextEngine {
899
978
  }
900
979
  }
901
980
  const fileRoleByPath = new Map();
981
+ for (const artifact of artifactInventory.entries.filter(entry => entry.freshness.current)) {
982
+ fileRoleByPath.set(artifact.path, {
983
+ path: artifact.path,
984
+ role: artifact.artifactRole === 'operation_target' ? 'target' : 'dependency',
985
+ artifactRole: artifact.artifactRole,
986
+ score: artifact.score,
987
+ evidence: artifact.evidence,
988
+ });
989
+ fileFreshnessByPath.set(artifact.path, artifact.freshness);
990
+ }
902
991
  const roleCandidates = this.indexer
903
992
  ? assembleContextFileRoles({
904
993
  codegraph: this.cg,
@@ -911,7 +1000,10 @@ export class ContextEngine {
911
1000
  if (this.indexer?.getFileFreshness) {
912
1001
  fileFreshnessByPath.set(candidate.path, this.indexer.getFileFreshness(candidate.path));
913
1002
  }
914
- fileRoleByPath.set(candidate.path, candidate);
1003
+ const inventoryRole = fileRoleByPath.get(candidate.path);
1004
+ fileRoleByPath.set(candidate.path, inventoryRole && inventoryRole.score >= candidate.score
1005
+ ? inventoryRole
1006
+ : candidate);
915
1007
  if (candidate.role === 'target') {
916
1008
  requiredFileSet.add(candidate.path);
917
1009
  continue;
@@ -1639,4 +1731,10 @@ function getGroupFilePaths(group) {
1639
1731
  return group;
1640
1732
  return group?.files ?? [];
1641
1733
  }
1734
+ function countValues(values) {
1735
+ const counts = {};
1736
+ for (const value of values)
1737
+ counts[value] = (counts[value] ?? 0) + 1;
1738
+ return counts;
1739
+ }
1642
1740
  //# sourceMappingURL=context-engine.js.map