scai 0.1.92 โ†’ 0.1.94

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/README.md CHANGED
@@ -226,14 +226,24 @@ This will:
226
226
 
227
227
  ```bash
228
228
  scai gen summ <file>
229
- scai gen comm <file>
229
+ scai gen comm <file|folder...>
230
230
  scai gen changelog
231
231
  scai gen tests <file>
232
232
  ```
233
233
 
234
234
  * `summ`: Summarize a file
235
- * `comm`: Add comments to a file
235
+
236
+ * `comm`: Add comments to one or more files, or to all matching files in a folder (recursive).
237
+ **Example:**
238
+
239
+ ```bash
240
+ scai gen comm src/ utils/helpers.ts
241
+ ```
242
+
243
+ This will add comments to all `.ts` and `.js` files under `src/` and to `utils/helpers.ts`.
244
+
236
245
  * `changelog`: Update or create `CHANGELOG.md` from Git diff
246
+
237
247
  * `tests`: Create Jest test stubs (ALPHA)
238
248
 
239
249
  You can also pipe file content directly:
@@ -264,22 +274,12 @@ scai stores settings in `~/.scai/config.json`. You can override or view them:
264
274
  scai config
265
275
  ```
266
276
 
267
- <br>
268
-
269
- ## ๐Ÿ” Background Daemon and Indexing โš ๏ธ ALPHA Notice
270
-
271
- These features are experimental and subject to change:
272
-
273
- * `index`, `find`, `ask`
274
- * `daemon`, `stop-daemon`
275
- * `gen tests` (test generation)
276
-
277
- <br>
277
+ ---
278
278
 
279
279
  ## Commands
280
280
 
281
281
  ### `index`
282
- The `index` command is used to manage and perform operations on the indexed files and repositories.
282
+ The `index` command is used to manage and perform operations on the indexed files and repositories. It allows you to control which repository you're working with and have indexed.
283
283
 
284
284
  #### `scai index start`
285
285
 
@@ -289,6 +289,12 @@ Index supported files in the configured index directory.
289
289
  scai index set <dir>
290
290
  ```
291
291
 
292
+ Or just this for cwd (current working dir)
293
+
294
+ ```bash
295
+ scai index set
296
+ ```
297
+
292
298
  Set and activate the index directory.
