vibe-cokit 1.11.2 → 1.12.0

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 (3) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +120 -14
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # vibe-cokit (vk)
2
2
 
3
- A toolkit for interacting with Claude Code.
3
+ A toolkit for interacting with Claude Code and OpenCode.
4
4
 
5
5
  ## Install
6
6
 
@@ -12,7 +12,9 @@ bun install -g vibe-cokit
12
12
 
13
13
  ```bash
14
14
  vk init # Initialize vibe-cokit for current project
15
+ vk init opencode # Install the OpenCode kit in current project
15
16
  vk update # Update CLI + config + skills
17
+ vk update opencode # Update the OpenCode kit in current project
16
18
  vk skills # Install/update skills
17
19
  vk doctor # Health check setup
18
20
  vk doctor --fix # Auto-fix setup issues
@@ -45,7 +47,7 @@ Available plugins: `context7`, `code-review`, `ralph-loop`, `typescript-lsp`, `p
45
47
 
46
48
  - [gh](https://cli.github.com) — GitHub CLI
47
49
  - [git](https://git-scm.com) — Git version control
48
- - [claude](https://docs.anthropic.com/en/docs/claude-code) — Claude Code CLI (for mcp/plugin commands)
50
+ - [claude](https://docs.anthropic.com/en/docs/claude-code) — Claude Code CLI (for Claude setup and mcp/plugin commands)
49
51
 
50
52
  ## Development
51
53
 
package/dist/cli.js CHANGED
@@ -732,7 +732,7 @@ import { join as join3 } from "path";
732
732
 
733
733
  // src/utils/config.ts
734
734
  import { homedir as homedir2 } from "os";
735
- import { join as join2 } from "path";
735
+ import { dirname, join as join2 } from "path";
736
736
  import { mkdir as mkdir2, cp, rm, stat as stat2, readdir as readdir2, readFile, writeFile, appendFile as appendFile2 } from "fs/promises";
737
737
  import { execFile as execFile2 } from "child_process";
738
738
  import { promisify as promisify2 } from "util";
@@ -2475,6 +2475,7 @@ async function requireClaude() {
2475
2475
  var exec2 = promisify2(execFile2);
2476
2476
  var REPO = "vibe-cokit/claude-code";
2477
2477
  var ANTIGRAVITY_REPO = "vibe-cokit/antigravity";
2478
+ var OPENCODE_REPO = "vibe-cokit/opencode";
2478
2479
  var SKILLS_REPO = "vibe-cokit/skills";
2479
2480
  var CLAUDE_DIR = join2(homedir2(), ".claude");
2480
2481
  var CLAUDE_SKILLS_DIR = join2(CLAUDE_DIR, "skills");
@@ -2482,6 +2483,7 @@ var ANTIGRAVITY_SKILLS_DIR = join2(homedir2(), ".gemini", "antigravity", "skills
2482
2483
  var CONFIG_FOLDERS = ["agents", "commands", "hooks", "prompts", "workflows"];
2483
2484
  var TEMP_DIR = join2(homedir2(), ".vibe-cokit-tmp");
2484
2485
  var SETTINGS_PATH = join2(CLAUDE_DIR, "settings.json");
2486
+ var OPENCODE_SETTINGS_PATH = join2(process.cwd(), ".opencode", ".vk.json");
2485
2487
  function log(step) {
2486
2488
  console.log(` \u2192 ${step}`);
2487
2489
  }
@@ -2558,6 +2560,17 @@ async function readSettings() {
2558
2560
  async function writeSettings(settings) {
2559
2561
  await Bun.write(SETTINGS_PATH, JSON.stringify(settings, null, 2));
2560
2562
  }
2563
+ async function readOpenCodeSettings() {
2564
+ const file = Bun.file(OPENCODE_SETTINGS_PATH);
2565
+ if (await file.exists()) {
2566
+ return await file.json();
2567
+ }
2568
+ return {};
2569
+ }
2570
+ async function writeOpenCodeSettings(settings) {
2571
+ await mkdir2(dirname(OPENCODE_SETTINGS_PATH), { recursive: true });
2572
+ await Bun.write(OPENCODE_SETTINGS_PATH, JSON.stringify(settings, null, 2));
2573
+ }
2561
2574
  async function updateSettings(commitSha) {
2562
2575
  const settings = await readSettings();
2563
2576
  settings.version = commitSha;
@@ -2572,6 +2585,15 @@ async function getCurrentVersion() {
2572
2585
  const settings = await readSettings();
2573
2586
  return get_default(settings, "version", null);
2574
2587
  }
2588
+ async function getOpenCodeVersion() {
2589
+ const settings = await readOpenCodeSettings();
2590
+ return get_default(settings, "version", null);
2591
+ }
2592
+ async function updateOpenCodeVersion(commitSha) {
2593
+ const settings = await readOpenCodeSettings();
2594
+ settings.version = commitSha;
2595
+ await writeOpenCodeSettings(settings);
2596
+ }
2575
2597
  async function getRemoteSha(ref, repo = REPO) {
2576
2598
  const target = ref ?? "HEAD";
2577
2599
  const { stdout } = await exec2("git", ["ls-remote", `https://github.com/${repo}.git`, target]);
@@ -2640,6 +2662,17 @@ async function copyAgentFolder(srcDir) {
2640
2662
  await cp(src, target, { recursive: true, force: true });
2641
2663
  }
2642
2664
  }
2665
+ async function copyOpenCodeKit(srcDir) {
2666
+ const cwd = process.cwd();
2667
+ await cp(join2(srcDir, "AGENTS.md"), join2(cwd, "AGENTS.md"), { force: true });
2668
+ await cp(join2(srcDir, "opencode.jsonc"), join2(cwd, "opencode.jsonc"), { force: true });
2669
+ await cp(join2(srcDir, ".opencode"), join2(cwd, ".opencode"), { recursive: true, force: true });
2670
+ await mkdir2(join2(cwd, "docs"), { recursive: true });
2671
+ await cp(join2(srcDir, "docs", "opencode"), join2(cwd, "docs", "opencode"), {
2672
+ recursive: true,
2673
+ force: true
2674
+ });
2675
+ }
2643
2676
  async function ensureGitignore(entry) {
2644
2677
  const gitignorePath = join2(process.cwd(), ".gitignore");
2645
2678
  try {
@@ -2659,7 +2692,7 @@ async function ensureGitignore(entry) {
2659
2692
  }
2660
2693
 
2661
2694
  // src/commands/init.ts
2662
- var VALID_AGENTS = ["claude-code", "antigravity"];
2695
+ var VALID_AGENTS = ["claude-code", "antigravity", "opencode"];
2663
2696
  async function initCommand(agent) {
2664
2697
  const agentType = agent ?? "claude-code";
2665
2698
  if (!VALID_AGENTS.includes(agentType)) {
@@ -2674,6 +2707,8 @@ async function initCommand(agent) {
2674
2707
  return initClaudeCode();
2675
2708
  case "antigravity":
2676
2709
  return initAntigravity();
2710
+ case "opencode":
2711
+ return initOpenCode();
2677
2712
  }
2678
2713
  }
2679
2714
  async function initClaudeCode() {
@@ -2753,13 +2788,45 @@ vibe-cokit init (antigravity)
2753
2788
  await cleanup(tmpDir);
2754
2789
  }
2755
2790
  }
2791
+ async function initOpenCode() {
2792
+ const tmpDir = join3(TEMP_DIR, crypto.randomUUID());
2793
+ try {
2794
+ console.log(`
2795
+ vibe-cokit init (opencode)
2796
+ `);
2797
+ log("Verifying prerequisites...");
2798
+ await verifyPrerequisites();
2799
+ log("Cloning OpenCode kit...");
2800
+ await cloneRepo(tmpDir, OPENCODE_REPO);
2801
+ log("Installing OpenCode kit into current project...");
2802
+ await copyOpenCodeKit(tmpDir);
2803
+ log("Updating version tracking...");
2804
+ const sha = await getCommitSha(tmpDir);
2805
+ await updateOpenCodeVersion(sha);
2806
+ console.log(`
2807
+ \u2713 OpenCode kit initialized successfully!`);
2808
+ console.log(` Version: ${sha.slice(0, 8)}`);
2809
+ console.log(" Config: ./opencode.jsonc");
2810
+ console.log(" Agents: ./.opencode/");
2811
+ console.log(` Rules: ./AGENTS.md
2812
+ `);
2813
+ } catch (err) {
2814
+ logError("init", err);
2815
+ console.error(`
2816
+ \u2717 Init failed: ${getErrorMsg(err)}
2817
+ `);
2818
+ process.exit(1);
2819
+ } finally {
2820
+ await cleanup(tmpDir);
2821
+ }
2822
+ }
2756
2823
 
2757
2824
  // src/commands/update.ts
2758
2825
  import { join as join4 } from "path";
2759
2826
  import { execFile as execFile3 } from "child_process";
2760
2827
  import { promisify as promisify3 } from "util";
2761
2828
  var exec3 = promisify3(execFile3);
2762
- var VALID_AGENTS2 = ["claude-code", "antigravity"];
2829
+ var VALID_AGENTS2 = ["claude-code", "antigravity", "opencode"];
2763
2830
  async function updateCommand(agent, ref) {
2764
2831
  const agentType = agent;
2765
2832
  if (agentType && !VALID_AGENTS2.includes(agentType)) {
@@ -2797,6 +2864,9 @@ vibe-cokit update${agentType ? ` (${agentType})` : ""}
2797
2864
  await updateAntigravity(ref);
2798
2865
  await updateSkills(ref, ANTIGRAVITY_SKILLS_DIR);
2799
2866
  break;
2867
+ case "opencode":
2868
+ await updateOpenCode(ref);
2869
+ break;
2800
2870
  }
2801
2871
  }
2802
2872
  console.log(`
@@ -2898,6 +2968,33 @@ async function updateAntigravity(ref) {
2898
2968
  await cleanup(tmpDir);
2899
2969
  }
2900
2970
  }
2971
+ async function updateOpenCode(ref) {
2972
+ const tmpDir = join4(TEMP_DIR, crypto.randomUUID());
2973
+ try {
2974
+ log("Checking OpenCode kit version...");
2975
+ const currentSha = await getOpenCodeVersion();
2976
+ log("Fetching latest OpenCode kit version...");
2977
+ const targetSha = await getRemoteSha(ref, OPENCODE_REPO);
2978
+ if (currentSha && currentSha === targetSha) {
2979
+ log(`OpenCode kit: up-to-date (${currentSha.slice(0, 8)})`);
2980
+ return;
2981
+ }
2982
+ log("Cloning OpenCode kit...");
2983
+ await cloneRepo(tmpDir, OPENCODE_REPO);
2984
+ if (ref) {
2985
+ log(`Checking out ${ref}...`);
2986
+ await exec3("git", ["-C", tmpDir, "checkout", ref]);
2987
+ }
2988
+ log("Updating OpenCode kit in current project...");
2989
+ await copyOpenCodeKit(tmpDir);
2990
+ const sha = await getCommitSha(tmpDir);
2991
+ await updateOpenCodeVersion(sha);
2992
+ const from = currentSha ? currentSha.slice(0, 8) : "none";
2993
+ log(`OpenCode kit updated: ${from} -> ${sha.slice(0, 8)}`);
2994
+ } finally {
2995
+ await cleanup(tmpDir);
2996
+ }
2997
+ }
2901
2998
 
2902
2999
  // src/commands/skills.ts
2903
3000
  import { join as join5 } from "path";
@@ -2953,19 +3050,19 @@ vibe-cokit skills
2953
3050
 
2954
3051
  // src/commands/help.ts
2955
3052
  var HELP_TEXT = `
2956
- vibe-cokit v${version} \u2014 A toolkit for interacting with Claude Code
3053
+ vibe-cokit v${version} \u2014 A toolkit for interacting with Claude Code and OpenCode
2957
3054
 
2958
3055
  USAGE
2959
3056
  vk <command> [options]
2960
3057
 
2961
3058
  COMMANDS
2962
3059
  init Set up vibe-cokit for the current project
2963
- Clones config repo, copies agents/commands/hooks/prompts/workflows
2964
- to ~/.claude/, adds CLAUDE.md to current directory, runs claude init
3060
+ Supports claude-code, antigravity, and opencode setup flows
3061
+ OpenCode installs AGENTS.md, opencode.jsonc, .opencode/, and docs/opencode/
2965
3062
 
2966
- update [ref] Update everything: CLI + config + skills
2967
- Upgrades CLI package via npm, updates config and skills
2968
- Compares versions with remote, skips if already up-to-date
3063
+ update [agent] Update CLI or a specific kit (claude-code | antigravity | opencode)
3064
+ Upgrades CLI package via npm, then updates the selected kit when provided
3065
+ OpenCode updates the project-local OpenCode kit files and tracked commit
2969
3066
  Aliases: upgrade
2970
3067
 
2971
3068
  skills [ref] Install or update skills from vibe-cokit skills repo
@@ -2987,7 +3084,9 @@ COMMANDS
2987
3084
 
2988
3085
  EXAMPLES
2989
3086
  vk init # Initialize vibe-cokit
3087
+ vk init opencode # Install the OpenCode kit in this project
2990
3088
  vk update # Update CLI + config + skills
3089
+ vk update opencode # Update the project OpenCode kit
2991
3090
  vk skills # Install/update all skills
2992
3091
  vk mcp install # List available MCP modules
2993
3092
  vk mcp install serena context7 # Install specific MCP servers
@@ -3012,6 +3111,7 @@ FILES
3012
3111
  ~/.claude/ Config directory (agents, commands, hooks, prompts, workflows)
3013
3112
  ~/.claude/skills/ Skills directory
3014
3113
  ./CLAUDE.md Project-level Claude config (created by init)
3114
+ ./opencode.jsonc Project OpenCode config (created by init opencode)
3015
3115
  `;
3016
3116
  function helpCommand() {
3017
3117
  console.log(HELP_TEXT);
@@ -3021,6 +3121,7 @@ function helpCommand() {
3021
3121
  async function versionCommand() {
3022
3122
  const commitSha = await getCurrentVersion();
3023
3123
  const skillsSha = await getSkillsVersion();
3124
+ const opencodeSha = await getOpenCodeVersion();
3024
3125
  console.log(`
3025
3126
  vibe-cokit v${version}`);
3026
3127
  if (commitSha) {
@@ -3033,6 +3134,11 @@ vibe-cokit v${version}`);
3033
3134
  } else {
3034
3135
  console.log(` Skills commit: not installed`);
3035
3136
  }
3137
+ if (opencodeSha) {
3138
+ console.log(` OpenCode kit: ${opencodeSha.slice(0, 10)}`);
3139
+ } else {
3140
+ console.log(` OpenCode kit: not installed`);
3141
+ }
3036
3142
  console.log();
3037
3143
  }
3038
3144
 
@@ -3041,7 +3147,7 @@ import { join as join7 } from "path";
3041
3147
 
3042
3148
  // src/utils/keyboard.ts
3043
3149
  import { homedir as homedir3, platform } from "os";
3044
- import { join as join6, dirname, basename } from "path";
3150
+ import { join as join6, dirname as dirname2, basename } from "path";
3045
3151
  import { readdir as readdir3, stat as stat3, cp as cp2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
3046
3152
  var PATCH_MARKER = "/* Vietnamese IME fix */";
3047
3153
  var DEL_CHAR = "\x7F";
@@ -3236,7 +3342,7 @@ async function patchCliJs(filePath) {
3236
3342
  return { success: false, message: "\u0110\xE3 patch tr\u01B0\u1EDBc \u0111\xF3" };
3237
3343
  }
3238
3344
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
3239
- const backupDir = fileType === "binary" ? "/tmp" : dirname(filePath);
3345
+ const backupDir = fileType === "binary" ? "/tmp" : dirname2(filePath);
3240
3346
  const backupPath = join6(backupDir, `${basename(filePath)}.backup-${timestamp}`);
3241
3347
  await cp2(filePath, backupPath);
3242
3348
  try {
@@ -4033,11 +4139,11 @@ async function logsCommand(options) {
4033
4139
  var debugMode = process.argv.includes("--debug") || process.env["VK_DEBUG"] === "1";
4034
4140
  await logger.init(debugMode);
4035
4141
  var cli = dist_default("vibe-cokit");
4036
- cli.command("", "A toolkit for interacting with Claude Code").action(() => {
4142
+ cli.command("", "A toolkit for interacting with Claude Code and OpenCode").action(() => {
4037
4143
  cli.outputHelp();
4038
4144
  });
4039
- cli.command("init [agent]", "Initialize vibe-cokit (claude-code | antigravity)").action((agent) => initCommand(agent));
4040
- cli.command("update [agent] [ref]", "Update agent config to latest (claude-code | antigravity)").alias("upgrade").action((agent, ref) => updateCommand(agent, ref));
4145
+ cli.command("init [agent]", "Initialize vibe-cokit (claude-code | antigravity | opencode)").action((agent) => initCommand(agent));
4146
+ cli.command("update [agent] [ref]", "Update agent config to latest (claude-code | antigravity | opencode)").alias("upgrade").action((agent, ref) => updateCommand(agent, ref));
4041
4147
  cli.command("skills [ref]", "Install or update skills from vibe-cokit").action(skillsCommand);
4042
4148
  cli.command("help", "Show detailed usage guide").action(helpCommand);
4043
4149
  cli.command("version", "Show version and installed commit IDs").action(versionCommand);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibe-cokit",
3
- "version": "1.11.2",
4
- "description": "A toolkit for interacting with Claude Code",
3
+ "version": "1.12.0",
4
+ "description": "A toolkit for interacting with Claude Code and OpenCode",
5
5
  "module": "index.ts",
6
6
  "type": "module",
7
7
  "bin": {