@claudiu.ceia/astkit 0.1.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 +21 -0
- package/README.md +393 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/src/app.d.ts +1 -0
- package/dist/src/app.js +41 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +4 -0
- package/dist/src/code-rank/code-rank.d.ts +9 -0
- package/dist/src/code-rank/code-rank.js +71 -0
- package/dist/src/code-rank/index.d.ts +1 -0
- package/dist/src/code-rank/index.js +1 -0
- package/dist/src/code-rank/rank.d.ts +29 -0
- package/dist/src/code-rank/rank.js +185 -0
- package/dist/src/common/input.d.ts +5 -0
- package/dist/src/common/input.js +25 -0
- package/dist/src/nav/declarations.d.ts +19 -0
- package/dist/src/nav/declarations.js +106 -0
- package/dist/src/nav/definition.d.ts +14 -0
- package/dist/src/nav/definition.js +62 -0
- package/dist/src/nav/location.d.ts +6 -0
- package/dist/src/nav/location.js +35 -0
- package/dist/src/nav/references.d.ts +19 -0
- package/dist/src/nav/references.js +75 -0
- package/dist/src/patch/patch.d.ts +27 -0
- package/dist/src/patch/patch.js +345 -0
- package/dist/src/pattern/balance.d.ts +1 -0
- package/dist/src/pattern/balance.js +25 -0
- package/dist/src/pattern/index.d.ts +5 -0
- package/dist/src/pattern/index.js +4 -0
- package/dist/src/pattern/match.d.ts +2 -0
- package/dist/src/pattern/match.js +141 -0
- package/dist/src/pattern/render.d.ts +1 -0
- package/dist/src/pattern/render.js +32 -0
- package/dist/src/pattern/syntax.d.ts +3 -0
- package/dist/src/pattern/syntax.js +87 -0
- package/dist/src/pattern/types.d.ts +27 -0
- package/dist/src/pattern/types.js +1 -0
- package/dist/src/search/search.d.ts +16 -0
- package/dist/src/search/search.js +207 -0
- package/dist/src/service.d.ts +16 -0
- package/dist/src/service.js +72 -0
- package/dist/src/sgrep/index.d.ts +5 -0
- package/dist/src/sgrep/index.js +3 -0
- package/dist/src/sgrep/isomorphisms/expand.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/expand.js +51 -0
- package/dist/src/sgrep/isomorphisms/index.d.ts +3 -0
- package/dist/src/sgrep/isomorphisms/index.js +2 -0
- package/dist/src/sgrep/isomorphisms/registry.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/registry.js +8 -0
- package/dist/src/sgrep/isomorphisms/rules/commutative-binary.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/rules/commutative-binary.js +51 -0
- package/dist/src/sgrep/isomorphisms/rules/object-literal-property-order.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/rules/object-literal-property-order.js +82 -0
- package/dist/src/sgrep/isomorphisms/rules/redundant-parentheses.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/rules/redundant-parentheses.js +43 -0
- package/dist/src/sgrep/isomorphisms/template-ast.d.ts +2 -0
- package/dist/src/sgrep/isomorphisms/template-ast.js +59 -0
- package/dist/src/sgrep/isomorphisms/types.d.ts +15 -0
- package/dist/src/sgrep/isomorphisms/types.js +0 -0
- package/dist/src/sgrep/phases/output.d.ts +9 -0
- package/dist/src/sgrep/phases/output.js +11 -0
- package/dist/src/sgrep/phases/parse.d.ts +10 -0
- package/dist/src/sgrep/phases/parse.js +11 -0
- package/dist/src/sgrep/phases/search.d.ts +11 -0
- package/dist/src/sgrep/phases/search.js +111 -0
- package/dist/src/sgrep/sgrep.d.ts +3 -0
- package/dist/src/sgrep/sgrep.js +17 -0
- package/dist/src/sgrep/types.d.ts +32 -0
- package/dist/src/sgrep/types.js +3 -0
- package/dist/src/spatch/files.d.ts +7 -0
- package/dist/src/spatch/files.js +51 -0
- package/dist/src/spatch/index.d.ts +3 -0
- package/dist/src/spatch/index.js +2 -0
- package/dist/src/spatch/patch-document.d.ts +9 -0
- package/dist/src/spatch/patch-document.js +64 -0
- package/dist/src/spatch/phases/output.d.ts +9 -0
- package/dist/src/spatch/phases/output.js +15 -0
- package/dist/src/spatch/phases/parse.d.ts +11 -0
- package/dist/src/spatch/phases/parse.js +16 -0
- package/dist/src/spatch/phases/rewrite.d.ts +14 -0
- package/dist/src/spatch/phases/rewrite.js +111 -0
- package/dist/src/spatch/spatch.d.ts +3 -0
- package/dist/src/spatch/spatch.js +17 -0
- package/dist/src/spatch/template.d.ts +2 -0
- package/dist/src/spatch/template.js +1 -0
- package/dist/src/spatch/text.d.ts +5 -0
- package/dist/src/spatch/text.js +35 -0
- package/dist/src/spatch/types.d.ts +40 -0
- package/dist/src/spatch/types.js +20 -0
- package/package.json +66 -0
- package/skills/astkit-tooling/SKILL.md +101 -0
- package/skills/astkit-tooling/agents/openai.yaml +4 -0
- package/skills/astkit-tooling/references/cognitive-model.md +61 -0
- package/skills/astkit-tooling/references/non-goals.md +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Claudiu Ceia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# astkit
|
|
2
|
+
|
|
3
|
+
`astkit` is a CLI for structural code inspection and navigation in TypeScript/JavaScript projects.
|
|
4
|
+
It operates on AST structure, TypeScript type services, and reference graphs, and is designed for token-efficient workflows used by LLM agents and senior engineers.
|
|
5
|
+
|
|
6
|
+
## What astkit provides
|
|
7
|
+
|
|
8
|
+
- Definition and reference navigation via the TypeScript language service
|
|
9
|
+
- Structural search and rewrite using AST-shaped patterns
|
|
10
|
+
- Reference-based symbol ranking as an impact heuristic
|
|
11
|
+
|
|
12
|
+
## Non-Goals
|
|
13
|
+
|
|
14
|
+
`astkit` does not:
|
|
15
|
+
- infer program intent or meaning
|
|
16
|
+
- perform whole-program flow analysis
|
|
17
|
+
- prove correctness or enforce architecture
|
|
18
|
+
- replace the TypeScript compiler or type checker
|
|
19
|
+
- make decisions automatically
|
|
20
|
+
- guarantee behavioral equivalence after rewrites
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install --save-dev @claudiu.ceia/astkit typescript
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`astkit` uses the project's `typescript` installation for type services.
|
|
29
|
+
|
|
30
|
+
## Run
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @claudiu.ceia/astkit <command> [args]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or via the bin entry:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
astkit <command> [args]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Install Skill (Codex)
|
|
43
|
+
|
|
44
|
+
From an installed npm package:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx skills add ./node_modules/@claudiu.ceia/astkit/skills/astkit-tooling -a codex
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
From this repository:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm run skill:install
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## CLI Reference
|
|
57
|
+
|
|
58
|
+
General help:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
astkit --help
|
|
62
|
+
astkit <command> --help
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Full command surface:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
astkit nav declarations <file>
|
|
69
|
+
astkit nav definition <location>
|
|
70
|
+
astkit nav references <location>
|
|
71
|
+
astkit search [--json] [--no-color] [--no-isomorphisms] [--cwd <path>] <pattern-input> [scope]
|
|
72
|
+
astkit patch [--interactive] [--json] [--no-color] [--dry-run] [--cwd <path>] <patch-input> [scope]
|
|
73
|
+
astkit code-rank [--json] [--limit <n>] [--cwd <path>] [scope]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `nav`
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
astkit nav declarations <file>
|
|
80
|
+
astkit nav definition <location>
|
|
81
|
+
astkit nav references <location>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`<location>` format:
|
|
85
|
+
- `path/to/file.ts:120:17`
|
|
86
|
+
|
|
87
|
+
Line and character are 1-indexed.
|
|
88
|
+
|
|
89
|
+
Mock execution:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
$ astkit nav declarations src/__tests__/fixtures/simple.ts
|
|
93
|
+
{
|
|
94
|
+
"file": "src/__tests__/fixtures/simple.ts",
|
|
95
|
+
"declarations": [
|
|
96
|
+
{
|
|
97
|
+
"name": "User",
|
|
98
|
+
"kind": "interface",
|
|
99
|
+
"signature": "User",
|
|
100
|
+
"line": 1
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "UserService",
|
|
104
|
+
"kind": "class",
|
|
105
|
+
"signature": "UserService",
|
|
106
|
+
"line": 7
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
$ astkit nav definition src/__tests__/fixtures/importer.ts:1:15
|
|
112
|
+
{
|
|
113
|
+
"symbol": "User",
|
|
114
|
+
"definitions": [
|
|
115
|
+
{
|
|
116
|
+
"file": "src/__tests__/fixtures/simple.ts",
|
|
117
|
+
"line": 1,
|
|
118
|
+
"character": 18,
|
|
119
|
+
"kind": "interface",
|
|
120
|
+
"containerName": "\".../simple\""
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
$ astkit nav references src/__tests__/fixtures/simple.ts:1:18
|
|
126
|
+
{
|
|
127
|
+
"symbol": "interface User",
|
|
128
|
+
"definition": {
|
|
129
|
+
"file": "src/__tests__/fixtures/simple.ts",
|
|
130
|
+
"line": 1,
|
|
131
|
+
"character": 18
|
|
132
|
+
},
|
|
133
|
+
"references": [
|
|
134
|
+
{
|
|
135
|
+
"file": "src/__tests__/fixtures/simple.ts",
|
|
136
|
+
"line": 1,
|
|
137
|
+
"character": 18,
|
|
138
|
+
"isDefinition": true,
|
|
139
|
+
"isWriteAccess": true
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"file": "src/__tests__/fixtures/importer.ts",
|
|
143
|
+
"line": 1,
|
|
144
|
+
"character": 15,
|
|
145
|
+
"isDefinition": false,
|
|
146
|
+
"isWriteAccess": true
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### `search` (`sgrep`)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
astkit search <pattern-input> [scope] [--cwd <path>] [--no-color] [--no-isomorphisms] [--json]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- Default output is compact, file-grouped text
|
|
159
|
+
- In interactive terminals, captures are colorized
|
|
160
|
+
- `--no-color` disables coloring
|
|
161
|
+
- Isomorphism expansion is enabled by default (commutative binary operators, object-literal key order, redundant parentheses)
|
|
162
|
+
- `--no-isomorphisms` disables isomorphism expansion
|
|
163
|
+
- `--json` prints structured result
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# inline pattern
|
|
169
|
+
astkit search 'const :[name] = :[value];' src
|
|
170
|
+
|
|
171
|
+
# pattern loaded from file
|
|
172
|
+
astkit search rules/find-const.sgrep src --cwd /repo
|
|
173
|
+
|
|
174
|
+
# machine output
|
|
175
|
+
astkit search --json 'const :[name] = :[value];' src
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Mock execution:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
$ astkit search 'const :[name] = :[value];' src
|
|
182
|
+
//src/example.ts
|
|
183
|
+
12: const foo = 42;
|
|
184
|
+
27: const bar = makeValue( ...
|
|
185
|
+
|
|
186
|
+
$ astkit search --json 'const :[name] = :[value];' src
|
|
187
|
+
{
|
|
188
|
+
"scope": "/repo/src",
|
|
189
|
+
"pattern": "const :[name] = :[value];",
|
|
190
|
+
"filesScanned": 24,
|
|
191
|
+
"filesMatched": 2,
|
|
192
|
+
"totalMatches": 3,
|
|
193
|
+
"files": [
|
|
194
|
+
{
|
|
195
|
+
"file": "src/example.ts",
|
|
196
|
+
"matchCount": 2,
|
|
197
|
+
"matches": [
|
|
198
|
+
{
|
|
199
|
+
"line": 12,
|
|
200
|
+
"character": 1,
|
|
201
|
+
"matched": "const foo = 42;",
|
|
202
|
+
"captures": {
|
|
203
|
+
"name": "foo",
|
|
204
|
+
"value": "42"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### `patch` (`spatch`)
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
astkit patch <patch-input> [scope] [--cwd <path>] [--dry-run] [--json] [--no-color] [--interactive]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
- `patch-input` can be inline patch text or a file path
|
|
220
|
+
- Patch format uses `+`/`-`/context lines in one document
|
|
221
|
+
- Default output is compact diff-style text
|
|
222
|
+
- `--json` prints structured output
|
|
223
|
+
- `--no-color` disables color in compact output
|
|
224
|
+
- `--interactive` lets you accept/reject each match
|
|
225
|
+
|
|
226
|
+
Example:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
astkit patch $'-const :[name] = :[value];\n+let :[name] = :[value];' src
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Mock execution:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
$ astkit patch --dry-run $'-const :[name] = :[value];\n+let :[name] = :[value];' src
|
|
236
|
+
diff --git a/src/example.ts b/src/example.ts
|
|
237
|
+
--- a/src/example.ts
|
|
238
|
+
+++ b/src/example.ts
|
|
239
|
+
@@ -12,1 +12,1 @@
|
|
240
|
+
-const foo = 42;
|
|
241
|
+
+let foo = 42;
|
|
242
|
+
1 file changed, 1 replacement, (dry-run)
|
|
243
|
+
|
|
244
|
+
$ astkit patch --interactive $'-const :[name] = :[value];\n+let :[name] = :[value];' src
|
|
245
|
+
------------------------------------------------------------------------
|
|
246
|
+
Change 1/2: src/example.ts:12
|
|
247
|
+
@@ -12,1 +12,1 @@
|
|
248
|
+
-const foo = 42;
|
|
249
|
+
+let foo = 42;
|
|
250
|
+
Choice [y/n/a/q] (default: n): y
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### `code-rank`
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
astkit code-rank [scope] [--cwd <path>] [--limit <n>] [--json]
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- Ranks exported symbols by TypeScript reference strength
|
|
260
|
+
- Uses the TypeScript language service (`findReferences`)
|
|
261
|
+
- Default output is compact, one symbol per line
|
|
262
|
+
- `--json` prints structured output
|
|
263
|
+
|
|
264
|
+
Example:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
astkit code-rank src --limit 20
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Mock execution:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
$ astkit code-rank src --limit 3
|
|
274
|
+
1. score=14 refs=3 ext=3 files=2 function hot src/a.ts:1:8
|
|
275
|
+
2. score=9 refs=2 ext=2 files=1 function warm src/a.ts:5:8
|
|
276
|
+
3. score=6 refs=1 ext=1 files=1 interface User src/model.ts:1:18
|
|
277
|
+
|
|
278
|
+
$ astkit code-rank src --limit 1 --json
|
|
279
|
+
{
|
|
280
|
+
"scope": "/repo/src",
|
|
281
|
+
"symbolsRanked": 1,
|
|
282
|
+
"symbols": [
|
|
283
|
+
{
|
|
284
|
+
"symbol": "hot",
|
|
285
|
+
"kind": "function",
|
|
286
|
+
"file": "src/a.ts",
|
|
287
|
+
"line": 1,
|
|
288
|
+
"character": 8,
|
|
289
|
+
"score": 14,
|
|
290
|
+
"referenceCount": 3
|
|
291
|
+
}
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Structural Pattern Syntax
|
|
297
|
+
|
|
298
|
+
Both `search` and `patch` use the same hole/metavariable syntax:
|
|
299
|
+
|
|
300
|
+
- `:[name]`
|
|
301
|
+
- `:[_]` anonymous hole (ignored in captures)
|
|
302
|
+
- `:[name~regex]` regex-constrained hole
|
|
303
|
+
- `...` variadic wildcard (matches balanced text and can be reused in replacement)
|
|
304
|
+
|
|
305
|
+
Repeated named holes enforce equality:
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
:[x] + :[x]
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
This matches `foo + foo` but not `foo + bar`.
|
|
312
|
+
|
|
313
|
+
Hole captures are structurally balanced (brackets/strings/comments), which helps avoid malformed partial matches.
|
|
314
|
+
|
|
315
|
+
## Output Examples
|
|
316
|
+
|
|
317
|
+
Default compact `search` output:
|
|
318
|
+
|
|
319
|
+
```text
|
|
320
|
+
//src/example.ts
|
|
321
|
+
12: const foo = 42;
|
|
322
|
+
34: const bar = compute( ...
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
JSON `search` output (`--json`) includes:
|
|
326
|
+
- files scanned/matched
|
|
327
|
+
- total matches
|
|
328
|
+
- byte spans
|
|
329
|
+
- line/character
|
|
330
|
+
- captures
|
|
331
|
+
|
|
332
|
+
`patch --json` includes structured match and replacement stats per file.
|
|
333
|
+
|
|
334
|
+
## Programmatic API
|
|
335
|
+
|
|
336
|
+
Root exports:
|
|
337
|
+
- `patchProject` from `src/spatch`
|
|
338
|
+
- `searchProject` from `src/sgrep`
|
|
339
|
+
- `rankCode` from `src/code-rank`
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
import { patchProject, rankCode, searchProject } from "@claudiu.ceia/astkit";
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
See detailed internals:
|
|
346
|
+
- `src/spatch/README.md`
|
|
347
|
+
- `src/sgrep/README.md`
|
|
348
|
+
|
|
349
|
+
## Development
|
|
350
|
+
|
|
351
|
+
Run local CLI:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
bun run astkit -- <command> [args]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Build distributable output:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
npm run build
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Run tests:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
bun test
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Run typecheck:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
npm run typecheck
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Preview npm package contents:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
npm run pack:check
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Install this repo's skill locally for Codex:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
npm run skill:install
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Code Organization
|
|
388
|
+
|
|
389
|
+
- `src/nav/*`: TypeScript language-service navigation commands
|
|
390
|
+
- `src/sgrep/*`: search pipeline (`parse -> search -> output`)
|
|
391
|
+
- `src/spatch/*`: patch pipeline (`parse -> rewrite -> output`)
|
|
392
|
+
- `src/pattern/*`: shared structural parser/matcher/renderer
|
|
393
|
+
- `src/common/*`: shared helpers (for example inline-or-file text resolution)
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const app: import("@stricli/core").Application<import("@stricli/core").CommandContext>;
|
package/dist/src/app.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { buildApplication, buildRouteMap, text_en } from "@stricli/core";
|
|
2
|
+
import { codeRankCommand } from "./code-rank/code-rank.js";
|
|
3
|
+
import { declarationsCommand } from "./nav/declarations.js";
|
|
4
|
+
import { definitionCommand } from "./nav/definition.js";
|
|
5
|
+
import { referencesCommand } from "./nav/references.js";
|
|
6
|
+
import { patchCommand } from "./patch/patch.js";
|
|
7
|
+
import { searchCommand } from "./search/search.js";
|
|
8
|
+
const navRouteMap = buildRouteMap({
|
|
9
|
+
routes: {
|
|
10
|
+
declarations: declarationsCommand,
|
|
11
|
+
definition: definitionCommand,
|
|
12
|
+
references: referencesCommand,
|
|
13
|
+
},
|
|
14
|
+
docs: {
|
|
15
|
+
brief: "Code navigation and reading",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const rootRouteMap = buildRouteMap({
|
|
19
|
+
routes: {
|
|
20
|
+
nav: navRouteMap,
|
|
21
|
+
search: searchCommand,
|
|
22
|
+
patch: patchCommand,
|
|
23
|
+
"code-rank": codeRankCommand,
|
|
24
|
+
},
|
|
25
|
+
docs: {
|
|
26
|
+
brief: "Structural and type-aware code tooling for TS/JS",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
export const app = buildApplication(rootRouteMap, {
|
|
30
|
+
name: "astkit",
|
|
31
|
+
scanner: {
|
|
32
|
+
caseStyle: "original",
|
|
33
|
+
},
|
|
34
|
+
documentation: {
|
|
35
|
+
caseStyle: "original",
|
|
36
|
+
},
|
|
37
|
+
localization: {
|
|
38
|
+
defaultLocale: "en",
|
|
39
|
+
loadText: () => text_en,
|
|
40
|
+
},
|
|
41
|
+
});
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CodeRankResult } from "./rank.ts";
|
|
2
|
+
export type CodeRankCommandFlags = {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function runCodeRankCommand(scope: string | undefined, flags: CodeRankCommandFlags): Promise<CodeRankResult>;
|
|
8
|
+
export declare function formatCodeRankOutput(result: CodeRankResult): string;
|
|
9
|
+
export declare const codeRankCommand: import("@stricli/core").Command<import("@stricli/core").CommandContext>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { buildCommand, numberParser } from "@stricli/core";
|
|
2
|
+
import { rankCode } from "./rank.js";
|
|
3
|
+
export async function runCodeRankCommand(scope, flags) {
|
|
4
|
+
return rankCode({
|
|
5
|
+
cwd: flags.cwd,
|
|
6
|
+
scope: scope ?? ".",
|
|
7
|
+
limit: flags.limit,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export function formatCodeRankOutput(result) {
|
|
11
|
+
if (result.symbols.length === 0) {
|
|
12
|
+
return "No ranked symbols.";
|
|
13
|
+
}
|
|
14
|
+
const lines = [];
|
|
15
|
+
for (let index = 0; index < result.symbols.length; index += 1) {
|
|
16
|
+
const symbol = result.symbols[index];
|
|
17
|
+
if (!symbol) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const rank = index + 1;
|
|
21
|
+
lines.push(`${rank}. score=${symbol.score} refs=${symbol.referenceCount} ext=${symbol.externalReferenceCount} files=${symbol.referencingFileCount} ${symbol.kind} ${symbol.symbol} ${symbol.file}:${symbol.line}:${symbol.character}`);
|
|
22
|
+
}
|
|
23
|
+
return lines.join("\n");
|
|
24
|
+
}
|
|
25
|
+
export const codeRankCommand = buildCommand({
|
|
26
|
+
async func(flags, scope) {
|
|
27
|
+
const result = await runCodeRankCommand(scope, flags);
|
|
28
|
+
if (flags.json ?? false) {
|
|
29
|
+
this.process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.process.stdout.write(`${formatCodeRankOutput(result)}\n`);
|
|
33
|
+
},
|
|
34
|
+
parameters: {
|
|
35
|
+
flags: {
|
|
36
|
+
json: {
|
|
37
|
+
kind: "boolean",
|
|
38
|
+
optional: true,
|
|
39
|
+
brief: "Output structured JSON instead of compact text",
|
|
40
|
+
},
|
|
41
|
+
limit: {
|
|
42
|
+
kind: "parsed",
|
|
43
|
+
optional: true,
|
|
44
|
+
brief: "Maximum number of ranked symbols to return",
|
|
45
|
+
placeholder: "n",
|
|
46
|
+
parse: numberParser,
|
|
47
|
+
},
|
|
48
|
+
cwd: {
|
|
49
|
+
kind: "parsed",
|
|
50
|
+
optional: true,
|
|
51
|
+
brief: "Working directory for resolving scope",
|
|
52
|
+
placeholder: "path",
|
|
53
|
+
parse: (input) => input,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
positional: {
|
|
57
|
+
kind: "tuple",
|
|
58
|
+
parameters: [
|
|
59
|
+
{
|
|
60
|
+
brief: "Scope file or directory (defaults to current directory)",
|
|
61
|
+
placeholder: "scope",
|
|
62
|
+
parse: (input) => input,
|
|
63
|
+
optional: true,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
docs: {
|
|
69
|
+
brief: "Rank exported symbols by reference strength",
|
|
70
|
+
},
|
|
71
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { rankCode, type CodeRankOptions, type CodeRankResult, type RankedSymbol, } from "./rank.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { rankCode, } from "./rank.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type CodeRankOptions = {
|
|
2
|
+
cwd?: string;
|
|
3
|
+
scope?: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
extensions?: readonly string[];
|
|
6
|
+
excludedDirectories?: readonly string[];
|
|
7
|
+
};
|
|
8
|
+
export type RankedSymbol = {
|
|
9
|
+
symbol: string;
|
|
10
|
+
kind: string;
|
|
11
|
+
file: string;
|
|
12
|
+
line: number;
|
|
13
|
+
character: number;
|
|
14
|
+
score: number;
|
|
15
|
+
referenceCount: number;
|
|
16
|
+
internalReferenceCount: number;
|
|
17
|
+
externalReferenceCount: number;
|
|
18
|
+
referencingFileCount: number;
|
|
19
|
+
referencingFiles: string[];
|
|
20
|
+
};
|
|
21
|
+
export type CodeRankResult = {
|
|
22
|
+
cwd: string;
|
|
23
|
+
scope: string;
|
|
24
|
+
filesScanned: number;
|
|
25
|
+
symbolsScanned: number;
|
|
26
|
+
symbolsRanked: number;
|
|
27
|
+
symbols: RankedSymbol[];
|
|
28
|
+
};
|
|
29
|
+
export declare function rankCode(options?: CodeRankOptions): Promise<CodeRankResult>;
|