opencode-diff-viewer 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,49 +3,18 @@
3
3
  [![npm version](https://img.shields.io/npm/v/opencode-diff-viewer.svg)](https://www.npmjs.com/package/opencode-diff-viewer)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/opencode-diff-viewer.svg)](https://www.npmjs.com/package/opencode-diff-viewer)
5
5
 
6
- 一个 OpenCode 插件,使用 [lumen](https://github.com/jnsahaj/lumen) 提供美观的 TUI diff 查看功能。
6
+ 一个 OpenCode 插件,使用 [lumen](https://github.com/jnsahaj/lumen) + [tmux](https://github.com/tmux/tmux) 提供美观的 TUI diff 查看功能。
7
7
 
8
8
  ## 功能特性
9
9
 
10
- - ✨ **自动安装 lumen** - 插件会自动检测并安装 lumen 依赖
10
+ - ✨ **自动安装 tmux 和 lumen** - 插件会自动检测并安装依赖
11
11
  - 🚀 **一键查看 diff** - 使用 `/diff` 命令快速查看代码变更
12
- - 🔧 **智能终端适配** - 自动检测操作系统,打开新终端窗口展示 diff
12
+ - 🔧 **tmux 集成** - 在后台 tmux 会话中运行 lumen
13
13
  - 🤖 **LLM 工具集成** - LLM 可自动调用 `view_diff` 工具
14
14
 
15
- ## 前置条件
16
-
17
- ### 1. 安装 lumen
18
-
19
- 插件会自动尝试安装 lumen,如果自动安装失败,需要手动安装:
20
-
21
- **macOS / Linux (Homebrew)**:
22
- ```bash
23
- brew install jnsahaj/lumen/lumen
24
- ```
25
-
26
- **Bun**:
27
- ```bash
28
- bun install jnsahaj/lumen/lumen
29
- ```
30
-
31
- **Cargo (Rust)**:
32
- ```bash
33
- cargo install lumen
34
- ```
35
-
36
- **Windows**:
37
- 下载 [lumen releases](https://github.com/jnsahaj/lumen/releases) 并添加到 PATH
15
+ ## 快速开始
38
16
 
39
- ### 2. Git 仓库
40
-
41
- 确保项目是 git 仓库,并且有修改的文件:
42
- ```bash
43
- git status # 查看修改的文件
44
- ```
45
-
46
- ## 安装(全局配置)
47
-
48
- ### 1. 安装 npm 包
17
+ ### 1. 安装插件
49
18
 
50
19
  ```bash
51
20
  # npm
@@ -58,7 +27,7 @@ pnpm add -g opencode-diff-viewer
58
27
  bun add -g opencode-diff-viewer
59
28
  ```
60
29
 
61
- ### 2. 配置全局 opencode.json
30
+ ### 2. 配置 OpenCode
62
31
 
63
32
  创建或编辑 `~/.config/opencode/opencode.json`:
64
33
 
@@ -68,7 +37,7 @@ cat > ~/.config/opencode/opencode.json << 'EOF'
68
37
  {
69
38
  "command": {
70
39
  "diff": {
71
- "template": "View git diff using lumen TUI.",
40
+ "template": "View git diff using lumen in tmux.",
72
41
  "description": "View diff of modified files using lumen TUI"
73
42
  }
74
43
  },
@@ -77,28 +46,53 @@ cat > ~/.config/opencode/opencode.json << 'EOF'
77
46
  EOF
78
47
  ```
79
48
 
80
- ### 3. 重启 OpenCode
49
+ ### 3. 启动 OpenCode(使用启动脚本)
50
+
51
+ ```bash
52
+ # 使用启动脚本自动在 tmux 中启动 OpenCode
53
+ opencode-diff-viewer
81
54
 
82
- 安装完成后重启 OpenCode TUI,插件会自动加载。
55
+ # 或手动运行
56
+ ./start-opencode.sh
57
+ ```
58
+
59
+ 启动脚本会自动:
60
+ - 检查并安装 tmux(如果未安装)
61
+ - 在 tmux 会话中启动 OpenCode
62
+ - 附加到 tmux 会话
83
63
 
84
64
  ## 使用方法
85
65
 
86
- ### 通过命令
66
+ ### 在 OpenCode 中使用 /diff
87
67
 
88
- 在 OpenCode TUI 中直接输入:
68
+ 在 OpenCode TUI 中输入:
89
69
 
90
70
  ```bash
91
71
  /diff # 查看所有修改文件的 diff
92
72
  /diff src/app.ts # 查看指定文件的 diff
93
73
  ```
94
74
 
95
- ### 通过 LLM
75
+ 执行后,lumen 会在 tmux 会话 `opencode-diff-viewer` 中运行。
96
76
 
97
- LLM 可以自动调用 `view_diff` 工具来展示代码变更。无需手动操作,LLM 会根据对话上下文智能判断何时需要展示 diff
77
+ ### 查看 lumen diff
98
78
 
99
- ## lumen 快捷键
79
+ **新开一个终端窗口**,运行:
100
80
 
101
- 在 lumen diff 查看器中:
81
+ ```bash
82
+ tmux attach -t opencode-diff-viewer
83
+ ```
84
+
85
+ 查看完成后,按 `Ctrl+B` 然后 `D` 分离 tmux 会话,回到 OpenCode。
86
+
87
+ ## tmux 快捷键
88
+
89
+ | 快捷键 | 功能 |
90
+ |--------|------|
91
+ | `Ctrl+B` 然后 `D` | 分离会话(回到终端) |
92
+ | `Ctrl+B` 然后 `?` | 查看所有快捷键 |
93
+ | `Ctrl+C` | 终止当前会话 |
94
+
95
+ ## lumen 快捷键
102
96
 
103
97
  | 快捷键 | 功能 |
104
98
  |--------|------|
@@ -108,63 +102,71 @@ LLM 可以自动调用 `view_diff` 工具来展示代码变更。无需手动操
108
102
  | `e` | 在编辑器中打开文件 |
109
103
  | `q` | 退出 |
110
104
 
111
- ## 故障排除
105
+ ## 前置条件
112
106
 
113
- ### 1. lumen 未安装
107
+ ### tmux
114
108
 
109
+ 启动脚本会自动安装 tmux。如果失败,手动安装:
110
+
111
+ ```bash
112
+ brew install tmux
113
+ # or
114
+ apt install tmux
115
115
  ```
116
- ❌ lumen is not installed
116
+
117
+ ### lumen
118
+
119
+ 插件会自动安装 lumen。如果失败,手动安装:
120
+
121
+ ```bash
122
+ brew install jnsahaj/lumen/lumen
123
+ # or
124
+ cargo install lumen
117
125
  ```
118
126
 
119
- **解决方案**: 手动安装 lumen(见上方前置条件)
127
+ ## 故障排除
120
128
 
121
- ### 2. 没有修改的文件
129
+ ### 1. 没有修改的文件
122
130
 
123
131
  ```
124
132
  📝 No modified files
125
133
  ```
126
134
 
127
135
  **解决方案**: 确保文件已修改并暂存:
136
+
128
137
  ```bash
129
138
  git add .
130
139
  ```
131
140
 
132
- ### 3. 新终端未打开
133
-
134
- 检查终端模拟器是否支持:
135
- - macOS: Terminal.app
136
- - Linux: gnome-terminal 或 xterm
141
+ ### 2. 插件未加载
137
142
 
138
- ### 4. 插件未加载
143
+ 检查配置:
139
144
 
140
- 检查全局配置文件是否正确:
141
145
  ```bash
142
146
  cat ~/.config/opencode/opencode.json
143
147
  ```
144
148
 
145
- 确保配置正确:
146
- ```json
147
- {
148
- "command": {
149
- "diff": {
150
- "template": "View git diff using lumen TUI.",
151
- "description": "View diff of modified files using lumen TUI"
152
- }
153
- },
154
- "plugin": ["opencode-diff-viewer"]
155
- }
149
+ ### 3. tmux 会话丢失
150
+
151
+ 重新运行启动脚本:
152
+
153
+ ```bash
154
+ opencode-diff-viewer
156
155
  ```
157
156
 
158
157
  ## 工作原理
159
158
 
160
- 1. **检测修改文件** - 插件使用 `git diff` 获取已暂存和未暂存的修改
161
- 2. **启动 lumen** - 在新终端窗口中运行 `lumen diff --file <files>`
162
- 3. **自动安装** - 插件启动时检查 lumen,未安装则自动安装
159
+ 1. **启动脚本** - tmux new-session 启动 OpenCode
160
+ 2. **插件加载** - OpenCode 启动时自动加载
161
+ 3. **自动安装依赖** - 检查并安装 tmux 和 lumen
162
+ 4. **执行 /diff** - 创建新的 tmux 会话 "opencode-diff-viewer"
163
+ 5. **运行 lumen** - 在 tmux 会话中显示 diff
163
164
 
164
165
  ## 项目结构
165
166
 
166
167
  ```
167
168
  opencode-diff-viewer/
169
+ ├── start-opencode.sh # 启动脚本
168
170
  ├── src/
169
171
  │ ├── index.ts # 插件主逻辑
170
172
  │ └── command-diff.md # /diff 命令定义
@@ -184,18 +186,11 @@ cd opencode-diff-viewer
184
186
 
185
187
  # 安装依赖
186
188
  npm install
187
- # 或
188
- pnpm install
189
- # 或
190
- bun install
191
189
 
192
190
  # 构建
193
191
  npm run build
194
192
 
195
193
  # 链接本地包
196
- npm link
197
-
198
- # 在全局使用
199
194
  npm link -g opencode-diff-viewer
200
195
  ```
201
196
 
@@ -213,6 +208,7 @@ npm publish
213
208
 
214
209
  ## 依赖
215
210
 
211
+ - [tmux](https://github.com/tmux/tmux) - 终端复用器
216
212
  - [lumen](https://github.com/jnsahaj/lumen) - TUI Diff 查看器
217
213
  - [@opencode-ai/plugin](https://www.npmjs.com/package/@opencode-ai/plugin) - OpenCode 插件 SDK
218
214
 
package/dist/index.js CHANGED
@@ -9,6 +9,15 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
9
9
  return false;
10
10
  }
11
11
  };
12
+ const isTmuxInstalled = async () => {
13
+ try {
14
+ await $ `which tmux`;
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ };
12
21
  const isBrewInstalled = async () => {
13
22
  try {
14
23
  await $ `which brew`;
@@ -51,6 +60,21 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
51
60
  error: "Neither brew nor cargo available. Please install lumen manually:\n brew install jnsahaj/lumen/lumen\n # or\n cargo install lumen"
52
61
  };
53
62
  };
63
+ const installTmux = async () => {
64
+ if (await isBrewInstalled()) {
65
+ try {
66
+ await $ `brew install tmux`;
67
+ return { success: true, method: "brew" };
68
+ }
69
+ catch (e) {
70
+ console.warn(`brew install tmux failed: ${e}`);
71
+ }
72
+ }
73
+ return {
74
+ success: false,
75
+ error: "Please install tmux manually:\n brew install tmux\n # or\n apt install tmux"
76
+ };
77
+ };
54
78
  const ensureLumenInstalled = async () => {
55
79
  if (await isLumenInstalled()) {
56
80
  return { installed: true };
@@ -61,7 +85,25 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
61
85
  }
62
86
  return { installed: false, message: `❌ ${result.error}` };
63
87
  };
64
- await ensureLumenInstalled();
88
+ const ensureTmuxInstalled = async () => {
89
+ if (await isTmuxInstalled()) {
90
+ return { installed: true };
91
+ }
92
+ const result = await installTmux();
93
+ if (result.success) {
94
+ return { installed: true, message: `✅ tmux installed via ${result.method}` };
95
+ }
96
+ return { installed: false, message: `❌ ${result.error}` };
97
+ };
98
+ // Check and install dependencies on startup
99
+ const tmuxCheck = await ensureTmuxInstalled();
100
+ if (!tmuxCheck.installed) {
101
+ console.warn(tmuxCheck.message);
102
+ }
103
+ const lumenCheck = await ensureLumenInstalled();
104
+ if (!lumenCheck.installed) {
105
+ console.warn(lumenCheck.message);
106
+ }
65
107
  const getModifiedFiles = async () => {
66
108
  try {
67
109
  const unstaged = await $ `git diff --name-only`.text();
@@ -77,6 +119,18 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
77
119
  }
78
120
  };
79
121
  const launchDiffViewer = async (files) => {
122
+ // Check tmux
123
+ if (!await isTmuxInstalled()) {
124
+ return `❌ tmux is not installed.
125
+
126
+ To install:
127
+ brew install tmux
128
+ # or
129
+ apt install tmux
130
+
131
+ Then restart OpenCode.`;
132
+ }
133
+ // Check lumen
80
134
  if (!await isLumenInstalled()) {
81
135
  return `❌ lumen is not installed.
82
136
 
@@ -93,40 +147,27 @@ Then restart OpenCode.`;
93
147
  }
94
148
  const fileList = modifiedFiles.map(f => ` • ${f}`).join('\n');
95
149
  const fileArgs = modifiedFiles.map(f => `"${f}"`).join(' ');
150
+ const sessionName = "opencode-diff-viewer";
96
151
  const cmd = `cd "${directory}" && lumen diff ${fileArgs}`;
97
- const platform = process.platform;
98
- // Try to launch in new terminal
99
- let launched = false;
100
- let errorMsg = "";
101
152
  try {
102
- if (platform === 'darwin') {
103
- await $ `osascript -e 'tell application "Terminal" to do script "${cmd}; exit"'`;
104
- launched = true;
105
- }
106
- else if (platform === 'linux') {
107
- try {
108
- await $ `which gnome-terminal && gnome-terminal -- bash -c "${cmd}; read -p 'Press Enter to close...'" `;
109
- launched = true;
110
- }
111
- catch {
112
- try {
113
- await $ `which xterm && xterm -e "bash -c '${cmd}; read -p Press Enter to close...'" `;
114
- launched = true;
115
- }
116
- catch (e) {
117
- errorMsg = "No terminal emulator found (gnome-terminal/xterm)";
118
- }
119
- }
120
- }
153
+ // Kill existing session if it exists
154
+ await $ `tmux kill-session -t "${sessionName}" 2>/dev/null || true`;
155
+ // Create new tmux session
156
+ await $ `tmux new-session -d -s "${sessionName}" "${cmd}"`;
157
+ return `✅ Opened lumen in tmux session "${sessionName}":\n${fileList}\n\nTo use lumen:
158
+ 1. Run: tmux attach -t "${sessionName}"
159
+ 2. Navigate: j/k or arrows, {/} for hunks
160
+ 3. Detach: Ctrl+B then D
161
+
162
+ Keybindings:
163
+ j/k or ↑/↓: Navigate {/}: Jump hunks
164
+ tab: Sidebar e: Edit file
165
+ q: Quit`;
121
166
  }
122
167
  catch (e) {
123
- errorMsg = e.message || "Unknown error";
124
- }
125
- if (launched) {
126
- return `✅ Opened lumen diff viewer:\n${fileList}\n\nKeybindings:\n j/k: Navigate {/}: Jump hunks tab: Sidebar e: Edit q: Quit`;
168
+ return `❌ Failed to launch tmux session: ${e.message || e}\n\nTry manually:
169
+ tmux new-session -s "${sessionName}" "${cmd}"`;
127
170
  }
128
- // If we couldn't launch, show manual instructions
129
- return `📺 Could not open terminal automatically.\n\nTo view diffs in lumen:\n1. Open a new terminal\n2. Run:\n ${cmd}\n\nModified files:\n${fileList}`;
130
171
  };
131
172
  return {
132
173
  "tui.command.execute": async (input, output) => {
@@ -141,7 +182,7 @@ Then restart OpenCode.`;
141
182
  },
142
183
  tool: {
143
184
  view_diff: tool({
144
- description: "Open the lumen diff viewer to show git diff for modified files.",
185
+ description: "Open the lumen diff viewer in a tmux session.",
145
186
  args: {
146
187
  file: tool.schema.string().optional().describe("Optional: specific file path"),
147
188
  },
package/package.json CHANGED
@@ -1,21 +1,24 @@
1
1
  {
2
2
  "name": "opencode-diff-viewer",
3
- "version": "1.0.7",
4
- "description": "OpenCode plugin for viewing git diffs using lumen TUI",
3
+ "version": "1.0.9",
4
+ "description": "OpenCode plugin for viewing git diffs using lumen TUI with tmux",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist/",
9
- "command-diff.md"
9
+ "command-diff.md",
10
+ "start-opencode.sh"
10
11
  ],
11
12
  "scripts": {
12
- "build": "tsc"
13
+ "build": "tsc",
14
+ "start": "./start-opencode.sh"
13
15
  },
14
16
  "keywords": [
15
17
  "opencode",
16
18
  "opencode-plugin",
17
19
  "diff",
18
20
  "lumen",
21
+ "tmux",
19
22
  "git"
20
23
  ],
21
24
  "author": "AarynLu",
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+
3
+ # OpenCode Diff Viewer - 启动脚本
4
+ # 自动在 tmux 中启动 OpenCode
5
+
6
+ set -e
7
+
8
+ SESSION_NAME="opencode"
9
+
10
+ # 检查 tmux 是否安装
11
+ if ! command -v tmux &> /dev/null; then
12
+ echo "❌ tmux 未安装,正在安装..."
13
+ if command -v brew &> /dev/null; then
14
+ brew install tmux
15
+ else
16
+ echo "❌ 请先安装 tmux: brew install tmux"
17
+ exit 1
18
+ fi
19
+ fi
20
+
21
+ # 检查 OpenCode 是否安装
22
+ if ! command -v opencode &> /dev/null; then
23
+ echo "❌ OpenCode 未安装"
24
+ exit 1
25
+ fi
26
+
27
+ # 检查是否有正在运行的 OpenCode 会话
28
+ if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
29
+ echo "📎 已存在 OpenCode 会话,正在附加..."
30
+ tmux attach-session -t "$SESSION_NAME"
31
+ else
32
+ echo "🚀 在 tmux 中启动 OpenCode..."
33
+ tmux new-session -d -s "$SESSION_NAME" "opencode"
34
+ echo "✅ OpenCode 已在 tmux 会话 '${SESSION_NAME}' 中启动"
35
+ echo ""
36
+ echo "下一步:"
37
+ echo " 1. 运行: tmux attach -t ${SESSION_NAME}"
38
+ echo " 2. 在 OpenCode 中使用 /diff 命令查看代码变更"
39
+ echo " 3. lumen 会在后台 tmux 会话 'opencode-diff-viewer' 中运行"
40
+ echo ""
41
+ echo "tmux 快捷键:"
42
+ echo " Ctrl+B 然后 D - 分离会话"
43
+ echo " Ctrl+B 然后 ? - 查看帮助"
44
+ echo ""
45
+ tmux attach-session -t "$SESSION_NAME"
46
+ fi