claude-crap 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +308 -0
- package/LICENSE +21 -0
- package/README.md +550 -0
- package/bin/claude-crap.mjs +141 -0
- package/dist/adapters/bandit.d.ts +48 -0
- package/dist/adapters/bandit.d.ts.map +1 -0
- package/dist/adapters/bandit.js +145 -0
- package/dist/adapters/bandit.js.map +1 -0
- package/dist/adapters/common.d.ts +73 -0
- package/dist/adapters/common.d.ts.map +1 -0
- package/dist/adapters/common.js +78 -0
- package/dist/adapters/common.js.map +1 -0
- package/dist/adapters/eslint.d.ts +52 -0
- package/dist/adapters/eslint.d.ts.map +1 -0
- package/dist/adapters/eslint.js +142 -0
- package/dist/adapters/eslint.js.map +1 -0
- package/dist/adapters/index.d.ts +47 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +64 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/semgrep.d.ts +30 -0
- package/dist/adapters/semgrep.d.ts.map +1 -0
- package/dist/adapters/semgrep.js +130 -0
- package/dist/adapters/semgrep.js.map +1 -0
- package/dist/adapters/stryker.d.ts +55 -0
- package/dist/adapters/stryker.d.ts.map +1 -0
- package/dist/adapters/stryker.js +165 -0
- package/dist/adapters/stryker.js.map +1 -0
- package/dist/ast/cyclomatic.d.ts +48 -0
- package/dist/ast/cyclomatic.d.ts.map +1 -0
- package/dist/ast/cyclomatic.js +106 -0
- package/dist/ast/cyclomatic.js.map +1 -0
- package/dist/ast/index.d.ts +26 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +23 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/ast/language-config.d.ts +70 -0
- package/dist/ast/language-config.d.ts.map +1 -0
- package/dist/ast/language-config.js +192 -0
- package/dist/ast/language-config.js.map +1 -0
- package/dist/ast/tree-sitter-engine.d.ts +133 -0
- package/dist/ast/tree-sitter-engine.d.ts.map +1 -0
- package/dist/ast/tree-sitter-engine.js +270 -0
- package/dist/ast/tree-sitter-engine.js.map +1 -0
- package/dist/config.d.ts +57 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/crap-config.d.ts +97 -0
- package/dist/crap-config.d.ts.map +1 -0
- package/dist/crap-config.js +144 -0
- package/dist/crap-config.js.map +1 -0
- package/dist/dashboard/server.d.ts +65 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +147 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +574 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/crap.d.ts +71 -0
- package/dist/metrics/crap.d.ts.map +1 -0
- package/dist/metrics/crap.js +67 -0
- package/dist/metrics/crap.js.map +1 -0
- package/dist/metrics/index.d.ts +31 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +27 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/score.d.ts +143 -0
- package/dist/metrics/score.d.ts.map +1 -0
- package/dist/metrics/score.js +224 -0
- package/dist/metrics/score.js.map +1 -0
- package/dist/metrics/tdr.d.ts +106 -0
- package/dist/metrics/tdr.d.ts.map +1 -0
- package/dist/metrics/tdr.js +117 -0
- package/dist/metrics/tdr.js.map +1 -0
- package/dist/metrics/workspace-walker.d.ts +43 -0
- package/dist/metrics/workspace-walker.d.ts.map +1 -0
- package/dist/metrics/workspace-walker.js +137 -0
- package/dist/metrics/workspace-walker.js.map +1 -0
- package/dist/sarif/index.d.ts +21 -0
- package/dist/sarif/index.d.ts.map +1 -0
- package/dist/sarif/index.js +19 -0
- package/dist/sarif/index.js.map +1 -0
- package/dist/sarif/sarif-builder.d.ts +128 -0
- package/dist/sarif/sarif-builder.d.ts.map +1 -0
- package/dist/sarif/sarif-builder.js +79 -0
- package/dist/sarif/sarif-builder.js.map +1 -0
- package/dist/sarif/sarif-store.d.ts +205 -0
- package/dist/sarif/sarif-store.d.ts.map +1 -0
- package/dist/sarif/sarif-store.js +246 -0
- package/dist/sarif/sarif-store.js.map +1 -0
- package/dist/sarif/sarif-validator.d.ts +45 -0
- package/dist/sarif/sarif-validator.d.ts.map +1 -0
- package/dist/sarif/sarif-validator.js +138 -0
- package/dist/sarif/sarif-validator.js.map +1 -0
- package/dist/schemas/tool-schemas.d.ts +216 -0
- package/dist/schemas/tool-schemas.d.ts.map +1 -0
- package/dist/schemas/tool-schemas.js +208 -0
- package/dist/schemas/tool-schemas.js.map +1 -0
- package/dist/sdk.d.ts +45 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +44 -0
- package/dist/sdk.js.map +1 -0
- package/dist/tools/index.d.ts +24 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +23 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/test-harness.d.ts +75 -0
- package/dist/tools/test-harness.d.ts.map +1 -0
- package/dist/tools/test-harness.js +137 -0
- package/dist/tools/test-harness.js.map +1 -0
- package/dist/workspace-guard.d.ts +53 -0
- package/dist/workspace-guard.d.ts.map +1 -0
- package/dist/workspace-guard.js +61 -0
- package/dist/workspace-guard.js.map +1 -0
- package/package.json +133 -0
- package/plugin/.claude-plugin/plugin.json +29 -0
- package/plugin/.mcp.json +18 -0
- package/plugin/CLAUDE.md +143 -0
- package/plugin/bundle/dashboard/public/index.html +368 -0
- package/plugin/bundle/dashboard/public/vendor/vue.global.prod.js +9 -0
- package/plugin/bundle/mcp-server.mjs +8718 -0
- package/plugin/bundle/mcp-server.mjs.map +7 -0
- package/plugin/bundle/tdr-engine.mjs +50 -0
- package/plugin/bundle/tdr-engine.mjs.map +7 -0
- package/plugin/hooks/hooks.json +62 -0
- package/plugin/hooks/lib/crap-config.mjs +152 -0
- package/plugin/hooks/lib/gatekeeper-rules.mjs +257 -0
- package/plugin/hooks/lib/hook-io.mjs +151 -0
- package/plugin/hooks/lib/quality-gate.mjs +329 -0
- package/plugin/hooks/lib/test-harness.mjs +152 -0
- package/plugin/hooks/post-tool-use.mjs +245 -0
- package/plugin/hooks/pre-tool-use.mjs +290 -0
- package/plugin/hooks/session-start.mjs +109 -0
- package/plugin/hooks/stop-quality-gate.mjs +226 -0
- package/plugin/package.json +18 -0
- package/plugin/skills/adopt/SKILL.md +74 -0
- package/plugin/skills/analyze/SKILL.md +77 -0
- package/plugin/skills/check-test/SKILL.md +50 -0
- package/plugin/skills/score/SKILL.md +31 -0
- package/scripts/bug-report.mjs +328 -0
- package/scripts/build-fast.mjs +130 -0
- package/scripts/bundle-plugin.mjs +74 -0
- package/scripts/doctor.mjs +320 -0
- package/scripts/install.mjs +192 -0
- package/scripts/lib/cli-ui.mjs +122 -0
- package/scripts/postinstall.mjs +127 -0
- package/scripts/run-tests.mjs +95 -0
- package/scripts/status.mjs +110 -0
- package/scripts/uninstall.mjs +72 -0
- package/src/adapters/bandit.ts +191 -0
- package/src/adapters/common.ts +133 -0
- package/src/adapters/eslint.ts +187 -0
- package/src/adapters/index.ts +78 -0
- package/src/adapters/semgrep.ts +150 -0
- package/src/adapters/stryker.ts +218 -0
- package/src/ast/cyclomatic.ts +131 -0
- package/src/ast/index.ts +33 -0
- package/src/ast/language-config.ts +231 -0
- package/src/ast/tree-sitter-engine.ts +385 -0
- package/src/config.ts +109 -0
- package/src/crap-config.ts +196 -0
- package/src/dashboard/public/index.html +368 -0
- package/src/dashboard/public/vendor/vue.global.prod.js +9 -0
- package/src/dashboard/server.ts +205 -0
- package/src/index.ts +696 -0
- package/src/metrics/crap.ts +101 -0
- package/src/metrics/index.ts +51 -0
- package/src/metrics/score.ts +329 -0
- package/src/metrics/tdr.ts +155 -0
- package/src/metrics/workspace-walker.ts +146 -0
- package/src/sarif/index.ts +31 -0
- package/src/sarif/sarif-builder.ts +139 -0
- package/src/sarif/sarif-store.ts +347 -0
- package/src/sarif/sarif-validator.ts +145 -0
- package/src/schemas/tool-schemas.ts +225 -0
- package/src/sdk.ts +110 -0
- package/src/tests/adapters/bandit.test.ts +111 -0
- package/src/tests/adapters/dispatch.test.ts +100 -0
- package/src/tests/adapters/eslint.test.ts +138 -0
- package/src/tests/adapters/semgrep.test.ts +125 -0
- package/src/tests/adapters/stryker.test.ts +103 -0
- package/src/tests/crap-config.test.ts +228 -0
- package/src/tests/crap.test.ts +59 -0
- package/src/tests/cyclomatic.test.ts +87 -0
- package/src/tests/dashboard-http.test.ts +108 -0
- package/src/tests/dashboard-integrity.test.ts +128 -0
- package/src/tests/integration/mcp-server.integration.test.ts +352 -0
- package/src/tests/pre-tool-use-hook.test.ts +178 -0
- package/src/tests/sarif-store.test.ts +241 -0
- package/src/tests/sarif-validator.test.ts +164 -0
- package/src/tests/score.test.ts +260 -0
- package/src/tests/skills-frontmatter.test.ts +172 -0
- package/src/tests/stop-quality-gate-strictness.test.ts +243 -0
- package/src/tests/tdr.test.ts +86 -0
- package/src/tests/test-harness.test.ts +153 -0
- package/src/tests/workspace-guard.test.ts +111 -0
- package/src/tools/index.ts +24 -0
- package/src/tools/test-harness.ts +158 -0
- package/src/workspace-guard.ts +64 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ast/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public SDK entry point for the tree-sitter based AST engine and the
|
|
3
|
+
* cyclomatic complexity walker.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {
|
|
9
|
+
* TreeSitterEngine,
|
|
10
|
+
* computeCyclomaticComplexity,
|
|
11
|
+
* detectLanguageFromPath,
|
|
12
|
+
* type FileMetrics,
|
|
13
|
+
* type FunctionMetrics,
|
|
14
|
+
* type SupportedLanguage,
|
|
15
|
+
* } from "claude-crap/ast";
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @module ast
|
|
19
|
+
*/
|
|
20
|
+
export { TreeSitterEngine } from "./tree-sitter-engine.js";
|
|
21
|
+
export { computeCyclomaticComplexity } from "./cyclomatic.js";
|
|
22
|
+
export { LANGUAGE_TABLE, detectLanguageFromPath } from "./language-config.js";
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ast/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQ3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAG9D,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language tree-sitter node classification tables.
|
|
3
|
+
*
|
|
4
|
+
* Every language grammar exposes a different set of node type names. To
|
|
5
|
+
* keep the AST engine language-agnostic we encode, for each supported
|
|
6
|
+
* language, three sets:
|
|
7
|
+
*
|
|
8
|
+
* - `functionNodeTypes` — nodes that represent a function/method/lambda.
|
|
9
|
+
* These are the units we report metrics for.
|
|
10
|
+
* - `branchingNodeTypes` — nodes that add one independent path through
|
|
11
|
+
* the function. Used to compute cyclomatic
|
|
12
|
+
* complexity by counting occurrences.
|
|
13
|
+
* - `nameField` — the tree-sitter field name that holds the
|
|
14
|
+
* function's identifier, used to extract the
|
|
15
|
+
* function name for reporting.
|
|
16
|
+
*
|
|
17
|
+
* We also define which WASM grammar file to load per language. The paths
|
|
18
|
+
* are resolved at runtime against the `tree-sitter-wasms` package, but
|
|
19
|
+
* can be overridden via the engine constructor if you want to ship your
|
|
20
|
+
* own grammars.
|
|
21
|
+
*
|
|
22
|
+
* @module ast/language-config
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Languages currently supported by the AST engine. This is the same
|
|
26
|
+
* `enum` that appears in the `analyze_file_ast` tool schema — keep them
|
|
27
|
+
* in sync when adding a new language.
|
|
28
|
+
*/
|
|
29
|
+
export type SupportedLanguage = "csharp" | "javascript" | "typescript" | "python" | "java";
|
|
30
|
+
/**
|
|
31
|
+
* Per-language classification record. Immutable by convention.
|
|
32
|
+
*/
|
|
33
|
+
export interface LanguageConfig {
|
|
34
|
+
/** Canonical language identifier (stable across releases). */
|
|
35
|
+
readonly id: SupportedLanguage;
|
|
36
|
+
/** WASM grammar filename inside `tree-sitter-wasms/out/`. */
|
|
37
|
+
readonly wasmName: string;
|
|
38
|
+
/** File extensions that should map to this language. */
|
|
39
|
+
readonly extensions: ReadonlyArray<string>;
|
|
40
|
+
/** Tree-sitter node types that represent callable units. */
|
|
41
|
+
readonly functionNodeTypes: ReadonlySet<string>;
|
|
42
|
+
/** Tree-sitter node types that add +1 to cyclomatic complexity. */
|
|
43
|
+
readonly branchingNodeTypes: ReadonlySet<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Boolean / short-circuit operator node types. These are counted only
|
|
46
|
+
* when the node is an `"&&"`, `"||"`, `"??"` (etc.) operator, so the
|
|
47
|
+
* walker inspects the operator text on top of the node type.
|
|
48
|
+
*/
|
|
49
|
+
readonly booleanOperators: ReadonlyArray<string>;
|
|
50
|
+
/**
|
|
51
|
+
* Child-field names we try in order to extract the function name. The
|
|
52
|
+
* walker reads the first non-empty match.
|
|
53
|
+
*/
|
|
54
|
+
readonly nameFieldCandidates: ReadonlyArray<string>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Complete language table. Look up by {@link SupportedLanguage} identifier.
|
|
58
|
+
*/
|
|
59
|
+
export declare const LANGUAGE_TABLE: Readonly<Record<SupportedLanguage, LanguageConfig>>;
|
|
60
|
+
/**
|
|
61
|
+
* Infer a {@link SupportedLanguage} from a file path by matching its
|
|
62
|
+
* extension. Returns `null` when no known language matches. Useful when
|
|
63
|
+
* the caller does not already know the language and wants the engine to
|
|
64
|
+
* pick one automatically.
|
|
65
|
+
*
|
|
66
|
+
* @param filePath File path (absolute or relative).
|
|
67
|
+
* @returns The detected language or `null`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function detectLanguageFromPath(filePath: string): SupportedLanguage | null;
|
|
70
|
+
//# sourceMappingURL=language-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-config.d.ts","sourceRoot":"","sources":["../../src/ast/language-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,EAAE,iBAAiB,CAAC;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,mEAAmE;IACnE,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACrD;AAkJD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAM9E,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAQjF"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language tree-sitter node classification tables.
|
|
3
|
+
*
|
|
4
|
+
* Every language grammar exposes a different set of node type names. To
|
|
5
|
+
* keep the AST engine language-agnostic we encode, for each supported
|
|
6
|
+
* language, three sets:
|
|
7
|
+
*
|
|
8
|
+
* - `functionNodeTypes` — nodes that represent a function/method/lambda.
|
|
9
|
+
* These are the units we report metrics for.
|
|
10
|
+
* - `branchingNodeTypes` — nodes that add one independent path through
|
|
11
|
+
* the function. Used to compute cyclomatic
|
|
12
|
+
* complexity by counting occurrences.
|
|
13
|
+
* - `nameField` — the tree-sitter field name that holds the
|
|
14
|
+
* function's identifier, used to extract the
|
|
15
|
+
* function name for reporting.
|
|
16
|
+
*
|
|
17
|
+
* We also define which WASM grammar file to load per language. The paths
|
|
18
|
+
* are resolved at runtime against the `tree-sitter-wasms` package, but
|
|
19
|
+
* can be overridden via the engine constructor if you want to ship your
|
|
20
|
+
* own grammars.
|
|
21
|
+
*
|
|
22
|
+
* @module ast/language-config
|
|
23
|
+
*/
|
|
24
|
+
// -----------------------------------------------------------------------------
|
|
25
|
+
// C#
|
|
26
|
+
// -----------------------------------------------------------------------------
|
|
27
|
+
// Grammar: https://github.com/tree-sitter/tree-sitter-c-sharp
|
|
28
|
+
const CSHARP = {
|
|
29
|
+
id: "csharp",
|
|
30
|
+
wasmName: "tree-sitter-c_sharp.wasm",
|
|
31
|
+
extensions: [".cs"],
|
|
32
|
+
functionNodeTypes: new Set([
|
|
33
|
+
"method_declaration",
|
|
34
|
+
"local_function_statement",
|
|
35
|
+
"lambda_expression",
|
|
36
|
+
"anonymous_method_expression",
|
|
37
|
+
"constructor_declaration",
|
|
38
|
+
"destructor_declaration",
|
|
39
|
+
"operator_declaration",
|
|
40
|
+
"conversion_operator_declaration",
|
|
41
|
+
"accessor_declaration",
|
|
42
|
+
]),
|
|
43
|
+
branchingNodeTypes: new Set([
|
|
44
|
+
"if_statement",
|
|
45
|
+
"else_clause",
|
|
46
|
+
"while_statement",
|
|
47
|
+
"do_statement",
|
|
48
|
+
"for_statement",
|
|
49
|
+
"for_each_statement",
|
|
50
|
+
"case_switch_label",
|
|
51
|
+
"case_pattern_switch_label",
|
|
52
|
+
"switch_expression_arm",
|
|
53
|
+
"catch_clause",
|
|
54
|
+
"conditional_expression",
|
|
55
|
+
"conditional_access_expression",
|
|
56
|
+
"when_clause",
|
|
57
|
+
]),
|
|
58
|
+
booleanOperators: ["&&", "||", "??"],
|
|
59
|
+
nameFieldCandidates: ["name"],
|
|
60
|
+
};
|
|
61
|
+
// -----------------------------------------------------------------------------
|
|
62
|
+
// JavaScript
|
|
63
|
+
// -----------------------------------------------------------------------------
|
|
64
|
+
// Grammar: https://github.com/tree-sitter/tree-sitter-javascript
|
|
65
|
+
const JAVASCRIPT = {
|
|
66
|
+
id: "javascript",
|
|
67
|
+
wasmName: "tree-sitter-javascript.wasm",
|
|
68
|
+
extensions: [".js", ".jsx", ".mjs", ".cjs"],
|
|
69
|
+
functionNodeTypes: new Set([
|
|
70
|
+
"function_declaration",
|
|
71
|
+
"function_expression",
|
|
72
|
+
"arrow_function",
|
|
73
|
+
"method_definition",
|
|
74
|
+
"generator_function",
|
|
75
|
+
"generator_function_declaration",
|
|
76
|
+
]),
|
|
77
|
+
branchingNodeTypes: new Set([
|
|
78
|
+
"if_statement",
|
|
79
|
+
"else_clause",
|
|
80
|
+
"while_statement",
|
|
81
|
+
"do_statement",
|
|
82
|
+
"for_statement",
|
|
83
|
+
"for_in_statement",
|
|
84
|
+
"for_of_statement",
|
|
85
|
+
"switch_case",
|
|
86
|
+
"catch_clause",
|
|
87
|
+
"ternary_expression",
|
|
88
|
+
]),
|
|
89
|
+
booleanOperators: ["&&", "||", "??"],
|
|
90
|
+
nameFieldCandidates: ["name"],
|
|
91
|
+
};
|
|
92
|
+
// -----------------------------------------------------------------------------
|
|
93
|
+
// TypeScript
|
|
94
|
+
// -----------------------------------------------------------------------------
|
|
95
|
+
// Grammar: https://github.com/tree-sitter/tree-sitter-typescript
|
|
96
|
+
// The TypeScript grammar inherits most node types from JavaScript, so we
|
|
97
|
+
// extend the JS tables rather than re-declaring them from scratch.
|
|
98
|
+
const TYPESCRIPT = {
|
|
99
|
+
id: "typescript",
|
|
100
|
+
wasmName: "tree-sitter-typescript.wasm",
|
|
101
|
+
extensions: [".ts", ".tsx", ".mts", ".cts"],
|
|
102
|
+
functionNodeTypes: new Set([
|
|
103
|
+
...JAVASCRIPT.functionNodeTypes,
|
|
104
|
+
"function_signature",
|
|
105
|
+
"method_signature",
|
|
106
|
+
"abstract_method_signature",
|
|
107
|
+
]),
|
|
108
|
+
branchingNodeTypes: new Set([...JAVASCRIPT.branchingNodeTypes]),
|
|
109
|
+
booleanOperators: [...JAVASCRIPT.booleanOperators],
|
|
110
|
+
nameFieldCandidates: ["name"],
|
|
111
|
+
};
|
|
112
|
+
// -----------------------------------------------------------------------------
|
|
113
|
+
// Python
|
|
114
|
+
// -----------------------------------------------------------------------------
|
|
115
|
+
// Grammar: https://github.com/tree-sitter/tree-sitter-python
|
|
116
|
+
const PYTHON = {
|
|
117
|
+
id: "python",
|
|
118
|
+
wasmName: "tree-sitter-python.wasm",
|
|
119
|
+
extensions: [".py", ".pyi"],
|
|
120
|
+
functionNodeTypes: new Set(["function_definition", "lambda"]),
|
|
121
|
+
branchingNodeTypes: new Set([
|
|
122
|
+
"if_statement",
|
|
123
|
+
"elif_clause",
|
|
124
|
+
"else_clause",
|
|
125
|
+
"while_statement",
|
|
126
|
+
"for_statement",
|
|
127
|
+
"try_statement",
|
|
128
|
+
"except_clause",
|
|
129
|
+
"conditional_expression",
|
|
130
|
+
"match_statement",
|
|
131
|
+
"case_clause",
|
|
132
|
+
]),
|
|
133
|
+
booleanOperators: ["and", "or"],
|
|
134
|
+
nameFieldCandidates: ["name"],
|
|
135
|
+
};
|
|
136
|
+
// -----------------------------------------------------------------------------
|
|
137
|
+
// Java
|
|
138
|
+
// -----------------------------------------------------------------------------
|
|
139
|
+
// Grammar: https://github.com/tree-sitter/tree-sitter-java
|
|
140
|
+
const JAVA = {
|
|
141
|
+
id: "java",
|
|
142
|
+
wasmName: "tree-sitter-java.wasm",
|
|
143
|
+
extensions: [".java"],
|
|
144
|
+
functionNodeTypes: new Set([
|
|
145
|
+
"method_declaration",
|
|
146
|
+
"constructor_declaration",
|
|
147
|
+
"lambda_expression",
|
|
148
|
+
]),
|
|
149
|
+
branchingNodeTypes: new Set([
|
|
150
|
+
"if_statement",
|
|
151
|
+
"while_statement",
|
|
152
|
+
"do_statement",
|
|
153
|
+
"for_statement",
|
|
154
|
+
"enhanced_for_statement",
|
|
155
|
+
"switch_label",
|
|
156
|
+
"switch_rule",
|
|
157
|
+
"catch_clause",
|
|
158
|
+
"ternary_expression",
|
|
159
|
+
]),
|
|
160
|
+
booleanOperators: ["&&", "||"],
|
|
161
|
+
nameFieldCandidates: ["name"],
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Complete language table. Look up by {@link SupportedLanguage} identifier.
|
|
165
|
+
*/
|
|
166
|
+
export const LANGUAGE_TABLE = {
|
|
167
|
+
csharp: CSHARP,
|
|
168
|
+
javascript: JAVASCRIPT,
|
|
169
|
+
typescript: TYPESCRIPT,
|
|
170
|
+
python: PYTHON,
|
|
171
|
+
java: JAVA,
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Infer a {@link SupportedLanguage} from a file path by matching its
|
|
175
|
+
* extension. Returns `null` when no known language matches. Useful when
|
|
176
|
+
* the caller does not already know the language and wants the engine to
|
|
177
|
+
* pick one automatically.
|
|
178
|
+
*
|
|
179
|
+
* @param filePath File path (absolute or relative).
|
|
180
|
+
* @returns The detected language or `null`.
|
|
181
|
+
*/
|
|
182
|
+
export function detectLanguageFromPath(filePath) {
|
|
183
|
+
const lower = filePath.toLowerCase();
|
|
184
|
+
for (const config of Object.values(LANGUAGE_TABLE)) {
|
|
185
|
+
for (const ext of config.extensions) {
|
|
186
|
+
if (lower.endsWith(ext))
|
|
187
|
+
return config.id;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=language-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-config.js","sourceRoot":"","sources":["../../src/ast/language-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-sitter based AST analysis engine.
|
|
3
|
+
*
|
|
4
|
+
* This module wraps `web-tree-sitter` (the WASM build of tree-sitter) to
|
|
5
|
+
* parse source files and extract deterministic per-function metrics. The
|
|
6
|
+
* WASM variant is used instead of the native bindings so that `npm install`
|
|
7
|
+
* never has to invoke a C compiler — matching the plugin's "zero install
|
|
8
|
+
* friction" promise.
|
|
9
|
+
*
|
|
10
|
+
* The engine is lazy:
|
|
11
|
+
*
|
|
12
|
+
* - `web-tree-sitter` is initialized only on first use.
|
|
13
|
+
* - Grammar WASM files are loaded on demand and cached per language.
|
|
14
|
+
*
|
|
15
|
+
* This keeps MCP server startup fast (crucial because Claude Code will
|
|
16
|
+
* spin the server up and tear it down across sessions).
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* const engine = new TreeSitterEngine();
|
|
22
|
+
* const result = await engine.analyzeFile({
|
|
23
|
+
* filePath: "src/foo.ts",
|
|
24
|
+
* language: "typescript",
|
|
25
|
+
* });
|
|
26
|
+
* console.log(result.functions);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @module ast/tree-sitter-engine
|
|
30
|
+
*/
|
|
31
|
+
import { type SupportedLanguage } from "./language-config.js";
|
|
32
|
+
/**
|
|
33
|
+
* Per-function metrics returned by the engine.
|
|
34
|
+
*/
|
|
35
|
+
export interface FunctionMetrics {
|
|
36
|
+
/** Human-readable function name, or `"<anonymous>"` when not available. */
|
|
37
|
+
readonly name: string;
|
|
38
|
+
/** 1-based line where the function body starts. */
|
|
39
|
+
readonly startLine: number;
|
|
40
|
+
/** 1-based line where the function body ends. */
|
|
41
|
+
readonly endLine: number;
|
|
42
|
+
/** McCabe cyclomatic complexity (always ≥ 1). */
|
|
43
|
+
readonly cyclomaticComplexity: number;
|
|
44
|
+
/** Physical lines of code covered by the function (endLine - startLine + 1). */
|
|
45
|
+
readonly lineCount: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* File-level metrics returned by the engine.
|
|
49
|
+
*/
|
|
50
|
+
export interface FileMetrics {
|
|
51
|
+
/** File path that was analyzed, echoed from the request for traceability. */
|
|
52
|
+
readonly filePath: string;
|
|
53
|
+
/** Language the file was parsed as. */
|
|
54
|
+
readonly language: SupportedLanguage;
|
|
55
|
+
/** Total physical lines in the file, including blanks and comments. */
|
|
56
|
+
readonly physicalLoc: number;
|
|
57
|
+
/** Physical lines that contain at least one non-whitespace character. */
|
|
58
|
+
readonly logicalLoc: number;
|
|
59
|
+
/** Per-function metrics sorted by starting line. */
|
|
60
|
+
readonly functions: ReadonlyArray<FunctionMetrics>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Request accepted by {@link TreeSitterEngine.analyzeFile}.
|
|
64
|
+
*/
|
|
65
|
+
export interface AnalyzeFileRequest {
|
|
66
|
+
readonly filePath: string;
|
|
67
|
+
readonly language: SupportedLanguage;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Options accepted by the engine constructor. All fields are optional and
|
|
71
|
+
* safe defaults are used when omitted.
|
|
72
|
+
*/
|
|
73
|
+
export interface TreeSitterEngineOptions {
|
|
74
|
+
/**
|
|
75
|
+
* Directory where the language grammar WASM files live (one per
|
|
76
|
+
* language, e.g. `tree-sitter-typescript.wasm`). Defaults to the
|
|
77
|
+
* `tree-sitter-wasms/out` directory inside `node_modules`.
|
|
78
|
+
*/
|
|
79
|
+
readonly grammarsDir?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Directory where the `web-tree-sitter` runtime WASM (`tree-sitter.wasm`)
|
|
82
|
+
* lives. This is a different package from the grammars — the runtime
|
|
83
|
+
* ships with `web-tree-sitter` itself. Defaults to that package's
|
|
84
|
+
* install directory inside `node_modules`.
|
|
85
|
+
*/
|
|
86
|
+
readonly runtimeDir?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Override the WASM loader for tests. Receives the grammar filename
|
|
89
|
+
* and must return the raw bytes.
|
|
90
|
+
*/
|
|
91
|
+
readonly loadGrammar?: (wasmPath: string) => Promise<Uint8Array>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* High-level AST engine. Instances are meant to be long-lived — create
|
|
95
|
+
* one at server startup and reuse it for every analysis request.
|
|
96
|
+
*/
|
|
97
|
+
export declare class TreeSitterEngine {
|
|
98
|
+
private parserCtor;
|
|
99
|
+
private readonly loadedLanguages;
|
|
100
|
+
private readonly grammarsDir;
|
|
101
|
+
private readonly runtimeDir;
|
|
102
|
+
private readonly loadGrammar;
|
|
103
|
+
private initPromise;
|
|
104
|
+
constructor(options?: TreeSitterEngineOptions);
|
|
105
|
+
/**
|
|
106
|
+
* Analyze a source file and return per-function and file-level metrics.
|
|
107
|
+
*
|
|
108
|
+
* @param req The analysis request.
|
|
109
|
+
* @returns A {@link FileMetrics} snapshot ready to be serialized.
|
|
110
|
+
* @throws When the file cannot be read or the grammar cannot be loaded.
|
|
111
|
+
*/
|
|
112
|
+
analyzeFile(req: AnalyzeFileRequest): Promise<FileMetrics>;
|
|
113
|
+
/**
|
|
114
|
+
* Ensure a parser with the requested language grammar bound is ready.
|
|
115
|
+
* Both the Parser class and the grammar are initialized lazily and
|
|
116
|
+
* cached on first use.
|
|
117
|
+
*
|
|
118
|
+
* @param config Language configuration for the requested grammar.
|
|
119
|
+
* @returns A fresh parser instance configured for the language.
|
|
120
|
+
*/
|
|
121
|
+
private ensureParserFor;
|
|
122
|
+
/**
|
|
123
|
+
* Import and initialize `web-tree-sitter`. Isolated in its own method
|
|
124
|
+
* so the dynamic import runs exactly once per engine instance.
|
|
125
|
+
*
|
|
126
|
+
* `web-tree-sitter` uses `export = Parser` so under ESM interop the
|
|
127
|
+
* Parser class arrives on the `default` property of the imported
|
|
128
|
+
* namespace. `Parser.init()` is a STATIC method on the class, not a
|
|
129
|
+
* top-level module function.
|
|
130
|
+
*/
|
|
131
|
+
private initParserModule;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=tree-sitter-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-sitter-engine.d.ts","sourceRoot":"","sources":["../../src/ast/tree-sitter-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH,OAAO,EAAuC,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA2BnG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyC;IACzE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;IACxE,OAAO,CAAC,WAAW,CAA8B;gBAErC,OAAO,GAAE,uBAA4B;IAMjD;;;;;;OAMG;IACG,WAAW,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBhE;;;;;;;OAOG;YACW,eAAe;IAyB7B;;;;;;;;OAQG;YACW,gBAAgB;CAsB/B"}
|