@cl-mcp/core 2.0.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/config.d.ts +18 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +23 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/data/metadata.d.ts +36 -0
  8. package/dist/data/metadata.d.ts.map +1 -0
  9. package/dist/data/metadata.js +98 -0
  10. package/dist/data/metadata.js.map +1 -0
  11. package/dist/data/paths.d.ts +17 -0
  12. package/dist/data/paths.d.ts.map +1 -0
  13. package/dist/data/paths.js +99 -0
  14. package/dist/data/paths.js.map +1 -0
  15. package/dist/data/registry.d.ts +48 -0
  16. package/dist/data/registry.d.ts.map +1 -0
  17. package/dist/data/registry.js +193 -0
  18. package/dist/data/registry.js.map +1 -0
  19. package/dist/data/schema.d.ts +4924 -0
  20. package/dist/data/schema.d.ts.map +1 -0
  21. package/dist/data/schema.js +356 -0
  22. package/dist/data/schema.js.map +1 -0
  23. package/dist/domain/context.d.ts +11 -0
  24. package/dist/domain/context.d.ts.map +1 -0
  25. package/dist/domain/context.js +168 -0
  26. package/dist/domain/context.js.map +1 -0
  27. package/dist/domain/formatters.d.ts +64 -0
  28. package/dist/domain/formatters.d.ts.map +1 -0
  29. package/dist/domain/formatters.js +607 -0
  30. package/dist/domain/formatters.js.map +1 -0
  31. package/dist/domain/resolver.d.ts +19 -0
  32. package/dist/domain/resolver.d.ts.map +1 -0
  33. package/dist/domain/resolver.js +146 -0
  34. package/dist/domain/resolver.js.map +1 -0
  35. package/dist/domain/search.d.ts +25 -0
  36. package/dist/domain/search.d.ts.map +1 -0
  37. package/dist/domain/search.js +177 -0
  38. package/dist/domain/search.js.map +1 -0
  39. package/dist/handlers.d.ts +24 -0
  40. package/dist/handlers.d.ts.map +1 -0
  41. package/dist/handlers.js +378 -0
  42. package/dist/handlers.js.map +1 -0
  43. package/dist/index.d.ts +25 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +28 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/types.d.ts +7 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +6 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +44 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcin Milewicz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @cl-mcp/core
