aidx 1.0.2 → 1.0.3

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.
Files changed (3) hide show
  1. package/dist/index.js +33 -22
  2. package/package.json +4 -6
  3. package/readme.md +5 -5
package/dist/index.js CHANGED
@@ -7,15 +7,13 @@ import { statSync } from 'fs';
7
7
  import path from 'path';
8
8
  import clipboardy from 'clipboardy';
9
9
  import chalk from 'chalk';
10
- import { encode } from 'gpt-tokenizer';
11
10
  import * as Diff from 'diff';
12
- import { isBinaryFile } from 'isbinaryfile';
13
11
  // --- CONFIGURATION ---
14
12
  const METADATA = {
15
13
  name: "aidx",
16
14
  description: "A CLI bridge between local code and LLMs.",
17
15
  author: "rx76d",
18
- version: "1.0.2",
16
+ version: "1.0.3",
19
17
  license: "MIT",
20
18
  github: "https://github.com/rx76d/aidx"
21
19
  };
@@ -46,6 +44,24 @@ console.log("Full code here...");
46
44
  </file>
47
45
  ================================================================
48
46
  `;
47
+ // --- UTILS: ZERO-DEPENDENCY HELPERS ---
48
+ // 1. Token Estimator (1 token ~= 4 chars in Code)
49
+ function estimateTokens(text) {
50
+ return Math.ceil(text.length / 4);
51
+ }
52
+ // 2. Binary Detector (Checks for null bytes in first 1KB)
53
+ function isBinary(buffer) {
54
+ // If file is empty, it's text safe
55
+ if (buffer.length === 0)
56
+ return false;
57
+ // Check first 1000 bytes for a null byte (common in images/binaries)
58
+ const len = Math.min(buffer.length, 1000);
59
+ for (let i = 0; i < len; i++) {
60
+ if (buffer[i] === 0x00)
61
+ return true;
62
+ }
63
+ return false;
64
+ }
49
65
  // --- GLOBAL HANDLERS ---
50
66
  process.on('SIGINT', () => {
51
67
  console.log(chalk.yellow('\n\nOperation cancelled by user.'));
@@ -72,7 +88,7 @@ program
72
88
  .name(METADATA.name)
73
89
  .description(METADATA.description)
74
90
  .version(METADATA.version);
75
- // --- ROOT COMMAND (DASHBOARD) ---
91
+ // --- ROOT COMMAND ---
76
92
  program.action(async () => {
77
93
  const backupEnabled = await getBackupStatus();
78
94
  console.log('\n' + chalk.bgBlue.bold(` ${METADATA.name.toUpperCase()} `) + chalk.dim(` v${METADATA.version}`));
@@ -80,13 +96,12 @@ program.action(async () => {
80
96
  console.log(`${chalk.bold('Description:')} ${METADATA.description}`);
81
97
  console.log(`${chalk.bold('Author:')} ${METADATA.author}`);
82
98
  console.log(`${chalk.bold('Backups:')} ${backupEnabled ? chalk.green('ENABLED') : chalk.dim('DISABLED')}`);
83
- console.log(`${chalk.bold('Limit:')} 1.5MB per file`);
84
99
  console.log(chalk.dim('----------------------------------------'));
85
100
  console.log('\nAvailable Commands:');
86
101
  console.log(` ${chalk.cyan('npx aidx copy')} Select files and copy context`);
87
102
  console.log(` ${chalk.cyan('npx aidx apply')} Apply AI changes to disk`);
88
103
  console.log(` ${chalk.cyan('npx aidx backup --on')} Enable auto-backups`);
89
- console.log(` ${chalk.cyan('npx aidx backup --off')} Disable auto-backups`);
104
+ console.log(` ${chalk.cyan('npx aidx backup --off')} Disable auto-backups`);
90
105
  console.log(` ${chalk.cyan('npx aidx stl')} Show AI token limits`);
91
106
  console.log(`\nRun ${chalk.gray('npx aidx --help')} for details.\n`);
92
107
  });
@@ -152,7 +167,7 @@ program
152
167
  console.log(`\nCurrent Backup Status: ${status ? chalk.green('ENABLED') : chalk.red('DISABLED')}`);
153
168
  }
154
169
  });
155
- // --- COMMAND: COPY (ROBUST) ---
170
+ // --- COMMAND: COPY (FAST) ---
156
171
  program
157
172
  .command('copy')
158
173
  .description('Select files and copy to clipboard')
@@ -160,19 +175,15 @@ program
160
175
  console.log(chalk.blue('Scanning directory...'));
161
176
  const files = await glob(['**/*'], {
162
177
  ignore: [
163
- // Windows System Junk (CRITICAL FOR STABILITY)
164
178
  '**/Application Data/**', '**/Cookies/**', '**/Local Settings/**', '**/Recent/**', '**/Start Menu/**',
165
- // Dev Junk
166
179
  '**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/.vscode/**',
167
180
  '**/__pycache__/**', '**/venv/**', '**/target/**', '**/bin/**', '**/obj/**',
168
- '**/vendor/**',
169
- // File Types
170
- '**/*.lock', '**/*.log', '**/*.png', '**/*.exe', '**/*.dll', '**/*.zip', '**/*.tar', '**/*.gz'
181
+ '**/vendor/**', '**/*.lock', '**/*.log', '**/*.png', '**/*.exe', '**/*.dll', '**/*.zip', '**/*.tar', '**/*.gz'
171
182
  ],
172
183
  onlyFiles: true,
173
184
  dot: true,
174
- suppressErrors: true, // Fixes Windows EPERM crashes
175
- followSymbolicLinks: false // Fixes Infinite Loops
185
+ suppressErrors: true,
186
+ followSymbolicLinks: false
176
187
  });
177
188
  if (files.length === 0)
178
189
  return console.log(chalk.red('Error: No files found.'));
@@ -194,23 +205,22 @@ program
194
205
  console.log(chalk.dim('Reading files...'));
195
206
  for (const file of selectedFiles) {
196
207
  try {
197
- // 1. Check Size
198
208
  const stats = statSync(file);
199
209
  if (stats.size > MAX_FILE_SIZE) {
200
210
  console.log(chalk.yellow(`⚠ Skipped large file (>1.5MB): ${file}`));
201
211
  skippedCount++;
202
212
  continue;
203
213
  }
204
- // 2. Check Binary
205
- if (await isBinaryFile(file)) {
214
+ // Optimized Read: Read buffer first to check binary, then convert to string
215
+ const buffer = await fs.readFile(file);
216
+ if (isBinary(buffer)) {
206
217
  console.log(chalk.yellow(`⚠ Skipped binary file: ${file}`));
207
218
  skippedCount++;
208
219
  continue;
209
220
  }
210
- const content = await fs.readFile(file, 'utf-8');
211
- // 3. Check Secrets
221
+ const content = buffer.toString('utf-8');
212
222
  if (file.includes('.env') || SECRET_REGEX.test(content)) {
213
- console.log(chalk.red(`\nSECURITY ALERT: Secrets detected in ${file}`));
223
+ console.log(chalk.red(`\n🛑 SECURITY ALERT: Secrets detected in ${file}`));
214
224
  skippedCount++;
215
225
  continue;
216
226
  }
@@ -223,14 +233,15 @@ program
223
233
  output += XML_SCHEMA_INSTRUCTION;
224
234
  try {
225
235
  await clipboardy.write(output);
226
- const tokens = encode(output).length;
236
+ // LIGHTWEIGHT TOKENIZER USAGE
237
+ const tokens = estimateTokens(output);
227
238
  const finalCount = selectedFiles.length - skippedCount;
228
239
  const tokenColor = tokens > 100000 ? chalk.red : tokens > 30000 ? chalk.yellow : chalk.green;
229
240
  console.log(chalk.green(`\n✔ Copied ${finalCount} files to clipboard`));
230
241
  console.log(`Estimated Tokens: ${tokenColor(tokens.toLocaleString())}`);
231
242
  }
232
243
  catch (e) {
233
- console.log(chalk.red('Clipboard write failed (File too large for OS).'));
244
+ console.log(chalk.red('Clipboard write failed (File too large for OS).'));
234
245
  console.log(chalk.dim('Try selecting fewer files.'));
235
246
  }
236
247
  });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "aidx",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A CLI bridge between local code and LLMs. Copy context to clipboard and apply AI changes safely with diffs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
- "aidx": "dist/index.js"
8
+ "aidx": "./dist/index.js"
9
9
  },
10
10
  "files": [
11
11
  "dist",
@@ -48,9 +48,7 @@
48
48
  "clipboardy": "^4.0.0",
49
49
  "commander": "^12.0.0",
50
50
  "diff": "^5.2.0",
51
- "fast-glob": "^3.3.2",
52
- "gpt-tokenizer": "^2.1.2",
53
- "isbinaryfile": "^5.0.2"
51
+ "fast-glob": "^3.3.2"
54
52
  },
55
53
  "devDependencies": {
56
54
  "@types/diff": "^5.0.9",
@@ -61,4 +59,4 @@
61
59
  "engines": {
62
60
  "node": ">=18.0.0"
63
61
  }
64
- }
62
+ }
package/readme.md CHANGED
@@ -90,25 +90,25 @@ Command Description
90
90
 
91
91
  # ✨ Features
92
92
 
93
- 🛡️ **Security Guard**
93
+ 🛡️ **Security Guard**:
94
94
  Automatically detects and blocks API keys (AWS, OpenAI, Stripe) from being copied to the clipboard. If a file looks like a secret, it is skipped.
95
95
 
96
- 💾 **Automatic Backups**
96
+ 💾 **Automatic Backups**:
97
97
  Don't trust the AI completely? Turn on backups.
98
98
  ```npx aidx backup --on```
99
99
  Before src/App.tsx is updated, aidx will save a copy to src/App.tsx.bak.
100
100
 
101
- 🌍 **Universal Support**
101
+ 🌍 **Universal Support**:
102
102
  Works with almost any text-based language:
103
103
  Web: TS, JS, HTML, CSS, Svelte, Vue, JSX
104
104
  Backend: Python, Go, Rust, Java, C#, PHP
105
105
  Config: JSON, YAML, TOML, SQL, Markdown
106
106
  Smart Ignores: Automatically ignores node_modules, .git, __pycache__, venv, target, bin, and binary files (.png, .exe).
107
107
 
108
- 📊 **Token Awareness**
108
+ 📊 **Token Awareness**:
109
109
  Calculates estimated token usage before you paste, so you know if you are about to exceed the limits of GPT-5 or Claude 3.5.
110
110
 
111
- 🛡️ **License**
111
+ 🛡️ **License**:
112
112
  This project is open source and available under the MIT License.
113
113
  <div align="center">
114
114
  <sub>Developed by rx76d</sub>