@morphllm/morphsdk 0.2.102 → 0.2.103
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/dist/chunk-2MAUPERG.js +129 -0
- package/dist/chunk-2MAUPERG.js.map +1 -0
- package/dist/{chunk-QH4BSXOD.js → chunk-4CZPXV6R.js} +8 -7
- package/dist/chunk-4CZPXV6R.js.map +1 -0
- package/dist/{chunk-AIXF4GQC.js → chunk-AFLEE2PO.js} +2 -2
- package/dist/{chunk-CP4NZGRY.js → chunk-EMMSRY32.js} +3 -3
- package/dist/chunk-EMMSRY32.js.map +1 -0
- package/dist/{chunk-QZNGKOCZ.js → chunk-HDRLLCAD.js} +4 -4
- package/dist/{chunk-BKIM7SNY.js → chunk-I3IN742Q.js} +4 -4
- package/dist/{chunk-7UYDS6OX.js → chunk-KQP6ZPYB.js} +4 -4
- package/dist/{chunk-OTPYEYMZ.js → chunk-MY4OU4ON.js} +2 -2
- package/dist/{chunk-UBX7QYBD.js → chunk-O5DA5V5S.js} +4 -4
- package/dist/{chunk-GJU7UOFL.js → chunk-OUEJ6XEO.js} +4 -4
- package/dist/{chunk-L5WXPMCH.js → chunk-QUIGATZE.js} +2 -2
- package/dist/chunk-TLC3QKE6.js +114 -0
- package/dist/chunk-TLC3QKE6.js.map +1 -0
- package/dist/{chunk-4J6NACK2.js → chunk-Y2OTK5WC.js} +15 -15
- package/dist/{chunk-4KMBU6T3.js → chunk-YJZP5ZL5.js} +4 -4
- package/dist/{chunk-76DJEQEP.js → chunk-ZRLEAPZV.js} +4 -4
- package/dist/{chunk-BGEEES52.js → chunk-ZROQPUCQ.js} +7 -7
- package/dist/client.cjs +2922 -2840
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +18 -21
- package/dist/edge.cjs +437 -0
- package/dist/edge.cjs.map +1 -0
- package/dist/edge.d.ts +5 -0
- package/dist/edge.js +25 -0
- package/dist/edge.js.map +1 -0
- package/dist/index.cjs +1981 -1888
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +28 -26
- package/dist/modelrouter/core.cjs +2 -2
- package/dist/modelrouter/core.cjs.map +1 -1
- package/dist/modelrouter/core.js +1 -1
- package/dist/modelrouter/index.cjs +2 -2
- package/dist/modelrouter/index.cjs.map +1 -1
- package/dist/modelrouter/index.js +1 -1
- package/dist/tools/browser/index.js +3 -3
- package/dist/tools/codebase_search/anthropic.js +2 -2
- package/dist/tools/codebase_search/index.js +6 -6
- package/dist/tools/codebase_search/openai.js +2 -2
- package/dist/tools/codebase_search/vercel.js +2 -2
- package/dist/tools/fastapply/anthropic.cjs +109 -40
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +3 -2
- package/dist/tools/fastapply/apply.cjs +227 -0
- package/dist/tools/fastapply/apply.cjs.map +1 -0
- package/dist/tools/fastapply/apply.d.ts +59 -0
- package/dist/tools/fastapply/apply.js +15 -0
- package/dist/tools/fastapply/apply.js.map +1 -0
- package/dist/tools/fastapply/core.cjs +156 -116
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.d.ts +5 -41
- package/dist/tools/fastapply/core.js +6 -2
- package/dist/tools/fastapply/index.cjs +113 -76
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.d.ts +2 -1
- package/dist/tools/fastapply/index.js +11 -9
- package/dist/tools/fastapply/openai.cjs +110 -41
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +3 -2
- package/dist/tools/fastapply/vercel.cjs +110 -41
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +3 -2
- package/dist/tools/index.cjs +113 -76
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +11 -9
- package/dist/tools/warp_grep/agent/runner.js +3 -3
- package/dist/tools/warp_grep/anthropic.cjs +549 -500
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +5 -9
- package/dist/tools/warp_grep/client.cjs +550 -501
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.js +4 -8
- package/dist/tools/warp_grep/gemini.cjs +549 -500
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.js +4 -8
- package/dist/tools/warp_grep/gemini.js.map +1 -1
- package/dist/tools/warp_grep/harness.js +12 -12
- package/dist/tools/warp_grep/index.cjs +559 -501
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +12 -12
- package/dist/tools/warp_grep/openai.cjs +549 -500
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +5 -9
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/vercel.cjs +549 -500
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +5 -9
- package/package.json +7 -2
- package/dist/chunk-CKTA4AXM.js +0 -233
- package/dist/chunk-CKTA4AXM.js.map +0 -1
- package/dist/chunk-CP4NZGRY.js.map +0 -1
- package/dist/chunk-QH4BSXOD.js.map +0 -1
- /package/dist/{chunk-AIXF4GQC.js.map → chunk-AFLEE2PO.js.map} +0 -0
- /package/dist/{chunk-QZNGKOCZ.js.map → chunk-HDRLLCAD.js.map} +0 -0
- /package/dist/{chunk-BKIM7SNY.js.map → chunk-I3IN742Q.js.map} +0 -0
- /package/dist/{chunk-7UYDS6OX.js.map → chunk-KQP6ZPYB.js.map} +0 -0
- /package/dist/{chunk-OTPYEYMZ.js.map → chunk-MY4OU4ON.js.map} +0 -0
- /package/dist/{chunk-UBX7QYBD.js.map → chunk-O5DA5V5S.js.map} +0 -0
- /package/dist/{chunk-GJU7UOFL.js.map → chunk-OUEJ6XEO.js.map} +0 -0
- /package/dist/{chunk-L5WXPMCH.js.map → chunk-QUIGATZE.js.map} +0 -0
- /package/dist/{chunk-4J6NACK2.js.map → chunk-Y2OTK5WC.js.map} +0 -0
- /package/dist/{chunk-4KMBU6T3.js.map → chunk-YJZP5ZL5.js.map} +0 -0
- /package/dist/{chunk-76DJEQEP.js.map → chunk-ZRLEAPZV.js.map} +0 -0
- /package/dist/{chunk-BGEEES52.js.map → chunk-ZROQPUCQ.js.map} +0 -0
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,30 +20,17 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
20
|
-
// tools/fastapply/core.ts
|
|
21
|
-
var core_exports = {};
|
|
22
|
-
__export(core_exports, {
|
|
23
|
-
FastApplyClient: () => FastApplyClient,
|
|
24
|
-
applyEdit: () => applyEdit,
|
|
25
|
-
countChanges: () => countChanges,
|
|
26
|
-
executeEditFile: () => executeEditFile,
|
|
27
|
-
generateUdiff: () => generateUdiff
|
|
28
|
-
});
|
|
29
|
-
module.exports = __toCommonJS(core_exports);
|
|
30
|
-
var import_promises = require("fs/promises");
|
|
31
|
-
var import_path = require("path");
|
|
32
|
-
var import_diff = require("diff");
|
|
33
|
-
|
|
34
33
|
// tools/utils/resilience.ts
|
|
35
|
-
var DEFAULT_RETRY_CONFIG = {
|
|
36
|
-
maxRetries: 3,
|
|
37
|
-
initialDelay: 1e3,
|
|
38
|
-
maxDelay: 3e4,
|
|
39
|
-
backoffMultiplier: 2,
|
|
40
|
-
retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
|
|
41
|
-
};
|
|
42
34
|
async function fetchWithRetry(url, options, retryConfig = {}) {
|
|
43
35
|
const {
|
|
44
36
|
maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
|
|
@@ -104,63 +96,28 @@ async function withTimeout(promise, timeoutMs, errorMessage) {
|
|
|
104
96
|
function sleep(ms) {
|
|
105
97
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
106
98
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
var FastApplyClient = class {
|
|
118
|
-
config;
|
|
119
|
-
constructor(config = {}) {
|
|
120
|
-
this.config = {
|
|
121
|
-
morphApiKey: config.apiKey,
|
|
122
|
-
morphApiUrl: DEFAULT_CONFIG.morphApiUrl,
|
|
123
|
-
debug: config.debug,
|
|
124
|
-
timeout: config.timeout || DEFAULT_CONFIG.timeout,
|
|
125
|
-
retryConfig: config.retryConfig,
|
|
126
|
-
generateUdiff: DEFAULT_CONFIG.generateUdiff,
|
|
127
|
-
autoWrite: DEFAULT_CONFIG.autoWrite
|
|
99
|
+
var DEFAULT_RETRY_CONFIG;
|
|
100
|
+
var init_resilience = __esm({
|
|
101
|
+
"tools/utils/resilience.ts"() {
|
|
102
|
+
"use strict";
|
|
103
|
+
DEFAULT_RETRY_CONFIG = {
|
|
104
|
+
maxRetries: 3,
|
|
105
|
+
initialDelay: 1e3,
|
|
106
|
+
maxDelay: 3e4,
|
|
107
|
+
backoffMultiplier: 2,
|
|
108
|
+
retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
|
|
128
109
|
};
|
|
129
110
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Apply an edit to code directly without file I/O
|
|
142
|
-
*
|
|
143
|
-
* Useful for sandbox environments or when you manage your own file system.
|
|
144
|
-
* Compatible with the earlier OpenAI client API contract.
|
|
145
|
-
*
|
|
146
|
-
* @param input - Code and edit parameters
|
|
147
|
-
* @param overrides - Optional config overrides for this operation
|
|
148
|
-
* @returns Result with merged code
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```typescript
|
|
152
|
-
* const result = await client.applyEdit({
|
|
153
|
-
* originalCode: 'function hello() { return "world"; }',
|
|
154
|
-
* codeEdit: 'function hello() { return "universe"; }',
|
|
155
|
-
* instructions: 'Change return value'
|
|
156
|
-
* });
|
|
157
|
-
* console.log(result.mergedCode);
|
|
158
|
-
* ```
|
|
159
|
-
*/
|
|
160
|
-
async applyEdit(input, overrides) {
|
|
161
|
-
return applyEdit(input, { ...this.config, ...overrides });
|
|
162
|
-
}
|
|
163
|
-
};
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// tools/fastapply/apply.ts
|
|
114
|
+
var apply_exports = {};
|
|
115
|
+
__export(apply_exports, {
|
|
116
|
+
applyEdit: () => applyEdit,
|
|
117
|
+
callMorphAPI: () => callMorphAPI,
|
|
118
|
+
countChanges: () => countChanges,
|
|
119
|
+
generateUdiff: () => generateUdiff
|
|
120
|
+
});
|
|
164
121
|
function generateUdiff(original, modified, filepath) {
|
|
165
122
|
return (0, import_diff.createTwoFilesPatch)(
|
|
166
123
|
filepath,
|
|
@@ -191,9 +148,9 @@ function countChanges(original, modified) {
|
|
|
191
148
|
};
|
|
192
149
|
}
|
|
193
150
|
async function callMorphAPI(originalCode, codeEdit, instructions, filepath, config) {
|
|
194
|
-
const apiKey = config.morphApiKey || process.env
|
|
195
|
-
const apiUrl = config.morphApiUrl ||
|
|
196
|
-
const timeout = config.timeout ||
|
|
151
|
+
const apiKey = config.morphApiKey || (typeof process !== "undefined" ? process.env?.MORPH_API_KEY : void 0);
|
|
152
|
+
const apiUrl = config.morphApiUrl || DEFAULT_API_URL;
|
|
153
|
+
const timeout = config.timeout || DEFAULT_TIMEOUT;
|
|
197
154
|
const debug = config.debug || false;
|
|
198
155
|
if (!apiKey) {
|
|
199
156
|
throw new Error(
|
|
@@ -241,6 +198,118 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
|
|
|
241
198
|
}
|
|
242
199
|
return data.choices[0].message.content;
|
|
243
200
|
}
|
|
201
|
+
async function applyEdit(input, config = {}) {
|
|
202
|
+
const debug = config.debug || false;
|
|
203
|
+
const filepath = input.filepath || "file";
|
|
204
|
+
try {
|
|
205
|
+
if (debug) {
|
|
206
|
+
console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);
|
|
207
|
+
}
|
|
208
|
+
const mergedCode = await callMorphAPI(
|
|
209
|
+
input.originalCode,
|
|
210
|
+
input.codeEdit,
|
|
211
|
+
input.instructions,
|
|
212
|
+
filepath,
|
|
213
|
+
config
|
|
214
|
+
);
|
|
215
|
+
const udiff = config.generateUdiff !== false ? generateUdiff(input.originalCode, mergedCode, filepath) : void 0;
|
|
216
|
+
const changes = countChanges(input.originalCode, mergedCode);
|
|
217
|
+
return {
|
|
218
|
+
success: true,
|
|
219
|
+
mergedCode,
|
|
220
|
+
udiff,
|
|
221
|
+
changes
|
|
222
|
+
};
|
|
223
|
+
} catch (error) {
|
|
224
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
225
|
+
if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },
|
|
229
|
+
error: errorMessage
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
var import_diff, DEFAULT_API_URL, DEFAULT_TIMEOUT;
|
|
234
|
+
var init_apply = __esm({
|
|
235
|
+
"tools/fastapply/apply.ts"() {
|
|
236
|
+
"use strict";
|
|
237
|
+
import_diff = require("diff");
|
|
238
|
+
init_resilience();
|
|
239
|
+
DEFAULT_API_URL = "https://api.morphllm.com";
|
|
240
|
+
DEFAULT_TIMEOUT = 3e4;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// tools/fastapply/core.ts
|
|
245
|
+
var core_exports = {};
|
|
246
|
+
__export(core_exports, {
|
|
247
|
+
FastApplyClient: () => FastApplyClient,
|
|
248
|
+
applyEdit: () => applyEdit,
|
|
249
|
+
callMorphAPI: () => callMorphAPI,
|
|
250
|
+
countChanges: () => countChanges,
|
|
251
|
+
executeEditFile: () => executeEditFile,
|
|
252
|
+
generateUdiff: () => generateUdiff
|
|
253
|
+
});
|
|
254
|
+
module.exports = __toCommonJS(core_exports);
|
|
255
|
+
var import_path = require("path");
|
|
256
|
+
init_apply();
|
|
257
|
+
var DEFAULT_CONFIG = {
|
|
258
|
+
morphApiUrl: "https://api.morphllm.com",
|
|
259
|
+
baseDir: process.cwd(),
|
|
260
|
+
generateUdiff: true,
|
|
261
|
+
autoWrite: true,
|
|
262
|
+
timeout: 3e4,
|
|
263
|
+
debug: false
|
|
264
|
+
};
|
|
265
|
+
var FastApplyClient = class {
|
|
266
|
+
config;
|
|
267
|
+
constructor(config = {}) {
|
|
268
|
+
this.config = {
|
|
269
|
+
morphApiKey: config.apiKey,
|
|
270
|
+
morphApiUrl: DEFAULT_CONFIG.morphApiUrl,
|
|
271
|
+
debug: config.debug,
|
|
272
|
+
timeout: config.timeout || DEFAULT_CONFIG.timeout,
|
|
273
|
+
retryConfig: config.retryConfig,
|
|
274
|
+
generateUdiff: DEFAULT_CONFIG.generateUdiff,
|
|
275
|
+
autoWrite: DEFAULT_CONFIG.autoWrite
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Execute a file edit operation
|
|
280
|
+
*
|
|
281
|
+
* @param input - Edit parameters including filepath, instructions, and code_edit
|
|
282
|
+
* @param overrides - Optional config overrides for this operation
|
|
283
|
+
* @returns Edit result with success status and changes
|
|
284
|
+
*/
|
|
285
|
+
async execute(input, overrides) {
|
|
286
|
+
return executeEditFile(input, { ...this.config, ...overrides });
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Apply an edit to code directly without file I/O
|
|
290
|
+
*
|
|
291
|
+
* Useful for sandbox environments or when you manage your own file system.
|
|
292
|
+
* Compatible with the earlier OpenAI client API contract.
|
|
293
|
+
*
|
|
294
|
+
* @param input - Code and edit parameters
|
|
295
|
+
* @param overrides - Optional config overrides for this operation
|
|
296
|
+
* @returns Result with merged code
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* const result = await client.applyEdit({
|
|
301
|
+
* originalCode: 'function hello() { return "world"; }',
|
|
302
|
+
* codeEdit: 'function hello() { return "universe"; }',
|
|
303
|
+
* instructions: 'Change return value'
|
|
304
|
+
* });
|
|
305
|
+
* console.log(result.mergedCode);
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
async applyEdit(input, overrides) {
|
|
309
|
+
const { applyEdit: applyEdit2 } = await Promise.resolve().then(() => (init_apply(), apply_exports));
|
|
310
|
+
return applyEdit2(input, { ...this.config, ...overrides });
|
|
311
|
+
}
|
|
312
|
+
};
|
|
244
313
|
async function executeEditFile(input, config = {}) {
|
|
245
314
|
const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;
|
|
246
315
|
const fullPath = (0, import_path.resolve)((0, import_path.join)(baseDir, input.target_filepath));
|
|
@@ -256,22 +325,24 @@ async function executeEditFile(input, config = {}) {
|
|
|
256
325
|
}
|
|
257
326
|
try {
|
|
258
327
|
if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);
|
|
328
|
+
const { readFile, writeFile } = await import("fs/promises");
|
|
329
|
+
const { callMorphAPI: callMorphAPI2, generateUdiff: generateUdiff2, countChanges: countChanges2 } = await Promise.resolve().then(() => (init_apply(), apply_exports));
|
|
259
330
|
let originalCode = "";
|
|
260
331
|
try {
|
|
261
|
-
originalCode = await
|
|
332
|
+
originalCode = await readFile(fullPath, "utf-8");
|
|
262
333
|
} catch (error) {
|
|
263
334
|
if (error.code !== "ENOENT") {
|
|
264
335
|
throw error;
|
|
265
336
|
}
|
|
266
337
|
if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);
|
|
267
338
|
}
|
|
268
|
-
const mergedCode = await
|
|
269
|
-
const udiff = config.generateUdiff !== false ?
|
|
339
|
+
const mergedCode = await callMorphAPI2(originalCode, input.code_edit, input.instructions, input.target_filepath, config);
|
|
340
|
+
const udiff = config.generateUdiff !== false ? generateUdiff2(originalCode, mergedCode, input.target_filepath) : void 0;
|
|
270
341
|
if (config.autoWrite !== false) {
|
|
271
|
-
await
|
|
342
|
+
await writeFile(fullPath, mergedCode, "utf-8");
|
|
272
343
|
if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);
|
|
273
344
|
}
|
|
274
|
-
const changes =
|
|
345
|
+
const changes = countChanges2(originalCode, mergedCode);
|
|
275
346
|
return {
|
|
276
347
|
success: true,
|
|
277
348
|
filepath: input.target_filepath,
|
|
@@ -289,42 +360,11 @@ async function executeEditFile(input, config = {}) {
|
|
|
289
360
|
};
|
|
290
361
|
}
|
|
291
362
|
}
|
|
292
|
-
async function applyEdit(input, config = {}) {
|
|
293
|
-
const debug = config.debug || false;
|
|
294
|
-
const filepath = input.filepath || "file";
|
|
295
|
-
try {
|
|
296
|
-
if (debug) {
|
|
297
|
-
console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);
|
|
298
|
-
}
|
|
299
|
-
const mergedCode = await callMorphAPI(
|
|
300
|
-
input.originalCode,
|
|
301
|
-
input.codeEdit,
|
|
302
|
-
input.instructions,
|
|
303
|
-
filepath,
|
|
304
|
-
config
|
|
305
|
-
);
|
|
306
|
-
const udiff = config.generateUdiff !== false ? generateUdiff(input.originalCode, mergedCode, filepath) : void 0;
|
|
307
|
-
const changes = countChanges(input.originalCode, mergedCode);
|
|
308
|
-
return {
|
|
309
|
-
success: true,
|
|
310
|
-
mergedCode,
|
|
311
|
-
udiff,
|
|
312
|
-
changes
|
|
313
|
-
};
|
|
314
|
-
} catch (error) {
|
|
315
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
316
|
-
if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
|
|
317
|
-
return {
|
|
318
|
-
success: false,
|
|
319
|
-
changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },
|
|
320
|
-
error: errorMessage
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
363
|
// Annotate the CommonJS export names for ESM import in node:
|
|
325
364
|
0 && (module.exports = {
|
|
326
365
|
FastApplyClient,
|
|
327
366
|
applyEdit,
|
|
367
|
+
callMorphAPI,
|
|
328
368
|
countChanges,
|
|
329
369
|
executeEditFile,
|
|
330
370
|
generateUdiff
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../tools/fastapply/core.ts","../../../tools/utils/resilience.ts"],"sourcesContent":["/**\n * Core implementation of Morph Fast Apply\n */\n\nimport { readFile, writeFile } from 'fs/promises';\nimport { join, resolve, relative } from 'path';\nimport { createTwoFilesPatch } from 'diff';\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type {\n EditFileInput,\n EditFileResult,\n EditFileConfig,\n EditChanges,\n MorphApplyResponse,\n ApplyEditInput,\n ApplyEditResult,\n ApplyEditConfig,\n} from './types.js';\n\nconst DEFAULT_CONFIG: Required<Omit<EditFileConfig, 'morphApiKey' | 'systemPrompt' | 'retryConfig' | 'description'>> = {\n morphApiUrl: 'https://api.morphllm.com',\n baseDir: process.cwd(),\n generateUdiff: true,\n autoWrite: true,\n timeout: 30000,\n debug: false,\n};\n\n/**\n * FastApply client for programmatic file editing\n */\nexport class FastApplyClient {\n private config: EditFileConfig;\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n morphApiKey: config.apiKey,\n morphApiUrl: DEFAULT_CONFIG.morphApiUrl,\n debug: config.debug,\n timeout: config.timeout || DEFAULT_CONFIG.timeout,\n retryConfig: config.retryConfig,\n generateUdiff: DEFAULT_CONFIG.generateUdiff,\n autoWrite: DEFAULT_CONFIG.autoWrite,\n };\n }\n\n /**\n * Execute a file edit operation\n * \n * @param input - Edit parameters including filepath, instructions, and code_edit\n * @param overrides - Optional config overrides for this operation\n * @returns Edit result with success status and changes\n */\n async execute(input: EditFileInput, overrides?: Partial<EditFileConfig>): Promise<EditFileResult> {\n return executeEditFile(input, { ...this.config, ...overrides });\n }\n\n /**\n * Apply an edit to code directly without file I/O\n * \n * Useful for sandbox environments or when you manage your own file system.\n * Compatible with the earlier OpenAI client API contract.\n * \n * @param input - Code and edit parameters\n * @param overrides - Optional config overrides for this operation\n * @returns Result with merged code\n * \n * @example\n * ```typescript\n * const result = await client.applyEdit({\n * originalCode: 'function hello() { return \"world\"; }',\n * codeEdit: 'function hello() { return \"universe\"; }',\n * instructions: 'Change return value'\n * });\n * console.log(result.mergedCode);\n * ```\n */\n async applyEdit(input: ApplyEditInput, overrides?: Partial<ApplyEditConfig>): Promise<ApplyEditResult> {\n return applyEdit(input, { ...this.config, ...overrides });\n }\n}\n\n/**\n * Generate a unified diff between two strings\n */\nexport function generateUdiff(\n original: string,\n modified: string,\n filepath: string\n): string {\n return createTwoFilesPatch(\n filepath,\n filepath,\n original,\n modified,\n 'Original',\n 'Modified'\n );\n}\n\n/**\n * Count changes from a unified diff\n */\nexport function countChanges(original: string, modified: string): EditChanges {\n const diff = generateUdiff(original, modified, 'file');\n const lines = diff.split('\\n');\n \n let linesAdded = 0;\n let linesRemoved = 0;\n \n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n linesAdded++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n linesRemoved++;\n }\n }\n \n const linesModified = Math.min(linesAdded, linesRemoved);\n \n return {\n linesAdded: linesAdded - linesModified,\n linesRemoved: linesRemoved - linesModified,\n linesModified,\n };\n}\n\n/**\n * Call Morph Apply API to merge code edits\n * Uses OpenAI-compatible chat completions endpoint with XML-formatted message\n */\nasync function callMorphAPI(\n originalCode: string,\n codeEdit: string,\n instructions: string,\n filepath: string,\n config: EditFileConfig\n): Promise<string> {\n const apiKey = config.morphApiKey || process.env.MORPH_API_KEY;\n const apiUrl = config.morphApiUrl || DEFAULT_CONFIG.morphApiUrl;\n const timeout = config.timeout || DEFAULT_CONFIG.timeout;\n const debug = config.debug || false;\n \n if (!apiKey) {\n throw new Error(\n 'Morph API key not found. Set MORPH_API_KEY environment variable or pass morphApiKey in config.'\n );\n }\n \n // Format message with XML tags as per Morph Fast Apply spec\n const message = `<instruction>${instructions}</instruction>\\n<code>${originalCode}</code>\\n<update>${codeEdit}</update>`;\n \n if (debug) {\n console.log(`[FastApply] Calling ${apiUrl}/v1/chat/completions`);\n console.log(`[FastApply] File: ${filepath}, Instructions: ${instructions.slice(0, 60)}...`);\n console.log(`[FastApply] Original: ${originalCode.length} chars, Edit: ${codeEdit.length} chars`);\n }\n \n const startTime = Date.now();\n \n // Fetch with retry and timeout\n const fetchPromise = fetchWithRetry(\n `${apiUrl}/v1/chat/completions`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: 'morph-v3-fast',\n messages: [{ role: 'user', content: message }],\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n timeout,\n `Morph API request timed out after ${timeout}ms`\n );\n \n if (!response.ok) {\n const error = await response.text();\n if (debug) console.error(`[FastApply] API error: ${response.status} - ${error}`);\n throw new Error(`Morph API error (${response.status}): ${error}`);\n }\n \n const data: MorphApplyResponse = await response.json();\n const elapsed = Date.now() - startTime;\n \n if (debug) {\n console.log(`[FastApply] ✅ Success in ${elapsed}ms, merged: ${data.choices[0].message.content.length} chars`);\n }\n \n return data.choices[0].message.content;\n}\n\n/**\n * Execute a file edit using Morph Fast Apply\n */\nexport async function executeEditFile(\n input: EditFileInput,\n config: EditFileConfig = {}\n): Promise<EditFileResult> {\n const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;\n const fullPath = resolve(join(baseDir, input.target_filepath));\n const debug = config.debug || false;\n \n // Security: ensure file is within baseDir\n const relativePath = relative(baseDir, fullPath);\n if (relativePath.startsWith('..') || fullPath === baseDir) {\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`,\n };\n }\n \n try {\n if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);\n \n // Handle both existing and non-existent files\n let originalCode = '';\n try {\n originalCode = await readFile(fullPath, 'utf-8');\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n throw error; // Re-throw if it's not a \"file not found\" error\n }\n // File doesn't exist, proceed with empty content (will create new file)\n if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);\n }\n \n const mergedCode = await callMorphAPI(originalCode, input.code_edit, input.instructions, input.target_filepath, config);\n \n const udiff = config.generateUdiff !== false ? generateUdiff(originalCode, mergedCode, input.target_filepath) : undefined;\n \n if (config.autoWrite !== false) {\n await writeFile(fullPath, mergedCode, 'utf-8');\n if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);\n }\n \n const changes = countChanges(originalCode, mergedCode);\n \n return {\n success: true,\n filepath: input.target_filepath,\n udiff,\n changes,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n \n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n\n/**\n * Apply an edit to code directly without file I/O\n * \n * This is the code-in/code-out API that accepts code content directly\n * and returns the merged result without reading or writing any files.\n * \n * @param input - Code and edit parameters\n * @param config - Optional configuration\n * @returns Result with merged code\n * \n * @example\n * ```typescript\n * import { applyEdit } from '@morphllm/morphsdk';\n * \n * const result = await applyEdit({\n * originalCode: fs.readFileSync('file.ts', 'utf-8'),\n * codeEdit: '// ... existing code ...\\nconst newVar = 42;\\n// ... existing code ...',\n * instructions: 'Add a new variable',\n * filepath: 'file.ts' // optional, for udiff context\n * });\n * \n * if (result.success) {\n * fs.writeFileSync('file.ts', result.mergedCode);\n * }\n * ```\n */\nexport async function applyEdit(\n input: ApplyEditInput,\n config: ApplyEditConfig = {}\n): Promise<ApplyEditResult> {\n const debug = config.debug || false;\n const filepath = input.filepath || 'file';\n\n try {\n if (debug) {\n console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);\n }\n\n const mergedCode = await callMorphAPI(\n input.originalCode,\n input.codeEdit,\n input.instructions,\n filepath,\n config\n );\n\n const udiff = config.generateUdiff !== false\n ? generateUdiff(input.originalCode, mergedCode, filepath)\n : undefined;\n\n const changes = countChanges(input.originalCode, mergedCode);\n\n return {\n success: true,\n mergedCode,\n udiff,\n changes,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n"],"mappings":"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","names":["resolve"]}
|
|
1
|
+
{"version":3,"sources":["../../../tools/utils/resilience.ts","../../../tools/fastapply/apply.ts","../../../tools/fastapply/core.ts"],"sourcesContent":["/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","/**\n * Edge-compatible code application API\n *\n * This module has zero Node.js dependencies and works on:\n * - Cloudflare Workers\n * - Vercel Edge Functions\n * - Deno Deploy\n * - Browser environments\n *\n * For file-based operations, use executeEditFile from core.ts\n */\n\nimport { createTwoFilesPatch } from 'diff';\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type {\n EditChanges,\n MorphApplyResponse,\n ApplyEditInput,\n ApplyEditResult,\n ApplyEditConfig,\n} from './types.js';\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * Generate a unified diff between two strings\n */\nexport function generateUdiff(\n original: string,\n modified: string,\n filepath: string\n): string {\n return createTwoFilesPatch(\n filepath,\n filepath,\n original,\n modified,\n 'Original',\n 'Modified'\n );\n}\n\n/**\n * Count changes from a unified diff\n */\nexport function countChanges(original: string, modified: string): EditChanges {\n const diff = generateUdiff(original, modified, 'file');\n const lines = diff.split('\\n');\n\n let linesAdded = 0;\n let linesRemoved = 0;\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n linesAdded++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n linesRemoved++;\n }\n }\n\n const linesModified = Math.min(linesAdded, linesRemoved);\n\n return {\n linesAdded: linesAdded - linesModified,\n linesRemoved: linesRemoved - linesModified,\n linesModified,\n };\n}\n\n/**\n * Call Morph Apply API to merge code edits\n * Uses OpenAI-compatible chat completions endpoint with XML-formatted message\n */\nexport async function callMorphAPI(\n originalCode: string,\n codeEdit: string,\n instructions: string,\n filepath: string,\n config: ApplyEditConfig\n): Promise<string> {\n const apiKey = config.morphApiKey || (typeof process !== 'undefined' ? process.env?.MORPH_API_KEY : undefined);\n const apiUrl = config.morphApiUrl || DEFAULT_API_URL;\n const timeout = config.timeout || DEFAULT_TIMEOUT;\n const debug = config.debug || false;\n\n if (!apiKey) {\n throw new Error(\n 'Morph API key not found. Set MORPH_API_KEY environment variable or pass morphApiKey in config.'\n );\n }\n\n // Format message with XML tags as per Morph Fast Apply spec\n const message = `<instruction>${instructions}</instruction>\\n<code>${originalCode}</code>\\n<update>${codeEdit}</update>`;\n\n if (debug) {\n console.log(`[FastApply] Calling ${apiUrl}/v1/chat/completions`);\n console.log(`[FastApply] File: ${filepath}, Instructions: ${instructions.slice(0, 60)}...`);\n console.log(`[FastApply] Original: ${originalCode.length} chars, Edit: ${codeEdit.length} chars`);\n }\n\n const startTime = Date.now();\n\n // Fetch with retry and timeout\n const fetchPromise = fetchWithRetry(\n `${apiUrl}/v1/chat/completions`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: 'morph-v3-fast',\n messages: [{ role: 'user', content: message }],\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n timeout,\n `Morph API request timed out after ${timeout}ms`\n );\n\n if (!response.ok) {\n const error = await response.text();\n if (debug) console.error(`[FastApply] API error: ${response.status} - ${error}`);\n throw new Error(`Morph API error (${response.status}): ${error}`);\n }\n\n const data: MorphApplyResponse = await response.json();\n const elapsed = Date.now() - startTime;\n\n if (debug) {\n console.log(`[FastApply] ✅ Success in ${elapsed}ms, merged: ${data.choices[0].message.content.length} chars`);\n }\n\n return data.choices[0].message.content;\n}\n\n/**\n * Apply an edit to code directly without file I/O\n *\n * This is the edge-compatible code-in/code-out API that accepts code content directly\n * and returns the merged result without reading or writing any files.\n *\n * Works on Cloudflare Workers, Vercel Edge Functions, Deno, and browsers.\n *\n * @param input - Code and edit parameters\n * @param config - Optional configuration\n * @returns Result with merged code\n *\n * @example\n * ```typescript\n * import { applyEdit } from '@morphllm/morphsdk';\n *\n * const result = await applyEdit({\n * originalCode: fs.readFileSync('file.ts', 'utf-8'),\n * codeEdit: '// ... existing code ...\\nconst newVar = 42;\\n// ... existing code ...',\n * instructions: 'Add a new variable',\n * filepath: 'file.ts' // optional, for udiff context\n * });\n *\n * if (result.success) {\n * fs.writeFileSync('file.ts', result.mergedCode);\n * }\n * ```\n */\nexport async function applyEdit(\n input: ApplyEditInput,\n config: ApplyEditConfig = {}\n): Promise<ApplyEditResult> {\n const debug = config.debug || false;\n const filepath = input.filepath || 'file';\n\n try {\n if (debug) {\n console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);\n }\n\n const mergedCode = await callMorphAPI(\n input.originalCode,\n input.codeEdit,\n input.instructions,\n filepath,\n config\n );\n\n const udiff = config.generateUdiff !== false\n ? generateUdiff(input.originalCode, mergedCode, filepath)\n : undefined;\n\n const changes = countChanges(input.originalCode, mergedCode);\n\n return {\n success: true,\n mergedCode,\n udiff,\n changes,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n","/**\n * Core implementation of Morph Fast Apply\n *\n * This module provides file-based operations that require Node.js.\n * For edge-compatible code-in/code-out operations, use applyEdit from ./apply.ts\n */\n\nimport { join, resolve, relative } from 'path';\nimport type {\n EditFileInput,\n EditFileResult,\n EditFileConfig,\n} from './types.js';\n\n// Re-export edge-compatible functions\nexport { applyEdit, generateUdiff, countChanges, callMorphAPI } from './apply.js';\n\nconst DEFAULT_CONFIG: Required<Omit<EditFileConfig, 'morphApiKey' | 'systemPrompt' | 'retryConfig' | 'description'>> = {\n morphApiUrl: 'https://api.morphllm.com',\n baseDir: process.cwd(),\n generateUdiff: true,\n autoWrite: true,\n timeout: 30000,\n debug: false,\n};\n\n/**\n * FastApply client for programmatic file editing\n * Note: This client requires Node.js for file operations\n */\nexport class FastApplyClient {\n private config: EditFileConfig;\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n morphApiKey: config.apiKey,\n morphApiUrl: DEFAULT_CONFIG.morphApiUrl,\n debug: config.debug,\n timeout: config.timeout || DEFAULT_CONFIG.timeout,\n retryConfig: config.retryConfig,\n generateUdiff: DEFAULT_CONFIG.generateUdiff,\n autoWrite: DEFAULT_CONFIG.autoWrite,\n };\n }\n\n /**\n * Execute a file edit operation\n *\n * @param input - Edit parameters including filepath, instructions, and code_edit\n * @param overrides - Optional config overrides for this operation\n * @returns Edit result with success status and changes\n */\n async execute(input: EditFileInput, overrides?: Partial<EditFileConfig>): Promise<EditFileResult> {\n return executeEditFile(input, { ...this.config, ...overrides });\n }\n\n /**\n * Apply an edit to code directly without file I/O\n *\n * Useful for sandbox environments or when you manage your own file system.\n * Compatible with the earlier OpenAI client API contract.\n *\n * @param input - Code and edit parameters\n * @param overrides - Optional config overrides for this operation\n * @returns Result with merged code\n *\n * @example\n * ```typescript\n * const result = await client.applyEdit({\n * originalCode: 'function hello() { return \"world\"; }',\n * codeEdit: 'function hello() { return \"universe\"; }',\n * instructions: 'Change return value'\n * });\n * console.log(result.mergedCode);\n * ```\n */\n async applyEdit(input: import('./types.js').ApplyEditInput, overrides?: Partial<import('./types.js').ApplyEditConfig>): Promise<import('./types.js').ApplyEditResult> {\n const { applyEdit } = await import('./apply.js');\n return applyEdit(input, { ...this.config, ...overrides });\n }\n}\n\n/**\n * Execute a file edit using Morph Fast Apply\n * Note: This function requires Node.js for file I/O\n */\nexport async function executeEditFile(\n input: EditFileInput,\n config: EditFileConfig = {}\n): Promise<EditFileResult> {\n const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;\n const fullPath = resolve(join(baseDir, input.target_filepath));\n const debug = config.debug || false;\n\n // Security: ensure file is within baseDir\n const relativePath = relative(baseDir, fullPath);\n if (relativePath.startsWith('..') || fullPath === baseDir) {\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`,\n };\n }\n\n try {\n if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);\n\n // Dynamic import to avoid loading Node.js fs module at module evaluation time\n const { readFile, writeFile } = await import('fs/promises');\n const { callMorphAPI, generateUdiff, countChanges } = await import('./apply.js');\n\n // Handle both existing and non-existent files\n let originalCode = '';\n try {\n originalCode = await readFile(fullPath, 'utf-8');\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n throw error; // Re-throw if it's not a \"file not found\" error\n }\n // File doesn't exist, proceed with empty content (will create new file)\n if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);\n }\n\n const mergedCode = await callMorphAPI(originalCode, input.code_edit, input.instructions, input.target_filepath, config);\n\n const udiff = config.generateUdiff !== false ? generateUdiff(originalCode, mergedCode, input.target_filepath) : undefined;\n\n if (config.autoWrite !== false) {\n await writeFile(fullPath, mergedCode, 'utf-8');\n if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);\n }\n\n const changes = countChanges(originalCode, mergedCode);\n\n return {\n success: true,\n filepath: input.target_filepath,\n udiff,\n changes,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,eAAsB,eACpB,KACA,SACA,cAA2B,CAAC,GACT;AACnB,QAAM;AAAA,IACJ,aAAa,qBAAqB;AAAA,IAClC,eAAe,qBAAqB;AAAA,IACpC,WAAW,qBAAqB;AAAA,IAChC,oBAAoB,qBAAqB;AAAA,IACzC,kBAAkB,qBAAqB;AAAA,IACvC;AAAA,EACF,IAAI;AAEJ,MAAI,YAA0B;AAC9B,MAAI,QAAQ;AAEZ,WAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK,OAAO;AAGzC,UAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AACtD,YAAI,UAAU,YAAY;AAExB,gBAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AACrD,gBAAM,WAAW,aACb,SAAS,UAAU,IAAI,MACvB,KAAK,IAAI,OAAO,QAAQ;AAE5B,gBAAM,QAAQ,IAAI,MAAM,QAAQ,SAAS,MAAM,oBAAoB,QAAQ,IAAI;AAC/E,cAAI,SAAS;AACX,oBAAQ,UAAU,GAAG,KAAK;AAAA,UAC5B;AAEA,gBAAM,MAAM,QAAQ;AACpB,mBAAS;AACT;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,kBAAY;AAGZ,YAAM,cAAc,gBAAgB;AAAA,QAAK,aACvC,WAAW,SAAS,SAAS,OAAO;AAAA,MACtC;AAEA,UAAI,CAAC,eAAe,YAAY,YAAY;AAC1C,cAAM;AAAA,MACR;AAGA,YAAM,WAAW,KAAK,IAAI,OAAO,QAAQ;AACzC,UAAI,SAAS;AACX,gBAAQ,UAAU,GAAG,SAAS;AAAA,MAChC;AAEA,YAAM,MAAM,QAAQ;AACpB,eAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,MAAM,sBAAsB;AACrD;AAmBA,eAAsB,YACpB,SACA,WACA,cACY;AACZ,MAAI;AAEJ,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAC3B,aAAO,IAAI,MAAM,gBAAgB,6BAA6B,SAAS,IAAI,CAAC;AAAA,IAC9E,GAAG,SAAS;AAAA,EACd,CAAC;AAED,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,cAAc,CAAC;AAC3D,iBAAa,SAAU;AACvB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,iBAAa,SAAU;AACvB,UAAM;AAAA,EACR;AACF;AAKA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAAA,aAAW,WAAWA,UAAS,EAAE,CAAC;AACvD;AAvJA,IAaM;AAbN;AAAA;AAAA;AAaA,IAAM,uBAA+D;AAAA,MACnE,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,MACV,mBAAmB;AAAA,MACnB,iBAAiB,CAAC,gBAAgB,aAAa,WAAW;AAAA,IAC5D;AAAA;AAAA;;;ACnBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BO,SAAS,cACd,UACA,UACA,UACQ;AACR,aAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,aAAa,UAAkB,UAA+B;AAC5E,QAAM,OAAO,cAAc,UAAU,UAAU,MAAM;AACrD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAE7B,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GAAG;AACnD;AAAA,IACF,WAAW,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GAAG;AAC1D;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB,KAAK,IAAI,YAAY,YAAY;AAEvD,SAAO;AAAA,IACL,YAAY,aAAa;AAAA,IACzB,cAAc,eAAe;AAAA,IAC7B;AAAA,EACF;AACF;AAMA,eAAsB,aACpB,cACA,UACA,cACA,UACA,QACiB;AACjB,QAAM,SAAS,OAAO,gBAAgB,OAAO,YAAY,cAAc,QAAQ,KAAK,gBAAgB;AACpG,QAAM,SAAS,OAAO,eAAe;AACrC,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,QAAQ,OAAO,SAAS;AAE9B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAU,gBAAgB,YAAY;AAAA,QAAyB,YAAY;AAAA,UAAoB,QAAQ;AAE7G,MAAI,OAAO;AACT,YAAQ,IAAI,uBAAuB,MAAM,sBAAsB;AAC/D,YAAQ,IAAI,qBAAqB,QAAQ,mBAAmB,aAAa,MAAM,GAAG,EAAE,CAAC,KAAK;AAC1F,YAAQ,IAAI,yBAAyB,aAAa,MAAM,iBAAiB,SAAS,MAAM,QAAQ;AAAA,EAClG;AAEA,QAAM,YAAY,KAAK,IAAI;AAG3B,QAAM,eAAe;AAAA,IACnB,GAAG,MAAM;AAAA,IACT;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,iBAAiB,UAAU,MAAM;AAAA,MACnC;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,OAAO;AAAA,QACP,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,QAAQ,CAAC;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,IACA,OAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,IACA,qCAAqC,OAAO;AAAA,EAC9C;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,QAAI,MAAO,SAAQ,MAAM,0BAA0B,SAAS,MAAM,MAAM,KAAK,EAAE;AAC/E,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,EAClE;AAEA,QAAM,OAA2B,MAAM,SAAS,KAAK;AACrD,QAAM,UAAU,KAAK,IAAI,IAAI;AAE7B,MAAI,OAAO;AACT,YAAQ,IAAI,iCAA4B,OAAO,eAAe,KAAK,QAAQ,CAAC,EAAE,QAAQ,QAAQ,MAAM,QAAQ;AAAA,EAC9G;AAEA,SAAO,KAAK,QAAQ,CAAC,EAAE,QAAQ;AACjC;AA8BA,eAAsB,UACpB,OACA,SAA0B,CAAC,GACD;AAC1B,QAAM,QAAQ,OAAO,SAAS;AAC9B,QAAM,WAAW,MAAM,YAAY;AAEnC,MAAI;AACF,QAAI,OAAO;AACT,cAAQ,IAAI,sCAAsC,MAAM,aAAa,MAAM,SAAS;AAAA,IACtF;AAEA,UAAM,aAAa,MAAM;AAAA,MACvB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO,kBAAkB,QACnC,cAAc,MAAM,cAAc,YAAY,QAAQ,IACtD;AAEJ,UAAM,UAAU,aAAa,MAAM,cAAc,UAAU;AAE3D,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,QAAI,MAAO,SAAQ,MAAM,sBAAsB,YAAY,EAAE;AAE7D,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,EAAE;AAAA,MAC5D,OAAO;AAAA,IACT;AAAA,EACF;AACF;AApNA,IAYA,aAUM,iBACA;AAvBN;AAAA;AAAA;AAYA,kBAAoC;AACpC;AASA,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAAA;AAAA;;;ACvBxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,kBAAwC;AAQxC;AAEA,IAAM,iBAAiH;AAAA,EACrH,aAAa;AAAA,EACb,SAAS,QAAQ,IAAI;AAAA,EACrB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAMO,IAAM,kBAAN,MAAsB;AAAA,EACnB;AAAA,EAER,YAAY,SAAoF,CAAC,GAAG;AAClG,SAAK,SAAS;AAAA,MACZ,aAAa,OAAO;AAAA,MACpB,aAAa,eAAe;AAAA,MAC5B,OAAO,OAAO;AAAA,MACd,SAAS,OAAO,WAAW,eAAe;AAAA,MAC1C,aAAa,OAAO;AAAA,MACpB,eAAe,eAAe;AAAA,MAC9B,WAAW,eAAe;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,OAAsB,WAA8D;AAChG,WAAO,gBAAgB,OAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,UAAU,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,UAAU,OAA4C,WAA0G;AACpK,UAAM,EAAE,WAAAC,WAAU,IAAI,MAAM;AAC5B,WAAOA,WAAU,OAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,UAAU,CAAC;AAAA,EAC1D;AACF;AAMA,eAAsB,gBACpB,OACA,SAAyB,CAAC,GACD;AACzB,QAAM,UAAU,OAAO,WAAW,eAAe;AACjD,QAAM,eAAW,yBAAQ,kBAAK,SAAS,MAAM,eAAe,CAAC;AAC7D,QAAM,QAAQ,OAAO,SAAS;AAG9B,QAAM,mBAAe,sBAAS,SAAS,QAAQ;AAC/C,MAAI,aAAa,WAAW,IAAI,KAAK,aAAa,SAAS;AACzD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,MAAM;AAAA,MAChB,SAAS,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,EAAE;AAAA,MAC5D,OAAO,sBAAsB,MAAM,eAAe;AAAA,IACpD;AAAA,EACF;AAEA,MAAI;AACF,QAAI,MAAO,SAAQ,IAAI,6BAA6B,MAAM,eAAe,EAAE;AAG3E,UAAM,EAAE,UAAU,UAAU,IAAI,MAAM,OAAO,aAAa;AAC1D,UAAM,EAAE,cAAAC,eAAc,eAAAC,gBAAe,cAAAC,cAAa,IAAI,MAAM;AAG5D,QAAI,eAAe;AACnB,QAAI;AACF,qBAAe,MAAM,SAAS,UAAU,OAAO;AAAA,IACjD,SAAS,OAAY;AACnB,UAAI,MAAM,SAAS,UAAU;AAC3B,cAAM;AAAA,MACR;AAEA,UAAI,MAAO,SAAQ,IAAI,sDAAsD;AAAA,IAC/E;AAEA,UAAM,aAAa,MAAMF,cAAa,cAAc,MAAM,WAAW,MAAM,cAAc,MAAM,iBAAiB,MAAM;AAEtH,UAAM,QAAQ,OAAO,kBAAkB,QAAQC,eAAc,cAAc,YAAY,MAAM,eAAe,IAAI;AAEhH,QAAI,OAAO,cAAc,OAAO;AAC9B,YAAM,UAAU,UAAU,YAAY,OAAO;AAC7C,UAAI,MAAO,SAAQ,IAAI,qBAAqB,WAAW,MAAM,aAAa,MAAM,eAAe,EAAE;AAAA,IACnG;AAEA,UAAM,UAAUC,cAAa,cAAc,UAAU;AAErD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,QAAI,MAAO,SAAQ,MAAM,sBAAsB,YAAY,EAAE;AAE7D,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,MAAM;AAAA,MAChB,SAAS,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,EAAE;AAAA,MAC5D,OAAO;AAAA,IACT;AAAA,EACF;AACF;","names":["resolve","applyEdit","callMorphAPI","generateUdiff","countChanges"]}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { EditFileInput, EditFileConfig, EditFileResult, ApplyEditInput, ApplyEditConfig, ApplyEditResult
|
|
1
|
+
import { EditFileInput, EditFileConfig, EditFileResult, ApplyEditInput, ApplyEditConfig, ApplyEditResult } from './types.js';
|
|
2
|
+
export { applyEdit, callMorphAPI, countChanges, generateUdiff } from './apply.js';
|
|
2
3
|
import '../utils/resilience.js';
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
-
* Core implementation of Morph Fast Apply
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* FastApply client for programmatic file editing
|
|
7
|
+
* Note: This client requires Node.js for file operations
|
|
10
8
|
*/
|
|
11
9
|
declare class FastApplyClient {
|
|
12
10
|
private config;
|
|
@@ -46,44 +44,10 @@ declare class FastApplyClient {
|
|
|
46
44
|
*/
|
|
47
45
|
applyEdit(input: ApplyEditInput, overrides?: Partial<ApplyEditConfig>): Promise<ApplyEditResult>;
|
|
48
46
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Generate a unified diff between two strings
|
|
51
|
-
*/
|
|
52
|
-
declare function generateUdiff(original: string, modified: string, filepath: string): string;
|
|
53
|
-
/**
|
|
54
|
-
* Count changes from a unified diff
|
|
55
|
-
*/
|
|
56
|
-
declare function countChanges(original: string, modified: string): EditChanges;
|
|
57
47
|
/**
|
|
58
48
|
* Execute a file edit using Morph Fast Apply
|
|
49
|
+
* Note: This function requires Node.js for file I/O
|
|
59
50
|
*/
|
|
60
51
|
declare function executeEditFile(input: EditFileInput, config?: EditFileConfig): Promise<EditFileResult>;
|
|
61
|
-
/**
|
|
62
|
-
* Apply an edit to code directly without file I/O
|
|
63
|
-
*
|
|
64
|
-
* This is the code-in/code-out API that accepts code content directly
|
|
65
|
-
* and returns the merged result without reading or writing any files.
|
|
66
|
-
*
|
|
67
|
-
* @param input - Code and edit parameters
|
|
68
|
-
* @param config - Optional configuration
|
|
69
|
-
* @returns Result with merged code
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* import { applyEdit } from '@morphllm/morphsdk';
|
|
74
|
-
*
|
|
75
|
-
* const result = await applyEdit({
|
|
76
|
-
* originalCode: fs.readFileSync('file.ts', 'utf-8'),
|
|
77
|
-
* codeEdit: '// ... existing code ...\nconst newVar = 42;\n// ... existing code ...',
|
|
78
|
-
* instructions: 'Add a new variable',
|
|
79
|
-
* filepath: 'file.ts' // optional, for udiff context
|
|
80
|
-
* });
|
|
81
|
-
*
|
|
82
|
-
* if (result.success) {
|
|
83
|
-
* fs.writeFileSync('file.ts', result.mergedCode);
|
|
84
|
-
* }
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
declare function applyEdit(input: ApplyEditInput, config?: ApplyEditConfig): Promise<ApplyEditResult>;
|
|
88
52
|
|
|
89
|
-
export { FastApplyClient,
|
|
53
|
+
export { FastApplyClient, executeEditFile };
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FastApplyClient,
|
|
3
|
+
executeEditFile
|
|
4
|
+
} from "../../chunk-TLC3QKE6.js";
|
|
5
|
+
import {
|
|
3
6
|
applyEdit,
|
|
7
|
+
callMorphAPI,
|
|
4
8
|
countChanges,
|
|
5
|
-
executeEditFile,
|
|
6
9
|
generateUdiff
|
|
7
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-2MAUPERG.js";
|
|
8
11
|
import "../../chunk-4VWJFZVS.js";
|
|
9
12
|
import "../../chunk-PZ5AY32C.js";
|
|
10
13
|
export {
|
|
11
14
|
FastApplyClient,
|
|
12
15
|
applyEdit,
|
|
16
|
+
callMorphAPI,
|
|
13
17
|
countChanges,
|
|
14
18
|
executeEditFile,
|
|
15
19
|
generateUdiff
|