scai 0.1.67 → 0.1.68

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.
@@ -1,5 +1,6 @@
1
1
  // File: src/utils/buildContextualPrompt.ts
2
2
  import chalk from 'chalk';
3
+ import path from 'path';
3
4
  function estimateTokenCount(text) {
4
5
  return Math.round(text.length / 4); // simple heuristic approximation
5
6
  }
@@ -36,21 +37,39 @@ export function buildContextualPrompt({ baseInstruction, code, summary, function
36
37
  const prompt = parts.join('\n\n');
37
38
  const tokenEstimate = estimateTokenCount(prompt);
38
39
  // 🔵 Colorized diagnostic output
40
+ // 🔵 Colorized diagnostic output
39
41
  const header = chalk.bgBlue.white.bold(' [SCAI] Prompt Overview ');
40
42
  const labelColor = chalk.cyan;
41
43
  const contentColor = chalk.gray;
42
44
  console.log('\n' + header);
43
45
  console.log(labelColor('🔢 Token Estimate:'), contentColor(`${tokenEstimate.toLocaleString()} tokens`));
44
- console.log(labelColor('🧩 Prompt Sections:'));
45
- console.log(contentColor([
46
- summary ? '📄 Summary' : null,
47
- functions?.length ? '🔧 Functions' : null,
48
- relatedFiles?.length ? '📚 Related Files' : null,
49
- projectFileTree ? '📁 File Tree' : null,
50
- '📦 Code',
51
- ]
52
- .filter(Boolean)
53
- .join(', ')));
46
+ // 📄 Summary
47
+ if (summary) {
48
+ console.log(labelColor('📄 Summary:'), contentColor(`${estimateTokenCount(summary).toLocaleString()} tokens`));
49
+ }
50
+ // 🔧 Functions
51
+ if (functions?.length) {
52
+ const fnCount = functions.length;
53
+ const fnTokens = functions.reduce((sum, f) => sum + estimateTokenCount(f.content), 0);
54
+ console.log(labelColor(`🔧 Functions (${fnCount}):`), contentColor(`${fnTokens.toLocaleString()} tokens`));
55
+ }
56
+ // 📚 Related Files
57
+ if (relatedFiles?.length) {
58
+ const relCount = relatedFiles.length;
59
+ const relTokens = relatedFiles.reduce((sum, f) => sum + estimateTokenCount(f.summary), 0);
60
+ console.log(labelColor(`📚 Related Files (${relCount}):`), contentColor(`${relTokens.toLocaleString()} tokens`));
61
+ // Optional: Show top 3 file names
62
+ const fileList = relatedFiles.slice(0, 3).map(f => `- ${path.basename(f.path)}`).join('\n');
63
+ if (fileList)
64
+ console.log(contentColor(fileList + (relCount > 3 ? `\n ...+${relCount - 3} more` : '')));
65
+ }
66
+ // 📁 File Tree
67
+ if (projectFileTree) {
68
+ console.log(labelColor('📁 File Tree:'), contentColor(`${estimateTokenCount(projectFileTree).toLocaleString()} tokens`));
69
+ }
70
+ // 📦 Code Section
71
+ console.log(labelColor('📦 Code:'), contentColor(`${estimateTokenCount(prompt).toLocaleString()} tokens`));
72
+ // 📌 Key
54
73
  console.log(labelColor('🔍 Key:'), contentColor('[buildContextualPrompt]\n'));
55
74
  return prompt;
56
75
  }
@@ -1,17 +1,38 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { getIndexDir } from '../constants.js';
4
- export function generateFocusedFileTree(focusPath, maxDepth = 2) {
4
+ /**
5
+ * Generate a reduced file tree centered around the focus path, including nearby sibling folders.
6
+ */
7
+ export function generateFocusedFileTree(focusPath, maxDepth = 2, siblingWindow = 2) {
5
8
  const absoluteFocus = path.resolve(focusPath);
6
- const parentDir = path.dirname(absoluteFocus);
9
+ const fileOrDir = fs.statSync(absoluteFocus);
10
+ const targetDir = fileOrDir.isDirectory()
11
+ ? absoluteFocus
12
+ : path.dirname(absoluteFocus);
13
+ const parentDir = path.dirname(targetDir);
7
14
  const indexDir = getIndexDir();
8
- const relativeTitle = path.relative(indexDir, parentDir).replace(/\\/g, '/');
9
- const tree = generateFileTree(parentDir, maxDepth, absoluteFocus);
10
- return `📂 ${relativeTitle || '.'}\n${tree}`;
15
+ const siblings = fs
16
+ .readdirSync(parentDir, { withFileTypes: true })
17
+ .filter(entry => entry.isDirectory())
18
+ .sort((a, b) => a.name.localeCompare(b.name));
19
+ const focusIndex = siblings.findIndex(entry => path.resolve(path.join(parentDir, entry.name)) === path.resolve(targetDir));
20
+ const start = Math.max(0, focusIndex - siblingWindow);
21
+ const end = Math.min(siblings.length, focusIndex + siblingWindow + 1);
22
+ const nearbySiblings = siblings.slice(start, end);
23
+ const relativeTitle = path.relative(indexDir, parentDir).replace(/\\/g, '/') || '.';
24
+ let output = `📂 ${relativeTitle}\n`;
25
+ nearbySiblings.forEach(entry => {
26
+ const siblingPath = path.join(parentDir, entry.name);
27
+ const isFocusDir = path.resolve(siblingPath) === path.resolve(targetDir);
28
+ const tree = generateFileTree(siblingPath, maxDepth - 1, isFocusDir ? absoluteFocus : undefined, '│ ');
29
+ output += `${isFocusDir ? '➡️ ' : ''}${entry.name}/\n${tree}`;
30
+ });
31
+ return output;
11
32
  }
12
33
  function generateFileTree(dir, depth, highlightPath, prefix = '') {
13
34
  if (depth < 0)
14
- return ''; // Stop at maxDepth
35
+ return '';
15
36
  let output = '';
16
37
  const entries = fs.readdirSync(dir, { withFileTypes: true });
17
38
  const sorted = entries.sort((a, b) => Number(b.isDirectory()) - Number(a.isDirectory()));
@@ -20,13 +41,11 @@ function generateFileTree(dir, depth, highlightPath, prefix = '') {
20
41
  const connector = isLast ? '└── ' : '├── ';
21
42
  const fullPath = path.join(dir, entry.name);
22
43
  const isHighlighted = highlightPath && path.resolve(fullPath) === path.resolve(highlightPath);
23
- // If it is a directory, recurse and reduce depth
24
44
  if (entry.isDirectory()) {
25
45
  output += `${prefix}${connector}${entry.name}/\n`;
26
46
  output += generateFileTree(fullPath, depth - 1, highlightPath, prefix + (isLast ? ' ' : '│ '));
27
47
  }
28
48
  else {
29
- // Highlight the file if it matches the focusPath
30
49
  const name = isHighlighted ? `➡️ ${entry.name}` : entry.name;
31
50
  output += `${prefix}${connector}${name}\n`;
32
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.67",
3
+ "version": "0.1.68",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"