opencode-setup 0.1.0 → 0.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/dist/{chunk-PKHQD5QT.js → chunk-FTV7ABVP.js} +90 -17
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +144 -4
- package/dist/core/agent-generator.d.ts +2 -0
- package/dist/core/agents-md-generator.d.ts +3 -0
- package/dist/core/command-generator.d.ts +2 -0
- package/dist/core/config-generator.d.ts +6 -0
- package/dist/core/env-generator.d.ts +3 -0
- package/dist/core/omo-generator.d.ts +20 -0
- package/dist/core/skill-generator.d.ts +3 -0
- package/dist/doctor/checks.d.ts +7 -0
- package/dist/doctor/reporter.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +29 -17
- package/dist/migrate/aider.d.ts +1 -0
- package/dist/migrate/claude-code.d.ts +1 -0
- package/dist/migrate/common.d.ts +8 -0
- package/dist/migrate/cursor.d.ts +1 -0
- package/dist/migrate/index.d.ts +3 -0
- package/dist/preset/registry.d.ts +58 -0
- package/dist/prompt/questions.d.ts +18 -0
- package/dist/prompt/wizard.d.ts +1 -0
- package/dist/templates/omo/free.json +55 -0
- package/dist/templates/omo/premium.json +60 -0
- package/dist/tools/setup-doctor.d.ts +5 -0
- package/dist/tools/setup-init.d.ts +2 -0
- package/dist/tools/setup-migrate.d.ts +2 -0
- package/dist/tools/setup-preset.d.ts +7 -0
- package/dist/tools/setup-validate.d.ts +5 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/migration.d.ts +25 -0
- package/dist/types/opencode-config.d.ts +55 -0
- package/dist/types/user-profile.d.ts +55 -0
- package/dist/validator/config-validator.d.ts +1 -0
- package/package.json +9 -9
- package/templates/omo/free.json +55 -0
- package/templates/omo/premium.json +60 -0
|
@@ -82,6 +82,18 @@ var STACK_PRESETS = [
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
];
|
|
85
|
+
var OMO_PRESETS = [
|
|
86
|
+
{
|
|
87
|
+
name: "omo-free",
|
|
88
|
+
description: "OpenCode Go \uBB23\uB85C \uBAA8\uB378 \uAE30\uBC18 OMO \uC124\uC815",
|
|
89
|
+
configPath: "omo/free.json"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "omo-premium",
|
|
93
|
+
description: "\uACE0\uC131\uB2A5 \uC720\uB8CC \uBAA8\uB378 \uAE30\uBC18 OMO \uC124\uC815",
|
|
94
|
+
configPath: "omo/premium.json"
|
|
95
|
+
}
|
|
96
|
+
];
|
|
85
97
|
function listPresets() {
|
|
86
98
|
const lines = ["# Available Presets\n"];
|
|
87
99
|
lines.push("## Model Presets");
|
|
@@ -99,6 +111,14 @@ function listPresets() {
|
|
|
99
111
|
for (const preset of STACK_PRESETS) {
|
|
100
112
|
lines.push(`| \`${preset.name}\` | ${preset.description} |`);
|
|
101
113
|
}
|
|
114
|
+
lines.push("");
|
|
115
|
+
lines.push("## OMO Presets");
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push("| Name | Description |");
|
|
118
|
+
lines.push("|------|-------------|");
|
|
119
|
+
for (const preset of OMO_PRESETS) {
|
|
120
|
+
lines.push(`| \`${preset.name}\` | ${preset.description} |`);
|
|
121
|
+
}
|
|
102
122
|
return lines.join("\n");
|
|
103
123
|
}
|
|
104
124
|
function getModelPreset(name) {
|
|
@@ -107,6 +127,9 @@ function getModelPreset(name) {
|
|
|
107
127
|
function getStackPreset(name) {
|
|
108
128
|
return STACK_PRESETS.find((p) => p.name === name);
|
|
109
129
|
}
|
|
130
|
+
function getOMOPreset(name) {
|
|
131
|
+
return OMO_PRESETS.find((p) => p.name === name);
|
|
132
|
+
}
|
|
110
133
|
async function applyPreset(name, projectDir, options = {}) {
|
|
111
134
|
const files = [];
|
|
112
135
|
const warnings = [];
|
|
@@ -182,6 +205,39 @@ async function applyPreset(name, projectDir, options = {}) {
|
|
|
182
205
|
warnings.push(...modelResult.warnings);
|
|
183
206
|
return { success: true, files, warnings };
|
|
184
207
|
}
|
|
208
|
+
const omoPreset = getOMOPreset(name);
|
|
209
|
+
if (omoPreset) {
|
|
210
|
+
const { homedir: homedir2 } = await import("os");
|
|
211
|
+
const homeDir = homedir2();
|
|
212
|
+
const configDir = join(homeDir, ".config/opencode");
|
|
213
|
+
const omoConfigPath = join(configDir, "oh-my-opencode.json");
|
|
214
|
+
if (!existsSync(configDir)) {
|
|
215
|
+
mkdirSync(configDir, { recursive: true });
|
|
216
|
+
}
|
|
217
|
+
const src = join(TEMPLATES_DIR, omoPreset.configPath);
|
|
218
|
+
if (existsSync(src)) {
|
|
219
|
+
cpSync(src, omoConfigPath);
|
|
220
|
+
files.push(omoConfigPath);
|
|
221
|
+
} else {
|
|
222
|
+
warnings.push(`OMO template not found: ${src}`);
|
|
223
|
+
}
|
|
224
|
+
const opencodeConfigPath = join(projectDir, "opencode.json");
|
|
225
|
+
if (existsSync(opencodeConfigPath)) {
|
|
226
|
+
try {
|
|
227
|
+
const opencodeConfig = JSON.parse(readFileSync(opencodeConfigPath, "utf-8"));
|
|
228
|
+
const plugins = opencodeConfig.plugin || [];
|
|
229
|
+
if (!plugins.includes("oh-my-opencode")) {
|
|
230
|
+
plugins.push("oh-my-opencode");
|
|
231
|
+
opencodeConfig.plugin = plugins;
|
|
232
|
+
writeFileSync(opencodeConfigPath, JSON.stringify(opencodeConfig, null, 2) + "\n");
|
|
233
|
+
files.push(opencodeConfigPath);
|
|
234
|
+
}
|
|
235
|
+
} catch {
|
|
236
|
+
warnings.push(`Could not update opencode.json with oh-my-opencode plugin`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return { success: true, files, warnings };
|
|
240
|
+
}
|
|
185
241
|
return {
|
|
186
242
|
success: false,
|
|
187
243
|
files: [],
|
|
@@ -204,7 +260,7 @@ async function runValidation(directory) {
|
|
|
204
260
|
errors.push({ type: "warning", file: "~/.config/opencode/opencode.json", message: "Missing $schema field" });
|
|
205
261
|
}
|
|
206
262
|
if (config.model) {
|
|
207
|
-
const modelPattern = /^[a-
|
|
263
|
+
const modelPattern = /^[a-zA-Z0-9._-]+\/[a-zA-Z0-9._-]+$/;
|
|
208
264
|
if (!modelPattern.test(config.model)) {
|
|
209
265
|
errors.push({ type: "error", file: "~/.config/opencode/opencode.json", message: `Invalid model format: '${config.model}'. Expected 'provider/model'` });
|
|
210
266
|
}
|
|
@@ -279,6 +335,7 @@ async function runValidation(directory) {
|
|
|
279
335
|
|
|
280
336
|
// src/doctor/checks.ts
|
|
281
337
|
import { join as join3 } from "path";
|
|
338
|
+
import { homedir } from "os";
|
|
282
339
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
283
340
|
import { execSync } from "child_process";
|
|
284
341
|
function execCommand(cmd) {
|
|
@@ -332,16 +389,16 @@ function checkApiKeys() {
|
|
|
332
389
|
return { name: "API Keys", status: "pass", message: `Configured: ${found.join(", ")}` };
|
|
333
390
|
}
|
|
334
391
|
function checkAuthFile() {
|
|
335
|
-
const authPath = join3(
|
|
336
|
-
const expandedPath = authPath.replace("~",
|
|
392
|
+
const authPath = join3(homedir(), ".local/share/opencode/auth.json");
|
|
393
|
+
const expandedPath = authPath.replace("~", homedir());
|
|
337
394
|
if (existsSync3(expandedPath)) {
|
|
338
395
|
return { name: "Auth File", status: "pass", message: "auth.json exists" };
|
|
339
396
|
}
|
|
340
397
|
return { name: "Auth File", status: "warn", message: "auth.json not found", fix: "Run /connect in OpenCode to authenticate with providers" };
|
|
341
398
|
}
|
|
342
399
|
function checkConfig() {
|
|
343
|
-
const configPath = join3(
|
|
344
|
-
const expandedPath = configPath.replace("~",
|
|
400
|
+
const configPath = join3(homedir(), ".config/opencode/opencode.json");
|
|
401
|
+
const expandedPath = configPath.replace("~", homedir());
|
|
345
402
|
if (!existsSync3(expandedPath)) {
|
|
346
403
|
return { name: "Global Config", status: "warn", message: "Global opencode.json not found", fix: "Run 'opencode-setup init' or configure OpenCode manually" };
|
|
347
404
|
}
|
|
@@ -388,8 +445,8 @@ function checkLSP() {
|
|
|
388
445
|
return { name: "LSP", status: "warn", message: "No LSP servers found", fix: "Install LSP servers: typescript-language-server, gopls, rust-analyzer, or pyright" };
|
|
389
446
|
}
|
|
390
447
|
function checkPlugins() {
|
|
391
|
-
const configPath = join3(
|
|
392
|
-
const expandedPath = configPath.replace("~",
|
|
448
|
+
const configPath = join3(homedir(), ".config/opencode/opencode.json");
|
|
449
|
+
const expandedPath = configPath.replace("~", homedir());
|
|
393
450
|
if (!existsSync3(expandedPath)) {
|
|
394
451
|
return { name: "Plugins", status: "warn", message: "Cannot check plugins - no global config" };
|
|
395
452
|
}
|
|
@@ -474,7 +531,8 @@ function copyDirectory(src, dest) {
|
|
|
474
531
|
try {
|
|
475
532
|
cpSync2(srcPath, destPath);
|
|
476
533
|
copied.push(destPath);
|
|
477
|
-
} catch {
|
|
534
|
+
} catch (err) {
|
|
535
|
+
console.warn(`Failed to copy ${srcPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
478
536
|
}
|
|
479
537
|
}
|
|
480
538
|
}
|
|
@@ -557,12 +615,16 @@ function migrateClaudeCode(rootPath) {
|
|
|
557
615
|
}
|
|
558
616
|
const settings = readFileSafe(join5(rootPath, ".claude", "settings.json"));
|
|
559
617
|
if (settings) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
618
|
+
try {
|
|
619
|
+
const parsed = JSON.parse(settings);
|
|
620
|
+
if (parsed.model) {
|
|
621
|
+
suggestions.push(`\uBAA8\uB378 \uC124\uC815 \uAC10\uC9C0\uB428: ${parsed.model} - opencode.json\uC5D0 \uC218\uB3D9\uC73C\uB85C \uCD94\uAC00 \uD544\uC694`);
|
|
622
|
+
}
|
|
623
|
+
if (parsed["dangerously-skip-permissions"]) {
|
|
624
|
+
warnings.push("dangerously-skip-permissions\uB294 OpenCode\uC5D0\uC11C \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
625
|
+
}
|
|
626
|
+
} catch {
|
|
627
|
+
warnings.push(".claude/settings.json \uD30C\uC2F1 \uC2E4\uD328 - \uC124\uC815\uC774 \uC190\uC0C1\uB418\uC5C8\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
566
628
|
}
|
|
567
629
|
}
|
|
568
630
|
const omccPath = join5(rootPath, ".claude", "hooks", "oh-my-claude-code");
|
|
@@ -580,6 +642,7 @@ function migrateClaudeCode(rootPath) {
|
|
|
580
642
|
const settingsObj = JSON.parse(settingsData);
|
|
581
643
|
if (settingsObj.model) opencodeConfig.model = settingsObj.model;
|
|
582
644
|
} catch {
|
|
645
|
+
warnings.push(".claude/settings.json \uD30C\uC2F1 \uC2E4\uD328 - \uC124\uC815\uC774 \uC190\uC0C1\uB418\uC5C8\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
583
646
|
}
|
|
584
647
|
}
|
|
585
648
|
const configPath = join5(rootPath, "opencode.json");
|
|
@@ -610,6 +673,7 @@ function migrateCursor(rootPath) {
|
|
|
610
673
|
suggestions.push("MCP \uC11C\uBC84 \uC124\uC815 \uAC10\uC9C0\uB428 - opencode.json\uC758 mcp \uC139\uC158\uC5D0 \uCD94\uAC00 \uD544\uC694");
|
|
611
674
|
}
|
|
612
675
|
} catch {
|
|
676
|
+
warnings.push("MCP \uC124\uC815 \uD30C\uC2F1 \uC2E4\uD328 - JSON \uD615\uC2DD \uC624\uB958");
|
|
613
677
|
}
|
|
614
678
|
}
|
|
615
679
|
const cursorSettings = readFileSafe(join6(rootPath, ".cursor", "settings.json"));
|
|
@@ -718,8 +782,17 @@ function autoMigrate(rootPath) {
|
|
|
718
782
|
}
|
|
719
783
|
|
|
720
784
|
// src/core/config-generator.ts
|
|
721
|
-
import { mkdirSync as mkdirSync3, existsSync as existsSync6, writeFileSync as writeFileSync3, cpSync as cpSync3 } from "fs";
|
|
785
|
+
import { mkdirSync as mkdirSync3, existsSync as existsSync6, writeFileSync as writeFileSync3, cpSync as cpSync3, renameSync } from "fs";
|
|
722
786
|
import { join as join8, dirname as dirname3 } from "path";
|
|
787
|
+
function atomicWrite(filePath, content) {
|
|
788
|
+
const dir = dirname3(filePath);
|
|
789
|
+
if (!existsSync6(dir)) {
|
|
790
|
+
mkdirSync3(dir, { recursive: true });
|
|
791
|
+
}
|
|
792
|
+
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
793
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
794
|
+
renameSync(tempPath, filePath);
|
|
795
|
+
}
|
|
723
796
|
var PROVIDER_API_KEYS = {
|
|
724
797
|
anthropic: "ANTHROPIC_API_KEY",
|
|
725
798
|
google: "GEMINI_API_KEY",
|
|
@@ -822,7 +895,7 @@ function generateProjectConfig(profile) {
|
|
|
822
895
|
}
|
|
823
896
|
function backupFile2(path) {
|
|
824
897
|
if (existsSync6(path)) {
|
|
825
|
-
const backupPath = `${path}.bak`;
|
|
898
|
+
const backupPath = `${path}.bak.${Date.now()}`;
|
|
826
899
|
cpSync3(path, backupPath);
|
|
827
900
|
}
|
|
828
901
|
}
|
|
@@ -833,7 +906,7 @@ function writeConfig(config, filePath) {
|
|
|
833
906
|
}
|
|
834
907
|
backupFile2(filePath);
|
|
835
908
|
const content = JSON.stringify(config, null, 2) + "\n";
|
|
836
|
-
|
|
909
|
+
atomicWrite(filePath, content);
|
|
837
910
|
}
|
|
838
911
|
function writeGlobalConfig(profile, homeDir) {
|
|
839
912
|
const config = generateGlobalConfig(profile);
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli.js
CHANGED
|
@@ -19,13 +19,14 @@ import {
|
|
|
19
19
|
writeGlobalConfig,
|
|
20
20
|
writeProjectConfig,
|
|
21
21
|
writeSkills
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-FTV7ABVP.js";
|
|
23
23
|
|
|
24
24
|
// src/cli.ts
|
|
25
25
|
import { Command } from "commander";
|
|
26
26
|
|
|
27
27
|
// src/prompt/wizard.ts
|
|
28
28
|
import { homedir } from "os";
|
|
29
|
+
import { join as join2 } from "path";
|
|
29
30
|
|
|
30
31
|
// src/prompt/questions.ts
|
|
31
32
|
import { select, checkbox, input, confirm } from "@inquirer/prompts";
|
|
@@ -198,6 +199,137 @@ async function askConfirmGeneration(files) {
|
|
|
198
199
|
});
|
|
199
200
|
return answer;
|
|
200
201
|
}
|
|
202
|
+
async function askOMO(budget, plugins) {
|
|
203
|
+
const hasOMOPlugin = plugins.includes("oh-my-opencode");
|
|
204
|
+
if (hasOMOPlugin) {
|
|
205
|
+
const enableOMO = await confirm({
|
|
206
|
+
message: "oh-my-opencode \uD50C\uB7EC\uADF8\uC778\uC744 \uC120\uD0DD\uD558\uC168\uC2B5\uB2C8\uB2E4. OMO \uC5D0\uC774\uC804\uD2B8 \uC124\uC815\uC744 \uD65C\uC131\uD654\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
207
|
+
default: true
|
|
208
|
+
});
|
|
209
|
+
if (!enableOMO) {
|
|
210
|
+
return { enabled: false };
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
const enableOMO = await confirm({
|
|
214
|
+
message: "oh-my-opencode (\uBA40\uD2F0 \uC5D0\uC774\uC804\uD2B8 \uC624\uCF00\uC2A4\uD2B8\uB808\uC774\uC158)\uB97C \uC0AC\uC6A9\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
215
|
+
default: false
|
|
216
|
+
});
|
|
217
|
+
if (!enableOMO) {
|
|
218
|
+
return { enabled: false };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
console.log("\n\u{1F916} OMO \uC5D0\uC774\uC804\uD2B8 \uC124\uC815");
|
|
222
|
+
console.log(" \uC608\uC0B0\uC5D0 \uB530\uB77C \uCD5C\uC801\uC758 \uC5D0\uC774\uC804\uD2B8 \uBAA8\uB378 \uC870\uD569\uC744 \uCD94\uCC9C\uD569\uB2C8\uB2E4.\n");
|
|
223
|
+
const omoConfig = generateOMOConfigByBudget(budget);
|
|
224
|
+
return {
|
|
225
|
+
enabled: true,
|
|
226
|
+
config: omoConfig
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function generateOMOConfigByBudget(budget) {
|
|
230
|
+
switch (budget) {
|
|
231
|
+
case "free":
|
|
232
|
+
case "low":
|
|
233
|
+
return {
|
|
234
|
+
agents: {
|
|
235
|
+
sisyphus: { model: "opencode-go/kimi-k2.5" },
|
|
236
|
+
prometheus: { model: "opencode-go/glm-5" },
|
|
237
|
+
atlas: { model: "opencode-go/kimi-k2.5" },
|
|
238
|
+
explore: { model: "opencode-go/minimax-m2.7" },
|
|
239
|
+
librarian: { model: "opencode-go/minimax-m2.5" },
|
|
240
|
+
"multimodal-looker": { model: "opencode-go/kimi-k2.5" },
|
|
241
|
+
"frontend-ui-ux-engineer": { model: "opencode-go/gemini-2.5-pro", variant: "low" },
|
|
242
|
+
"document-writer": { model: "opencode-go/gemini-2.5-pro", variant: "low" }
|
|
243
|
+
},
|
|
244
|
+
categories: {
|
|
245
|
+
explore: { model: "opencode-go/minimax-m2.7" },
|
|
246
|
+
quick: { model: "opencode-go/minimax-m2.7" },
|
|
247
|
+
deep: { model: "opencode-go/glm-5.1" },
|
|
248
|
+
"unspecified-low": { model: "opencode-go/kimi-k2.5" },
|
|
249
|
+
"unspecified-high": { model: "opencode-go/glm-5.1" },
|
|
250
|
+
ultrabrain: { model: "opencode-go/glm-5.1", variant: "high" },
|
|
251
|
+
oracle: { model: "opencode-go/glm-5.1", variant: "high" }
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
case "mid":
|
|
255
|
+
return {
|
|
256
|
+
agents: {
|
|
257
|
+
sisyphus: { model: "anthropic/claude-opus-4-5" },
|
|
258
|
+
hephaestus: { model: "openai/gpt-5.4", variant: "medium" },
|
|
259
|
+
prometheus: { model: "openai/gpt-5.4" },
|
|
260
|
+
atlas: { model: "kimi-for-coding/k2p5" },
|
|
261
|
+
explore: { model: "opencode-go/minimax-m2.7" },
|
|
262
|
+
librarian: { model: "opencode-go/minimax-m2.5" },
|
|
263
|
+
"multimodal-looker": { model: "opencode-go/kimi-k2.5" },
|
|
264
|
+
"frontend-ui-ux-engineer": { model: "google/antigravity-gemini-3-pro", variant: "low" },
|
|
265
|
+
"document-writer": { model: "google/antigravity-gemini-3-pro", variant: "low" }
|
|
266
|
+
},
|
|
267
|
+
categories: {
|
|
268
|
+
explore: { model: "opencode-go/minimax-m2.7" },
|
|
269
|
+
quick: { model: "opencode-go/minimax-m2.7" },
|
|
270
|
+
deep: { model: "openai/gpt-5.3-codex", variant: "high" },
|
|
271
|
+
"unspecified-low": { model: "anthropic/claude-sonnet-4-6" },
|
|
272
|
+
"unspecified-high": { model: "anthropic/claude-opus-4-6" },
|
|
273
|
+
ultrabrain: { model: "openai/gpt-5.4", variant: "xhigh" },
|
|
274
|
+
oracle: { model: "openai/gpt-5.4", variant: "xhigh" }
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
case "high":
|
|
278
|
+
default:
|
|
279
|
+
return {
|
|
280
|
+
agents: {
|
|
281
|
+
sisyphus: { model: "anthropic/claude-opus-4-6" },
|
|
282
|
+
hephaestus: { model: "openai/gpt-5.4", variant: "medium" },
|
|
283
|
+
prometheus: { model: "openai/gpt-5.4" },
|
|
284
|
+
atlas: { model: "anthropic/claude-sonnet-4-5" },
|
|
285
|
+
explore: { model: "kimi-for-coding/k2p5" },
|
|
286
|
+
librarian: { model: "google/gemini-2.5-flash" },
|
|
287
|
+
"multimodal-looker": { model: "opencode-go/kimi-k2.5" },
|
|
288
|
+
"frontend-ui-ux-engineer": { model: "google/antigravity-gemini-3-pro", variant: "low" },
|
|
289
|
+
"document-writer": { model: "google/antigravity-gemini-3-pro", variant: "low" }
|
|
290
|
+
},
|
|
291
|
+
categories: {
|
|
292
|
+
explore: { model: "venice/minimax-m2.7" },
|
|
293
|
+
quick: { model: "venice/minimax-m2.7" },
|
|
294
|
+
deep: { model: "openai/gpt-5.3-codex", variant: "high" },
|
|
295
|
+
"unspecified-low": { model: "anthropic/claude-sonnet-4-6" },
|
|
296
|
+
"unspecified-high": { model: "anthropic/claude-opus-4-6" },
|
|
297
|
+
ultrabrain: { model: "openai/gpt-5.4", variant: "xhigh" },
|
|
298
|
+
oracle: { model: "openai/gpt-5.4", variant: "xhigh" }
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/core/omo-generator.ts
|
|
305
|
+
import { mkdirSync, existsSync, writeFileSync } from "fs";
|
|
306
|
+
import { join, dirname } from "path";
|
|
307
|
+
function getOMOConfigPath(homeDir) {
|
|
308
|
+
return join(homeDir, ".config/opencode/oh-my-opencode.json");
|
|
309
|
+
}
|
|
310
|
+
function serializeOMOConfig(config) {
|
|
311
|
+
const toKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
312
|
+
const transformRecord = (record) => Object.fromEntries(
|
|
313
|
+
Object.entries(record).filter(([, value]) => value !== void 0).map(([key, value]) => [toKebabCase(key), value])
|
|
314
|
+
);
|
|
315
|
+
const transformed = {
|
|
316
|
+
agents: transformRecord(config.agents),
|
|
317
|
+
categories: transformRecord(config.categories)
|
|
318
|
+
};
|
|
319
|
+
return JSON.stringify(transformed, null, 2) + "\n";
|
|
320
|
+
}
|
|
321
|
+
function writeOMOConfig(omoProfile, homeDir) {
|
|
322
|
+
if (!omoProfile?.enabled || !omoProfile.config) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const configPath = getOMOConfigPath(homeDir);
|
|
326
|
+
const configDir = dirname(configPath);
|
|
327
|
+
if (!existsSync(configDir)) {
|
|
328
|
+
mkdirSync(configDir, { recursive: true });
|
|
329
|
+
}
|
|
330
|
+
const content = serializeOMOConfig(omoProfile.config);
|
|
331
|
+
writeFileSync(configPath, content, "utf-8");
|
|
332
|
+
}
|
|
201
333
|
|
|
202
334
|
// src/prompt/wizard.ts
|
|
203
335
|
function getProjectDir() {
|
|
@@ -230,6 +362,8 @@ async function runInitWizard() {
|
|
|
230
362
|
const mcpServers = await askMCPServers();
|
|
231
363
|
console.log("\n\u{1F527} \uD50C\uB7EC\uADF8\uC778");
|
|
232
364
|
const plugins = await askPlugins();
|
|
365
|
+
console.log("\n\u{1F916} oh-my-opencode (OMO) \uC124\uC815");
|
|
366
|
+
const omo = await askOMO(budget, plugins);
|
|
233
367
|
console.log("\n\u{1F512} \uAD8C\uD55C \uC124\uC815");
|
|
234
368
|
const permissionLevel = await askPermissionLevel();
|
|
235
369
|
const profile = {
|
|
@@ -244,18 +378,20 @@ async function runInitWizard() {
|
|
|
244
378
|
projectScale,
|
|
245
379
|
mcpServers,
|
|
246
380
|
plugins,
|
|
247
|
-
permissionLevel
|
|
381
|
+
permissionLevel,
|
|
382
|
+
omo
|
|
248
383
|
};
|
|
249
384
|
const projectDir = getProjectDir();
|
|
250
385
|
const homeDir = getHomeDir();
|
|
251
386
|
const filesToCreate = [
|
|
252
|
-
`${homeDir
|
|
387
|
+
`${join2(homeDir, ".config/opencode/opencode.json")} (\uAE00\uB85C\uBC8C \uC124\uC815)`,
|
|
253
388
|
`${projectDir}/opencode.json (\uD504\uB85C\uC81D\uD2B8 \uC124\uC815)`,
|
|
254
389
|
`${projectDir}/AGENTS.md (\uD504\uB85C\uC81D\uD2B8 \uAC00\uC774\uB4DC)`,
|
|
255
390
|
`${projectDir}/.opencode/commands/ (\uCEE4\uC2A4\uD140 \uCEE4\uB9E8\uB4DC)`,
|
|
256
391
|
`${projectDir}/.opencode/agents/ (\uCEE4\uC2A4\uD140 \uC5D0\uC774\uC804\uD2B8)`,
|
|
257
392
|
`${projectDir}/.opencode/skills/ (\uC2A4\uD0AC)`,
|
|
258
|
-
`${projectDir}/.env.example (\uD658\uACBD\uBCC0\uC218 \uD15C\uD50C\uB9BF)
|
|
393
|
+
`${projectDir}/.env.example (\uD658\uACBD\uBCC0\uC218 \uD15C\uD50C\uB9BF)`,
|
|
394
|
+
...omo?.enabled ? [`${join2(homeDir, ".config/opencode/oh-my-opencode.json")} (OMO \uC124\uC815)`] : []
|
|
259
395
|
];
|
|
260
396
|
const confirmed = await askConfirmGeneration(filesToCreate);
|
|
261
397
|
if (!confirmed) {
|
|
@@ -283,6 +419,10 @@ async function runInitWizard() {
|
|
|
283
419
|
const envContent = generateEnvExample(profile);
|
|
284
420
|
writeEnvExample(envContent, projectDir);
|
|
285
421
|
console.log(" \u2713 .env.example \uC0DD\uC131\uB428");
|
|
422
|
+
if (omo?.enabled) {
|
|
423
|
+
writeOMOConfig(omo, homeDir);
|
|
424
|
+
console.log(" \u2713 oh-my-opencode \uC124\uC815 \uC0DD\uC131\uB428");
|
|
425
|
+
}
|
|
286
426
|
console.log("\n\u2705 \uC0DD\uC131 \uC644\uB8CC!\n");
|
|
287
427
|
console.log("\uB2E4\uC74C \uB2E8\uACC4:");
|
|
288
428
|
console.log("1. .env.example\uC744 .env\uB85C \uBCF5\uC0AC\uD558\uACE0 API \uD0A4\uB97C \uC124\uC815\uD558\uC138\uC694");
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UserProfile, OpenCodeConfig } from "../types";
|
|
2
|
+
export declare function generateGlobalConfig(profile: UserProfile): OpenCodeConfig;
|
|
3
|
+
export declare function generateProjectConfig(profile: UserProfile): OpenCodeConfig;
|
|
4
|
+
export declare function writeConfig(config: OpenCodeConfig, filePath: string): void;
|
|
5
|
+
export declare function writeGlobalConfig(profile: UserProfile, homeDir: string): void;
|
|
6
|
+
export declare function writeProjectConfig(profile: UserProfile, projectDir: string): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OMOConfig, OMOProfile } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* OMO 설정 파일 경로
|
|
4
|
+
*/
|
|
5
|
+
export declare function getOMOConfigPath(homeDir: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* OMO 설정을 JSON으로 직렬화
|
|
8
|
+
*/
|
|
9
|
+
export declare function serializeOMOConfig(config: OMOConfig): string;
|
|
10
|
+
/**
|
|
11
|
+
* OMO 설정 파일 생성
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeOMOConfig(omoProfile: OMOProfile | undefined, homeDir: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* OMO 설정 유효성 검사
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateOMOConfig(config: OMOConfig): {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
errors: string[];
|
|
20
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -18,11 +18,12 @@ import {
|
|
|
18
18
|
writeGlobalConfig,
|
|
19
19
|
writeProjectConfig,
|
|
20
20
|
writeSkills
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-FTV7ABVP.js";
|
|
22
22
|
|
|
23
23
|
// src/tools/setup-init.ts
|
|
24
24
|
import { tool } from "@opencode-ai/plugin";
|
|
25
25
|
import { homedir } from "os";
|
|
26
|
+
import { join } from "path";
|
|
26
27
|
var { schema } = tool;
|
|
27
28
|
var setupInit = tool({
|
|
28
29
|
description: "Initialize OpenCode environment with custom profile. Accepts a UserProfile JSON string.",
|
|
@@ -41,24 +42,24 @@ var setupInit = tool({
|
|
|
41
42
|
const generatedFiles = [];
|
|
42
43
|
try {
|
|
43
44
|
writeGlobalConfig(profile, homeDir);
|
|
44
|
-
generatedFiles.push(
|
|
45
|
+
generatedFiles.push(join(homeDir, ".config/opencode/opencode.json"));
|
|
45
46
|
writeProjectConfig(profile, projectDir);
|
|
46
|
-
generatedFiles.push(
|
|
47
|
+
generatedFiles.push(join(projectDir, "opencode.json"));
|
|
47
48
|
const agentsMD = generateAgentsMD(profile);
|
|
48
49
|
writeAgentsMD(agentsMD, projectDir);
|
|
49
|
-
generatedFiles.push(
|
|
50
|
+
generatedFiles.push(join(projectDir, "AGENTS.md"));
|
|
50
51
|
const commands = generateCommands();
|
|
51
52
|
writeCommands(commands, projectDir);
|
|
52
|
-
generatedFiles.push(
|
|
53
|
+
generatedFiles.push(join(projectDir, ".opencode/commands/"));
|
|
53
54
|
const agents = generateAgents();
|
|
54
55
|
writeAgents(agents, projectDir);
|
|
55
|
-
generatedFiles.push(
|
|
56
|
+
generatedFiles.push(join(projectDir, ".opencode/agents/"));
|
|
56
57
|
const skills = generateSkills(profile);
|
|
57
58
|
writeSkills(skills, projectDir);
|
|
58
|
-
generatedFiles.push(
|
|
59
|
+
generatedFiles.push(join(projectDir, ".opencode/skills/"));
|
|
59
60
|
const envContent = generateEnvExample(profile);
|
|
60
61
|
writeEnvExample(envContent, projectDir);
|
|
61
|
-
generatedFiles.push(
|
|
62
|
+
generatedFiles.push(join(projectDir, ".env.example"));
|
|
62
63
|
const filesList = generatedFiles.map((f) => ` \u2022 ${f}`).join("\n");
|
|
63
64
|
return `\u2705 OpenCode environment initialized successfully!
|
|
64
65
|
|
|
@@ -95,20 +96,26 @@ var setupPresetApply = tool2({
|
|
|
95
96
|
name: schema2.string().describe("Preset name (e.g., 'budget', 'balanced', 'frontend-ts', 'backend-go')")
|
|
96
97
|
},
|
|
97
98
|
async execute(args, context) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
try {
|
|
100
|
+
const result = await applyPreset(args.name, context.directory);
|
|
101
|
+
if (!result.success) {
|
|
102
|
+
return `\u274C Failed to apply preset '${args.name}'.
|
|
101
103
|
|
|
102
104
|
${result.warnings.join("\n")}`;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
}
|
|
106
|
+
const filesList = result.files.map((f) => ` \u2022 ${f}`).join("\n");
|
|
107
|
+
return `\u2705 Preset '${args.name}' applied successfully!
|
|
106
108
|
|
|
107
109
|
Generated files:
|
|
108
110
|
${filesList}${result.warnings.length > 0 ? `
|
|
109
111
|
|
|
110
112
|
Warnings:
|
|
111
113
|
${result.warnings.join("\n")}` : ""}`;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return `\u274C Failed to apply preset '${args.name}'.
|
|
116
|
+
|
|
117
|
+
Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
118
|
+
}
|
|
112
119
|
}
|
|
113
120
|
});
|
|
114
121
|
|
|
@@ -123,10 +130,15 @@ var setupMigrate = tool3({
|
|
|
123
130
|
},
|
|
124
131
|
async execute(args, context) {
|
|
125
132
|
const rootPath = args.sourcePath || context.directory;
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
try {
|
|
134
|
+
if (!args.tool) {
|
|
135
|
+
return autoMigrate(rootPath);
|
|
136
|
+
}
|
|
137
|
+
return runMigration(args.tool, rootPath);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
+
return `Migration failed: ${message}`;
|
|
128
141
|
}
|
|
129
|
-
return runMigration(args.tool, rootPath);
|
|
130
142
|
}
|
|
131
143
|
});
|
|
132
144
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateAider(rootPath: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateClaudeCode(rootPath: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function readFileSafe(filePath: string): string | null;
|
|
2
|
+
export declare function writeFileSafe(filePath: string, content: string): void;
|
|
3
|
+
export declare function backupFile(filePath: string): void;
|
|
4
|
+
export declare function copyDirectory(src: string, dest: string): string[];
|
|
5
|
+
export declare function detectTool(rootPath: string): string | null;
|
|
6
|
+
export declare function parseJSON<T = unknown>(content: string): T | null;
|
|
7
|
+
export declare function parseYAML(content: string): Record<string, unknown>;
|
|
8
|
+
export declare function formatMigrationResult(toolName: string, files: string[], warnings: string[], suggestions: string[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateCursor(rootPath: string): string;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset Registry
|
|
3
|
+
* Manages model presets and stack presets
|
|
4
|
+
*/
|
|
5
|
+
export interface ModelPreset {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
monthlyCost: string;
|
|
9
|
+
config: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface StackPreset {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
modelPreset: string;
|
|
15
|
+
includes: {
|
|
16
|
+
agentsMD: string;
|
|
17
|
+
commands: string[];
|
|
18
|
+
agents: string[];
|
|
19
|
+
skills: string[];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface OMOPreset {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
configPath: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ApplyResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
files: string[];
|
|
30
|
+
warnings: string[];
|
|
31
|
+
}
|
|
32
|
+
export declare const MODEL_PRESETS: ModelPreset[];
|
|
33
|
+
export declare const STACK_PRESETS: StackPreset[];
|
|
34
|
+
export declare const OMO_PRESETS: OMOPreset[];
|
|
35
|
+
/**
|
|
36
|
+
* List all presets (model + stack + omo) in table format
|
|
37
|
+
*/
|
|
38
|
+
export declare function listPresets(): string;
|
|
39
|
+
/**
|
|
40
|
+
* Get model preset by name
|
|
41
|
+
*/
|
|
42
|
+
export declare function getModelPreset(name: string): ModelPreset | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Get stack preset by name
|
|
45
|
+
*/
|
|
46
|
+
export declare function getStackPreset(name: string): StackPreset | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Get OMO preset by name
|
|
49
|
+
*/
|
|
50
|
+
export declare function getOMOPreset(name: string): OMOPreset | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Apply a preset to the project directory
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyPreset(name: string, projectDir: string, options?: {
|
|
55
|
+
projectName?: string;
|
|
56
|
+
testRunner?: string;
|
|
57
|
+
linter?: string;
|
|
58
|
+
}): Promise<ApplyResult>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ExperienceLevel, PreviousTool, BudgetTier, ProjectScale, PermissionLevel, MCPServerChoice, OMOProfile } from "../types";
|
|
2
|
+
export declare function askExperience(): Promise<ExperienceLevel>;
|
|
3
|
+
export declare function askPreviousTool(): Promise<PreviousTool>;
|
|
4
|
+
export declare function askProviders(): Promise<string[]>;
|
|
5
|
+
export declare function askBudget(): Promise<BudgetTier>;
|
|
6
|
+
export declare function askProjectLanguage(): Promise<string>;
|
|
7
|
+
export declare function askProjectFramework(): Promise<string>;
|
|
8
|
+
export declare function askTestRunner(): Promise<string>;
|
|
9
|
+
export declare function askLinter(): Promise<string>;
|
|
10
|
+
export declare function askProjectScale(): Promise<ProjectScale>;
|
|
11
|
+
export declare function askMCPServers(): Promise<MCPServerChoice[]>;
|
|
12
|
+
export declare function askPlugins(): Promise<string[]>;
|
|
13
|
+
export declare function askPermissionLevel(): Promise<PermissionLevel>;
|
|
14
|
+
export declare function askConfirmGeneration(files: string[]): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* OMO (oh-my-opencode) 사용 여부 및 설정 선택
|
|
17
|
+
*/
|
|
18
|
+
export declare function askOMO(budget: BudgetTier, plugins: string[]): Promise<OMOProfile>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runInitWizard(): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agents": {
|
|
3
|
+
"sisyphus": {
|
|
4
|
+
"model": "opencode-go/kimi-k2.5"
|
|
5
|
+
},
|
|
6
|
+
"prometheus": {
|
|
7
|
+
"model": "opencode-go/glm-5"
|
|
8
|
+
},
|
|
9
|
+
"atlas": {
|
|
10
|
+
"model": "opencode-go/kimi-k2.5"
|
|
11
|
+
},
|
|
12
|
+
"explore": {
|
|
13
|
+
"model": "opencode-go/minimax-m2.7"
|
|
14
|
+
},
|
|
15
|
+
"librarian": {
|
|
16
|
+
"model": "opencode-go/minimax-m2.5"
|
|
17
|
+
},
|
|
18
|
+
"multimodal-looker": {
|
|
19
|
+
"model": "opencode-go/kimi-k2.5"
|
|
20
|
+
},
|
|
21
|
+
"frontend-ui-ux-engineer": {
|
|
22
|
+
"model": "opencode-go/gemini-2.5-pro",
|
|
23
|
+
"variant": "low"
|
|
24
|
+
},
|
|
25
|
+
"document-writer": {
|
|
26
|
+
"model": "opencode-go/gemini-2.5-pro",
|
|
27
|
+
"variant": "low"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"categories": {
|
|
31
|
+
"explore": {
|
|
32
|
+
"model": "opencode-go/minimax-m2.7"
|
|
33
|
+
},
|
|
34
|
+
"quick": {
|
|
35
|
+
"model": "opencode-go/minimax-m2.7"
|
|
36
|
+
},
|
|
37
|
+
"deep": {
|
|
38
|
+
"model": "opencode-go/glm-5.1"
|
|
39
|
+
},
|
|
40
|
+
"unspecified-low": {
|
|
41
|
+
"model": "opencode-go/kimi-k2.5"
|
|
42
|
+
},
|
|
43
|
+
"unspecified-high": {
|
|
44
|
+
"model": "opencode-go/glm-5.1"
|
|
45
|
+
},
|
|
46
|
+
"ultrabrain": {
|
|
47
|
+
"model": "opencode-go/glm-5.1",
|
|
48
|
+
"variant": "high"
|
|
49
|
+
},
|
|
50
|
+
"oracle": {
|
|
51
|
+
"model": "opencode-go/glm-5.1",
|
|
52
|
+
"variant": "high"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agents": {
|
|
3
|
+
"sisyphus": {
|
|
4
|
+
"model": "anthropic/claude-opus-4-6"
|
|
5
|
+
},
|
|
6
|
+
"hephaestus": {
|
|
7
|
+
"model": "openai/gpt-5.4",
|
|
8
|
+
"variant": "medium"
|
|
9
|
+
},
|
|
10
|
+
"prometheus": {
|
|
11
|
+
"model": "openai/gpt-5.4"
|
|
12
|
+
},
|
|
13
|
+
"atlas": {
|
|
14
|
+
"model": "anthropic/claude-sonnet-4-5"
|
|
15
|
+
},
|
|
16
|
+
"explore": {
|
|
17
|
+
"model": "kimi-for-coding/k2p5"
|
|
18
|
+
},
|
|
19
|
+
"librarian": {
|
|
20
|
+
"model": "google/gemini-2.5-flash"
|
|
21
|
+
},
|
|
22
|
+
"multimodal-looker": {
|
|
23
|
+
"model": "opencode-go/kimi-k2.5"
|
|
24
|
+
},
|
|
25
|
+
"frontend-ui-ux-engineer": {
|
|
26
|
+
"model": "google/antigravity-gemini-3-pro",
|
|
27
|
+
"variant": "low"
|
|
28
|
+
},
|
|
29
|
+
"document-writer": {
|
|
30
|
+
"model": "google/antigravity-gemini-3-pro",
|
|
31
|
+
"variant": "low"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"categories": {
|
|
35
|
+
"explore": {
|
|
36
|
+
"model": "venice/minimax-m2.7"
|
|
37
|
+
},
|
|
38
|
+
"quick": {
|
|
39
|
+
"model": "venice/minimax-m2.7"
|
|
40
|
+
},
|
|
41
|
+
"deep": {
|
|
42
|
+
"model": "openai/gpt-5.3-codex",
|
|
43
|
+
"variant": "high"
|
|
44
|
+
},
|
|
45
|
+
"unspecified-low": {
|
|
46
|
+
"model": "anthropic/claude-sonnet-4-6"
|
|
47
|
+
},
|
|
48
|
+
"unspecified-high": {
|
|
49
|
+
"model": "anthropic/claude-opus-4-6"
|
|
50
|
+
},
|
|
51
|
+
"ultrabrain": {
|
|
52
|
+
"model": "openai/gpt-5.4",
|
|
53
|
+
"variant": "xhigh"
|
|
54
|
+
},
|
|
55
|
+
"oracle": {
|
|
56
|
+
"model": "openai/gpt-5.4",
|
|
57
|
+
"variant": "xhigh"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
export declare const setupPresetList: {
|
|
3
|
+
description: string;
|
|
4
|
+
args: {};
|
|
5
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
6
|
+
};
|
|
7
|
+
export declare const setupPresetApply: ReturnType<typeof tool>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PreviousTool } from "./user-profile";
|
|
2
|
+
import type { OpenCodeConfig } from "./opencode-config";
|
|
3
|
+
export interface MigrationSource {
|
|
4
|
+
tool: PreviousTool;
|
|
5
|
+
rootPath: string;
|
|
6
|
+
claudeMD?: string;
|
|
7
|
+
skills?: string[];
|
|
8
|
+
hooks?: string[];
|
|
9
|
+
rules?: string[];
|
|
10
|
+
mcpConfig?: string;
|
|
11
|
+
hasOMCC?: boolean;
|
|
12
|
+
cursorRules?: string;
|
|
13
|
+
aiderConfig?: string;
|
|
14
|
+
conventions?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MigrationResult {
|
|
17
|
+
agentsMD: string;
|
|
18
|
+
config: OpenCodeConfig;
|
|
19
|
+
copiedSkills: string[];
|
|
20
|
+
customAgents: Record<string, string>;
|
|
21
|
+
customCommands: Record<string, string>;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
pluginSuggestions: string[];
|
|
24
|
+
envVars: Record<string, string>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface OpenCodeConfig {
|
|
2
|
+
$schema: string;
|
|
3
|
+
model?: string;
|
|
4
|
+
provider?: Record<string, ProviderConfig>;
|
|
5
|
+
permission?: PermissionConfig;
|
|
6
|
+
agent?: Record<string, AgentConfig>;
|
|
7
|
+
default_agent?: string;
|
|
8
|
+
command?: Record<string, CommandConfig>;
|
|
9
|
+
mcp?: Record<string, MCPConfig>;
|
|
10
|
+
lsp?: Record<string, LSPConfig>;
|
|
11
|
+
plugin?: string[];
|
|
12
|
+
instructions?: string[];
|
|
13
|
+
theme?: string;
|
|
14
|
+
autoupdate?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ProviderConfig {
|
|
17
|
+
options?: {
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
baseURL?: string;
|
|
20
|
+
};
|
|
21
|
+
models?: Record<string, {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export interface AgentConfig {
|
|
27
|
+
description?: string;
|
|
28
|
+
model?: string;
|
|
29
|
+
prompt?: string;
|
|
30
|
+
temperature?: number;
|
|
31
|
+
reasoningEffort?: "low" | "medium" | "high";
|
|
32
|
+
}
|
|
33
|
+
export interface PermissionConfig {
|
|
34
|
+
edit?: "allow" | "ask" | "deny";
|
|
35
|
+
bash?: Record<string, "allow" | "ask" | "deny">;
|
|
36
|
+
webfetch?: "allow" | "ask" | "deny";
|
|
37
|
+
}
|
|
38
|
+
export interface MCPConfig {
|
|
39
|
+
type: "sse" | "stdio";
|
|
40
|
+
url?: string;
|
|
41
|
+
command?: string;
|
|
42
|
+
args?: string[];
|
|
43
|
+
env?: Record<string, string>;
|
|
44
|
+
}
|
|
45
|
+
export interface LSPConfig {
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
command: string;
|
|
48
|
+
args?: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface CommandConfig {
|
|
51
|
+
template: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
agent?: string;
|
|
54
|
+
model?: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { MigrationSource } from "./migration";
|
|
2
|
+
export type ExperienceLevel = "new" | "beginner" | "intermediate" | "advanced";
|
|
3
|
+
export type PreviousTool = "none" | "claude-code" | "cursor" | "aider" | "other";
|
|
4
|
+
export type BudgetTier = "free" | "low" | "mid" | "high";
|
|
5
|
+
export type PermissionLevel = "safe" | "balanced" | "auto";
|
|
6
|
+
export type ProjectScale = "single" | "monorepo";
|
|
7
|
+
export interface MCPServerChoice {
|
|
8
|
+
name: string;
|
|
9
|
+
config: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* OMO (oh-my-opencode) 에이전트 설정
|
|
13
|
+
*/
|
|
14
|
+
export interface OMOAgentConfig {
|
|
15
|
+
model: string;
|
|
16
|
+
variant?: "low" | "medium" | "high" | "xhigh";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* OMO (oh-my-opencode) 카테고리 설정
|
|
20
|
+
*/
|
|
21
|
+
export interface OMOCategoryConfig {
|
|
22
|
+
model: string;
|
|
23
|
+
variant?: "low" | "medium" | "high" | "xhigh";
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* OMO (oh-my-opencode) 전체 설정
|
|
27
|
+
* 키는 kebab-case로 저장됨 (e.g., "frontend-ui-ux-engineer")
|
|
28
|
+
*/
|
|
29
|
+
export interface OMOConfig {
|
|
30
|
+
agents: Record<string, OMOAgentConfig | undefined>;
|
|
31
|
+
categories: Record<string, OMOCategoryConfig | undefined>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* OMO 사용 여부 및 설정 선택
|
|
35
|
+
*/
|
|
36
|
+
export interface OMOProfile {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
config?: OMOConfig;
|
|
39
|
+
}
|
|
40
|
+
export interface UserProfile {
|
|
41
|
+
experienceLevel: ExperienceLevel;
|
|
42
|
+
previousTool: PreviousTool;
|
|
43
|
+
providers: string[];
|
|
44
|
+
budget: BudgetTier;
|
|
45
|
+
projectLanguage: string;
|
|
46
|
+
projectFramework: string;
|
|
47
|
+
testRunner: string;
|
|
48
|
+
linter: string;
|
|
49
|
+
projectScale: ProjectScale;
|
|
50
|
+
mcpServers: MCPServerChoice[];
|
|
51
|
+
plugins: string[];
|
|
52
|
+
permissionLevel: PermissionLevel;
|
|
53
|
+
migrationSource?: MigrationSource;
|
|
54
|
+
omo?: OMOProfile;
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runValidation(directory: string): Promise<string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-setup",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "OpenCode 환경 세팅 CLI + Plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"node": ">=18"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
|
-
"build": "tsup src/index.ts src/cli.ts --format esm --outDir dist --target node18 --external @opencode-ai/plugin --external zod --external commander --external @inquirer/prompts --clean && chmod +x dist/cli.js && sed -i '' '1s/^/#!\\/usr\\/bin\\/env node\\n/' dist/cli.js && rm -rf dist/templates && cp -r templates dist/templates",
|
|
58
|
+
"build": "tsup src/index.ts src/cli.ts --format esm --outDir dist --target node18 --external @opencode-ai/plugin --external zod --external commander --external @inquirer/prompts --clean && tsc --emitDeclarationOnly && chmod +x dist/cli.js && sed -i '' '1s/^/#!\\/usr\\/bin\\/env node\\n/' dist/cli.js && rm -rf dist/templates && cp -r templates dist/templates",
|
|
59
59
|
"prepare": "npm run build",
|
|
60
60
|
"lint": "tsc --noEmit",
|
|
61
61
|
"test": "bun test",
|
|
@@ -70,14 +70,14 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@inquirer/prompts": "
|
|
74
|
-
"commander": "
|
|
75
|
-
"zod": "
|
|
73
|
+
"@inquirer/prompts": "^6.0.0",
|
|
74
|
+
"commander": "^13.0.0",
|
|
75
|
+
"zod": "^3.24.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@types/node": "
|
|
79
|
-
"tsup": "
|
|
80
|
-
"tsx": "
|
|
81
|
-
"typescript": "
|
|
78
|
+
"@types/node": "^22.0.0",
|
|
79
|
+
"tsup": "^8.0.0",
|
|
80
|
+
"tsx": "^4.0.0",
|
|
81
|
+
"typescript": "^5.7.0"
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agents": {
|
|
3
|
+
"sisyphus": {
|
|
4
|
+
"model": "opencode-go/kimi-k2.5"
|
|
5
|
+
},
|
|
6
|
+
"prometheus": {
|
|
7
|
+
"model": "opencode-go/glm-5"
|
|
8
|
+
},
|
|
9
|
+
"atlas": {
|
|
10
|
+
"model": "opencode-go/kimi-k2.5"
|
|
11
|
+
},
|
|
12
|
+
"explore": {
|
|
13
|
+
"model": "opencode-go/minimax-m2.7"
|
|
14
|
+
},
|
|
15
|
+
"librarian": {
|
|
16
|
+
"model": "opencode-go/minimax-m2.5"
|
|
17
|
+
},
|
|
18
|
+
"multimodal-looker": {
|
|
19
|
+
"model": "opencode-go/kimi-k2.5"
|
|
20
|
+
},
|
|
21
|
+
"frontend-ui-ux-engineer": {
|
|
22
|
+
"model": "opencode-go/gemini-2.5-pro",
|
|
23
|
+
"variant": "low"
|
|
24
|
+
},
|
|
25
|
+
"document-writer": {
|
|
26
|
+
"model": "opencode-go/gemini-2.5-pro",
|
|
27
|
+
"variant": "low"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"categories": {
|
|
31
|
+
"explore": {
|
|
32
|
+
"model": "opencode-go/minimax-m2.7"
|
|
33
|
+
},
|
|
34
|
+
"quick": {
|
|
35
|
+
"model": "opencode-go/minimax-m2.7"
|
|
36
|
+
},
|
|
37
|
+
"deep": {
|
|
38
|
+
"model": "opencode-go/glm-5.1"
|
|
39
|
+
},
|
|
40
|
+
"unspecified-low": {
|
|
41
|
+
"model": "opencode-go/kimi-k2.5"
|
|
42
|
+
},
|
|
43
|
+
"unspecified-high": {
|
|
44
|
+
"model": "opencode-go/glm-5.1"
|
|
45
|
+
},
|
|
46
|
+
"ultrabrain": {
|
|
47
|
+
"model": "opencode-go/glm-5.1",
|
|
48
|
+
"variant": "high"
|
|
49
|
+
},
|
|
50
|
+
"oracle": {
|
|
51
|
+
"model": "opencode-go/glm-5.1",
|
|
52
|
+
"variant": "high"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agents": {
|
|
3
|
+
"sisyphus": {
|
|
4
|
+
"model": "anthropic/claude-opus-4-6"
|
|
5
|
+
},
|
|
6
|
+
"hephaestus": {
|
|
7
|
+
"model": "openai/gpt-5.4",
|
|
8
|
+
"variant": "medium"
|
|
9
|
+
},
|
|
10
|
+
"prometheus": {
|
|
11
|
+
"model": "openai/gpt-5.4"
|
|
12
|
+
},
|
|
13
|
+
"atlas": {
|
|
14
|
+
"model": "anthropic/claude-sonnet-4-5"
|
|
15
|
+
},
|
|
16
|
+
"explore": {
|
|
17
|
+
"model": "kimi-for-coding/k2p5"
|
|
18
|
+
},
|
|
19
|
+
"librarian": {
|
|
20
|
+
"model": "google/gemini-2.5-flash"
|
|
21
|
+
},
|
|
22
|
+
"multimodal-looker": {
|
|
23
|
+
"model": "opencode-go/kimi-k2.5"
|
|
24
|
+
},
|
|
25
|
+
"frontend-ui-ux-engineer": {
|
|
26
|
+
"model": "google/antigravity-gemini-3-pro",
|
|
27
|
+
"variant": "low"
|
|
28
|
+
},
|
|
29
|
+
"document-writer": {
|
|
30
|
+
"model": "google/antigravity-gemini-3-pro",
|
|
31
|
+
"variant": "low"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"categories": {
|
|
35
|
+
"explore": {
|
|
36
|
+
"model": "venice/minimax-m2.7"
|
|
37
|
+
},
|
|
38
|
+
"quick": {
|
|
39
|
+
"model": "venice/minimax-m2.7"
|
|
40
|
+
},
|
|
41
|
+
"deep": {
|
|
42
|
+
"model": "openai/gpt-5.3-codex",
|
|
43
|
+
"variant": "high"
|
|
44
|
+
},
|
|
45
|
+
"unspecified-low": {
|
|
46
|
+
"model": "anthropic/claude-sonnet-4-6"
|
|
47
|
+
},
|
|
48
|
+
"unspecified-high": {
|
|
49
|
+
"model": "anthropic/claude-opus-4-6"
|
|
50
|
+
},
|
|
51
|
+
"ultrabrain": {
|
|
52
|
+
"model": "openai/gpt-5.4",
|
|
53
|
+
"variant": "xhigh"
|
|
54
|
+
},
|
|
55
|
+
"oracle": {
|
|
56
|
+
"model": "openai/gpt-5.4",
|
|
57
|
+
"variant": "xhigh"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|