@x-all-in-one/coding-helper 0.0.5 → 0.0.6
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/dist/lib/opencode-manager.d.ts +26 -0
- package/dist/lib/opencode-manager.js +85 -1
- package/dist/lib/wizard.d.ts +2 -0
- package/dist/lib/wizard.js +137 -0
- package/dist/locales/en_US.json +14 -1
- package/dist/locales/zh_CN.json +14 -1
- package/package.json +1 -1
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export interface OhMyOpenCodeConfig {
|
|
2
|
+
$schema?: string;
|
|
3
|
+
agents?: Record<string, {
|
|
4
|
+
model?: string;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}>;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
1
9
|
export declare const OPENCODE_DEFAULT_CONFIG: {
|
|
2
10
|
BASE_URL: string;
|
|
3
11
|
PROVIDER_NAME: string;
|
|
@@ -50,6 +58,7 @@ export interface OpenCodeModelConfig {
|
|
|
50
58
|
export declare class OpenCodeManager {
|
|
51
59
|
private static instance;
|
|
52
60
|
private configPath;
|
|
61
|
+
private ohMyOpenCodeConfigPath;
|
|
53
62
|
private cachedModels;
|
|
54
63
|
private constructor();
|
|
55
64
|
static getInstance(): OpenCodeManager;
|
|
@@ -89,5 +98,22 @@ export declare class OpenCodeManager {
|
|
|
89
98
|
* Clear model config (only remove xaio provider)
|
|
90
99
|
*/
|
|
91
100
|
clearModelConfig(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Check if oh-my-opencode plugin is installed in opencode.json
|
|
103
|
+
*/
|
|
104
|
+
hasOhMyOpenCodePlugin(): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Get oh-my-opencode config
|
|
107
|
+
*/
|
|
108
|
+
getOhMyOpenCodeConfig(): OhMyOpenCodeConfig;
|
|
109
|
+
/**
|
|
110
|
+
* Save oh-my-opencode config
|
|
111
|
+
*/
|
|
112
|
+
saveOhMyOpenCodeConfig(config: OhMyOpenCodeConfig): void;
|
|
113
|
+
/**
|
|
114
|
+
* Update oh-my-opencode agent models
|
|
115
|
+
* Only updates the model field, preserves other agent configurations
|
|
116
|
+
*/
|
|
117
|
+
updateOhMyOpenCodeModels(model: string): void;
|
|
92
118
|
}
|
|
93
119
|
export declare const openCodeManager: OpenCodeManager;
|
|
@@ -3,11 +3,21 @@ import { homedir } from 'node:os';
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
// X-AIO Provider ID
|
|
5
5
|
const XAIO_PROVIDER_ID = 'xaio';
|
|
6
|
+
// oh-my-opencode agent names
|
|
7
|
+
const OH_MY_OPENCODE_AGENTS = [
|
|
8
|
+
'Sisyphus',
|
|
9
|
+
'librarian',
|
|
10
|
+
'explore',
|
|
11
|
+
'oracle',
|
|
12
|
+
'frontend-ui-ux-engineer',
|
|
13
|
+
'document-writer',
|
|
14
|
+
'multimodal-looker',
|
|
15
|
+
];
|
|
6
16
|
// Default configuration
|
|
7
17
|
export const OPENCODE_DEFAULT_CONFIG = {
|
|
8
18
|
BASE_URL: 'https://code-api.x-aio.com/v1',
|
|
9
19
|
PROVIDER_NAME: 'Coding Plan By X-AIO',
|
|
10
|
-
DEFAULT_MODEL: 'MiniMax-M2',
|
|
20
|
+
DEFAULT_MODEL: 'MiniMax-M2.1',
|
|
11
21
|
DEFAULT_SMALL_MODEL: 'Qwen3-Coder-30B-A3B-Instruct',
|
|
12
22
|
// Default limits (hardcoded for v1, will be fetched from API in future)
|
|
13
23
|
DEFAULT_CONTEXT: 128000,
|
|
@@ -19,12 +29,15 @@ export const OPENCODE_DEFAULT_CONFIG = {
|
|
|
19
29
|
export class OpenCodeManager {
|
|
20
30
|
static instance;
|
|
21
31
|
configPath;
|
|
32
|
+
ohMyOpenCodeConfigPath;
|
|
22
33
|
cachedModels = [];
|
|
23
34
|
constructor() {
|
|
24
35
|
// OpenCode config file paths (cross-platform support)
|
|
25
36
|
// - macOS/Linux: ~/.config/opencode/opencode.json
|
|
26
37
|
// - Windows: %USERPROFILE%\.config\opencode\opencode.json
|
|
27
38
|
this.configPath = join(homedir(), '.config', 'opencode', 'opencode.json');
|
|
39
|
+
// oh-my-opencode config path
|
|
40
|
+
this.ohMyOpenCodeConfigPath = join(homedir(), '.config', 'opencode', 'oh-my-opencode.json');
|
|
28
41
|
}
|
|
29
42
|
static getInstance() {
|
|
30
43
|
if (!OpenCodeManager.instance) {
|
|
@@ -234,5 +247,76 @@ export class OpenCodeManager {
|
|
|
234
247
|
}
|
|
235
248
|
this.saveConfig(currentConfig);
|
|
236
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Check if oh-my-opencode plugin is installed in opencode.json
|
|
252
|
+
*/
|
|
253
|
+
hasOhMyOpenCodePlugin() {
|
|
254
|
+
try {
|
|
255
|
+
const config = this.getConfig();
|
|
256
|
+
if (config.plugin && Array.isArray(config.plugin)) {
|
|
257
|
+
return config.plugin.some((p) => typeof p === 'string' && p.startsWith('oh-my-opencode'));
|
|
258
|
+
}
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get oh-my-opencode config
|
|
267
|
+
*/
|
|
268
|
+
getOhMyOpenCodeConfig() {
|
|
269
|
+
try {
|
|
270
|
+
if (existsSync(this.ohMyOpenCodeConfigPath)) {
|
|
271
|
+
const content = readFileSync(this.ohMyOpenCodeConfigPath, 'utf-8');
|
|
272
|
+
return JSON.parse(content);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
console.warn('Failed to read oh-my-opencode config:', error);
|
|
277
|
+
}
|
|
278
|
+
return {};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Save oh-my-opencode config
|
|
282
|
+
*/
|
|
283
|
+
saveOhMyOpenCodeConfig(config) {
|
|
284
|
+
try {
|
|
285
|
+
this.ensureDir(this.ohMyOpenCodeConfigPath);
|
|
286
|
+
writeFileSync(this.ohMyOpenCodeConfigPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
throw new Error(`Failed to save oh-my-opencode config: ${error}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Update oh-my-opencode agent models
|
|
294
|
+
* Only updates the model field, preserves other agent configurations
|
|
295
|
+
*/
|
|
296
|
+
updateOhMyOpenCodeModels(model) {
|
|
297
|
+
const prefixedModel = `${XAIO_PROVIDER_ID}/${model}`;
|
|
298
|
+
// Read existing config or create new one
|
|
299
|
+
const currentConfig = this.getOhMyOpenCodeConfig();
|
|
300
|
+
// Initialize agents if not exists
|
|
301
|
+
if (!currentConfig.agents) {
|
|
302
|
+
currentConfig.agents = {};
|
|
303
|
+
}
|
|
304
|
+
// Update each agent's model, preserving other settings
|
|
305
|
+
for (const agentName of OH_MY_OPENCODE_AGENTS) {
|
|
306
|
+
if (currentConfig.agents[agentName]) {
|
|
307
|
+
// Agent exists, only update model
|
|
308
|
+
currentConfig.agents[agentName].model = prefixedModel;
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
// Agent doesn't exist, create with only model
|
|
312
|
+
currentConfig.agents[agentName] = { model: prefixedModel };
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Ensure schema is set
|
|
316
|
+
if (!currentConfig.$schema) {
|
|
317
|
+
currentConfig.$schema = 'https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json';
|
|
318
|
+
}
|
|
319
|
+
this.saveOhMyOpenCodeConfig(currentConfig);
|
|
320
|
+
}
|
|
237
321
|
}
|
|
238
322
|
export const openCodeManager = OpenCodeManager.getInstance();
|
package/dist/lib/wizard.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export declare class Wizard {
|
|
|
42
42
|
showMainMenu(): Promise<void>;
|
|
43
43
|
openOfficialWebsite(): Promise<void>;
|
|
44
44
|
showToolMenu(toolName: any): Promise<void>;
|
|
45
|
+
installOhMyOpenCode(): Promise<void>;
|
|
46
|
+
installBun(): Promise<boolean>;
|
|
45
47
|
startTool(toolName: any): Promise<void>;
|
|
46
48
|
loadModelConfig(toolName: any): Promise<void>;
|
|
47
49
|
unloadModelConfig(toolName: any): Promise<void>;
|
package/dist/lib/wizard.js
CHANGED
|
@@ -718,6 +718,10 @@ export class Wizard {
|
|
|
718
718
|
if (detectedConfig) {
|
|
719
719
|
choices.push({ name: `> ${i18n.t('wizard.start_tool', { tool: SUPPORTED_TOOLS[toolName].displayName, shell: SUPPORTED_TOOLS[toolName].command })}`, value: 'start_tool' });
|
|
720
720
|
}
|
|
721
|
+
// Add oh-my-opencode install option for OpenCode only
|
|
722
|
+
if (toolName === 'opencode' && detectedConfig) {
|
|
723
|
+
choices.push({ name: `> ${i18n.t('wizard.action_install_oh_my_opencode')}`, value: 'install_oh_my_opencode' });
|
|
724
|
+
}
|
|
721
725
|
choices.push(new inquirer.Separator(), { name: `<- ${i18n.t('wizard.nav_return')}`, value: 'back' }, { name: `x ${i18n.t('wizard.nav_exit')}`, value: 'exit' });
|
|
722
726
|
const { action } = await this.promptWithHints([
|
|
723
727
|
{
|
|
@@ -725,6 +729,7 @@ export class Wizard {
|
|
|
725
729
|
name: 'action',
|
|
726
730
|
message: i18n.t('wizard.select_action'),
|
|
727
731
|
choices,
|
|
732
|
+
pageSize: 15,
|
|
728
733
|
},
|
|
729
734
|
]);
|
|
730
735
|
if (action === 'exit') {
|
|
@@ -746,7 +751,132 @@ export class Wizard {
|
|
|
746
751
|
else if (action === 'start_tool') {
|
|
747
752
|
await this.startTool(toolName);
|
|
748
753
|
}
|
|
754
|
+
else if (action === 'install_oh_my_opencode') {
|
|
755
|
+
await this.installOhMyOpenCode();
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
async installOhMyOpenCode() {
|
|
760
|
+
const { spawn, execSync } = await import('node:child_process');
|
|
761
|
+
// Check if bun is available (oh-my-opencode requires bun)
|
|
762
|
+
const isWindows = process.platform === 'win32';
|
|
763
|
+
let hasBun = false;
|
|
764
|
+
try {
|
|
765
|
+
execSync(isWindows ? 'where bun' : 'which bun', { stdio: 'ignore' });
|
|
766
|
+
hasBun = true;
|
|
767
|
+
}
|
|
768
|
+
catch {
|
|
769
|
+
hasBun = false;
|
|
770
|
+
}
|
|
771
|
+
if (!hasBun) {
|
|
772
|
+
console.log(chalk.yellow(`\n⚠️ ${i18n.t('wizard.oh_my_opencode_requires_bun')}`));
|
|
773
|
+
// Ask user if they want to install bun
|
|
774
|
+
const { installBun } = await this.promptWithHints([
|
|
775
|
+
{
|
|
776
|
+
type: 'confirm',
|
|
777
|
+
name: 'installBun',
|
|
778
|
+
message: i18n.t('wizard.bun_install_confirm'),
|
|
779
|
+
default: true,
|
|
780
|
+
},
|
|
781
|
+
]);
|
|
782
|
+
if (!installBun) {
|
|
783
|
+
console.log(chalk.gray(`\n${i18n.t('wizard.bun_install_skipped')}`));
|
|
784
|
+
console.log(chalk.cyan(` ${i18n.t('wizard.bun_install_hint')}`));
|
|
785
|
+
console.log(chalk.blue(' https://bun.sh/docs/installation\n'));
|
|
786
|
+
await this.promptWithHints([
|
|
787
|
+
{
|
|
788
|
+
type: 'input',
|
|
789
|
+
name: 'continue',
|
|
790
|
+
message: i18n.t('wizard.press_enter'),
|
|
791
|
+
},
|
|
792
|
+
]);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
// Install bun
|
|
796
|
+
const bunInstalled = await this.installBun();
|
|
797
|
+
if (!bunInstalled) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
749
800
|
}
|
|
801
|
+
console.log(chalk.cyan(`\n${i18n.t('wizard.oh_my_opencode_installing')}\n`));
|
|
802
|
+
return new Promise((resolve) => {
|
|
803
|
+
// Use bunx since oh-my-opencode requires bun
|
|
804
|
+
const command = isWindows ? 'bunx.cmd' : 'bunx';
|
|
805
|
+
const args = ['oh-my-opencode', 'install'];
|
|
806
|
+
const child = spawn(command, args, {
|
|
807
|
+
stdio: 'inherit',
|
|
808
|
+
shell: true,
|
|
809
|
+
});
|
|
810
|
+
child.on('close', (code) => {
|
|
811
|
+
if (code === 0) {
|
|
812
|
+
console.log(chalk.green(`\n✅ ${i18n.t('wizard.oh_my_opencode_installed')}`));
|
|
813
|
+
}
|
|
814
|
+
else {
|
|
815
|
+
console.log(chalk.red(`\n❌ ${i18n.t('wizard.oh_my_opencode_install_failed')}`));
|
|
816
|
+
}
|
|
817
|
+
resolve();
|
|
818
|
+
});
|
|
819
|
+
child.on('error', (error) => {
|
|
820
|
+
console.error(chalk.red(`\n❌ ${i18n.t('wizard.oh_my_opencode_install_failed')}`));
|
|
821
|
+
console.error(error);
|
|
822
|
+
resolve();
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
async installBun() {
|
|
827
|
+
const { spawn } = await import('node:child_process');
|
|
828
|
+
const isWindows = process.platform === 'win32';
|
|
829
|
+
console.log(chalk.cyan(`\n${i18n.t('wizard.bun_installing')}\n`));
|
|
830
|
+
return new Promise((resolve) => {
|
|
831
|
+
let command;
|
|
832
|
+
let args;
|
|
833
|
+
if (isWindows) {
|
|
834
|
+
// Windows: use npm to install bun globally
|
|
835
|
+
command = 'npm.cmd';
|
|
836
|
+
args = ['install', '-g', 'bun'];
|
|
837
|
+
}
|
|
838
|
+
else {
|
|
839
|
+
// macOS/Linux: use curl installer
|
|
840
|
+
command = 'bash';
|
|
841
|
+
args = ['-c', 'curl -fsSL https://bun.sh/install | bash'];
|
|
842
|
+
}
|
|
843
|
+
const child = spawn(command, args, {
|
|
844
|
+
stdio: 'inherit',
|
|
845
|
+
shell: true,
|
|
846
|
+
});
|
|
847
|
+
child.on('close', async (code) => {
|
|
848
|
+
if (code === 0) {
|
|
849
|
+
console.log(chalk.green(`\n✅ ${i18n.t('wizard.bun_installed')}`));
|
|
850
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
851
|
+
resolve(true);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
console.log(chalk.red(`\n❌ ${i18n.t('wizard.bun_install_failed')}`));
|
|
855
|
+
console.log(chalk.cyan(` ${i18n.t('wizard.bun_install_hint')}`));
|
|
856
|
+
console.log(chalk.blue(' https://bun.sh/docs/installation\n'));
|
|
857
|
+
await this.promptWithHints([
|
|
858
|
+
{
|
|
859
|
+
type: 'input',
|
|
860
|
+
name: 'continue',
|
|
861
|
+
message: i18n.t('wizard.press_enter'),
|
|
862
|
+
},
|
|
863
|
+
]);
|
|
864
|
+
resolve(false);
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
child.on('error', async (error) => {
|
|
868
|
+
console.error(chalk.red(`\n❌ ${i18n.t('wizard.bun_install_failed')}`));
|
|
869
|
+
console.error(error);
|
|
870
|
+
await this.promptWithHints([
|
|
871
|
+
{
|
|
872
|
+
type: 'input',
|
|
873
|
+
name: 'continue',
|
|
874
|
+
message: i18n.t('wizard.press_enter'),
|
|
875
|
+
},
|
|
876
|
+
]);
|
|
877
|
+
resolve(false);
|
|
878
|
+
});
|
|
879
|
+
});
|
|
750
880
|
}
|
|
751
881
|
async startTool(toolName) {
|
|
752
882
|
const tool = SUPPORTED_TOOLS[toolName];
|
|
@@ -832,6 +962,13 @@ export class Wizard {
|
|
|
832
962
|
openCodeModel,
|
|
833
963
|
openCodeSmallModel,
|
|
834
964
|
});
|
|
965
|
+
// Update oh-my-opencode agent models if plugin is installed
|
|
966
|
+
if (toolName === 'opencode' && openCodeManager.hasOhMyOpenCodePlugin()) {
|
|
967
|
+
spinner.text = i18n.t('wizard.oh_my_opencode_detected');
|
|
968
|
+
openCodeManager.updateOhMyOpenCodeModels(openCodeModel);
|
|
969
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
970
|
+
console.log(chalk.gray(` ${i18n.t('wizard.oh_my_opencode_models_updated')}`));
|
|
971
|
+
}
|
|
835
972
|
await new Promise(resolve => setTimeout(resolve, 800));
|
|
836
973
|
spinner.succeed(chalk.green(i18n.t('wizard.config_loaded', { tool: SUPPORTED_TOOLS[toolName].displayName })));
|
|
837
974
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
package/dist/locales/en_US.json
CHANGED
|
@@ -156,7 +156,20 @@
|
|
|
156
156
|
"directory_required": "Directory path cannot be empty",
|
|
157
157
|
"directory_not_exist": "Directory does not exist",
|
|
158
158
|
"press_ctrl_c_to_exit": "Press Ctrl+C to go back",
|
|
159
|
-
"nav_go_back": "Go back"
|
|
159
|
+
"nav_go_back": "Go back",
|
|
160
|
+
"action_install_oh_my_opencode": "Install oh-my-opencode Plugin",
|
|
161
|
+
"oh_my_opencode_installing": "Installing oh-my-opencode...",
|
|
162
|
+
"oh_my_opencode_installed": "oh-my-opencode installed successfully!",
|
|
163
|
+
"oh_my_opencode_install_failed": "Failed to install oh-my-opencode",
|
|
164
|
+
"oh_my_opencode_detected": "oh-my-opencode plugin detected, updating agent models...",
|
|
165
|
+
"oh_my_opencode_models_updated": "oh-my-opencode agent models updated",
|
|
166
|
+
"oh_my_opencode_requires_bun": "oh-my-opencode requires Bun to be installed",
|
|
167
|
+
"bun_install_hint": "Please install Bun first:",
|
|
168
|
+
"bun_install_confirm": "Would you like to install Bun now?",
|
|
169
|
+
"bun_installing": "Installing Bun...",
|
|
170
|
+
"bun_installed": "Bun installed successfully!",
|
|
171
|
+
"bun_install_failed": "Failed to install Bun",
|
|
172
|
+
"bun_install_skipped": "Bun installation skipped"
|
|
160
173
|
},
|
|
161
174
|
"doctor": {
|
|
162
175
|
"checking": "Running health check...",
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -156,7 +156,20 @@
|
|
|
156
156
|
"directory_required": "目录路径不能为空",
|
|
157
157
|
"directory_not_exist": "目录不存在",
|
|
158
158
|
"press_ctrl_c_to_exit": "按 Ctrl+C 可退出返回",
|
|
159
|
-
"nav_go_back": "返回上一步"
|
|
159
|
+
"nav_go_back": "返回上一步",
|
|
160
|
+
"action_install_oh_my_opencode": "安装 oh-my-opencode 插件",
|
|
161
|
+
"oh_my_opencode_installing": "正在安装 oh-my-opencode...",
|
|
162
|
+
"oh_my_opencode_installed": "oh-my-opencode 安装成功!",
|
|
163
|
+
"oh_my_opencode_install_failed": "oh-my-opencode 安装失败",
|
|
164
|
+
"oh_my_opencode_detected": "检测到 oh-my-opencode 插件,正在更新 Agent 模型...",
|
|
165
|
+
"oh_my_opencode_models_updated": "oh-my-opencode Agent 模型已更新",
|
|
166
|
+
"oh_my_opencode_requires_bun": "oh-my-opencode 需要先安装 Bun",
|
|
167
|
+
"bun_install_hint": "请先安装 Bun:",
|
|
168
|
+
"bun_install_confirm": "是否需要帮您安装 Bun?",
|
|
169
|
+
"bun_installing": "正在安装 Bun...",
|
|
170
|
+
"bun_installed": "Bun 安装成功!",
|
|
171
|
+
"bun_install_failed": "Bun 安装失败",
|
|
172
|
+
"bun_install_skipped": "已跳过 Bun 安装"
|
|
160
173
|
},
|
|
161
174
|
"doctor": {
|
|
162
175
|
"checking": "正在进行健康检查...",
|