clast-ai 0.1.2 → 0.2.1
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/.claude-plugin/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +11 -9
- package/README.md +468 -398
- package/bench/ab/onair-concept.json +22 -0
- package/bench/ab/onair-deadcode.json +7 -0
- package/bench/ab/onair-hard.json +32 -0
- package/bench/ab/onair-impact.json +17 -0
- package/bench/ab/onair-refactors.json +18 -0
- package/bench/ab/onair-survey.json +17 -0
- package/bench/ab/onair-tasks.json +20 -0
- package/bench/ab/onair.json +52 -0
- package/bench/ab/vscode-concept.json +22 -0
- package/bench/ab/vscode-hard.json +32 -0
- package/bench/ab/vscode-impact.json +17 -0
- package/bench/ab/vscode-refactors.json +18 -0
- package/bench/ab/vscode-tasks.json +20 -0
- package/bench/ab/vscode.json +52 -0
- package/bench/ab.mjs +213 -0
- package/bench/bench.mjs +98 -0
- package/bench/resolution.mjs +75 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +266 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/defaults.d.ts +12 -2
- package/dist/config/defaults.js +38 -31
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +26 -14
- package/dist/config/index.js.map +1 -1
- package/dist/db/index.d.ts +73 -13
- package/dist/db/index.js +481 -39
- package/dist/db/index.js.map +1 -1
- package/dist/engine.d.ts +15 -0
- package/dist/engine.js +28 -0
- package/dist/engine.js.map +1 -0
- package/dist/indexer/imports.d.ts +6 -0
- package/dist/indexer/imports.js +254 -0
- package/dist/indexer/imports.js.map +1 -0
- package/dist/indexer/index.d.ts +63 -0
- package/dist/indexer/index.js +360 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/process.d.ts +22 -0
- package/dist/indexer/process.js +42 -0
- package/dist/indexer/process.js.map +1 -0
- package/dist/indexer/scan.d.ts +43 -0
- package/dist/indexer/scan.js +223 -0
- package/dist/indexer/scan.js.map +1 -0
- package/dist/indexer/worker.d.ts +1 -0
- package/dist/indexer/worker.js +23 -0
- package/dist/indexer/worker.js.map +1 -0
- package/dist/llm/comment-generator.d.ts +17 -19
- package/dist/llm/comment-generator.js +46 -80
- package/dist/llm/comment-generator.js.map +1 -1
- package/dist/llm/index.d.ts +0 -1
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/prompts.d.ts +0 -1
- package/dist/llm/prompts.js +16 -16
- package/dist/migrate.d.ts +35 -0
- package/dist/migrate.js +194 -0
- package/dist/migrate.js.map +1 -0
- package/dist/parser/extractor.d.ts +21 -16
- package/dist/parser/extractor.js +700 -228
- package/dist/parser/extractor.js.map +1 -1
- package/dist/parser/index.d.ts +17 -21
- package/dist/parser/index.js +115 -171
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/langs/c.d.ts +3 -0
- package/dist/parser/langs/c.js +879 -0
- package/dist/parser/langs/c.js.map +1 -0
- package/dist/parser/langs/csharp.d.ts +2 -0
- package/dist/parser/langs/csharp.js +548 -0
- package/dist/parser/langs/csharp.js.map +1 -0
- package/dist/parser/langs/dart.d.ts +2 -0
- package/dist/parser/langs/dart.js +893 -0
- package/dist/parser/langs/dart.js.map +1 -0
- package/dist/parser/langs/go.d.ts +2 -0
- package/dist/parser/langs/go.js +455 -0
- package/dist/parser/langs/go.js.map +1 -0
- package/dist/parser/langs/java.d.ts +2 -0
- package/dist/parser/langs/java.js +390 -0
- package/dist/parser/langs/java.js.map +1 -0
- package/dist/parser/langs/php.d.ts +2 -0
- package/dist/parser/langs/php.js +486 -0
- package/dist/parser/langs/php.js.map +1 -0
- package/dist/parser/langs/python.d.ts +2 -0
- package/dist/parser/langs/python.js +216 -0
- package/dist/parser/langs/python.js.map +1 -0
- package/dist/parser/langs/ruby.d.ts +2 -0
- package/dist/parser/langs/ruby.js +602 -0
- package/dist/parser/langs/ruby.js.map +1 -0
- package/dist/parser/langs/rust.d.ts +2 -0
- package/dist/parser/langs/rust.js +931 -0
- package/dist/parser/langs/rust.js.map +1 -0
- package/dist/parser/langs/swift.d.ts +2 -0
- package/dist/parser/langs/swift.js +616 -0
- package/dist/parser/langs/swift.js.map +1 -0
- package/dist/parser/langs/typescript.d.ts +4 -0
- package/dist/parser/langs/typescript.js +535 -0
- package/dist/parser/langs/typescript.js.map +1 -0
- package/dist/parser/registry.d.ts +16 -0
- package/dist/parser/registry.js +87 -0
- package/dist/parser/registry.js.map +1 -0
- package/dist/parser/returns.d.ts +9 -0
- package/dist/parser/returns.js +152 -0
- package/dist/parser/returns.js.map +1 -0
- package/dist/parser/spec.d.ts +165 -0
- package/dist/parser/spec.js +188 -0
- package/dist/parser/spec.js.map +1 -0
- package/dist/query/arity.d.ts +27 -0
- package/dist/query/arity.js +187 -0
- package/dist/query/arity.js.map +1 -0
- package/dist/query/callgraph.d.ts +113 -0
- package/dist/query/callgraph.js +332 -0
- package/dist/query/callgraph.js.map +1 -0
- package/dist/query/format.d.ts +36 -0
- package/dist/query/format.js +136 -0
- package/dist/query/format.js.map +1 -0
- package/dist/query/hierarchy.d.ts +44 -0
- package/dist/query/hierarchy.js +441 -0
- package/dist/query/hierarchy.js.map +1 -0
- package/dist/query/resolve.d.ts +265 -0
- package/dist/query/resolve.js +1957 -0
- package/dist/query/resolve.js.map +1 -0
- package/dist/query/search.d.ts +35 -0
- package/dist/query/search.js +379 -0
- package/dist/query/search.js.map +1 -0
- package/dist/query/words.d.ts +30 -0
- package/dist/query/words.js +201 -0
- package/dist/query/words.js.map +1 -0
- package/dist/server/index.d.ts +1 -3
- package/dist/server/index.js +313 -73
- package/dist/server/index.js.map +1 -1
- package/dist/tools/context.d.ts +35 -0
- package/dist/tools/context.js +79 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/explore.d.ts +51 -0
- package/dist/tools/explore.js +779 -0
- package/dist/tools/explore.js.map +1 -0
- package/dist/tools/impact.d.ts +21 -0
- package/dist/tools/impact.js +743 -0
- package/dist/tools/impact.js.map +1 -0
- package/dist/tools/search.d.ts +59 -0
- package/dist/tools/search.js +843 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/stats.d.ts +26 -0
- package/dist/tools/stats.js +604 -0
- package/dist/tools/stats.js.map +1 -0
- package/dist/types.d.ts +95 -40
- package/dist/types.js +9 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/watcher/index.d.ts +18 -16
- package/dist/watcher/index.js +94 -77
- package/dist/watcher/index.js.map +1 -1
- package/package.json +21 -24
- package/plugin/server.mjs +72 -0
- package/skills/audit/SKILL.md +37 -0
- package/skills/deadcode/SKILL.md +33 -0
- package/skills/explore/SKILL.md +54 -0
- package/skills/impact/SKILL.md +24 -0
- package/skills/status/SKILL.md +11 -0
- package/src/cli.ts +265 -0
- package/src/config/defaults.ts +50 -32
- package/src/config/index.ts +23 -14
- package/src/db/index.ts +540 -43
- package/src/engine.ts +30 -0
- package/src/indexer/imports.ts +241 -0
- package/src/indexer/index.ts +369 -0
- package/src/indexer/process.ts +63 -0
- package/src/indexer/scan.ts +226 -0
- package/src/indexer/worker.ts +24 -0
- package/src/llm/comment-generator.ts +52 -103
- package/src/llm/index.ts +80 -80
- package/src/llm/prompts.ts +95 -95
- package/src/migrate.ts +213 -0
- package/src/parser/extractor.ts +643 -256
- package/src/parser/index.ts +105 -205
- package/src/parser/langs/c.ts +860 -0
- package/src/parser/langs/csharp.ts +519 -0
- package/src/parser/langs/dart.ts +820 -0
- package/src/parser/langs/go.ts +437 -0
- package/src/parser/langs/java.ts +361 -0
- package/src/parser/langs/php.ts +450 -0
- package/src/parser/langs/python.ts +206 -0
- package/src/parser/langs/ruby.ts +554 -0
- package/src/parser/langs/rust.ts +904 -0
- package/src/parser/langs/swift.ts +590 -0
- package/src/parser/langs/typescript.ts +499 -0
- package/src/parser/registry.ts +88 -0
- package/src/parser/returns.ts +137 -0
- package/src/parser/spec.ts +309 -0
- package/src/query/arity.ts +173 -0
- package/src/query/callgraph.ts +473 -0
- package/src/query/format.ts +136 -0
- package/src/query/hierarchy.ts +447 -0
- package/src/query/resolve.ts +1972 -0
- package/src/query/search.ts +430 -0
- package/src/query/words.ts +183 -0
- package/src/server/index.ts +390 -79
- package/src/tools/context.ts +82 -0
- package/src/tools/explore.ts +860 -0
- package/src/tools/impact.ts +748 -0
- package/src/tools/search.ts +886 -0
- package/src/tools/stats.ts +633 -0
- package/src/types.ts +113 -45
- package/src/version.ts +2 -0
- package/src/watcher/index.ts +82 -88
- package/tsconfig.json +6 -3
- package/.mcp.json +0 -8
- package/commands/clast-status.md +0 -9
- package/dist/config/defaults.d.ts.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/queries.d.ts +0 -44
- package/dist/db/queries.d.ts.map +0 -1
- package/dist/db/queries.js +0 -251
- package/dist/db/queries.js.map +0 -1
- package/dist/db/schema.d.ts +0 -3
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js +0 -94
- package/dist/db/schema.js.map +0 -1
- package/dist/db/types.d.ts +0 -44
- package/dist/db/types.d.ts.map +0 -1
- package/dist/db/types.js +0 -2
- package/dist/db/types.js.map +0 -1
- package/dist/llm/comment-generator.d.ts.map +0 -1
- package/dist/llm/index.d.ts.map +0 -1
- package/dist/llm/prompts.d.ts.map +0 -1
- package/dist/parser/call-resolver.d.ts +0 -15
- package/dist/parser/call-resolver.d.ts.map +0 -1
- package/dist/parser/call-resolver.js +0 -16
- package/dist/parser/call-resolver.js.map +0 -1
- package/dist/parser/extractor.d.ts.map +0 -1
- package/dist/parser/index.d.ts.map +0 -1
- package/dist/parser/languages.d.ts +0 -11
- package/dist/parser/languages.d.ts.map +0 -1
- package/dist/parser/languages.js +0 -74
- package/dist/parser/languages.js.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/register-tools.d.ts +0 -7
- package/dist/server/register-tools.d.ts.map +0 -1
- package/dist/server/register-tools.js +0 -17
- package/dist/server/register-tools.js.map +0 -1
- package/dist/server/tools/clast-call-graph.d.ts +0 -4
- package/dist/server/tools/clast-call-graph.d.ts.map +0 -1
- package/dist/server/tools/clast-call-graph.js +0 -70
- package/dist/server/tools/clast-call-graph.js.map +0 -1
- package/dist/server/tools/clast-comment.d.ts +0 -5
- package/dist/server/tools/clast-comment.d.ts.map +0 -1
- package/dist/server/tools/clast-comment.js +0 -64
- package/dist/server/tools/clast-comment.js.map +0 -1
- package/dist/server/tools/clast-file-summary.d.ts +0 -4
- package/dist/server/tools/clast-file-summary.d.ts.map +0 -1
- package/dist/server/tools/clast-file-summary.js +0 -42
- package/dist/server/tools/clast-file-summary.js.map +0 -1
- package/dist/server/tools/clast-get-context.d.ts +0 -4
- package/dist/server/tools/clast-get-context.d.ts.map +0 -1
- package/dist/server/tools/clast-get-context.js +0 -80
- package/dist/server/tools/clast-get-context.js.map +0 -1
- package/dist/server/tools/clast-reindex.d.ts +0 -5
- package/dist/server/tools/clast-reindex.d.ts.map +0 -1
- package/dist/server/tools/clast-reindex.js +0 -36
- package/dist/server/tools/clast-reindex.js.map +0 -1
- package/dist/server/tools/clast-search.d.ts +0 -4
- package/dist/server/tools/clast-search.d.ts.map +0 -1
- package/dist/server/tools/clast-search.js +0 -29
- package/dist/server/tools/clast-search.js.map +0 -1
- package/dist/server/tools/clast-status.d.ts +0 -5
- package/dist/server/tools/clast-status.d.ts.map +0 -1
- package/dist/server/tools/clast-status.js +0 -23
- package/dist/server/tools/clast-status.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/watcher/gitignore.d.ts +0 -9
- package/dist/watcher/gitignore.d.ts.map +0 -1
- package/dist/watcher/gitignore.js +0 -38
- package/dist/watcher/gitignore.js.map +0 -1
- package/dist/watcher/index.d.ts.map +0 -1
- package/skills/clast-explore/SKILL.md +0 -41
- package/src/db/queries.ts +0 -332
- package/src/db/schema.ts +0 -106
- package/src/db/types.ts +0 -47
- package/src/parser/call-resolver.ts +0 -17
- package/src/parser/languages.ts +0 -86
- package/src/server/register-tools.ts +0 -30
- package/src/server/tools/clast-call-graph.ts +0 -82
- package/src/server/tools/clast-comment.ts +0 -76
- package/src/server/tools/clast-file-summary.ts +0 -59
- package/src/server/tools/clast-get-context.ts +0 -97
- package/src/server/tools/clast-reindex.ts +0 -52
- package/src/server/tools/clast-search.ts +0 -38
- package/src/server/tools/clast-status.ts +0 -37
- package/src/watcher/gitignore.ts +0 -42
package/src/types.ts
CHANGED
|
@@ -1,69 +1,137 @@
|
|
|
1
|
-
|
|
1
|
+
/** Kinds of symbols stored in the index. */
|
|
2
|
+
export type SymbolKind =
|
|
2
3
|
| 'function'
|
|
3
4
|
| 'method'
|
|
4
5
|
| 'class'
|
|
5
6
|
| 'interface'
|
|
6
|
-
| 'enum'
|
|
7
|
-
| 'import'
|
|
8
|
-
| 'export'
|
|
9
|
-
| 'variable'
|
|
10
|
-
| 'type_alias'
|
|
11
7
|
| 'struct'
|
|
12
8
|
| 'trait'
|
|
13
|
-
| '
|
|
9
|
+
| 'enum'
|
|
10
|
+
| 'type'
|
|
11
|
+
| 'namespace'
|
|
12
|
+
| 'constant'
|
|
13
|
+
| 'variable'
|
|
14
|
+
| 'field'
|
|
15
|
+
| 'property'
|
|
16
|
+
| 'macro'
|
|
17
|
+
| 'declaration';
|
|
14
18
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
export const SYMBOL_KINDS: SymbolKind[] = [
|
|
20
|
+
'function', 'method', 'class', 'interface', 'struct', 'trait', 'enum', 'type',
|
|
21
|
+
'namespace', 'constant', 'variable', 'field', 'property', 'macro', 'declaration',
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/** Kinds that can contain members (used for outlines and qualified names). */
|
|
25
|
+
export const CONTAINER_KINDS = new Set<SymbolKind>([
|
|
26
|
+
'class', 'interface', 'struct', 'trait', 'enum', 'namespace',
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
export const CALLABLE_KINDS = new Set<SymbolKind>(['function', 'method', 'macro', 'declaration']);
|
|
30
|
+
|
|
31
|
+
/** A symbol as produced by the extractor (before it gets a database id). */
|
|
32
|
+
export interface ExSymbol {
|
|
18
33
|
name: string;
|
|
19
|
-
|
|
34
|
+
/** Dotted qualified name, e.g. "ParserManager.parseAndStore". */
|
|
35
|
+
qname: string;
|
|
36
|
+
kind: SymbolKind;
|
|
37
|
+
/** Declared return type (bare class name) of a function / method, when it could be read off the signature. */
|
|
38
|
+
ret: string | null;
|
|
20
39
|
signature: string;
|
|
40
|
+
doc: string;
|
|
41
|
+
/** 1-based line of the definition. */
|
|
21
42
|
startLine: number;
|
|
22
43
|
endLine: number;
|
|
23
44
|
startCol: number;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
/** 1-based first line of the leading doc comment / decorators, or 0. */
|
|
46
|
+
docLine: number;
|
|
47
|
+
/** Index of the parent symbol in the same extraction, or -1. */
|
|
48
|
+
parent: number;
|
|
49
|
+
exported: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ExCall {
|
|
53
|
+
/** Index of the calling symbol in the same extraction, or -1 for file level. */
|
|
54
|
+
caller: number;
|
|
55
|
+
name: string;
|
|
56
|
+
line: number;
|
|
57
|
+
/** Receiver text for member calls ("this", "self", "Foo", "db"), if simple. */
|
|
58
|
+
receiver: string | null;
|
|
59
|
+
/** Declared type of the receiver when a type hint was in scope (`Foo` for `x: Foo; x.bar()`). */
|
|
60
|
+
rtype: string | null;
|
|
61
|
+
/** Number of arguments at the call site; -1 when unknown (spread arguments, macros, no argument list). */
|
|
62
|
+
argc: number;
|
|
63
|
+
count: number;
|
|
64
|
+
/**
|
|
65
|
+
* For calls on an expression receiver that is itself a call
|
|
66
|
+
* (`a.b().c()`): index of that receiver-producing call in the same
|
|
67
|
+
* extraction, else -1. The receiver type is then that call's return type.
|
|
68
|
+
*/
|
|
69
|
+
via: number;
|
|
28
70
|
}
|
|
29
71
|
|
|
30
|
-
export interface
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
calleeId: number | null;
|
|
34
|
-
calleeName: string;
|
|
35
|
-
filePath: string;
|
|
72
|
+
export interface ExImport {
|
|
73
|
+
source: string;
|
|
74
|
+
names: string[];
|
|
36
75
|
line: number;
|
|
37
76
|
}
|
|
38
77
|
|
|
39
|
-
export interface
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
78
|
+
export interface ExHeritage {
|
|
79
|
+
symbol: number;
|
|
80
|
+
name: string;
|
|
81
|
+
/** Module / namespace the supertype was written with (`forms` in `forms.CharField`), if any. */
|
|
82
|
+
qualifier: string | null;
|
|
83
|
+
kind: 'extends' | 'implements';
|
|
84
|
+
/** Number of type arguments the supertype was written with (`Base<T>` -> 1); tells `Foo` from `Foo<T>` in C#. */
|
|
85
|
+
arity: number;
|
|
45
86
|
}
|
|
46
87
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
88
|
+
/** Everything extracted from a single source file. */
|
|
89
|
+
export interface Extraction {
|
|
90
|
+
lang: string;
|
|
91
|
+
lineCount: number;
|
|
92
|
+
symbols: ExSymbol[];
|
|
93
|
+
calls: ExCall[];
|
|
94
|
+
imports: ExImport[];
|
|
95
|
+
heritage: ExHeritage[];
|
|
96
|
+
/** Name of the symbol exported as the module default (`module.exports = X`), if any. */
|
|
97
|
+
defaultExport: string | null;
|
|
98
|
+
/** Declared field types of class-like symbols: [container, field, type]. */
|
|
99
|
+
fieldTypes: Array<[string, string, string]>;
|
|
100
|
+
/** Identifier occurrences: [name, "12,40,41"] (1-based lines, capped per file). */
|
|
101
|
+
occ: Array<[string, string]>;
|
|
102
|
+
hadError: boolean;
|
|
53
103
|
}
|
|
54
104
|
|
|
55
|
-
export interface
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
105
|
+
export interface SymbolRow {
|
|
106
|
+
id: number;
|
|
107
|
+
file_id: number;
|
|
108
|
+
name: string;
|
|
109
|
+
name_lc: string;
|
|
110
|
+
qname: string;
|
|
111
|
+
kind: SymbolKind;
|
|
112
|
+
signature: string;
|
|
113
|
+
doc: string;
|
|
114
|
+
start_line: number;
|
|
115
|
+
end_line: number;
|
|
116
|
+
start_col: number;
|
|
117
|
+
doc_line: number;
|
|
118
|
+
parent_id: number | null;
|
|
119
|
+
exported: number;
|
|
120
|
+
/** Declared return type name, if known. */
|
|
121
|
+
ret: string | null;
|
|
122
|
+
/** Joined from files. */
|
|
123
|
+
path: string;
|
|
124
|
+
lang: string;
|
|
59
125
|
}
|
|
60
126
|
|
|
61
|
-
export interface
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
127
|
+
export interface FileRow {
|
|
128
|
+
id: number;
|
|
129
|
+
path: string;
|
|
130
|
+
hash: string;
|
|
131
|
+
mtime: number;
|
|
132
|
+
size: number;
|
|
133
|
+
lang: string;
|
|
134
|
+
line_count: number;
|
|
135
|
+
symbol_count: number;
|
|
136
|
+
indexed_at: number;
|
|
69
137
|
}
|
package/src/version.ts
ADDED
package/src/watcher/index.ts
CHANGED
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
import { watch, type FSWatcher } from 'chokidar';
|
|
2
|
-
import {
|
|
2
|
+
import { basename, relative, sep } from 'node:path';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
|
-
import {
|
|
5
|
-
import { buildIgnorePatterns } from './gitignore.js';
|
|
6
|
-
import type { ParserManager } from '../parser/index.js';
|
|
7
|
-
import type { ClastDatabase } from '../db/index.js';
|
|
8
|
-
import type { ClastConfig } from '../config/index.js';
|
|
4
|
+
import type { Indexer } from '../indexer/index.js';
|
|
9
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Watches the project and keeps the index current. Events are debounced per
|
|
8
|
+
* file and processed strictly one at a time (the parser and database are not
|
|
9
|
+
* re-entrant).
|
|
10
|
+
*/
|
|
10
11
|
export class FileWatcher extends EventEmitter {
|
|
11
12
|
private watcher: FSWatcher | null = null;
|
|
12
|
-
private
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
|
17
|
-
private _pendingCount = 0;
|
|
18
|
-
private supportedExts: Set<string>;
|
|
13
|
+
private timers = new Map<string, ReturnType<typeof setTimeout>>();
|
|
14
|
+
private queue: Array<{ rel: string; kind: 'change' | 'unlink' }> = [];
|
|
15
|
+
private draining = false;
|
|
16
|
+
private rescanTimer: ReturnType<typeof setTimeout> | null = null;
|
|
19
17
|
|
|
20
18
|
constructor(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
db: ClastDatabase,
|
|
24
|
-
parser: ParserManager
|
|
19
|
+
private readonly indexer: Indexer,
|
|
20
|
+
private readonly debounceMs: number
|
|
25
21
|
) {
|
|
26
22
|
super();
|
|
27
|
-
this.projectRoot = projectRoot;
|
|
28
|
-
this.config = config;
|
|
29
|
-
this.db = db;
|
|
30
|
-
this.parser = parser;
|
|
31
|
-
this.supportedExts = new Set(getSupportedExtensions(config.languages));
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
get isActive(): boolean {
|
|
@@ -36,96 +27,99 @@ export class FileWatcher extends EventEmitter {
|
|
|
36
27
|
}
|
|
37
28
|
|
|
38
29
|
get pendingCount(): number {
|
|
39
|
-
return this.
|
|
30
|
+
return this.timers.size + this.queue.length;
|
|
40
31
|
}
|
|
41
32
|
|
|
42
33
|
start(): void {
|
|
43
34
|
if (this.watcher) return;
|
|
44
|
-
|
|
35
|
+
const root = this.indexer.root;
|
|
36
|
+
const rules = this.indexer.rules;
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.watcher = watch(this.projectRoot, {
|
|
49
|
-
ignored: [
|
|
50
|
-
/(^|[/\\])\./,
|
|
51
|
-
...ignoredPatterns.map(p => {
|
|
52
|
-
if (!p.includes('*') && !p.includes('/')) {
|
|
53
|
-
return `**/${p}/**`;
|
|
54
|
-
}
|
|
55
|
-
return p;
|
|
56
|
-
}),
|
|
57
|
-
],
|
|
38
|
+
this.watcher = watch(root, {
|
|
58
39
|
persistent: true,
|
|
59
40
|
ignoreInitial: true,
|
|
41
|
+
followSymlinks: false,
|
|
42
|
+
awaitWriteFinish: false,
|
|
43
|
+
// Prune ignored directories early so huge trees (node_modules, build
|
|
44
|
+
// output) are never even watched.
|
|
45
|
+
ignored: (path: string, stats?: { isDirectory(): boolean; isFile(): boolean }) => {
|
|
46
|
+
const rel = relative(root, path).split(sep).join('/');
|
|
47
|
+
if (!rel || rel.startsWith('..')) return false;
|
|
48
|
+
const name = basename(path);
|
|
49
|
+
if (name === '.gitignore') return false;
|
|
50
|
+
if (stats?.isFile()) return !rules.isSupported(rel) || rules.isIgnored(rel);
|
|
51
|
+
if (stats?.isDirectory()) return name.startsWith('.') || rules.isIgnored(rel + '/x');
|
|
52
|
+
return false;
|
|
53
|
+
},
|
|
60
54
|
});
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
this.watcher.on('
|
|
64
|
-
this.watcher.on('
|
|
56
|
+
const toRel = (p: string): string => relative(root, p).split(sep).join('/');
|
|
57
|
+
this.watcher.on('add', p => this.schedule(toRel(p), 'change'));
|
|
58
|
+
this.watcher.on('change', p => this.schedule(toRel(p), 'change'));
|
|
59
|
+
this.watcher.on('unlink', p => this.schedule(toRel(p), 'unlink'));
|
|
60
|
+
this.watcher.on('unlinkDir', () => this.scheduleRescan());
|
|
65
61
|
this.watcher.on('error', err => {
|
|
66
|
-
|
|
62
|
+
this.emit('error', { filePath: '', error: err as Error });
|
|
67
63
|
});
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
stop(): void {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this.debounceTimers.clear();
|
|
77
|
-
|
|
78
|
-
this.watcher.close();
|
|
66
|
+
async stop(): Promise<void> {
|
|
67
|
+
for (const t of this.timers.values()) clearTimeout(t);
|
|
68
|
+
this.timers.clear();
|
|
69
|
+
if (this.rescanTimer) clearTimeout(this.rescanTimer);
|
|
70
|
+
this.queue = [];
|
|
71
|
+
const w = this.watcher;
|
|
79
72
|
this.watcher = null;
|
|
73
|
+
if (w) await w.close();
|
|
80
74
|
}
|
|
81
75
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (
|
|
76
|
+
/** A changed .gitignore or a removed directory affects many files: rescan. */
|
|
77
|
+
private scheduleRescan(): void {
|
|
78
|
+
if (this.rescanTimer) clearTimeout(this.rescanTimer);
|
|
79
|
+
this.rescanTimer = setTimeout(() => {
|
|
80
|
+
this.rescanTimer = null;
|
|
81
|
+
this.indexer.indexAll().catch(err => this.emit('error', { filePath: '', error: err as Error }));
|
|
82
|
+
}, Math.max(this.debounceMs, 500));
|
|
83
|
+
}
|
|
85
84
|
|
|
86
|
-
|
|
85
|
+
private schedule(rel: string, kind: 'change' | 'unlink'): void {
|
|
86
|
+
if (basename(rel) === '.gitignore') {
|
|
87
|
+
this.scheduleRescan();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!this.indexer.rules.isSupported(rel)) return;
|
|
91
|
+
const existing = this.timers.get(rel);
|
|
87
92
|
if (existing) clearTimeout(existing);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.debounceTimers.set(
|
|
91
|
-
filePath,
|
|
93
|
+
this.timers.set(
|
|
94
|
+
rel,
|
|
92
95
|
setTimeout(() => {
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
}, this.
|
|
96
|
+
this.timers.delete(rel);
|
|
97
|
+
this.queue.push({ rel, kind });
|
|
98
|
+
void this.drain();
|
|
99
|
+
}, this.debounceMs)
|
|
97
100
|
);
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
private
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const existing = this.debounceTimers.get(filePath);
|
|
105
|
-
if (existing) {
|
|
106
|
-
clearTimeout(existing);
|
|
107
|
-
this.debounceTimers.delete(filePath);
|
|
108
|
-
this._pendingCount--;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
this.parser.removeFile(filePath, this.projectRoot, this.db);
|
|
113
|
-
this.emit('deleted', { filePath });
|
|
114
|
-
} catch (err) {
|
|
115
|
-
this.emit('error', { filePath, error: err as Error });
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private async processFile(filePath: string): Promise<void> {
|
|
103
|
+
private async drain(): Promise<void> {
|
|
104
|
+
if (this.draining) return;
|
|
105
|
+
this.draining = true;
|
|
120
106
|
try {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
107
|
+
// Let a bulk index finish first; it will pick up these files anyway.
|
|
108
|
+
await this.indexer.whenIdle();
|
|
109
|
+
while (this.queue.length) {
|
|
110
|
+
const { rel, kind } = this.queue.shift()!;
|
|
111
|
+
try {
|
|
112
|
+
if (kind === 'unlink') {
|
|
113
|
+
if (this.indexer.removeFile(rel)) this.emit('deleted', { filePath: rel });
|
|
114
|
+
} else if (await this.indexer.indexFile(rel)) {
|
|
115
|
+
this.emit('indexed', { filePath: rel });
|
|
116
|
+
}
|
|
117
|
+
} catch (err) {
|
|
118
|
+
this.emit('error', { filePath: rel, error: err as Error });
|
|
119
|
+
}
|
|
126
120
|
}
|
|
127
|
-
}
|
|
128
|
-
this.
|
|
121
|
+
} finally {
|
|
122
|
+
this.draining = false;
|
|
129
123
|
}
|
|
130
124
|
}
|
|
131
125
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
3
|
+
"target": "ES2023",
|
|
4
4
|
"module": "NodeNext",
|
|
5
5
|
"moduleResolution": "NodeNext",
|
|
6
|
-
"lib": ["
|
|
6
|
+
"lib": ["ES2023"],
|
|
7
|
+
"types": ["node"],
|
|
7
8
|
"outDir": "dist",
|
|
8
9
|
"rootDir": "src",
|
|
9
10
|
"strict": true,
|
|
11
|
+
"noUncheckedIndexedAccess": true,
|
|
12
|
+
"noUnusedLocals": true,
|
|
13
|
+
"noUnusedParameters": true,
|
|
10
14
|
"esModuleInterop": true,
|
|
11
15
|
"skipLibCheck": true,
|
|
12
16
|
"forceConsistentCasingInFileNames": true,
|
|
13
17
|
"resolveJsonModule": true,
|
|
14
18
|
"declaration": true,
|
|
15
|
-
"declarationMap": true,
|
|
16
19
|
"sourceMap": true
|
|
17
20
|
},
|
|
18
21
|
"include": ["src/**/*.ts"],
|
package/.mcp.json
DELETED
package/commands/clast-status.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: clast-status
|
|
3
|
-
description: Show Clast AST indexing status for the current repository
|
|
4
|
-
allowed-tools: [clast_status]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Call the `clast_status` tool and present the results to the user in a clear, readable format.
|
|
8
|
-
Include: files indexed, total symbols, total call edges, total comments, last indexed time,
|
|
9
|
-
watcher status, and any pending files.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,WA0C5B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAwBjE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAkB3D;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAK9E"}
|
package/dist/db/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAA+C;IACzD,OAAO,EAAE,OAAO,CAAC;IAExB,OAAO;WAUM,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAgBzD,IAAI,IAAI,IAAI;IASZ,KAAK,IAAI,IAAI;IASb,IAAI,GAAG,IAAI,QAAQ,CAElB;CACF;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/db/queries.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Database } from 'sql.js';
|
|
2
|
-
import type { FileRow, AstNodeRow, CallEdgeRow, CommentRow, StatusRow } from './types.js';
|
|
3
|
-
export declare class Queries {
|
|
4
|
-
private db;
|
|
5
|
-
constructor(db: Database);
|
|
6
|
-
private run;
|
|
7
|
-
private get;
|
|
8
|
-
private all;
|
|
9
|
-
private getLastInsertId;
|
|
10
|
-
upsertFile(filePath: string, hash: string, language: string, nodeCount: number): void;
|
|
11
|
-
deleteFile(filePath: string): void;
|
|
12
|
-
getFileHash(filePath: string): string | null;
|
|
13
|
-
getAllFiles(): FileRow[];
|
|
14
|
-
insertNode(node: Omit<AstNodeRow, 'id'>): number;
|
|
15
|
-
insertNodes(nodes: Omit<AstNodeRow, 'id'>[]): number[];
|
|
16
|
-
getNodeById(id: number): AstNodeRow | undefined;
|
|
17
|
-
getNodeByName(name: string): AstNodeRow[];
|
|
18
|
-
getNodesByFile(filePath: string): AstNodeRow[];
|
|
19
|
-
searchNodes(query: string, type?: string, limit?: number): AstNodeRow[];
|
|
20
|
-
insertEdge(edge: Omit<CallEdgeRow, 'id'>): number;
|
|
21
|
-
insertEdges(edges: Omit<CallEdgeRow, 'id'>[]): void;
|
|
22
|
-
getCallersOf(nameOrId: string | number, depth?: number): AstNodeRow[];
|
|
23
|
-
getCalleesOf(nameOrId: string | number, depth?: number): AstNodeRow[];
|
|
24
|
-
getCallEdgesForNode(nodeId: number): {
|
|
25
|
-
outgoing: CallEdgeRow[];
|
|
26
|
-
incoming: CallEdgeRow[];
|
|
27
|
-
};
|
|
28
|
-
insertComment(nodeId: number, text: string, source: 'original' | 'generated'): number;
|
|
29
|
-
getCommentsForNode(nodeId: number): CommentRow[];
|
|
30
|
-
deleteCommentsBySource(nodeId: number, source: 'original' | 'generated'): void;
|
|
31
|
-
getNodeWithContext(name: string): {
|
|
32
|
-
nodes: AstNodeRow[];
|
|
33
|
-
comments: CommentRow[];
|
|
34
|
-
callers: AstNodeRow[];
|
|
35
|
-
callees: AstNodeRow[];
|
|
36
|
-
};
|
|
37
|
-
getStatus(): StatusRow;
|
|
38
|
-
deleteNodesForFile(filePath: string): void;
|
|
39
|
-
resolveEdges(): number;
|
|
40
|
-
getNodesWithoutComments(limit?: number): AstNodeRow[];
|
|
41
|
-
/** Flush the in-memory database to a Uint8Array for saving to disk. */
|
|
42
|
-
export(): Uint8Array;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=queries.d.ts.map
|
package/dist/db/queries.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1F,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAW;gBAET,EAAE,EAAE,QAAQ;IAIxB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,GAAG;IAYX,OAAO,CAAC,GAAG;IAaX,OAAO,CAAC,eAAe;IAUvB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQrF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASlC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK5C,WAAW,IAAI,OAAO,EAAE;IAMxB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM;IAahD,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE;IAetD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI/C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE;IAOzC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAO9C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,UAAU,EAAE;IAgB3E,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,MAAM;IASjD,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI;IAanD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,UAAU,EAAE;IAuBxE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,UAAU,EAAE;IAyBxE,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE;IAczF,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM;IASrF,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAIhD,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAM9E,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;QAChC,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,CAAC;QACtB,OAAO,EAAE,UAAU,EAAE,CAAC;KACvB;IAmBD,SAAS,IAAI,SAAS;IAoBtB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM1C,YAAY,IAAI,MAAM;IAyBtB,uBAAuB,CAAC,KAAK,GAAE,MAAY,GAAG,UAAU,EAAE;IAU1D,uEAAuE;IACvE,MAAM,IAAI,UAAU;CAGrB"}
|