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 +75 -79
- package/dist/index.js +72 -31
- package/package.json +7 -4
- package/start-opencode.sh +46 -0
package/README.md
CHANGED
|
@@ -3,49 +3,18 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/opencode-diff-viewer)
|
|
4
4
|
[](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** -
|
|
10
|
+
- ✨ **自动安装 tmux 和 lumen** - 插件会自动检测并安装依赖
|
|
11
11
|
- 🚀 **一键查看 diff** - 使用 `/diff` 命令快速查看代码变更
|
|
12
|
-
- 🔧
|
|
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
|
-
###
|
|
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.
|
|
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
|
|
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.
|
|
49
|
+
### 3. 启动 OpenCode(使用启动脚本)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 使用启动脚本自动在 tmux 中启动 OpenCode
|
|
53
|
+
opencode-diff-viewer
|
|
81
54
|
|
|
82
|
-
|
|
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
|
-
|
|
75
|
+
执行后,lumen 会在 tmux 会话 `opencode-diff-viewer` 中运行。
|
|
96
76
|
|
|
97
|
-
|
|
77
|
+
### 查看 lumen diff
|
|
98
78
|
|
|
99
|
-
|
|
79
|
+
**新开一个终端窗口**,运行:
|
|
100
80
|
|
|
101
|
-
|
|
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
|
-
###
|
|
107
|
+
### tmux
|
|
114
108
|
|
|
109
|
+
启动脚本会自动安装 tmux。如果失败,手动安装:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
brew install tmux
|
|
113
|
+
# or
|
|
114
|
+
apt install tmux
|
|
115
115
|
```
|
|
116
|
-
|
|
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
|
-
|
|
127
|
+
## 故障排除
|
|
120
128
|
|
|
121
|
-
###
|
|
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
|
-
###
|
|
133
|
-
|
|
134
|
-
检查终端模拟器是否支持:
|
|
135
|
-
- macOS: Terminal.app
|
|
136
|
-
- Linux: gnome-terminal 或 xterm
|
|
141
|
+
### 2. 插件未加载
|
|
137
142
|
|
|
138
|
-
|
|
143
|
+
检查配置:
|
|
139
144
|
|
|
140
|
-
检查全局配置文件是否正确:
|
|
141
145
|
```bash
|
|
142
146
|
cat ~/.config/opencode/opencode.json
|
|
143
147
|
```
|
|
144
148
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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.
|
|
161
|
-
2.
|
|
162
|
-
3.
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|