codescoop 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 html-scan contributors
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,249 @@
1
+
2
+ # CodeScoop
3
+
4
+ > **Scoop the exact code you need for component debugging and migration.**
5
+
6
+ [![npm version](https://img.shields.io/npm/v/codescoop.svg)](https://www.npmjs.com/package/codescoop)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ **Stop guessing which CSS rules apply to your HTML. Stop copy-pasting 5,000 lines of code.**
10
+
11
+ CodeScoop is a forensic tool for your frontend. It extracts the dependency graph of a single component—HTML, specific CSS rules, JS events, and variables—so you can debug legacy sites or feed clean context to an LLM.
12
+
13
+ ## The Problem
14
+
15
+ You are trying to fix a bug in a legacy WordPress header, or convert it to Next.js.
16
+ - **The Debugging Nightmare:** You see `class="btn"`, but where is the style coming from? `style.css`? `bootstrap.min.css`? An inline script?
17
+ - **The AI Nightmare:** You paste the HTML into ChatGPT. It hallucinates CSS that doesn't exist or misses the JS logic entirely because you didn't paste the right file.
18
+
19
+ ## The Solution
20
+
21
+ ```bash
22
+ codescoop index.html -s "header"
23
+ ```
24
+
25
+ **One command. Complete context.**
26
+
27
+ CodeScoop analyzes your project and generates a forensic report containing:
28
+
29
+ * The exact HTML structure
30
+ * **The Winning CSS:** Specificity scoring shows you exactly which rule wins (and which are overridden)
31
+ * **Ghost Classes:** Identifies classes in HTML that have *no* matching CSS
32
+ * **JS Forensics:** Finds jQuery listeners and vanilla JS events targeting your elements
33
+ * **Variable Resolution:** Inlines values for `var(--primary)` so you don't need to hunt them down
34
+
35
+ ---
36
+
37
+ ## Key Features
38
+
39
+ ### CSS Conflict Detection
40
+
41
+ Don't just list files. **Solve specificity wars.** CodeScoop calculates specificity scores for every matching rule so you can see exactly why your style isn't applying.
42
+
43
+ ### Ghost Class Detection
44
+
45
+ Cleaning up legacy code? CodeScoop flags classes in your HTML that have **zero matching CSS rules** in your project. Delete them with confidence.
46
+
47
+ ### Smart Extraction
48
+
49
+ It doesn't dump the whole file. It extracts *only* the rules that affect your specific component.
50
+
51
+ * *Result:* A 50-line context file instead of a 5,000-line dump.
52
+
53
+ ### React Conversion Mode (`--for-conversion`)
54
+
55
+ If you *are* migrating, this flag analyzes JS patterns and suggests:
56
+
57
+ * State variables (`useState`)
58
+ * Event handlers to implement
59
+ * Animation libraries to install
60
+
61
+ ### Works With Everything
62
+
63
+ Static HTML, **Live URLs**, PHP, Blade, Twig, EJS, ERB, Handlebars, JSP, ASP.
64
+
65
+ ### Advanced Modern CSS Support
66
+
67
+ * **Shadow DOM:** Native support for `::part()` and `::slotted()` selectors allows you to analyze Web Components styling.
68
+ * **CSS Houdini:** Detects and reports custom properties defined with `@property`, preserving their type syntax and initial values.
69
+
70
+ ---
71
+
72
+ ## Quick Start
73
+
74
+ ```bash
75
+ npm install -g codescoop
76
+
77
+ # 1. Debug a specific component
78
+ codescoop page.html -s ".navbar"
79
+
80
+ # 2. Analyze a live site (e.g., WordPress local dev)
81
+ codescoop http://localhost:8000 -s ".hero" --dir ./wp-content/themes/mytheme
82
+
83
+ # 3. Get a migration-ready bundle for AI
84
+ codescoop page.html -s ".card" --for-conversion
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Usage Scenarios
90
+
91
+ ### 1. The "Why is this not working?" Audit
92
+
93
+ You have a button that refuses to turn blue.
94
+
95
+ ```bash
96
+ codescoop index.html -s ".btn-primary"
97
+ ```
98
+
99
+ **Output:**
100
+
101
+ ```markdown
102
+ ## CSS Conflict Analysis for `.btn-primary`
103
+
104
+ | Status | Specificity | File | Rule |
105
+ |--------|-------------|------|------|
106
+ | Winner | **(0, 2, 0)** | `theme.css:45` | `background: red !important;` |
107
+ | Overridden | **(0, 1, 0)** | `main.css:12` | `background: blue;` |
108
+ | Overridden | **(0, 0, 1)** | `reset.css:5` | `background: gray;` |
109
+ ```
110
+
111
+ *Verdict: `theme.css` is overriding your change with `!important`.*
112
+
113
+ ### 2. The Legacy Cleanup
114
+
115
+ You inherited a 5-year-old site. You want to know which classes are useless.
116
+
117
+ ```bash
118
+ codescoop old-page.html -s "main"
119
+ ```
120
+
121
+ **Output:**
122
+
123
+ ```markdown
124
+ ## Ghost Classes Detected
125
+ These classes appear in the HTML but have NO matching CSS in the project:
126
+
127
+ | Class | Location |
128
+ |-------|----------|
129
+ | `.clearfix-old` | `line 45` |
130
+ | `.legacy-wrapper-v2` | `line 102` |
131
+ | `.hidden-xs` | `line 15` |
132
+ ```
133
+
134
+ *Action: Safe to delete these from your HTML.*
135
+
136
+ ### 3. The "Perfect Context" for AI
137
+
138
+ You want to convert a widget to React.
139
+
140
+ ```bash
141
+ codescoop widget.php -s ".sidebar-widget" --for-conversion
142
+ ```
143
+
144
+ **Output:**
145
+
146
+ * **Clean HTML:** JSX-ready structure
147
+ * **Scoped CSS:** Only the rules needed for this widget
148
+ * **JS Hints:** "Found `$('.widget').on('click')` -> Implement `onClick` handler"
149
+ * **Variables:** `var(--spacing)` resolved to `16px`
150
+
151
+ *Result: Paste this into Claude/GPT and get a working component on the first try.*
152
+
153
+ ---
154
+
155
+ ## How It Works
156
+
157
+ ```
158
+ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
159
+ │ Your Input │───▶│ CodeScoop │───▶│ Forensic Rep │
160
+ │ HTML/URL/PHP │ │ │ │ │
161
+ └─────────────────┘ │ ┌────────────┐ │ │ • Specificity │
162
+ │ │ Parse HTML │ │ │ • Ghost Classes│
163
+ ┌─────────────────┐ │ ├────────────┤ │ │ • JS Events │
164
+ │ Project Files │───▶│ │ Find CSS │ │ │ • Variables │
165
+ │ CSS/SCSS/JS │ │ ├────────────┤ │ │ • Clean Code │
166
+ └─────────────────┘ │ │ Calc Score │ │ └─────────────────┘
167
+ │ ├────────────┤ │
168
+ │ │ Find Ghosts│ │
169
+ │ └────────────┘ │
170
+ └──────────────────┘
171
+ ```
172
+
173
+ ---
174
+
175
+ ## CLI Reference
176
+
177
+ ```bash
178
+ codescoop <source> [options]
179
+ ```
180
+
181
+ | Option | Short | Description |
182
+ | --- | --- | --- |
183
+ | `--selector <sel>` | `-s` | CSS selector to target |
184
+ | `--dir <path>` | `-d` | Project directory to scan (Required for live URLs) |
185
+ | `--for-conversion` | | Add React/Next.js migration hints |
186
+ | `--compact` | `-c` | Minimal output (hides long code blocks) |
187
+ | `--summary-only` | | Just list files and ghost classes |
188
+ | `--skip-minified` | | Exclude `*.min.css` / `*.min.js` |
189
+ | `--max-rules <n>` | | Max CSS rules per file (Default: 50) |
190
+
191
+ ---
192
+
193
+ ## Why Not Just Copy-Paste?
194
+
195
+ | Feature | Manual Copy-Paste | CodeScoop |
196
+ | --- | --- | --- |
197
+ | **Context** | Partial (whatever you see) | Complete (hidden dependencies) |
198
+ | **CSS Conflicts** | Guesswork | **Specificity Scoring** |
199
+ | **Dead Code** | Hard to find | **Ghost Class Detection** |
200
+ | **Variables** | Undefined | Auto-resolved |
201
+ | **Time** | 15+ mins per component | < 10 seconds |
202
+
203
+ ---
204
+
205
+ ---
206
+
207
+ ## How CodeScoop Handles Complexity (The "Black Holes")
208
+
209
+ Frontend analysis is hard. Here is how CodeScoop solves the common "black holes" that break other tools:
210
+
211
+ ### 1. The "Dynamic Class" Trap (`.menu.is-open`)
212
+ * **Problem:** Classes like `.is-open` are often added by JS and missing from static HTML.
213
+ * **Solution:** CodeScoop uses **Greedy Prefix Matching**. If you target `.menu`, we automatically find `.menu.is-open`, `.menu:hover`, and `.menu::before`. We also filter common state classes (`is-*`, `has-*`) to prevent false alarms.
214
+
215
+ ### 2. Nested SCSS (`&__element`)
216
+ * **Problem:** BEM syntax like `&__item` is invisible to standard regex searches.
217
+ * **Solution:** We implement **AST Resolution**. CodeScoop parses your SCSS, unwraps the `&` nesting, and resolves the actual selector (e.g., resolving `&__item` to `.block__item`) to ensure no rule is left behind.
218
+
219
+ ### 3. Tailwind & Runtime CSS
220
+ * **Problem:** Utility classes (`p-4`, `flex`) clutter reports and look like "missing" styles if not built.
221
+ * **Solution:** Our **Smart Filter** distinguishes between likely utility classes (Tailwind/Bootstrap patterns) and your actual missing custom styles, keeping your "Ghost Class" report clean and actionable.
222
+
223
+ ### 4. The Import Maze
224
+ * **Problem:** Styles buried 5 levels deep in `@import` chains are often missed.
225
+ * **Solution:** CodeScoop performs a **Deep Project Scan**, indexing every CSS/SCSS file in your directory to find relevant rules regardless of where they are imported.
226
+
227
+ ### 5. Advanced Modern CSS
228
+ * **Problem:** Modern features like Shadow DOM (`::part`) and CSS Houdini (`@property`) are often ignored by traditional parsers.
229
+ * **Solution:** CodeScoop includes native support for these features, correctly identifying `::part()` and `::slotted()` rules and extracting structured `@property` definitions.
230
+
231
+ ---
232
+
233
+ ## Contributing
234
+
235
+ Found a bug? Want a feature? PRs welcome!
236
+
237
+ ```bash
238
+ git clone https://github.com/yourusername/codescoop.git
239
+ cd codescoop && npm install
240
+ node bin/codescoop.js test/sample.html -s ".navbar"
241
+ ```
242
+
243
+ ---
244
+
245
+ <p align="center">
246
+ <b>Debug faster. Migrate smarter. Scoop exactly what you need.</b>
247
+
248
+ <code>npm install -g codescoop</code>
249
+ </p>
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CodeScoop CLI
5
+ * Extract component dependencies for AI-powered React/Next.js conversion
6
+ */
7
+
8
+ const { program } = require('commander');
9
+ const chalk = require('chalk');
10
+ const path = require('path');
11
+ const fs = require('fs');
12
+ const { runAnalysis } = require('../src/index');
13
+ const { runInteractiveMode } = require('../src/cli/interactive');
14
+ const {
15
+ validateHTMLFile,
16
+ validateOutputPath,
17
+ validateProjectDir,
18
+ sanitizeSelector,
19
+ formatError
20
+ } = require('../src/utils/validation');
21
+ const { fetchURL, isURL } = require('../src/utils/url-fetcher');
22
+ const { isTemplateFile, parseTemplateFile } = require('../src/utils/template-parser');
23
+
24
+ // ASCII Art Banner
25
+ const banner = `
26
+ ${chalk.magenta('╔═══════════════════════════════════════════╗')}
27
+ ${chalk.magenta('║')} ${chalk.bold.white('🍒 CodeScoop')} ${chalk.gray('- Scoop code for AI')} ${chalk.magenta('║')}
28
+ ${chalk.magenta('╚═══════════════════════════════════════════╝')}
29
+ `;
30
+
31
+ program
32
+ .name('codescoop')
33
+ .description('Scoop out component dependencies for AI-powered conversion')
34
+ .version('1.0.0')
35
+ .argument('<source>', 'HTML file, URL, or template (.php, .blade.php, etc.)')
36
+ .option('-s, --selector <selector>', 'CSS selector to target (e.g., ".navbar", "#header")')
37
+ .option('-l, --lines <range>', 'Line range to target (e.g., "45-80")')
38
+ .option('-o, --output <path>', 'Output file path (default: <component>-analysis.md)')
39
+ .option('-d, --dir <path>', 'Project directory to scan (default: directory containing file)')
40
+ .option('-m, --match-index <n>', 'Which match to use if multiple elements found (0-based)', '0')
41
+ .option('-c, --compact', 'Compact mode: limit output size for LLM consumption')
42
+ .option('--for-conversion', 'Generate React/Next.js conversion context for LLMs')
43
+ .option('--max-rules <n>', 'Max CSS rules per file (default: 20 in compact mode)', '20')
44
+ .option('--max-js <n>', 'Max JS references per file (default: 10 in compact mode)', '10')
45
+ .option('--summary-only', 'Only show summary and file list, no code blocks')
46
+ .option('--skip-minified', 'Skip minified files (*.min.css, *.min.js)')
47
+ .option('--no-interactive', 'Skip interactive mode, require --selector or --lines')
48
+ .option('--include-inline', 'Include inline <style> and <script> blocks (default: true)', true)
49
+ .option('--verbose', 'Show detailed logging')
50
+ .action(async (source, options) => {
51
+ console.log(banner);
52
+
53
+ let htmlPath;
54
+ let htmlContent = null;
55
+ let projectDir;
56
+ let sourceType = 'file'; // file, url, or template
57
+
58
+ try {
59
+ // ============================================
60
+ // STEP 1: Detect source type and get HTML
61
+ // ============================================
62
+
63
+ if (isURL(source)) {
64
+ // URL Mode - fetch live page
65
+ sourceType = 'url';
66
+ console.log(chalk.cyan(`🌐 Fetching URL: ${source}`));
67
+
68
+ const result = await fetchURL(source);
69
+ if (result.statusCode !== 200) {
70
+ console.error(chalk.red(`✖ HTTP ${result.statusCode} - Failed to fetch URL`));
71
+ process.exit(1);
72
+ }
73
+
74
+ htmlContent = result.html;
75
+ htmlPath = source;
76
+ console.log(chalk.green(`✓ Fetched ${(htmlContent.length / 1024).toFixed(1)}KB`));
77
+
78
+ // For URL mode, project dir must be specified
79
+ projectDir = options.dir ? path.resolve(options.dir) : null;
80
+ if (!projectDir) {
81
+ console.log(chalk.yellow(`⚠️ No --dir specified. Only inline styles/scripts will be analyzed.`));
82
+ console.log(chalk.gray(` Use --dir /path/to/project to scan local CSS/JS files.`));
83
+ }
84
+
85
+ } else {
86
+ // File Mode - local file
87
+ htmlPath = path.resolve(source);
88
+
89
+ // Check file exists
90
+ if (!fs.existsSync(htmlPath)) {
91
+ console.error(chalk.red(`✖ File not found: ${htmlPath}`));
92
+ process.exit(1);
93
+ }
94
+
95
+ // Check if it's a template file
96
+ if (isTemplateFile(htmlPath)) {
97
+ sourceType = 'template';
98
+ console.log(chalk.cyan(`📄 Parsing template: ${path.basename(htmlPath)}`));
99
+
100
+ const parsed = parseTemplateFile(htmlPath);
101
+ htmlContent = parsed.html;
102
+
103
+ if (parsed.warnings.length > 0) {
104
+ parsed.warnings.forEach(w => console.warn(chalk.yellow(`⚠️ ${w}`)));
105
+ }
106
+
107
+ if (parsed.dynamicClasses.length > 0) {
108
+ console.log(chalk.yellow(`⚠️ Found ${parsed.dynamicClasses.length} dynamic class attributes`));
109
+ }
110
+
111
+ console.log(chalk.green(`✓ Extracted HTML from ${parsed.templateType} template`));
112
+
113
+ } else {
114
+ // Standard HTML file
115
+ sourceType = 'file';
116
+ const validation = validateHTMLFile(htmlPath);
117
+
118
+ validation.warnings.forEach(w => console.warn(chalk.yellow(`⚠️ ${w}`)));
119
+
120
+ if (!validation.valid) {
121
+ validation.errors.forEach(e => console.error(chalk.red(`✖ ${e}`)));
122
+ process.exit(1);
123
+ }
124
+ }
125
+
126
+ // Set project directory
127
+ projectDir = options.dir ? path.resolve(options.dir) : path.dirname(htmlPath);
128
+
129
+ // Validate project directory
130
+ const dirValidation = validateProjectDir(projectDir);
131
+ dirValidation.warnings.forEach(w => console.warn(chalk.yellow(`⚠️ ${w}`)));
132
+
133
+ if (!dirValidation.valid) {
134
+ dirValidation.errors.forEach(e => console.error(chalk.red(`✖ ${e}`)));
135
+ process.exit(1);
136
+ }
137
+ }
138
+
139
+ // ============================================
140
+ // STEP 2: Validate options
141
+ // ============================================
142
+
143
+ // Validate output path if provided
144
+ if (options.output) {
145
+ const outputValidation = validateOutputPath(options.output);
146
+ outputValidation.warnings.forEach(w => console.warn(chalk.yellow(`⚠️ ${w}`)));
147
+
148
+ if (!outputValidation.valid) {
149
+ outputValidation.errors.forEach(e => console.error(chalk.red(`✖ ${e}`)));
150
+ process.exit(1);
151
+ }
152
+ }
153
+
154
+ // Validate selector if provided
155
+ if (options.selector) {
156
+ const selectorValidation = sanitizeSelector(options.selector);
157
+ if (!selectorValidation.valid) {
158
+ console.error(chalk.red(`✖ Invalid selector: ${selectorValidation.error}`));
159
+ process.exit(1);
160
+ }
161
+ options.selector = selectorValidation.selector;
162
+ }
163
+
164
+ // Validate match index
165
+ const matchIndex = parseInt(options.matchIndex, 10);
166
+ if (isNaN(matchIndex) || matchIndex < 0) {
167
+ console.error(chalk.red(`✖ Invalid match-index: "${options.matchIndex}". Must be a non-negative number.`));
168
+ process.exit(1);
169
+ }
170
+
171
+ // Verbose logging
172
+ if (options.verbose) {
173
+ console.log(chalk.gray(`Source type: ${sourceType}`));
174
+ console.log(chalk.gray(`Source: ${htmlPath}`));
175
+ if (projectDir) console.log(chalk.gray(`Project directory: ${projectDir}`));
176
+ }
177
+
178
+ // ============================================
179
+ // STEP 3: Interactive mode if needed
180
+ // ============================================
181
+
182
+ if (!options.selector && !options.lines) {
183
+ if (options.interactive === false) {
184
+ console.error(chalk.red('Error: --selector or --lines required when --no-interactive is set'));
185
+ console.log(chalk.gray('\nExamples:'));
186
+ console.log(chalk.gray(' codescoop page.html -s ".navbar"'));
187
+ console.log(chalk.gray(' codescoop https://site.com --selector "header" --dir ./theme'));
188
+ console.log(chalk.gray(' codescoop template.php -s ".content"'));
189
+ process.exit(1);
190
+ }
191
+
192
+ // Interactive mode only works for local files
193
+ if (sourceType === 'url') {
194
+ console.error(chalk.red('Error: Interactive mode not available for URLs. Use --selector.'));
195
+ process.exit(1);
196
+ }
197
+
198
+ console.log(chalk.yellow('No selector specified. Launching interactive mode...\n'));
199
+ const selection = await runInteractiveMode(htmlPath);
200
+
201
+ if (!selection) {
202
+ console.log(chalk.gray('No selection made. Exiting.'));
203
+ process.exit(0);
204
+ }
205
+
206
+ options.selector = selection.selector;
207
+ }
208
+
209
+ // ============================================
210
+ // STEP 4: Run analysis
211
+ // ============================================
212
+
213
+ const result = await runAnalysis({
214
+ htmlPath,
215
+ htmlContent, // Pass pre-fetched content for URL/template modes
216
+ projectDir,
217
+ selector: options.selector,
218
+ lineRange: options.lines,
219
+ matchIndex: matchIndex,
220
+ outputPath: options.output,
221
+ includeInline: options.includeInline,
222
+ verbose: options.verbose,
223
+ sourceType,
224
+ // Compact mode options
225
+ compact: options.compact,
226
+ forConversion: options.forConversion,
227
+ maxRulesPerFile: parseInt(options.maxRules, 10) || 20,
228
+ maxJsPerFile: parseInt(options.maxJs, 10) || 10,
229
+ summaryOnly: options.summaryOnly,
230
+ skipMinified: options.skipMinified
231
+ });
232
+
233
+ // ============================================
234
+ // STEP 5: Output results
235
+ // ============================================
236
+
237
+ console.log(chalk.green(`\n✓ Analysis complete!`));
238
+ console.log(chalk.white(` Output: ${result.outputPath}`));
239
+ console.log(chalk.gray(` Found ${result.cssMatches} CSS rules, ${result.jsMatches} JS references`));
240
+
241
+ if (result.libraryCount > 0) {
242
+ console.log(chalk.cyan(` Libraries detected: ${result.libraryCount}`));
243
+ }
244
+
245
+ if (result.missingImports && result.missingImports.length > 0) {
246
+ console.log(chalk.yellow(`\n⚠ ${result.missingImports.length} files contain relevant code but are NOT imported:`));
247
+ result.missingImports.slice(0, 5).forEach(file => {
248
+ console.log(chalk.yellow(` - ${file}`));
249
+ });
250
+ if (result.missingImports.length > 5) {
251
+ console.log(chalk.yellow(` ... and ${result.missingImports.length - 5} more`));
252
+ }
253
+ }
254
+
255
+ } catch (error) {
256
+ console.error(chalk.red(`\n✖ ${formatError(error, options.verbose)}`));
257
+ if (options.verbose) {
258
+ console.error(chalk.gray(error.stack));
259
+ }
260
+ process.exit(1);
261
+ }
262
+ });
263
+
264
+ // Handle uncaught errors gracefully
265
+ process.on('uncaughtException', (error) => {
266
+ console.error(chalk.red(`\n✖ Unexpected error: ${error.message}`));
267
+ console.error(chalk.gray('This is likely a bug. Please report it.'));
268
+ process.exit(1);
269
+ });
270
+
271
+ process.on('unhandledRejection', (reason) => {
272
+ console.error(chalk.red(`\n✖ Unhandled promise rejection: ${reason}`));
273
+ process.exit(1);
274
+ });
275
+
276
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "codescoop",
3
+ "version": "1.0.0",
4
+ "description": "Extract HTML component dependencies for AI-powered React/Next.js conversion",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "codescoop": "./bin/codescoop.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/codescoop.js"
11
+ },
12
+ "keywords": [
13
+ "html",
14
+ "css",
15
+ "javascript",
16
+ "react",
17
+ "nextjs",
18
+ "conversion",
19
+ "migration",
20
+ "jquery",
21
+ "wordpress",
22
+ "magento",
23
+ "component",
24
+ "extractor",
25
+ "analyzer",
26
+ "cli",
27
+ "llm",
28
+ "ai",
29
+ "gpt",
30
+ "claude",
31
+ "chatgpt",
32
+ "openai",
33
+ "anthropic",
34
+ "debugging",
35
+ "scss",
36
+ "dependencies",
37
+ "php",
38
+ "blade",
39
+ "twig"
40
+ ],
41
+ "author": "",
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/yourusername/codescoop.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/yourusername/codescoop/issues"
49
+ },
50
+ "homepage": "https://github.com/yourusername/codescoop#readme",
51
+ "engines": {
52
+ "node": ">=16.0.0"
53
+ },
54
+ "files": [
55
+ "bin/",
56
+ "src/",
57
+ "README.md",
58
+ "LICENSE"
59
+ ],
60
+ "dependencies": {
61
+ "acorn": "^8.11.3",
62
+ "acorn-loose": "^8.4.0",
63
+ "acorn-walk": "^8.3.2",
64
+ "chalk": "^4.1.2",
65
+ "cheerio": "^1.0.0-rc.12",
66
+ "commander": "^12.0.0",
67
+ "glob": "^10.3.10",
68
+ "inquirer": "^8.2.6",
69
+ "js-beautify": "^1.14.11",
70
+ "postcss": "^8.4.35",
71
+ "postcss-scss": "^4.0.9",
72
+ "sass": "^1.71.1",
73
+ "specificity": "^1.0.0"
74
+ }
75
+ }