jbai-cli 1.0.1 → 1.1.1

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
@@ -75,6 +75,30 @@ jbai-gemini "What is Kubernetes?"
75
75
  jbai-opencode
76
76
  ```
77
77
 
78
+ ## Super Mode (Skip Confirmations)
79
+
80
+ Add `--super` (or `--yolo` or `-s`) to any command to enable maximum permissions:
81
+
82
+ ```bash
83
+ # Claude Code - skips all permission prompts
84
+ jbai-claude --super
85
+
86
+ # Codex - full auto mode
87
+ jbai-codex --super exec "refactor this code"
88
+
89
+ # Aider - auto-confirm all changes
90
+ jbai-aider --super
91
+ ```
92
+
93
+ | Tool | Super Mode Flag |
94
+ |------|-----------------|
95
+ | Claude Code | `--dangerously-skip-permissions` |
96
+ | Codex | `--full-auto` |
97
+ | Aider | `--yes` |
98
+ | OpenCode | `--yes` |
99
+
100
+ ⚠️ **Use with caution** - super mode allows the AI to make changes without confirmation.
101
+
78
102
  ## Using Different Models
79
103
 
80
104
  Each tool has a sensible default, but you can specify any available model:
@@ -128,12 +152,30 @@ jbai-gemini --model gemini-2.5-pro "Your question"
128
152
  | `jbai token set` | Set/update token |
129
153
  | `jbai test` | Test API connections |
130
154
  | `jbai models` | List all models |
155
+ | `jbai install` | Install all AI tools |
156
+ | `jbai install claude` | Install specific tool |
157
+ | `jbai doctor` | Check tool installation status |
131
158
  | `jbai env staging` | Use staging environment |
132
159
  | `jbai env production` | Use production environment |
133
160
 
134
- ## Prerequisites
161
+ ## Installing AI Tools
162
+
163
+ jbai-cli can install the underlying tools for you:
164
+
165
+ ```bash
166
+ # Install all tools at once
167
+ jbai install
168
+
169
+ # Install specific tool
170
+ jbai install claude
171
+ jbai install codex
172
+ jbai install aider
173
+
174
+ # Check what's installed
175
+ jbai doctor
176
+ ```
135
177
 
136
- Install the underlying tools you want to use:
178
+ ### Manual Installation
137
179
 
138
180
  | Tool | Install Command |
139
181
  |------|-----------------|
package/bin/jbai-aider.js CHANGED
@@ -15,7 +15,12 @@ if (config.isTokenExpired(token)) {
15
15
  }
16
16
 
17
17
  const endpoints = config.getEndpoints();
18
- const args = process.argv.slice(2);
18
+ let args = process.argv.slice(2);
19
+
20
+ // Check for super mode (--super, --yolo, -s)
21
+ const superFlags = ['--super', '--yolo', '-s'];
22
+ const superMode = args.some(a => superFlags.includes(a));
23
+ args = args.filter(a => !superFlags.includes(a));
19
24
 
20
25
  // Build aider arguments
21
26
  const hasModel = args.includes('--model');
@@ -28,6 +33,13 @@ const aiderArgs = [
28
33
  if (!hasModel) {
29
34
  aiderArgs.push('--model', config.MODELS.openai.default);
30
35
  }
36
+
37
+ // Add super mode flags (auto-confirm all)
38
+ if (superMode) {
39
+ aiderArgs.push('--yes');
40
+ console.log('🚀 Super mode: --yes (auto-confirm) enabled');
41
+ }
42
+
31
43
  aiderArgs.push(...args);
32
44
 
33
45
  const child = spawn('aider', aiderArgs, {
@@ -37,7 +49,10 @@ const child = spawn('aider', aiderArgs, {
37
49
 
38
50
  child.on('error', (err) => {
39
51
  if (err.code === 'ENOENT') {
40
- console.error('❌ Aider not found. Install: pip install aider-chat');
52
+ const tool = config.TOOLS.aider;
53
+ console.error(`❌ ${tool.name} not found.\n`);
54
+ console.error(`Install with: ${tool.install}`);
55
+ console.error(`Or run: jbai install aider`);
41
56
  } else {
42
57
  console.error(`Error: ${err.message}`);
43
58
  }
@@ -15,11 +15,22 @@ if (config.isTokenExpired(token)) {
15
15
  }
16
16
 
17
17
  const endpoints = config.getEndpoints();
18
- const args = process.argv.slice(2);
18
+ let args = process.argv.slice(2);
19
+
20
+ // Check for super mode (--super, --yolo, -s)
21
+ const superFlags = ['--super', '--yolo', '-s'];
22
+ const superMode = args.some(a => superFlags.includes(a));
23
+ args = args.filter(a => !superFlags.includes(a));
19
24
 
20
25
  // Check if model specified
21
26
  const hasModel = args.includes('--model') || args.includes('-m');
22
- const finalArgs = hasModel ? args : ['--model', config.MODELS.claude.default, ...args];
27
+ let finalArgs = hasModel ? args : ['--model', config.MODELS.claude.default, ...args];
28
+
29
+ // Add super mode flags
30
+ if (superMode) {
31
+ finalArgs = ['--dangerously-skip-permissions', ...finalArgs];
32
+ console.log('🚀 Super mode: --dangerously-skip-permissions enabled');
33
+ }
23
34
 
24
35
  // Set environment for Claude Code
25
36
  const env = {
@@ -36,7 +47,10 @@ const child = spawn('claude', finalArgs, {
36
47
 
37
48
  child.on('error', (err) => {
38
49
  if (err.code === 'ENOENT') {
39
- console.error('❌ Claude Code not found. Install: npm install -g @anthropic-ai/claude-code');
50
+ const tool = config.TOOLS.claude;
51
+ console.error(`❌ ${tool.name} not found.\n`);
52
+ console.error(`Install with: ${tool.install}`);
53
+ console.error(`Or run: jbai install claude`);
40
54
  } else {
41
55
  console.error(`Error: ${err.message}`);
42
56
  }
package/bin/jbai-codex.js CHANGED
@@ -18,9 +18,15 @@ if (config.isTokenExpired(token)) {
18
18
  }
19
19
 
20
20
  const endpoints = config.getEndpoints();
21
- const env = config.getEnvironment();
22
- const providerName = env === 'staging' ? 'jbai-staging' : 'jbai';
23
- const envVarName = env === 'staging' ? 'GRAZIE_STAGING_TOKEN' : 'GRAZIE_API_TOKEN';
21
+ const environment = config.getEnvironment();
22
+ const providerName = environment === 'staging' ? 'jbai-staging' : 'jbai';
23
+ const envVarName = environment === 'staging' ? 'GRAZIE_STAGING_TOKEN' : 'GRAZIE_API_TOKEN';
24
+ let args = process.argv.slice(2);
25
+
26
+ // Check for super mode (--super, --yolo, -s)
27
+ const superFlags = ['--super', '--yolo', '-s'];
28
+ const superMode = args.some(a => superFlags.includes(a));
29
+ args = args.filter(a => !superFlags.includes(a));
24
30
 
25
31
  // Ensure Codex config exists
26
32
  const codexDir = path.join(os.homedir(), '.codex');
@@ -38,9 +44,9 @@ if (fs.existsSync(codexConfig)) {
38
44
 
39
45
  if (!configContent.includes(`[model_providers.${providerName}]`)) {
40
46
  const providerConfig = `