2
+
3
+ Transport-agnostic core of [cl-mcp](https://github.com/marcinmilewicz/cl-mcp) — the
4
+ shared engine behind the MCP server and the CLI.
5
+
6
+ It owns everything except the transport:
7
+
8
+ - **Metadata loading** — a multi-library registry with a Zod trust boundary
9
+ (`CL_MCP_METADATA_PATH` = single library, `CL_MCP_DATA_DIR` = a directory of
10
+ libraries).
11
+ - **Search & resolution domain** — semantic search plus a name-resolution
12
+ cascade (exact → selector → fuzzy → semantic), with compound-name support
13
+ (`Dialog.Root`).
14
+ - **Tool handlers** — the six tools as pure `args → ToolResponse` functions
15
+ (`TOOL_HANDLERS`), with no SDK dependency.
16
+
17
+ Importing this package has **no side effects**; call `loadPreloadedMetadata()`
18
+ before using any accessor or handler.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install @cl-mcp/core @cl-mcp/analyzer
24
+ ```
25
+
26
+ `@cl-mcp/analyzer` is a peer dependency (it provides the shared metadata types
27
+ and analysis primitives).
28
+
29
+ ## Frontends
30
+
31
+ Both official frontends are thin adapters over this package and re-use the exact
32
+ same handlers:
33
+
34
+ - [`@cl-mcp/mcp-server`](https://www.npmjs.com/package/@cl-mcp/mcp-server) — MCP protocol (stdio) adapter.
35
+ - [`@cl-mcp/cli`](https://www.npmjs.com/package/@cl-mcp/cli) — shell adapter (`cl-mcp` bin).
36
+
37
+ See the [documentation site](https://marcinmilewicz.github.io/cl-mcp/) and the
38
+ [API reference](https://marcinmilewicz.github.io/cl-mcp/api/) for details.
39
+
40
+ ## License
41
+
42
+ MIT © Marcin Milewicz
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Library Configuration
3
+ *
4
+ * Dynamic configuration derived from loaded metadata — always describes the
5
+ * ACTIVE library (see data/registry.ts). No hardcoded library-specific values.
6
+ */
7
+ export declare const METADATA_FILENAME = "component-metadata.json";
8
+ export interface LibraryConfig {
9
+ name: string;
10
+ selectorPrefix: string;
11
+ packageName: string;
12
+ version: string;
13
+ /** Framework of the loaded metadata. Absent (legacy pre-v4.2 files) means "angular". */
14
+ framework?: "angular" | "react";
15
+ }
16
+ export declare function setLibraryConfig(config: LibraryConfig): void;
17
+ export declare function getLibraryConfig(): LibraryConfig;
18
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CACjC;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAE5D;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAUhD"}
package/dist/config.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Library Configuration
3
+ *
4
+ * Dynamic configuration derived from loaded metadata — always describes the
5
+ * ACTIVE library (see data/registry.ts). No hardcoded library-specific values.
6
+ */
7
+ export const METADATA_FILENAME = "component-metadata.json";
8
+ let _config = null;
9
+ export function setLibraryConfig(config) {
10
+ _config = config;
11
+ }
12
+ export function getLibraryConfig() {
13
+ if (!_config) {
14
+ return {
15
+ name: "component-library",
16
+ selectorPrefix: "",
17
+ packageName: "unknown",
18
+ version: "0.0.0",
19
+ };
20
+ }
21
+ return _config;
22
+ }
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAW3D,IAAI,OAAO,GAAyB,IAAI,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IACpD,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,cAAc,EAAE,EAAE;YAClB,WAAW,EAAE,SAAS;YACtB,OAAO,EAAE,OAAO;SACjB,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Metadata Loader for @cl-mcp/mcp-server
3
+ *
4
+ * Loads and provides access to the pre-generated component-metadata.json.
5
+ * Acts as the central data access layer.
6
+ */
7
+ import type { AnalyzedComponentEntry, FileAnalysis, ComponentMetadataFile, ComponentMetadataEntry } from '../types.js';
8
+ import type { ComponentSearchMeta } from '../domain/search.js';
9
+ export type { ComponentMetadataEntry, ComponentMetadataFile } from '../types.js';
10
+ export { buildImportedByIndex } from './registry.js';
11
+ /** Metadata of the ACTIVE library (see data/registry.ts for switching). */
12
+ export declare function getMetadata(): ComponentMetadataFile;
13
+ /**
14
+ * Load every resolvable component-metadata.json into the registry.
15
+ * Must be called once before any tool handlers access metadata.
16
+ * A single file = single-library mode (pre-registry behavior).
17
+ */
18
+ export declare function loadPreloadedMetadata(): void;
19
+ export declare function getAvailableComponents(): string[];
20
+ export declare function getPreloadedComponentMetadata(componentName: string): ComponentMetadataEntry | null;
21
+ /**
22
+ * Narrow a `ComponentMetadataEntry | null` (or a component name) down to
23
+ * `AnalyzedComponentEntry | null`. Centralizes the `kind === 'analyzed'`
24
+ * guard that was duplicated across formatters/search/resolver/context.
25
+ */
26
+ export declare function getAnalyzedEntry(entryOrName: ComponentMetadataEntry | string | null | undefined): AnalyzedComponentEntry | null;
27
+ export declare function componentExists(componentName: string): boolean;
28
+ export declare function getComponentAnalysis(componentName: string): readonly FileAnalysis[];
29
+ export declare function extractSelectors(preloaded: ComponentMetadataEntry | null): string[];
30
+ export declare function extractDirectiveSelectors(preloaded: ComponentMetadataEntry | null): string[];
31
+ export declare function countDirectivesAndPipes(preloaded: ComponentMetadataEntry | null): {
32
+ directives: number;
33
+ pipes: number;
34
+ };
35
+ export declare function buildSearchMetadataMap(components: string[]): Map<string, ComponentSearchMeta>;
36
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/data/metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACvH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAIrD,2EAA2E;AAC3E,wBAAgB,WAAW,IAAI,qBAAqB,CAMnD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C;AAID,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAElG;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9D,sBAAsB,GAAG,IAAI,CAI/B;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAInF;AAID,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG,MAAM,EAAE,CAMnF;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG,MAAM,EAAE,CAM5F;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAKvH;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAc7F"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Metadata Loader for @cl-mcp/mcp-server
3
+ *
4
+ * Loads and provides access to the pre-generated component-metadata.json.
5
+ * Acts as the central data access layer.
6
+ */
7
+ import { getActiveLibrary, loadLibraries } from './registry.js';
8
+ // Reverse-index builder lives in the registry now; re-exported for tests
9
+ // and back-compat.
10
+ export { buildImportedByIndex } from './registry.js';
11
+ // ── Metadata Access ─────────────────────────────────────────────────
12
+ /** Metadata of the ACTIVE library (see data/registry.ts for switching). */
13
+ export function getMetadata() {
14
+ try {
15
+ return getActiveLibrary().metadata;
16
+ }
17
+ catch {
18
+ throw new Error('[MCP] Metadata not loaded. Call loadPreloadedMetadata() first.');
19
+ }
20
+ }
21
+ /**
22
+ * Load every resolvable component-metadata.json into the registry.
23
+ * Must be called once before any tool handlers access metadata.
24
+ * A single file = single-library mode (pre-registry behavior).
25
+ */
26
+ export function loadPreloadedMetadata() {
27
+ try {
28
+ loadLibraries();
29
+ }
30
+ catch (error) {
31
+ throw new Error(`[MCP] Failed to load component metadata: ${error}`);
32
+ }
33
+ }
34
+ // ── Data Access Helpers ─────────────────────────────────────────────
35
+ export function getAvailableComponents() {
36
+ return Object.keys(getMetadata().components);
37
+ }
38
+ export function getPreloadedComponentMetadata(componentName) {
39
+ return getMetadata().components[componentName] ?? null;
40
+ }
41
+ /**
42
+ * Narrow a `ComponentMetadataEntry | null` (or a component name) down to
43
+ * `AnalyzedComponentEntry | null`. Centralizes the `kind === 'analyzed'`
44
+ * guard that was duplicated across formatters/search/resolver/context.
45
+ */
46
+ export function getAnalyzedEntry(entryOrName) {
47
+ const entry = typeof entryOrName === 'string' ? getPreloadedComponentMetadata(entryOrName) : entryOrName ?? null;
48
+ return entry && entry.kind === 'analyzed' ? entry : null;
49
+ }
50
+ export function componentExists(componentName) {
51
+ return componentName in getMetadata().components;
52
+ }
53
+ export function getComponentAnalysis(componentName) {
54
+ const preloaded = getPreloadedComponentMetadata(componentName);
55
+ if (!preloaded || preloaded.kind !== 'analyzed')
56
+ return [];
57
+ return preloaded.analysis;
58
+ }
59
+ // ── Selector extraction helpers ─────────────────────────────────────
60
+ export function extractSelectors(preloaded) {
61
+ if (!preloaded || preloaded.kind !== 'analyzed')
62
+ return [];
63
+ return preloaded.analysis
64
+ .flatMap((a) => a.components)
65
+ .map((c) => c.metadata.selector)
66
+ .filter((s) => Boolean(s));
67
+ }
68
+ export function extractDirectiveSelectors(preloaded) {
69
+ if (!preloaded || preloaded.kind !== 'analyzed')
70
+ return [];
71
+ return preloaded.analysis
72
+ .flatMap((a) => a.directives ?? [])
73
+ .map((d) => d.metadata.selector)
74
+ .filter((s) => Boolean(s));
75
+ }
76
+ export function countDirectivesAndPipes(preloaded) {
77
+ if (!preloaded || preloaded.kind !== 'analyzed')
78
+ return { directives: 0, pipes: 0 };
79
+ const directives = preloaded.analysis.reduce((sum, a) => sum + (a.directives?.length ?? 0), 0);
80
+ const pipes = preloaded.analysis.reduce((sum, a) => sum + (a.pipes?.length ?? 0), 0);
81
+ return { directives, pipes };
82
+ }
83
+ export function buildSearchMetadataMap(components) {
84
+ const metadataMap = new Map();
85
+ for (const compName of components) {
86
+ const preloaded = getPreloadedComponentMetadata(compName);
87
+ if (preloaded && preloaded.kind === 'analyzed') {
88
+ const componentSelectors = extractSelectors(preloaded);
89
+ const directiveSelectors = extractDirectiveSelectors(preloaded);
90
+ metadataMap.set(compName, {
91
+ llmSummary: preloaded.llmSummary,
92
+ selectors: [...componentSelectors, ...directiveSelectors],
93
+ });
94
+ }
95
+ }
96
+ return metadataMap;
97
+ }
98
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/data/metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Path resolution for @cl-mcp/mcp-server.
3
+ *
4
+ * Resolves the metadata JSON file path using:
5
+ * 1. CL_MCP_METADATA_PATH environment variable (direct path to JSON)
6
+ * 2. CL_MCP_DATA_DIR environment variable + library name
7
+ * 3. Default data/ directory relative to package root
8
+ */
9
+ /**
10
+ * Resolve EVERY loadable component-metadata.json. A single result is the
11
+ * single-library mode; multiple results put the server into multi-library
12
+ * mode (one registry entry per file).
13
+ */
14
+ export declare function resolveAllMetadataPaths(): string[];
15
+ /** First resolvable metadata path — legacy single-library entry point. */
16
+ export declare function resolveMetadataPath(): string;
17
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/data/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgDH;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAsClD;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Path resolution for @cl-mcp/mcp-server.
3
+ *
4
+ * Resolves the metadata JSON file path using:
5
+ * 1. CL_MCP_METADATA_PATH environment variable (direct path to JSON)
6
+ * 2. CL_MCP_DATA_DIR environment variable + library name
7
+ * 3. Default data/ directory relative to package root
8
+ */
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { METADATA_FILENAME } from '../config.js';
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+ /** Validate that a path doesn't contain traversal sequences. */
16
+ function validateSecurePath(envVar, value) {
17
+ if (value.includes('..')) {
18
+ throw new Error(`[MCP] Security: ${envVar} contains path traversal sequence: "${value}"`);
19
+ }
20
+ return path.resolve(value);
21
+ }
22
+ /** Walk up from startDir looking for a directory containing marker. */
23
+ function findAncestorWithFile(startDir, filename, maxDepth = 8) {
24
+ let dir = startDir;
25
+ for (let i = 0; i < maxDepth; i++) {
26
+ if (fs.existsSync(path.join(dir, filename))) {
27
+ return dir;
28
+ }
29
+ const parent = path.dirname(dir);
30
+ if (parent === dir)
31
+ break;
32
+ dir = parent;
33
+ }
34
+ return null;
35
+ }
36
+ /** Every metadata file found in a data directory (all subdirs + the dir itself). */
37
+ function scanDataDir(dataDir) {
38
+ const found = [];
39
+ if (!fs.existsSync(dataDir) || !fs.statSync(dataDir).isDirectory())
40
+ return found;
41
+ const entries = fs.readdirSync(dataDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
42
+ for (const entry of entries) {
43
+ if (!entry.isDirectory())
44
+ continue;
45
+ const candidate = path.join(dataDir, entry.name, METADATA_FILENAME);
46
+ if (fs.existsSync(candidate))
47
+ found.push(candidate);
48
+ }
49
+ const direct = path.join(dataDir, METADATA_FILENAME);
50
+ if (fs.existsSync(direct))
51
+ found.push(direct);
52
+ return found;
53
+ }
54
+ /**
55
+ * Resolve EVERY loadable component-metadata.json. A single result is the
56
+ * single-library mode; multiple results put the server into multi-library
57
+ * mode (one registry entry per file).
58
+ */
59
+ export function resolveAllMetadataPaths() {
60
+ // 1. Direct path via environment variable — always single-library.
61
+ if (process.env.CL_MCP_METADATA_PATH) {
62
+ const metadataPath = validateSecurePath('CL_MCP_METADATA_PATH', process.env.CL_MCP_METADATA_PATH);
63
+ if (fs.existsSync(metadataPath) && fs.statSync(metadataPath).isFile()) {
64
+ return [metadataPath];
65
+ }
66
+ // If path is a directory, look for metadata file inside
67
+ const inDir = path.join(metadataPath, METADATA_FILENAME);
68
+ if (fs.existsSync(inDir)) {
69
+ return [inDir];
70
+ }
71
+ throw new Error(`[MCP] Metadata not found at CL_MCP_METADATA_PATH: ${metadataPath}`);
72
+ }
73
+ // 2. Data directory via environment variable — every library inside.
74
+ if (process.env.CL_MCP_DATA_DIR) {
75
+ const dataDir = validateSecurePath('CL_MCP_DATA_DIR', process.env.CL_MCP_DATA_DIR);
76
+ const found = scanDataDir(dataDir);
77
+ if (found.length > 0)
78
+ return found;
79
+ }
80
+ // 3. Look for data/ directory relative to workspace root
81
+ const workspaceRoot = findAncestorWithFile(__dirname, 'package.json');
82
+ if (workspaceRoot) {
83
+ // Try monorepo root (go up from packages/mcp-server/dist/data/)
84
+ const monorepoRoot = findAncestorWithFile(workspaceRoot, 'vitest.workspace.ts');
85
+ if (monorepoRoot) {
86
+ const found = scanDataDir(path.join(monorepoRoot, 'data'));
87
+ if (found.length > 0)
88
+ return found;
89
+ }
90
+ }
91
+ throw new Error(`[MCP] Component metadata not found. Set CL_MCP_METADATA_PATH to the path of your ${METADATA_FILENAME} file, ` +
92
+ `or CL_MCP_DATA_DIR to a directory of per-library metadata.\n` +
93
+ ` Example: CL_MCP_METADATA_PATH=./data/angular-material/${METADATA_FILENAME}`);
94
+ }
95
+ /** First resolvable metadata path — legacy single-library entry point. */
96
+ export function resolveMetadataPath() {
97
+ return resolveAllMetadataPaths()[0];
98
+ }
99
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/data/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,gEAAgE;AAChE,SAAS,kBAAkB,CAAC,MAAc,EAAE,KAAa;IACvD,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,uCAAuC,KAAK,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,uEAAuE;AACvE,SAAS,oBAAoB,CAAC,QAAgB,EAAE,QAAgB,EAAE,QAAQ,GAAG,CAAC;IAC5E,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC5C,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oFAAoF;AACpF,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAC;IAEjF,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9G,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACrC,mEAAmE;IACnE,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACrC,MAAM,YAAY,GAAG,kBAAkB,CAAC,sBAAsB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClG,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACtE,OAAO,CAAC,YAAY,CAAC,CAAC;QACxB,CAAC;QACD,wDAAwD;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qDAAqD,YAAY,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,qEAAqE;IACrE,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,kBAAkB,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACnF,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IACrC,CAAC;IAED,yDAAyD;IACzD,MAAM,aAAa,GAAG,oBAAoB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACtE,IAAI,aAAa,EAAE,CAAC;QAClB,gEAAgE;QAChE,MAAM,YAAY,GAAG,oBAAoB,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;QAChF,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,oFAAoF,iBAAiB,SAAS;QAC9G,8DAA8D;QAC9D,2DAA2D,iBAAiB,EAAE,CAC/E,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB;IACjC,OAAO,uBAAuB,EAAE,CAAC,CAAC,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Library registry — multi-library support.
3
+ *
4
+ * Loads EVERY resolvable component-metadata.json (one per library) and keeps
5
+ * them keyed by a short library name. The rest of the server still reads a
6
+ * single "active" library through the existing accessors (`getMetadata()`,
7
+ * `getLibraryConfig()`); tool handlers switch the active library before
8
+ * delegating to domain code. Handlers compute synchronously, so the active
9
+ * pointer cannot be observed mid-switch.
10
+ *
11
+ * A single metadata file (CL_MCP_METADATA_PATH or one data subdir) is the
12
+ * single-library mode — behavior is identical to the pre-registry server.
13
+ */
14
+ import type { LibraryConfig } from '../config.js';
15
+ import type { ComponentMetadataFile } from '../types.js';
16
+ export interface LoadedLibrary {
17
+ /** Short name (e.g. `ui`) used as the qualifier in `ui:Button`. */
18
+ name: string;
19
+ metadataPath: string;
20
+ metadata: ComponentMetadataFile;
21
+ config: LibraryConfig;
22
+ }
23
+ export declare function loadLibraries(): void;
24
+ export declare function getLibraryNames(): string[];
25
+ export declare function isMultiLibrary(): boolean;
26
+ export declare function getActiveLibrary(): LoadedLibrary;
27
+ export declare function setActiveLibrary(name: string): void;
28
+ /** Run `fn` with the given library active, restoring the previous one after. */
29
+ export declare function withLibrary<T>(name: string, fn: () => T): T;
30
+ /**
31
+ * Resolve a user-supplied library qualifier: exact registry name,
32
+ * case-insensitive name, full import alias (`@acme/ui`), or alias tail.
33
+ */
34
+ export declare function resolveLibraryQualifier(input: string): string | null;
35
+ /** Test-only: reset registry state. */
36
+ export declare function __resetRegistryForTests(): void;
37
+ /** Test-only: inject libraries directly (bypasses path resolution). */
38
+ export declare function __setLibrariesForTests(libraries: Map<string, LoadedLibrary>): void;
39
+ /**
40
+ * Populate `importedBy` on every analyzed entry by reversing the
41
+ * `importsFrom` edges. Exported (via metadata.ts) for tests.
42
+ *
43
+ * Referential-integrity note: the analyzer writes only the forward
44
+ * `importsFrom` edge; keeping `importedBy` off disk means drift between
45
+ * the two can't happen.
46
+ */
47
+ export declare function buildImportedByIndex(file: ComponentMetadataFile): void;
48
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/data/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,MAAM,EAAE,aAAa,CAAC;CACvB;AAKD,wBAAgB,aAAa,IAAI,IAAI,CA2BpC;AAwED,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAGhD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQnD;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ3D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAepE;AAED,uCAAuC;AACvC,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,IAAI,CAIlF;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAkBtE"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Library registry — multi-library support.
3
+ *
4
+ * Loads EVERY resolvable component-metadata.json (one per library) and keeps
5
+ * them keyed by a short library name. The rest of the server still reads a
6
+ * single "active" library through the existing accessors (`getMetadata()`,
7
+ * `getLibraryConfig()`); tool handlers switch the active library before
8
+ * delegating to domain code. Handlers compute synchronously, so the active
9
+ * pointer cannot be observed mid-switch.
10
+ *
11
+ * A single metadata file (CL_MCP_METADATA_PATH or one data subdir) is the
12
+ * single-library mode — behavior is identical to the pre-registry server.
13
+ */
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { setLibraryConfig } from '../config.js';
17
+ import { resolveAllMetadataPaths } from './paths.js';
18
+ import { parseComponentMetadata } from './schema.js';
19
+ let _libraries = null;
20
+ let _activeName = null;
21
+ export function loadLibraries() {
22
+ const metadataPaths = resolveAllMetadataPaths();
23
+ const libraries = new Map();
24
+ for (const metadataPath of metadataPaths) {
25
+ const library = loadOne(metadataPath);
26
+ let name = library.name;
27
+ // Collision (two dirs deriving the same short name) — disambiguate.
28
+ let suffix = 2;
29
+ while (libraries.has(name)) {
30
+ name = `${library.name}-${suffix++}`;
31
+ }
32
+ libraries.set(name, { ...library, name });
33
+ }
34
+ if (libraries.size === 0) {
35
+ throw new Error('[MCP] No component metadata could be loaded.');
36
+ }
37
+ _libraries = libraries;
38
+ _activeName = [...libraries.keys()][0];
39
+ setLibraryConfig(libraries.get(_activeName).config);
40
+ console.error(`[MCP] Loaded ${libraries.size} librar${libraries.size === 1 ? 'y' : 'ies'}: ` +
41
+ [...libraries.values()].map((l) => `${l.name} (${l.config.framework ?? 'angular'}, v${l.metadata.version})`).join(', '));
42
+ }
43
+ function loadOne(metadataPath) {
44
+ const content = fs.readFileSync(metadataPath, 'utf-8');
45
+ let raw;
46
+ try {
47
+ raw = JSON.parse(content);
48
+ }
49
+ catch (parseErr) {
50
+ throw new Error(`[cl-mcp] Could not parse ${metadataPath} as JSON: ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`);
51
+ }
52
+ let metadata;
53
+ try {
54
+ metadata = parseComponentMetadata(raw);
55
+ }
56
+ catch (schemaErr) {
57
+ const msg = schemaErr instanceof Error ? schemaErr.message : String(schemaErr);
58
+ console.error(msg);
59
+ throw schemaErr;
60
+ }
61
+ buildImportedByIndex(metadata);
62
+ const major = Number.parseInt(String(metadata.version).split('.')[0] ?? '', 10);
63
+ if (Number.isFinite(major) && major !== 4) {
64
+ console.error(`[cl-mcp] ${metadataPath}: schema v${metadata.version} but server expects v4.x; ` +
65
+ `type fields may render as '<unresolved>' or carry legacy 'unknown'/'void' sentinels.`);
66
+ }
67
+ if (metadata.diagnostics && metadata.diagnostics.length > 0) {
68
+ const codes = metadata.diagnostics.map((d) => d.code);
69
+ console.error(`[cl-mcp] ${metadataPath}: ${metadata.diagnostics.length} analyzer diagnostic(s): ${codes.join(', ')}`);
70
+ }
71
+ // Derive per-library config. v4.2+ files carry the canonical `libraryName`;
72
+ // older files fall back to the componentsPath heuristic.
73
+ const componentsPath = metadata.componentsPath || '';
74
+ const packageName = metadata.libraryName || componentsPath.replace('node_modules/', '');
75
+ let selectorPrefix = '';
76
+ if (metadata.selectorMap) {
77
+ const firstSelector = Object.keys(metadata.selectorMap)[0];
78
+ const prefixMatch = firstSelector?.match(/^([a-z]+-)/);
79
+ if (prefixMatch)
80
+ selectorPrefix = prefixMatch[1];
81
+ }
82
+ const config = {
83
+ name: packageName.split('/').pop() || 'unknown',
84
+ selectorPrefix,
85
+ packageName,
86
+ version: metadata.version,
87
+ framework: metadata.framework ?? 'angular',
88
+ };
89
+ // Short registry name: prefer the metadata's parent directory (matches the
90
+ // workspace manifest naming), falling back to the package-name tail.
91
+ const dirName = path.basename(path.dirname(metadataPath));
92
+ const name = dirName && dirName !== '.' && dirName !== 'data' ? dirName : config.name;
93
+ return { name, metadataPath, metadata, config };
94
+ }
95
+ // ── Access ──────────────────────────────────────────────────────────
96
+ function requireLibraries() {
97
+ if (!_libraries || !_activeName) {
98
+ throw new Error('[MCP] Libraries not loaded. Call loadLibraries() first.');
99
+ }
100
+ return _libraries;
101
+ }
102
+ export function getLibraryNames() {
103
+ return [...requireLibraries().keys()];
104
+ }
105
+ export function isMultiLibrary() {
106
+ return requireLibraries().size > 1;
107
+ }
108
+ export function getActiveLibrary() {
109
+ const libraries = requireLibraries();
110
+ return libraries.get(_activeName);
111
+ }
112
+ export function setActiveLibrary(name) {
113
+ const libraries = requireLibraries();
114
+ const library = libraries.get(name);
115
+ if (!library) {
116
+ throw new Error(`[MCP] Unknown library "${name}". Available: ${[...libraries.keys()].join(', ')}`);
117
+ }
118
+ _activeName = name;
119
+ setLibraryConfig(library.config);
120
+ }
121
+ /** Run `fn` with the given library active, restoring the previous one after. */
122
+ export function withLibrary(name, fn) {
123
+ const previous = _activeName;
124
+ setActiveLibrary(name);
125
+ try {
126
+ return fn();
127
+ }
128
+ finally {
129
+ if (previous)
130
+ setActiveLibrary(previous);
131
+ }
132
+ }
133
+ /**
134
+ * Resolve a user-supplied library qualifier: exact registry name,
135
+ * case-insensitive name, full import alias (`@acme/ui`), or alias tail.
136
+ */
137
+ export function resolveLibraryQualifier(input) {
138
+ const libraries = requireLibraries();
139
+ if (libraries.has(input))
140
+ return input;
141
+ const lower = input.toLowerCase();
142
+ for (const [name, lib] of libraries) {
143
+ if (name.toLowerCase() === lower ||
144
+ lib.config.packageName.toLowerCase() === lower ||
145
+ lib.config.name.toLowerCase() === lower) {
146
+ return name;
147
+ }
148
+ }
149
+ return null;
150
+ }
151
+ /** Test-only: reset registry state. */
152
+ export function __resetRegistryForTests() {
153
+ _libraries = null;
154
+ _activeName = null;
155
+ }
156
+ /** Test-only: inject libraries directly (bypasses path resolution). */
157
+ export function __setLibrariesForTests(libraries) {
158
+ _libraries = libraries;
159
+ _activeName = [...libraries.keys()][0] ?? null;
160
+ if (_activeName)
161
+ setLibraryConfig(libraries.get(_activeName).config);
162
+ }
163
+ // ── Derived indices ─────────────────────────────────────────────────
164
+ /**
165
+ * Populate `importedBy` on every analyzed entry by reversing the
166
+ * `importsFrom` edges. Exported (via metadata.ts) for tests.
167
+ *
168
+ * Referential-integrity note: the analyzer writes only the forward
169
+ * `importsFrom` edge; keeping `importedBy` off disk means drift between
170
+ * the two can't happen.
171
+ */
172
+ export function buildImportedByIndex(file) {
173
+ // Clear any stray field first (defensive against hand-edited JSON).
174
+ for (const entry of Object.values(file.components)) {
175
+ if (entry.kind === 'analyzed') {
176
+ entry.importedBy = [];
177
+ }
178
+ }
179
+ for (const [sourceName, entry] of Object.entries(file.components)) {
180
+ if (entry.kind !== 'analyzed' || !entry.importsFrom)
181
+ continue;
182
+ for (const target of entry.importsFrom) {
183
+ const targetEntry = file.components[target];
184
+ if (!targetEntry || targetEntry.kind !== 'analyzed')
185
+ continue;
186
+ const list = targetEntry.importedBy;
187
+ if (list && !list.includes(sourceName)) {
188
+ list.push(sourceName);
189
+ }
190
+ }
191
+ }
192
+ }
193
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/data/registry.ts"],"names":[],"mappings":"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"}