opencode-diff-viewer 1.0.5 → 1.0.6
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 +26 -39
- package/dist/index.d.ts +0 -5
- package/dist/index.js +45 -52
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,38 +3,33 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/opencode-diff-viewer)
|
|
4
4
|
[](https://www.npmjs.com/package/opencode-diff-viewer)
|
|
5
5
|
|
|
6
|
-
一个 OpenCode 插件,使用 [
|
|
6
|
+
一个 OpenCode 插件,使用 [delta](https://github.com/dandavison/delta) 提供语法高亮的 git diff 查看功能。
|
|
7
7
|
|
|
8
8
|
## 功能特性
|
|
9
9
|
|
|
10
|
-
- ✨ **自动安装
|
|
10
|
+
- ✨ **自动安装 delta** - 插件会自动检测并安装 delta 依赖
|
|
11
11
|
- 🚀 **一键查看 diff** - 使用 `/diff` 命令快速查看代码变更
|
|
12
|
-
-
|
|
12
|
+
- 🎨 **语法高亮** - 支持多种编程语言的语法高亮
|
|
13
13
|
- 🤖 **LLM 工具集成** - LLM 可自动调用 `view_diff` 工具
|
|
14
14
|
|
|
15
15
|
## 前置条件
|
|
16
16
|
|
|
17
|
-
### 1. 安装
|
|
17
|
+
### 1. 安装 delta
|
|
18
18
|
|
|
19
|
-
插件会自动尝试安装
|
|
19
|
+
插件会自动尝试安装 delta,如果自动安装失败,需要手动安装:
|
|
20
20
|
|
|
21
21
|
**macOS / Linux (Homebrew)**:
|
|
22
22
|
```bash
|
|
23
|
-
brew install
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**macOS / Linux (Bun)**:
|
|
27
|
-
```bash
|
|
28
|
-
bun install jnsahaj/lumen/lumen
|
|
23
|
+
brew install dandavison/delta/delta
|
|
29
24
|
```
|
|
30
25
|
|
|
31
26
|
**Cargo (Rust)**:
|
|
32
27
|
```bash
|
|
33
|
-
cargo install
|
|
28
|
+
cargo install delta
|
|
34
29
|
```
|
|
35
30
|
|
|
36
31
|
**Windows**:
|
|
37
|
-
下载 [
|
|
32
|
+
下载 [delta releases](https://github.com/dandavison/delta/releases) 并添加到 PATH
|
|
38
33
|
|
|
39
34
|
### 2. Git 仓库
|
|
40
35
|
|
|
@@ -68,8 +63,8 @@ cat > ~/.config/opencode/opencode.json << 'EOF'
|
|
|
68
63
|
{
|
|
69
64
|
"command": {
|
|
70
65
|
"diff": {
|
|
71
|
-
"template": "View git diff
|
|
72
|
-
"description": "
|
|
66
|
+
"template": "View git diff with syntax highlighting.",
|
|
67
|
+
"description": "Show git diff with syntax highlighting"
|
|
73
68
|
}
|
|
74
69
|
},
|
|
75
70
|
"plugin": ["opencode-diff-viewer"]
|
|
@@ -96,32 +91,30 @@ EOF
|
|
|
96
91
|
|
|
97
92
|
LLM 可以自动调用 `view_diff` 工具来展示代码变更。无需手动操作,LLM 会根据对话上下文智能判断何时需要展示 diff。
|
|
98
93
|
|
|
99
|
-
##
|
|
94
|
+
## delta 快捷键
|
|
100
95
|
|
|
101
|
-
在
|
|
96
|
+
在 diff 输出中:
|
|
102
97
|
|
|
103
98
|
| 快捷键 | 功能 |
|
|
104
99
|
|--------|------|
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `e` | 在编辑器中打开文件 |
|
|
109
|
-
| `q` | 退出 |
|
|
100
|
+
| `n` / `p` | 下/上一个变更 |
|
|
101
|
+
| `N` / `P` | 下/上一个文件 |
|
|
102
|
+
| `q` | 退出(如果启用 pager) |
|
|
110
103
|
|
|
111
104
|
## 故障排除
|
|
112
105
|
|
|
113
|
-
### 1.
|
|
106
|
+
### 1. delta 未安装
|
|
114
107
|
|
|
115
108
|
```
|
|
116
|
-
❌
|
|
109
|
+
❌ delta is not installed
|
|
117
110
|
```
|
|
118
111
|
|
|
119
|
-
**解决方案**: 手动安装
|
|
112
|
+
**解决方案**: 手动安装 delta(见上方前置条件)
|
|
120
113
|
|
|
121
114
|
### 2. 没有修改的文件
|
|
122
115
|
|
|
123
116
|
```
|
|
124
|
-
📝 No modified files
|
|
117
|
+
📝 No modified files
|
|
125
118
|
```
|
|
126
119
|
|
|
127
120
|
**解决方案**: 确保文件已修改并暂存:
|
|
@@ -129,26 +122,20 @@ LLM 可以自动调用 `view_diff` 工具来展示代码变更。无需手动操
|
|
|
129
122
|
git add .
|
|
130
123
|
```
|
|
131
124
|
|
|
132
|
-
### 3.
|
|
133
|
-
|
|
134
|
-
检查终端模拟器是否支持:
|
|
135
|
-
- macOS: Terminal.app
|
|
136
|
-
- Linux: gnome-terminal 或 xterm
|
|
137
|
-
|
|
138
|
-
### 4. 插件未加载
|
|
125
|
+
### 3. 插件未加载
|
|
139
126
|
|
|
140
127
|
检查全局配置文件是否正确:
|
|
141
128
|
```bash
|
|
142
129
|
cat ~/.config/opencode/opencode.json
|
|
143
130
|
```
|
|
144
131
|
|
|
145
|
-
|
|
132
|
+
确保配置正确:
|
|
146
133
|
```json
|
|
147
134
|
{
|
|
148
135
|
"command": {
|
|
149
136
|
"diff": {
|
|
150
|
-
"template": "View git diff
|
|
151
|
-
"description": "
|
|
137
|
+
"template": "View git diff with syntax highlighting.",
|
|
138
|
+
"description": "Show git diff with syntax highlighting"
|
|
152
139
|
}
|
|
153
140
|
},
|
|
154
141
|
"plugin": ["opencode-diff-viewer"]
|
|
@@ -158,8 +145,8 @@ cat ~/.config/opencode/opencode.json
|
|
|
158
145
|
## 工作原理
|
|
159
146
|
|
|
160
147
|
1. **检测修改文件** - 插件使用 `git diff` 获取已暂存和未暂存的修改
|
|
161
|
-
2.
|
|
162
|
-
3. **自动安装** - 插件启动时检查
|
|
148
|
+
2. **格式化输出** - 通过 `delta` 管道输出,带语法高亮
|
|
149
|
+
3. **自动安装** - 插件启动时检查 delta,未安装则自动安装
|
|
163
150
|
|
|
164
151
|
## 项目结构
|
|
165
152
|
|
|
@@ -213,7 +200,7 @@ npm publish
|
|
|
213
200
|
|
|
214
201
|
## 依赖
|
|
215
202
|
|
|
216
|
-
- [
|
|
203
|
+
- [delta](https://github.com/dandavison/delta) - 语法高亮的 git diff 查看器
|
|
217
204
|
- [@opencode-ai/plugin](https://www.npmjs.com/package/@opencode-ai/plugin) - OpenCode 插件 SDK
|
|
218
205
|
|
|
219
206
|
## License
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { tool } from "@opencode-ai/plugin";
|
|
2
|
-
/**
|
|
3
|
-
* OpenCode Diff Viewer Plugin
|
|
4
|
-
* Uses lumen (https://github.com/jnsahaj/lumen) for visual git diffs.
|
|
5
|
-
* Automatically installs lumen if not present.
|
|
6
|
-
*/
|
|
7
2
|
export const DiffViewerPlugin = async ({ project, client, $, directory, worktree }) => {
|
|
8
|
-
const
|
|
3
|
+
const isDeltaInstalled = async () => {
|
|
9
4
|
try {
|
|
10
|
-
await $ `which
|
|
5
|
+
await $ `which delta`;
|
|
11
6
|
return true;
|
|
12
7
|
}
|
|
13
8
|
catch {
|
|
@@ -32,10 +27,10 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
|
|
|
32
27
|
return false;
|
|
33
28
|
}
|
|
34
29
|
};
|
|
35
|
-
const
|
|
30
|
+
const installDelta = async () => {
|
|
36
31
|
if (await isBrewInstalled()) {
|
|
37
32
|
try {
|
|
38
|
-
await $ `brew install
|
|
33
|
+
await $ `brew install delta`;
|
|
39
34
|
return { success: true, method: "brew" };
|
|
40
35
|
}
|
|
41
36
|
catch (e) {
|
|
@@ -44,7 +39,7 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
|
|
|
44
39
|
}
|
|
45
40
|
if (await isCargoInstalled()) {
|
|
46
41
|
try {
|
|
47
|
-
await $ `cargo install
|
|
42
|
+
await $ `cargo install delta`;
|
|
48
43
|
return { success: true, method: "cargo" };
|
|
49
44
|
}
|
|
50
45
|
catch (e) {
|
|
@@ -53,20 +48,20 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
|
|
|
53
48
|
}
|
|
54
49
|
return {
|
|
55
50
|
success: false,
|
|
56
|
-
error: "Neither brew nor cargo available. Please install
|
|
51
|
+
error: "Neither brew nor cargo available. Please install delta manually:\n brew install dandavison/delta/delta\n # or\n cargo install delta"
|
|
57
52
|
};
|
|
58
53
|
};
|
|
59
|
-
const
|
|
60
|
-
if (await
|
|
54
|
+
const ensureDeltaInstalled = async () => {
|
|
55
|
+
if (await isDeltaInstalled()) {
|
|
61
56
|
return { installed: true };
|
|
62
57
|
}
|
|
63
|
-
const result = await
|
|
58
|
+
const result = await installDelta();
|
|
64
59
|
if (result.success) {
|
|
65
|
-
return { installed: true, message: `✅
|
|
60
|
+
return { installed: true, message: `✅ delta installed via ${result.method}` };
|
|
66
61
|
}
|
|
67
62
|
return { installed: false, message: `❌ ${result.error}` };
|
|
68
63
|
};
|
|
69
|
-
await
|
|
64
|
+
await ensureDeltaInstalled();
|
|
70
65
|
const getModifiedFiles = async () => {
|
|
71
66
|
try {
|
|
72
67
|
const unstaged = await $ `git diff --name-only`.text();
|
|
@@ -81,47 +76,45 @@ export const DiffViewerPlugin = async ({ project, client, $, directory, worktree
|
|
|
81
76
|
return [];
|
|
82
77
|
}
|
|
83
78
|
};
|
|
84
|
-
const
|
|
85
|
-
if (!await
|
|
86
|
-
return
|
|
79
|
+
const showDiff = async (files) => {
|
|
80
|
+
if (!await isDeltaInstalled()) {
|
|
81
|
+
return `❌ delta is not installed.
|
|
82
|
+
|
|
83
|
+
To install:
|
|
84
|
+
brew install dandavison/delta/delta
|
|
85
|
+
# or
|
|
86
|
+
cargo install delta
|
|
87
|
+
|
|
88
|
+
Then restart OpenCode.`;
|
|
87
89
|
}
|
|
88
90
|
const modifiedFiles = files && files.length > 0 ? files : await getModifiedFiles();
|
|
89
91
|
if (modifiedFiles.length === 0) {
|
|
90
|
-
return "📝 No modified files
|
|
92
|
+
return "📝 No modified files.\n\nRun \`git add .\` to stage changes first.";
|
|
91
93
|
}
|
|
92
|
-
const platform = process.platform;
|
|
93
|
-
const fileArgs = modifiedFiles.map(f => `"${f}"`).join(' ');
|
|
94
|
-
const cmd = `cd "${directory}" && lumen diff ${fileArgs}`;
|
|
95
94
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
// Get diff output with delta
|
|
96
|
+
let diffOutput = "";
|
|
97
|
+
// Show staged diff
|
|
98
|
+
const stagedDiff = await $ `cd "${directory}" && git diff --staged`.text();
|
|
99
|
+
if (stagedDiff.trim()) {
|
|
100
|
+
diffOutput += "=== STAGED CHANGES ===\n\n";
|
|
101
|
+
diffOutput += await $ `cd "${directory}" && git diff --staged | delta --pager=never`.text();
|
|
98
102
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
await $ `which xterm && xterm -e "bash -c '${cmd}; read -p Press Enter to close...'" `;
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
return `❌ No terminal emulator found (gnome-terminal/xterm).\n\nPlease run manually:\n ${cmd}`;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
103
|
+
// Show unstaged diff
|
|
104
|
+
const unstagedDiff = await $ `cd "${directory}" && git diff`.text();
|
|
105
|
+
if (unstagedDiff.trim()) {
|
|
106
|
+
if (diffOutput)
|
|
107
|
+
diffOutput += "\n=== UNSTAGED CHANGES ===\n\n";
|
|
108
|
+
diffOutput += await $ `cd "${directory}" && git diff | delta --pager=never`.text();
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
if (!diffOutput.trim()) {
|
|
111
|
+
return "📝 No changes to show.";
|
|
114
112
|
}
|
|
115
|
-
|
|
116
|
-
${modifiedFiles.
|
|
117
|
-
|
|
118
|
-
Keybindings:
|
|
119
|
-
j/k or ↑/↓: Navigate {/}: Jump between hunks
|
|
120
|
-
tab: Toggle sidebar e: Open in editor
|
|
121
|
-
q: Quit`;
|
|
113
|
+
const fileList = modifiedFiles.map(f => ` • ${f}`).join('\n');
|
|
114
|
+
return `✅ Modified files (${modifiedFiles.length}):\n${fileList}\n\n${diffOutput}`;
|
|
122
115
|
}
|
|
123
|
-
catch (
|
|
124
|
-
return `❌
|
|
116
|
+
catch (e) {
|
|
117
|
+
return `❌ Error showing diff: ${e.message || e}`;
|
|
125
118
|
}
|
|
126
119
|
};
|
|
127
120
|
return {
|
|
@@ -129,7 +122,7 @@ Keybindings:
|
|
|
129
122
|
if (input.command === "diff") {
|
|
130
123
|
const files = input.args?.trim() ? [input.args.trim()] : undefined;
|
|
131
124
|
output.handled = true;
|
|
132
|
-
output.result = await
|
|
125
|
+
output.result = await showDiff(files);
|
|
133
126
|
}
|
|
134
127
|
},
|
|
135
128
|
"file.edited": async ({ event }) => {
|
|
@@ -137,12 +130,12 @@ Keybindings:
|
|
|
137
130
|
},
|
|
138
131
|
tool: {
|
|
139
132
|
view_diff: tool({
|
|
140
|
-
description: "
|
|
133
|
+
description: "Show git diff with syntax highlighting using delta.",
|
|
141
134
|
args: {
|
|
142
|
-
file: tool.schema.string().optional().describe("Optional: specific file path
|
|
135
|
+
file: tool.schema.string().optional().describe("Optional: specific file path"),
|
|
143
136
|
},
|
|
144
137
|
async execute(args, ctx) {
|
|
145
|
-
return await
|
|
138
|
+
return await showDiff(args.file ? [args.file] : undefined);
|
|
146
139
|
},
|
|
147
140
|
}),
|
|
148
141
|
},
|