293
299
  ```bash
294
300
  scai index list
@@ -312,6 +318,104 @@ scai index delete
312
318
 
313
319
  ---
314
320
 
321
+ ## ๐Ÿ›๏ธ Maintenance & Utilities
322
+ # Database Commands
323
+
324
+ Your CLI now supports a set of **database management commands** under the `db` namespace. These commands allow you to check the status of the database, reset it, or run migrations.
325
+
326
+ ---
327
+
328
+ ### ๐Ÿ“‹ Available Commands
329
+
330
+ #### ๐Ÿ” Check Database
331
+
332
+ ```bash
333
+ scai db check
334
+ ```
335
+
336
+ Runs the **dbcheck** script to verify the database status.
337
+
338
+ * Useful for quickly checking if the database is healthy.
339
+ * Prints detailed output directly in the console.
340
+
341
+ ---
342
+
343
+ #### โ™ป๏ธ Reset Database
344
+
345
+ ```bash
346
+ scai db reset
347
+ ```
348
+
349
+ Deletes and resets the SQLite database.
350
+
351
+ * Will ask for confirmation before proceeding.
352
+ * Respond with `y` or `Y` to confirm.
353
+ * Any other key (including `n`, `N`, or just pressing **Enter**) will cancel the reset.
354
+
355
+ ---
356
+
357
+ #### ๐Ÿ“ฆ Run Migrations
358
+
359
+ ```bash
360
+ scai db migrate
361
+ ```
362
+
363
+ Executes all database migration scripts.
364
+
365
+ Note the **Migrate** command is for **internal use only**. Do **not** run it unless explicitly instructed, as it may delete existing data or corrupt your local database.
366
+
367
+ If you're upgrading from an earlier version, please run the following commands to avoid indexing issues:
368
+
369
+ ```bash
370
+ scai db reset
371
+ scai index
372
+ ```
373
+ </br>
374
+
375
+ ---
376
+
377
+ ### โœ… Example Workflow
378
+
379
+ 1. **Check** current database state:
380
+
381
+ ```bash
382
+ scai db check
383
+ ```
384
+
385
+ 2. Confirm you're in the correct repo.
386
+
387
+ ```bash
388
+ scai index list
389
+ ```
390
+
391
+ Use the switch command to switch if necessary.
392
+
393
+ ```bash
394
+ scai index switch
395
+ ```
396
+
397
+ 2. If necessary, **reset** the database:
398
+
399
+ ```bash
400
+ scai db reset
401
+ ```
402
+
403
+ โ†’ Confirm with `y` when prompted.
404
+
405
+ </br>
406
+
407
+ ---
408
+
409
+ ## ๐Ÿ” Background Daemon and Indexing โš ๏ธ ALPHA Notice
410
+
411
+ These features are experimental and subject to change:
412
+
413
+ * `find`, `ask`
414
+ * `daemon`, `stop-daemon`
415
+ * `gen tests` (test generation)
416
+
417
+ <br>
418
+
315
419
  > **Note:** Indexing very large repositories (millions of lines) may take **hours or days**. Please be patient, and only index huge codebases if you are ok with some extra processing taking place on your computer.
316
420
 
317
421
  The `scai index` command **automatically** starts a background daemon that continuously:
@@ -324,8 +428,6 @@ You won't gain much value from the index unless you scope it to one repository.
324
428
 
325
429
  ---
326
430
 
327
- ### ๐Ÿ” Codebase Search & Ask (ALPHA)
328
-
329
431
  > **Important:** You must `index` a **code repository** first or `find` and `ask` have no context to work with.
330
432
 
331
433
  1. **Set index directory:**
@@ -389,40 +491,16 @@ You can run it in two ways:
389
491
 
390
492
  ---
391
493
 
392
- Note the **Migrate** command is for **internal use only**. Do **not** run it unless explicitly instructed, as it may delete existing data or corrupt your local database.
494
+ ### Backup only of `~/.scai`:**
393
495
 
394
- If you're upgrading from an earlier version, please run the following commands to avoid indexing issues:
395
-
396
- ```bash
397
- scai reset-db
398
- scai index
399
- ```
400
- </br>
401
-
402
- ---
403
-
404
- ## ๐Ÿ›๏ธ Maintenance & Utilities
405
-
406
- * **Reset database (w/ backup):**
407
-
408
- ```bash
409
- scai reset-db
410
- ```
411
- * **Backup only of `~/.scai`:**
496
+ Creates a backup of the .scai folder in the user root dir.
412
497
 
413
498
  ```bash
414
499
  scai backup
