@optiqcode/cli 1.0.0 → 1.2.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/dist/commands/index.js +1 -1
- package/dist/index.js +4 -10
- package/dist/utils/files.js +227 -4
- package/package.json +1 -1
package/dist/commands/index.js
CHANGED
|
@@ -73,7 +73,7 @@ export async function index(options) {
|
|
|
73
73
|
Authorization: `Bearer ${config.apiKey}`,
|
|
74
74
|
'Content-Type': 'application/json',
|
|
75
75
|
},
|
|
76
|
-
timeout:
|
|
76
|
+
timeout: 0, // No timeout for large codebases
|
|
77
77
|
});
|
|
78
78
|
if (response.data.success) {
|
|
79
79
|
spinner.succeed(chalk.green('✓ Indexing complete'));
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import fs from 'fs/promises';
|
|
|
9
9
|
import logUpdate from 'log-update';
|
|
10
10
|
import { getConfig, saveConfig } from './utils/config.js';
|
|
11
11
|
import { isValidDirectory, getGitIgnorePatterns, shouldIgnoreFile } from './utils/files.js';
|
|
12
|
-
const BACKEND_URL = process.env.OPTIQ_BACKEND_URL || '
|
|
12
|
+
const BACKEND_URL = process.env.OPTIQ_BACKEND_URL || 'https://optiqcode.com';
|
|
13
13
|
async function showBanner() {
|
|
14
14
|
console.clear();
|
|
15
15
|
console.log(chalk.white.bold(`
|
|
@@ -194,7 +194,7 @@ async function indexOnce(targetPath, config) {
|
|
|
194
194
|
'X-API-Key': config.apiKey,
|
|
195
195
|
'Content-Type': 'application/json',
|
|
196
196
|
},
|
|
197
|
-
timeout:
|
|
197
|
+
timeout: 0, // No timeout for large codebases
|
|
198
198
|
});
|
|
199
199
|
if (response.data.success) {
|
|
200
200
|
spinner.succeed(chalk.white('✓ Indexing complete'));
|
|
@@ -274,7 +274,7 @@ async function watchDirectory(targetPath, config) {
|
|
|
274
274
|
'X-API-Key': config.apiKey,
|
|
275
275
|
'Content-Type': 'application/json',
|
|
276
276
|
},
|
|
277
|
-
timeout:
|
|
277
|
+
timeout: 0, // No timeout for large codebases
|
|
278
278
|
});
|
|
279
279
|
if (response.data.success) {
|
|
280
280
|
repoId = response.data.repo_id;
|
|
@@ -351,7 +351,7 @@ async function watchDirectory(targetPath, config) {
|
|
|
351
351
|
logUpdate(lines.join('\n'));
|
|
352
352
|
};
|
|
353
353
|
// Update dashboard every 5 seconds to show uptime
|
|
354
|
-
|
|
354
|
+
setInterval(updateDashboard, 5000);
|
|
355
355
|
const processChanges = async () => {
|
|
356
356
|
if (pendingChanges.size === 0 || isProcessing)
|
|
357
357
|
return;
|
|
@@ -359,13 +359,10 @@ async function watchDirectory(targetPath, config) {
|
|
|
359
359
|
const changes = Array.from(pendingChanges.entries());
|
|
360
360
|
pendingChanges.clear();
|
|
361
361
|
// Collect unique files first
|
|
362
|
-
const uniqueFiles = new Set();
|
|
363
362
|
for (const [filePath] of changes) {
|
|
364
363
|
const relativePath = path.relative(targetPath, filePath);
|
|
365
|
-
uniqueFiles.add(relativePath);
|
|
366
364
|
allIndexedFiles.add(relativePath);
|
|
367
365
|
}
|
|
368
|
-
const fileList = Array.from(uniqueFiles);
|
|
369
366
|
try {
|
|
370
367
|
const filesArray = [];
|
|
371
368
|
let hasChanges = false;
|
|
@@ -446,17 +443,14 @@ async function watchDirectory(targetPath, config) {
|
|
|
446
443
|
};
|
|
447
444
|
watcher
|
|
448
445
|
.on('add', (filePath) => {
|
|
449
|
-
const relativePath = path.relative(targetPath, filePath);
|
|
450
446
|
pendingChanges.set(filePath, 'add');
|
|
451
447
|
scheduleProcess();
|
|
452
448
|
})
|
|
453
449
|
.on('change', (filePath) => {
|
|
454
|
-
const relativePath = path.relative(targetPath, filePath);
|
|
455
450
|
pendingChanges.set(filePath, 'change');
|
|
456
451
|
scheduleProcess();
|
|
457
452
|
})
|
|
458
453
|
.on('unlink', (filePath) => {
|
|
459
|
-
const relativePath = path.relative(targetPath, filePath);
|
|
460
454
|
pendingChanges.set(filePath, 'unlink');
|
|
461
455
|
scheduleProcess();
|
|
462
456
|
})
|
package/dist/utils/files.js
CHANGED
|
@@ -1,20 +1,199 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
const DEFAULT_IGNORE_PATTERNS = [
|
|
4
|
-
|
|
4
|
+
// Version Control
|
|
5
5
|
'.git',
|
|
6
|
+
'.svn',
|
|
7
|
+
'.hg',
|
|
8
|
+
'.bzr',
|
|
9
|
+
// JavaScript/Node.js
|
|
10
|
+
'node_modules',
|
|
11
|
+
'bower_components',
|
|
12
|
+
'jspm_packages',
|
|
6
13
|
'dist',
|
|
7
14
|
'build',
|
|
8
|
-
'
|
|
15
|
+
'out',
|
|
9
16
|
'.next',
|
|
10
17
|
'.nuxt',
|
|
11
|
-
'
|
|
18
|
+
'.output',
|
|
19
|
+
'.vuepress/dist',
|
|
20
|
+
'.docusaurus',
|
|
12
21
|
'.cache',
|
|
22
|
+
'.parcel-cache',
|
|
23
|
+
'.turbo',
|
|
24
|
+
'.vercel',
|
|
25
|
+
'.netlify',
|
|
26
|
+
// TypeScript
|
|
27
|
+
'*.tsbuildinfo',
|
|
28
|
+
// Python
|
|
29
|
+
'__pycache__',
|
|
30
|
+
'*.py[cod]',
|
|
31
|
+
'*$py.class',
|
|
32
|
+
'*.so',
|
|
33
|
+
'.Python',
|
|
34
|
+
'env',
|
|
35
|
+
'venv',
|
|
36
|
+
'ENV',
|
|
37
|
+
'env.bak',
|
|
38
|
+
'venv.bak',
|
|
39
|
+
'.venv',
|
|
40
|
+
'pip-log.txt',
|
|
41
|
+
'pip-delete-this-directory.txt',
|
|
42
|
+
'.pytest_cache',
|
|
43
|
+
'.mypy_cache',
|
|
44
|
+
'.dmypy.json',
|
|
45
|
+
'dmypy.json',
|
|
46
|
+
'.pyre',
|
|
47
|
+
'.pytype',
|
|
48
|
+
'celerybeat-schedule',
|
|
49
|
+
'*.egg-info',
|
|
50
|
+
'dist',
|
|
51
|
+
'build',
|
|
52
|
+
'eggs',
|
|
53
|
+
'.eggs',
|
|
54
|
+
'lib',
|
|
55
|
+
'lib64',
|
|
56
|
+
'parts',
|
|
57
|
+
'sdist',
|
|
58
|
+
'var',
|
|
59
|
+
'wheels',
|
|
60
|
+
'*.egg',
|
|
61
|
+
// Rust
|
|
62
|
+
'target',
|
|
63
|
+
'Cargo.lock',
|
|
64
|
+
'**/*.rs.bk',
|
|
65
|
+
// Go
|
|
66
|
+
'vendor',
|
|
67
|
+
'*.exe',
|
|
68
|
+
'*.exe~',
|
|
69
|
+
'*.dll',
|
|
70
|
+
'*.so',
|
|
71
|
+
'*.dylib',
|
|
72
|
+
'*.test',
|
|
73
|
+
'*.out',
|
|
74
|
+
// Java/JVM
|
|
75
|
+
'*.class',
|
|
76
|
+
'*.jar',
|
|
77
|
+
'*.war',
|
|
78
|
+
'*.ear',
|
|
79
|
+
'target',
|
|
80
|
+
'build',
|
|
81
|
+
'.gradle',
|
|
82
|
+
'.mvn',
|
|
83
|
+
'bin',
|
|
84
|
+
'out',
|
|
85
|
+
// C/C++
|
|
86
|
+
'*.o',
|
|
87
|
+
'*.obj',
|
|
88
|
+
'*.a',
|
|
89
|
+
'*.lib',
|
|
90
|
+
'*.so',
|
|
91
|
+
'*.dylib',
|
|
92
|
+
'*.dll',
|
|
93
|
+
'*.exe',
|
|
94
|
+
'*.out',
|
|
95
|
+
'*.app',
|
|
96
|
+
'cmake-build-*',
|
|
97
|
+
'CMakeFiles',
|
|
98
|
+
'CMakeCache.txt',
|
|
99
|
+
// Ruby
|
|
100
|
+
'*.gem',
|
|
101
|
+
'*.rbc',
|
|
102
|
+
'.bundle',
|
|
103
|
+
'vendor/bundle',
|
|
104
|
+
'lib/bundler/man',
|
|
105
|
+
'pkg',
|
|
106
|
+
'spec/reports',
|
|
107
|
+
'test/tmp',
|
|
108
|
+
'test/version_tmp',
|
|
109
|
+
'tmp',
|
|
110
|
+
// PHP
|
|
111
|
+
'vendor',
|
|
112
|
+
'composer.phar',
|
|
113
|
+
'composer.lock',
|
|
114
|
+
// .NET/C#
|
|
115
|
+
'bin',
|
|
116
|
+
'obj',
|
|
117
|
+
'*.dll',
|
|
118
|
+
'*.exe',
|
|
119
|
+
'*.pdb',
|
|
120
|
+
'*.user',
|
|
121
|
+
'*.suo',
|
|
122
|
+
'*.cache',
|
|
123
|
+
'packages',
|
|
124
|
+
// Swift
|
|
125
|
+
'.build',
|
|
126
|
+
'Packages',
|
|
127
|
+
'*.xcodeproj',
|
|
128
|
+
'*.xcworkspace',
|
|
129
|
+
'DerivedData',
|
|
130
|
+
// Elixir
|
|
131
|
+
'_build',
|
|
132
|
+
'deps',
|
|
133
|
+
'*.ez',
|
|
134
|
+
// Scala
|
|
135
|
+
'target',
|
|
136
|
+
'project/target',
|
|
137
|
+
'project/project',
|
|
138
|
+
// Haskell
|
|
139
|
+
'dist',
|
|
140
|
+
'dist-*',
|
|
141
|
+
'cabal-dev',
|
|
142
|
+
'*.hi',
|
|
143
|
+
'*.chi',
|
|
144
|
+
'*.chs.h',
|
|
145
|
+
'.hpc',
|
|
146
|
+
'.hsenv',
|
|
147
|
+
'.cabal-sandbox',
|
|
148
|
+
'cabal.sandbox.config',
|
|
149
|
+
'.stack-work',
|
|
150
|
+
// Dart/Flutter
|
|
151
|
+
'.dart_tool',
|
|
152
|
+
'.flutter-plugins',
|
|
153
|
+
'.flutter-plugins-dependencies',
|
|
154
|
+
'.packages',
|
|
155
|
+
'pubspec.lock',
|
|
156
|
+
// IDEs and Editors
|
|
13
157
|
'.vscode',
|
|
14
158
|
'.idea',
|
|
15
|
-
'*.
|
|
159
|
+
'*.swp',
|
|
160
|
+
'*.swo',
|
|
161
|
+
'*~',
|
|
162
|
+
'.project',
|
|
163
|
+
'.classpath',
|
|
164
|
+
'.settings',
|
|
165
|
+
'*.sublime-project',
|
|
166
|
+
'*.sublime-workspace',
|
|
167
|
+
// OS Files
|
|
16
168
|
'.DS_Store',
|
|
17
169
|
'Thumbs.db',
|
|
170
|
+
'desktop.ini',
|
|
171
|
+
// Logs and Databases
|
|
172
|
+
'*.log',
|
|
173
|
+
'*.sql',
|
|
174
|
+
'*.sqlite',
|
|
175
|
+
'*.sqlite3',
|
|
176
|
+
'*.db',
|
|
177
|
+
// Testing and Coverage
|
|
178
|
+
'coverage',
|
|
179
|
+
'.nyc_output',
|
|
180
|
+
'htmlcov',
|
|
181
|
+
'.tox',
|
|
182
|
+
'.coverage',
|
|
183
|
+
'.coverage.*',
|
|
184
|
+
'nosetests.xml',
|
|
185
|
+
'coverage.xml',
|
|
186
|
+
'*.cover',
|
|
187
|
+
// Documentation
|
|
188
|
+
'docs/_build',
|
|
189
|
+
'site',
|
|
190
|
+
// Temporary files
|
|
191
|
+
'tmp',
|
|
192
|
+
'temp',
|
|
193
|
+
'*.tmp',
|
|
194
|
+
'*.bak',
|
|
195
|
+
'*.swp',
|
|
196
|
+
'*.swo',
|
|
18
197
|
];
|
|
19
198
|
export async function isValidDirectory(dirPath) {
|
|
20
199
|
try {
|
|
@@ -22,6 +201,50 @@ export async function isValidDirectory(dirPath) {
|
|
|
22
201
|
if (!stat.isDirectory()) {
|
|
23
202
|
return { valid: false, error: 'Path is not a directory' };
|
|
24
203
|
}
|
|
204
|
+
// Prevent indexing common non-project directories
|
|
205
|
+
const dirName = path.basename(dirPath);
|
|
206
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
207
|
+
const absolutePath = path.resolve(dirPath);
|
|
208
|
+
// Block home directory
|
|
209
|
+
if (homeDir && path.resolve(absolutePath) === path.resolve(homeDir)) {
|
|
210
|
+
return { valid: false, error: 'Cannot index home directory. Please specify a project directory.' };
|
|
211
|
+
}
|
|
212
|
+
// Block common system/user directories
|
|
213
|
+
const blockedDirs = ['Desktop', 'Documents', 'Downloads', 'Pictures', 'Videos', 'Music'];
|
|
214
|
+
if (homeDir && blockedDirs.some(blocked => path.resolve(absolutePath) === path.resolve(path.join(homeDir, blocked)))) {
|
|
215
|
+
return { valid: false, error: `Cannot index ${dirName} directory. Please specify a project directory.` };
|
|
216
|
+
}
|
|
217
|
+
// Check for project indicators (at least one should exist)
|
|
218
|
+
const projectIndicators = [
|
|
219
|
+
'package.json',
|
|
220
|
+
'Cargo.toml',
|
|
221
|
+
'go.mod',
|
|
222
|
+
'requirements.txt',
|
|
223
|
+
'pyproject.toml',
|
|
224
|
+
'pom.xml',
|
|
225
|
+
'build.gradle',
|
|
226
|
+
'.git',
|
|
227
|
+
'tsconfig.json',
|
|
228
|
+
'composer.json',
|
|
229
|
+
'Gemfile',
|
|
230
|
+
];
|
|
231
|
+
let hasProjectIndicator = false;
|
|
232
|
+
for (const indicator of projectIndicators) {
|
|
233
|
+
try {
|
|
234
|
+
await fs.access(path.join(dirPath, indicator));
|
|
235
|
+
hasProjectIndicator = true;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// File doesn't exist, continue checking
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!hasProjectIndicator) {
|
|
243
|
+
return {
|
|
244
|
+
valid: false,
|
|
245
|
+
error: 'Directory does not appear to be a project (no package.json, Cargo.toml, .git, etc. found)'
|
|
246
|
+
};
|
|
247
|
+
}
|
|
25
248
|
// Count files
|
|
26
249
|
const fileCount = await countFiles(dirPath);
|
|
27
250
|
if (fileCount === 0) {
|