@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/dist/cli.js ADDED
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+ import { join } from 'path';
3
+ import { Command } from 'commander';
4
+ import { ParsemeConfig } from './config.js';
5
+ import { ParsemeGenerator } from './generator.js';
6
+ import { confirmPrompt } from './prompt.js';
7
+ const program = new Command();
8
+ async function promptForMissingConfig(config, cliOptions) {
9
+ const finalConfig = { ...config };
10
+ // Only prompt if running interactively (stdin is a TTY) and not in CI
11
+ if (!process.stdin.isTTY || process.env.CI) {
12
+ return finalConfig;
13
+ }
14
+ // Prompt for README suggestion if not set via CLI or config
15
+ if (cliOptions.readmeSuggestion === undefined && config.readmeSuggestion === undefined) {
16
+ const wantReadmeSuggestion = await confirmPrompt('Show README.md section suggestion for AI agents?', true);
17
+ finalConfig.readmeSuggestion = wantReadmeSuggestion;
18
+ }
19
+ return finalConfig;
20
+ }
21
+ program.name('parseme').description('AI Project Context Generator').version('0.1.0');
22
+ // Main command - just run parseme
23
+ program
24
+ .description('Generate project context using config file')
25
+ .option('-c, --config <path>', 'Config file path')
26
+ .option('-o, --output <path>', 'Output file path')
27
+ .option('-r, --root <path>', 'Root directory to analyze')
28
+ .option('--context-dir <path>', 'Context directory path (default: parseme-context)')
29
+ .option('--include <patterns...>', 'Include patterns (glob)')
30
+ .option('--exclude <patterns...>', 'Exclude patterns (glob)')
31
+ .option('--no-git', 'Disable git information')
32
+ .option('--max-depth <number>', 'Maximum directory depth', parseInt)
33
+ .option('--no-readme-suggestion', 'Disable README.md section suggestion')
34
+ .action(async (options) => {
35
+ try {
36
+ // Convert CLI options to config format
37
+ const cliOptions = {
38
+ ...(options.output && { outputPath: options.output }),
39
+ ...(options.root && { rootDir: options.root }),
40
+ ...(options.contextDir && { contextDir: options.contextDir }),
41
+ ...(options.include && { includePatterns: options.include }),
42
+ ...(options.exclude && { excludePatterns: options.exclude }),
43
+ ...(options.git === false && { includeGitInfo: false }),
44
+ ...(options.maxDepth && { maxDepth: options.maxDepth }),
45
+ ...(options.readmeSuggestion === false && { readmeSuggestion: false }),
46
+ };
47
+ const configFromFile = await ParsemeConfig.fromFile(options.config);
48
+ const interactiveConfig = await promptForMissingConfig(configFromFile.get(), cliOptions);
49
+ // Merge: CLI options > interactive prompts > config file > defaults
50
+ const finalConfig = {
51
+ ...interactiveConfig,
52
+ ...cliOptions,
53
+ };
54
+ const config = new ParsemeConfig(finalConfig);
55
+ const generator = new ParsemeGenerator(config.get());
56
+ await generator.generateToFile();
57
+ console.log('Context generated successfully');
58
+ console.log('Tip: Add parseme as a git hook to keep context auto-updated! See README for setup instructions.');
59
+ const shouldShowReadmeSuggestion = finalConfig.readmeSuggestion !== false;
60
+ if (shouldShowReadmeSuggestion) {
61
+ console.log('Tip: Add this section to your README.md to help AI agents find the context:');
62
+ console.log('');
63
+ console.log('## For AI Assistants');
64
+ console.log('This project includes AI-optimized documentation:');
65
+ console.log('- `PARSEME.md` - Main project context and overview');
66
+ console.log('- `parseme-context/` - Detailed JSON files with code structure, dependencies, and git info');
67
+ console.log('');
68
+ }
69
+ }
70
+ catch (error) {
71
+ console.error('Failed to generate context:', error);
72
+ process.exit(1);
73
+ }
74
+ });
75
+ program
76
+ .command('init')
77
+ .description('Initialize parseme configuration')
78
+ .option('-f, --force', 'Overwrite existing config')
79
+ .option('--format <format>', 'Config format: js, ts, or json', 'js')
80
+ .action(async (options) => {
81
+ try {
82
+ // Validate format
83
+ if (!['js', 'ts', 'json'].includes(options.format)) {
84
+ console.error('Invalid format. Use js, ts, or json');
85
+ process.exit(1);
86
+ }
87
+ const configPath = join(process.cwd(), `parseme.config.${options.format}`);
88
+ const config = new ParsemeConfig();
89
+ // Check if config already exists
90
+ if (!options.force) {
91
+ try {
92
+ const fs = await import('fs/promises');
93
+ await fs.access(configPath);
94
+ console.log('Configuration file already exists. Use --force to overwrite.');
95
+ process.exit(1);
96
+ }
97
+ catch {
98
+ // File doesn't exist, continue
99
+ }
100
+ }
101
+ await config.save(configPath);
102
+ console.log(`Configuration file created at ${configPath}`);
103
+ if (options.format === 'ts') {
104
+ console.log('For TypeScript configs, ensure tsx or ts-node is available to load .ts files');
105
+ }
106
+ console.log('Add "parseme": "parseme" to your package.json scripts');
107
+ }
108
+ catch (error) {
109
+ console.error('Failed to create configuration:', error);
110
+ process.exit(1);
111
+ }
112
+ });
113
+ // If no command and no args, run main action
114
+ if (process.argv.length <= 2) {
115
+ // Run the default action
116
+ (async () => {
117
+ try {
118
+ const configFromFile = await ParsemeConfig.fromFile();
119
+ const interactiveConfig = await promptForMissingConfig(configFromFile.get(), {});
120
+ const config = new ParsemeConfig(interactiveConfig);
121
+ const generator = new ParsemeGenerator(config.get());
122
+ await generator.generateToFile();
123
+ console.log('Context generated successfully');
124
+ console.log('Tip: Add parseme as a git hook to keep context auto-updated! See README for setup instructions.');
125
+ const shouldShowReadmeSuggestion = interactiveConfig.readmeSuggestion !== false;
126
+ if (shouldShowReadmeSuggestion) {
127
+ console.log('Tip: Add this section to your README.md to help AI agents find the context:');
128
+ console.log('');
129
+ console.log('## For AI Assistants');
130
+ console.log('This project includes AI-optimized documentation:');
131
+ console.log('- `PARSEME.md` - Main project context and overview');
132
+ console.log('- `parseme-context/` - Detailed JSON files with code structure, dependencies, and git info');
133
+ console.log('');
134
+ }
135
+ }
136
+ catch (error) {
137
+ console.error('Failed to generate context:', error);
138
+ console.log('Run "parseme init" to create a configuration file');
139
+ process.exit(1);
140
+ }
141
+ })();
142
+ }
143
+ else {
144
+ program.parse();
145
+ }
@@ -0,0 +1,44 @@
1
+ import type { GeneratorOptions } from './types.js';
2
+ export interface ParsemeConfigFile extends GeneratorOptions {
3
+ outputPath?: string;
4
+ contextDir?: string;
5
+ rootDir?: string;
6
+ includePatterns?: string[];
7
+ excludePatterns?: string[];
8
+ maxDepth?: number;
9
+ includeGitInfo?: boolean;
10
+ readmeSuggestion?: boolean;
11
+ sections?: {
12
+ overview?: boolean;
13
+ architecture?: boolean;
14
+ routes?: boolean;
15
+ dependencies?: boolean;
16
+ git?: boolean;
17
+ fileStructure?: boolean;
18
+ };
19
+ style?: {
20
+ includeLineNumbers?: boolean;
21
+ includeFileStats?: boolean;
22
+ groupByType?: boolean;
23
+ sortOrder?: 'alphabetical' | 'type' | 'size';
24
+ };
25
+ limits?: {
26
+ maxLinesPerFile?: number;
27
+ maxCharsPerFile?: number;
28
+ maxFilesPerContext?: number;
29
+ truncateStrategy?: 'truncate' | 'split' | 'summarize';
30
+ };
31
+ }
32
+ export declare class ParsemeConfig {
33
+ private readonly config;
34
+ constructor(config?: Partial<ParsemeConfigFile>);
35
+ static fromFileWithOptions(configPath?: string, cliOptions?: Partial<ParsemeConfigFile>): Promise<ParsemeConfig>;
36
+ static fromFile(configPath?: string): Promise<ParsemeConfig>;
37
+ private mergeWithDefaults;
38
+ get(): ParsemeConfigFile;
39
+ save(path?: string): Promise<void>;
40
+ private generateJSConfig;
41
+ private generateTSConfig;
42
+ private mergeExcludePatterns;
43
+ private readGitignorePatterns;
44
+ }
package/dist/config.js ADDED
@@ -0,0 +1,203 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { readFile, writeFile } from 'fs/promises';
3
+ import { join, extname } from 'path';
4
+ export class ParsemeConfig {
5
+ config;
6
+ constructor(config = {}) {
7
+ this.config = this.mergeWithDefaults(config);
8
+ }
9
+ static async fromFileWithOptions(configPath, cliOptions = {}) {
10
+ const configFromFile = await ParsemeConfig.fromFile(configPath);
11
+ const mergedConfig = {
12
+ ...configFromFile.get(),
13
+ ...cliOptions, // CLI options take priority
14
+ };
15
+ return new ParsemeConfig(mergedConfig);
16
+ }
17
+ static async fromFile(configPath) {
18
+ const defaultPaths = [
19
+ 'parseme.config.ts',
20
+ 'parseme.config.js',
21
+ 'parseme.config.json',
22
+ '.parsemerc.ts',
23
+ '.parsemerc.js',
24
+ '.parsemerc.json',
25
+ '.parsemerc',
26
+ ];
27
+ const paths = configPath ? [configPath] : defaultPaths;
28
+ for (const path of paths) {
29
+ try {
30
+ const ext = extname(path);
31
+ if (ext === '.js' || ext === '.ts') {
32
+ // Dynamic import for JS/TS config files
33
+ const fullPath = path.startsWith('/') ? path : join(process.cwd(), path);
34
+ if (ext === '.ts') {
35
+ // For TypeScript files, try to import directly first
36
+ // This works if the user has transpiled their TS config to JS or is using tsx/ts-node
37
+ try {
38
+ const module = await import(fullPath);
39
+ const config = module.default || module;
40
+ return new ParsemeConfig(config);
41
+ }
42
+ catch {
43
+ // If direct import fails, suggest using .js instead
44
+ console.warn(`Could not load TypeScript config file: ${path}`);
45
+ console.warn(`Consider using a .js config file or ensure tsx/ts-node is available`);
46
+ }
47
+ }
48
+ else {
49
+ // JavaScript files
50
+ const module = await import(fullPath);
51
+ const config = module.default || module;
52
+ return new ParsemeConfig(config);
53
+ }
54
+ }
55
+ else {
56
+ // JSON config files
57
+ const content = await readFile(path, 'utf-8');
58
+ const config = JSON.parse(content);
59
+ return new ParsemeConfig(config);
60
+ }
61
+ }
62
+ catch {
63
+ // Continue to next path
64
+ }
65
+ }
66
+ // Return default config if no file found
67
+ return new ParsemeConfig();
68
+ }
69
+ mergeWithDefaults(config) {
70
+ const rootDir = config.rootDir || process.cwd();
71
+ return {
72
+ // Output
73
+ outputPath: config.outputPath || 'PARSEME.md',
74
+ contextDir: config.contextDir || 'parseme-context',
75
+ // Analysis
76
+ rootDir,
77
+ maxDepth: config.maxDepth || 10,
78
+ excludePatterns: this.mergeExcludePatterns(config.excludePatterns, rootDir),
79
+ includePatterns: config.includePatterns || [
80
+ 'src/**/*.ts',
81
+ 'src/**/*.js',
82
+ 'src/**/*.tsx',
83
+ 'src/**/*.jsx',
84
+ 'lib/**/*.ts',
85
+ 'lib/**/*.js',
86
+ 'package.json',
87
+ 'tsconfig.json',
88
+ 'README.md',
89
+ ],
90
+ // Git
91
+ includeGitInfo: config.includeGitInfo ?? true,
92
+ // Sections
93
+ sections: {
94
+ overview: true,
95
+ architecture: true,
96
+ routes: true,
97
+ dependencies: true,
98
+ git: true,
99
+ fileStructure: true,
100
+ ...config.sections,
101
+ },
102
+ // Style
103
+ style: {
104
+ includeLineNumbers: false,
105
+ includeFileStats: true,
106
+ groupByType: true,
107
+ sortOrder: 'type',
108
+ ...config.style,
109
+ },
110
+ // Size limits
111
+ limits: {
112
+ maxLinesPerFile: config.limits?.maxLinesPerFile ?? 1000,
113
+ maxCharsPerFile: config.limits?.maxCharsPerFile ?? 50000, // ~15k tokens
114
+ maxFilesPerContext: config.limits?.maxFilesPerContext ?? 20,
115
+ truncateStrategy: config.limits?.truncateStrategy ?? 'truncate',
116
+ },
117
+ };
118
+ }
119
+ get() {
120
+ return { ...this.config };
121
+ }
122
+ async save(path = 'parseme.config.js') {
123
+ const ext = extname(path);
124
+ if (ext === '.js') {
125
+ // Generate JavaScript config file
126
+ const configContent = this.generateJSConfig();
127
+ await writeFile(path, configContent);
128
+ }
129
+ else if (ext === '.ts') {
130
+ // Generate TypeScript config file
131
+ const configContent = this.generateTSConfig();
132
+ await writeFile(path, configContent);
133
+ }
134
+ else {
135
+ // Generate JSON config file
136
+ await writeFile(path, JSON.stringify(this.config, null, 2));
137
+ }
138
+ }
139
+ generateJSConfig() {
140
+ return `/** @type {import('parseme').ParsemeConfigFile} */
141
+ export default ${JSON.stringify(this.config, null, 2)};
142
+ `;
143
+ }
144
+ generateTSConfig() {
145
+ return `import type { ParsemeConfigFile } from 'parseme';
146
+
147
+ const config: ParsemeConfigFile = ${JSON.stringify(this.config, null, 2)};
148
+
149
+ export default config;
150
+ `;
151
+ }
152
+ mergeExcludePatterns(configPatterns, rootDir) {
153
+ const defaultPatterns = [
154
+ 'node_modules/**',
155
+ 'dist/**',
156
+ 'build/**',
157
+ 'coverage/**',
158
+ '.git/**',
159
+ '**/*.log',
160
+ '**/*.tmp',
161
+ '**/.DS_Store',
162
+ '**/.*',
163
+ ];
164
+ // Priority: Config patterns > .gitignore patterns > Default patterns
165
+ if (configPatterns) {
166
+ return configPatterns;
167
+ }
168
+ // Try to read .gitignore patterns
169
+ const gitignorePatterns = this.readGitignorePatterns(rootDir);
170
+ if (gitignorePatterns.length > 0) {
171
+ // Merge gitignore patterns with critical defaults
172
+ const criticalDefaults = ['node_modules/**', '.git/**'];
173
+ return [...new Set([...criticalDefaults, ...gitignorePatterns])];
174
+ }
175
+ return defaultPatterns;
176
+ }
177
+ readGitignorePatterns(rootDir) {
178
+ try {
179
+ const gitignorePath = join(rootDir, '.gitignore');
180
+ if (!existsSync(gitignorePath)) {
181
+ return [];
182
+ }
183
+ const gitignoreContent = readFileSync(gitignorePath, 'utf-8');
184
+ return gitignoreContent
185
+ .split('\n')
186
+ .map((line) => line.trim())
187
+ .filter((line) => line && !line.startsWith('#'))
188
+ .map((pattern) => {
189
+ // Convert gitignore patterns to glob patterns
190
+ if (pattern.endsWith('/')) {
191
+ return pattern + '**';
192
+ }
193
+ if (!pattern.includes('/') && !pattern.includes('*')) {
194
+ return '**/' + pattern;
195
+ }
196
+ return pattern;
197
+ });
198
+ }
199
+ catch {
200
+ return [];
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,15 @@
1
+ import { type ParsemeConfigFile } from './config.js';
2
+ import type { ContextOutput, GeneratorOptions } from './types.js';
3
+ export declare class ParsemeGenerator {
4
+ private readonly config;
5
+ private readonly projectAnalyzer;
6
+ private readonly astAnalyzer;
7
+ private readonly frameworkDetector;
8
+ private readonly gitAnalyzer;
9
+ private readonly contextBuilder;
10
+ constructor(options?: GeneratorOptions);
11
+ static fromConfig(configPath?: string): Promise<ParsemeGenerator>;
12
+ static fromConfigWithOptions(configPath?: string, cliOptions?: Partial<ParsemeConfigFile>): Promise<ParsemeGenerator>;
13
+ generate(outputPath?: string): Promise<ContextOutput>;
14
+ generateToFile(outputPath?: string, contextDir?: string): Promise<void>;
15
+ }
@@ -0,0 +1,88 @@
1
+ import { mkdir, writeFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { ASTAnalyzer } from './analyzers/ast-analyzer.js';
4
+ import { FrameworkDetector } from './analyzers/framework-detector.js';
5
+ import { GitAnalyzer } from './analyzers/git-analyzer.js';
6
+ import { ProjectAnalyzer } from './analyzers/project-analyzer.js';
7
+ import { ContextBuilder } from './builders/context-builder.js';
8
+ import { ParsemeConfig } from './config.js';
9
+ export class ParsemeGenerator {
10
+ config;
11
+ projectAnalyzer;
12
+ astAnalyzer;
13
+ frameworkDetector;
14
+ gitAnalyzer;
15
+ contextBuilder;
16
+ constructor(options = {}) {
17
+ this.config = new ParsemeConfig(options);
18
+ this.projectAnalyzer = new ProjectAnalyzer(this.config);
19
+ this.astAnalyzer = new ASTAnalyzer(this.config);
20
+ this.frameworkDetector = new FrameworkDetector(this.config);
21
+ this.gitAnalyzer = new GitAnalyzer(this.config);
22
+ this.contextBuilder = new ContextBuilder(this.config);
23
+ }
24
+ static async fromConfig(configPath) {
25
+ const config = await ParsemeConfig.fromFile(configPath);
26
+ return new ParsemeGenerator(config.get());
27
+ }
28
+ static async fromConfigWithOptions(configPath, cliOptions = {}) {
29
+ const config = await ParsemeConfig.fromFileWithOptions(configPath, cliOptions);
30
+ return new ParsemeGenerator(config.get());
31
+ }
32
+ async generate(outputPath) {
33
+ const configData = this.config.get();
34
+ // Step 1: Analyze the project structure and metadata
35
+ const projectInfo = await this.projectAnalyzer.analyze(configData.rootDir);
36
+ // Step 2: Detect framework and analyze specific patterns
37
+ projectInfo.framework = await this.frameworkDetector.detect(projectInfo);
38
+ // Step 3: Analyze all relevant files with AST
39
+ const fileAnalyses = await this.astAnalyzer.analyzeProject(configData.rootDir);
40
+ // Step 4: Get git information if enabled
41
+ const gitInfo = configData.includeGitInfo
42
+ ? await this.gitAnalyzer.analyze(configData.rootDir)
43
+ : undefined;
44
+ // Calculate final output path for link generation
45
+ const finalOutputPath = outputPath || configData.outputPath || join(configData.rootDir, 'PARSEME.md');
46
+ // Step 5: Build the context output
47
+ return this.contextBuilder.build({
48
+ projectInfo,
49
+ fileAnalyses,
50
+ gitInfo,
51
+ options: configData,
52
+ contextDir: configData.contextDir,
53
+ outputPath: finalOutputPath,
54
+ });
55
+ }
56
+ async generateToFile(outputPath, contextDir) {
57
+ // Use outputPath from config if not specified
58
+ const configData = this.config.get();
59
+ let finalOutputPath;
60
+ if (outputPath) {
61
+ finalOutputPath = outputPath;
62
+ }
63
+ else if (configData.outputPath) {
64
+ // If outputPath is relative, resolve it relative to rootDir
65
+ finalOutputPath = configData.outputPath.startsWith('/')
66
+ ? configData.outputPath
67
+ : join(configData.rootDir, configData.outputPath);
68
+ }
69
+ else {
70
+ finalOutputPath = join(configData.rootDir, 'PARSEME.md');
71
+ }
72
+ const context = await this.generate(finalOutputPath);
73
+ // Use contextDir from config if not specified
74
+ const finalContextDir = contextDir || configData.contextDir || 'parseme-context';
75
+ // If contextDir is relative, make it relative to the output file's directory
76
+ const baseDir = join(finalOutputPath, '..');
77
+ const parsemeDir = finalContextDir.startsWith('/')
78
+ ? finalContextDir // Absolute path
79
+ : join(baseDir, finalContextDir); // Relative path
80
+ await mkdir(parsemeDir, { recursive: true });
81
+ await writeFile(finalOutputPath, context.parseme);
82
+ if (context.context) {
83
+ for (const [filename, content] of Object.entries(context.context)) {
84
+ await writeFile(join(parsemeDir, `${filename}.json`), content);
85
+ }
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,4 @@
1
+ export { ParsemeGenerator } from './generator.js';
2
+ export { ParsemeConfig } from './config.js';
3
+ export type { GeneratorOptions, ContextOutput, ProjectInfo, FrameworkInfo, RouteInfo, FileAnalysis, GitInfo, } from './types.js';
4
+ export type { ParsemeConfigFile } from './config.js';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // Main exports for the parseme package
2
+ export { ParsemeGenerator } from './generator.js';
3
+ export { ParsemeConfig } from './config.js';
@@ -0,0 +1,8 @@
1
+ interface PromptOptions {
2
+ message: string;
3
+ defaultValue?: string;
4
+ choices?: string[];
5
+ }
6
+ export declare function prompt(options: PromptOptions): Promise<string>;
7
+ export declare function confirmPrompt(message: string, defaultValue?: boolean): Promise<boolean>;
8
+ export {};
package/dist/prompt.js ADDED
@@ -0,0 +1,42 @@
1
+ import { createInterface } from 'readline';
2
+ export async function prompt(options) {
3
+ const rl = createInterface({
4
+ input: process.stdin,
5
+ output: process.stdout,
6
+ });
7
+ return new Promise((resolve) => {
8
+ const { message, defaultValue, choices } = options;
9
+ let promptMessage = message;
10
+ if (choices) {
11
+ promptMessage += ` (${choices.join('/')})`;
12
+ }
13
+ if (defaultValue) {
14
+ promptMessage += ` [${defaultValue}]`;
15
+ }
16
+ promptMessage += ': ';
17
+ rl.question(promptMessage, (answer) => {
18
+ rl.close();
19
+ const trimmed = answer.trim();
20
+ if (!trimmed && defaultValue) {
21
+ resolve(defaultValue);
22
+ }
23
+ else if (choices && trimmed) {
24
+ const normalized = trimmed.toLowerCase();
25
+ const match = choices.find((choice) => choice.toLowerCase().startsWith(normalized));
26
+ resolve(match || trimmed);
27
+ }
28
+ else {
29
+ resolve(trimmed);
30
+ }
31
+ });
32
+ });
33
+ }
34
+ export async function confirmPrompt(message, defaultValue = true) {
35
+ const answer = await prompt({
36
+ message,
37
+ defaultValue: defaultValue ? 'y' : 'n',
38
+ choices: ['y', 'n', 'yes', 'no'],
39
+ });
40
+ const normalized = answer.toLowerCase();
41
+ return normalized === 'y' || normalized === 'yes';
42
+ }
@@ -0,0 +1,82 @@
1
+ import type { ServiceInfo, ModelInfo, ConfigInfo, MiddlewareInfo, UtilityInfo } from './analyzers/pattern-detector.js';
2
+ export type { ServiceInfo, ModelInfo, ConfigInfo, MiddlewareInfo, UtilityInfo };
3
+ export interface GeneratorOptions {
4
+ rootDir?: string;
5
+ includeGitInfo?: boolean;
6
+ maxDepth?: number;
7
+ excludePatterns?: string[];
8
+ includePatterns?: string[];
9
+ }
10
+ export interface ProjectInfo {
11
+ name: string;
12
+ version?: string;
13
+ description?: string;
14
+ type: 'typescript' | 'javascript' | 'mixed';
15
+ category: ProjectCategory;
16
+ packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun';
17
+ framework?: FrameworkInfo;
18
+ buildTool?: BuildToolInfo;
19
+ dependencies: Record<string, string>;
20
+ devDependencies: Record<string, string>;
21
+ scripts?: Record<string, string>;
22
+ entryPoints?: string[];
23
+ outputTargets?: string[];
24
+ }
25
+ export type ProjectCategory = 'backend-api' | 'frontend-web' | 'frontend-mobile' | 'npm-package' | 'monorepo' | 'cli-tool' | 'desktop-app' | 'fullstack' | 'unknown';
26
+ export interface BuildToolInfo {
27
+ name: string;
28
+ version?: string;
29
+ configFiles: string[];
30
+ features: string[];
31
+ }
32
+ export interface FrameworkInfo {
33
+ name: string;
34
+ version?: string;
35
+ features: string[];
36
+ routes?: RouteInfo[];
37
+ components?: ComponentInfo[];
38
+ }
39
+ export interface RouteInfo {
40
+ method: string;
41
+ path: string;
42
+ handler: string;
43
+ middleware?: string[];
44
+ file: string;
45
+ line: number;
46
+ }
47
+ export interface ComponentInfo {
48
+ name: string;
49
+ file: string;
50
+ line: number;
51
+ }
52
+ export interface FileAnalysis {
53
+ path: string;
54
+ type: 'route' | 'middleware' | 'model' | 'service' | 'utility' | 'config' | 'test' | 'component';
55
+ framework?: string;
56
+ exports: string[];
57
+ imports: string[];
58
+ functions: string[];
59
+ classes: string[];
60
+ routes?: RouteInfo[];
61
+ components?: ComponentInfo[];
62
+ services?: ServiceInfo[];
63
+ models?: ModelInfo[];
64
+ configs?: ConfigInfo[];
65
+ middleware?: MiddlewareInfo[];
66
+ utilities?: UtilityInfo[];
67
+ }
68
+ export interface ContextOutput {
69
+ parseme: string;
70
+ context?: {
71
+ structure: string;
72
+ routes: string;
73
+ dependencies: string;
74
+ [key: string]: string;
75
+ };
76
+ }
77
+ export interface GitInfo {
78
+ branch: string;
79
+ lastCommit: string;
80
+ changedFiles: string[];
81
+ status: 'clean' | 'dirty';
82
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ // Core types for the parseme package
2
+ export {};