@xinleibird/bridge-opencode 0.2.6 → 0.2.8
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.
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bridge.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
|
+
import type { FilePart, Part } from "@opencode-ai/sdk";
|
|
2
3
|
import crypto from "node:crypto";
|
|
3
4
|
import { access } from "node:fs/promises";
|
|
4
5
|
import { basename, isAbsolute, join } from "node:path";
|
|
@@ -104,12 +105,29 @@ export const BridgePlugin: Plugin = async ({ directory }) => {
|
|
|
104
105
|
pendingByCallID.delete(input.callID);
|
|
105
106
|
|
|
106
107
|
for (const filePath of pending.filePaths) {
|
|
107
|
-
await
|
|
108
|
-
|
|
108
|
+
const before = await checkBuffer(filePath);
|
|
109
|
+
let reloadSucceeded = false;
|
|
110
|
+
try {
|
|
111
|
+
await refreshBuffer(filePath);
|
|
112
|
+
reloadSucceeded = true;
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error(`Failed to reload ${filePath}:`, err);
|
|
115
|
+
} finally {
|
|
116
|
+
if (before.isCurrent) {
|
|
117
|
+
try {
|
|
118
|
+
await sendMessage(
|
|
119
|
+
reloadSucceeded ? "🔄 Reloaded by OpenCode." : "⚠️ Reload failed.",
|
|
120
|
+
reloadSucceeded ? "info" : "warn",
|
|
121
|
+
);
|
|
122
|
+
} catch {
|
|
123
|
+
// non-fatal
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
109
127
|
}
|
|
110
128
|
},
|
|
111
129
|
|
|
112
|
-
"chat.
|
|
130
|
+
"experimental.chat.messages.transform": async (_, output) => {
|
|
113
131
|
let selections: Awaited<ReturnType<typeof getVisualSelections>>;
|
|
114
132
|
try {
|
|
115
133
|
selections = await getVisualSelections();
|
|
@@ -121,8 +139,17 @@ export const BridgePlugin: Plugin = async ({ directory }) => {
|
|
|
121
139
|
const filteredSelections = selections.filter((s) => !s.cwd || s.cwd === cwd);
|
|
122
140
|
if (filteredSelections.length === 0) return;
|
|
123
141
|
|
|
142
|
+
const userMessages = output.messages.filter((m) => m.info.role === "user");
|
|
143
|
+
if (userMessages.length === 0) return;
|
|
144
|
+
|
|
145
|
+
const latestUserMessage = userMessages[userMessages.length - 1];
|
|
146
|
+
const msgInfo = latestUserMessage.info;
|
|
147
|
+
if (!msgInfo || msgInfo.role !== "user") return;
|
|
148
|
+
if (!latestUserMessage.parts) {
|
|
149
|
+
latestUserMessage.parts = [];
|
|
150
|
+
}
|
|
151
|
+
|
|
124
152
|
const refs: string[] = [];
|
|
125
|
-
let attached = 0;
|
|
126
153
|
for (const s of filteredSelections) {
|
|
127
154
|
try {
|
|
128
155
|
await access(s.filePath);
|
|
@@ -131,13 +158,59 @@ export const BridgePlugin: Plugin = async ({ directory }) => {
|
|
|
131
158
|
}
|
|
132
159
|
if (!s.startLine) continue;
|
|
133
160
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
: s.filePath;
|
|
161
|
+
const fileRef = `${s.filePath}:${s.startLine}-${s.endLine}`;
|
|
162
|
+
refs.push(fileRef);
|
|
137
163
|
|
|
138
|
-
const
|
|
164
|
+
const fileName = basename(s.filePath);
|
|
139
165
|
|
|
140
|
-
|
|
166
|
+
const filePart: FilePart = {
|
|
167
|
+
id: crypto.randomUUID(),
|
|
168
|
+
sessionID: msgInfo.sessionID,
|
|
169
|
+
messageID: msgInfo.id,
|
|
170
|
+
type: "file",
|
|
171
|
+
mime: "text/plain",
|
|
172
|
+
filename: fileName,
|
|
173
|
+
url: `file://${s.filePath}?start=${s.startLine}&end=${s.endLine}`,
|
|
174
|
+
source: {
|
|
175
|
+
text: {
|
|
176
|
+
start: 0,
|
|
177
|
+
value: fileRef,
|
|
178
|
+
end: fileRef.length,
|
|
179
|
+
},
|
|
180
|
+
type: "file",
|
|
181
|
+
path: s.filePath,
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
latestUserMessage.parts.push(filePart);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (refs.length === 0) return;
|
|
188
|
+
|
|
189
|
+
const textPart = latestUserMessage.parts.find((p) => p.type === "text") as Part | undefined;
|
|
190
|
+
if (textPart && textPart.type === "text" && typeof textPart.text === "string") {
|
|
191
|
+
textPart.text = `${refs.join("\n")}\n\n${textPart.text}`;
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
"chat.message": async (input, output) => {
|
|
196
|
+
let selections: Awaited<ReturnType<typeof getVisualSelections>>;
|
|
197
|
+
try {
|
|
198
|
+
selections = await getVisualSelections();
|
|
199
|
+
} catch {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (!selections || selections.length === 0) return;
|
|
203
|
+
|
|
204
|
+
const filteredSelections = selections.filter((s) => !s.cwd || s.cwd === cwd);
|
|
205
|
+
if (filteredSelections.length === 0) return;
|
|
206
|
+
|
|
207
|
+
for (const s of filteredSelections) {
|
|
208
|
+
try {
|
|
209
|
+
await access(s.filePath);
|
|
210
|
+
} catch {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (!s.startLine) continue;
|
|
141
214
|
|
|
142
215
|
const fileName = basename(s.filePath);
|
|
143
216
|
|
|
@@ -147,20 +220,11 @@ export const BridgePlugin: Plugin = async ({ directory }) => {
|
|
|
147
220
|
sessionID: input.sessionID,
|
|
148
221
|
messageID: input.messageID ?? "",
|
|
149
222
|
mime: "text/plain",
|
|
150
|
-
filename: fileName
|
|
223
|
+
filename: `${fileName}:${s.startLine}-${s.endLine}`,
|
|
151
224
|
url: `file://${s.filePath}?start=${s.startLine}&end=${s.endLine}`,
|
|
152
225
|
});
|
|
153
|
-
attached++;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (attached === 0) return;
|
|
157
|
-
|
|
158
|
-
const textPart = output.parts.find((p: any) => p.type === "text") as any;
|
|
159
|
-
if (textPart && typeof textPart.text === "string") {
|
|
160
|
-
textPart.text = `${refs.join("\n")}\n\n${textPart.text}`;
|
|
161
226
|
}
|
|
162
227
|
},
|
|
163
228
|
};
|
|
164
229
|
};
|
|
165
|
-
|
|
166
230
|
export default BridgePlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xinleibird/bridge-opencode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,5 +38,8 @@
|
|
|
38
38
|
"aarch64-unknown-linux-gnu"
|
|
39
39
|
]
|
|
40
40
|
}
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@opencode-ai/sdk": "^1.15.12"
|
|
41
44
|
}
|
|
42
45
|
}
|