@contentrain/mcp 0.3.1 → 1.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.
- package/LICENSE +1 -1
- package/README.md +147 -238
- package/dist/apply-manager-CaTuu7Lj.mjs +751 -0
- package/dist/apply-manager-CaTuu7Lj.mjs.map +1 -0
- package/dist/astro-parser-RofKmKQi.mjs +166 -0
- package/dist/astro-parser-RofKmKQi.mjs.map +1 -0
- package/dist/branch-lifecycle-DB6sgeJi.mjs +97 -0
- package/dist/branch-lifecycle-DB6sgeJi.mjs.map +1 -0
- package/dist/chunk-BEJ448es.mjs +35 -0
- package/dist/compiler-rIC4ETHv.mjs +44509 -0
- package/dist/compiler-rIC4ETHv.mjs.map +1 -0
- package/dist/compiler-sfc.cjs-BbD04rn_.mjs +50279 -0
- package/dist/compiler-sfc.cjs-BbD04rn_.mjs.map +1 -0
- package/dist/config-CPlhDwsv.mjs +27 -0
- package/dist/config-CPlhDwsv.mjs.map +1 -0
- package/dist/context-yh3cuw5N.mjs +46 -0
- package/dist/context-yh3cuw5N.mjs.map +1 -0
- package/dist/core/apply-manager.d.mts +144 -0
- package/dist/core/apply-manager.d.mts.map +1 -0
- package/dist/core/apply-manager.mjs +6 -0
- package/dist/core/config.d.mts +8 -0
- package/dist/core/config.d.mts.map +1 -0
- package/dist/core/config.mjs +2 -0
- package/dist/core/content-manager.d.mts +53 -0
- package/dist/core/content-manager.d.mts.map +1 -0
- package/dist/core/content-manager.mjs +2 -0
- package/dist/core/context.d.mts +13 -0
- package/dist/core/context.d.mts.map +1 -0
- package/dist/core/context.mjs +3 -0
- package/dist/core/graph-builder.d.mts +12 -0
- package/dist/core/graph-builder.d.mts.map +1 -0
- package/dist/core/graph-builder.mjs +2 -0
- package/dist/core/meta-manager.d.mts +14 -0
- package/dist/core/meta-manager.d.mts.map +1 -0
- package/dist/core/meta-manager.mjs +2 -0
- package/dist/core/model-manager.d.mts +44 -0
- package/dist/core/model-manager.d.mts.map +1 -0
- package/dist/core/model-manager.mjs +2 -0
- package/dist/core/scan-config.d.mts +24 -0
- package/dist/core/scan-config.d.mts.map +1 -0
- package/dist/core/scan-config.mjs +2 -0
- package/dist/core/scanner.d.mts +25 -0
- package/dist/core/scanner.d.mts.map +1 -0
- package/dist/core/scanner.mjs +3 -0
- package/dist/core/validator.d.mts +23 -0
- package/dist/core/validator.d.mts.map +1 -0
- package/dist/core/validator.mjs +3 -0
- package/dist/detect-C8XmJ4S6.mjs +362 -0
- package/dist/detect-C8XmJ4S6.mjs.map +1 -0
- package/dist/fs-BbuGnVcG.mjs +52 -0
- package/dist/fs-BbuGnVcG.mjs.map +1 -0
- package/dist/git/branch-lifecycle.d.mts +28 -0
- package/dist/git/branch-lifecycle.d.mts.map +1 -0
- package/dist/git/branch-lifecycle.mjs +2 -0
- package/dist/git/transaction.d.mts +25 -0
- package/dist/git/transaction.d.mts.map +1 -0
- package/dist/git/transaction.mjs +4 -0
- package/dist/graph-builder-fPrDDwnu.mjs +162 -0
- package/dist/graph-builder-fPrDDwnu.mjs.map +1 -0
- package/dist/id-BdD4HvMY.mjs +12 -0
- package/dist/id-BdD4HvMY.mjs.map +1 -0
- package/dist/index.d.mts +1 -359
- package/dist/index.mjs +15 -2161
- package/dist/index.mjs.map +1 -1
- package/dist/meta-manager-CECrfsKm.mjs +53 -0
- package/dist/meta-manager-CECrfsKm.mjs.map +1 -0
- package/dist/model-manager-BcWWu5l2.mjs +963 -0
- package/dist/model-manager-BcWWu5l2.mjs.map +1 -0
- package/dist/node-Cbq5eR5i.mjs +300 -0
- package/dist/node-Cbq5eR5i.mjs.map +1 -0
- package/dist/scan-config-AJGxCdNd.mjs +159 -0
- package/dist/scan-config-AJGxCdNd.mjs.map +1 -0
- package/dist/scanner-BdTiv8sw.mjs +619 -0
- package/dist/scanner-BdTiv8sw.mjs.map +1 -0
- package/dist/serializer-Dueih-i2.mjs +33 -0
- package/dist/serializer-Dueih-i2.mjs.map +1 -0
- package/dist/server-CTcDpxwW.mjs +1861 -0
- package/dist/server-CTcDpxwW.mjs.map +1 -0
- package/dist/server.d.mts +7 -0
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +11 -0
- package/dist/source-map-generator-DpO-ejrt.mjs +893 -0
- package/dist/source-map-generator-DpO-ejrt.mjs.map +1 -0
- package/dist/svelte-parser-COTNG92w.mjs +225 -0
- package/dist/svelte-parser-COTNG92w.mjs.map +1 -0
- package/dist/templates/index.d.mts +8 -0
- package/dist/templates/index.d.mts.map +1 -0
- package/dist/templates/index.mjs +2 -0
- package/dist/templates-3HWi-PTu.mjs +824 -0
- package/dist/templates-3HWi-PTu.mjs.map +1 -0
- package/dist/transaction-BsECnmL5.mjs +128 -0
- package/dist/transaction-BsECnmL5.mjs.map +1 -0
- package/dist/tsx-parser-Bf8Firrq.mjs +2 -0
- package/dist/tsx-parser-CYVyBWjn.mjs +234 -0
- package/dist/tsx-parser-CYVyBWjn.mjs.map +1 -0
- package/dist/util/detect.d.mts +20 -0
- package/dist/util/detect.d.mts.map +1 -0
- package/dist/util/detect.mjs +2 -0
- package/dist/util/fs.d.mts +12 -0
- package/dist/util/fs.d.mts.map +1 -0
- package/dist/util/fs.mjs +2 -0
- package/dist/util/id.d.mts +6 -0
- package/dist/util/id.d.mts.map +1 -0
- package/dist/util/id.mjs +2 -0
- package/dist/util/serializer.d.mts +14 -0
- package/dist/util/serializer.d.mts.map +1 -0
- package/dist/util/serializer.mjs +2 -0
- package/dist/validator-ku84AyFr.mjs +755 -0
- package/dist/validator-ku84AyFr.mjs.map +1 -0
- package/dist/vue-parser-CjS4YAoQ.mjs +225 -0
- package/dist/vue-parser-CjS4YAoQ.mjs.map +1 -0
- package/package.json +107 -43
- package/dist/fs-D83-Ii_y.mjs +0 -75
- package/dist/fs-D83-Ii_y.mjs.map +0 -1
- package/dist/index.d.mts.map +0 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { r as pathExists } from "./fs-BbuGnVcG.mjs";
|
|
2
|
+
import { basename, extname, join } from "node:path";
|
|
3
|
+
import { readdir } from "node:fs/promises";
|
|
4
|
+
//#region src/core/scan-config.ts
|
|
5
|
+
/** File extensions to scan across all JS/TS ecosystem projects */
|
|
6
|
+
const SCAN_EXTENSIONS = new Set([
|
|
7
|
+
".tsx",
|
|
8
|
+
".jsx",
|
|
9
|
+
".vue",
|
|
10
|
+
".ts",
|
|
11
|
+
".js",
|
|
12
|
+
".mjs",
|
|
13
|
+
".astro",
|
|
14
|
+
".svelte"
|
|
15
|
+
]);
|
|
16
|
+
/** Directory names to always exclude from scanning */
|
|
17
|
+
const SCAN_IGNORE_DIRS = new Set([
|
|
18
|
+
"node_modules",
|
|
19
|
+
".pnpm",
|
|
20
|
+
"dist",
|
|
21
|
+
"build",
|
|
22
|
+
"out",
|
|
23
|
+
".output",
|
|
24
|
+
".nuxt",
|
|
25
|
+
".next",
|
|
26
|
+
".svelte-kit",
|
|
27
|
+
".expo",
|
|
28
|
+
".turbo",
|
|
29
|
+
".parcel-cache",
|
|
30
|
+
".vercel",
|
|
31
|
+
".netlify",
|
|
32
|
+
"coverage",
|
|
33
|
+
"__tests__",
|
|
34
|
+
"__mocks__",
|
|
35
|
+
".git",
|
|
36
|
+
".vscode",
|
|
37
|
+
".idea",
|
|
38
|
+
".contentrain"
|
|
39
|
+
]);
|
|
40
|
+
/** Max files per scan operation */
|
|
41
|
+
const MAX_SCAN_FILES = 500;
|
|
42
|
+
/** File patterns to skip regardless of extension */
|
|
43
|
+
const SKIP_FILE_RE = /\.(test|spec)\.[^.]+$|\.d\.ts$|\.min\.[^.]+$/;
|
|
44
|
+
/** Directories that represent entry points / pages / screens */
|
|
45
|
+
const PAGE_DIR_NAMES = new Set([
|
|
46
|
+
"pages",
|
|
47
|
+
"routes",
|
|
48
|
+
"screens",
|
|
49
|
+
"views",
|
|
50
|
+
"controllers",
|
|
51
|
+
"handlers",
|
|
52
|
+
"resolvers"
|
|
53
|
+
]);
|
|
54
|
+
/** Directories that represent reusable components / modules */
|
|
55
|
+
const COMPONENT_DIR_NAMES = new Set([
|
|
56
|
+
"components",
|
|
57
|
+
"ui",
|
|
58
|
+
"widgets",
|
|
59
|
+
"elements",
|
|
60
|
+
"features",
|
|
61
|
+
"modules",
|
|
62
|
+
"services",
|
|
63
|
+
"providers",
|
|
64
|
+
"shared",
|
|
65
|
+
"common"
|
|
66
|
+
]);
|
|
67
|
+
/** Directories that represent layouts / templates */
|
|
68
|
+
const LAYOUT_DIR_NAMES = new Set(["layouts", "templates"]);
|
|
69
|
+
/** Next.js App Router special files that are page-like */
|
|
70
|
+
const NEXTJS_PAGE_FILES = new Set([
|
|
71
|
+
"page.tsx",
|
|
72
|
+
"page.jsx",
|
|
73
|
+
"page.ts",
|
|
74
|
+
"page.js",
|
|
75
|
+
"layout.tsx",
|
|
76
|
+
"layout.jsx",
|
|
77
|
+
"layout.ts",
|
|
78
|
+
"layout.js",
|
|
79
|
+
"error.tsx",
|
|
80
|
+
"error.jsx",
|
|
81
|
+
"loading.tsx",
|
|
82
|
+
"loading.jsx",
|
|
83
|
+
"not-found.tsx",
|
|
84
|
+
"not-found.jsx"
|
|
85
|
+
]);
|
|
86
|
+
/** Classify a file into page/component/layout/other based on path heuristics */
|
|
87
|
+
function classifyFile(relPath) {
|
|
88
|
+
const parts = relPath.split("/");
|
|
89
|
+
const fileName = parts[parts.length - 1] ?? "";
|
|
90
|
+
if (parts.includes("app") && NEXTJS_PAGE_FILES.has(fileName)) return fileName.startsWith("layout") ? "layout" : "page";
|
|
91
|
+
for (const part of parts) {
|
|
92
|
+
const lower = part.toLowerCase();
|
|
93
|
+
if (LAYOUT_DIR_NAMES.has(lower)) return "layout";
|
|
94
|
+
if (PAGE_DIR_NAMES.has(lower)) return "page";
|
|
95
|
+
if (COMPONENT_DIR_NAMES.has(lower)) return "component";
|
|
96
|
+
}
|
|
97
|
+
return "other";
|
|
98
|
+
}
|
|
99
|
+
/** Common source directories across all JS/TS project types */
|
|
100
|
+
const AUTO_DETECT_DIRS = [
|
|
101
|
+
"src",
|
|
102
|
+
"app",
|
|
103
|
+
"lib",
|
|
104
|
+
"pages",
|
|
105
|
+
"components",
|
|
106
|
+
"layouts",
|
|
107
|
+
"views",
|
|
108
|
+
"screens",
|
|
109
|
+
"modules",
|
|
110
|
+
"routes",
|
|
111
|
+
"controllers",
|
|
112
|
+
"services",
|
|
113
|
+
"features",
|
|
114
|
+
"shared",
|
|
115
|
+
"common",
|
|
116
|
+
"hooks",
|
|
117
|
+
"composables",
|
|
118
|
+
"stores"
|
|
119
|
+
];
|
|
120
|
+
/** Auto-detect which source directories exist in the project */
|
|
121
|
+
async function autoDetectSourceDirs(projectRoot) {
|
|
122
|
+
const found = [];
|
|
123
|
+
for (const dir of AUTO_DETECT_DIRS) if (await pathExists(join(projectRoot, dir))) found.push(dir);
|
|
124
|
+
return found.length > 0 ? found : ["."];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Discover source files matching scan criteria.
|
|
128
|
+
* Returns relative paths (relative to projectRoot).
|
|
129
|
+
*/
|
|
130
|
+
async function discoverFiles(projectRoot, options) {
|
|
131
|
+
const extensions = options?.include ? new Set(options.include.map((e) => e.startsWith(".") ? e : `.${e}`)) : SCAN_EXTENSIONS;
|
|
132
|
+
const extraExcludes = new Set(options?.exclude ?? []);
|
|
133
|
+
const scanDirs = options?.paths ?? await autoDetectSourceDirs(projectRoot);
|
|
134
|
+
const files = [];
|
|
135
|
+
for (const dir of scanDirs) {
|
|
136
|
+
const absDir = join(projectRoot, dir);
|
|
137
|
+
if (!await pathExists(absDir)) continue;
|
|
138
|
+
let entries;
|
|
139
|
+
try {
|
|
140
|
+
entries = await readdir(absDir, { recursive: true });
|
|
141
|
+
} catch {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
if (files.length >= 500) break;
|
|
146
|
+
const fileName = basename(entry);
|
|
147
|
+
if (entry.split("/").some((seg) => SCAN_IGNORE_DIRS.has(seg) || extraExcludes.has(seg))) continue;
|
|
148
|
+
if (!extensions.has(extname(fileName))) continue;
|
|
149
|
+
if (SKIP_FILE_RE.test(fileName)) continue;
|
|
150
|
+
files.push(join(dir, entry));
|
|
151
|
+
}
|
|
152
|
+
if (files.length >= 500) break;
|
|
153
|
+
}
|
|
154
|
+
return files.toSorted((a, b) => a.localeCompare(b)).slice(0, 500);
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
export { classifyFile as a, autoDetectSourceDirs as i, SCAN_EXTENSIONS as n, discoverFiles as o, SCAN_IGNORE_DIRS as r, MAX_SCAN_FILES as t };
|
|
158
|
+
|
|
159
|
+
//# sourceMappingURL=scan-config-AJGxCdNd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-config-AJGxCdNd.mjs","names":[],"sources":["../src/core/scan-config.ts"],"sourcesContent":["import { readdir } from 'node:fs/promises'\nimport { join, extname, basename } from 'node:path'\nimport { pathExists } from '../util/fs.js'\n\n// ─── Shared Scan Constants ───\n\n/** File extensions to scan across all JS/TS ecosystem projects */\nexport const SCAN_EXTENSIONS = new Set([\n '.tsx', '.jsx', '.vue', '.ts', '.js', '.mjs', '.astro', '.svelte',\n])\n\n/** Directory names to always exclude from scanning */\nexport const SCAN_IGNORE_DIRS = new Set([\n // Package managers / deps\n 'node_modules', '.pnpm',\n // Build outputs\n 'dist', 'build', 'out', '.output',\n // Framework caches\n '.nuxt', '.next', '.svelte-kit', '.expo', '.turbo', '.parcel-cache', '.vercel', '.netlify',\n // Test / coverage\n 'coverage', '__tests__', '__mocks__',\n // VCS / IDE\n '.git', '.vscode', '.idea',\n // Contentrain\n '.contentrain',\n])\n\n/** Max files per scan operation */\nexport const MAX_SCAN_FILES = 500\n\n/** File patterns to skip regardless of extension */\nconst SKIP_FILE_RE = /\\.(test|spec)\\.[^.]+$|\\.d\\.ts$|\\.min\\.[^.]+$/\n\n// ─── File Classification ───\n// Covers: React, Next.js, Nuxt, Vue, Astro, SvelteKit, Remix,\n// React Native/Expo, NestJS, Express, Fastify, Koa, Hapi\n\n/** Directories that represent entry points / pages / screens */\nconst PAGE_DIR_NAMES = new Set([\n // Frontend routing\n 'pages', 'routes', 'screens', 'views',\n // Backend entry points\n 'controllers', 'handlers', 'resolvers',\n])\n\n/** Directories that represent reusable components / modules */\nconst COMPONENT_DIR_NAMES = new Set([\n // UI components\n 'components', 'ui', 'widgets', 'elements',\n // Feature modules\n 'features', 'modules',\n // Backend services\n 'services', 'providers',\n // Shared / common\n 'shared', 'common',\n])\n\n/** Directories that represent layouts / templates */\nconst LAYOUT_DIR_NAMES = new Set([\n 'layouts', 'templates',\n])\n\n/** Next.js App Router special files that are page-like */\nconst NEXTJS_PAGE_FILES = new Set([\n 'page.tsx', 'page.jsx', 'page.ts', 'page.js',\n 'layout.tsx', 'layout.jsx', 'layout.ts', 'layout.js',\n 'error.tsx', 'error.jsx',\n 'loading.tsx', 'loading.jsx',\n 'not-found.tsx', 'not-found.jsx',\n])\n\n/** Classify a file into page/component/layout/other based on path heuristics */\nexport function classifyFile(relPath: string): 'page' | 'component' | 'layout' | 'other' {\n const parts = relPath.split('/')\n const fileName = parts[parts.length - 1] ?? ''\n\n // Next.js App Router: files in app/ with special names are pages\n if (parts.includes('app') && NEXTJS_PAGE_FILES.has(fileName)) {\n return fileName.startsWith('layout') ? 'layout' : 'page'\n }\n\n // Check directory names in path (check layout first — more specific)\n for (const part of parts) {\n const lower = part.toLowerCase()\n if (LAYOUT_DIR_NAMES.has(lower)) return 'layout'\n if (PAGE_DIR_NAMES.has(lower)) return 'page'\n if (COMPONENT_DIR_NAMES.has(lower)) return 'component'\n }\n\n return 'other'\n}\n\n// ─── Source Directory Detection ───\n\n/** Common source directories across all JS/TS project types */\nconst AUTO_DETECT_DIRS = [\n // Standard source\n 'src', 'app', 'lib',\n // Frontend specific\n 'pages', 'components', 'layouts', 'views',\n // Mobile\n 'screens',\n // Backend\n 'modules', 'routes', 'controllers', 'services',\n // Shared\n 'features', 'shared', 'common',\n // Hooks / composables\n 'hooks', 'composables',\n // Stores\n 'stores',\n]\n\n/** Auto-detect which source directories exist in the project */\nexport async function autoDetectSourceDirs(projectRoot: string): Promise<string[]> {\n const found: string[] = []\n for (const dir of AUTO_DETECT_DIRS) {\n if (await pathExists(join(projectRoot, dir))) {\n found.push(dir)\n }\n }\n return found.length > 0 ? found : ['.']\n}\n\n// ─── File Discovery ───\n\nexport interface DiscoverFilesOptions {\n paths?: string[]\n include?: string[]\n exclude?: string[]\n}\n\n/**\n * Discover source files matching scan criteria.\n * Returns relative paths (relative to projectRoot).\n */\nexport async function discoverFiles(\n projectRoot: string,\n options?: DiscoverFilesOptions,\n): Promise<string[]> {\n const extensions = options?.include\n ? new Set(options.include.map(e => e.startsWith('.') ? e : `.${e}`))\n : SCAN_EXTENSIONS\n const extraExcludes = new Set(options?.exclude ?? [])\n const scanDirs = options?.paths ?? await autoDetectSourceDirs(projectRoot)\n\n const files: string[] = []\n\n for (const dir of scanDirs) {\n const absDir = join(projectRoot, dir)\n if (!(await pathExists(absDir))) continue\n\n let entries: string[]\n try {\n entries = await readdir(absDir, { recursive: true }) as unknown as string[]\n } catch {\n continue\n }\n\n for (const entry of entries) {\n if (files.length >= MAX_SCAN_FILES) break\n\n const fileName = basename(entry)\n\n // Check if any path segment is excluded\n const pathSegments = entry.split('/')\n if (pathSegments.some(seg => SCAN_IGNORE_DIRS.has(seg) || extraExcludes.has(seg))) continue\n\n // Check extension\n if (!extensions.has(extname(fileName))) continue\n\n // Skip test/spec/declaration/minified files\n if (SKIP_FILE_RE.test(fileName)) continue\n\n files.push(join(dir, entry))\n }\n\n if (files.length >= MAX_SCAN_FILES) break\n }\n\n return files.toSorted((a, b) => a.localeCompare(b)).slice(0, MAX_SCAN_FILES)\n}\n"],"mappings":"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"}
|