jbai-cli 1.9.6 → 2.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 +34 -38
- package/bin/jbai-claude-opus.js +6 -0
- package/bin/jbai-claude-sonnet.js +6 -0
- package/bin/jbai-claude.js +3 -17
- package/bin/jbai-codex-5.2.js +6 -0
- package/bin/jbai-codex-5.3.js +6 -0
- package/bin/jbai-codex-5.4.js +6 -0
- package/bin/jbai-codex-rockhopper.js +6 -0
- package/bin/jbai-codex.js +13 -17
- package/bin/jbai-continue.js +3 -17
- package/bin/jbai-council.js +1 -1
- package/bin/jbai-gemini-3.1.js +6 -0
- package/bin/jbai-gemini-supernova.js +6 -0
- package/bin/jbai-gemini.js +3 -17
- package/bin/jbai-goose.js +3 -18
- package/bin/jbai-opencode-deepseek.js +6 -0
- package/bin/jbai-opencode-grok.js +6 -0
- package/bin/jbai-opencode-rockhopper.js +6 -0
- package/bin/jbai-opencode.js +6 -51
- package/bin/jbai-proxy.js +27 -5
- package/bin/jbai.js +337 -122
- package/lib/completions.js +255 -0
- package/lib/config.js +18 -82
- package/lib/model-list.js +2 -2
- package/lib/postinstall.js +3 -23
- package/lib/shortcut.js +47 -0
- package/package.json +13 -4
- package/lib/handoff.js +0 -152
- package/lib/interactive-handoff.js +0 -220
package/bin/jbai.js
CHANGED
|
@@ -7,8 +7,8 @@ const fs = require('fs');
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const config = require('../lib/config');
|
|
10
|
-
const { createHandoff } = require('../lib/handoff');
|
|
11
10
|
const { getGroupsForTool, showModelsForTool } = require('../lib/model-list');
|
|
11
|
+
const completions = require('../lib/completions');
|
|
12
12
|
|
|
13
13
|
const TOOLS = {
|
|
14
14
|
claude: {
|
|
@@ -49,23 +49,40 @@ const TOOLS = {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
const MENU_WRAPPERS = {
|
|
53
|
+
claude: 'jbai-claude.js',
|
|
54
|
+
codex: 'jbai-codex.js',
|
|
55
|
+
opencode: 'jbai-opencode.js',
|
|
56
|
+
gemini: 'jbai-gemini.js',
|
|
57
|
+
goose: 'jbai-goose.js',
|
|
58
|
+
continue: 'jbai-continue.js',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const CLI_PACKAGE = 'jbai-cli';
|
|
62
|
+
const NPM_BIN = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
63
|
+
|
|
52
64
|
const VERSION = require('../package.json').version;
|
|
53
65
|
|
|
54
66
|
const HELP = `
|
|
55
67
|
jbai-cli v${VERSION} - JetBrains AI Platform CLI Tools
|
|
56
68
|
|
|
69
|
+
Launch 'jbai' with no arguments to open the interactive terminal control panel.
|
|
70
|
+
|
|
57
71
|
COMMANDS:
|
|
58
72
|
jbai token Show token status
|
|
59
73
|
jbai token set Set token interactively
|
|
60
74
|
jbai token refresh Auto-refresh token via API
|
|
61
75
|
jbai token refresh <token> Set new token (saves to ~/.jbai/token + ~/.zshrc)
|
|
62
76
|
jbai test Test API endpoints (incl. Codex /responses)
|
|
63
|
-
jbai handoff Continue task in Orca Lab
|
|
64
77
|
jbai env [staging|production] Switch environment
|
|
65
78
|
jbai models [tool] List Grazie models (all|claude|codex|gemini|opencode|goose|continue)
|
|
66
79
|
jbai install Install all AI tools (claude, codex, gemini, opencode, goose, continue)
|
|
67
80
|
jbai install claude Install specific tool
|
|
68
81
|
jbai doctor Check which tools are installed
|
|
82
|
+
jbai completions Print zsh completions to stdout
|
|
83
|
+
jbai completions --install Add completions to ~/.zshrc
|
|
84
|
+
jbai completions --bash Print bash completions
|
|
85
|
+
jbai menu Open interactive control panel
|
|
69
86
|
jbai help Show this help
|
|
70
87
|
|
|
71
88
|
PROXY (for Codex Desktop, Cursor, etc.):
|
|
@@ -81,20 +98,34 @@ TOOL WRAPPERS:
|
|
|
81
98
|
jbai-opencode Launch OpenCode with JetBrains AI
|
|
82
99
|
jbai-council Launch Claude + Codex + OpenCode in tmux council mode
|
|
83
100
|
|
|
101
|
+
MODEL SHORTCUTS (super mode by default):
|
|
102
|
+
jbai-claude-opus Claude Code + Opus 4.6
|
|
103
|
+
jbai-claude-sonnet Claude Code + Sonnet 4.6
|
|
104
|
+
jbai-codex-5.4 Codex + GPT-5.4
|
|
105
|
+
jbai-codex-5.3 Codex + GPT-5.3
|
|
106
|
+
jbai-codex-5.2 Codex + GPT-5.2
|
|
107
|
+
jbai-codex-rockhopper Codex + Rockhopper Alpha (OpenAI EAP)
|
|
108
|
+
jbai-gemini-supernova Gemini + Supernova (Google EAP)
|
|
109
|
+
jbai-gemini-3.1 Gemini + 3.1 Pro Preview
|
|
110
|
+
jbai-opencode-rockhopper OpenCode + Rockhopper Alpha
|
|
111
|
+
jbai-opencode-grok OpenCode + Grok 4 (xAI)
|
|
112
|
+
jbai-opencode-deepseek OpenCode + DeepSeek R1
|
|
113
|
+
|
|
84
114
|
SUPER MODE:
|
|
85
115
|
Add --super (or --yolo or -s) to skip confirmations:
|
|
86
116
|
jbai-claude --super # Skip permission prompts
|
|
87
117
|
jbai-codex --super # Full auto mode
|
|
88
118
|
jbai-gemini --super # Auto-confirm changes
|
|
119
|
+
(All model shortcuts above run in super mode by default)
|
|
89
120
|
|
|
90
121
|
EXAMPLES:
|
|
91
122
|
jbai token set # Set your token
|
|
92
123
|
jbai-claude # Start Claude Code
|
|
93
124
|
jbai-codex exec "explain code" # Run Codex task
|
|
94
|
-
jbai-
|
|
125
|
+
jbai-codex-rockhopper # Codex with Rockhopper (super mode)
|
|
126
|
+
jbai-gemini-supernova # Gemini with Supernova (super mode)
|
|
95
127
|
jbai-council # Launch all 3 agents in tmux
|
|
96
128
|
jbai-council --super # All agents in super mode
|
|
97
|
-
jbai handoff --task "fix lint" # Handoff task to Orca Lab
|
|
98
129
|
|
|
99
130
|
TOKEN:
|
|
100
131
|
Get token: ${config.getEndpoints().tokenUrl}
|
|
@@ -506,139 +537,318 @@ async function installTools(toolKey) {
|
|
|
506
537
|
console.log('Run: jbai doctor to verify');
|
|
507
538
|
}
|
|
508
539
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
Options:
|
|
517
|
-
--task, -t Task description (or pass as positional)
|
|
518
|
-
--repo, -r Git repo URL (defaults to origin remote)
|
|
519
|
-
--ref Git ref (defaults to current branch)
|
|
520
|
-
--branch, -b Working branch name for the agent
|
|
521
|
-
--model, -m Claude model (default: ${config.MODELS.claude.default})
|
|
522
|
-
--grazie-env, -e STAGING | PREPROD | PRODUCTION
|
|
523
|
-
--grazie-token Override Grazie token (default: ~/.jbai/token)
|
|
524
|
-
--git-token, -g GitHub token (default: GITHUB_TOKEN/GH_TOKEN)
|
|
525
|
-
--facade-token, -f Facade JWT token (default: FACADE_JWT_TOKEN)
|
|
526
|
-
--orca-url, -o Orca Lab URL (default: http://localhost:3000)
|
|
527
|
-
--no-open Do not open the Orca Lab URL
|
|
528
|
-
--no-auto-start Do not auto-start the agent task
|
|
529
|
-
--help Show this help
|
|
530
|
-
`;
|
|
540
|
+
function ask(question) {
|
|
541
|
+
return new Promise((resolve) => {
|
|
542
|
+
const rl = readline.createInterface({
|
|
543
|
+
input: process.stdin,
|
|
544
|
+
output: process.stdout
|
|
545
|
+
});
|
|
531
546
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
547
|
+
rl.question(question, (answer) => {
|
|
548
|
+
rl.close();
|
|
549
|
+
resolve((answer || '').trim());
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function waitForEnter() {
|
|
555
|
+
return ask('\nPress Enter to continue...');
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function runNodeScript(scriptName, args = []) {
|
|
559
|
+
return new Promise((resolve) => {
|
|
560
|
+
const scriptPath = path.join(__dirname, scriptName);
|
|
561
|
+
const child = spawn(process.execPath, [scriptPath, ...args], {
|
|
562
|
+
stdio: 'inherit'
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
child.on('close', (code) => resolve(code || 0));
|
|
566
|
+
child.on('error', (error) => {
|
|
567
|
+
console.error(`Unable to run ${scriptName}: ${error.message}`);
|
|
568
|
+
resolve(1);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function runCommand(command, args = []) {
|
|
574
|
+
return new Promise((resolve) => {
|
|
575
|
+
const child = spawn(command, args, {
|
|
576
|
+
stdio: 'inherit',
|
|
577
|
+
shell: false
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
child.on('close', (code) => resolve(code || 0));
|
|
581
|
+
child.on('error', (error) => {
|
|
582
|
+
console.error(`Command failed: ${command} ${args.join(' ')}`);
|
|
583
|
+
console.error(error.message);
|
|
584
|
+
resolve(1);
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
async function launchAgent(tool) {
|
|
590
|
+
const script = MENU_WRAPPERS[tool];
|
|
591
|
+
if (!script) {
|
|
592
|
+
console.log(`Unsupported agent: ${tool}`);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
546
595
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
596
|
+
if (!isToolInstalled(tool)) {
|
|
597
|
+
console.log(`❌ ${TOOLS[tool].name} is not installed.`);
|
|
598
|
+
const installNow = (await ask(`Install ${TOOLS[tool].name} now? [y/N]: `)).toLowerCase() === 'y';
|
|
599
|
+
if (!installNow) {
|
|
600
|
+
return;
|
|
552
601
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
602
|
+
|
|
603
|
+
await installTools(tool);
|
|
604
|
+
if (!isToolInstalled(tool)) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
await runNodeScript(script);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
async function setupClients() {
|
|
613
|
+
const installed = Object.keys(TOOLS).filter(isToolInstalled);
|
|
614
|
+
if (installed.length === 0) {
|
|
615
|
+
console.log('No tools installed yet. Install a tool first, then wire it up.');
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
const code = await runNodeScript('jbai-proxy.js', ['setup']);
|
|
620
|
+
if (code !== 0) {
|
|
621
|
+
console.log('Client setup reported issues. Fix the errors above and try again.');
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
console.log('\nClient wiring complete.');
|
|
626
|
+
console.log('- Codex Desktop: config.toml updated');
|
|
627
|
+
console.log('- Shell env: JBAI_PROXY_KEY added');
|
|
628
|
+
console.log('- Proxy: started + launch settings configured');
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
async function updateCli() {
|
|
632
|
+
const confirm = (await ask('Update jbai-cli to latest from npm? [Y/n]: ')).toLowerCase();
|
|
633
|
+
if (confirm && confirm !== 'y' && confirm !== '') {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const code = await runCommand(NPM_BIN, ['install', '-g', `${CLI_PACKAGE}@latest`]);
|
|
638
|
+
if (code === 0) {
|
|
639
|
+
console.log('✅ Update completed. Restart terminal to load updated binary.');
|
|
640
|
+
} else {
|
|
641
|
+
console.log('❌ Update failed. Check npm output and try again.');
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
async function uninstallCli() {
|
|
646
|
+
const confirm = (await ask(`This will uninstall ${CLI_PACKAGE} and close this app. Continue? [y/N]: `)).toLowerCase();
|
|
647
|
+
if (confirm !== 'y') {
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
const code = await runCommand(NPM_BIN, ['uninstall', '-g', CLI_PACKAGE]);
|
|
652
|
+
if (code === 0) {
|
|
653
|
+
console.log('✅ jbai-cli removed.');
|
|
654
|
+
process.exit(0);
|
|
655
|
+
}
|
|
656
|
+
console.log('❌ Uninstall failed. Check npm output and try again.');
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function environmentLabel() {
|
|
660
|
+
return config.getEnvironment() === 'production' ? 'PRODUCTION' : 'STAGING';
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
async function runTokenMenu() {
|
|
664
|
+
while (true) {
|
|
665
|
+
const action = (await ask(`\nToken Management\n1) Show status\n2) Set token\n3) Refresh token\n0) Back\n\nSelect: `)).toLowerCase();
|
|
666
|
+
|
|
667
|
+
if (action === '0' || action === 'b' || action === 'back') {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (action === '1') {
|
|
672
|
+
showTokenStatus();
|
|
673
|
+
await waitForEnter();
|
|
570
674
|
continue;
|
|
571
675
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
676
|
+
|
|
677
|
+
if (action === '2') {
|
|
678
|
+
await setToken();
|
|
679
|
+
await waitForEnter();
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
if (action === '3') {
|
|
684
|
+
await refreshTokenCommand();
|
|
685
|
+
await waitForEnter();
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
console.log('Invalid selection.');
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
async function runSettingsMenu() {
|
|
694
|
+
while (true) {
|
|
695
|
+
const action = (await ask(`\nSettings\n1) Show environment (${environmentLabel()})\n2) Switch to staging\n3) Switch to production\n0) Back\n\nSelect: `)).toLowerCase();
|
|
696
|
+
|
|
697
|
+
if (action === '0' || action === 'b' || action === 'back') {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (action === '1') {
|
|
702
|
+
console.log(`Current environment: ${environmentLabel()}`);
|
|
703
|
+
console.log(`Token URL: ${config.getEndpoints().tokenUrl}`);
|
|
704
|
+
await waitForEnter();
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (action === '2') {
|
|
709
|
+
setEnvironment('staging');
|
|
710
|
+
await waitForEnter();
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (action === '3') {
|
|
715
|
+
setEnvironment('production');
|
|
716
|
+
await waitForEnter();
|
|
586
717
|
continue;
|
|
587
718
|
}
|
|
588
|
-
|
|
719
|
+
|
|
720
|
+
console.log('Invalid selection.');
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
async function runAgentMenu() {
|
|
725
|
+
const action = (await ask(`\nStart Agent\n1) Claude\n2) Codex\n3) OpenCode\n4) Gemini\n5) Goose\n6) Continue\n0) Back\n\nSelect: `)).toLowerCase();
|
|
726
|
+
|
|
727
|
+
const map = {
|
|
728
|
+
'1': 'claude',
|
|
729
|
+
'2': 'codex',
|
|
730
|
+
'3': 'opencode',
|
|
731
|
+
'4': 'gemini',
|
|
732
|
+
'5': 'goose',
|
|
733
|
+
'6': 'continue'
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
if (action === '0' || action === 'b' || action === 'back') {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const tool = map[action];
|
|
741
|
+
if (!tool) {
|
|
742
|
+
console.log('Invalid selection.');
|
|
743
|
+
await waitForEnter();
|
|
744
|
+
return;
|
|
589
745
|
}
|
|
590
746
|
|
|
591
|
-
|
|
747
|
+
console.log(`\nStarting ${TOOLS[tool].name}...\n`);
|
|
748
|
+
await launchAgent(tool);
|
|
592
749
|
}
|
|
593
750
|
|
|
594
|
-
function
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
751
|
+
async function runInstallMenu() {
|
|
752
|
+
const missing = Object.entries(TOOLS).filter(([key]) => !isToolInstalled(key));
|
|
753
|
+
if (missing.length === 0) {
|
|
754
|
+
console.log('✅ All agents are already installed.');
|
|
755
|
+
await waitForEnter();
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const choices = [];
|
|
760
|
+
missing.forEach(([key], index) => {
|
|
761
|
+
choices.push(`${index + 1}) ${TOOLS[key].name}`);
|
|
601
762
|
});
|
|
602
|
-
}
|
|
603
763
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (
|
|
607
|
-
console.log(HANDOFF_HELP);
|
|
764
|
+
const action = (await ask(`\nInstall Agents\n${choices.join('\n')}\nA) Install all missing\n0) Back\n\nSelect: `)).toLowerCase();
|
|
765
|
+
|
|
766
|
+
if (action === '0' || action === 'b' || action === 'back') {
|
|
608
767
|
return;
|
|
609
768
|
}
|
|
610
769
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
770
|
+
if (action === 'a') {
|
|
771
|
+
await installTools();
|
|
772
|
+
await waitForEnter();
|
|
773
|
+
return;
|
|
614
774
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
775
|
+
|
|
776
|
+
const index = parseInt(action, 10);
|
|
777
|
+
if (!Number.isInteger(index) || index < 1 || index > missing.length) {
|
|
778
|
+
console.log('Invalid selection.');
|
|
779
|
+
return;
|
|
618
780
|
}
|
|
619
781
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
782
|
+
const tool = missing[index - 1][0];
|
|
783
|
+
await installTools(tool);
|
|
784
|
+
await waitForEnter();
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
async function runStandaloneMenu() {
|
|
788
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
789
|
+
console.log('Interactive mode requires a TTY terminal. Run: jbai help');
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
while (true) {
|
|
794
|
+
const action = (await ask(`\n┌─ jbai control panel\n│1) Token management\n│2) Settings (environment)\n│3) Install agents\n│4) Wire configured clients\n│5) Doctor (health + install status)\n│6) Start agent chat\n│7) Update jbai-cli\n│8) Uninstall jbai-cli\n│9) Version\n│0) Exit\n└─ Select: `)).toLowerCase();
|
|
795
|
+
|
|
796
|
+
if (action === '0' || action === 'q' || action === 'exit') {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (action === '1') {
|
|
801
|
+
await runTokenMenu();
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
if (action === '2') {
|
|
806
|
+
await runSettingsMenu();
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (action === '3') {
|
|
811
|
+
await runInstallMenu();
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
if (action === '4') {
|
|
816
|
+
await setupClients();
|
|
817
|
+
await waitForEnter();
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (action === '5') {
|
|
822
|
+
doctor();
|
|
823
|
+
await waitForEnter();
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
if (action === '6') {
|
|
828
|
+
await runAgentMenu();
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
if (action === '7') {
|
|
833
|
+
await updateCli();
|
|
834
|
+
await waitForEnter();
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (action === '8') {
|
|
839
|
+
await uninstallCli();
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
if (action === '9') {
|
|
844
|
+
console.log(`jbai-cli v${VERSION}`);
|
|
845
|
+
console.log(`Node: ${process.version}`);
|
|
846
|
+
console.log(`Environment: ${environmentLabel()}`);
|
|
847
|
+
await waitForEnter();
|
|
848
|
+
continue;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
console.log('Invalid selection.');
|
|
642
852
|
}
|
|
643
853
|
}
|
|
644
854
|
|
|
@@ -658,9 +868,6 @@ switch (command) {
|
|
|
658
868
|
case 'test':
|
|
659
869
|
testEndpoints();
|
|
660
870
|
break;
|
|
661
|
-
case 'handoff':
|
|
662
|
-
handoffToOrca(args);
|
|
663
|
-
break;
|
|
664
871
|
case 'models':
|
|
665
872
|
if (args[0]) {
|
|
666
873
|
const allowed = new Set(['all', 'claude', 'codex', 'gemini', 'opencode', 'goose', 'continue']);
|
|
@@ -688,12 +895,20 @@ switch (command) {
|
|
|
688
895
|
proxyMod.main();
|
|
689
896
|
break;
|
|
690
897
|
}
|
|
898
|
+
case 'completions':
|
|
899
|
+
completions.run(args);
|
|
900
|
+
break;
|
|
691
901
|
case 'help':
|
|
692
902
|
case '--help':
|
|
693
903
|
case '-h':
|
|
694
|
-
case undefined:
|
|
695
904
|
console.log(HELP);
|
|
696
905
|
break;
|
|
906
|
+
case 'menu':
|
|
907
|
+
runStandaloneMenu();
|
|
908
|
+
break;
|
|
909
|
+
case undefined:
|
|
910
|
+
runStandaloneMenu();
|
|
911
|
+
break;
|
|
697
912
|
case 'version':
|
|
698
913
|
case '--version':
|
|
699
914
|
case '-v':
|