41
- # JetBrains AI (${env})
47
+ # JetBrains AI (${environment})
42
48
  [model_providers.${providerName}]
43
- name = "JetBrains AI (${env})"
49
+ name = "JetBrains AI (${environment})"
44
50
  base_url = "${endpoints.openai}"
45
51
  env_http_headers = { "Grazie-Authenticate-JWT" = "${envVarName}" }
46
52
  wire_api = "responses"
@@ -49,13 +55,19 @@ wire_api = "responses"
49
55
  console.log(`✅ Added ${providerName} provider to Codex config`);
50
56
  }
51
57
 
52
- const args = process.argv.slice(2);
53
58
  const hasModel = args.includes('--model');
54
59
  const finalArgs = ['-c', `model_provider=${providerName}`];
55
60
 
56
61
  if (!hasModel) {
57
62
  finalArgs.push('--model', config.MODELS.openai.default);
58
63
  }
64
+
65
+ // Add super mode flags (full-auto)
66
+ if (superMode) {
67
+ finalArgs.push('--full-auto');
68
+ console.log('🚀 Super mode: --full-auto enabled');
69
+ }
70
+
59
71
  finalArgs.push(...args);
60
72
 
61
73
  const childEnv = {
@@ -70,7 +82,10 @@ const child = spawn('codex', finalArgs, {
70
82
 
71
83
  child.on('error', (err) => {
72
84
  if (err.code === 'ENOENT') {
73
- console.error('❌ Codex not found. Install: npm install -g @openai/codex');
85
+ const tool = config.TOOLS.codex;
86
+ console.error(`❌ ${tool.name} not found.\n`);
87
+ console.error(`Install with: ${tool.install}`);
88
+ console.error(`Or run: jbai install codex`);
74
89
  } else {
75
90
  console.error(`Error: ${err.message}`);
76
91
  }
@@ -15,11 +15,22 @@ if (config.isTokenExpired(token)) {
15
15
  }
16
16
 
17
17
  const endpoints = config.getEndpoints();
18
- const args = process.argv.slice(2);
18
+ let args = process.argv.slice(2);
19
+
20
+ // Check for super mode (--super, --yolo, -s)
21
+ const superFlags = ['--super', '--yolo', '-s'];
22
+ const superMode = args.some(a => superFlags.includes(a));
23
+ args = args.filter(a => !superFlags.includes(a));
19
24
 
20
25
  // Check if model specified
21
26
  const hasModel = args.includes('--model') || args.includes('-m');
22
- const finalArgs = hasModel ? args : ['--model', config.MODELS.claude.default, ...args];
27
+ let finalArgs = hasModel ? args : ['--model', config.MODELS.claude.default, ...args];
28
+
29
+ // Add super mode flags
30
+ if (superMode) {
31
+ finalArgs = ['--yes', ...finalArgs];
32
+ console.log('🚀 Super mode: --yes (auto-confirm) enabled');
33
+ }
23
34
 
24
35
  // Set environment for OpenCode
25
36
  const env = {
@@ -37,7 +48,10 @@ const child = spawn('opencode', finalArgs, {
37
48
 
38
49
  child.on('error', (err) => {
39
50
  if (err.code === 'ENOENT') {
40
- console.error('❌ OpenCode not found. Install: go install github.com/opencode-ai/opencode@latest');
51
+ const tool = config.TOOLS.opencode;
52
+ console.error(`❌ ${tool.name} not found.\n`);
53
+ console.error(`Install with: ${tool.install}`);
54
+ console.error(`Or run: jbai install opencode`);
41
55
  } else {
42
56
  console.error(`Error: ${err.message}`);
43
57
  }
package/bin/jbai.js CHANGED
@@ -1,10 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawn } = require('child_process');
3
+ const { spawn, execSync } = require('child_process');
4
4
  const readline = require('readline');
5
5
  const https = require('https');
6
6
  const config = require('../lib/config');
7
7
 
8
+ const TOOLS = {
9
+ claude: {
10
+ name: 'Claude Code',
11
+ command: 'claude',
12
+ install: 'npm install -g @anthropic-ai/claude-code',
13
+ check: 'claude --version'
14
+ },
15
+ codex: {
16
+ name: 'Codex CLI',
17
+ command: 'codex',
18
+ install: 'npm install -g @openai/codex',
19
+ check: 'codex --version'
20
+ },
21
+ aider: {
22
+ name: 'Aider',
23
+ command: 'aider',
24
+ install: 'pip install aider-chat',
25
+ check: 'aider --version'
26
+ },
27
+ opencode: {
28
+ name: 'OpenCode',
29
+ command: 'opencode',
30
+ install: 'go install github.com/opencode-ai/opencode@latest',
31
+ check: 'opencode --version'
32
+ }
33
+ };
34
+
8
35
  const VERSION = require('../package.json').version;
9
36
 
10
37
  const HELP = `
@@ -17,6 +44,9 @@ COMMANDS:
17
44
  jbai test Test all API endpoints
18
45
  jbai env [staging|production] Switch environment
19
46
  jbai models List available models
47
+ jbai install Install all AI tools (claude, codex, aider)
48
+ jbai install claude Install specific tool
49
+ jbai doctor Check which tools are installed
20
50
  jbai help Show this help
21
51
 
22
52
  TOOL WRAPPERS:
@@ -26,6 +56,12 @@ TOOL WRAPPERS:
26
56
  jbai-gemini Launch Gemini with JetBrains AI
27
57
  jbai-opencode Launch OpenCode with JetBrains AI
28
58
 
59
+ SUPER MODE:
60
+ Add --super (or --yolo or -s) to skip confirmations:
61
+ jbai-claude --super # Skip permission prompts
62
+ jbai-codex --super # Full auto mode
63
+ jbai-aider --super # Auto-confirm changes
64
+
29
65
  EXAMPLES:
30
66
  jbai token set # Set your token
31
67
  jbai-claude # Start Claude Code
@@ -212,6 +248,131 @@ function setEnvironment(env) {
212
248
  console.log(` Token URL: ${config.ENDPOINTS[env].tokenUrl}`);
213
249
  }
214
250
 
251
+ function isToolInstalled(toolKey) {
252
+ const tool = TOOLS[toolKey];
253
+ if (!tool) return false;
254
+ try {
255
+ execSync(`which ${tool.command}`, { stdio: 'ignore' });
256
+ return true;
257
+ } catch {
258
+ return false;
259
+ }
260
+ }
261
+
262
+ function doctor() {
263
+ console.log('Tool Status:\n');
264
+
265
+ const token = config.getToken();
266
+ console.log(`Token: ${token ? '✅ Set' : '❌ Not set'}`);
267
+ if (token) {
268
+ console.log(`Environment: ${config.getEnvironment()}`);
269
+ console.log(`Expired: ${config.isTokenExpired(token) ? '⚠️ Yes' : '✅ No'}`);
270
+ }
271
+ console.log('');
272
+
273
+ for (const [key, tool] of Object.entries(TOOLS)) {
274
+ const installed = isToolInstalled(key);
275
+ const status = installed ? '✅' : '❌';
276
+ console.log(`${status} ${tool.name.padEnd(12)} ${installed ? 'Installed' : 'Not installed'}`);
277
+ if (!installed) {
278
+ console.log(` Install: ${tool.install}`);
279
+ }
280
+ }
281
+
282
+ console.log('\n✅ Gemini Built-in (no install needed)');
283
+ }
284
+
285
+ async function installTools(toolKey) {
286
+ const rl = readline.createInterface({
287
+ input: process.stdin,
288
+ output: process.stdout
289
+ });
290
+
291
+ const askConfirm = (question) => new Promise(resolve => {
292
+ rl.question(question, answer => resolve(answer.toLowerCase() === 'y' || answer === ''));
293
+ });
294
+
295
+ if (toolKey && toolKey !== 'all') {
296
+ // Install specific tool
297
+ const tool = TOOLS[toolKey];
298
+ if (!tool) {
299
+ console.log(`Unknown tool: ${toolKey}`);
300
+ console.log(`Available: ${Object.keys(TOOLS).join(', ')}`);
301
+ rl.close();
302
+ return;
303
+ }
304
+
305
+ if (isToolInstalled(toolKey)) {
306
+ console.log(`✅ ${tool.name} is already installed`);
307
+ rl.close();
308
+ return;
309
+ }
310
+
311
+ console.log(`Installing ${tool.name}...`);
312
+ console.log(`Running: ${tool.install}\n`);
313
+
314
+ try {
315
+ execSync(tool.install, { stdio: 'inherit' });
316
+ console.log(`\n✅ ${tool.name} installed successfully`);
317
+ } catch (e) {
318
+ console.log(`\n❌ Failed to install ${tool.name}`);
319
+ }
320
+ rl.close();
321
+ return;
322
+ }
323
+
324
+ // Install all tools
325
+ console.log('This will install the following tools:\n');
326
+
327
+ const toInstall = [];
328
+ for (const [key, tool] of Object.entries(TOOLS)) {
329
+ const installed = isToolInstalled(key);
330
+ if (installed) {
331
+ console.log(`✅ ${tool.name} - already installed`);
332
+ } else {
333
+ console.log(`📦 ${tool.name} - will install`);
334
+ console.log(` ${tool.install}`);
335
+ toInstall.push({ key, tool });
336
+ }
337
+ }
338
+
339
+ if (toInstall.length === 0) {
340
+ console.log('\n✅ All tools are already installed!');
341
+ rl.close();
342
+ return;
343
+ }
344
+
345
+ console.log('');
346
+ const confirm = await askConfirm(`Install ${toInstall.length} tool(s)? [Y/n] `);
347
+
348
+ if (!confirm) {
349
+ console.log('Cancelled');
350
+ rl.close();
351
+ return;
352
+ }
353
+
354
+ for (const { key, tool } of toInstall) {
355
+ console.log(`\n📦 Installing ${tool.name}...`);
356
+ console.log(`Running: ${tool.install}\n`);
357
+
358
+ try {
359
+ execSync(tool.install, { stdio: 'inherit' });
360
+ console.log(`✅ ${tool.name} installed`);
361
+ } catch (e) {
362
+ console.log(`❌ Failed to install ${tool.name}`);
363
+ const skip = await askConfirm('Continue with other tools? [Y/n] ');
364
+ if (!skip) {
365
+ rl.close();
366
+ return;
367
+ }
368
+ }
369
+ }
370
+
371
+ rl.close();
372
+ console.log('\n✅ Installation complete!');
373
+ console.log('Run: jbai doctor to verify');
374
+ }
375
+
215
376
  // Main
216
377
  const [,, command, ...args] = process.argv;
217
378
 
@@ -232,6 +393,13 @@ switch (command) {
232
393
  case 'env':
233
394
  setEnvironment(args[0]);
234
395
  break;
396
+ case 'install':
397
+ installTools(args[0]);
398
+ break;
399
+ case 'doctor':
400
+ case 'status':
401
+ doctor();
402
+ break;
235
403
  case 'help':
236
404
  case '--help':
237
405
  case '-h':
package/lib/config.js CHANGED
@@ -122,12 +122,36 @@ function isTokenExpired(token) {
122
122
  return expiry < new Date();
123
123
  }
124
124
 
125
+ const TOOLS = {
126
+ claude: {
127
+ name: 'Claude Code',
128
+ command: 'claude',
129
+ install: 'npm install -g @anthropic-ai/claude-code'
130
+ },
131
+ codex: {
132
+ name: 'Codex CLI',
133
+ command: 'codex',
134
+ install: 'npm install -g @openai/codex'
135
+ },
136
+ aider: {
137
+ name: 'Aider',
138
+ command: 'aider',
139
+ install: 'pip install aider-chat'
140
+ },
141
+ opencode: {
142
+ name: 'OpenCode',
143
+ command: 'opencode',
144
+ install: 'go install github.com/opencode-ai/opencode@latest'
145
+ }
146
+ };
147
+
125
148
  module.exports = {
126
149
  CONFIG_DIR,
127
150
  TOKEN_FILE,
128
151
  CONFIG_FILE,
129
152
  ENDPOINTS,
130
153
  MODELS,
154
+ TOOLS,
131
155
  ensureConfigDir,
132
156
  getToken,
133
157
  setToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jbai-cli",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "CLI wrappers to use AI coding tools (Claude Code, Codex, Aider, Gemini) with JetBrains AI Platform",
5
5
  "keywords": [
6
6
  "jetbrains",