415
500
  ```
416
501
 
417
- ---
418
-
419
- ## ๐Ÿงบ Module Pipeline Mode
420
-
421
- For custom pipelines on a single file:
422
-
423
- ```bash
424
- scai src/file.ts -m summary,comments
425
- ```
502
+ Results in this:
503
+ ~/.scai_backup_2025-08-12T06-58-00-227Z/
426
504
  ---
427
505
 
428
506
  ## ๐Ÿ” License & Fair Use
package/dist/CHANGELOG.md CHANGED
@@ -121,4 +121,14 @@ Type handling with the module pipeline
121
121
 
122
122
  ## 2025-08-19
123
123
 
124
- * Improved line classification and merging logic
124
+ * Improved line classification and merging logic
125
+
126
+ ## 2025-08-19
127
+
128
+ โ€ข Update `gen` command's `comm` subcommand to allow targeting files or folders
129
+
130
+ ## 2025-08-20
131
+
132
+ โ€ข Add DB-related commands to db subcommand (check, reset, migrate)
133
+ โ€ข Update table view limits for files and functions in dbcheck.ts
134
+ โ€ข Improved resetDatabase command with confirmation prompt before deleting database
@@ -1,12 +1,28 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import lockfile from 'proper-lockfile';
4
+ import readline from 'readline';
4
5
  import { backupScaiFolder } from '../db/backup.js';
5
6
  import { getDbPathForRepo, getDbForRepo } from '../db/client.js';
6
7
  export async function resetDatabase() {
8
+ const dbPath = getDbPathForRepo();
9
+ console.log(`โš ๏ธ You are about to delete the database at: ${dbPath}`);
10
+ const rl = readline.createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout,
13
+ });
14
+ const confirm = await new Promise((resolve) => {
15
+ rl.question('Are you sure you want to proceed? (y/N): ', (answer) => {
16
+ rl.close();
17
+ resolve(answer.trim().toLowerCase() === 'y');
18
+ });
19
+ });
20
+ if (!confirm) {
21
+ console.log('โŒ Reset aborted. Database was not deleted.');
22
+ return;
23
+ }
7
24
  console.log('๐Ÿ” Backing up existing .scai folder...');
8
25
  await backupScaiFolder();
9
- const dbPath = getDbPathForRepo();
10
26
  // Close the DB connection
11
27
  try {
12
28
  const db = getDbForRepo();
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ import { addCommentsModule } from './pipeline/modules/commentModule.js';
31
31
  import { generateTestsModule } from './pipeline/modules/generateTestsModule.js';
32
32
  import { preserveCodeModule } from './pipeline/modules/preserveCodeModule.js';
33
33
  import { runInteractiveDelete } from './commands/DeleteIndex.js';
34
+ import { resolveTargetsToFiles } from './utils/resolveTargetsToFiles.js';
34
35
  // ๐ŸŽ›๏ธ CLI Setup
35
36
  const cmd = new Command('scai')
36
37
  .version(version)
@@ -104,10 +105,13 @@ auth
104
105
  // ๐Ÿ› ๏ธ Group: `gen` commands for content generation
105
106
  const gen = cmd.command('gen').description('Generate code-related output');
106
107
  gen
107
- .command('comm <file>')
108
- .description('Write comments for the given file')
109
- .action((file) => {
110
- handleAgentRun(file, [addCommentsModule, preserveCodeModule]);
108
+ .command("comm <targets...>")
109
+ .description("Write comments for the given file(s) or folder(s)")
110
+ .action(async (targets) => {
111
+ const files = await resolveTargetsToFiles(targets, [".ts", ".js"]);
112
+ for (const file of files) {
113
+ await handleAgentRun(file, [addCommentsModule, preserveCodeModule]);
114
+ }
111
115
  });
112
116
  gen
113
117
  .command('changelog')
@@ -184,14 +188,13 @@ index
184
188
  .action(() => {
185
189
  runInteractiveDelete();
186
190
  });
187
- // This will help resolve the current directory in an ES Module
188
- cmd
189
- .command('check-db')
191
+ const db = cmd.command('db').description('Database operations');
192
+ db
193
+ .command('check')
190
194
  .description('Run the dbcheck script to check the database status')
191
195
  .action(() => {
192
196
  const __filename = fileURLToPath(import.meta.url);
193
197
  const __dirname = dirname(__filename);
194
- // Go up two levels from dist/commands โ†’ dist โ†’ then into dist/scripts/dbcheck.js
195
198
  const scriptPath = resolve(__dirname, '..', 'dist/scripts', 'dbcheck.js');
196
199
  console.log(`๐Ÿš€ Running database check script: ${scriptPath}`);
197
200
  try {
@@ -201,6 +204,14 @@ cmd
201
204
  console.error('โŒ Error running dbcheck script:', err instanceof Error ? err.message : err);
202
205
  }
203
206
  });
207
+ db
208
+ .command('reset')
209
+ .description('Delete and reset the SQLite database')
210
+ .action(() => resetDatabase());
211
+ db
212
+ .command('migrate')
213
+ .description('Run DB migration scripts')
214
+ .action(runMigrateCommand);
204
215
  cmd
205
216
  .command('backup')
206
217
  .description('Backup the current .scai folder')
@@ -226,10 +237,6 @@ cmd
226
237
  .command('stop-daemon')
227
238
  .description('Stop the background summarizer daemon')
228
239
  .action(runStopDaemonCommand);
229
- cmd
230
- .command('migrate')
231
- .description('Run DB migration scripts')
232
- .action(runMigrateCommand);
233
240
  cmd
234
241
  .command('inspect')
235
242
  .argument('<filepath>', 'Path to the file to inspect')
@@ -237,10 +244,6 @@ cmd
237
244
  .action(async (filepath) => {
238
245
  await runInspectCommand(filepath);
239
246
  });
240
- cmd
241
- .command('reset-db')
242
- .description('Delete and reset the SQLite database')
243
- .action(() => resetDatabase());
244
247
  cmd
245
248
  .command('pipe')
246
249
  .description('Run a module pipeline on a given file')
@@ -50,7 +50,7 @@ const summaries = db.prepare(`
50
50
  SELECT id, substr(summary, 1, 50) || '...' AS short_summary
51
51
  FROM files
52
52
  WHERE summary IS NOT NULL AND summary != ''
