@parseme/cli 0.0.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/LICENSE +21 -0
- package/README.md +453 -0
- package/dist/analyzers/ast-analyzer.d.ts +12 -0
- package/dist/analyzers/ast-analyzer.js +176 -0
- package/dist/analyzers/framework-detector.d.ts +12 -0
- package/dist/analyzers/framework-detector.js +180 -0
- package/dist/analyzers/git-analyzer.d.ts +13 -0
- package/dist/analyzers/git-analyzer.js +92 -0
- package/dist/analyzers/pattern-detector.d.ts +58 -0
- package/dist/analyzers/pattern-detector.js +174 -0
- package/dist/analyzers/project-analyzer.d.ts +14 -0
- package/dist/analyzers/project-analyzer.js +205 -0
- package/dist/builders/context-builder.d.ts +35 -0
- package/dist/builders/context-builder.js +332 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +145 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.js +203 -0
- package/dist/generator.d.ts +15 -0
- package/dist/generator.js +88 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/prompt.d.ts +8 -0
- package/dist/prompt.js +42 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.js +2 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 citrus551
|
|
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,453 @@
|
|
|
1
|
+
# PARSEME
|
|
2
|
+
|
|
3
|
+
AI Project Context Generator - Automated context generation for AI coding assistants.
|
|
4
|
+
|
|
5
|
+
PARSEME analyzes your TypeScript/JavaScript projects and generates a PARSEME.md file—a README.md for AI agents. This file provides comprehensive context documentation that helps AI assistants understand your codebase structure, architecture, and patterns. By providing persistent, reusable context, PARSEME prevents AI agents from repeatedly analyzing your codebase from scratch—saving valuable tokens and improving efficiency for every interaction.
|
|
6
|
+
|
|
7
|
+
## Development Status
|
|
8
|
+
|
|
9
|
+
**This project is currently in active development and beta phase.**
|
|
10
|
+
|
|
11
|
+
The core functionality is working, but expect:
|
|
12
|
+
|
|
13
|
+
- Breaking changes in configuration format
|
|
14
|
+
- API modifications as the interface gets refined
|
|
15
|
+
- Additional features being added regularly
|
|
16
|
+
- Possible bugs and edge cases
|
|
17
|
+
|
|
18
|
+
### Feedback Welcome!
|
|
19
|
+
|
|
20
|
+
Your feedback is **highly appreciated** and helps shape the future of this tool! Please:
|
|
21
|
+
|
|
22
|
+
- [Report bugs or issues](https://github.com/citrus551/parseme-modules/issues)
|
|
23
|
+
- [Suggest features or improvements](https://github.com/citrus551/parseme-modules/discussions)
|
|
24
|
+
- For other inquiries, contact: mail.citrus551@passmail.net
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- **Universal Pattern Detection** - Dynamic code analysis that works across any JavaScript/TypeScript framework
|
|
29
|
+
- **Project Analysis** - AST-based code analysis with automatic endpoint, component, and service discovery
|
|
30
|
+
- **Framework Agnostic** - No framework-specific dependencies - works with any codebase structure
|
|
31
|
+
- **Configurable Output** - Multi-file context generation optimized for AI assistants
|
|
32
|
+
- **Git Integration** - Includes repository status and change tracking
|
|
33
|
+
- **Highly Configurable** - Comprehensive configuration options via JavaScript, TypeScript, or JSON
|
|
34
|
+
- **Dev Tool Integration** - Works seamlessly as an npm script
|
|
35
|
+
|
|
36
|
+
### 🔍 **What PARSEME Detects**
|
|
37
|
+
|
|
38
|
+
PARSEME uses AST analysis to identify:
|
|
39
|
+
|
|
40
|
+
- **📡 API Endpoints** - HTTP routes, GraphQL resolvers, RPC methods
|
|
41
|
+
- **🧩 Components** - UI components across all major frameworks
|
|
42
|
+
- **⚙️ Services** - Business logic classes and service functions
|
|
43
|
+
- **📋 Data Models** - Interfaces, types, schemas, DTOs
|
|
44
|
+
- **🔗 Middleware** - Request/response handlers and interceptors
|
|
45
|
+
- **🛠️ Utilities** - Helper functions, hooks, composables
|
|
46
|
+
- **📁 Project Structure** - Organized by detected patterns and purpose
|
|
47
|
+
|
|
48
|
+
## **Language Support**
|
|
49
|
+
|
|
50
|
+
- **TypeScript** - Full support including advanced types, decorators, interfaces
|
|
51
|
+
- **JavaScript (ES6+)** - Modern JavaScript with all ES features
|
|
52
|
+
- **JSX/TSX** - React and other JSX-based frameworks
|
|
53
|
+
- **Mixed codebases** - Projects with both JS and TS files
|
|
54
|
+
|
|
55
|
+
## Supported Projects
|
|
56
|
+
|
|
57
|
+
PARSEME aims to automatically analyse any JavaScript or TypeScript project:
|
|
58
|
+
|
|
59
|
+
### 🖥️ **Backend APIs**
|
|
60
|
+
|
|
61
|
+
- **NestJS** - Controllers, services, decorators, dependency injection
|
|
62
|
+
- **Express.js** - Routes, middleware, error handlers
|
|
63
|
+
- **Fastify** - Route registration, plugins, hooks
|
|
64
|
+
- **Koa.js** - Context-based middleware, routing
|
|
65
|
+
- **Hapi.js** - Route configuration, server plugins
|
|
66
|
+
- **Custom frameworks** - Any HTTP endpoint patterns
|
|
67
|
+
|
|
68
|
+
### 🎨 **Frontend Applications**
|
|
69
|
+
|
|
70
|
+
- **React** - Components (functional & class), hooks, JSX patterns
|
|
71
|
+
- **Vue.js** - Components (Composition & Options API), composables
|
|
72
|
+
- **Angular** - Components, services, decorators, modules
|
|
73
|
+
- **Svelte** - Components, stores, reactive patterns
|
|
74
|
+
- **Lit** - Web components, custom elements
|
|
75
|
+
- **Vanilla JS/TS** - Any component or module patterns
|
|
76
|
+
|
|
77
|
+
### 📦 **NPM Packages & Libraries**
|
|
78
|
+
|
|
79
|
+
- **TypeScript libraries** - Interfaces, types, utility functions
|
|
80
|
+
- **JavaScript utilities** - Helper functions, class libraries
|
|
81
|
+
- **Node.js modules** - CommonJS and ES modules
|
|
82
|
+
- **Monorepo packages** - Lerna, Nx, Rush, Turborepo
|
|
83
|
+
|
|
84
|
+
### 🛠️ **Development Tools**
|
|
85
|
+
|
|
86
|
+
- **CLI applications** - Command-line tools and scripts
|
|
87
|
+
- **Build tools** - Webpack plugins, Vite configurations
|
|
88
|
+
- **Desktop applications** - Electron, Tauri apps
|
|
89
|
+
- **Testing utilities** - Jest plugins, test helpers
|
|
90
|
+
|
|
91
|
+
### 🏗️ **Fullstack Frameworks**
|
|
92
|
+
|
|
93
|
+
- **Next.js** - Pages, API routes, middleware, components
|
|
94
|
+
- **Nuxt.js** - Vue-based fullstack applications
|
|
95
|
+
- **SvelteKit** - Svelte-based fullstack applications
|
|
96
|
+
- **Remix** - React-based fullstack applications
|
|
97
|
+
-
|
|
98
|
+
|
|
99
|
+
## Development Status
|
|
100
|
+
|
|
101
|
+
**This project is currently in active development and beta phase.**
|
|
102
|
+
|
|
103
|
+
The core functionality is working, but expect:
|
|
104
|
+
|
|
105
|
+
- Breaking changes in configuration format
|
|
106
|
+
- API modifications as the interface gets refined
|
|
107
|
+
- Additional features being added regularly
|
|
108
|
+
- Possible bugs and edge cases
|
|
109
|
+
|
|
110
|
+
### Feedback Welcome!
|
|
111
|
+
|
|
112
|
+
Your feedback is **highly appreciated** and helps shape the future of this tool! Please:
|
|
113
|
+
|
|
114
|
+
- [Report bugs or issues](https://github.com/citrus551/parseme-modules/issues)
|
|
115
|
+
- [Suggest features or improvements](https://github.com/citrus551/parseme-modules/discussions)
|
|
116
|
+
- For other inquiries, contact: mail.citrus551@passmail.net
|
|
117
|
+
- Share your use cases and experiences
|
|
118
|
+
- Star the repo if you find it useful
|
|
119
|
+
|
|
120
|
+
## Installation
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm install --save-dev parseme
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Quick Start
|
|
127
|
+
|
|
128
|
+
1. **Initialize configuration**:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx parseme init
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
2. **Add to your package.json scripts**:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"scripts": {
|
|
139
|
+
"parseme": "parseme"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
3. **Generate context**:
|
|
145
|
+
```bash
|
|
146
|
+
npm run parseme
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
This will create a `PARSEME.md` file and a `parseme-context/` directory with comprehensive project context.
|
|
150
|
+
|
|
151
|
+
## Configuration
|
|
152
|
+
|
|
153
|
+
PARSEME supports multiple configuration formats with automatic discovery and priority handling.
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
/** @type {import('parseme').ParsemeConfigFile} */
|
|
157
|
+
export default {
|
|
158
|
+
// Output settings
|
|
159
|
+
outputPath: 'PARSEME.md',
|
|
160
|
+
contextDir: 'parseme-context', // or "docs/context", "/absolute/path"
|
|
161
|
+
|
|
162
|
+
// Analysis settings
|
|
163
|
+
includePatterns: ['src/**/*.ts', 'src/**/*.js', 'package.json'],
|
|
164
|
+
excludePatterns: ['node_modules/**', 'dist/**', '**/*.test.ts'],
|
|
165
|
+
|
|
166
|
+
// AI-friendly size limits
|
|
167
|
+
limits: {
|
|
168
|
+
maxLinesPerFile: 1000,
|
|
169
|
+
maxCharsPerFile: 50000,
|
|
170
|
+
maxFilesPerContext: 20,
|
|
171
|
+
truncateStrategy: 'split', // or 'truncate'
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
// Content sections
|
|
175
|
+
sections: {
|
|
176
|
+
overview: true,
|
|
177
|
+
architecture: true,
|
|
178
|
+
routes: true,
|
|
179
|
+
dependencies: true,
|
|
180
|
+
git: true,
|
|
181
|
+
fileStructure: true,
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Configuration File Formats & Priority
|
|
187
|
+
|
|
188
|
+
PARSEME supports three configuration formats with the following priority:
|
|
189
|
+
|
|
190
|
+
1. **TypeScript** (`.ts`) - `parseme.config.ts`, `.parsemerc.ts`
|
|
191
|
+
2. **JavaScript** (`.js`) - `parseme.config.js`, `.parsemerc.js`
|
|
192
|
+
3. **JSON** (`.json`) - `parseme.config.json`, `.parsemerc.json`, `.parsemerc`
|
|
193
|
+
|
|
194
|
+
#### TypeScript Configuration
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import type { ParsemeConfigFile } from 'parseme';
|
|
198
|
+
|
|
199
|
+
const config: ParsemeConfigFile = {
|
|
200
|
+
outputPath: 'PARSEME.md',
|
|
201
|
+
includePatterns: ['src/**/*.ts'],
|
|
202
|
+
// ... other options
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export default config;
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### JSON Configuration
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"outputPath": "PARSEME.md",
|
|
213
|
+
"contextDir": "parseme-context",
|
|
214
|
+
"includePatterns": ["src/**/*.ts"]
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Configuration Priority
|
|
219
|
+
|
|
220
|
+
Configuration values are resolved in the following order (highest to lowest priority):
|
|
221
|
+
|
|
222
|
+
1. **CLI flags** - `--output`, `--root`, `--include`, etc.
|
|
223
|
+
2. **Config file** - Based on file format priority above
|
|
224
|
+
3. **Default values** - Built-in sensible defaults
|
|
225
|
+
|
|
226
|
+
**Example**: `npx parseme --output custom.md` overrides `outputPath` from config file.
|
|
227
|
+
|
|
228
|
+
### Configuration Options
|
|
229
|
+
|
|
230
|
+
#### Output Settings
|
|
231
|
+
|
|
232
|
+
- `outputPath` - Where to save the main PARSEME.md file (default: "PARSEME.md")
|
|
233
|
+
- `contextDir` - Directory for detailed context files (default: "parseme-context")
|
|
234
|
+
|
|
235
|
+
#### Analysis Settings
|
|
236
|
+
|
|
237
|
+
- `rootDir` - Project root directory (default: current directory)
|
|
238
|
+
- `includePatterns` - Glob patterns for files to analyze
|
|
239
|
+
- `excludePatterns` - Glob patterns for files to ignore
|
|
240
|
+
- `maxDepth` - Maximum directory depth to traverse
|
|
241
|
+
|
|
242
|
+
#### Framework Settings
|
|
243
|
+
|
|
244
|
+
Configure framework-specific analysis:
|
|
245
|
+
|
|
246
|
+
- **Express**: `detectMiddleware`, `documentRoutes`
|
|
247
|
+
- **NestJS**: `includeDecorators`, `documentModules`
|
|
248
|
+
- **Fastify**: `includePlugins`
|
|
249
|
+
|
|
250
|
+
#### Content Sections
|
|
251
|
+
|
|
252
|
+
Toggle which sections to include:
|
|
253
|
+
|
|
254
|
+
- `overview` - Project overview and metadata
|
|
255
|
+
- `architecture` - File type breakdown
|
|
256
|
+
- `routes` - API endpoints and routing
|
|
257
|
+
- `dependencies` - Package dependencies
|
|
258
|
+
- `git` - Repository information
|
|
259
|
+
- `fileStructure` - Detailed file listing
|
|
260
|
+
|
|
261
|
+
#### Style Options
|
|
262
|
+
|
|
263
|
+
- `includeLineNumbers` - Add line numbers to code references
|
|
264
|
+
- `includeFileStats` - Include file statistics
|
|
265
|
+
- `groupByType` - Group files by detected type
|
|
266
|
+
- `sortOrder` - "alphabetical", "type", or "size"
|
|
267
|
+
|
|
268
|
+
## Output Format
|
|
269
|
+
|
|
270
|
+
PARSEME always generates multi-file output:
|
|
271
|
+
|
|
272
|
+
- `PARSEME.md` - Main overview and summary (Markdown format)
|
|
273
|
+
- Context directory (default: `parseme-context/`) with detailed JSON files:
|
|
274
|
+
- `structure.json` - Detailed AST analysis with file exports, imports, functions, and classes
|
|
275
|
+
- `routes.json` - API routes documentation with methods, paths, and handlers
|
|
276
|
+
- `dependencies.json` - Production dependency analysis with package versions
|
|
277
|
+
- `git.json` - Git repository information with branch, status, and changed files
|
|
278
|
+
|
|
279
|
+
The context directory location can be customized via the `contextDir` configuration option.
|
|
280
|
+
|
|
281
|
+
## CLI Commands
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Generate context (auto-detects config file)
|
|
285
|
+
npx parseme
|
|
286
|
+
|
|
287
|
+
# Initialize configuration (JavaScript by default)
|
|
288
|
+
npx parseme init
|
|
289
|
+
|
|
290
|
+
# Initialize with TypeScript format
|
|
291
|
+
npx parseme init --format ts
|
|
292
|
+
|
|
293
|
+
# Initialize with JSON format
|
|
294
|
+
npx parseme init --format json
|
|
295
|
+
|
|
296
|
+
# Use custom config file
|
|
297
|
+
npx parseme --config custom.config.js
|
|
298
|
+
|
|
299
|
+
# Override config with CLI flags
|
|
300
|
+
npx parseme --output custom.md --context-dir docs/context --root ./src --no-git
|
|
301
|
+
|
|
302
|
+
# Include/exclude patterns
|
|
303
|
+
npx parseme --include "src/**/*.ts" --exclude "**/*.test.ts"
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### CLI Options
|
|
307
|
+
|
|
308
|
+
- `-c, --config <path>` - Config file path
|
|
309
|
+
- `-o, --output <path>` - Output file path
|
|
310
|
+
- `-r, --root <path>` - Root directory to analyze
|
|
311
|
+
- `--context-dir <path>` - Context directory path (default: parseme-context)
|
|
312
|
+
- `--include <patterns...>` - Include patterns (glob)
|
|
313
|
+
- `--exclude <patterns...>` - Exclude patterns (glob)
|
|
314
|
+
- `--no-git` - Disable git information
|
|
315
|
+
- `--max-depth <number>` - Maximum directory depth
|
|
316
|
+
- `--no-readme-suggestion` - Disable README.md section suggestion
|
|
317
|
+
|
|
318
|
+
### Interactive Configuration
|
|
319
|
+
|
|
320
|
+
When the README suggestion setting is not configured and you're running parseme interactively, you'll be prompted to configure:
|
|
321
|
+
|
|
322
|
+
- **README suggestion** - Whether to show the README.md section suggestion for AI agents
|
|
323
|
+
|
|
324
|
+
The prompt is automatically disabled in:
|
|
325
|
+
|
|
326
|
+
- CI environments (when `CI=true`)
|
|
327
|
+
- Non-interactive terminals (no TTY)
|
|
328
|
+
- When the value is explicitly provided via CLI flags or config files
|
|
329
|
+
|
|
330
|
+
Example interactive session:
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
$ npx parseme
|
|
334
|
+
|
|
335
|
+
Show README.md section suggestion for AI agents? [y]: y
|
|
336
|
+
|
|
337
|
+
Context generated successfully
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Framework Support
|
|
341
|
+
|
|
342
|
+
PARSEME automatically detects and provides specialized analysis for:
|
|
343
|
+
|
|
344
|
+
### Express.js
|
|
345
|
+
|
|
346
|
+
- Route detection (`app.get`, `router.post`, etc.)
|
|
347
|
+
- Middleware identification
|
|
348
|
+
- Request handler mapping
|
|
349
|
+
|
|
350
|
+
### NestJS
|
|
351
|
+
|
|
352
|
+
- Controller and decorator analysis
|
|
353
|
+
- Module structure detection
|
|
354
|
+
- Dependency injection mapping
|
|
355
|
+
|
|
356
|
+
### Fastify
|
|
357
|
+
|
|
358
|
+
- Route registration detection
|
|
359
|
+
- Plugin identification
|
|
360
|
+
- Hook analysis
|
|
361
|
+
|
|
362
|
+
### Koa & Hapi
|
|
363
|
+
|
|
364
|
+
- Route and middleware detection
|
|
365
|
+
- Framework-specific patterns
|
|
366
|
+
|
|
367
|
+
## Integration Examples
|
|
368
|
+
|
|
369
|
+
### Basic Express Project
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
// parseme.config.js
|
|
373
|
+
export default {
|
|
374
|
+
includePatterns: ['src/**/*.js', 'routes/**/*.js', 'middleware/**/*.js'],
|
|
375
|
+
frameworks: {
|
|
376
|
+
express: {
|
|
377
|
+
detectMiddleware: true,
|
|
378
|
+
documentRoutes: true,
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### TypeScript NestJS Project
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
// parseme.config.js
|
|
388
|
+
export default {
|
|
389
|
+
includePatterns: ['src/**/*.ts', '!src/**/*.spec.ts'],
|
|
390
|
+
frameworks: {
|
|
391
|
+
nestjs: {
|
|
392
|
+
includeDecorators: true,
|
|
393
|
+
documentModules: true,
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
sections: {
|
|
397
|
+
overview: true,
|
|
398
|
+
architecture: true,
|
|
399
|
+
routes: true,
|
|
400
|
+
dependencies: true,
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Programmatic API
|
|
406
|
+
|
|
407
|
+
You can also use PARSEME programmatically:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { ParsemeGenerator } from 'parseme';
|
|
411
|
+
|
|
412
|
+
const generator = await ParsemeGenerator.fromConfig('./custom.config.js');
|
|
413
|
+
const context = await generator.generate();
|
|
414
|
+
|
|
415
|
+
// Or generate directly to file
|
|
416
|
+
await generator.generateToFile('./output/PARSEME.md');
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Git Hook Integration
|
|
420
|
+
|
|
421
|
+
Keep your AI context automatically updated by adding parseme as a post-commit hook:
|
|
422
|
+
|
|
423
|
+
### Manual Setup
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
# Create and make executable
|
|
427
|
+
echo '#!/bin/sh\nnpx parseme' > .git/hooks/post-commit
|
|
428
|
+
chmod +x .git/hooks/post-commit
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Using Husky
|
|
432
|
+
|
|
433
|
+
```json
|
|
434
|
+
// package.json
|
|
435
|
+
{
|
|
436
|
+
"husky": {
|
|
437
|
+
"hooks": {
|
|
438
|
+
"post-commit": "npx parseme"
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
This automatically regenerates your AI context files after every commit, ensuring they're always up-to-date!
|
|
445
|
+
|
|
446
|
+
## Requirements
|
|
447
|
+
|
|
448
|
+
- Node.js ≥20.19.5
|
|
449
|
+
- npm ≥10.8.2
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ParsemeConfig } from '../config.js';
|
|
2
|
+
import type { FileAnalysis } from '../types.js';
|
|
3
|
+
export declare class ASTAnalyzer {
|
|
4
|
+
private readonly config;
|
|
5
|
+
private readonly ig;
|
|
6
|
+
private readonly patternDetector;
|
|
7
|
+
constructor(config: ParsemeConfig);
|
|
8
|
+
analyzeProject(rootDir: string): Promise<FileAnalysis[]>;
|
|
9
|
+
analyzeFile(filePath: string, relativePath: string): Promise<FileAnalysis | null>;
|
|
10
|
+
private parseFile;
|
|
11
|
+
private determineFileType;
|
|
12
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { relative, extname } from 'path';
|
|
3
|
+
import { parse } from '@babel/parser';
|
|
4
|
+
import traverse from '@babel/traverse';
|
|
5
|
+
import * as t from '@babel/types';
|
|
6
|
+
import { glob } from 'glob';
|
|
7
|
+
import ignore from 'ignore';
|
|
8
|
+
import { PatternDetector } from './pattern-detector.js';
|
|
9
|
+
export class ASTAnalyzer {
|
|
10
|
+
config;
|
|
11
|
+
ig;
|
|
12
|
+
patternDetector;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.ig = ignore();
|
|
16
|
+
const configData = this.config.get();
|
|
17
|
+
this.ig.add(configData.excludePatterns || []);
|
|
18
|
+
this.patternDetector = new PatternDetector(config);
|
|
19
|
+
}
|
|
20
|
+
async analyzeProject(rootDir) {
|
|
21
|
+
const configData = this.config.get();
|
|
22
|
+
const patterns = configData.includePatterns || ['**/*.ts', '**/*.js'];
|
|
23
|
+
const files = await glob(patterns, {
|
|
24
|
+
cwd: rootDir,
|
|
25
|
+
absolute: true,
|
|
26
|
+
ignore: configData.excludePatterns,
|
|
27
|
+
});
|
|
28
|
+
const analyses = [];
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const relativePath = relative(rootDir, file);
|
|
31
|
+
// Skip if ignored
|
|
32
|
+
if (this.ig.ignores(relativePath)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const analysis = await this.analyzeFile(file, relativePath);
|
|
37
|
+
if (analysis) {
|
|
38
|
+
analyses.push(analysis);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.warn(`Failed to analyze ${relativePath}:`, error);
|
|
43
|
+
// Continue with other files
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return analyses;
|
|
47
|
+
}
|
|
48
|
+
async analyzeFile(filePath, relativePath) {
|
|
49
|
+
try {
|
|
50
|
+
const content = await readFile(filePath, 'utf-8');
|
|
51
|
+
const ext = extname(filePath);
|
|
52
|
+
// Skip non-JS/TS files for AST analysis
|
|
53
|
+
if (!['.js', '.ts', '.jsx', '.tsx'].includes(ext)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const ast = this.parseFile(content, ext);
|
|
57
|
+
// Use pattern detector to analyze the file
|
|
58
|
+
const patterns = this.patternDetector.analyzePatterns(ast, relativePath, content);
|
|
59
|
+
const analysis = {
|
|
60
|
+
path: relativePath,
|
|
61
|
+
type: this.determineFileType(relativePath, content, patterns),
|
|
62
|
+
exports: [],
|
|
63
|
+
imports: [],
|
|
64
|
+
functions: [],
|
|
65
|
+
classes: [],
|
|
66
|
+
routes: patterns.endpoints,
|
|
67
|
+
components: patterns.components,
|
|
68
|
+
services: patterns.services,
|
|
69
|
+
models: patterns.models,
|
|
70
|
+
configs: patterns.configs,
|
|
71
|
+
middleware: patterns.middleware,
|
|
72
|
+
utilities: patterns.utilities,
|
|
73
|
+
};
|
|
74
|
+
traverse.default(ast, {
|
|
75
|
+
// Import declarations
|
|
76
|
+
ImportDeclaration: (path) => {
|
|
77
|
+
analysis.imports.push(path.node.source.value);
|
|
78
|
+
},
|
|
79
|
+
// Export declarations
|
|
80
|
+
ExportNamedDeclaration: (path) => {
|
|
81
|
+
if (path.node.declaration) {
|
|
82
|
+
if (t.isFunctionDeclaration(path.node.declaration) && path.node.declaration.id) {
|
|
83
|
+
analysis.exports.push(path.node.declaration.id.name);
|
|
84
|
+
}
|
|
85
|
+
else if (t.isVariableDeclaration(path.node.declaration)) {
|
|
86
|
+
path.node.declaration.declarations.forEach((decl) => {
|
|
87
|
+
if (t.isIdentifier(decl.id)) {
|
|
88
|
+
analysis.exports.push(decl.id.name);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (path.node.specifiers) {
|
|
94
|
+
path.node.specifiers.forEach((spec) => {
|
|
95
|
+
if (t.isExportSpecifier(spec) && t.isIdentifier(spec.exported)) {
|
|
96
|
+
analysis.exports.push(spec.exported.name);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
ExportDefaultDeclaration: (_path) => {
|
|
102
|
+
analysis.exports.push('default');
|
|
103
|
+
},
|
|
104
|
+
// Function declarations
|
|
105
|
+
FunctionDeclaration: (path) => {
|
|
106
|
+
if (path.node.id) {
|
|
107
|
+
analysis.functions.push(path.node.id.name);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
// Class declarations
|
|
111
|
+
ClassDeclaration: (path) => {
|
|
112
|
+
if (path.node.id) {
|
|
113
|
+
analysis.classes.push(path.node.id.name);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
return analysis;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.warn(`Failed to parse ${relativePath}:`, error);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
parseFile(content, ext) {
|
|
125
|
+
const isTypeScript = ext === '.ts' || ext === '.tsx';
|
|
126
|
+
const isJSX = ext === '.jsx' || ext === '.tsx';
|
|
127
|
+
return parse(content, {
|
|
128
|
+
sourceType: 'module',
|
|
129
|
+
allowImportExportEverywhere: true,
|
|
130
|
+
allowReturnOutsideFunction: true,
|
|
131
|
+
plugins: [
|
|
132
|
+
...(isTypeScript ? ['typescript'] : []),
|
|
133
|
+
...(isJSX ? ['jsx'] : []),
|
|
134
|
+
'decorators-legacy',
|
|
135
|
+
'classProperties',
|
|
136
|
+
'objectRestSpread',
|
|
137
|
+
'asyncGenerators',
|
|
138
|
+
'functionBind',
|
|
139
|
+
'exportDefaultFrom',
|
|
140
|
+
'exportNamespaceFrom',
|
|
141
|
+
'dynamicImport',
|
|
142
|
+
'nullishCoalescingOperator',
|
|
143
|
+
'optionalChaining',
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
determineFileType(relativePath, content, patterns) {
|
|
148
|
+
// Use pattern analysis to determine file type dynamically
|
|
149
|
+
if (patterns.endpoints.length > 0) {
|
|
150
|
+
return 'route';
|
|
151
|
+
}
|
|
152
|
+
if (patterns.middleware.length > 0) {
|
|
153
|
+
return 'middleware';
|
|
154
|
+
}
|
|
155
|
+
if (patterns.models.length > 0) {
|
|
156
|
+
return 'model';
|
|
157
|
+
}
|
|
158
|
+
if (patterns.services.length > 0) {
|
|
159
|
+
return 'service';
|
|
160
|
+
}
|
|
161
|
+
if (patterns.components.length > 0) {
|
|
162
|
+
return 'component';
|
|
163
|
+
}
|
|
164
|
+
if (patterns.configs.length > 0) {
|
|
165
|
+
return 'config';
|
|
166
|
+
}
|
|
167
|
+
// Fallback to path-based detection
|
|
168
|
+
if (relativePath.includes('test') || relativePath.includes('spec')) {
|
|
169
|
+
return 'test';
|
|
170
|
+
}
|
|
171
|
+
if (relativePath.includes('util') || relativePath.includes('helper')) {
|
|
172
|
+
return 'utility';
|
|
173
|
+
}
|
|
174
|
+
return 'utility';
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ParsemeConfig } from '../config.js';
|
|
2
|
+
import type { ProjectInfo, FrameworkInfo } from '../types.js';
|
|
3
|
+
export declare class FrameworkDetector {
|
|
4
|
+
private readonly config;
|
|
5
|
+
constructor(config: ParsemeConfig);
|
|
6
|
+
detect(projectInfo: ProjectInfo): Promise<FrameworkInfo>;
|
|
7
|
+
private detectExpress;
|
|
8
|
+
private detectFastify;
|
|
9
|
+
private detectNestJS;
|
|
10
|
+
private detectKoa;
|
|
11
|
+
private detectHapi;
|
|
12
|
+
}
|