scai 0.1.20 → 0.1.22

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
@@ -1,150 +1,145 @@
1
1
  # ⚙️ scai — Smart Commit AI ✨
2
2
 
3
- > AI-powered CLI tools for smart commit messages, code comments, summaries, and changelogs — all powered by local models.
3
+ > AI-powered CLI tool for smart commit messages, code comments, summaries, test generation, and changelogs — all powered by local models.
4
4
 
5
- **scai** (Smart Commit AI) is a lightweight, privacy-focused CLI tool that uses local AI models (via [Ollama](https://ollama.com)) to help developers work faster and cleaner:
5
+ **scai** (Smart Commit AI) is a lightweight, privacy-focused CLI tool that helps developers work faster and cleaner:
6
6
 
7
7
  - 💬 Suggest high-quality Git commit messages
8
8
  - ✨ Automatically comment your code
9
9
  - 🧠 Summarize code files instantly in the terminal
10
+ - 🧪 Generate test files for your code (JavaScript/TypeScript)
10
11
  - 📝 Generate changelog entries based on Git diffs
11
- - 🔒 100% local — no API keys, no cloud, no telemetry
12
+ - 🔒 100% local — no API keys, no cloud, no telemetry
12
13
 
13
14
  ---
14
15
 
15
16
  ## 🚀 Features
16
17
 
17
- - ⚡️ Powered by local Ollama models like `llama3` and `codellama`
18
- - 🛠️ CLI built with Node.js + TypeScript
19
- - 🔒 No external services, full privacy by design
20
- - ✅ Global options for model and language selection
18
+ - ⚡️ Powered by local AI models (e.g., `llama3`, `codellama`)
19
+ - 🛠️ Built with Node.js and TypeScript
20
+ - 🔒 No external services or APIs required
21
+ - ✅ Global options to select model and programming language
21
22
 
22
23
  ---
23
24
 
24
25
  ## ❤️ Why Local AI?
25
26
 
26
- We believe your code — and your workflow — should stay **yours**. scai runs entirely on your machine using open-source models and tools.
27
+ At scai, we believe your code — and your workflow — should stay **yours**. That's why we prioritize **local models** and **privacy-first** development:
27
28
 
28
- Works entirely offline
29
- No API keys or cloud dependencies
30
- Backed by open-source models
31
- ✅ Designed for CLI-first developers
29
+ - **Local models**: scai runs entirely on your machine, with no need for cloud-based processing. We use open-source models like `llama3` and `codellama`, ensuring that your code stays private and secure.
30
+ - **Privacy by design**: We do not send your code to the cloud, store your data, or require API keys. Your data remains 100% local, ensuring full control over your project.
31
+ - **EU & Danish friendly**: As a Danish company, we are deeply committed to respecting European privacy regulations (GDPR). This means no data collection, no tracking, and full compliance with the strictest data protection laws.
32
+
33
+ By running everything locally, you can be sure that your sensitive code and workflows stay safe, private, and within your control.
34
+
35
+ ---
32
36
 
33
37
  ## 📦 Installation
34
38
 
35
- 1. **Install [Ollama](https://ollama.com)**
39
+ 1. **Install Ollama:**
36
40
  - On **Windows**: [Download Ollama](https://ollama.com/download)
37
- - On **macOS**:
38
- - Via Homebrew:
39
- ```bash
40
- brew install ollama
41
- ```
42
- - Or download directly from the website
41
+ - On **macOS**: via Homebrew (`brew install ollama`) or [download from Ollama](https://ollama.com)
43
42
 
44
- 2. **Install scai globally:**
43
+ 2. **Install scai globally:**
44
+ ```bash
45
+ npm install -g scai
46
+ ```
45
47
 
46
- ```bash
47
- npm install -g scai
48
- ```
48
+ 3. **Initialize the tool and models:**
49
+ ```bash
50
+ scai init
51
+ ```
49
52
 
50
- 3. **Initialize the tool and models:**
53
+ This will download required models and set up scai.
51
54
 
52
- ```bash
53
- scai init
54
- ```
55
+ ---
55
56
 
56
- This will:
57
- - Start the Ollama background server
58
- - Download required models (`llama3`, etc.)
57
+ ## ⚒️ Usage Examples
59
58
 
60
- ## 🧪 Usage Examples
59
+ ### 🔧 Git Commands
61
60
 
62
- ### 💬 Suggest a commit message
61
+ - **Suggest a commit message:**
62
+ ```bash
63
+ git add .
64
+ scai git sugg
65
+ ```
63
66
 
64
- ```bash
65
- git add .
66
- scai sugg
67
- ```
67
+ *Example output:*
68
+ ```
69
+ feat(api): add error handling to user service
70
+ ```
68
71
 
69
- > Example output:
70
- ```
71
- feat(api): add error handling to user service
72
- ```
72
+ To commit automatically with the suggestion:
73
+ ```bash
74
+ scai git sugg --commit
75
+ ```
73
76
 
74
- To commit automatically with the suggestion:
77
+ ### 🛠️ Generate Code-Related Output (`gen` commands)
75
78
 
76
- ```bash
77
- scai sugg --commit
78
- ```
79
+ - **Summarize a code file:**
80
+ ```bash
81
+ scai gen summ <file>
82
+ ```
79
83
 
80
- ---
84
+ Prints a summary of what the code does directly in the terminal. You can also pipe file content:
85
+ ```bash
86
+ cat <file> | scai gen summ
87
+ ```
81
88
 
82
- ### Comment a code file
89
+ - **Generate tests for a code file:**
90
+ ```bash
91
+ scai gen tests <file>
92
+ ```
83
93
 
84
- ```bash
85
- scai comm <file>
86
- ```
94
+ Creates a Jest test file for the specified JavaScript/TypeScript module.
87
95
 
88
- Adds clear, helpful comments to the code. Optional flag:
89
- - `-a, --apply` — Overwrite the original file with the commented version
96
+ - **Update the changelog:**
97
+ ```bash
98
+ scai gen changelog
99
+ ```
90
100
 
91
- ---
92
-
93
- ### 🔍 Summarize a code file
101
+ Analyzes the current Git diff and updates (or creates) a `CHANGELOG.md` file with relevant changes.
94
102
 
95
- ```bash
96
- scai summ <file>
97
- ```
103
+ ## ⚙️ Configuration
98
104
 
99
- Prints a summary of what the code does directly to your terminal.
105
+ scai stores your configuration locally in the `~/.scai/config.json` file. You can configure the model and programming language settings as follows:
100
106
 
101
- To pipe input for summarization:
107
+ - **Set the model:**
108
+ ```bash
109
+ scai set model <model>
110
+ ```
102
111
 
103
- ```bash
104
- cat <file> | scai summ
105
- ```
112
+ e.g., `scai set model codellama:7b`
106
113
 
107
- ---
114
+ - **Set the programming language:**
115
+ ```bash
116
+ scai set lang <lang>
117
+ ```
108
118
 
109
- ### 📝 Update the changelog
119
+ e.g., `scai set lang rust`
110
120
 
111
- ```bash
112
- scai changelog
113
- ```
121
+ - **Show current configuration:**
122
+ ```bash
123
+ scai config
124
+ ```
114
125
 
115
- Analyzes the current Git diff and updates (or creates) a `CHANGELOG.md` file with relevant public-facing changes.
126
+ You can also use global options `--model` and `--lang` with any command to override the settings:
127
+ ```bash
128
+ scai --model codellama:34b --lang ts git sugg
129
+ ```
116
130
 
117
131
  ---
118
132
 
119
- ### 📦 Module Pipeline (Advanced Usage)
120
-
121
- For more advanced functionality, scai allows you to run custom pipelines with multiple modules to process code. You can specify multiple modules to be run, such as comment, summary, cleanup, and more.
122
-
123
- ```bash
124
- scai <file> --modules comment,summary,cleanup
125
- ```
126
- Like with regular Unix commands you can pipe this to a file
127
-
128
- ```bash
129
- scai <file> --modules comment,summary > test.txt
130
- ```
131
- Or to both stdout and a file with tee fx.
132
- ```bash
133
- scai <file> --modules comment,summary | tee test.txt
134
- ```
135
-
136
133
  ## 🔐 License & Fair Use
137
134
 
138
135
  **scai is free to use** for individuals, teams, and companies — including in commercial work.
139
136
 
140
137
  You may:
141
-
142
138
  - ✅ Use it internally in your projects
143
139
  - ✅ Use it at work or in commercial development
144
140
  - ✅ Share and recommend it
145
141
 
146
142
  But you may not:
147
-
148
143
  - ❌ Repackage or resell **scai** as a product or SaaS
149
144
  - ❌ Claim ownership of the tool
150
145
 
@@ -6,15 +6,37 @@ import { shouldIgnoreFile } from '../utils/shouldIgnoreFiles.js';
6
6
  import { detectFileType } from '../utils/detectFileType.js';
7
7
  import { runDaemonScheduler } from './DaemonCmd.js';
8
8
  import { IGNORED_FOLDER_GLOBS } from '../config/IgnoredPaths.js';
9
+ import { db } from '../db/client.js';
9
10
  const IGNORE = [
10
11
  '**/node_modules/**', '**/dist/**', '**/build/**',
11
12
  '**/coverage/**', '**/.git/**', '**/*.test.*'
12
13
  ];
13
14
  export async function runIndexCommand(targetDir = process.cwd(), options = {}) {
14
- console.log(`📂 Indexing files in: ${targetDir}`);
15
+ const resolvedDir = path.resolve(targetDir);
16
+ console.log(`📂 Indexing files in: ${resolvedDir}`);
15
17
  initSchema();
18
+ // 🧠 Check if another directory has already been indexed
19
+ const indexedPaths = db.prepare(`
20
+ SELECT DISTINCT path FROM files LIMIT 100
21
+ `).all();
22
+ const knownRoot = indexedPaths.length > 0
23
+ ? path.dirname(indexedPaths[0].path)
24
+ : null;
25
+ if (knownRoot && !resolvedDir.startsWith(knownRoot) && !options.force) {
26
+ console.warn(`⚠️ You're indexing a different folder than before:
27
+ - Previously: ${knownRoot}
28
+ - Now: ${resolvedDir}
29
+
30
+ This will add more files into the existing index and may reduce accuracy or performance.
31
+
32
+ Use --force to continue, or consider clearing the index:
33
+ scai reset-db
34
+
35
+ Aborting.`);
36
+ process.exit(1);
37
+ }
16
38
  const files = await fg('**/*.*', {
17
- cwd: targetDir,
39
+ cwd: resolvedDir,
18
40
  ignore: IGNORED_FOLDER_GLOBS,
19
41
  absolute: true,
20
42
  });
@@ -28,7 +50,7 @@ export async function runIndexCommand(targetDir = process.cwd(), options = {}) {
28
50
  indexFile(file, null, type); // empty summary for now
29
51
  const ext = path.extname(file);
30
52
  countByExt[ext] = (countByExt[ext] || 0) + 1;
31
- console.log(`📄 Indexed: ${path.relative(targetDir, file)}`);
53
+ console.log(`📄 Indexed: ${path.relative(resolvedDir, file)}`);
32
54
  count++;
33
55
  }
34
56
  catch (err) {
@@ -39,6 +61,6 @@ export async function runIndexCommand(targetDir = process.cwd(), options = {}) {
39
61
  console.log(`✅ Done. Indexed ${count} files.`);
40
62
  if (options.detached) {
41
63
  console.log('🚀 Starting summarizer daemon in background mode...');
42
- runDaemonScheduler(); // Infinite loop every 30 min
64
+ runDaemonScheduler();
43
65
  }
44
66
  }
package/dist/config.js ADDED
@@ -0,0 +1,68 @@
1
+ import fs from 'fs';
2
+ import { CONFIG_PATH, SCAI_HOME, INDEX_DIR } from './constants.js'; // Correctly import INDEX_DIR from constants
3
+ // Default configuration values
4
+ const defaultConfig = {
5
+ model: 'llama3',
6
+ language: 'ts',
7
+ indexDir: INDEX_DIR, // Default index directory from constants
8
+ };
9
+ // Function to ensure the configuration directory exists
10
+ function ensureConfigDir() {
11
+ if (!fs.existsSync(SCAI_HOME)) {
12
+ fs.mkdirSync(SCAI_HOME, { recursive: true });
13
+ }
14
+ }
15
+ // Function to read the configuration file
16
+ function readConfig() {
17
+ try {
18
+ const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
19
+ return { ...defaultConfig, ...JSON.parse(content) };
20
+ }
21
+ catch {
22
+ return defaultConfig; // Return default config if read fails
23
+ }
24
+ }
25
+ // Function to write the configuration to the config file
26
+ function writeConfig(newConfig) {
27
+ ensureConfigDir();
28
+ const current = readConfig();
29
+ const merged = { ...current, ...newConfig };
30
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(merged, null, 2));
31
+ }
32
+ export const Config = {
33
+ // Get the current model from the config
34
+ getModel() {
35
+ return readConfig().model;
36
+ },
37
+ // Set a new model in the config
38
+ setModel(model) {
39
+ writeConfig({ model });
40
+ console.log(`📦 Model set to: ${model}`);
41
+ },
42
+ // Get the current language from the config
43
+ getLanguage() {
44
+ return readConfig().language;
45
+ },
46
+ // Set a new language in the config
47
+ setLanguage(language) {
48
+ writeConfig({ language });
49
+ console.log(`🗣️ Language set to: ${language}`);
50
+ },
51
+ // Get the index directory from the config
52
+ getIndexDir() {
53
+ return readConfig().indexDir;
54
+ },
55
+ // Set a new index directory in the config
56
+ setIndexDir(indexDir) {
57
+ writeConfig({ indexDir });
58
+ console.log(`📁 Index directory set to: ${indexDir}`);
59
+ },
60
+ // Show the current configuration
61
+ show() {
62
+ const cfg = readConfig();
63
+ console.log(`🔧 Current configuration:`);
64
+ console.log(` Model : ${cfg.model}`);
65
+ console.log(` Language : ${cfg.language}`);
66
+ console.log(` Index dir : ${cfg.indexDir}`);
67
+ }
68
+ };
@@ -0,0 +1,19 @@
1
+ import os from 'os';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ export const SCAI_HOME = path.join(os.homedir(), '.scai');
5
+ export const DB_PATH = path.join(SCAI_HOME, 'db.sqlite');
6
+ export const PID_PATH = path.join(SCAI_HOME, 'daemon.pid');
7
+ export const CONFIG_PATH = path.join(SCAI_HOME, 'config.json');
8
+ // Function to read config and get the indexDir on-demand
9
+ export function getIndexDir() {
10
+ try {
11
+ const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
12
+ return config.indexDir || path.join(os.homedir(), 'defaultIndex'); // Default if not set
13
+ }
14
+ catch (e) {
15
+ return path.join(os.homedir(), 'defaultIndex'); // Fallback if no config file
16
+ }
17
+ }
18
+ // On-demand index directory retrieval
19
+ export const INDEX_DIR = getIndexDir();
package/dist/db/client.js CHANGED
@@ -1,7 +1,5 @@
1
1
  import Database from 'better-sqlite3';
2
- import path from 'path';
3
2
  import fs from 'fs';
4
- const DB_PATH = path.resolve(process.cwd(), '.scai/db.sqlite');
5
- // Ensure directory exists
6
- fs.mkdirSync(path.dirname(DB_PATH), { recursive: true });
3
+ import { DB_PATH, SCAI_HOME } from '../constants.js';
4
+ fs.mkdirSync(SCAI_HOME, { recursive: true });
7
5
  export const db = new Database(DB_PATH);
@@ -17,7 +17,7 @@ export function indexFile(filePath, summary, type) {
17
17
  // Step 2: Insert into FTS with the same id
18
18
  db.prepare(sqlTemplates.insertIntoFtsTemplate).run({ path: filePath, summary });
19
19
  }
20
- export function queryFiles(query, limit = 3) {
20
+ export function queryFiles(query, limit = 10) {
21
21
  // Sanitize the query by removing or escaping special characters
22
22
  const safeQuery = query
23
23
  .trim()
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
- // Importing package.json for version
3
+ import path from "path";
4
+ import { Config } from './config.js';
4
5
  import { createRequire } from 'module';
5
6
  const require = createRequire(import.meta.url);
6
7
  const { version } = require('../package.json');
7
- // Importing commands
8
+ // 🧠 Commands
8
9
  import { checkEnv } from "./commands/EnvCmd.js";
9
10
  import { checkGit } from "./commands/GitCmd.js";
10
11
  import { suggestCommitMessage } from "./commands/CommitSuggesterCmd.js";
11
12
  import { handleRefactor } from "./commands/RefactorCmd.js";
12
13
  import { generateTests } from "./commands/TestGenCmd.js";
13
14
  import { bootstrap } from './modelSetup.js';
14
- import { ModelConfig } from './config/ModelConfig.js';
15
15
  import { summarizeFile } from "./commands/SummaryCmd.js";
16
16
  import { handleChangelogUpdate } from './commands/ChangeLogUpdateCmd.js';
17
17
  import { runModulePipelineFromCLI } from './commands/ModulePipelineCmd.js';
@@ -21,12 +21,12 @@ import { runQueryCommand } from './commands/QueryCmd.js';
21
21
  import { runDaemonBatch } from './commands/DaemonCmd.js';
22
22
  import { runStopDaemonCommand } from "./commands/StopDaemonCmd.js";
23
23
  import { runAskCommand } from './commands/AskCmd.js';
24
- // Create the CLI instance
24
+ // 🎛️ CLI Setup
25
25
  const cmd = new Command('scai')
26
26
  .version(version)
27
27
  .option('--model <model>', 'Set the model to use (e.g., codellama:34b)')
28
28
  .option('--lang <lang>', 'Set the target language (ts, java, rust)');
29
- // Define CLI commands
29
+ // 🚀 Init command
30
30
  cmd
31
31
  .command('init')
32
32
  .description('Initialize the model and download required models')
@@ -34,77 +34,109 @@ cmd
34
34
  await bootstrap();
35
35
  console.log('✅ Model initialization completed!');
36
36
  });
37
- cmd
37
+ // 🔧 Group: Git-related commands
38
+ const git = cmd.command('git').description('Git utilities');
39
+ git
40
+ .command('status')
41
+ .description('Check Git status')
42
+ .action(checkGit);
43
+ git
38
44
  .command('sugg')
39
45
  .description('Suggest a commit message from staged changes')
40
46
  .option('-c, --commit', 'Automatically commit with suggested message')
41
47
  .action(suggestCommitMessage);
42
- cmd
48
+ // 🛠️ Group: `gen` commands for content generation
49
+ const gen = cmd.command('gen').description('Generate code-related output');
50
+ gen
43
51
  .command('comm <file>')
44
52
  .description('Write comments for the given file')
45
53
  .option('-a, --apply', 'Apply the refactored version to the original file')
46
54
  .action((file, options) => handleRefactor(file, options));
47
- cmd
55
+ gen
48
56
  .command('changelog')
49
57
  .description('Update or create the CHANGELOG.md based on current Git diff')
50
58
  .action(async () => {
51
59
  await handleChangelogUpdate();
52
60
  });
53
- cmd
61
+ gen
54
62
  .command('summ [file]')
55
63
  .description('Print a summary of the given file to the terminal')
56
64
  .action((file) => summarizeFile(file));
65
+ gen
66
+ .command('tests <file>')
67
+ .description('Generate a Jest test file for the specified JS/TS module')
68
+ .action((file) => generateTests(file));
69
+ // 🔍 Indexing
57
70
  cmd
58
- .command('git')
59
- .description('Check Git status')
60
- .action(checkGit);
71
+ .command('index [targetDir]')
72
+ .description('Index supported files in the given directory (or current folder if none)')
73
+ .option('-d, --detached', 'Run summarizer daemon after indexing')
74
+ .option('--force', 'Force indexing even if another folder has already been indexed')
75
+ .action((targetDir, options) => {
76
+ const resolvedDir = targetDir ? path.resolve(targetDir) : process.cwd();
77
+ runIndexCommand(resolvedDir, { detached: options.detached, force: options.force });
78
+ });
79
+ // ⚙️ Group: Configuration settings
80
+ const set = cmd.command('set').description('Set configuration values');
81
+ set
82
+ .command('model <model>')
83
+ .description('Set the model to use')
84
+ .action((model) => {
85
+ Config.setModel(model);
86
+ Config.show();
87
+ });
88
+ set
89
+ .command('lang <lang>')
90
+ .description('Set the programming language')
91
+ .action((lang) => {
92
+ Config.setLanguage(lang);
93
+ Config.show();
94
+ });
95
+ set
96
+ .command('index-dir <dir>')
97
+ .description('Set the path to the indexed directory')
98
+ .action((dir) => {
99
+ Config.setIndexDir(path.resolve(dir));
100
+ Config.show();
101
+ });
102
+ // 🧪 Diagnostics and info
61
103
  cmd
62
104
  .command('env')
63
105
  .description('Check environment variables')
64
106
  .action(checkEnv);
65
- cmd
66
- .command('gen-tests <file>')
67
- .description('Generate a Jest test file for the specified JS/TS module')
68
- .action((file) => generateTests(file));
69
107
  cmd
70
108
  .command('config')
71
109
  .description('Show the currently active model and language settings')
72
110
  .action(() => {
73
- ModelConfig.logCurrentConfig();
74
- });
75
- cmd
76
- .command('daemon')
77
- .description('Run background summarization of indexed files')
78
- .action(runDaemonBatch);
79
- cmd
80
- .command('stop-daemon')
81
- .description('Stop the background summarizer daemon')
82
- .action(runStopDaemonCommand);
83
- cmd
84
- .command('index [targetDir]')
85
- .description('Index supported files in the given directory (or current folder if none)')
86
- .option('-d, --detached', 'Run summarizer daemon after indexing')
87
- .action((targetDir, options) => {
88
- runIndexCommand(targetDir, { detached: options.detached });
111
+ Config.show();
89
112
  });
113
+ // 🧠 Query and assistant
90
114
  cmd
91
115
  .command('query <query>')
92
116
  .description('Search indexed files by keyword')
93
117
  .action(runQueryCommand);
94
- // Command structure using Commander
95
118
  cmd
96
119
  .command('ask')
97
120
  .description('Ask a question using file summaries and a local model')
98
121
  .argument('<question...>', 'The question to ask')
99
122
  .action((question) => {
100
123
  const q = question.join(' ');
101
- runAskCommand(q); // No model option, just pass the question
124
+ runAskCommand(q);
102
125
  });
126
+ // 🛠️ Background tasks and maintenance
127
+ cmd
128
+ .command('daemon')
129
+ .description('Run background summarization of indexed files')
130
+ .action(runDaemonBatch);
131
+ cmd
132
+ .command('stop-daemon')
133
+ .description('Stop the background summarizer daemon')
134
+ .action(runStopDaemonCommand);
103
135
  cmd
104
136
  .command('reset-db')
105
137
  .description('Delete and reset the SQLite database')
106
138
  .action(() => resetDatabase());
107
- // Default
139
+ // 🧬 Fallback: Pipeline mode
108
140
  cmd
109
141
  .arguments('<file>')
110
142
  .option('-m, --modules <modules>', 'Comma-separated list of modules to run (e.g., comments,cleanup,summary)')
@@ -115,11 +147,11 @@ cmd
115
147
  }
116
148
  runModulePipelineFromCLI(file, options);
117
149
  });
118
- // ✅ Now that commands are defined, parse args
150
+ // ✅ Parse CLI args
119
151
  cmd.parse(process.argv);
120
- // Apply global options after parsing
152
+ // 🔁 Apply global options post-parse
121
153
  const opts = cmd.opts();
122
154
  if (opts.model)
123
- ModelConfig.setModel(opts.model);
155
+ Config.setModel(opts.model);
124
156
  if (opts.lang)
125
- ModelConfig.setLanguage(opts.lang);
157
+ Config.setLanguage(opts.lang);
@@ -1,10 +1,10 @@
1
- import { ModelConfig } from '../../config/ModelConfig.js';
1
+ import { Config } from '../../config.js';
2
2
  import { generate } from '../../lib/generate.js';
3
3
  export const changelogModule = {
4
4
  name: 'changelogModule',
5
5
  description: 'Generates changelog entry based on Git diff',
6
6
  async run(input) {
7
- const model = ModelConfig.getModel();
7
+ const model = Config.getModel();
8
8
  const prompt = `
9
9
  You're an experienced changelog writer. Based on this Git diff, write a markdown bullet-point entry suitable for CHANGELOG.md:
10
10
 
@@ -1,11 +1,11 @@
1
- import { ModelConfig } from '../../config/ModelConfig.js';
1
+ import { Config } from '../../config.js';
2
2
  import { generate } from '../../lib/generate.js';
3
3
  export const addCommentsModule = {
4
4
  name: 'addComments',
5
5
  description: 'Adds meaningful // comments to each block of code',
6
6
  async run(input) {
7
- const model = ModelConfig.getModel();
8
- const lang = ModelConfig.getLanguage();
7
+ const model = Config.getModel();
8
+ const lang = Config.getLanguage();
9
9
  const prompt = `
10
10
  You are a senior ${lang.toUpperCase()} engineer reviewing source code.
11
11
 
@@ -1,10 +1,10 @@
1
1
  import { generate } from '../../lib/generate.js';
2
- import { ModelConfig } from '../../config/ModelConfig.js';
2
+ import { Config } from '../../config.js';
3
3
  export const commitSuggesterModule = {
4
4
  name: 'commitSuggester',
5
5
  description: 'Suggests conventional commit messages from Git diff',
6
6
  async run({ content }) {
7
- const model = ModelConfig.getModel();
7
+ const model = Config.getModel();
8
8
  const prompt = `
9
9
  Suggest ALWAYS 3 concise, conventional Git commit messages based on the input code diff.
10
10
  Use this format ONLY:
@@ -1,14 +1,14 @@
1
1
  // src/pipeline/modules/generateTestsModule.ts
2
2
  import fs from 'fs/promises';
3
3
  import path from 'path';
4
- import { ModelConfig } from '../../config/ModelConfig.js';
4
+ import { Config } from '../../config.js';
5
5
  import { generate } from '../../lib/generate.js';
6
6
  export const generateTestsModule = {
7
7
  name: 'generateTests',
8
8
  description: 'Generate a Jest test file for the class/module',
9
9
  async run({ content, filepath }) {
10
- const model = ModelConfig.getModel();
11
- const lang = ModelConfig.getLanguage();
10
+ const model = Config.getModel();
11
+ const lang = Config.getLanguage();
12
12
  if (!filepath)
13
13
  throw new Error('Missing filepath in pipeline context');
14
14
  const prompt = `
@@ -1,11 +1,11 @@
1
- import { ModelConfig } from '../../config/ModelConfig.js';
1
+ import { Config } from '../../config.js';
2
2
  import { generate } from '../../lib/generate.js';
3
3
  export const refactorModule = {
4
4
  name: 'refactor',
5
5
  description: 'Break code into small, clean functions',
6
6
  async run(input) {
7
- const model = ModelConfig.getModel();
8
- const lang = ModelConfig.getLanguage();
7
+ const model = Config.getModel();
8
+ const lang = Config.getLanguage();
9
9
  const prompt = `
10
10
  You are a senior ${lang.toUpperCase()} engineer.
11
11
 
@@ -1,11 +1,11 @@
1
- import { ModelConfig } from '../../config/ModelConfig.js';
1
+ import { Config } from '../../config.js';
2
2
  import { generate } from '../../lib/generate.js';
3
3
  import path from 'path';
4
4
  export const summaryModule = {
5
5
  name: 'summary',
6
6
  description: 'Generates a general summary of any file content.',
7
7
  run: async ({ content, filepath }) => {
8
- const model = ModelConfig.getModel();
8
+ const model = Config.getModel();
9
9
  const ext = filepath ? path.extname(filepath).toLowerCase() : '';
10
10
  const filename = filepath ? path.basename(filepath) : '';
11
11
  // More neutral prompt for general-purpose content
@@ -36,7 +36,6 @@ ${content}
36
36
  }
37
37
  else {
38
38
  console.warn('⚠️ No summary generated.');
39
- response.summary = '⚠️ No summary generated.';
40
39
  }
41
40
  return response;
42
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"
@@ -1,23 +0,0 @@
1
- export class ModelConfig {
2
- static setModel(model) {
3
- this.model = model;
4
- console.log(`📦 Model set to: ${model}`);
5
- }
6
- static getModel() {
7
- return this.model;
8
- }
9
- static setLanguage(lang) {
10
- this.language = lang;
11
- console.log(`🗣️ Language set to: ${lang}`);
12
- }
13
- static getLanguage() {
14
- return this.language;
15
- }
16
- static logCurrentConfig() {
17
- console.log(`🔧 Current configuration:`);
18
- console.log(` Model : ${this.model}`);
19
- console.log(` Language: ${this.language}`);
20
- }
21
- }
22
- ModelConfig.model = 'llama3';
23
- ModelConfig.language = 'ts';
File without changes