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.
Files changed (37) hide show
  1. package/dist/{chunk-PKHQD5QT.js → chunk-FTV7ABVP.js} +90 -17
  2. package/dist/cli.d.ts +1 -0
  3. package/dist/cli.js +144 -4
  4. package/dist/core/agent-generator.d.ts +2 -0
  5. package/dist/core/agents-md-generator.d.ts +3 -0
  6. package/dist/core/command-generator.d.ts +2 -0
  7. package/dist/core/config-generator.d.ts +6 -0
  8. package/dist/core/env-generator.d.ts +3 -0
  9. package/dist/core/omo-generator.d.ts +20 -0
  10. package/dist/core/skill-generator.d.ts +3 -0
  11. package/dist/doctor/checks.d.ts +7 -0
  12. package/dist/doctor/reporter.d.ts +2 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +29 -17
  15. package/dist/migrate/aider.d.ts +1 -0
  16. package/dist/migrate/claude-code.d.ts +1 -0
  17. package/dist/migrate/common.d.ts +8 -0
  18. package/dist/migrate/cursor.d.ts +1 -0
  19. package/dist/migrate/index.d.ts +3 -0
  20. package/dist/preset/registry.d.ts +58 -0
  21. package/dist/prompt/questions.d.ts +18 -0
  22. package/dist/prompt/wizard.d.ts +1 -0
  23. package/dist/templates/omo/free.json +55 -0
  24. package/dist/templates/omo/premium.json +60 -0
  25. package/dist/tools/setup-doctor.d.ts +5 -0
  26. package/dist/tools/setup-init.d.ts +2 -0
  27. package/dist/tools/setup-migrate.d.ts +2 -0
  28. package/dist/tools/setup-preset.d.ts +7 -0
  29. package/dist/tools/setup-validate.d.ts +5 -0
  30. package/dist/types/index.d.ts +4 -0
  31. package/dist/types/migration.d.ts +25 -0
  32. package/dist/types/opencode-config.d.ts +55 -0
  33. package/dist/types/user-profile.d.ts +55 -0
  34. package/dist/validator/config-validator.d.ts +1 -0
  35. package/package.json +9 -9
  36. package/templates/omo/free.json +55 -0
  37. 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-z0-9-]+\/[a-z0-9-]+$/i;
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(process.env.HOME || "~", ".local/share/opencode/auth.json");
336
- const expandedPath = authPath.replace("~", process.env.HOME || "");
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(process.env.HOME || "~", ".config/opencode/opencode.json");
344
- const expandedPath = configPath.replace("~", process.env.HOME || "");
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(process.env.HOME || "~", ".config/opencode/opencode.json");
392
- const expandedPath = configPath.replace("~", process.env.HOME || "");
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
- const parsed = JSON.parse(settings);
561
- if (parsed.model) {
562
- suggestions.push(`\uBAA8\uB378 \uC124\uC815 \uAC10\uC9C0\uB428: ${parsed.model} - opencode.json\uC5D0 \uC218\uB3D9\uC73C\uB85C \uCD94\uAC00 \uD544\uC694`);
563
- }
564
- if (parsed["dangerously-skip-permissions"]) {
565
- warnings.push("dangerously-skip-permissions\uB294 OpenCode\uC5D0\uC11C \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
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
- writeFileSync3(filePath, content, "utf-8");
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-PKHQD5QT.js";
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}/.config/opencode/opencode.json (\uAE00\uB85C\uBC8C \uC124\uC815)`,
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,2 @@
1
+ export declare function generateAgents(): Record<string, string>;
2
+ export declare function writeAgents(agents: Record<string, string>, dir: string): void;
@@ -0,0 +1,3 @@
1
+ import type { UserProfile } from "../types";
2
+ export declare function generateAgentsMD(profile: UserProfile): string;
3
+ export declare function writeAgentsMD(content: string, dir: string): void;
@@ -0,0 +1,2 @@
1
+ export declare function generateCommands(): Record<string, string>;
2
+ export declare function writeCommands(commands: Record<string, string>, dir: string): void;
@@ -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,3 @@
1
+ import type { UserProfile } from "../types";
2
+ export declare function generateEnvExample(profile: UserProfile): string;
3
+ export declare function writeEnvExample(content: string, dir: 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
+ };
@@ -0,0 +1,3 @@
1
+ import type { UserProfile } from "../types";
2
+ export declare function generateSkills(profile: UserProfile): Record<string, string>;
3
+ export declare function writeSkills(skills: Record<string, string>, dir: string): void;
@@ -0,0 +1,7 @@
1
+ export interface CheckResult {
2
+ name: string;
3
+ status: "pass" | "warn" | "fail";
4
+ message: string;
5
+ fix?: string;
6
+ }
7
+ export declare function runAllChecks(directory: string): Promise<CheckResult[]>;
@@ -0,0 +1,2 @@
1
+ import type { CheckResult } from "./checks.js";
2
+ export declare function formatReport(results: CheckResult[]): string;
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare const OcSetupPlugin: Plugin;
package/dist/index.js CHANGED
@@ -18,11 +18,12 @@ import {
18
18
  writeGlobalConfig,
19
19
  writeProjectConfig,
20
20
  writeSkills
21
- } from "./chunk-PKHQD5QT.js";
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(`${homeDir}/.config/opencode/opencode.json`);
45
+ generatedFiles.push(join(homeDir, ".config/opencode/opencode.json"));
45
46
  writeProjectConfig(profile, projectDir);
46
- generatedFiles.push(`${projectDir}/opencode.json`);
47
+ generatedFiles.push(join(projectDir, "opencode.json"));
47
48
  const agentsMD = generateAgentsMD(profile);
48
49
  writeAgentsMD(agentsMD, projectDir);
49
- generatedFiles.push(`${projectDir}/AGENTS.md`);
50
+ generatedFiles.push(join(projectDir, "AGENTS.md"));
50
51
  const commands = generateCommands();
51
52
  writeCommands(commands, projectDir);
52
- generatedFiles.push(`${projectDir}/.opencode/commands/`);
53
+ generatedFiles.push(join(projectDir, ".opencode/commands/"));
53
54
  const agents = generateAgents();
54
55
  writeAgents(agents, projectDir);
55
- generatedFiles.push(`${projectDir}/.opencode/agents/`);
56
+ generatedFiles.push(join(projectDir, ".opencode/agents/"));
56
57
  const skills = generateSkills(profile);
57
58
  writeSkills(skills, projectDir);
58
- generatedFiles.push(`${projectDir}/.opencode/skills/`);
59
+ generatedFiles.push(join(projectDir, ".opencode/skills/"));
59
60
  const envContent = generateEnvExample(profile);
60
61
  writeEnvExample(envContent, projectDir);
61
- generatedFiles.push(`${projectDir}/.env.example`);
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
- const result = await applyPreset(args.name, context.directory);
99
- if (!result.success) {
100
- return `\u274C Failed to apply preset '${args.name}'.
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
- const filesList = result.files.map((f) => ` \u2022 ${f}`).join("\n");
105
- return `\u2705 Preset '${args.name}' applied successfully!
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
- if (!args.tool) {
127
- return autoMigrate(rootPath);
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,3 @@
1
+ export type MigrationTool = "claude-code" | "cursor" | "aider";
2
+ export declare function runMigration(tool: MigrationTool, rootPath: string): Promise<string>;
3
+ export declare function autoMigrate(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,5 @@
1
+ export declare const setupDoctor: {
2
+ description: string;
3
+ args: {};
4
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
5
+ };
@@ -0,0 +1,2 @@
1
+ import { tool } from "@opencode-ai/plugin";
2
+ export declare const setupInit: ReturnType<typeof tool>;
@@ -0,0 +1,2 @@
1
+ import { tool } from "@opencode-ai/plugin";
2
+ export declare const setupMigrate: ReturnType<typeof tool>;
@@ -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,5 @@
1
+ export declare const setupValidate: {
2
+ description: string;
3
+ args: {};
4
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
5
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./user-profile";
2
+ export * from "./opencode-config";
3
+ export * from "./migration";
4
+ export type { OMOConfig, OMOAgentConfig, OMOCategoryConfig, OMOProfile } from "./user-profile";
@@ -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.0",
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": "latest",
74
- "commander": "latest",
75
- "zod": "latest"
73
+ "@inquirer/prompts": "^6.0.0",
74
+ "commander": "^13.0.0",
75
+ "zod": "^3.24.0"
76
76
  },
77
77
  "devDependencies": {
78
- "@types/node": "latest",
79
- "tsup": "latest",
80
- "tsx": "latest",
81
- "typescript": "latest"
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
+ }