@mortice/mapwright 0.8.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/CHANGELOG.md +161 -0
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/dist/catalogue/canonicalisation.d.ts +36 -0
- package/dist/catalogue/canonicalisation.js +262 -0
- package/dist/catalogue/config.d.ts +13 -0
- package/dist/catalogue/config.js +77 -0
- package/dist/catalogue/deterministic.d.ts +3 -0
- package/dist/catalogue/deterministic.js +25 -0
- package/dist/catalogue/diagnostics.d.ts +2 -0
- package/dist/catalogue/diagnostics.js +34 -0
- package/dist/catalogue/evidence.d.ts +1 -0
- package/dist/catalogue/evidence.js +10 -0
- package/dist/catalogue/examples.d.ts +3 -0
- package/dist/catalogue/examples.js +20 -0
- package/dist/catalogue/identity.d.ts +61 -0
- package/dist/catalogue/identity.js +114 -0
- package/dist/catalogue/ignore.d.ts +4 -0
- package/dist/catalogue/ignore.js +29 -0
- package/dist/catalogue/indexer.d.ts +20 -0
- package/dist/catalogue/indexer.js +1393 -0
- package/dist/catalogue/linkage.d.ts +16 -0
- package/dist/catalogue/linkage.js +419 -0
- package/dist/catalogue/moduleResolution.d.ts +4 -0
- package/dist/catalogue/moduleResolution.js +67 -0
- package/dist/catalogue/ordering.d.ts +13 -0
- package/dist/catalogue/ordering.js +86 -0
- package/dist/catalogue/packages.d.ts +12 -0
- package/dist/catalogue/packages.js +475 -0
- package/dist/catalogue/pythonReExports.d.ts +7 -0
- package/dist/catalogue/pythonReExports.js +113 -0
- package/dist/catalogue/resolveRefs.d.ts +40 -0
- package/dist/catalogue/resolveRefs.js +284 -0
- package/dist/catalogue/scanner.d.ts +8 -0
- package/dist/catalogue/scanner.js +99 -0
- package/dist/catalogue/schema.d.ts +289 -0
- package/dist/catalogue/schema.js +1 -0
- package/dist/catalogue/store.d.ts +41 -0
- package/dist/catalogue/store.js +209 -0
- package/dist/catalogue/templates.d.ts +18 -0
- package/dist/catalogue/templates.js +158 -0
- package/dist/catalogue/version.d.ts +12 -0
- package/dist/catalogue/version.js +30 -0
- package/dist/cli/commands/adoptionPlan.d.ts +8 -0
- package/dist/cli/commands/adoptionPlan.js +24 -0
- package/dist/cli/commands/auditDocs.d.ts +8 -0
- package/dist/cli/commands/auditDocs.js +24 -0
- package/dist/cli/commands/changeImpact.d.ts +10 -0
- package/dist/cli/commands/changeImpact.js +36 -0
- package/dist/cli/commands/changes.d.ts +12 -0
- package/dist/cli/commands/changes.js +31 -0
- package/dist/cli/commands/check.d.ts +9 -0
- package/dist/cli/commands/check.js +4 -0
- package/dist/cli/commands/compatibility.d.ts +10 -0
- package/dist/cli/commands/compatibility.js +43 -0
- package/dist/cli/commands/diff.d.ts +31 -0
- package/dist/cli/commands/diff.js +118 -0
- package/dist/cli/commands/dogfood.d.ts +8 -0
- package/dist/cli/commands/dogfood.js +24 -0
- package/dist/cli/commands/drift.d.ts +8 -0
- package/dist/cli/commands/drift.js +13 -0
- package/dist/cli/commands/index.d.ts +9 -0
- package/dist/cli/commands/index.js +9 -0
- package/dist/cli/commands/indexWorkspace.d.ts +8 -0
- package/dist/cli/commands/indexWorkspace.js +23 -0
- package/dist/cli/commands/recommendConfig.d.ts +7 -0
- package/dist/cli/commands/recommendConfig.js +20 -0
- package/dist/cli/commands/schema.d.ts +1 -0
- package/dist/cli/commands/schema.js +37 -0
- package/dist/cli/commands/template.d.ts +5 -0
- package/dist/cli/commands/template.js +44 -0
- package/dist/cli/commands/validate.d.ts +9 -0
- package/dist/cli/commands/validate.js +85 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +211 -0
- package/dist/comparison/artefactValidate.d.ts +19 -0
- package/dist/comparison/artefactValidate.js +334 -0
- package/dist/comparison/candidates.d.ts +12 -0
- package/dist/comparison/candidates.js +391 -0
- package/dist/comparison/compare.d.ts +15 -0
- package/dist/comparison/compare.js +240 -0
- package/dist/comparison/compatibility.d.ts +26 -0
- package/dist/comparison/compatibility.js +316 -0
- package/dist/comparison/drift.d.ts +34 -0
- package/dist/comparison/drift.js +71 -0
- package/dist/comparison/identity.d.ts +30 -0
- package/dist/comparison/identity.js +73 -0
- package/dist/comparison/impact.d.ts +14 -0
- package/dist/comparison/impact.js +291 -0
- package/dist/comparison/index.d.ts +6 -0
- package/dist/comparison/index.js +6 -0
- package/dist/comparison/integrity.d.ts +12 -0
- package/dist/comparison/integrity.js +199 -0
- package/dist/comparison/ordering.d.ts +4 -0
- package/dist/comparison/ordering.js +69 -0
- package/dist/comparison/projections.d.ts +19 -0
- package/dist/comparison/projections.js +185 -0
- package/dist/comparison/relationshipPolicy.d.ts +19 -0
- package/dist/comparison/relationshipPolicy.js +98 -0
- package/dist/comparison/schema.d.ts +178 -0
- package/dist/comparison/schema.js +16 -0
- package/dist/comparison/store.d.ts +58 -0
- package/dist/comparison/store.js +462 -0
- package/dist/comparison/validate.d.ts +23 -0
- package/dist/comparison/validate.js +137 -0
- package/dist/comparison/version.d.ts +9 -0
- package/dist/comparison/version.js +11 -0
- package/dist/extractors/docTags.d.ts +9 -0
- package/dist/extractors/docTags.js +106 -0
- package/dist/extractors/generic.d.ts +5 -0
- package/dist/extractors/generic.js +3 -0
- package/dist/extractors/javascript.d.ts +3 -0
- package/dist/extractors/javascript.js +4 -0
- package/dist/extractors/markdown.d.ts +7 -0
- package/dist/extractors/markdown.js +269 -0
- package/dist/extractors/python.d.ts +7 -0
- package/dist/extractors/python.js +314 -0
- package/dist/extractors/typescript.d.ts +7 -0
- package/dist/extractors/typescript.js +387 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mcp/resources.d.ts +18 -0
- package/dist/mcp/resources.js +57 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +95 -0
- package/dist/mcp/tools.d.ts +29 -0
- package/dist/mcp/tools.js +902 -0
- package/dist/queries/adoption.d.ts +62 -0
- package/dist/queries/adoption.js +366 -0
- package/dist/queries/capabilities.d.ts +45 -0
- package/dist/queries/capabilities.js +124 -0
- package/dist/queries/changes.d.ts +33 -0
- package/dist/queries/changes.js +53 -0
- package/dist/queries/dependencies.d.ts +17 -0
- package/dist/queries/dependencies.js +94 -0
- package/dist/queries/dogfood.d.ts +50 -0
- package/dist/queries/dogfood.js +116 -0
- package/dist/queries/editingContext.d.ts +84 -0
- package/dist/queries/editingContext.js +240 -0
- package/dist/queries/examples.d.ts +8 -0
- package/dist/queries/examples.js +16 -0
- package/dist/queries/files.d.ts +8 -0
- package/dist/queries/files.js +14 -0
- package/dist/queries/lists.d.ts +94 -0
- package/dist/queries/lists.js +184 -0
- package/dist/queries/overview.d.ts +2 -0
- package/dist/queries/overview.js +8 -0
- package/dist/queries/publicApis.d.ts +60 -0
- package/dist/queries/publicApis.js +120 -0
- package/dist/queries/ranking.d.ts +67 -0
- package/dist/queries/ranking.js +387 -0
- package/dist/queries/recommendConfig.d.ts +47 -0
- package/dist/queries/recommendConfig.js +123 -0
- package/dist/queries/relationships.d.ts +5 -0
- package/dist/queries/relationships.js +15 -0
- package/dist/queries/reuseCandidates.d.ts +34 -0
- package/dist/queries/reuseCandidates.js +181 -0
- package/dist/queries/symbols.d.ts +40 -0
- package/dist/queries/symbols.js +41 -0
- package/dist/security/pathPolicy.d.ts +12 -0
- package/dist/security/pathPolicy.js +46 -0
- package/dist/security/secretPatterns.d.ts +1 -0
- package/dist/security/secretPatterns.js +4 -0
- package/dist/security/sourceAccess.d.ts +12 -0
- package/dist/security/sourceAccess.js +35 -0
- package/package.json +60 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded, deterministically ordered list views for MCP list tools and static
|
|
3
|
+
* resources (Gate 2). Ordering comes from `../catalogue/ordering.js`; tool max
|
|
4
|
+
* limits and static resource windows are defined by the resource-continuation
|
|
5
|
+
* contract and enforced independently.
|
|
6
|
+
*/
|
|
7
|
+
import type { CapabilityRecord, CatalogueSnapshot, DiagnosticRecord, ExampleRecord, FileRecord, PackageRecord, PublicApiRecord, RelationshipRecord, SymbolRecord } from "../catalogue/schema.js";
|
|
8
|
+
export type CollectionName = "files" | "symbols" | "packages" | "capabilities" | "publicApis" | "examples" | "relationships" | "diagnostics";
|
|
9
|
+
export interface ListLimit {
|
|
10
|
+
default: number;
|
|
11
|
+
max: number;
|
|
12
|
+
}
|
|
13
|
+
/** Tool default/maximum page sizes from resource-continuation.md. */
|
|
14
|
+
export declare const LIST_LIMITS: Record<CollectionName, ListLimit>;
|
|
15
|
+
/** Fixed static-resource window sizes from resource-continuation.md. */
|
|
16
|
+
export declare const RESOURCE_WINDOWS: Record<CollectionName, number>;
|
|
17
|
+
/** Continuation tool per collection (Option A continuation). */
|
|
18
|
+
export declare const CONTINUATION_TOOLS: Record<CollectionName, string>;
|
|
19
|
+
/** Human-readable order key descriptions from semantic-ordering.md. */
|
|
20
|
+
export declare const ORDER_DESCRIPTIONS: Record<CollectionName, string>;
|
|
21
|
+
export interface ListEnvelope<T> {
|
|
22
|
+
total: number;
|
|
23
|
+
returned: number;
|
|
24
|
+
offset: number;
|
|
25
|
+
limit: number;
|
|
26
|
+
truncated: boolean;
|
|
27
|
+
order: string;
|
|
28
|
+
records: T[];
|
|
29
|
+
}
|
|
30
|
+
export interface ResourceEnvelope<T> {
|
|
31
|
+
total: number;
|
|
32
|
+
returned: number;
|
|
33
|
+
offset: 0;
|
|
34
|
+
limit: number;
|
|
35
|
+
truncated: boolean;
|
|
36
|
+
order: string;
|
|
37
|
+
continuation: {
|
|
38
|
+
tool: string;
|
|
39
|
+
nextOffset: number;
|
|
40
|
+
} | null;
|
|
41
|
+
records: T[];
|
|
42
|
+
}
|
|
43
|
+
/** Build a static-resource envelope over the fixed window (always offset 0). */
|
|
44
|
+
export declare function toResourceEnvelope<T>(collection: CollectionName, sorted: T[]): ResourceEnvelope<T>;
|
|
45
|
+
export interface ListFilesFilter {
|
|
46
|
+
language?: string;
|
|
47
|
+
kind?: FileRecord["kind"];
|
|
48
|
+
}
|
|
49
|
+
export declare function selectFiles(snapshot: CatalogueSnapshot, filter?: ListFilesFilter): FileRecord[];
|
|
50
|
+
export interface ListSymbolsFilter {
|
|
51
|
+
language?: string;
|
|
52
|
+
kind?: SymbolRecord["kind"];
|
|
53
|
+
packageId?: string;
|
|
54
|
+
}
|
|
55
|
+
export declare function selectSymbols(snapshot: CatalogueSnapshot, filter?: ListSymbolsFilter): SymbolRecord[];
|
|
56
|
+
export interface ListPackagesFilter {
|
|
57
|
+
ecosystem?: PackageRecord["ecosystem"];
|
|
58
|
+
}
|
|
59
|
+
export declare function selectPackages(snapshot: CatalogueSnapshot, filter?: ListPackagesFilter): PackageRecord[];
|
|
60
|
+
export interface ListCapabilitiesFilter {
|
|
61
|
+
stability?: CapabilityRecord["stability"];
|
|
62
|
+
}
|
|
63
|
+
export declare function selectCapabilities(snapshot: CatalogueSnapshot, filter?: ListCapabilitiesFilter): CapabilityRecord[];
|
|
64
|
+
export interface ListPublicApisFilter {
|
|
65
|
+
stability?: PublicApiRecord["stability"];
|
|
66
|
+
packageId?: string;
|
|
67
|
+
}
|
|
68
|
+
export declare function selectPublicApis(snapshot: CatalogueSnapshot, filter?: ListPublicApisFilter): PublicApiRecord[];
|
|
69
|
+
export interface ListExamplesFilter {
|
|
70
|
+
capabilityId?: string;
|
|
71
|
+
publicApiId?: string;
|
|
72
|
+
}
|
|
73
|
+
export declare function selectExamples(snapshot: CatalogueSnapshot, filter?: ListExamplesFilter): ExampleRecord[];
|
|
74
|
+
export interface ListRelationshipsFilter {
|
|
75
|
+
type?: RelationshipRecord["type"];
|
|
76
|
+
}
|
|
77
|
+
export declare function selectRelationships(snapshot: CatalogueSnapshot, filter?: ListRelationshipsFilter): RelationshipRecord[];
|
|
78
|
+
export interface ListDiagnosticsFilter {
|
|
79
|
+
severity?: DiagnosticRecord["severity"];
|
|
80
|
+
category?: DiagnosticRecord["category"];
|
|
81
|
+
}
|
|
82
|
+
export declare function selectDiagnostics(snapshot: CatalogueSnapshot, filter?: ListDiagnosticsFilter): DiagnosticRecord[];
|
|
83
|
+
export interface ListPaging {
|
|
84
|
+
offset?: number;
|
|
85
|
+
limit?: number;
|
|
86
|
+
}
|
|
87
|
+
export declare function listFilesPage(snapshot: CatalogueSnapshot, options?: ListFilesFilter & ListPaging): ListEnvelope<FileRecord>;
|
|
88
|
+
export declare function listSymbolsPage(snapshot: CatalogueSnapshot, options?: ListSymbolsFilter & ListPaging): ListEnvelope<SymbolRecord>;
|
|
89
|
+
export declare function listPackagesPage(snapshot: CatalogueSnapshot, options?: ListPackagesFilter & ListPaging): ListEnvelope<PackageRecord>;
|
|
90
|
+
export declare function listCapabilitiesPage(snapshot: CatalogueSnapshot, options?: ListCapabilitiesFilter & ListPaging): ListEnvelope<CapabilityRecord>;
|
|
91
|
+
export declare function listPublicApisPage(snapshot: CatalogueSnapshot, options?: ListPublicApisFilter & ListPaging): ListEnvelope<PublicApiRecord>;
|
|
92
|
+
export declare function listExamplesPage(snapshot: CatalogueSnapshot, options?: ListExamplesFilter & ListPaging): ListEnvelope<ExampleRecord>;
|
|
93
|
+
export declare function listRelationshipsPage(snapshot: CatalogueSnapshot, options?: ListRelationshipsFilter & ListPaging): ListEnvelope<RelationshipRecord>;
|
|
94
|
+
export declare function listDiagnosticsPage(snapshot: CatalogueSnapshot, options?: ListDiagnosticsFilter & ListPaging): ListEnvelope<DiagnosticRecord>;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { sortCapabilities, sortDiagnostics, sortExamples, sortFiles, sortPackages, sortPublicApis, sortRelationships, sortSymbols } from "../catalogue/ordering.js";
|
|
2
|
+
/** Tool default/maximum page sizes from resource-continuation.md. */
|
|
3
|
+
export const LIST_LIMITS = {
|
|
4
|
+
files: { default: 100, max: 1000 },
|
|
5
|
+
symbols: { default: 100, max: 1000 },
|
|
6
|
+
packages: { default: 50, max: 500 },
|
|
7
|
+
capabilities: { default: 50, max: 500 },
|
|
8
|
+
publicApis: { default: 100, max: 1000 },
|
|
9
|
+
examples: { default: 50, max: 500 },
|
|
10
|
+
relationships: { default: 100, max: 1000 },
|
|
11
|
+
diagnostics: { default: 50, max: 500 }
|
|
12
|
+
};
|
|
13
|
+
/** Fixed static-resource window sizes from resource-continuation.md. */
|
|
14
|
+
export const RESOURCE_WINDOWS = {
|
|
15
|
+
files: 250,
|
|
16
|
+
symbols: 250,
|
|
17
|
+
packages: 100,
|
|
18
|
+
capabilities: 100,
|
|
19
|
+
publicApis: 250,
|
|
20
|
+
examples: 100,
|
|
21
|
+
relationships: 250,
|
|
22
|
+
diagnostics: 100
|
|
23
|
+
};
|
|
24
|
+
/** Continuation tool per collection (Option A continuation). */
|
|
25
|
+
export const CONTINUATION_TOOLS = {
|
|
26
|
+
files: "list_files",
|
|
27
|
+
symbols: "list_symbols",
|
|
28
|
+
packages: "list_packages",
|
|
29
|
+
capabilities: "list_capabilities",
|
|
30
|
+
publicApis: "list_public_apis",
|
|
31
|
+
examples: "list_examples",
|
|
32
|
+
relationships: "list_relationships",
|
|
33
|
+
diagnostics: "list_diagnostics"
|
|
34
|
+
};
|
|
35
|
+
/** Human-readable order key descriptions from semantic-ordering.md. */
|
|
36
|
+
export const ORDER_DESCRIPTIONS = {
|
|
37
|
+
files: "package, file path, id",
|
|
38
|
+
symbols: "package, module path, qualified name, symbol kind, id",
|
|
39
|
+
packages: "ecosystem, package name, package root, id",
|
|
40
|
+
capabilities: "package, capability name, id",
|
|
41
|
+
publicApis: "package, canonical consumer import path, exported name, export kind, id",
|
|
42
|
+
examples: "package, example name or path, id",
|
|
43
|
+
relationships: "type, from id, to id, semantic discriminator, id",
|
|
44
|
+
diagnostics: "severity order, category, file path, diagnostic code, id"
|
|
45
|
+
};
|
|
46
|
+
function clampLimit(collection, requested) {
|
|
47
|
+
const limits = LIST_LIMITS[collection];
|
|
48
|
+
if (typeof requested !== "number" || !Number.isFinite(requested)) {
|
|
49
|
+
return limits.default;
|
|
50
|
+
}
|
|
51
|
+
const floored = Math.floor(requested);
|
|
52
|
+
if (floored <= 0) {
|
|
53
|
+
return limits.default;
|
|
54
|
+
}
|
|
55
|
+
return Math.min(floored, limits.max);
|
|
56
|
+
}
|
|
57
|
+
function clampOffset(offset) {
|
|
58
|
+
if (typeof offset !== "number" || !Number.isFinite(offset)) {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
return Math.max(0, Math.floor(offset));
|
|
62
|
+
}
|
|
63
|
+
function toListEnvelope(collection, sorted, offset, limit) {
|
|
64
|
+
const safeOffset = clampOffset(offset);
|
|
65
|
+
const safeLimit = clampLimit(collection, limit);
|
|
66
|
+
const records = sorted.slice(safeOffset, safeOffset + safeLimit);
|
|
67
|
+
return {
|
|
68
|
+
total: sorted.length,
|
|
69
|
+
returned: records.length,
|
|
70
|
+
offset: safeOffset,
|
|
71
|
+
limit: safeLimit,
|
|
72
|
+
truncated: safeOffset + records.length < sorted.length,
|
|
73
|
+
order: ORDER_DESCRIPTIONS[collection],
|
|
74
|
+
records
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Build a static-resource envelope over the fixed window (always offset 0). */
|
|
78
|
+
export function toResourceEnvelope(collection, sorted) {
|
|
79
|
+
const window = RESOURCE_WINDOWS[collection];
|
|
80
|
+
const records = sorted.slice(0, window);
|
|
81
|
+
const truncated = records.length < sorted.length;
|
|
82
|
+
return {
|
|
83
|
+
total: sorted.length,
|
|
84
|
+
returned: records.length,
|
|
85
|
+
offset: 0,
|
|
86
|
+
limit: window,
|
|
87
|
+
truncated,
|
|
88
|
+
order: ORDER_DESCRIPTIONS[collection],
|
|
89
|
+
continuation: truncated ? { tool: CONTINUATION_TOOLS[collection], nextOffset: records.length } : null,
|
|
90
|
+
records
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function selectFiles(snapshot, filter = {}) {
|
|
94
|
+
return sortFiles(snapshot.files.filter((file) => {
|
|
95
|
+
if (filter.language && file.language !== filter.language)
|
|
96
|
+
return false;
|
|
97
|
+
if (filter.kind && file.kind !== filter.kind)
|
|
98
|
+
return false;
|
|
99
|
+
return true;
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
export function selectSymbols(snapshot, filter = {}) {
|
|
103
|
+
return sortSymbols(snapshot.symbols.filter((symbol) => {
|
|
104
|
+
if (filter.language && symbol.language !== filter.language)
|
|
105
|
+
return false;
|
|
106
|
+
if (filter.kind && symbol.kind !== filter.kind)
|
|
107
|
+
return false;
|
|
108
|
+
if (filter.packageId && symbol.packageId !== filter.packageId)
|
|
109
|
+
return false;
|
|
110
|
+
return true;
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
export function selectPackages(snapshot, filter = {}) {
|
|
114
|
+
return sortPackages(snapshot.packages.filter((pkg) => {
|
|
115
|
+
if (filter.ecosystem && (pkg.ecosystem ?? "unknown") !== filter.ecosystem)
|
|
116
|
+
return false;
|
|
117
|
+
return true;
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
export function selectCapabilities(snapshot, filter = {}) {
|
|
121
|
+
return sortCapabilities(snapshot.capabilities.filter((capability) => {
|
|
122
|
+
if (filter.stability && capability.stability !== filter.stability)
|
|
123
|
+
return false;
|
|
124
|
+
return true;
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
export function selectPublicApis(snapshot, filter = {}) {
|
|
128
|
+
return sortPublicApis(snapshot.publicApis.filter((api) => {
|
|
129
|
+
if (filter.stability && api.stability !== filter.stability)
|
|
130
|
+
return false;
|
|
131
|
+
if (filter.packageId && api.packageId !== filter.packageId)
|
|
132
|
+
return false;
|
|
133
|
+
return true;
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
export function selectExamples(snapshot, filter = {}) {
|
|
137
|
+
return sortExamples(snapshot.examples.filter((example) => {
|
|
138
|
+
if (filter.capabilityId && !example.capabilityIds.includes(filter.capabilityId))
|
|
139
|
+
return false;
|
|
140
|
+
if (filter.publicApiId && !example.publicApiIds.includes(filter.publicApiId))
|
|
141
|
+
return false;
|
|
142
|
+
return true;
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
export function selectRelationships(snapshot, filter = {}) {
|
|
146
|
+
return sortRelationships(snapshot.relationships.filter((relationship) => {
|
|
147
|
+
if (filter.type && relationship.type !== filter.type)
|
|
148
|
+
return false;
|
|
149
|
+
return true;
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
export function selectDiagnostics(snapshot, filter = {}) {
|
|
153
|
+
return sortDiagnostics(snapshot.diagnostics.filter((diagnostic) => {
|
|
154
|
+
if (filter.severity && diagnostic.severity !== filter.severity)
|
|
155
|
+
return false;
|
|
156
|
+
if (filter.category && diagnostic.category !== filter.category)
|
|
157
|
+
return false;
|
|
158
|
+
return true;
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
export function listFilesPage(snapshot, options = {}) {
|
|
162
|
+
return toListEnvelope("files", selectFiles(snapshot, options), options.offset, options.limit);
|
|
163
|
+
}
|
|
164
|
+
export function listSymbolsPage(snapshot, options = {}) {
|
|
165
|
+
return toListEnvelope("symbols", selectSymbols(snapshot, options), options.offset, options.limit);
|
|
166
|
+
}
|
|
167
|
+
export function listPackagesPage(snapshot, options = {}) {
|
|
168
|
+
return toListEnvelope("packages", selectPackages(snapshot, options), options.offset, options.limit);
|
|
169
|
+
}
|
|
170
|
+
export function listCapabilitiesPage(snapshot, options = {}) {
|
|
171
|
+
return toListEnvelope("capabilities", selectCapabilities(snapshot, options), options.offset, options.limit);
|
|
172
|
+
}
|
|
173
|
+
export function listPublicApisPage(snapshot, options = {}) {
|
|
174
|
+
return toListEnvelope("publicApis", selectPublicApis(snapshot, options), options.offset, options.limit);
|
|
175
|
+
}
|
|
176
|
+
export function listExamplesPage(snapshot, options = {}) {
|
|
177
|
+
return toListEnvelope("examples", selectExamples(snapshot, options), options.offset, options.limit);
|
|
178
|
+
}
|
|
179
|
+
export function listRelationshipsPage(snapshot, options = {}) {
|
|
180
|
+
return toListEnvelope("relationships", selectRelationships(snapshot, options), options.offset, options.limit);
|
|
181
|
+
}
|
|
182
|
+
export function listDiagnosticsPage(snapshot, options = {}) {
|
|
183
|
+
return toListEnvelope("diagnostics", selectDiagnostics(snapshot, options), options.offset, options.limit);
|
|
184
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function getWorkspaceOverview(snapshot) {
|
|
2
|
+
return {
|
|
3
|
+
catalogueId: snapshot.catalogueId,
|
|
4
|
+
stats: snapshot.stats,
|
|
5
|
+
packages: snapshot.packages.map((pkg) => ({ id: pkg.id, name: pkg.name, capabilityCount: pkg.capabilities.length })),
|
|
6
|
+
capabilities: snapshot.capabilities.map((cap) => ({ id: cap.id, name: cap.name, stability: cap.stability }))
|
|
7
|
+
};
|
|
8
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { CapabilityRecord, CatalogueSnapshot, DiagnosticRecord, ExampleRecord, PackageRecord, PublicApiRecord, SymbolRecord, TestRecord } from "../catalogue/schema.js";
|
|
2
|
+
import { type RankedEnvelope } from "./ranking.js";
|
|
3
|
+
import { type EditingContext } from "./editingContext.js";
|
|
4
|
+
export interface SearchPublicApisOptions {
|
|
5
|
+
query: string;
|
|
6
|
+
stability?: PublicApiRecord["stability"];
|
|
7
|
+
packageId?: string;
|
|
8
|
+
language?: string;
|
|
9
|
+
capabilityId?: string;
|
|
10
|
+
hasExamples?: boolean;
|
|
11
|
+
hasTests?: boolean;
|
|
12
|
+
limit?: number;
|
|
13
|
+
offset?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PublicApiCompact {
|
|
16
|
+
id: string;
|
|
17
|
+
symbolId: string;
|
|
18
|
+
name: string;
|
|
19
|
+
importPath?: string;
|
|
20
|
+
exportKind?: PublicApiRecord["exportKind"];
|
|
21
|
+
packageId?: string;
|
|
22
|
+
stability: PublicApiRecord["stability"];
|
|
23
|
+
}
|
|
24
|
+
export declare function toPublicApiCompact(api: PublicApiRecord): PublicApiCompact;
|
|
25
|
+
export declare function searchPublicApis(snapshot: CatalogueSnapshot, options: SearchPublicApisOptions): RankedEnvelope<PublicApiCompact>;
|
|
26
|
+
export interface PublicApiContextResult {
|
|
27
|
+
publicApi: PublicApiRecord;
|
|
28
|
+
symbol?: SymbolRecord;
|
|
29
|
+
capabilities: CapabilityRecord[];
|
|
30
|
+
owningPackage?: PackageRecord;
|
|
31
|
+
examples: ExampleRecord[];
|
|
32
|
+
tests: TestRecord[];
|
|
33
|
+
contracts: string[];
|
|
34
|
+
limitations: string[];
|
|
35
|
+
importPath?: string;
|
|
36
|
+
diagnostics: DiagnosticRecord[];
|
|
37
|
+
truncated: {
|
|
38
|
+
capabilities: boolean;
|
|
39
|
+
capabilitiesTotal: number;
|
|
40
|
+
examples: boolean;
|
|
41
|
+
examplesTotal: number;
|
|
42
|
+
tests: boolean;
|
|
43
|
+
testsTotal: number;
|
|
44
|
+
diagnostics: boolean;
|
|
45
|
+
diagnosticsTotal: number;
|
|
46
|
+
};
|
|
47
|
+
/** Bounded, advisory editing context; present only when opted in. */
|
|
48
|
+
editingContext?: EditingContext;
|
|
49
|
+
}
|
|
50
|
+
export interface PublicApiContextOptions {
|
|
51
|
+
maxCapabilities?: number;
|
|
52
|
+
maxExamples?: number;
|
|
53
|
+
maxTests?: number;
|
|
54
|
+
maxDiagnostics?: number;
|
|
55
|
+
/** Opt-in bounded editing context (Gate 4). Default false. */
|
|
56
|
+
includeEditingContext?: boolean;
|
|
57
|
+
/** Per-section budget for editing context when included. */
|
|
58
|
+
editingContextLimit?: number;
|
|
59
|
+
}
|
|
60
|
+
export declare function getPublicApiContext(snapshot: CatalogueSnapshot, publicApiId: string, options?: PublicApiContextOptions): PublicApiContextResult | undefined;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { buildRankedEnvelope, rankPublicApis } from "./ranking.js";
|
|
2
|
+
import { buildEditingContext } from "./editingContext.js";
|
|
3
|
+
export function toPublicApiCompact(api) {
|
|
4
|
+
return {
|
|
5
|
+
id: api.id,
|
|
6
|
+
symbolId: api.symbolId,
|
|
7
|
+
name: api.name,
|
|
8
|
+
importPath: api.importPath,
|
|
9
|
+
exportKind: api.exportKind,
|
|
10
|
+
packageId: api.packageId,
|
|
11
|
+
stability: api.stability
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function searchPublicApis(snapshot, options) {
|
|
15
|
+
const filters = {
|
|
16
|
+
stability: options.stability,
|
|
17
|
+
packageId: options.packageId,
|
|
18
|
+
language: options.language,
|
|
19
|
+
capabilityId: options.capabilityId,
|
|
20
|
+
hasExamples: options.hasExamples,
|
|
21
|
+
hasTests: options.hasTests
|
|
22
|
+
};
|
|
23
|
+
const ranked = rankPublicApis(options.query, snapshot.publicApis, filters, snapshot);
|
|
24
|
+
return buildRankedEnvelope(options.query, ranked, toPublicApiCompact, filters, {
|
|
25
|
+
offset: options.offset,
|
|
26
|
+
limit: options.limit
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const DEFAULT_PUBLIC_API_CONTEXT_LIMITS = {
|
|
30
|
+
maxCapabilities: 100,
|
|
31
|
+
maxExamples: 100,
|
|
32
|
+
maxTests: 100,
|
|
33
|
+
maxDiagnostics: 200
|
|
34
|
+
};
|
|
35
|
+
export function getPublicApiContext(snapshot, publicApiId, options = {}) {
|
|
36
|
+
const limits = {
|
|
37
|
+
maxCapabilities: normalizeLimit(options.maxCapabilities, DEFAULT_PUBLIC_API_CONTEXT_LIMITS.maxCapabilities),
|
|
38
|
+
maxExamples: normalizeLimit(options.maxExamples, DEFAULT_PUBLIC_API_CONTEXT_LIMITS.maxExamples),
|
|
39
|
+
maxTests: normalizeLimit(options.maxTests, DEFAULT_PUBLIC_API_CONTEXT_LIMITS.maxTests),
|
|
40
|
+
maxDiagnostics: normalizeLimit(options.maxDiagnostics, DEFAULT_PUBLIC_API_CONTEXT_LIMITS.maxDiagnostics)
|
|
41
|
+
};
|
|
42
|
+
const publicApi = snapshot.publicApis.find((api) => api.id === publicApiId);
|
|
43
|
+
if (!publicApi) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const symbol = snapshot.symbols.find((item) => item.id === publicApi.symbolId);
|
|
47
|
+
const allCapabilities = snapshot.capabilities.filter((capability) => publicApi.capabilityIds.includes(capability.id)).sort((a, b) => a.id.localeCompare(b.id));
|
|
48
|
+
const capabilities = allCapabilities.slice(0, limits.maxCapabilities);
|
|
49
|
+
const allExamples = snapshot.examples.filter((example) => example.publicApiIds.includes(publicApi.id)).sort((a, b) => a.id.localeCompare(b.id));
|
|
50
|
+
const examples = allExamples.slice(0, limits.maxExamples);
|
|
51
|
+
const allTests = snapshot.tests
|
|
52
|
+
.filter((test) => publicApi.tests.includes(test.filePath)
|
|
53
|
+
|| publicApi.tests.includes(test.id)
|
|
54
|
+
|| test.coversPublicApis.includes(publicApi.id)
|
|
55
|
+
|| (symbol ? test.coversSymbols.includes(symbol.id) : false))
|
|
56
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
57
|
+
const tests = allTests.slice(0, limits.maxTests);
|
|
58
|
+
const owningPackage = symbol ? findOwningPackage(snapshot, symbol.filePath) : undefined;
|
|
59
|
+
const allDiagnostics = snapshot.diagnostics
|
|
60
|
+
.filter((diagnostic) => {
|
|
61
|
+
if (diagnostic.target?.kind === "publicApi" && diagnostic.target.id === publicApi.id) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (symbol && diagnostic.target?.kind === "symbol" && diagnostic.target.id === symbol.id) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (symbol?.filePath && diagnostic.filePath === symbol.filePath) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
})
|
|
72
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
73
|
+
const diagnostics = allDiagnostics.slice(0, limits.maxDiagnostics);
|
|
74
|
+
const editingContext = options.includeEditingContext
|
|
75
|
+
? buildEditingContext(snapshot, { publicApi, symbol }, { perSectionLimit: options.editingContextLimit })
|
|
76
|
+
: undefined;
|
|
77
|
+
return {
|
|
78
|
+
publicApi,
|
|
79
|
+
symbol,
|
|
80
|
+
capabilities,
|
|
81
|
+
owningPackage,
|
|
82
|
+
examples,
|
|
83
|
+
tests,
|
|
84
|
+
contracts: [...new Set([...publicApi.contracts, ...capabilities.flatMap((capability) => capability.contracts)])].sort(),
|
|
85
|
+
limitations: [...new Set(capabilities.flatMap((capability) => capability.limitations))].sort(),
|
|
86
|
+
importPath: publicApi.importPath,
|
|
87
|
+
diagnostics,
|
|
88
|
+
editingContext,
|
|
89
|
+
truncated: {
|
|
90
|
+
capabilities: capabilities.length < allCapabilities.length,
|
|
91
|
+
capabilitiesTotal: allCapabilities.length,
|
|
92
|
+
examples: examples.length < allExamples.length,
|
|
93
|
+
examplesTotal: allExamples.length,
|
|
94
|
+
tests: tests.length < allTests.length,
|
|
95
|
+
testsTotal: allTests.length,
|
|
96
|
+
diagnostics: diagnostics.length < allDiagnostics.length,
|
|
97
|
+
diagnosticsTotal: allDiagnostics.length
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function findOwningPackage(snapshot, filePath) {
|
|
102
|
+
const candidates = snapshot.packages.filter((pkg) => {
|
|
103
|
+
if (pkg.path === ".") {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return filePath === pkg.path || filePath.startsWith(`${pkg.path}/`);
|
|
107
|
+
});
|
|
108
|
+
candidates.sort((a, b) => b.path.length - a.path.length || a.id.localeCompare(b.id));
|
|
109
|
+
return candidates[0];
|
|
110
|
+
}
|
|
111
|
+
function normalizeLimit(value, fallback) {
|
|
112
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
113
|
+
return fallback;
|
|
114
|
+
}
|
|
115
|
+
const normalized = Math.floor(value);
|
|
116
|
+
if (normalized <= 0) {
|
|
117
|
+
return fallback;
|
|
118
|
+
}
|
|
119
|
+
return normalized;
|
|
120
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic retrieval ranking for public API and symbol searches (Gate 2).
|
|
3
|
+
*
|
|
4
|
+
* Hard filters are applied as eligibility conditions *before* ranking. Ranking
|
|
5
|
+
* then operates only within the eligible set and produces a closed, versioned
|
|
6
|
+
* set of `MatchReason` values per result. Reasons are emitted in a fixed
|
|
7
|
+
* canonical order and never include unregistered strings.
|
|
8
|
+
*/
|
|
9
|
+
import type { CatalogueSnapshot, PublicApiRecord, SymbolKind, SymbolRecord } from "../catalogue/schema.js";
|
|
10
|
+
/** Version of the ranking + match-reason contract exposed to MCP callers. */
|
|
11
|
+
export declare const RANKING_CONTRACT_VERSION = "1";
|
|
12
|
+
/**
|
|
13
|
+
* Closed vocabulary of match reasons. Order here is also the canonical
|
|
14
|
+
* emission order for a single result's `matchReasons`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MATCH_REASONS: readonly ["exact_exported_name", "exact_declared_name", "exact_qualified_name", "exact_import_path", "case_insensitive_exact", "whole_token", "prefix", "substring", "public_export", "package_root_export", "subpath_export", "canonical_source", "explicit_documentation", "explicit_public_api", "has_explicit_example", "has_explicit_test", "has_direct_usage"];
|
|
17
|
+
export type MatchReason = (typeof MATCH_REASONS)[number];
|
|
18
|
+
export interface RankingFilters {
|
|
19
|
+
packageId?: string;
|
|
20
|
+
language?: string;
|
|
21
|
+
kind?: SymbolKind;
|
|
22
|
+
publicOnly?: boolean;
|
|
23
|
+
capabilityId?: string;
|
|
24
|
+
hasExamples?: boolean;
|
|
25
|
+
hasTests?: boolean;
|
|
26
|
+
stability?: PublicApiRecord["stability"];
|
|
27
|
+
}
|
|
28
|
+
export interface RankedResult<T> {
|
|
29
|
+
record: T;
|
|
30
|
+
matchReasons: MatchReason[];
|
|
31
|
+
}
|
|
32
|
+
export interface RankedEnvelope<C> {
|
|
33
|
+
total: number;
|
|
34
|
+
returned: number;
|
|
35
|
+
offset: number;
|
|
36
|
+
limit: number;
|
|
37
|
+
truncated: boolean;
|
|
38
|
+
rankingContractVersion: string;
|
|
39
|
+
filtersApplied: Record<string, unknown>;
|
|
40
|
+
normalizedQuery: string;
|
|
41
|
+
records: Array<C & {
|
|
42
|
+
matchReasons: MatchReason[];
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
/** NFC-normalize and trim a raw query. */
|
|
46
|
+
export declare function normalizeQuery(query: string): string;
|
|
47
|
+
/** Lowercase alphanumeric tokens, splitting on separators and camelCase boundaries. */
|
|
48
|
+
export declare function tokenize(value: string): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Public helper: compute the ordered string-oriented match reasons for a
|
|
51
|
+
* candidate name against a raw query. Used by lighter-weight rankers (e.g.
|
|
52
|
+
* reuse candidates) that want explanatory reasons without full scoring.
|
|
53
|
+
*/
|
|
54
|
+
export declare function nameMatchReasons(candidate: string, query: string, exactReason?: "exact_exported_name" | "exact_declared_name"): MatchReason[];
|
|
55
|
+
export declare function rankPublicApis(query: string, records: PublicApiRecord[], filters: RankingFilters, snapshot: CatalogueSnapshot): RankedResult<PublicApiRecord>[];
|
|
56
|
+
export declare function rankSymbols(query: string, records: SymbolRecord[], filters: RankingFilters, snapshot: CatalogueSnapshot): RankedResult<SymbolRecord>[];
|
|
57
|
+
/** Generic pagination + compaction helper for ranked results. */
|
|
58
|
+
export declare function paginateRanked<T, C>(ranked: RankedResult<T>[], toCompact: (record: T) => C, params: {
|
|
59
|
+
offset?: number;
|
|
60
|
+
limit?: number;
|
|
61
|
+
normalizedQuery: string;
|
|
62
|
+
filtersApplied: Record<string, unknown>;
|
|
63
|
+
}): RankedEnvelope<C>;
|
|
64
|
+
export declare function buildRankedEnvelope<T, C>(query: string, ranked: RankedResult<T>[], toCompact: (record: T) => C, filters: RankingFilters, paging: {
|
|
65
|
+
offset?: number;
|
|
66
|
+
limit?: number;
|
|
67
|
+
}): RankedEnvelope<C>;
|