opencode-fast-apply 2.1.2 → 2.1.3
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 +0 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,16 +20,6 @@ OpenCode plugin for Fast Apply - High-performance code editing with OpenAI-compa
|
|
|
20
20
|
npm install -g opencode-fast-apply
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Or add to your OpenCode config to auto-install:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"plugin": [
|
|
28
|
-
"opencode-fast-apply"
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
23
|
### 2. Configure your API endpoint
|
|
34
24
|
|
|
35
25
|
For **LM Studio** (default):
|
|
@@ -62,7 +52,6 @@ Add to your global config (`~/.config/opencode/opencode.json` or `opencode.jsonc
|
|
|
62
52
|
```json
|
|
63
53
|
{
|
|
64
54
|
"plugin": [
|
|
65
|
-
"opencode-pty",
|
|
66
55
|
"opencode-fast-apply"
|
|
67
56
|
]
|
|
68
57
|
}
|
|
@@ -111,7 +100,6 @@ function validateToken(token) {
|
|
|
111
100
|
| `FAST_APPLY_MODEL` | `fastapply-1.5b` | Model name |
|
|
112
101
|
| `FAST_APPLY_TIMEOUT` | `30000` | Request timeout in ms |
|
|
113
102
|
| `FAST_APPLY_TEMPERATURE` | `0.05` | Temperature (0.0-2.0) |
|
|
114
|
-
| `FAST_APPLY_MAX_TOKENS` | `8000` | Maximum tokens in response |
|
|
115
103
|
|
|
116
104
|
## How It Works
|
|
117
105
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,qBAAqB,CAAA;AAwbvD,eAAO,MAAM,eAAe,EAAE,MA4J7B,CAAA;AAGD,eAAe,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -11,13 +11,13 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
11
11
|
import { createTwoFilesPatch } from "diff";
|
|
12
12
|
import { readFile, writeFile, access } from "fs/promises";
|
|
13
13
|
import { constants } from "fs";
|
|
14
|
+
const sessionParamsCache = new Map();
|
|
14
15
|
// Get API key from environment (set in mcpm/jarvis config)
|
|
15
16
|
const FAST_APPLY_API_KEY = process.env.FAST_APPLY_API_KEY || "optional-api-key";
|
|
16
17
|
const FAST_APPLY_URL = (process.env.FAST_APPLY_URL || "http://localhost:1234/v1").replace(/\/v1\/?$/, "");
|
|
17
18
|
const FAST_APPLY_MODEL = process.env.FAST_APPLY_MODEL || "fastapply-1.5b";
|
|
18
19
|
const FAST_APPLY_TIMEOUT = parseInt(process.env.FAST_APPLY_TIMEOUT || "30000", 10);
|
|
19
20
|
const FAST_APPLY_TEMPERATURE = parseFloat(process.env.FAST_APPLY_TEMPERATURE || "0.05");
|
|
20
|
-
const FAST_APPLY_MAX_TOKENS = parseInt(process.env.FAST_APPLY_MAX_TOKENS || "8000", 10);
|
|
21
21
|
const FAST_APPLY_SYSTEM_PROMPT = "You are a coding assistant that helps merge code updates, ensuring every modification is fully integrated.";
|
|
22
22
|
const FAST_APPLY_USER_PROMPT = `Merge all changes from the <update> snippet into the <code> below.
|
|
23
23
|
- Preserve the code's structure, order, comments, and indentation exactly.
|
|
@@ -191,11 +191,6 @@ function shortenPath(filePath, workingDir) {
|
|
|
191
191
|
}
|
|
192
192
|
return filePath;
|
|
193
193
|
}
|
|
194
|
-
function truncate(str, maxLen = 80) {
|
|
195
|
-
if (str.length <= maxLen)
|
|
196
|
-
return str;
|
|
197
|
-
return str.slice(0, maxLen - 3) + "...";
|
|
198
|
-
}
|
|
199
194
|
function estimateTokens(text) {
|
|
200
195
|
return Math.ceil(text.length / 4);
|
|
201
196
|
}
|
|
@@ -261,7 +256,6 @@ async function callFastApply(originalCode, codeEdit, instructions) {
|
|
|
261
256
|
},
|
|
262
257
|
],
|
|
263
258
|
temperature: FAST_APPLY_TEMPERATURE,
|
|
264
|
-
max_tokens: FAST_APPLY_MAX_TOKENS,
|
|
265
259
|
}),
|
|
266
260
|
signal: controller.signal,
|
|
267
261
|
});
|
|
@@ -302,20 +296,23 @@ async function callFastApply(originalCode, codeEdit, instructions) {
|
|
|
302
296
|
};
|
|
303
297
|
}
|
|
304
298
|
}
|
|
305
|
-
async function
|
|
306
|
-
const
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
299
|
+
async function sendTUIMessage(client, sessionID, message, params) {
|
|
300
|
+
const agent = params.agent || undefined;
|
|
301
|
+
const variant = params.variant || undefined;
|
|
302
|
+
const model = params.providerId && params.modelId
|
|
303
|
+
? {
|
|
304
|
+
providerID: params.providerId,
|
|
305
|
+
modelID: params.modelId,
|
|
306
|
+
}
|
|
307
|
+
: undefined;
|
|
314
308
|
try {
|
|
315
309
|
await client.session.prompt({
|
|
316
310
|
path: { id: sessionID },
|
|
317
311
|
body: {
|
|
318
312
|
noReply: true,
|
|
313
|
+
agent: agent,
|
|
314
|
+
model: model,
|
|
315
|
+
variant: variant,
|
|
319
316
|
parts: [
|
|
320
317
|
{
|
|
321
318
|
type: "text",
|
|
@@ -330,6 +327,29 @@ async function sendTUINotification(client, sessionID, filePath, workingDir, inse
|
|
|
330
327
|
console.error("[fast-apply] Failed to send TUI notification:", error.message);
|
|
331
328
|
}
|
|
332
329
|
}
|
|
330
|
+
async function sendTUINotification(client, sessionID, filePath, workingDir, insertions, deletions, modifiedTokens, params) {
|
|
331
|
+
const shortPath = shortenPath(filePath, workingDir);
|
|
332
|
+
const tokenStr = formatTokenCount(modifiedTokens);
|
|
333
|
+
const message = [
|
|
334
|
+
`▣ Fast Apply | ~${tokenStr} tokens modified`,
|
|
335
|
+
"",
|
|
336
|
+
"Applied changes:",
|
|
337
|
+
`→ ${shortPath}: +${insertions} -${deletions}`
|
|
338
|
+
].join("\n");
|
|
339
|
+
await sendTUIMessage(client, sessionID, message, params);
|
|
340
|
+
}
|
|
341
|
+
async function sendTUIErrorNotification(client, sessionID, filePath, workingDir, errorMessage, params) {
|
|
342
|
+
const shortPath = shortenPath(filePath, workingDir);
|
|
343
|
+
const message = [
|
|
344
|
+
`✗ Fast Apply Error`,
|
|
345
|
+
"",
|
|
346
|
+
`File: ${shortPath}`,
|
|
347
|
+
`Error: ${errorMessage}`,
|
|
348
|
+
"",
|
|
349
|
+
"Fallback: Use native 'edit' tool"
|
|
350
|
+
].join("\n");
|
|
351
|
+
await sendTUIMessage(client, sessionID, message, params);
|
|
352
|
+
}
|
|
333
353
|
export const FastApplyPlugin = async ({ directory, client }) => {
|
|
334
354
|
if (!FAST_APPLY_API_KEY) {
|
|
335
355
|
console.warn("[fast-apply] FAST_APPLY_API_KEY not set - fast_apply_edit tool will be disabled");
|
|
@@ -338,6 +358,14 @@ export const FastApplyPlugin = async ({ directory, client }) => {
|
|
|
338
358
|
console.log(`[fast-apply] Plugin loaded with model: ${FAST_APPLY_MODEL} at ${FAST_APPLY_URL}`);
|
|
339
359
|
}
|
|
340
360
|
return {
|
|
361
|
+
"chat.message": async (input) => {
|
|
362
|
+
sessionParamsCache.set(input.sessionID, {
|
|
363
|
+
agent: input.agent,
|
|
364
|
+
providerId: input.model?.providerID,
|
|
365
|
+
modelId: input.model?.modelID,
|
|
366
|
+
variant: input.variant,
|
|
367
|
+
});
|
|
368
|
+
},
|
|
341
369
|
tool: {
|
|
342
370
|
fast_apply_edit: tool({
|
|
343
371
|
description: TOOL_INSTRUCTIONS,
|
|
@@ -354,6 +382,7 @@ export const FastApplyPlugin = async ({ directory, client }) => {
|
|
|
354
382
|
},
|
|
355
383
|
async execute(args, toolCtx) {
|
|
356
384
|
const { target_filepath, instructions, code_edit } = args;
|
|
385
|
+
const params = sessionParamsCache.get(toolCtx.sessionID) || {};
|
|
357
386
|
// Resolve file path relative to project directory
|
|
358
387
|
const filepath = target_filepath.startsWith("/")
|
|
359
388
|
? target_filepath
|
|
@@ -392,7 +421,9 @@ write({
|
|
|
392
421
|
// Call OpenAI API to merge the edit
|
|
393
422
|
const result = await callFastApply(originalCode, code_edit, instructions);
|
|
394
423
|
if (!result.success || !result.content) {
|
|
395
|
-
|
|
424
|
+
const errorMsg = result.error || "Unknown error";
|
|
425
|
+
await sendTUIErrorNotification(client, toolCtx.sessionID, target_filepath, directory, errorMsg, params);
|
|
426
|
+
return formatErrorOutput(errorMsg, target_filepath, directory);
|
|
396
427
|
}
|
|
397
428
|
const mergedCode = result.content;
|
|
398
429
|
try {
|
|
@@ -400,12 +431,13 @@ write({
|
|
|
400
431
|
}
|
|
401
432
|
catch (err) {
|
|
402
433
|
const error = err;
|
|
434
|
+
await sendTUIErrorNotification(client, toolCtx.sessionID, target_filepath, directory, error.message, params);
|
|
403
435
|
return formatErrorOutput(error.message, target_filepath, directory);
|
|
404
436
|
}
|
|
405
437
|
const diff = generateUnifiedDiff(target_filepath, originalCode, mergedCode);
|
|
406
438
|
const { added, removed } = countChanges(diff);
|
|
407
439
|
const modifiedTokens = estimateTokens(diff);
|
|
408
|
-
await sendTUINotification(client, toolCtx.sessionID, target_filepath, directory, added, removed, modifiedTokens);
|
|
440
|
+
await sendTUINotification(client, toolCtx.sessionID, target_filepath, directory, added, removed, modifiedTokens, params);
|
|
409
441
|
return formatFastApplyResult(target_filepath, directory, added, removed, diff, modifiedTokens);
|
|
410
442
|
},
|
|
411
443
|
}),
|
package/package.json
CHANGED