@reqlan/analytical 0.4.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.
Files changed (97) hide show
  1. package/out/analysis/analyser-registry.d.ts +21 -0
  2. package/out/analysis/analyser-registry.js +33 -0
  3. package/out/analysis/analyser-registry.js.map +1 -0
  4. package/out/analysis/completion-tracking-analyser.d.ts +3 -0
  5. package/out/analysis/completion-tracking-analyser.js +37 -0
  6. package/out/analysis/completion-tracking-analyser.js.map +1 -0
  7. package/out/analysis/deprecation-impact-analyser.d.ts +3 -0
  8. package/out/analysis/deprecation-impact-analyser.js +21 -0
  9. package/out/analysis/deprecation-impact-analyser.js.map +1 -0
  10. package/out/analysis/file-related-analyser.d.ts +5 -0
  11. package/out/analysis/file-related-analyser.js +41 -0
  12. package/out/analysis/file-related-analyser.js.map +1 -0
  13. package/out/analysis/git-dates-analyser.d.ts +9 -0
  14. package/out/analysis/git-dates-analyser.js +39 -0
  15. package/out/analysis/git-dates-analyser.js.map +1 -0
  16. package/out/analysis/list-ideas-analyser.d.ts +3 -0
  17. package/out/analysis/list-ideas-analyser.js +7 -0
  18. package/out/analysis/list-ideas-analyser.js.map +1 -0
  19. package/out/analysis/local-graph-analyser.d.ts +6 -0
  20. package/out/analysis/local-graph-analyser.js +42 -0
  21. package/out/analysis/local-graph-analyser.js.map +1 -0
  22. package/out/analysis/semantic-search-analyser.d.ts +8 -0
  23. package/out/analysis/semantic-search-analyser.js +51 -0
  24. package/out/analysis/semantic-search-analyser.js.map +1 -0
  25. package/out/analysis-api.d.ts +31 -0
  26. package/out/analysis-api.js +136 -0
  27. package/out/analysis-api.js.map +1 -0
  28. package/out/core/analytical-store.d.ts +78 -0
  29. package/out/core/analytical-store.js +141 -0
  30. package/out/core/analytical-store.js.map +1 -0
  31. package/out/core/context-model.d.ts +187 -0
  32. package/out/core/context-model.js +36 -0
  33. package/out/core/context-model.js.map +1 -0
  34. package/out/core/context-signals.d.ts +149 -0
  35. package/out/core/context-signals.js +397 -0
  36. package/out/core/context-signals.js.map +1 -0
  37. package/out/core/file-path-match.d.ts +7 -0
  38. package/out/core/file-path-match.js +39 -0
  39. package/out/core/file-path-match.js.map +1 -0
  40. package/out/core/file-reference-resolve.d.ts +8 -0
  41. package/out/core/file-reference-resolve.js +28 -0
  42. package/out/core/file-reference-resolve.js.map +1 -0
  43. package/out/core/idea-references.d.ts +13 -0
  44. package/out/core/idea-references.js +25 -0
  45. package/out/core/idea-references.js.map +1 -0
  46. package/out/core/index-error.d.ts +23 -0
  47. package/out/core/index-error.js +33 -0
  48. package/out/core/index-error.js.map +1 -0
  49. package/out/core/types.d.ts +172 -0
  50. package/out/core/types.js +48 -0
  51. package/out/core/types.js.map +1 -0
  52. package/out/core/workspace-paths.d.ts +4 -0
  53. package/out/core/workspace-paths.js +92 -0
  54. package/out/core/workspace-paths.js.map +1 -0
  55. package/out/create-runtime.d.ts +21 -0
  56. package/out/create-runtime.js +39 -0
  57. package/out/create-runtime.js.map +1 -0
  58. package/out/export/build-export-snapshot.d.ts +3 -0
  59. package/out/export/build-export-snapshot.js +573 -0
  60. package/out/export/build-export-snapshot.js.map +1 -0
  61. package/out/export/html-export-assets.d.ts +3 -0
  62. package/out/export/html-export-assets.js +1066 -0
  63. package/out/export/html-export-assets.js.map +1 -0
  64. package/out/export/html-export-template.d.ts +17 -0
  65. package/out/export/html-export-template.js +930 -0
  66. package/out/export/html-export-template.js.map +1 -0
  67. package/out/export/html-export-utils.d.ts +45 -0
  68. package/out/export/html-export-utils.js +262 -0
  69. package/out/export/html-export-utils.js.map +1 -0
  70. package/out/export/types.d.ts +187 -0
  71. package/out/export/types.js +2 -0
  72. package/out/export/types.js.map +1 -0
  73. package/out/export/write-html-export.d.ts +2 -0
  74. package/out/export/write-html-export.js +143 -0
  75. package/out/export/write-html-export.js.map +1 -0
  76. package/out/headless-index-service.d.ts +23 -0
  77. package/out/headless-index-service.js +171 -0
  78. package/out/headless-index-service.js.map +1 -0
  79. package/out/index-store/idea-extractor.d.ts +6 -0
  80. package/out/index-store/idea-extractor.js +271 -0
  81. package/out/index-store/idea-extractor.js.map +1 -0
  82. package/out/index-store/schema.d.ts +10 -0
  83. package/out/index-store/schema.js +54 -0
  84. package/out/index-store/schema.js.map +1 -0
  85. package/out/index-store/sqlite-store.d.ts +66 -0
  86. package/out/index-store/sqlite-store.js +964 -0
  87. package/out/index-store/sqlite-store.js.map +1 -0
  88. package/out/index-store/webview-graph-queries.d.ts +62 -0
  89. package/out/index-store/webview-graph-queries.js +256 -0
  90. package/out/index-store/webview-graph-queries.js.map +1 -0
  91. package/out/index-store/webview-table-queries.d.ts +57 -0
  92. package/out/index-store/webview-table-queries.js +199 -0
  93. package/out/index-store/webview-table-queries.js.map +1 -0
  94. package/out/index.d.ts +40 -0
  95. package/out/index.js +27 -0
  96. package/out/index.js.map +1 -0
  97. package/package.json +52 -0
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Registry and contracts for graph analysers.
3
+ */
4
+ import type { AnalyticalStore } from '../core/analytical-store.js';
5
+ import type { SqliteIndexStore } from '../index-store/sqlite-store.js';
6
+ export interface AnalyserContext {
7
+ store: SqliteIndexStore;
8
+ analytical: AnalyticalStore;
9
+ workspaceRoot?: string;
10
+ }
11
+ export interface Analyser<TParams = unknown, TResult = unknown> {
12
+ readonly id: string;
13
+ run(context: AnalyserContext, params: TParams): Promise<TResult> | TResult;
14
+ }
15
+ export declare class AnalyserRegistry {
16
+ private readonly analysers;
17
+ register<TParams, TResult>(analyser: Analyser<TParams, TResult>): void;
18
+ get(id: string): Analyser | undefined;
19
+ run<TParams, TResult>(context: AnalyserContext, id: string, params: TParams): Promise<TResult>;
20
+ list(): string[];
21
+ }
@@ -0,0 +1,33 @@
1
+ export class AnalyserRegistry {
2
+ constructor() {
3
+ this.analysers = new Map();
4
+ }
5
+ register(analyser) {
6
+ this.analysers.set(analyser.id, analyser);
7
+ }
8
+ get(id) {
9
+ return this.analysers.get(id);
10
+ }
11
+ async run(context, id, params) {
12
+ const analyser = this.analysers.get(id);
13
+ if (!analyser) {
14
+ throw new Error(`Unknown analyser: ${id}`);
15
+ }
16
+ const { startAnalysis, completeAnalysis, failAnalysis } = context.analytical.getState();
17
+ startAnalysis(id, params);
18
+ try {
19
+ const result = await analyser.run(context, params);
20
+ completeAnalysis(id, result);
21
+ return result;
22
+ }
23
+ catch (error) {
24
+ const message = error instanceof Error ? error.message : String(error);
25
+ failAnalysis(id, message);
26
+ throw error;
27
+ }
28
+ }
29
+ list() {
30
+ return [...this.analysers.keys()];
31
+ }
32
+ }
33
+ //# sourceMappingURL=analyser-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyser-registry.js","sourceRoot":"","sources":["../../src/analysis/analyser-registry.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAO,gBAAgB;IAA7B;QACqB,cAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IA+B/E,CAAC;IA7BG,QAAQ,CAAmB,QAAoC;QAC3D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAsC,CAAC,CAAC;IAC5E,CAAC;IAED,GAAG,CAAC,EAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAmB,OAAwB,EAAE,EAAU,EAAE,MAAe;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACxF,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAY,CAAC;YAC9D,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC7B,OAAO,MAAM,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC1B,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED,IAAI;QACA,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;CACJ"}
@@ -0,0 +1,3 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { CompletionSummary } from '../core/types.js';
3
+ export declare const completionTrackingAnalyser: Analyser<void, CompletionSummary>;
@@ -0,0 +1,37 @@
1
+ import { isDeprecated, ideaStatus, parseAttributes } from '../core/types.js';
2
+ const OUTSTANDING_STATUSES = new Set(['pending', 'todo', 'open', 'in_progress', 'blocked', 'stub']);
3
+ export const completionTrackingAnalyser = {
4
+ id: 'completion_tracking',
5
+ async run({ store }) {
6
+ const ideas = await store.listAllIdeas();
7
+ const allRaw = await store.getAllIdeasRaw();
8
+ const byStatus = {};
9
+ const byTag = {};
10
+ const outstanding = [];
11
+ const deprecated = [];
12
+ for (const idea of ideas) {
13
+ const raw = allRaw.find(entry => entry.id === idea.id);
14
+ const attributes = parseAttributes(raw?.attributesJson ?? '{}');
15
+ const status = ideaStatus(attributes) ?? 'unspecified';
16
+ byStatus[status] = (byStatus[status] ?? 0) + 1;
17
+ for (const tag of idea.tags) {
18
+ byTag[tag] = (byTag[tag] ?? 0) + 1;
19
+ }
20
+ if (isDeprecated(attributes) || idea.tags.some(tag => tag.toLowerCase() === 'deprecated')) {
21
+ deprecated.push(idea);
22
+ }
23
+ else if (OUTSTANDING_STATUSES.has(status.toLowerCase()) ||
24
+ idea.tags.some(tag => ['todo', 'stub', 'open'].includes(tag.toLowerCase()))) {
25
+ outstanding.push(idea);
26
+ }
27
+ }
28
+ return {
29
+ total: ideas.length,
30
+ byStatus,
31
+ byTag,
32
+ outstanding,
33
+ deprecated
34
+ };
35
+ }
36
+ };
37
+ //# sourceMappingURL=completion-tracking-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-tracking-analyser.js","sourceRoot":"","sources":["../../src/analysis/completion-tracking-analyser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAI7E,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpG,MAAM,CAAC,MAAM,0BAA0B,GAAsC;IACzE,EAAE,EAAE,qBAAqB;IACzB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE;QACf,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,MAAM,WAAW,GAAkB,EAAE,CAAC;QACtC,MAAM,UAAU,GAAkB,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,EAAE,cAAc,IAAI,IAAI,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,aAAa,CAAC;YACvD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAE/C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1B,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvC,CAAC;YAED,IAAI,YAAY,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,EAAE,CAAC;gBACxF,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;iBAAM,IACH,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,EAC7E,CAAC;gBACC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;QACL,CAAC;QAED,OAAO;YACH,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,QAAQ;YACR,KAAK;YACL,WAAW;YACX,UAAU;SACb,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { DeprecationImpact } from '../core/types.js';
3
+ export declare const deprecationImpactAnalyser: Analyser<void, DeprecationImpact[]>;
@@ -0,0 +1,21 @@
1
+ import { isDeprecated, parseAttributes } from '../core/types.js';
2
+ export const deprecationImpactAnalyser = {
3
+ id: 'deprecation_impact_analysis',
4
+ async run({ store }) {
5
+ const impacts = [];
6
+ const allIdeas = await store.listAllIdeas();
7
+ const allRaw = await store.getAllIdeasRaw();
8
+ for (const idea of allIdeas) {
9
+ const raw = allRaw.find(entry => entry.id === idea.id);
10
+ const attributes = parseAttributes(raw?.attributesJson ?? '{}');
11
+ if (!isDeprecated(attributes)) {
12
+ continue;
13
+ }
14
+ const inbound = await store.getEdgesTo(idea.id);
15
+ const dependents = (await Promise.all(inbound.map(edge => store.getIdea(edge.sourceId)))).filter((entry) => entry !== undefined);
16
+ impacts.push({ deprecated: idea, dependents });
17
+ }
18
+ return impacts;
19
+ }
20
+ };
21
+ //# sourceMappingURL=deprecation-impact-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecation-impact-analyser.js","sourceRoot":"","sources":["../../src/analysis/deprecation-impact-analyser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIjE,MAAM,CAAC,MAAM,yBAAyB,GAAwC;IAC1E,EAAE,EAAE,6BAA6B;IACjC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE;QACf,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC;QAC5C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,EAAE,cAAc,IAAI,IAAI,CAAC,CAAC;YAChE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5B,SAAS;YACb,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,CACf,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CACvE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAsC,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { FileRelatedRequirements } from '../core/types.js';
3
+ export declare const fileRelatedAnalyser: Analyser<{
4
+ fileUri: string;
5
+ }, FileRelatedRequirements>;
@@ -0,0 +1,41 @@
1
+ import { basename } from 'node:path';
2
+ import { matchFileReferenceTarget } from '../core/file-path-match.js';
3
+ import { toWorkspaceRelativePath } from '../core/workspace-paths.js';
4
+ export const fileRelatedAnalyser = {
5
+ id: 'file_related_requirements',
6
+ async run({ store, workspaceRoot }, { fileUri }) {
7
+ const indexedFileUri = workspaceRoot ? toWorkspaceRelativePath(fileUri, workspaceRoot) : fileUri;
8
+ const ideasInFile = await store.getIdeasInFile(indexedFileUri);
9
+ const fileName = basename(indexedFileUri);
10
+ const referencingIds = new Set();
11
+ const folderReferencingIds = new Set();
12
+ for (const edge of await store.getAllEdges()) {
13
+ if (edge.targetId && ideasInFile.some(idea => idea.id === edge.targetId)) {
14
+ referencingIds.add(edge.sourceId);
15
+ }
16
+ if (edge.kind === 'file_reference' && edge.targetFile) {
17
+ const match = matchFileReferenceTarget(edge.targetFile, indexedFileUri, fileName);
18
+ if (match === 'file') {
19
+ referencingIds.add(edge.sourceId);
20
+ }
21
+ else if (match === 'folder') {
22
+ folderReferencingIds.add(edge.sourceId);
23
+ }
24
+ }
25
+ }
26
+ const loadIdeas = async (ids) => (await Promise.all([...ids].map(id => store.getIdea(id)))).filter((idea) => idea !== undefined);
27
+ const referencingIdeas = await loadIdeas(referencingIds);
28
+ const folderReferencingIdeas = (await loadIdeas(folderReferencingIds)).filter(idea => !referencingIds.has(idea.id));
29
+ const commentLinkedIdeas = (await Promise.all((await store.getEdgesReferencingFile(fileName))
30
+ .filter(edge => edge.kind === 'comment_link')
31
+ .map(edge => (edge.targetId ? store.getIdea(edge.targetId) : Promise.resolve(undefined))))).filter((idea) => idea !== undefined);
32
+ return {
33
+ fileUri: indexedFileUri,
34
+ ideasInFile,
35
+ referencingIdeas,
36
+ commentLinkedIdeas,
37
+ folderReferencingIdeas
38
+ };
39
+ }
40
+ };
41
+ //# sourceMappingURL=file-related-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-related-analyser.js","sourceRoot":"","sources":["../../src/analysis/file-related-analyser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,CAAC,MAAM,mBAAmB,GAA2D;IACvF,EAAE,EAAE,2BAA2B;IAC/B,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE;QAC3C,MAAM,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACjG,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;QACzC,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/C,KAAK,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtC,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpD,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;gBAClF,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACnB,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtC,CAAC;qBAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC5B,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5C,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,EAAE,GAAgB,EAA0B,EAAE,CACjE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAC7D,CAAC,IAAI,EAAoC,EAAE,CAAC,IAAI,KAAK,SAAS,CACjE,CAAC;QAEN,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,CAAC;QACzD,MAAM,sBAAsB,GAAG,CAAC,MAAM,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CACzE,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACvC,CAAC;QAEF,MAAM,kBAAkB,GAAG,CACvB,MAAM,OAAO,CAAC,GAAG,CACb,CAAC,MAAM,KAAK,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;aAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;aAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAChG,CACJ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAoC,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAEzE,OAAO;YACH,OAAO,EAAE,cAAc;YACvB,WAAW;YACX,gBAAgB;YAChB,kBAAkB;YAClB,sBAAsB;SACzB,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ export interface GitDateInfo {
3
+ ideaId: string;
4
+ createdAt?: string;
5
+ modifiedAt?: string;
6
+ }
7
+ export declare const gitDatesAnalyser: Analyser<{
8
+ ideaIds?: string[];
9
+ }, GitDateInfo[]>;
@@ -0,0 +1,39 @@
1
+ import { URI } from 'langium';
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { resolveWorkspaceFileUri } from '../core/workspace-paths.js';
5
+ const execFileAsync = promisify(execFile);
6
+ export const gitDatesAnalyser = {
7
+ id: 'git_dates',
8
+ async run({ store, workspaceRoot }, { ideaIds }) {
9
+ const ideas = ideaIds
10
+ ? (await Promise.all(ideaIds.map(id => store.getIdea(id)))).filter((idea) => !!idea)
11
+ : await store.listAllIdeas();
12
+ const results = [];
13
+ for (const idea of ideas) {
14
+ const dates = await lookupGitDates(idea.fileUri, idea.lineStart + 1, workspaceRoot);
15
+ if (dates.createdAt || dates.modifiedAt) {
16
+ await store.updateGitDates(idea.id, dates.createdAt, dates.modifiedAt);
17
+ }
18
+ results.push({ ideaId: idea.id, ...dates });
19
+ }
20
+ return results;
21
+ }
22
+ };
23
+ async function lookupGitDates(fileUri, line, workspaceRoot) {
24
+ const resolvedUri = resolveWorkspaceFileUri(fileUri, workspaceRoot);
25
+ const filePath = resolvedUri.startsWith('file://') ? URI.parse(resolvedUri).fsPath : resolvedUri;
26
+ const cwd = workspaceRoot;
27
+ try {
28
+ const { stdout: createdStdout } = await execFileAsync('git', ['log', '--diff-filter=A', '--format=%aI', '-1', '--', filePath], { cwd });
29
+ const { stdout: modifiedStdout } = await execFileAsync('git', ['log', '-L', `${line},${line}:${filePath}`, '--format=%aI', '-1'], { cwd });
30
+ return {
31
+ createdAt: createdStdout.trim() || undefined,
32
+ modifiedAt: modifiedStdout.trim() || undefined
33
+ };
34
+ }
35
+ catch {
36
+ return {};
37
+ }
38
+ }
39
+ //# sourceMappingURL=git-dates-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-dates-analyser.js","sourceRoot":"","sources":["../../src/analysis/git-dates-analyser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAQ1C,MAAM,CAAC,MAAM,gBAAgB,GAAoD;IAC7E,EAAE,EAAE,WAAW;IACf,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE;QAC3C,MAAM,KAAK,GAAG,OAAO;YACjB,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAoC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACtH,CAAC,CAAC,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QACjC,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;YACpF,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACtC,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ,CAAC;AAEF,KAAK,UAAU,cAAc,CACzB,OAAe,EACf,IAAY,EACZ,aAAsB;IAEtB,MAAM,WAAW,GAAG,uBAAuB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;IACjG,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,IAAI,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,aAAa,CACjD,KAAK,EACL,CAAC,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAChE,EAAE,GAAG,EAAE,CACV,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,aAAa,CAClD,KAAK,EACL,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,IAAI,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,EAClE,EAAE,GAAG,EAAE,CACV,CAAC;QACF,OAAO;YACH,SAAS,EAAE,aAAa,CAAC,IAAI,EAAE,IAAI,SAAS;YAC5C,UAAU,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,SAAS;SACjD,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { IdeaSummary } from '../core/types.js';
3
+ export declare const listAllIdeasAnalyser: Analyser<void, IdeaSummary[]>;
@@ -0,0 +1,7 @@
1
+ export const listAllIdeasAnalyser = {
2
+ id: 'list_all_ideas',
3
+ async run({ store }) {
4
+ return store.listAllIdeas();
5
+ }
6
+ };
7
+ //# sourceMappingURL=list-ideas-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-ideas-analyser.js","sourceRoot":"","sources":["../../src/analysis/list-ideas-analyser.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,oBAAoB,GAAkC;IAC/D,EAAE,EAAE,gBAAgB;IACpB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE;QACf,OAAO,KAAK,CAAC,YAAY,EAAE,CAAC;IAChC,CAAC;CACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { GraphSlice } from '../core/types.js';
3
+ export declare const localGraphAnalyser: Analyser<{
4
+ centerId: string;
5
+ depth?: number;
6
+ }, GraphSlice>;
@@ -0,0 +1,42 @@
1
+ export const localGraphAnalyser = {
2
+ id: 'local_graph_analysis',
3
+ async run({ store }, { centerId, depth = 1 }) {
4
+ const center = await store.getIdea(centerId);
5
+ if (!center) {
6
+ return { centerId, depth, nodes: [], edges: [] };
7
+ }
8
+ const nodes = new Map();
9
+ const edges = new Map();
10
+ const visited = new Set();
11
+ const queue = [{ id: centerId, remaining: depth }];
12
+ while (queue.length > 0) {
13
+ const current = queue.shift();
14
+ if (visited.has(current.id)) {
15
+ continue;
16
+ }
17
+ visited.add(current.id);
18
+ const idea = await store.getIdea(current.id);
19
+ if (idea) {
20
+ nodes.set(idea.id, idea);
21
+ }
22
+ const outbound = await store.getEdgesFrom(current.id);
23
+ const inbound = await store.getEdgesTo(current.id);
24
+ for (const edge of [...outbound, ...inbound]) {
25
+ edges.set(edge.id, edge);
26
+ if (current.remaining > 0) {
27
+ const nextId = edge.sourceId === current.id ? edge.targetId : edge.sourceId;
28
+ if (nextId) {
29
+ queue.push({ id: nextId, remaining: current.remaining - 1 });
30
+ }
31
+ }
32
+ }
33
+ }
34
+ return {
35
+ centerId,
36
+ depth,
37
+ nodes: [...nodes.values()],
38
+ edges: [...edges.values()]
39
+ };
40
+ }
41
+ };
42
+ //# sourceMappingURL=local-graph-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-graph-analyser.js","sourceRoot":"","sources":["../../src/analysis/local-graph-analyser.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAA+D;IAC1F,EAAE,EAAE,sBAAsB;IAC1B,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,KAAK,GAA6C,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAE7F,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC1B,SAAS;YACb,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE,CAAC;gBACP,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACnD,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;gBAC3C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBACzB,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC5E,IAAI,MAAM,EAAE,CAAC;wBACT,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAC;oBACjE,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO;YACH,QAAQ;YACR,KAAK;YACL,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC1B,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;SAC7B,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Analyser } from './analyser-registry.js';
2
+ import type { SemanticMatch } from '../core/types.js';
3
+ export interface SemanticSearchParams {
4
+ query: string;
5
+ ideaset?: string;
6
+ limit?: number;
7
+ }
8
+ export declare const semanticSearchAnalyser: Analyser<SemanticSearchParams, SemanticMatch[]>;
@@ -0,0 +1,51 @@
1
+ export const semanticSearchAnalyser = {
2
+ id: 'semantic_analysis',
3
+ async run({ store }, { query, ideaset, limit = 20 }) {
4
+ const normalized = query.toLowerCase();
5
+ const tokens = normalized.split(/\s+/).filter(Boolean);
6
+ const candidates = await store.searchByNameOrSummary(query);
7
+ const matches = [];
8
+ for (const idea of candidates) {
9
+ if (ideaset && idea.kind === 'ideaset' && idea.name !== ideaset) {
10
+ continue;
11
+ }
12
+ const haystack = `${idea.name} ${idea.summary} ${idea.tags.join(' ')}`.toLowerCase();
13
+ const reasons = [];
14
+ let score = 0;
15
+ if (idea.name.toLowerCase().includes(normalized)) {
16
+ score += 3;
17
+ reasons.push('name match');
18
+ }
19
+ if (idea.summary.toLowerCase().includes(normalized)) {
20
+ score += 2;
21
+ reasons.push('summary match');
22
+ }
23
+ for (const token of tokens) {
24
+ if (haystack.includes(token)) {
25
+ score += 1;
26
+ reasons.push(`token:${token}`);
27
+ }
28
+ }
29
+ for (const tag of idea.tags) {
30
+ if (tag.toLowerCase().includes(normalized)) {
31
+ score += 1;
32
+ reasons.push(`tag:${tag}`);
33
+ }
34
+ }
35
+ const relatedEdges = await store.getEdgesFrom(idea.id);
36
+ for (const edge of relatedEdges) {
37
+ if (edge.label?.toLowerCase().includes(normalized)) {
38
+ score += 1;
39
+ reasons.push('reference label');
40
+ }
41
+ }
42
+ if (score > 0) {
43
+ matches.push({ idea, score, reasons: [...new Set(reasons)] });
44
+ }
45
+ }
46
+ return matches
47
+ .sort((left, right) => right.score - left.score)
48
+ .slice(0, limit);
49
+ }
50
+ };
51
+ //# sourceMappingURL=semantic-search-analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search-analyser.js","sourceRoot":"","sources":["../../src/analysis/semantic-search-analyser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { CompletionSummary, DeprecationImpact, FileRelatedRequirements, GraphSlice, IdeaSummary } from './core/types.js';
2
+ import type { AnalysisRuntime } from './create-runtime.js';
3
+ export interface RequirementMatch {
4
+ idea: IdeaSummary;
5
+ score?: number;
6
+ reasons?: string[];
7
+ }
8
+ export interface InteractionDescriptor {
9
+ name: string;
10
+ description: string;
11
+ parameters: Record<string, string>;
12
+ }
13
+ export declare class AnalysisApi {
14
+ private readonly runtime;
15
+ constructor(runtime: AnalysisRuntime);
16
+ ensureReady(): Promise<void>;
17
+ searchRequirements(query: string, limit?: number): Promise<RequirementMatch[]>;
18
+ listRequirements(limit?: number): Promise<IdeaSummary[]>;
19
+ getFileContext(filePath: string): Promise<FileRelatedRequirements>;
20
+ getLocalGraph(filePath: string, depth?: number): Promise<GraphSlice | undefined>;
21
+ summarizeSubtree(requirementName: string, depth?: number): Promise<GraphSlice | undefined>;
22
+ getCompletionStatus(): Promise<CompletionSummary>;
23
+ getDeprecationImpact(): Promise<DeprecationImpact[]>;
24
+ resolveRequirementReference(name?: string): Promise<IdeaSummary[]>;
25
+ resolveFileReference(pathPrefix?: string): Promise<Array<{
26
+ path: string;
27
+ ideas: IdeaSummary[];
28
+ }>>;
29
+ listInteractions(): InteractionDescriptor[];
30
+ formatIdea(idea: IdeaSummary): string;
31
+ }
@@ -0,0 +1,136 @@
1
+ export class AnalysisApi {
2
+ constructor(runtime) {
3
+ this.runtime = runtime;
4
+ }
5
+ async ensureReady() {
6
+ if (this.runtime.index.isReady) {
7
+ return;
8
+ }
9
+ await this.runtime.index.syncWorkspace();
10
+ }
11
+ async searchRequirements(query, limit = 8) {
12
+ await this.ensureReady();
13
+ const matches = await this.runtime.analysers.run(this.runtime.makeContext(), 'semantic_analysis', { query, limit });
14
+ return matches.map(match => ({
15
+ idea: match.idea,
16
+ score: match.score,
17
+ reasons: match.reasons
18
+ }));
19
+ }
20
+ async listRequirements(limit = 50) {
21
+ await this.ensureReady();
22
+ const ideas = await this.runtime.analysers.run(this.runtime.makeContext(), 'list_all_ideas', undefined);
23
+ return ideas.slice(0, limit);
24
+ }
25
+ async getFileContext(filePath) {
26
+ await this.ensureReady();
27
+ const fileUri = this.runtime.index.resolveFileUri(filePath);
28
+ return this.runtime.analysers.run(this.runtime.makeContext(), 'file_related_requirements', { fileUri });
29
+ }
30
+ async getLocalGraph(filePath, depth = 1) {
31
+ await this.ensureReady();
32
+ const fileUri = this.runtime.index.resolveFileUri(filePath);
33
+ const ideas = await this.runtime.index.indexStore.getIdeasInFile(fileUri);
34
+ if (ideas.length === 0) {
35
+ return undefined;
36
+ }
37
+ const center = ideas[0];
38
+ return this.runtime.analysers.run(this.runtime.makeContext(), 'local_graph_analysis', { centerId: center.id, depth });
39
+ }
40
+ async summarizeSubtree(requirementName, depth = 2) {
41
+ await this.ensureReady();
42
+ const matches = await this.searchRequirements(requirementName, 1);
43
+ const center = matches[0]?.idea;
44
+ if (!center) {
45
+ return undefined;
46
+ }
47
+ return this.runtime.analysers.run(this.runtime.makeContext(), 'local_graph_analysis', { centerId: center.id, depth });
48
+ }
49
+ async getCompletionStatus() {
50
+ await this.ensureReady();
51
+ return this.runtime.analysers.run(this.runtime.makeContext(), 'completion_tracking', undefined);
52
+ }
53
+ async getDeprecationImpact() {
54
+ await this.ensureReady();
55
+ return this.runtime.analysers.run(this.runtime.makeContext(), 'deprecation_impact_analysis', undefined);
56
+ }
57
+ async resolveRequirementReference(name) {
58
+ await this.ensureReady();
59
+ const query = name?.trim() ?? '';
60
+ if (query) {
61
+ const matches = await this.searchRequirements(query, 8);
62
+ return matches.map(match => match.idea);
63
+ }
64
+ return this.listRequirements(12);
65
+ }
66
+ async resolveFileReference(pathPrefix) {
67
+ await this.ensureReady();
68
+ const prefix = pathPrefix?.trim() ?? '';
69
+ const files = await this.runtime.index.listRqFiles(prefix).slice(0, 12);
70
+ const results = [];
71
+ for (const path of files) {
72
+ const related = await this.getFileContext(path).catch(() => undefined);
73
+ results.push({
74
+ path,
75
+ ideas: related?.ideasInFile.slice(0, 4) ?? []
76
+ });
77
+ }
78
+ return results;
79
+ }
80
+ listInteractions() {
81
+ return [
82
+ {
83
+ name: 'search_requirements',
84
+ description: 'Search requirements by keyword across names, summaries, tags, and references.',
85
+ parameters: { query: 'Search text', limit: 'Optional maximum number of matches' }
86
+ },
87
+ {
88
+ name: 'list_requirements',
89
+ description: 'List indexed requirements in the workspace.',
90
+ parameters: { limit: 'Optional maximum number of requirements' }
91
+ },
92
+ {
93
+ name: 'file_context',
94
+ description: 'Get requirements in, referencing, or comment-linked to a file.',
95
+ parameters: { filePath: 'Relative or absolute path to a .rq file' }
96
+ },
97
+ {
98
+ name: 'local_graph',
99
+ description: 'Get the local requirement graph around the first requirement in a file.',
100
+ parameters: { filePath: 'Relative or absolute path to a .rq file', depth: 'Optional hop depth' }
101
+ },
102
+ {
103
+ name: 'summarize_subtree',
104
+ description: 'Summarise a requirement subtree rooted at a named requirement.',
105
+ parameters: { requirementName: 'Requirement name or search text', depth: 'Optional hop depth' }
106
+ },
107
+ {
108
+ name: 'requirement_reference',
109
+ description: 'Resolve a requirement by name for compact chat or MCP context.',
110
+ parameters: { name: 'Optional requirement name or search text' }
111
+ },
112
+ {
113
+ name: 'file_reference',
114
+ description: 'Resolve requirements indexed in matching .rq files.',
115
+ parameters: { path: 'Optional path fragment filter' }
116
+ },
117
+ {
118
+ name: 'completion_status',
119
+ description: 'Summarise completion and deprecation status across the workspace graph.',
120
+ parameters: {}
121
+ },
122
+ {
123
+ name: 'list_interactions',
124
+ description: 'Discover available requirement graph interactions and parameters.',
125
+ parameters: {}
126
+ }
127
+ ];
128
+ }
129
+ formatIdea(idea) {
130
+ const location = `${this.runtime.index.relativePath(idea.fileUri)}:${idea.lineStart + 1}`;
131
+ const tags = idea.tags.length > 0 ? `\nTags: ${idea.tags.join(', ')}` : '';
132
+ const status = idea.status ? `\nStatus: ${idea.status}` : '';
133
+ return `### ${idea.name} (${location})\n${idea.summary || '(no summary)'}${status}${tags}`;
134
+ }
135
+ }
136
+ //# sourceMappingURL=analysis-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis-api.js","sourceRoot":"","sources":["../src/analysis-api.ts"],"names":[],"mappings":"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"}