@fragments-sdk/context 0.2.0 → 0.3.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.
@@ -0,0 +1,388 @@
1
+ // src/graph/types.ts
2
+ var GRAPH_EDGE_TYPES = [
3
+ "imports",
4
+ "hook-depends",
5
+ "renders",
6
+ "composes",
7
+ "parent-of",
8
+ "alternative-to",
9
+ "sibling-of"
10
+ ];
11
+ var EDGE_TYPE_WEIGHTS = {
12
+ "imports": 1,
13
+ "hook-depends": 0.75,
14
+ "renders": 0.5,
15
+ "composes": 0.5,
16
+ "parent-of": 1,
17
+ "alternative-to": 1,
18
+ "sibling-of": 0.75
19
+ };
20
+
21
+ // src/graph/engine.ts
22
+ var ComponentGraphEngine = class {
23
+ nodes;
24
+ outgoing;
25
+ incoming;
26
+ edges;
27
+ blockIndex;
28
+ health;
29
+ constructor(graph, blocks) {
30
+ this.nodes = /* @__PURE__ */ new Map();
31
+ this.outgoing = /* @__PURE__ */ new Map();
32
+ this.incoming = /* @__PURE__ */ new Map();
33
+ this.edges = graph.edges;
34
+ this.health = graph.health;
35
+ this.blockIndex = /* @__PURE__ */ new Map();
36
+ for (const node of graph.nodes) {
37
+ this.nodes.set(node.name, node);
38
+ this.outgoing.set(node.name, []);
39
+ this.incoming.set(node.name, []);
40
+ }
41
+ for (const edge of graph.edges) {
42
+ const out = this.outgoing.get(edge.source);
43
+ if (out) out.push(edge);
44
+ else this.outgoing.set(edge.source, [edge]);
45
+ const inc = this.incoming.get(edge.target);
46
+ if (inc) inc.push(edge);
47
+ else this.incoming.set(edge.target, [edge]);
48
+ }
49
+ if (blocks) {
50
+ for (const [blockName, block] of Object.entries(blocks)) {
51
+ for (const comp of block.components) {
52
+ const existing = this.blockIndex.get(comp);
53
+ if (existing) existing.push(blockName);
54
+ else this.blockIndex.set(comp, [blockName]);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ // -------------------------------------------------------------------------
60
+ // Core queries
61
+ // -------------------------------------------------------------------------
62
+ /** Get outgoing edges from a component, optionally filtered by edge type */
63
+ dependencies(component, edgeTypes) {
64
+ const edges = this.outgoing.get(component) ?? [];
65
+ if (!edgeTypes || edgeTypes.length === 0) return edges;
66
+ return edges.filter((e) => edgeTypes.includes(e.type));
67
+ }
68
+ /** Get incoming edges to a component, optionally filtered by edge type */
69
+ dependents(component, edgeTypes) {
70
+ const edges = this.incoming.get(component) ?? [];
71
+ if (!edgeTypes || edgeTypes.length === 0) return edges;
72
+ return edges.filter((e) => edgeTypes.includes(e.type));
73
+ }
74
+ /** BFS transitive closure — what's affected if this component changes */
75
+ impact(component, maxDepth = 3) {
76
+ const affected = [];
77
+ const visited = /* @__PURE__ */ new Set([component]);
78
+ const queue = [
79
+ { name: component, depth: 0, path: [component] }
80
+ ];
81
+ while (queue.length > 0) {
82
+ const current = queue.shift();
83
+ if (current.depth >= maxDepth) continue;
84
+ const deps = this.incoming.get(current.name) ?? [];
85
+ for (const edge of deps) {
86
+ if (visited.has(edge.source)) continue;
87
+ visited.add(edge.source);
88
+ const newPath = [...current.path, edge.source];
89
+ affected.push({
90
+ component: edge.source,
91
+ depth: current.depth + 1,
92
+ path: newPath,
93
+ edgeType: edge.type
94
+ });
95
+ queue.push({ name: edge.source, depth: current.depth + 1, path: newPath });
96
+ }
97
+ }
98
+ const affectedComponents = /* @__PURE__ */ new Set([component, ...affected.map((a) => a.component)]);
99
+ const affectedBlocks = /* @__PURE__ */ new Set();
100
+ for (const comp of affectedComponents) {
101
+ const blocks = this.blockIndex.get(comp);
102
+ if (blocks) {
103
+ for (const b of blocks) affectedBlocks.add(b);
104
+ }
105
+ }
106
+ return {
107
+ component,
108
+ affected,
109
+ affectedBlocks: [...affectedBlocks],
110
+ totalAffected: affected.length
111
+ };
112
+ }
113
+ /** BFS shortest path between two components (undirected) */
114
+ path(from, to) {
115
+ if (from === to) {
116
+ return { found: true, path: [from], edges: [] };
117
+ }
118
+ const visited = /* @__PURE__ */ new Set([from]);
119
+ const queue = [
120
+ { name: from, path: [from], edges: [] }
121
+ ];
122
+ while (queue.length > 0) {
123
+ const current = queue.shift();
124
+ const allEdges = [
125
+ ...this.outgoing.get(current.name) ?? [],
126
+ ...this.incoming.get(current.name) ?? []
127
+ ];
128
+ for (const edge of allEdges) {
129
+ const neighbor = edge.source === current.name ? edge.target : edge.source;
130
+ if (visited.has(neighbor)) continue;
131
+ visited.add(neighbor);
132
+ const newPath = [...current.path, neighbor];
133
+ const newEdges = [...current.edges, edge];
134
+ if (neighbor === to) {
135
+ return { found: true, path: newPath, edges: newEdges };
136
+ }
137
+ queue.push({ name: neighbor, path: newPath, edges: newEdges });
138
+ }
139
+ }
140
+ return { found: false, path: [], edges: [] };
141
+ }
142
+ /** Connected components via BFS on undirected projection */
143
+ islands() {
144
+ const visited = /* @__PURE__ */ new Set();
145
+ const components = [];
146
+ for (const nodeName of this.nodes.keys()) {
147
+ if (visited.has(nodeName)) continue;
148
+ const island = [];
149
+ const queue = [nodeName];
150
+ visited.add(nodeName);
151
+ while (queue.length > 0) {
152
+ const current = queue.shift();
153
+ island.push(current);
154
+ const allEdges = [
155
+ ...this.outgoing.get(current) ?? [],
156
+ ...this.incoming.get(current) ?? []
157
+ ];
158
+ for (const edge of allEdges) {
159
+ const neighbor = edge.source === current ? edge.target : edge.source;
160
+ if (!visited.has(neighbor) && this.nodes.has(neighbor)) {
161
+ visited.add(neighbor);
162
+ queue.push(neighbor);
163
+ }
164
+ }
165
+ }
166
+ components.push(island.sort());
167
+ }
168
+ return components.sort((a, b) => b.length - a.length);
169
+ }
170
+ /** All components reachable within N hops (undirected) */
171
+ neighbors(component, maxHops = 1) {
172
+ const neighbors = [];
173
+ const visited = /* @__PURE__ */ new Set([component]);
174
+ const queue = [
175
+ { name: component, hops: 0 }
176
+ ];
177
+ while (queue.length > 0) {
178
+ const current = queue.shift();
179
+ if (current.hops >= maxHops) continue;
180
+ const allEdges = [
181
+ ...this.outgoing.get(current.name) ?? [],
182
+ ...this.incoming.get(current.name) ?? []
183
+ ];
184
+ for (const edge of allEdges) {
185
+ const neighbor = edge.source === current.name ? edge.target : edge.source;
186
+ if (visited.has(neighbor)) continue;
187
+ visited.add(neighbor);
188
+ neighbors.push({
189
+ component: neighbor,
190
+ hops: current.hops + 1,
191
+ edgeType: edge.type
192
+ });
193
+ queue.push({ name: neighbor, hops: current.hops + 1 });
194
+ }
195
+ }
196
+ return { component, neighbors };
197
+ }
198
+ // -------------------------------------------------------------------------
199
+ // Design-system queries
200
+ // -------------------------------------------------------------------------
201
+ /** Get the composition tree for a compound component */
202
+ composition(component) {
203
+ const node = this.nodes.get(component);
204
+ const subComponents = node?.subComponents ?? [];
205
+ const parentEdges = (this.outgoing.get(component) ?? []).filter((e) => e.type === "parent-of");
206
+ const requiredChildren = parentEdges.map((e) => e.target);
207
+ const childEdges = (this.incoming.get(component) ?? []).filter((e) => e.type === "parent-of");
208
+ const parent = childEdges.length > 0 ? childEdges[0].source : void 0;
209
+ const siblings = [];
210
+ if (parent) {
211
+ const parentOut = (this.outgoing.get(parent) ?? []).filter((e) => e.type === "parent-of");
212
+ for (const edge of parentOut) {
213
+ if (edge.target !== component) {
214
+ siblings.push(edge.target);
215
+ }
216
+ }
217
+ }
218
+ const siblingEdges = [
219
+ ...(this.outgoing.get(component) ?? []).filter((e) => e.type === "sibling-of"),
220
+ ...(this.incoming.get(component) ?? []).filter((e) => e.type === "sibling-of")
221
+ ];
222
+ for (const edge of siblingEdges) {
223
+ const sib = edge.source === component ? edge.target : edge.source;
224
+ if (!siblings.includes(sib)) siblings.push(sib);
225
+ }
226
+ return {
227
+ component,
228
+ compositionPattern: node?.compositionPattern,
229
+ subComponents,
230
+ requiredChildren,
231
+ parent,
232
+ siblings,
233
+ blocks: this.blockIndex.get(component) ?? []
234
+ };
235
+ }
236
+ /** Get alternative components */
237
+ alternatives(component) {
238
+ const alts = [];
239
+ for (const edge of this.outgoing.get(component) ?? []) {
240
+ if (edge.type === "alternative-to") {
241
+ alts.push({ component: edge.target, note: edge.note });
242
+ }
243
+ }
244
+ for (const edge of this.incoming.get(component) ?? []) {
245
+ if (edge.type === "alternative-to") {
246
+ alts.push({ component: edge.source, note: edge.note });
247
+ }
248
+ }
249
+ return alts;
250
+ }
251
+ /** Get blocks that use a component */
252
+ blocksUsing(component) {
253
+ return this.blockIndex.get(component) ?? [];
254
+ }
255
+ /** Extract an induced subgraph for a set of components */
256
+ subgraph(components) {
257
+ const componentSet = new Set(components);
258
+ const nodes = components.map((name) => this.nodes.get(name)).filter((n) => n !== void 0);
259
+ const edges = this.edges.filter(
260
+ (e) => componentSet.has(e.source) && componentSet.has(e.target)
261
+ );
262
+ return {
263
+ nodes,
264
+ edges,
265
+ health: computeHealthFromData(nodes, edges, this.blockIndex)
266
+ };
267
+ }
268
+ /** Return precomputed health metrics */
269
+ getHealth() {
270
+ return this.health;
271
+ }
272
+ /** Get a single node by name */
273
+ getNode(name) {
274
+ return this.nodes.get(name);
275
+ }
276
+ /** Check if a component exists in the graph */
277
+ hasNode(name) {
278
+ return this.nodes.has(name);
279
+ }
280
+ };
281
+ function computeHealthFromData(nodes, edges, blockIndex) {
282
+ const nodeNames = new Set(nodes.map((n) => n.name));
283
+ const degreeMap = /* @__PURE__ */ new Map();
284
+ for (const name of nodeNames) {
285
+ degreeMap.set(name, 0);
286
+ }
287
+ for (const edge of edges) {
288
+ degreeMap.set(edge.source, (degreeMap.get(edge.source) ?? 0) + 1);
289
+ degreeMap.set(edge.target, (degreeMap.get(edge.target) ?? 0) + 1);
290
+ }
291
+ const orphans = [];
292
+ for (const [name, degree] of degreeMap) {
293
+ if (degree === 0) orphans.push(name);
294
+ }
295
+ const hubs = [...degreeMap.entries()].map(([name, degree]) => ({ name, degree })).sort((a, b) => b.degree - a.degree).slice(0, 10);
296
+ let inBlock = 0;
297
+ if (blockIndex) {
298
+ for (const name of nodeNames) {
299
+ if ((blockIndex.get(name) ?? []).length > 0) inBlock++;
300
+ }
301
+ }
302
+ const compositionCoverage = nodeNames.size > 0 ? Math.round(inBlock / nodeNames.size * 100) : 0;
303
+ const adjacency = /* @__PURE__ */ new Map();
304
+ for (const name of nodeNames) {
305
+ adjacency.set(name, /* @__PURE__ */ new Set());
306
+ }
307
+ for (const edge of edges) {
308
+ adjacency.get(edge.source)?.add(edge.target);
309
+ adjacency.get(edge.target)?.add(edge.source);
310
+ }
311
+ const visited = /* @__PURE__ */ new Set();
312
+ const connectedComponents = [];
313
+ for (const name of nodeNames) {
314
+ if (visited.has(name)) continue;
315
+ const island = [];
316
+ const queue = [name];
317
+ visited.add(name);
318
+ while (queue.length > 0) {
319
+ const current = queue.shift();
320
+ island.push(current);
321
+ for (const neighbor of adjacency.get(current) ?? []) {
322
+ if (!visited.has(neighbor)) {
323
+ visited.add(neighbor);
324
+ queue.push(neighbor);
325
+ }
326
+ }
327
+ }
328
+ connectedComponents.push(island.sort());
329
+ }
330
+ connectedComponents.sort((a, b) => b.length - a.length);
331
+ const totalDegree = [...degreeMap.values()].reduce((sum, d) => sum + d, 0);
332
+ const averageDegree = nodeNames.size > 0 ? Math.round(totalDegree / nodeNames.size * 100) / 100 : 0;
333
+ return {
334
+ orphans: orphans.sort(),
335
+ hubs,
336
+ compositionCoverage,
337
+ connectedComponents,
338
+ averageDegree,
339
+ nodeCount: nodeNames.size,
340
+ edgeCount: edges.length
341
+ };
342
+ }
343
+
344
+ // src/graph/serialization.ts
345
+ function serializeGraph(graph) {
346
+ return {
347
+ nodes: graph.nodes,
348
+ edges: graph.edges.map(serializeEdge),
349
+ health: graph.health
350
+ };
351
+ }
352
+ function deserializeGraph(serialized) {
353
+ return {
354
+ nodes: serialized.nodes,
355
+ edges: serialized.edges.map(deserializeEdge),
356
+ health: serialized.health
357
+ };
358
+ }
359
+ function serializeEdge(edge) {
360
+ const result = {
361
+ s: edge.source,
362
+ t: edge.target,
363
+ ty: edge.type,
364
+ w: edge.weight,
365
+ p: edge.provenance
366
+ };
367
+ if (edge.note) result.no = edge.note;
368
+ return result;
369
+ }
370
+ function deserializeEdge(edge) {
371
+ const result = {
372
+ source: edge.s,
373
+ target: edge.t,
374
+ type: edge.ty,
375
+ weight: edge.w,
376
+ provenance: edge.p
377
+ };
378
+ if (edge.no) result.note = edge.no;
379
+ return result;
380
+ }
381
+ export {
382
+ ComponentGraphEngine,
383
+ EDGE_TYPE_WEIGHTS,
384
+ GRAPH_EDGE_TYPES,
385
+ computeHealthFromData,
386
+ deserializeGraph,
387
+ serializeGraph
388
+ };
package/dist/index.d.ts CHANGED
@@ -6,3 +6,6 @@ export { deduplicateChunks, reciprocalRankFusion } from './search/index.js';
6
6
  export { F as FusedResult, R as RankedResult, a as ScoredChunk, S as SearchResult } from './types-B7duBj6U.js';
7
7
  export { AST_SUPPORTED_LANGUAGES, ChangedFiles, FileEntry, GrammarMapping, INDEXABLE_EXTENSIONS, detectLanguage, getTreeSitterGrammar, hashContent, resolveChanges, shouldIndexFile } from './indexing/index.js';
8
8
  export { ChunkMapping, CitationDocumentBlock, CitationDocumentOptions, DocumentMapping, RawCitation, ResolvedCitation, buildCitationDocuments, resolveCitation, resolveCitations } from './citations/index.js';
9
+ export { CLI_TOOL_EXTENSIONS, CliToolExtension, MCP_TOOL_DEFINITIONS, McpToolDefinition, McpToolParam, buildMcpTools, buildToolNames } from './mcp-tools/index.js';
10
+ export { CLI_COMMANDS, CLI_COMMAND_CATEGORIES, CliCategoryInfo, CliCommandCategory, CliCommandDef, CliOptionDef } from './cli-commands/index.js';
11
+ import './types-DOhSojcf.js';
package/dist/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ import {
2
+ CLI_TOOL_EXTENSIONS,
3
+ MCP_TOOL_DEFINITIONS,
4
+ buildMcpTools,
5
+ buildToolNames
6
+ } from "./chunk-HAJWPNLU.js";
7
+ import {
8
+ CLI_COMMANDS,
9
+ CLI_COMMAND_CATEGORIES
10
+ } from "./chunk-U4V5NX67.js";
1
11
  import {
2
12
  chunkByAST,
3
13
  chunkByLines,
@@ -10,7 +20,7 @@ import {
10
20
  import {
11
21
  deduplicateChunks,
12
22
  reciprocalRankFusion
13
- } from "./chunk-ZMBYQK43.js";
23
+ } from "./chunk-F3ZH5BUA.js";
14
24
  import {
15
25
  hashContent,
16
26
  resolveChanges
@@ -34,9 +44,15 @@ import {
34
44
  } from "./chunk-3FEHRHFQ.js";
35
45
  export {
36
46
  AST_SUPPORTED_LANGUAGES,
47
+ CLI_COMMANDS,
48
+ CLI_COMMAND_CATEGORIES,
49
+ CLI_TOOL_EXTENSIONS,
37
50
  INDEXABLE_EXTENSIONS,
51
+ MCP_TOOL_DEFINITIONS,
38
52
  PLACEHOLDER_PATTERNS,
39
53
  buildCitationDocuments,
54
+ buildMcpTools,
55
+ buildToolNames,
40
56
  chunkByAST,
41
57
  chunkByLines,
42
58
  chunkFile,
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared MCP tool definitions for Fragments.
3
+ *
4
+ * Both @fragments-sdk/mcp (standalone) and @fragments-sdk/cli (full-featured)
5
+ * import from here, eliminating duplication of tool names, descriptions, and
6
+ * input schemas.
7
+ */
8
+ interface McpToolParam {
9
+ type: string;
10
+ description: string;
11
+ enum?: string[];
12
+ items?: {
13
+ type: string;
14
+ };
15
+ properties?: Record<string, McpToolParam>;
16
+ }
17
+ interface McpToolDefinition {
18
+ /** Short key used to build the prefixed tool name, e.g. "discover" */
19
+ key: string;
20
+ description: string;
21
+ params: Record<string, McpToolParam>;
22
+ required?: string[];
23
+ }
24
+ /** Extra params only present in the CLI server (Playwright-backed) */
25
+ interface CliToolExtension {
26
+ key: string;
27
+ /** Additional params merged into the base tool's inputSchema.properties */
28
+ params: Record<string, McpToolParam>;
29
+ /** Override the description (e.g. CLI render mentions baseline) */
30
+ description?: string;
31
+ }
32
+ declare const MCP_TOOL_DEFINITIONS: McpToolDefinition[];
33
+ declare const CLI_TOOL_EXTENSIONS: CliToolExtension[];
34
+ interface McpSdkTool {
35
+ name: string;
36
+ description: string;
37
+ inputSchema: {
38
+ type: 'object';
39
+ properties: Record<string, unknown>;
40
+ required?: string[];
41
+ };
42
+ }
43
+ /**
44
+ * Build a TOOL_NAMES map: `{ discover: "prefix_discover", ... }`
45
+ */
46
+ declare function buildToolNames(prefix: string): Record<string, string>;
47
+ /**
48
+ * Build MCP SDK `Tool[]` from shared definitions, optionally merging CLI
49
+ * extensions.
50
+ */
51
+ declare function buildMcpTools(prefix: string, extensions?: CliToolExtension[]): McpSdkTool[];
52
+
53
+ export { CLI_TOOL_EXTENSIONS, type CliToolExtension, MCP_TOOL_DEFINITIONS, type McpToolDefinition, type McpToolParam, buildMcpTools, buildToolNames };
@@ -0,0 +1,12 @@
1
+ import {
2
+ CLI_TOOL_EXTENSIONS,
3
+ MCP_TOOL_DEFINITIONS,
4
+ buildMcpTools,
5
+ buildToolNames
6
+ } from "../chunk-HAJWPNLU.js";
7
+ export {
8
+ CLI_TOOL_EXTENSIONS,
9
+ MCP_TOOL_DEFINITIONS,
10
+ buildMcpTools,
11
+ buildToolNames
12
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  deduplicateChunks,
3
3
  reciprocalRankFusion
4
- } from "../chunk-ZMBYQK43.js";
4
+ } from "../chunk-F3ZH5BUA.js";
5
5
  export {
6
6
  deduplicateChunks,
7
7
  reciprocalRankFusion
@@ -1,3 +1,5 @@
1
+ import { S as SerializedComponentGraph } from '../types-DOhSojcf.js';
2
+
1
3
  /**
2
4
  * Compiled fragment types — shared between CLI and MCP packages.
3
5
  *
@@ -140,6 +142,8 @@ interface CompiledSegmentsFile {
140
142
  segments: Record<string, CompiledSegment>;
141
143
  blocks?: Record<string, CompiledBlock>;
142
144
  tokens?: CompiledTokenData;
145
+ /** Component relationship graph for AI structural queries */
146
+ graph?: SerializedComponentGraph;
143
147
  /** @deprecated Use blocks instead */
144
148
  recipes?: Record<string, CompiledBlock>;
145
149
  }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Component Graph data model — types for the design-system-semantic relationship graph.
3
+ *
4
+ * These types describe nodes (components), edges (relationships), and health
5
+ * metrics that together give AI agents structural understanding of a design system.
6
+ */
7
+ type GraphEdgeType = 'imports' | 'hook-depends' | 'renders' | 'composes' | 'parent-of' | 'alternative-to' | 'sibling-of';
8
+ declare const GRAPH_EDGE_TYPES: readonly GraphEdgeType[];
9
+ /** Default weight for each edge type */
10
+ declare const EDGE_TYPE_WEIGHTS: Record<GraphEdgeType, number>;
11
+ interface ComponentNode {
12
+ name: string;
13
+ category: string;
14
+ status: string;
15
+ compositionPattern?: 'compound' | 'simple' | 'controlled';
16
+ subComponents?: string[];
17
+ }
18
+ interface GraphEdge {
19
+ source: string;
20
+ target: string;
21
+ type: GraphEdgeType;
22
+ weight: number;
23
+ note?: string;
24
+ /** Where this edge was detected from */
25
+ provenance: string;
26
+ }
27
+ interface GraphHealth {
28
+ /** Components with zero edges */
29
+ orphans: string[];
30
+ /** Top components by total degree (in + out) */
31
+ hubs: Array<{
32
+ name: string;
33
+ degree: number;
34
+ }>;
35
+ /** Percentage of components appearing in at least one block */
36
+ compositionCoverage: number;
37
+ /** Disconnected groups (BFS on undirected projection) */
38
+ connectedComponents: string[][];
39
+ /** Average degree across all nodes */
40
+ averageDegree: number;
41
+ /** Total node and edge counts */
42
+ nodeCount: number;
43
+ edgeCount: number;
44
+ }
45
+ interface ComponentGraph {
46
+ nodes: ComponentNode[];
47
+ edges: GraphEdge[];
48
+ health: GraphHealth;
49
+ }
50
+ interface ImpactResult {
51
+ /** The component that was changed */
52
+ component: string;
53
+ /** Components affected at each depth level */
54
+ affected: Array<{
55
+ component: string;
56
+ depth: number;
57
+ path: string[];
58
+ edgeType: GraphEdgeType;
59
+ }>;
60
+ /** Blocks that use the changed component or any affected component */
61
+ affectedBlocks: string[];
62
+ /** Total count of affected components */
63
+ totalAffected: number;
64
+ }
65
+ interface PathResult {
66
+ /** Whether a path exists */
67
+ found: boolean;
68
+ /** Nodes along the shortest path (including source and target) */
69
+ path: string[];
70
+ /** Edges along the shortest path */
71
+ edges: GraphEdge[];
72
+ }
73
+ interface NeighborResult {
74
+ /** The center component */
75
+ component: string;
76
+ /** All components reachable within maxHops */
77
+ neighbors: Array<{
78
+ component: string;
79
+ hops: number;
80
+ edgeType: GraphEdgeType;
81
+ }>;
82
+ }
83
+ interface CompositionTree {
84
+ /** The root component */
85
+ component: string;
86
+ /** Composition pattern */
87
+ compositionPattern?: 'compound' | 'simple' | 'controlled';
88
+ /** Direct sub-components */
89
+ subComponents: string[];
90
+ /** Sub-components that must be present */
91
+ requiredChildren: string[];
92
+ /** Parent component (if this is a sub-component) */
93
+ parent?: string;
94
+ /** Sibling components at the same level */
95
+ siblings: string[];
96
+ /** Blocks that use this component */
97
+ blocks: string[];
98
+ }
99
+ interface SerializedEdge {
100
+ /** source */
101
+ s: string;
102
+ /** target */
103
+ t: string;
104
+ /** type */
105
+ ty: GraphEdgeType;
106
+ /** weight */
107
+ w: number;
108
+ /** note (optional) */
109
+ no?: string;
110
+ /** provenance */
111
+ p: string;
112
+ }
113
+ interface SerializedComponentGraph {
114
+ nodes: ComponentNode[];
115
+ edges: SerializedEdge[];
116
+ health: GraphHealth;
117
+ }
118
+
119
+ export { type ComponentGraph as C, EDGE_TYPE_WEIGHTS as E, type GraphEdgeType as G, type ImpactResult as I, type NeighborResult as N, type PathResult as P, type SerializedComponentGraph as S, type GraphEdge as a, type CompositionTree as b, type GraphHealth as c, type ComponentNode as d, type SerializedEdge as e, GRAPH_EDGE_TYPES as f };
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@fragments-sdk/context",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Code intelligence and RAG primitives for design system and codebase indexing",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/ConanMcN/fragments"
8
+ },
5
9
  "type": "module",
6
10
  "main": "./dist/index.js",
7
11
  "module": "./dist/index.js",
@@ -38,6 +42,18 @@
38
42
  "./citations": {
39
43
  "types": "./dist/citations/index.d.ts",
40
44
  "import": "./dist/citations/index.js"
45
+ },
46
+ "./mcp-tools": {
47
+ "types": "./dist/mcp-tools/index.d.ts",
48
+ "import": "./dist/mcp-tools/index.js"
49
+ },
50
+ "./cli-commands": {
51
+ "types": "./dist/cli-commands/index.d.ts",
52
+ "import": "./dist/cli-commands/index.js"
53
+ },
54
+ "./graph": {
55
+ "types": "./dist/graph/index.d.ts",
56
+ "import": "./dist/graph/index.js"
41
57
  }
42
58
  },
43
59
  "publishConfig": {