@optiqcode/cli 1.2.0 → 1.2.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.
@@ -3,7 +3,7 @@ import axios from 'axios';
3
3
  import chalk from 'chalk';
4
4
  import ora from 'ora';
5
5
  import { getConfig, saveConfig, clearConfig } from '../utils/config.js';
6
- const API_URL = 'https://optiqcode.com/api';
6
+ const API_URL = process.env.OPTIQ_BACKEND_URL ? `${process.env.OPTIQ_BACKEND_URL}/api` : 'http://localhost:3002/api';
7
7
  export async function login() {
8
8
  // Test comment: verifying incremental indexing works correctly
9
9
  console.log(chalk.blue('🔐 Login to Optiq\n'));
@@ -6,7 +6,7 @@ import path from 'path';
6
6
  import fs from 'fs/promises';
7
7
  import { getConfig } from '../utils/config.js';
8
8
  import { isValidDirectory, getGitIgnorePatterns, shouldIgnoreFile } from '../utils/files.js';
9
- const API_URL = 'https://optiqcode.com/api';
9
+ const API_URL = process.env.OPTIQ_BACKEND_URL ? `${process.env.OPTIQ_BACKEND_URL}/api` : 'http://localhost:3002/api';
10
10
  export async function index(options) {
11
11
  const config = await getConfig();
12
12
  if (!config) {
@@ -64,28 +64,42 @@ export async function index(options) {
64
64
  }
65
65
  }
66
66
  spinner.text = 'Uploading to Optiq...';
67
- // Send to API
68
- const response = await axios.post(`${API_URL}/nexus/index/content`, {
69
- repository_path: targetPath,
70
- files: fileContents,
71
- }, {
72
- headers: {
73
- Authorization: `Bearer ${config.apiKey}`,
74
- 'Content-Type': 'application/json',
75
- },
76
- timeout: 0, // No timeout for large codebases
77
- });
78
- if (response.data.success) {
79
- spinner.succeed(chalk.green('✓ Indexing complete'));
80
- console.log(chalk.blue('📊 Repository ID:'), chalk.bold(response.data.repo_id));
81
- console.log(chalk.blue('📁 Files indexed:'), chalk.bold(response.data.files_processed));
82
- console.log(chalk.blue('📝 Entities indexed:'), chalk.bold(response.data.entities_indexed));
83
- console.log(chalk.dim('\nUse this repo_id with the MCP server or API'));
84
- }
85
- else {
86
- spinner.fail(chalk.red('✗ Indexing failed'));
87
- console.log(chalk.red(response.data.error || 'Unknown error'));
67
+ // Batch upload files (50 at a time to avoid 413 errors)
68
+ const BATCH_SIZE = 50;
69
+ let uploadedCount = 0;
70
+ let repoId = '';
71
+ let totalFilesProcessed = 0;
72
+ let totalEntitiesIndexed = 0;
73
+ for (let i = 0; i < fileContents.length; i += BATCH_SIZE) {
74
+ const batch = fileContents.slice(i, i + BATCH_SIZE);
75
+ const batchNum = Math.floor(i / BATCH_SIZE) + 1;
76
+ const totalBatches = Math.ceil(fileContents.length / BATCH_SIZE);
77
+ spinner.text = `Uploading batch ${batchNum}/${totalBatches} (${uploadedCount}/${fileContents.length} files)...`;
78
+ const response = await axios.post(`${API_URL}/nexus/index/content`, {
79
+ repository_path: targetPath,
80
+ files: batch,
81
+ }, {
82
+ headers: {
83
+ Authorization: `Bearer ${config.apiKey}`,
84
+ 'Content-Type': 'application/json',
85
+ },
86
+ timeout: 0, // No timeout for large codebases
87
+ });
88
+ if (!response.data.success) {
89
+ spinner.fail(chalk.red('✗ Indexing failed'));
90
+ console.log(chalk.red(response.data.error || 'Unknown error'));
91
+ return;
92
+ }
93
+ repoId = response.data.repo_id;
94
+ totalFilesProcessed += response.data.files_processed || 0;
95
+ totalEntitiesIndexed += response.data.entities_indexed || 0;
96
+ uploadedCount += batch.length;
88
97
  }
98
+ spinner.succeed(chalk.green('✓ Indexing complete'));
99
+ console.log(chalk.blue('📊 Repository ID:'), chalk.bold(repoId));
100
+ console.log(chalk.blue('📁 Files indexed:'), chalk.bold(totalFilesProcessed));
101
+ console.log(chalk.blue('📝 Entities indexed:'), chalk.bold(totalEntitiesIndexed));
102
+ console.log(chalk.dim('\nUse this repo_id with the MCP server or API'));
89
103
  }
90
104
  catch (error) {
91
105
  spinner.fail(chalk.red('✗ Indexing failed'));
@@ -6,7 +6,7 @@ import path from 'path';
6
6
  import fs from 'fs/promises';
7
7
  import { getConfig } from '../utils/config.js';
8
8
  import { isValidDirectory, getGitIgnorePatterns, shouldIgnoreFile } from '../utils/files.js';
9
- const API_URL = 'https://optiqcode.com/api';
9
+ const API_URL = process.env.OPTIQ_BACKEND_URL ? `${process.env.OPTIQ_BACKEND_URL}/api` : 'http://localhost:3002/api';
10
10
  export async function watch(options) {
11
11
  const config = await getConfig();
12
12
  if (!config) {
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 || 'https://optiqcode.com';
12
+ const BACKEND_URL = process.env.OPTIQ_BACKEND_URL || 'http://localhost:3002';
13
13
  async function showBanner() {
14
14
  console.clear();
15
15
  console.log(chalk.white.bold(`
@@ -266,27 +266,35 @@ async function watchDirectory(targetPath, config) {
266
266
  path,
267
267
  content,
268
268
  }));
269
- const response = await axios.post(`${BACKEND_URL}/api/nexus/index/content`, {
270
- repository_path: targetPath,
271
- files: filesArray,
272
- }, {
273
- headers: {
274
- 'X-API-Key': config.apiKey,
275
- 'Content-Type': 'application/json',
276
- },
277
- timeout: 0, // No timeout for large codebases
278
- });
279
- if (response.data.success) {
269
+ // Batch upload files (50 at a time to avoid 413 errors)
270
+ const BATCH_SIZE = 50;
271
+ let uploadedCount = 0;
272
+ for (let i = 0; i < filesArray.length; i += BATCH_SIZE) {
273
+ const batch = filesArray.slice(i, i + BATCH_SIZE);
274
+ const batchNum = Math.floor(i / BATCH_SIZE) + 1;
275
+ const totalBatches = Math.ceil(filesArray.length / BATCH_SIZE);
276
+ spinner.text = `Uploading batch ${batchNum}/${totalBatches} (${uploadedCount}/${filesArray.length} files)...`;
277
+ const response = await axios.post(`${BACKEND_URL}/api/nexus/index/content`, {
278
+ repository_path: targetPath,
279
+ files: batch,
280
+ }, {
281
+ headers: {
282
+ 'X-API-Key': config.apiKey,
283
+ 'Content-Type': 'application/json',
284
+ },
285
+ timeout: 0, // No timeout for large codebases
286
+ });
287
+ if (!response.data.success) {
288
+ spinner.fail(chalk.gray('Initial indexing failed'));
289
+ console.log(chalk.gray(response.data.error || 'Unknown error'));
290
+ return;
291
+ }
280
292
  repoId = response.data.repo_id;
281
- spinner.succeed(chalk.white(`Indexed ${files.length} files`));
282
- console.log(chalk.gray('Repository ID:'), chalk.white.bold(repoId));
283
- console.log();
284
- }
285
- else {
286
- spinner.fail(chalk.gray('Initial indexing failed'));
287
- console.log(chalk.gray(response.data.error || 'Unknown error'));
288
- return;
293
+ uploadedCount += batch.length;
289
294
  }
295
+ spinner.succeed(chalk.white(`Indexed ${files.length} files`));
296
+ console.log(chalk.gray('Repository ID:'), chalk.white.bold(repoId));
297
+ console.log();
290
298
  }
291
299
  catch (error) {
292
300
  spinner.fail(chalk.gray('✗ Initial indexing failed'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optiqcode/cli",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "CLI tool for Optiq - automatic code indexing and context engine",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,4 +51,4 @@
51
51
  "@types/prompts": "^2.4.9",
52
52
  "typescript": "^5.3.0"
53
53
  }
54
- }
54
+ }