oh-my-opencode-slim 1.0.4 → 1.0.5
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 +9 -3
- package/dist/cli/config-io.d.ts +1 -0
- package/dist/cli/index.js +179 -9
- package/dist/cli/paths.d.ts +4 -0
- package/dist/cli/providers.d.ts +36 -2
- package/dist/cli/types.d.ts +3 -0
- package/dist/tui.d.ts +5 -0
- package/dist/tui.js +86 -0
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -37,9 +37,15 @@ Install and configure oh-my-opencode-slim: https://raw.githubusercontent.com/alv
|
|
|
37
37
|
bunx oh-my-opencode-slim@latest install
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
The installer also registers the companion TUI plugin in OpenCode's
|
|
41
|
+
`tui.json`, which adds an `OMOS <version>` badge beside the prompt without
|
|
42
|
+
replacing OpenCode's built-in TUI footer. For manual setups, add
|
|
43
|
+
`oh-my-opencode-slim` to the `plugin` array in both `opencode.json` and
|
|
44
|
+
`tui.json`.
|
|
45
|
+
|
|
40
46
|
### Getting Started
|
|
41
47
|
|
|
42
|
-
The installer generates
|
|
48
|
+
The installer generates both OpenAI and OpenCode Go presets, with OpenAI active by default. OpenAI uses `openai/gpt-5.5` for the higher-judgment agents and `openai/gpt-5.4-mini` for the faster scoped agents. To make OpenCode Go active during install, run `bunx oh-my-opencode-slim@latest install --preset=opencode-go`.
|
|
43
49
|
|
|
44
50
|
Then:
|
|
45
51
|
|
|
@@ -60,7 +66,7 @@ Then:
|
|
|
60
66
|
> [!TIP]
|
|
61
67
|
> Want to understand how automatic delegation works in practice? Review the **[Orchestrator prompt](https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/src/agents/orchestrator.ts#L28)** — it contains the delegation rules, specialist routing logic, and the thresholds for when the main agent should hand work off to subagents.
|
|
62
68
|
|
|
63
|
-
The default generated configuration
|
|
69
|
+
The default generated configuration includes both `openai` and `opencode-go` presets. Abbreviated:
|
|
64
70
|
|
|
65
71
|
```jsonc
|
|
66
72
|
{
|
|
@@ -85,7 +91,7 @@ want to customize how many resumable child-agent sessions are remembered.
|
|
|
85
91
|
|
|
86
92
|
### For Alternative Providers
|
|
87
93
|
|
|
88
|
-
To use Kimi, GitHub Copilot, ZAI Coding Plan, or a mixed-provider setup, use **[Configuration](docs/configuration.md)** for the full reference. If you want a ready-made starting point, check the **[Author's Preset](docs/authors-preset.md)** and **[$30 Preset](docs/thirty-dollars-preset.md)** - the `$30` preset is the best cheap setup.
|
|
94
|
+
To use OpenCode Go, Kimi, GitHub Copilot, ZAI Coding Plan, or a mixed-provider setup, use **[Configuration](docs/configuration.md)** for the full reference. If you want a ready-made starting point, check the **[Author's Preset](docs/authors-preset.md)** and **[$30 Preset](docs/thirty-dollars-preset.md)** - the `$30` preset is the best cheap setup.
|
|
89
95
|
|
|
90
96
|
The configuration guide also covers custom subagents via `agents.<name>`, where
|
|
91
97
|
you can define both a normal `prompt` and an `orchestratorPrompt` block for
|
package/dist/cli/config-io.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare function parseConfig(path: string): {
|
|
|
16
16
|
*/
|
|
17
17
|
export declare function writeConfig(configPath: string, config: OpenCodeConfig): void;
|
|
18
18
|
export declare function addPluginToOpenCodeConfig(): Promise<ConfigMergeResult>;
|
|
19
|
+
export declare function addPluginToOpenCodeTuiConfig(): Promise<ConfigMergeResult>;
|
|
19
20
|
export declare function writeLiteConfig(installConfig: InstallConfig, targetPath?: string): ConfigMergeResult;
|
|
20
21
|
export declare function disableDefaultAgents(): ConfigMergeResult;
|
|
21
22
|
export declare function enableLspByDefault(): ConfigMergeResult;
|
package/dist/cli/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
5
|
|
|
4
6
|
// src/cli/install.ts
|
|
5
7
|
import { existsSync as existsSync4 } from "node:fs";
|
|
8
|
+
import { createInterface } from "node:readline/promises";
|
|
6
9
|
|
|
7
10
|
// src/cli/config-io.ts
|
|
8
11
|
import {
|
|
@@ -27,6 +30,10 @@ function getCustomOpenCodeConfigDir() {
|
|
|
27
30
|
const configDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
28
31
|
return configDir || undefined;
|
|
29
32
|
}
|
|
33
|
+
function getCustomTuiConfigPath() {
|
|
34
|
+
const configPath = process.env.OPENCODE_TUI_CONFIG?.trim();
|
|
35
|
+
return configPath || undefined;
|
|
36
|
+
}
|
|
30
37
|
function getConfigDir() {
|
|
31
38
|
const customConfigDir = getCustomOpenCodeConfigDir();
|
|
32
39
|
if (customConfigDir) {
|
|
@@ -50,6 +57,15 @@ function getLiteConfig() {
|
|
|
50
57
|
function getLiteConfigJsonc() {
|
|
51
58
|
return join(getConfigDir(), "oh-my-opencode-slim.jsonc");
|
|
52
59
|
}
|
|
60
|
+
function getTuiConfig() {
|
|
61
|
+
const customConfigPath = getCustomTuiConfigPath();
|
|
62
|
+
if (customConfigPath)
|
|
63
|
+
return customConfigPath;
|
|
64
|
+
return join(getConfigDir(), "tui.json");
|
|
65
|
+
}
|
|
66
|
+
function getTuiConfigJsonc() {
|
|
67
|
+
return join(getConfigDir(), "tui.jsonc");
|
|
68
|
+
}
|
|
53
69
|
function getExistingLiteConfigPath() {
|
|
54
70
|
const jsonPath = getLiteConfig();
|
|
55
71
|
if (existsSync(jsonPath))
|
|
@@ -59,6 +75,18 @@ function getExistingLiteConfigPath() {
|
|
|
59
75
|
return jsoncPath;
|
|
60
76
|
return jsonPath;
|
|
61
77
|
}
|
|
78
|
+
function getExistingTuiConfigPath() {
|
|
79
|
+
const customConfigPath = getCustomTuiConfigPath();
|
|
80
|
+
if (customConfigPath)
|
|
81
|
+
return customConfigPath;
|
|
82
|
+
const jsonPath = join(getConfigDir(), "tui.json");
|
|
83
|
+
if (existsSync(jsonPath))
|
|
84
|
+
return jsonPath;
|
|
85
|
+
const jsoncPath = getTuiConfigJsonc();
|
|
86
|
+
if (existsSync(jsoncPath))
|
|
87
|
+
return jsoncPath;
|
|
88
|
+
return jsonPath;
|
|
89
|
+
}
|
|
62
90
|
function getExistingConfigPath() {
|
|
63
91
|
const jsonPath = getConfigJson();
|
|
64
92
|
if (existsSync(jsonPath))
|
|
@@ -74,6 +102,12 @@ function ensureConfigDir() {
|
|
|
74
102
|
mkdirSync(configDir, { recursive: true });
|
|
75
103
|
}
|
|
76
104
|
}
|
|
105
|
+
function ensureTuiConfigDir() {
|
|
106
|
+
const configDir = dirname(getTuiConfig());
|
|
107
|
+
if (!existsSync(configDir)) {
|
|
108
|
+
mkdirSync(configDir, { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
77
111
|
function ensureOpenCodeConfigDir() {
|
|
78
112
|
const configDir = dirname(getConfigJson());
|
|
79
113
|
if (!existsSync(configDir)) {
|
|
@@ -458,6 +492,7 @@ function installSkill(skill) {
|
|
|
458
492
|
|
|
459
493
|
// src/cli/providers.ts
|
|
460
494
|
var SCHEMA_URL = "https://unpkg.com/oh-my-opencode-slim@latest/oh-my-opencode-slim.schema.json";
|
|
495
|
+
var GENERATED_PRESETS = ["openai", "opencode-go"];
|
|
461
496
|
var MODEL_MAPPINGS = {
|
|
462
497
|
openai: {
|
|
463
498
|
orchestrator: { model: "openai/gpt-5.5" },
|
|
@@ -493,12 +528,31 @@ var MODEL_MAPPINGS = {
|
|
|
493
528
|
explorer: { model: "zai-coding-plan/glm-5", variant: "low" },
|
|
494
529
|
designer: { model: "zai-coding-plan/glm-5", variant: "medium" },
|
|
495
530
|
fixer: { model: "zai-coding-plan/glm-5", variant: "low" }
|
|
531
|
+
},
|
|
532
|
+
"opencode-go": {
|
|
533
|
+
orchestrator: { model: "opencode-go/glm-5.1" },
|
|
534
|
+
oracle: { model: "opencode-go/deepseek-v4-pro", variant: "max" },
|
|
535
|
+
council: { model: "opencode-go/deepseek-v4-pro", variant: "high" },
|
|
536
|
+
librarian: { model: "opencode-go/minimax-m2.7" },
|
|
537
|
+
explorer: { model: "opencode-go/minimax-m2.7" },
|
|
538
|
+
designer: { model: "opencode-go/kimi-k2.6", variant: "medium" },
|
|
539
|
+
fixer: { model: "opencode-go/deepseek-v4-flash", variant: "high" }
|
|
496
540
|
}
|
|
497
541
|
};
|
|
542
|
+
function isGeneratedPresetName(value) {
|
|
543
|
+
return GENERATED_PRESETS.includes(value);
|
|
544
|
+
}
|
|
545
|
+
function getGeneratedPresetNames() {
|
|
546
|
+
return [...GENERATED_PRESETS];
|
|
547
|
+
}
|
|
498
548
|
function generateLiteConfig(installConfig) {
|
|
549
|
+
const preset = installConfig.preset ?? "openai";
|
|
550
|
+
if (!isGeneratedPresetName(preset)) {
|
|
551
|
+
throw new Error(`Unsupported preset "${preset}". Available generated presets: ${getGeneratedPresetNames().join(", ")}`);
|
|
552
|
+
}
|
|
499
553
|
const config = {
|
|
500
554
|
$schema: SCHEMA_URL,
|
|
501
|
-
preset
|
|
555
|
+
preset,
|
|
502
556
|
presets: {}
|
|
503
557
|
};
|
|
504
558
|
const createAgentConfig = (agentName, modelInfo) => {
|
|
@@ -524,7 +578,10 @@ function generateLiteConfig(installConfig) {
|
|
|
524
578
|
createAgentConfig(agentName, modelInfo)
|
|
525
579
|
]));
|
|
526
580
|
};
|
|
527
|
-
|
|
581
|
+
const presets = config.presets;
|
|
582
|
+
for (const presetName of GENERATED_PRESETS) {
|
|
583
|
+
presets[presetName] = buildPreset(presetName);
|
|
584
|
+
}
|
|
528
585
|
if (installConfig.hasTmux) {
|
|
529
586
|
config.tmux = {
|
|
530
587
|
enabled: true,
|
|
@@ -546,6 +603,14 @@ function getPlugins(config) {
|
|
|
546
603
|
function getPluginEntries(config) {
|
|
547
604
|
return getPlugins(config).filter(isString);
|
|
548
605
|
}
|
|
606
|
+
function getPluginSpec(entry) {
|
|
607
|
+
if (isString(entry))
|
|
608
|
+
return entry;
|
|
609
|
+
if (!Array.isArray(entry))
|
|
610
|
+
return;
|
|
611
|
+
const spec = entry[0];
|
|
612
|
+
return isString(spec) ? spec : undefined;
|
|
613
|
+
}
|
|
549
614
|
function normalizePathForMatch(path) {
|
|
550
615
|
return path.replaceAll("\\", "/");
|
|
551
616
|
}
|
|
@@ -590,6 +655,10 @@ function isLocalPackageRootEntry(entry) {
|
|
|
590
655
|
function isPluginEntry(entry) {
|
|
591
656
|
return entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`) || entry.startsWith("file://") && entry.includes(PACKAGE_NAME) || isLocalPackageRootEntry(entry);
|
|
592
657
|
}
|
|
658
|
+
function isMatchingPluginEntry(entry) {
|
|
659
|
+
const spec = getPluginSpec(entry);
|
|
660
|
+
return spec ? isPluginEntry(spec) : false;
|
|
661
|
+
}
|
|
593
662
|
function getPluginEntry() {
|
|
594
663
|
const cliEntryPath = process.argv[1];
|
|
595
664
|
if (!cliEntryPath) {
|
|
@@ -672,7 +741,7 @@ async function addPluginToOpenCodeConfig() {
|
|
|
672
741
|
const config = parsedConfig ?? {};
|
|
673
742
|
const plugins = getPlugins(config);
|
|
674
743
|
const pluginEntry = getPluginEntry();
|
|
675
|
-
const filteredPlugins = plugins.filter((plugin) => !
|
|
744
|
+
const filteredPlugins = plugins.filter((plugin) => !isMatchingPluginEntry(plugin));
|
|
676
745
|
filteredPlugins.push(pluginEntry);
|
|
677
746
|
config.plugin = filteredPlugins;
|
|
678
747
|
writeConfig(configPath, config);
|
|
@@ -685,6 +754,42 @@ async function addPluginToOpenCodeConfig() {
|
|
|
685
754
|
};
|
|
686
755
|
}
|
|
687
756
|
}
|
|
757
|
+
async function addPluginToOpenCodeTuiConfig() {
|
|
758
|
+
const configPath = getExistingTuiConfigPath();
|
|
759
|
+
try {
|
|
760
|
+
ensureTuiConfigDir();
|
|
761
|
+
} catch (err) {
|
|
762
|
+
return {
|
|
763
|
+
success: false,
|
|
764
|
+
configPath,
|
|
765
|
+
error: `Failed to create config directory: ${err}`
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
try {
|
|
769
|
+
const { config: parsedConfig, error } = parseConfig(configPath);
|
|
770
|
+
if (error) {
|
|
771
|
+
return {
|
|
772
|
+
success: false,
|
|
773
|
+
configPath,
|
|
774
|
+
error: `Failed to parse TUI config: ${error}`
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
const config = parsedConfig ?? {};
|
|
778
|
+
const plugins = getPlugins(config);
|
|
779
|
+
const pluginEntry = getPluginEntry();
|
|
780
|
+
const filteredPlugins = plugins.filter((plugin) => !isMatchingPluginEntry(plugin));
|
|
781
|
+
filteredPlugins.push(pluginEntry);
|
|
782
|
+
config.plugin = filteredPlugins;
|
|
783
|
+
writeConfig(configPath, config);
|
|
784
|
+
return { success: true, configPath };
|
|
785
|
+
} catch (err) {
|
|
786
|
+
return {
|
|
787
|
+
success: false,
|
|
788
|
+
configPath,
|
|
789
|
+
error: `Failed to update opencode TUI config: ${err}`
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
}
|
|
688
793
|
function writeLiteConfig(installConfig, targetPath) {
|
|
689
794
|
const configPath = targetPath ?? getLiteConfig();
|
|
690
795
|
try {
|
|
@@ -1005,8 +1110,10 @@ var SYMBOLS = {
|
|
|
1005
1110
|
bullet: `${DIM}-${RESET}`,
|
|
1006
1111
|
info: `${BLUE}[i]${RESET}`,
|
|
1007
1112
|
warn: `${YELLOW}[!]${RESET}`,
|
|
1008
|
-
star: `${YELLOW}
|
|
1113
|
+
star: `${YELLOW}★${RESET}`
|
|
1009
1114
|
};
|
|
1115
|
+
var GITHUB_REPO = "alvinunreal/oh-my-opencode-slim";
|
|
1116
|
+
var GITHUB_URL = `https://github.com/${GITHUB_REPO}`;
|
|
1010
1117
|
function printHeader(isUpdate) {
|
|
1011
1118
|
console.log();
|
|
1012
1119
|
console.log(`${BOLD}oh-my-opencode-slim ${isUpdate ? "Update" : "Install"}${RESET}`);
|
|
@@ -1025,6 +1132,34 @@ function printError(message) {
|
|
|
1025
1132
|
function printInfo(message) {
|
|
1026
1133
|
console.log(`${SYMBOLS.info} ${message}`);
|
|
1027
1134
|
}
|
|
1135
|
+
async function confirm(message, defaultYes = true) {
|
|
1136
|
+
const suffix = defaultYes ? " (Y/n) " : " (y/N) ";
|
|
1137
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1138
|
+
try {
|
|
1139
|
+
const answer = (await rl.question(`${message}${suffix}`)).trim().toLowerCase();
|
|
1140
|
+
if (!answer)
|
|
1141
|
+
return defaultYes;
|
|
1142
|
+
return answer === "y" || answer === "yes";
|
|
1143
|
+
} finally {
|
|
1144
|
+
rl.close();
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
async function askToStarRepo(config) {
|
|
1148
|
+
if (!config.promptForStar || config.dryRun || !process.stdin.isTTY)
|
|
1149
|
+
return;
|
|
1150
|
+
console.log();
|
|
1151
|
+
const shouldStar = await confirm(`${SYMBOLS.star} Star the repo on GitHub?`, true);
|
|
1152
|
+
if (!shouldStar)
|
|
1153
|
+
return;
|
|
1154
|
+
try {
|
|
1155
|
+
const { execFileSync } = await import("node:child_process");
|
|
1156
|
+
execFileSync("gh", ["api", "--silent", "--method", "PUT", `/user/starred/${GITHUB_REPO}`], { stdio: "ignore", timeout: 1e4 });
|
|
1157
|
+
printSuccess("Thanks for starring! ★");
|
|
1158
|
+
} catch {
|
|
1159
|
+
printInfo(`Couldn't star automatically. You can star manually:
|
|
1160
|
+
${BLUE}${GITHUB_URL}${RESET}`);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1028
1163
|
async function checkOpenCodeInstalled() {
|
|
1029
1164
|
const installed = await isOpenCodeInstalled();
|
|
1030
1165
|
if (!installed) {
|
|
@@ -1056,7 +1191,7 @@ async function runInstall(config) {
|
|
|
1056
1191
|
const detected = detectCurrentConfig();
|
|
1057
1192
|
const isUpdate = detected.isInstalled;
|
|
1058
1193
|
printHeader(isUpdate);
|
|
1059
|
-
let totalSteps =
|
|
1194
|
+
let totalSteps = 6;
|
|
1060
1195
|
if (config.installSkills)
|
|
1061
1196
|
totalSteps += 1;
|
|
1062
1197
|
if (config.installCustomSkills)
|
|
@@ -1078,6 +1213,17 @@ async function runInstall(config) {
|
|
|
1078
1213
|
if (!handleStepResult(pluginResult, "Plugin added"))
|
|
1079
1214
|
return 1;
|
|
1080
1215
|
}
|
|
1216
|
+
printStep(step++, totalSteps, "Adding TUI version badge...");
|
|
1217
|
+
if (config.dryRun) {
|
|
1218
|
+
printInfo("Dry run mode - skipping TUI plugin installation");
|
|
1219
|
+
} else {
|
|
1220
|
+
const tuiResult = await addPluginToOpenCodeTuiConfig();
|
|
1221
|
+
if (!tuiResult.success) {
|
|
1222
|
+
printInfo(`Skipped TUI badge: ${tuiResult.error}`);
|
|
1223
|
+
} else {
|
|
1224
|
+
handleStepResult(tuiResult, "TUI badge added");
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1081
1227
|
printStep(step++, totalSteps, "Disabling OpenCode default agents...");
|
|
1082
1228
|
if (config.dryRun) {
|
|
1083
1229
|
printInfo("Dry run mode - skipping agent disabling");
|
|
@@ -1105,7 +1251,7 @@ ${JSON.stringify(liteConfig, null, 2)}
|
|
|
1105
1251
|
const configPath2 = getExistingLiteConfigPath();
|
|
1106
1252
|
const configExists = existsSync4(configPath2);
|
|
1107
1253
|
if (configExists && !config.reset) {
|
|
1108
|
-
printInfo(`Configuration already exists at ${configPath2}.
|
|
1254
|
+
printInfo(`Configuration already exists at ${configPath2}. Use --reset to overwrite.`);
|
|
1109
1255
|
} else {
|
|
1110
1256
|
const liteResult = writeLiteConfig(config, configExists ? configPath2 : undefined);
|
|
1111
1257
|
if (!handleStepResult(liteResult, configExists ? "Config reset" : "Config written"))
|
|
@@ -1176,13 +1322,14 @@ ${JSON.stringify(liteConfig, null, 2)}
|
|
|
1176
1322
|
console.log(" 5. Verify the agents are responding:");
|
|
1177
1323
|
console.log(` ${BLUE}> ping all agents${RESET}`);
|
|
1178
1324
|
console.log();
|
|
1179
|
-
const modelsInfo = "
|
|
1325
|
+
const modelsInfo = config.preset && config.preset !== "openai" ? `Generated OpenAI and OpenCode Go presets; ${config.preset} is active.` : "Generated OpenAI and OpenCode Go presets; OpenAI is active by default.";
|
|
1180
1326
|
console.log(`${modelsInfo}`);
|
|
1181
1327
|
const altProviders = "For the full configuration reference, see:";
|
|
1182
1328
|
console.log(altProviders);
|
|
1183
|
-
const docsUrl = "https://github.com/alvinunreal/oh-my-opencode-slim/
|
|
1329
|
+
const docsUrl = "https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/configuration.md";
|
|
1184
1330
|
console.log(` ${BLUE}${docsUrl}${RESET}`);
|
|
1185
1331
|
console.log();
|
|
1332
|
+
await askToStarRepo(config);
|
|
1186
1333
|
return 0;
|
|
1187
1334
|
}
|
|
1188
1335
|
async function install(args) {
|
|
@@ -1190,12 +1337,23 @@ async function install(args) {
|
|
|
1190
1337
|
hasTmux: false,
|
|
1191
1338
|
installSkills: args.skills === "yes",
|
|
1192
1339
|
installCustomSkills: args.skills === "yes",
|
|
1340
|
+
preset: args.preset,
|
|
1341
|
+
promptForStar: args.tui,
|
|
1193
1342
|
dryRun: args.dryRun,
|
|
1194
1343
|
reset: args.reset ?? false
|
|
1195
1344
|
};
|
|
1196
1345
|
return runInstall(config);
|
|
1197
1346
|
}
|
|
1198
1347
|
|
|
1348
|
+
// src/cli/providers.ts
|
|
1349
|
+
var GENERATED_PRESETS2 = ["openai", "opencode-go"];
|
|
1350
|
+
function isGeneratedPresetName2(value) {
|
|
1351
|
+
return GENERATED_PRESETS2.includes(value);
|
|
1352
|
+
}
|
|
1353
|
+
function getGeneratedPresetNames2() {
|
|
1354
|
+
return [...GENERATED_PRESETS2];
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1199
1357
|
// src/cli/index.ts
|
|
1200
1358
|
function parseArgs(args) {
|
|
1201
1359
|
const result = {
|
|
@@ -1207,6 +1365,13 @@ function parseArgs(args) {
|
|
|
1207
1365
|
result.tui = false;
|
|
1208
1366
|
} else if (arg.startsWith("--skills=")) {
|
|
1209
1367
|
result.skills = arg.split("=")[1];
|
|
1368
|
+
} else if (arg.startsWith("--preset=")) {
|
|
1369
|
+
const preset = arg.split("=")[1];
|
|
1370
|
+
if (!isGeneratedPresetName2(preset)) {
|
|
1371
|
+
console.error(`Unsupported preset: ${preset}. Available presets: ${getGeneratedPresetNames2().join(", ")}`);
|
|
1372
|
+
process.exit(1);
|
|
1373
|
+
}
|
|
1374
|
+
result.preset = preset;
|
|
1210
1375
|
} else if (arg === "--dry-run") {
|
|
1211
1376
|
result.dryRun = true;
|
|
1212
1377
|
} else if (arg === "--reset") {
|
|
@@ -1226,17 +1391,22 @@ Usage: bunx oh-my-opencode-slim install [OPTIONS]
|
|
|
1226
1391
|
|
|
1227
1392
|
Options:
|
|
1228
1393
|
--skills=yes|no Install recommended and bundled skills (default: yes)
|
|
1394
|
+
--preset=<name> Active generated config preset (default: openai)
|
|
1229
1395
|
--no-tui Non-interactive mode
|
|
1230
1396
|
--dry-run Simulate install without writing files
|
|
1231
1397
|
--reset Force overwrite of existing configuration
|
|
1232
1398
|
-h, --help Show this help message
|
|
1233
1399
|
|
|
1234
|
-
|
|
1400
|
+
Available presets: ${getGeneratedPresetNames2().join(", ")}
|
|
1401
|
+
|
|
1402
|
+
The installer generates OpenAI and OpenCode Go presets by default.
|
|
1403
|
+
OpenAI is active unless --preset selects another generated preset.
|
|
1235
1404
|
For the full config reference, see docs/configuration.md.
|
|
1236
1405
|
|
|
1237
1406
|
Examples:
|
|
1238
1407
|
bunx oh-my-opencode-slim install
|
|
1239
1408
|
bunx oh-my-opencode-slim install --no-tui --skills=yes
|
|
1409
|
+
bunx oh-my-opencode-slim install --preset=opencode-go
|
|
1240
1410
|
bunx oh-my-opencode-slim install --reset
|
|
1241
1411
|
`);
|
|
1242
1412
|
}
|
package/dist/cli/paths.d.ts
CHANGED
|
@@ -22,9 +22,13 @@ export declare function getConfigJson(): string;
|
|
|
22
22
|
export declare function getConfigJsonc(): string;
|
|
23
23
|
export declare function getLiteConfig(): string;
|
|
24
24
|
export declare function getLiteConfigJsonc(): string;
|
|
25
|
+
export declare function getTuiConfig(): string;
|
|
26
|
+
export declare function getTuiConfigJsonc(): string;
|
|
25
27
|
export declare function getExistingLiteConfigPath(): string;
|
|
28
|
+
export declare function getExistingTuiConfigPath(): string;
|
|
26
29
|
export declare function getExistingConfigPath(): string;
|
|
27
30
|
export declare function ensureConfigDir(): void;
|
|
31
|
+
export declare function ensureTuiConfigDir(): void;
|
|
28
32
|
/**
|
|
29
33
|
* Ensure the directory for OpenCode's main config file exists.
|
|
30
34
|
*/
|
package/dist/cli/providers.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { InstallConfig } from
|
|
1
|
+
import type { InstallConfig } from './types';
|
|
2
|
+
export declare const GENERATED_PRESETS: readonly ["openai", "opencode-go"];
|
|
2
3
|
export declare const MODEL_MAPPINGS: {
|
|
3
4
|
readonly openai: {
|
|
4
5
|
readonly orchestrator: {
|
|
@@ -75,7 +76,7 @@ export declare const MODEL_MAPPINGS: {
|
|
|
75
76
|
readonly variant: "low";
|
|
76
77
|
};
|
|
77
78
|
};
|
|
78
|
-
readonly
|
|
79
|
+
readonly 'zai-plan': {
|
|
79
80
|
readonly orchestrator: {
|
|
80
81
|
readonly model: "zai-coding-plan/glm-5";
|
|
81
82
|
};
|
|
@@ -100,5 +101,38 @@ export declare const MODEL_MAPPINGS: {
|
|
|
100
101
|
readonly variant: "low";
|
|
101
102
|
};
|
|
102
103
|
};
|
|
104
|
+
readonly 'opencode-go': {
|
|
105
|
+
readonly orchestrator: {
|
|
106
|
+
readonly model: "opencode-go/glm-5.1";
|
|
107
|
+
};
|
|
108
|
+
readonly oracle: {
|
|
109
|
+
readonly model: "opencode-go/deepseek-v4-pro";
|
|
110
|
+
readonly variant: "max";
|
|
111
|
+
};
|
|
112
|
+
readonly council: {
|
|
113
|
+
readonly model: "opencode-go/deepseek-v4-pro";
|
|
114
|
+
readonly variant: "high";
|
|
115
|
+
};
|
|
116
|
+
readonly librarian: {
|
|
117
|
+
readonly model: "opencode-go/minimax-m2.7";
|
|
118
|
+
};
|
|
119
|
+
readonly explorer: {
|
|
120
|
+
readonly model: "opencode-go/minimax-m2.7";
|
|
121
|
+
};
|
|
122
|
+
readonly designer: {
|
|
123
|
+
readonly model: "opencode-go/kimi-k2.6";
|
|
124
|
+
readonly variant: "medium";
|
|
125
|
+
};
|
|
126
|
+
readonly fixer: {
|
|
127
|
+
readonly model: "opencode-go/deepseek-v4-flash";
|
|
128
|
+
readonly variant: "high";
|
|
129
|
+
};
|
|
130
|
+
};
|
|
103
131
|
};
|
|
132
|
+
export type PresetName = keyof typeof MODEL_MAPPINGS;
|
|
133
|
+
export type GeneratedPresetName = (typeof GENERATED_PRESETS)[number];
|
|
134
|
+
export declare function isPresetName(value: string): value is PresetName;
|
|
135
|
+
export declare function getPresetNames(): PresetName[];
|
|
136
|
+
export declare function isGeneratedPresetName(value: string): value is GeneratedPresetName;
|
|
137
|
+
export declare function getGeneratedPresetNames(): GeneratedPresetName[];
|
|
104
138
|
export declare function generateLiteConfig(installConfig: InstallConfig): Record<string, unknown>;
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export type BooleanArg = 'yes' | 'no';
|
|
|
2
2
|
export interface InstallArgs {
|
|
3
3
|
tui: boolean;
|
|
4
4
|
skills?: BooleanArg;
|
|
5
|
+
preset?: string;
|
|
5
6
|
dryRun?: boolean;
|
|
6
7
|
reset?: boolean;
|
|
7
8
|
}
|
|
@@ -15,6 +16,8 @@ export interface InstallConfig {
|
|
|
15
16
|
hasTmux: boolean;
|
|
16
17
|
installSkills: boolean;
|
|
17
18
|
installCustomSkills: boolean;
|
|
19
|
+
preset?: string;
|
|
20
|
+
promptForStar?: boolean;
|
|
18
21
|
dryRun?: boolean;
|
|
19
22
|
reset: boolean;
|
|
20
23
|
}
|
package/dist/tui.d.ts
ADDED
package/dist/tui.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
32
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
34
|
+
|
|
35
|
+
// src/tui.ts
|
|
36
|
+
import { createElement, insert, setProp } from "@opentui/solid";
|
|
37
|
+
var PLUGIN_NAME = "oh-my-opencode-slim";
|
|
38
|
+
var PLUGIN_LABEL = "OMOS";
|
|
39
|
+
async function readPackageVersion() {
|
|
40
|
+
try {
|
|
41
|
+
const packageJson = await Bun.file(new URL("../package.json", import.meta.url)).json();
|
|
42
|
+
return typeof packageJson.version === "string" ? packageJson.version : undefined;
|
|
43
|
+
} catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function element(tag, props, children = []) {
|
|
48
|
+
const node = createElement(tag);
|
|
49
|
+
for (const [key, value] of Object.entries(props)) {
|
|
50
|
+
if (value !== undefined)
|
|
51
|
+
setProp(node, key, value);
|
|
52
|
+
}
|
|
53
|
+
for (const child of children) {
|
|
54
|
+
if (child === null || child === undefined || child === false)
|
|
55
|
+
continue;
|
|
56
|
+
insert(node, child);
|
|
57
|
+
}
|
|
58
|
+
return node;
|
|
59
|
+
}
|
|
60
|
+
function text(props, children) {
|
|
61
|
+
return element("text", props, children);
|
|
62
|
+
}
|
|
63
|
+
var plugin = {
|
|
64
|
+
id: `${PLUGIN_NAME}:tui`,
|
|
65
|
+
tui: async (api, _options, meta) => {
|
|
66
|
+
const version = meta.version ?? await readPackageVersion() ?? "dev";
|
|
67
|
+
const versionText = `${PLUGIN_LABEL} ${version}`;
|
|
68
|
+
api.slots.register({
|
|
69
|
+
order: 900,
|
|
70
|
+
slots: {
|
|
71
|
+
home_prompt_right() {
|
|
72
|
+
const theme = api.theme.current;
|
|
73
|
+
return text({ fg: theme.textMuted }, [versionText]);
|
|
74
|
+
},
|
|
75
|
+
session_prompt_right() {
|
|
76
|
+
const theme = api.theme.current;
|
|
77
|
+
return text({ fg: theme.textMuted }, [versionText]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var tui_default = plugin;
|
|
84
|
+
export {
|
|
85
|
+
tui_default as default
|
|
86
|
+
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode-slim",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./tui": {
|
|
13
|
+
"import": "./dist/tui.js",
|
|
14
|
+
"types": "./dist/tui.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
7
17
|
"bin": {
|
|
8
18
|
"oh-my-opencode-slim": "./dist/cli/index.js"
|
|
9
19
|
},
|
|
@@ -36,7 +46,7 @@
|
|
|
36
46
|
"LICENSE"
|
|
37
47
|
],
|
|
38
48
|
"scripts": {
|
|
39
|
-
"build:plugin": "bun build src/index.ts --outdir dist --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/sdk --external jsdom --external zod",
|
|
49
|
+
"build:plugin": "bun build src/index.ts src/tui.ts --outdir dist --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/sdk --external @opentui/core --external @opentui/solid --external jsdom --external zod",
|
|
40
50
|
"build:cli": "bun build src/cli/index.ts --outdir dist/cli --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/sdk --external jsdom --external zod",
|
|
41
51
|
"build": "bun run build:plugin && bun run build:cli && tsc --emitDeclarationOnly && bun run generate-schema",
|
|
42
52
|
"prepare": "bun run build",
|
|
@@ -68,6 +78,9 @@
|
|
|
68
78
|
"lru-cache": "^11.3.3",
|
|
69
79
|
"turndown": "^7.2.4"
|
|
70
80
|
},
|
|
81
|
+
"optionalDependencies": {
|
|
82
|
+
"@opentui/solid": "^0.1.97"
|
|
83
|
+
},
|
|
71
84
|
"devDependencies": {
|
|
72
85
|
"@biomejs/biome": "2.4.11",
|
|
73
86
|
"@types/jsdom": "^21.1.7",
|