53
- LIMIT 10
53
+ LIMIT 5
54
54
  `).all();
55
55
  summaries.forEach(row => {
56
56
  console.log(`${row.id.toString().padEnd(4)} ${row.short_summary}`);
@@ -60,7 +60,7 @@ const embeddings = db.prepare(`
60
60
  SELECT id, substr(embedding, 1, 50) || '...' AS short_embedding
61
61
  FROM files
62
62
  WHERE embedding IS NOT NULL AND embedding != ''
63
- LIMIT 10
63
+ LIMIT 5
64
64
  `).all();
65
65
  embeddings.forEach(row => {
66
66
  console.log(`${row.id.toString().padEnd(4)} ${row.short_embedding}`);
@@ -181,14 +181,14 @@ catch (err) {
181
181
  console.error('โŒ Error accessing function_calls table:', err.message);
182
182
  }
183
183
  // === Random Summary Samples ===
184
- console.log('\n๐Ÿงพ 10 Random Summaries (ID + Preview):');
184
+ console.log('\n๐Ÿงพ Random Summaries (ID + Preview):');
185
185
  console.log('-------------------------------------------');
186
186
  const randomSummaries = db.prepare(`
187
187
  SELECT id, filename, substr(summary, 1, 1000) || '...' AS preview
188
188
  FROM files
189
189
  WHERE summary IS NOT NULL AND summary != ''
190
190
  ORDER BY RANDOM()
191
- LIMIT 10
191
+ LIMIT 5
192
192
  `).all();
193
193
  randomSummaries.forEach(row => {
194
194
  console.log(`๐Ÿ“„ [${row.id}] ${row.filename}: ${row.preview}`);
@@ -200,27 +200,27 @@ const randomFunctions = db.prepare(`
200
200
  SELECT id, name, file_id, substr(content, 1, 100) || '...' AS preview
201
201
  FROM functions
202
202
  ORDER BY RANDOM()
203
- LIMIT 20
203
+ LIMIT 5
204
204
  `).all();
205
205
  randomFunctions.forEach(row => {
206
206
  console.log(`๐Ÿ”น [${row.id}] ${row.name} (file_id: ${row.file_id})`);
207
207
  console.log(` ${row.preview}\n`);
208
208
  });
209
- // === Column View of 100 Files ===
210
- console.log('\n๐Ÿ“Š Table View: First 500 Files');
209
+ // === Column View of Files ===
210
+ console.log('\n๐Ÿ“Š Table View: Files');
211
211
  console.log('-------------------------------------------');
212
212
  const fileRows = db.prepare(`
213
213
  SELECT id, filename, type, processing_status, functions_extracted_at, length(summary) AS summary_len
214
214
  FROM files
215
- LIMIT 500
215
+ LIMIT 50
216
216
  `).all();
217
217
  console.table(fileRows);
218
- // === Column View of 100 Functions ===
219
- console.log('\n๐Ÿ“Š Table View: First 500 Functions');
218
+ // === Column View of Functions ===
219
+ console.log('\n๐Ÿ“Š Table View: Functions');
220
220
  console.log('-------------------------------------------');
221
221
  const functionRows = db.prepare(`
222
222
  SELECT id, file_id, name, start_line, end_line, length(content) AS length
223
223
  FROM functions
224
- LIMIT 500
224
+ LIMIT 50
225
225
  `).all();
226
226
  console.table(functionRows);
@@ -0,0 +1,29 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ export async function resolveTargetsToFiles(targets, exts) {
4
+ const files = [];
5
+ for (const target of targets) {
6
+ const stat = await fs.stat(target);
7
+ if (stat.isDirectory()) {
8
+ files.push(...await collectFilesRecursive(target, exts));
9
+ }
10
+ else {
11
+ files.push(target);
12
+ }
13
+ }
14
+ return files;
15
+ }
16
+ async function collectFilesRecursive(dir, exts) {
17
+ const entries = await fs.readdir(dir, { withFileTypes: true });
18
+ const files = [];
19
+ for (const entry of entries) {
20
+ const fullPath = path.join(dir, entry.name);
21
+ if (entry.isDirectory()) {
22
+ files.push(...await collectFilesRecursive(fullPath, exts));
23
+ }
24
+ else if (exts.includes(path.extname(entry.name))) {
25
+ files.push(fullPath);
26
+ }
27
+ }
28
+ return files;
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.92",
3
+ "version": "0.1.94",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"