opencode-fast-apply 2.1.5 → 2.1.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.
@@ -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;AA2ZvD,eAAO,MAAM,eAAe,EAAE,MA4J7B,CAAA;AAGD,eAAe,eAAe,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;AA0avD,eAAO,MAAM,eAAe,EAAE,MA4J7B,CAAA;AAGD,eAAe,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -18,18 +18,18 @@ const FAST_APPLY_URL = (process.env.FAST_APPLY_URL || "http://localhost:1234/v1"
18
18
  const FAST_APPLY_MODEL = process.env.FAST_APPLY_MODEL || "fastapply-1.5b";
19
19
  const FAST_APPLY_TEMPERATURE = parseFloat(process.env.FAST_APPLY_TEMPERATURE || "0.05");
20
20
  const FAST_APPLY_SYSTEM_PROMPT = "You are a coding assistant that helps merge code updates, ensuring every modification is fully integrated.";
21
- const FAST_APPLY_USER_PROMPT = `Merge all changes from the <<<UPDATE>>> snippet into the <<<CODE>>> below.
21
+ const FAST_APPLY_USER_PROMPT = `Merge all changes from the <update> snippet into the <code> below.
22
22
  - Preserve the code's structure, order, comments, and indentation exactly.
23
- - Output only the updated code, enclosed within <<<UPDATED_CODE>>> and <<</UPDATED_CODE>>> tags.
23
+ - Output only the updated code, enclosed within <updated-code> and </updated-code> tags.
24
24
  - Do not include any additional text, explanations, placeholders, ellipses, or code fences.
25
25
 
26
- <<<CODE>>>{original_code}<<</CODE>>>
26
+ <code>{original_code}</code>
27
27
 
28
- <<<UPDATE>>>{update_snippet}<<</UPDATE>>>
28
+ <update>{update_snippet}</update>
29
29
 
30
30
  Provide the complete updated code.`;
31
- const UPDATED_CODE_START = "<<<UPDATED_CODE>>>";
32
- const UPDATED_CODE_END = "<<</UPDATED_CODE>>>";
31
+ const UPDATED_CODE_START = "<updated-code>";
32
+ const UPDATED_CODE_END = "</updated-code>";
33
33
  const TOOL_INSTRUCTIONS = `**DEFAULT tool for editing existing files. Use INSTEAD of native 'edit' tool.**
34
34
 
35
35
  CRITICAL: For EXISTING files ONLY. Use 'write' for new files.
@@ -97,17 +97,27 @@ function alsoKeepThis() {
97
97
 
98
98
  ## Fallback
99
99
  If API fails, use native \`edit\` tool with exact string matching.`;
100
+ function escapeXmlTags(text) {
101
+ return text
102
+ .replace(/<updated-code>/g, "&lt;updated-code&gt;")
103
+ .replace(/<\/updated-code>/g, "&lt;/updated-code&gt;");
104
+ }
105
+ function unescapeXmlTags(text) {
106
+ return text
107
+ .replace(/&lt;updated-code&gt;/g, "<updated-code>")
108
+ .replace(/&lt;\/updated-code&gt;/g, "</updated-code>");
109
+ }
100
110
  function extractUpdatedCode(raw) {
101
111
  const stripped = raw.trim();
102
112
  const startTag = UPDATED_CODE_START;
103
113
  const endTag = UPDATED_CODE_END;
104
114
  let startIdx = stripped.indexOf(startTag);
105
115
  if (startIdx === -1) {
106
- startIdx = stripped.indexOf("<<<UPDATED_CODE");
116
+ startIdx = stripped.indexOf("<updated-code");
107
117
  if (startIdx !== -1) {
108
- const closeTagIdx = stripped.indexOf(">>>", startIdx);
118
+ const closeTagIdx = stripped.indexOf(">", startIdx);
109
119
  if (closeTagIdx !== -1) {
110
- startIdx = closeTagIdx + 3;
120
+ startIdx = closeTagIdx + 1;
111
121
  }
112
122
  }
113
123
  }
@@ -118,28 +128,28 @@ function extractUpdatedCode(raw) {
118
128
  if (stripped.startsWith("```") && stripped.endsWith("```")) {
119
129
  const lines = stripped.split("\n");
120
130
  if (lines.length >= 2) {
121
- return lines.slice(1, -1).join("\n");
131
+ return unescapeXmlTags(lines.slice(1, -1).join("\n"));
122
132
  }
123
133
  }
124
- return stripped;
134
+ return unescapeXmlTags(stripped);
125
135
  }
126
136
  let endIdx = stripped.indexOf(endTag, startIdx);
127
137
  if (endIdx === -1) {
128
- endIdx = stripped.indexOf("<<</UPDATED_CODE", startIdx);
138
+ endIdx = stripped.indexOf("</updated-code", startIdx);
129
139
  }
130
140
  if (endIdx === -1) {
131
141
  const extracted = stripped.slice(startIdx).trim();
132
- const lastCloseTag = extracted.lastIndexOf("<<<");
142
+ const lastCloseTag = extracted.lastIndexOf("</");
133
143
  if (lastCloseTag !== -1 && extracted.slice(lastCloseTag).toLowerCase().includes("update")) {
134
- return extracted.slice(0, lastCloseTag).trim();
144
+ return unescapeXmlTags(extracted.slice(0, lastCloseTag).trim());
135
145
  }
136
- return extracted;
146
+ return unescapeXmlTags(extracted);
137
147
  }
138
148
  const inner = stripped.substring(startIdx, endIdx);
139
149
  if (!inner || inner.trim().length === 0) {
140
150
  throw new Error("Empty updated-code block");
141
151
  }
142
- return inner;
152
+ return unescapeXmlTags(inner);
143
153
  }
144
154
  function generateUnifiedDiff(filepath, original, modified) {
145
155
  const patch = createTwoFilesPatch(`a/${filepath}`, `b/${filepath}`, original, modified, "", "", { context: 3 });
@@ -219,9 +229,11 @@ async function callFastApply(originalCode, codeEdit, instructions) {
219
229
  };
220
230
  }
221
231
  try {
232
+ const escapedOriginalCode = escapeXmlTags(originalCode);
233
+ const escapedCodeEdit = escapeXmlTags(codeEdit);
222
234
  const userContent = FAST_APPLY_USER_PROMPT
223
- .replace("{original_code}", originalCode)
224
- .replace("{update_snippet}", codeEdit);
235
+ .replace("{original_code}", escapedOriginalCode)
236
+ .replace("{update_snippet}", escapedCodeEdit);
225
237
  const response = await fetch(`${FAST_APPLY_URL}/v1/chat/completions`, {
226
238
  method: "POST",
227
239
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-fast-apply",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
4
4
  "description": "OpenCode plugin for Fast Apply - High-performance code editing with OpenAI-compatible APIs (LM Studio, Ollama)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",