purecontext-mcp 1.5.2 → 1.7.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/FRAMEWORK-ADAPTERS.md +368 -351
- package/dist/adapters/astro-preprocessor.d.ts +25 -0
- package/dist/adapters/astro-preprocessor.d.ts.map +1 -0
- package/dist/adapters/astro-preprocessor.js +50 -0
- package/dist/adapters/astro-preprocessor.js.map +1 -0
- package/dist/adapters/astro.d.ts +13 -0
- package/dist/adapters/astro.d.ts.map +1 -0
- package/dist/adapters/astro.js +83 -0
- package/dist/adapters/astro.js.map +1 -0
- package/dist/adapters/detect-utils.d.ts +38 -0
- package/dist/adapters/detect-utils.d.ts.map +1 -0
- package/dist/adapters/detect-utils.js +95 -0
- package/dist/adapters/detect-utils.js.map +1 -0
- package/dist/adapters/nuxt.d.ts +20 -0
- package/dist/adapters/nuxt.d.ts.map +1 -1
- package/dist/adapters/nuxt.js +128 -13
- package/dist/adapters/nuxt.js.map +1 -1
- package/dist/adapters/svelte-preprocessor.d.ts +29 -0
- package/dist/adapters/svelte-preprocessor.d.ts.map +1 -0
- package/dist/adapters/svelte-preprocessor.js +83 -0
- package/dist/adapters/svelte-preprocessor.js.map +1 -0
- package/dist/adapters/svelte.d.ts +13 -0
- package/dist/adapters/svelte.d.ts.map +1 -0
- package/dist/adapters/svelte.js +96 -0
- package/dist/adapters/svelte.js.map +1 -0
- package/dist/adapters/vue.d.ts.map +1 -1
- package/dist/adapters/vue.js +87 -20
- package/dist/adapters/vue.js.map +1 -1
- package/dist/cli/hooks.d.ts +2 -2
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +104 -121
- package/dist/cli/hooks.js.map +1 -1
- package/dist/core/index-manager.d.ts.map +1 -1
- package/dist/core/index-manager.js +9 -2
- package/dist/core/index-manager.js.map +1 -1
- package/dist/core/indexing-worker.d.ts +2 -0
- package/dist/core/indexing-worker.d.ts.map +1 -1
- package/dist/core/indexing-worker.js +2 -0
- package/dist/core/indexing-worker.js.map +1 -1
- package/dist/core/watcher/file-watcher.d.ts +6 -0
- package/dist/core/watcher/file-watcher.d.ts.map +1 -1
- package/dist/core/watcher/file-watcher.js +11 -1
- package/dist/core/watcher/file-watcher.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/tools/index-repo.d.ts.map +1 -1
- package/dist/server/tools/index-repo.js +8 -2
- package/dist/server/tools/index-repo.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte component pre-processor.
|
|
3
|
+
*
|
|
4
|
+
* Splits a raw .svelte file buffer into typed ProcessedBlock[] so the TypeScript/
|
|
5
|
+
* JavaScript language handlers can parse each <script> block independently.
|
|
6
|
+
* Markup and <style> blocks are intentionally omitted — they don't contain
|
|
7
|
+
* symbols we want to index.
|
|
8
|
+
*
|
|
9
|
+
* Svelte components may contain an instance <script> and an optional module
|
|
10
|
+
* script (`<script context="module">` or `<script module>` in Svelte 5). Both
|
|
11
|
+
* are extracted.
|
|
12
|
+
*
|
|
13
|
+
* Byte-offset correctness:
|
|
14
|
+
* offsetInOriginal is always computed from Buffer.byteLength(), never from
|
|
15
|
+
* string character indices, so symbols inside multi-byte content that precedes
|
|
16
|
+
* a script block are positioned correctly.
|
|
17
|
+
*/
|
|
18
|
+
import { ParseError } from '../core/errors.js';
|
|
19
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Split a Svelte component buffer into its typed script blocks.
|
|
22
|
+
*
|
|
23
|
+
* Returns one ProcessedBlock per <script> block found, with language set to
|
|
24
|
+
* 'typescript' when lang="ts"/lang="tsx" is present and 'javascript' otherwise.
|
|
25
|
+
*
|
|
26
|
+
* Returns [] for markup-only components (no <script>).
|
|
27
|
+
* Throws ParseError for mismatched <script> open/close tags.
|
|
28
|
+
*/
|
|
29
|
+
export function splitSvelteSFC(source, filePath) {
|
|
30
|
+
const str = source.toString('utf8');
|
|
31
|
+
// ── Validate tag balance ──────────────────────────────────────────────────
|
|
32
|
+
const openCount = countMatches(str, /<script\b/gi);
|
|
33
|
+
const closeCount = countMatches(str, /<\/script>/gi);
|
|
34
|
+
if (openCount !== closeCount) {
|
|
35
|
+
throw new ParseError(`Malformed Svelte component: ${openCount} <script> open tags but ${closeCount} </script> close tags`, filePath);
|
|
36
|
+
}
|
|
37
|
+
if (openCount === 0) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
// ── Extract script blocks ─────────────────────────────────────────────────
|
|
41
|
+
// Captures: group 1 = attributes (everything between <script and >)
|
|
42
|
+
// group 2 = inner content
|
|
43
|
+
const SCRIPT_RE = /<script([^>]*)>([\s\S]*?)<\/script>/gi;
|
|
44
|
+
const blocks = [];
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = SCRIPT_RE.exec(str)) !== null) {
|
|
47
|
+
const attrs = match[1] ?? '';
|
|
48
|
+
const innerContent = match[2] ?? '';
|
|
49
|
+
// Byte offset of the first character of inner content within the original
|
|
50
|
+
// file. Reconstruct the open tag length in chars then convert the prefix to
|
|
51
|
+
// bytes so multi-byte characters before this point are accounted for.
|
|
52
|
+
//
|
|
53
|
+
// match.index → char index of '<'
|
|
54
|
+
// 7 → length of '<script'
|
|
55
|
+
// attrs.length → attribute string length in chars
|
|
56
|
+
// 1 → the '>' character
|
|
57
|
+
const contentCharStart = match.index + 7 + attrs.length + 1;
|
|
58
|
+
const offsetInOriginal = Buffer.byteLength(str.slice(0, contentCharStart), 'utf8');
|
|
59
|
+
blocks.push({
|
|
60
|
+
content: Buffer.from(innerContent, 'utf8'),
|
|
61
|
+
language: detectLanguage(attrs),
|
|
62
|
+
offsetInOriginal,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return blocks;
|
|
66
|
+
}
|
|
67
|
+
// ─── Internals ────────────────────────────────────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Determine block language from the <script> tag attributes string.
|
|
70
|
+
* lang="ts" | lang="tsx" → 'typescript'
|
|
71
|
+
* lang="js" | (no lang) → 'javascript'
|
|
72
|
+
*/
|
|
73
|
+
function detectLanguage(attrs) {
|
|
74
|
+
const langMatch = attrs.match(/\blang=["']([^"']+)["']/i);
|
|
75
|
+
if (!langMatch)
|
|
76
|
+
return 'javascript';
|
|
77
|
+
const lang = langMatch[1].toLowerCase();
|
|
78
|
+
return lang === 'ts' || lang === 'tsx' ? 'typescript' : 'javascript';
|
|
79
|
+
}
|
|
80
|
+
function countMatches(str, re) {
|
|
81
|
+
return (str.match(re) ?? []).length;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=svelte-preprocessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte-preprocessor.js","sourceRoot":"","sources":["../../src/adapters/svelte-preprocessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,iFAAiF;AAEjF;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,QAAgB;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEpC,6EAA6E;IAC7E,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACrD,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAClB,+BAA+B,SAAS,2BAA2B,UAAU,uBAAuB,EACpG,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,6EAA6E;IAC7E,oEAAoE;IACpE,oCAAoC;IACpC,MAAM,SAAS,GAAG,uCAAuC,CAAC;IAC1D,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,IAAI,KAA6B,CAAC;IAElC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEpC,0EAA0E;QAC1E,4EAA4E;QAC5E,sEAAsE;QACtE,EAAE;QACF,sCAAsC;QACtC,wCAAwC;QACxC,qDAAqD;QACrD,sCAAsC;QACtC,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;QAEnF,MAAM,CAAC,IAAI,CAAC;YACV,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;YAC1C,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC;YAC/B,gBAAgB;SACjB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iFAAiF;AAEjF;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC1D,IAAI,CAAC,SAAS;QAAE,OAAO,YAAY,CAAC;IACpC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;AACvE,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,EAAU;IAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte framework adapter.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Detect Svelte projects (package.json declares `svelte`/`@sveltejs/*`,
|
|
6
|
+
* a svelte.config.* file, or `.svelte` files present — incl. monorepo sub-apps).
|
|
7
|
+
* 2. Pre-process .svelte components into typed script blocks via svelte-preprocessor.
|
|
8
|
+
* 3. Emit one `component` symbol per .svelte file (name derived from filename).
|
|
9
|
+
* 4. Upgrade exported `useXxx` functions to kind `'composable'` via enrichMetadata.
|
|
10
|
+
*/
|
|
11
|
+
import type { FrameworkAdapter } from '../core/types.js';
|
|
12
|
+
export declare const svelteAdapter: FrameworkAdapter;
|
|
13
|
+
//# sourceMappingURL=svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.d.ts","sourceRoot":"","sources":["../../src/adapters/svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAyB7E,eAAO,MAAM,aAAa,EAAE,gBAyE3B,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte framework adapter.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Detect Svelte projects (package.json declares `svelte`/`@sveltejs/*`,
|
|
6
|
+
* a svelte.config.* file, or `.svelte` files present — incl. monorepo sub-apps).
|
|
7
|
+
* 2. Pre-process .svelte components into typed script blocks via svelte-preprocessor.
|
|
8
|
+
* 3. Emit one `component` symbol per .svelte file (name derived from filename).
|
|
9
|
+
* 4. Upgrade exported `useXxx` functions to kind `'composable'` via enrichMetadata.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'crypto';
|
|
12
|
+
import { basename } from 'path';
|
|
13
|
+
import { existsSync, readFileSync } from 'fs';
|
|
14
|
+
import { splitSvelteSFC } from './svelte-preprocessor.js';
|
|
15
|
+
import { registerAdapter } from './adapter-registry.js';
|
|
16
|
+
import { scanForFramework, pkgDepMatches, toPascalCase } from './detect-utils.js';
|
|
17
|
+
import { logger } from '../core/logger.js';
|
|
18
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
19
|
+
function makeId(filePath, name, kind) {
|
|
20
|
+
return createHash('sha256').update(`${filePath}:${name}:${kind}`).digest('hex').slice(0, 16);
|
|
21
|
+
}
|
|
22
|
+
function componentNameFromPath(filePath) {
|
|
23
|
+
return toPascalCase(basename(filePath, '.svelte'));
|
|
24
|
+
}
|
|
25
|
+
/** Returns true if a package.json declares a svelte / @sveltejs/* dependency. */
|
|
26
|
+
function pkgDeclaresSvelte(raw) {
|
|
27
|
+
return pkgDepMatches(raw, (k) => k === 'svelte' || k.startsWith('@sveltejs/'));
|
|
28
|
+
}
|
|
29
|
+
const SVELTE_CONFIG_NAMES = ['svelte.config.js', 'svelte.config.ts', 'svelte.config.mjs', 'svelte.config.cjs'];
|
|
30
|
+
// ─── Svelte adapter ─────────────────────────────────────────────────────────────
|
|
31
|
+
export const svelteAdapter = {
|
|
32
|
+
name: 'svelte',
|
|
33
|
+
extensions: () => ['.svelte'],
|
|
34
|
+
// ── Detection ───────────────────────────────────────────────────────────────
|
|
35
|
+
async detect(projectRoot) {
|
|
36
|
+
// Fast path: root package.json declares svelte.
|
|
37
|
+
try {
|
|
38
|
+
if (pkgDeclaresSvelte(readFileSync(`${projectRoot}/package.json`, 'utf8')))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// no package.json — fall through
|
|
43
|
+
}
|
|
44
|
+
// svelte.config.* at root.
|
|
45
|
+
if (SVELTE_CONFIG_NAMES.some((n) => existsSync(`${projectRoot}/${n}`)))
|
|
46
|
+
return true;
|
|
47
|
+
// Monorepo / sub-app fallback: bounded recursive scan for a `.svelte` file or
|
|
48
|
+
// a nested package.json declaring svelte.
|
|
49
|
+
return scanForFramework(projectRoot, {
|
|
50
|
+
matchesFile: (name) => name.endsWith('.svelte'),
|
|
51
|
+
pkgDeclares: pkgDeclaresSvelte,
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
// ── File routing ─────────────────────────────────────────────────────────────
|
|
55
|
+
fileFilter: (filePath) => filePath.endsWith('.svelte'),
|
|
56
|
+
// ── Pre-processing ───────────────────────────────────────────────────────────
|
|
57
|
+
preProcess: splitSvelteSFC,
|
|
58
|
+
// ── Framework symbol extraction ──────────────────────────────────────────────
|
|
59
|
+
/** Emit one `component` symbol per .svelte file. */
|
|
60
|
+
extractFrameworkSymbols(tree, source, filePath) {
|
|
61
|
+
const name = componentNameFromPath(filePath);
|
|
62
|
+
return [
|
|
63
|
+
{
|
|
64
|
+
id: makeId(filePath, name, 'component'),
|
|
65
|
+
name,
|
|
66
|
+
kind: 'component',
|
|
67
|
+
filePath,
|
|
68
|
+
startByte: 0,
|
|
69
|
+
endByte: source.length,
|
|
70
|
+
signature: `<${name}>`,
|
|
71
|
+
summary: `Svelte component ${name}`,
|
|
72
|
+
frameworkMeta: { svelte_component: true },
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
},
|
|
76
|
+
// ── Metadata enrichment ──────────────────────────────────────────────────────
|
|
77
|
+
/** Upgrade exported `useXxx` functions/consts to kind `'composable'`. */
|
|
78
|
+
enrichMetadata(symbol) {
|
|
79
|
+
if ((symbol.kind === 'function' || symbol.kind === 'const') && /^use[A-Z]/.test(symbol.name)) {
|
|
80
|
+
return {
|
|
81
|
+
...symbol,
|
|
82
|
+
kind: 'composable',
|
|
83
|
+
id: makeId(symbol.filePath, symbol.name, 'composable'),
|
|
84
|
+
frameworkMeta: { ...symbol.frameworkMeta, svelte_composable: true },
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (symbol.kind === 'component') {
|
|
88
|
+
return { ...symbol, frameworkMeta: { ...symbol.frameworkMeta, svelte_component: true } };
|
|
89
|
+
}
|
|
90
|
+
return symbol;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
// ─── Self-registration ────────────────────────────────────────────────────────
|
|
94
|
+
registerAdapter(svelteAdapter);
|
|
95
|
+
logger.debug("Adapter 'svelte' registered");
|
|
96
|
+
//# sourceMappingURL=svelte.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.js","sourceRoot":"","sources":["../../src/adapters/svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/adapters/vue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/adapters/vue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AA8H7E,eAAO,MAAM,UAAU,EAAE,gBAqFxB,CAAC"}
|
package/dist/adapters/vue.js
CHANGED
|
@@ -34,6 +34,85 @@ function toPascalCase(str) {
|
|
|
34
34
|
function componentNameFromPath(filePath) {
|
|
35
35
|
return toPascalCase(basename(filePath, '.vue'));
|
|
36
36
|
}
|
|
37
|
+
// ─── Detection helpers ──────────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Directory names that never contain first-party Vue source — skipped during
|
|
40
|
+
* the recursive detection scan to keep it fast and avoid false positives from
|
|
41
|
+
* bundled dependencies.
|
|
42
|
+
*/
|
|
43
|
+
const DETECT_IGNORE_DIRS = new Set([
|
|
44
|
+
'node_modules',
|
|
45
|
+
'.git',
|
|
46
|
+
'dist',
|
|
47
|
+
'build',
|
|
48
|
+
'out',
|
|
49
|
+
'.nuxt',
|
|
50
|
+
'.output',
|
|
51
|
+
'.next',
|
|
52
|
+
'coverage',
|
|
53
|
+
'vendor',
|
|
54
|
+
'target',
|
|
55
|
+
'.cache',
|
|
56
|
+
'.turbo',
|
|
57
|
+
'.svelte-kit',
|
|
58
|
+
]);
|
|
59
|
+
/** Max directory depth and total directories visited by the detection scan. */
|
|
60
|
+
const DETECT_MAX_DEPTH = 6;
|
|
61
|
+
const DETECT_MAX_DIRS = 2000;
|
|
62
|
+
/** Returns true if a parsed package.json declares a vue / @vue/* dependency. */
|
|
63
|
+
function pkgDeclaresVue(raw) {
|
|
64
|
+
try {
|
|
65
|
+
const pkg = JSON.parse(raw);
|
|
66
|
+
const deps = Object.assign({}, pkg['dependencies'], pkg['devDependencies']);
|
|
67
|
+
return Object.keys(deps).some((k) => k === 'vue' || k.startsWith('@vue/'));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Bounded recursive scan: returns true on the first sign of a Vue project —
|
|
75
|
+
* either a `.vue` file or a (possibly nested) package.json declaring vue.
|
|
76
|
+
* Skips heavy/irrelevant directories and caps depth + total directories so the
|
|
77
|
+
* scan stays cheap even on large monorepos. Symlinked directories are not
|
|
78
|
+
* followed (Dirent.isDirectory() is false for symlinks), avoiding cycles.
|
|
79
|
+
*/
|
|
80
|
+
function scanForVue(dir, depth, budget) {
|
|
81
|
+
if (depth > DETECT_MAX_DEPTH || budget.dirs >= DETECT_MAX_DIRS)
|
|
82
|
+
return false;
|
|
83
|
+
budget.dirs++;
|
|
84
|
+
let entries;
|
|
85
|
+
try {
|
|
86
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return false; // unreadable directory — skip
|
|
90
|
+
}
|
|
91
|
+
const subDirs = [];
|
|
92
|
+
for (const e of entries) {
|
|
93
|
+
if (e.isFile()) {
|
|
94
|
+
if (e.name.endsWith('.vue'))
|
|
95
|
+
return true;
|
|
96
|
+
if (e.name === 'package.json') {
|
|
97
|
+
try {
|
|
98
|
+
if (pkgDeclaresVue(readFileSync(`${dir}/${e.name}`, 'utf8')))
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// unreadable package.json — ignore
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (e.isDirectory() && !DETECT_IGNORE_DIRS.has(e.name)) {
|
|
107
|
+
subDirs.push(e.name);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
for (const name of subDirs) {
|
|
111
|
+
if (scanForVue(`${dir}/${name}`, depth + 1, budget))
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
37
116
|
/**
|
|
38
117
|
* Try to find an explicit component name from `defineOptions({ name: '...' })`.
|
|
39
118
|
* Falls back to the filename-derived PascalCase name.
|
|
@@ -51,32 +130,20 @@ export const vueAdapter = {
|
|
|
51
130
|
extensions: () => ['.vue'],
|
|
52
131
|
// ── Detection ───────────────────────────────────────────────────────────────
|
|
53
132
|
async detect(projectRoot) {
|
|
54
|
-
//
|
|
133
|
+
// Fast path: root package.json declares a vue dependency (common case).
|
|
55
134
|
try {
|
|
56
|
-
|
|
57
|
-
const pkg = JSON.parse(raw);
|
|
58
|
-
const deps = Object.assign({}, pkg['dependencies'], pkg['devDependencies']);
|
|
59
|
-
if (Object.keys(deps).some((k) => k === 'vue' || k.startsWith('@vue/'))) {
|
|
135
|
+
if (pkgDeclaresVue(readFileSync(`${projectRoot}/package.json`, 'utf8'))) {
|
|
60
136
|
return true;
|
|
61
137
|
}
|
|
62
138
|
}
|
|
63
139
|
catch {
|
|
64
|
-
// No package.json or parse error — fall through to
|
|
140
|
+
// No package.json or parse error — fall through to the recursive scan
|
|
65
141
|
}
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (entries.some((e) => e.isFile() && e.name.endsWith('.vue'))) {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// Directory doesn't exist — skip
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return false;
|
|
142
|
+
// Monorepo / sub-app fallback: bounded recursive scan for a `.vue` file or
|
|
143
|
+
// a nested package.json declaring vue. Handles projects where the Vue app
|
|
144
|
+
// lives in a subdirectory (frontend/, web/, apps/web/, …) rather than the
|
|
145
|
+
// indexed root. Skips heavy dirs and caps depth + total directories.
|
|
146
|
+
return scanForVue(projectRoot, 0, { dirs: 0 });
|
|
80
147
|
},
|
|
81
148
|
// ── File routing ─────────────────────────────────────────────────────────────
|
|
82
149
|
fileFilter: (filePath) => filePath.endsWith('.vue'),
|
package/dist/adapters/vue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../../src/adapters/vue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../../src/adapters/vue.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/hooks.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* `purecontext-mcp hooks --install` / `hooks --list`
|
|
3
3
|
* `purecontext-mcp hook-pretooluse|hook-posttooluse|hook-precompact|hook-worktree-create|hook-worktree-remove`
|
|
4
4
|
*
|
|
5
|
-
* Merges hook entries into ~/.claude/settings.json using
|
|
6
|
-
* (
|
|
5
|
+
* Merges hook entries into ~/.claude/settings.json using direct node invocation
|
|
6
|
+
* (node "<cliPath>" hook-*) so hooks never trigger npm registry SSL checks.
|
|
7
7
|
* Also injects PureContext agent instructions into ~/.claude/CLAUDE.md.
|
|
8
8
|
*/
|
|
9
9
|
export declare function cmdHooksInstall(): void;
|
package/dist/cli/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/cli/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/cli/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+GH,wBAAgB,eAAe,IAAI,IAAI,CAetC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAenC;AAID,wBAAgB,aAAa,IAAI,IAAI,CAoDpC;AA6BD,wBAAgB,cAAc,IAAI,IAAI,CAuBrC;AAwCD,oDAAoD;AACpD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBvD;AAED,iEAAiE;AACjE,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CA8BxD;AA6DD,qEAAqE;AACrE,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBvD;AAED,uDAAuD;AACvD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoB3D;AAED,8EAA8E;AAC9E,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3D;AAyED,qFAAqF;AACrF,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwC1D;AAED,8EAA8E;AAC9E,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CA8C1D;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAUpD"}
|