@morphllm/morphsdk 0.2.162 → 0.2.164

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.
Files changed (172) hide show
  1. package/dist/{chunk-OGMHU4PJ.js → chunk-3HVVQHHX.js} +9 -2
  2. package/dist/chunk-3HVVQHHX.js.map +1 -0
  3. package/dist/{chunk-JVKGSMEF.js → chunk-3NWJ74R4.js} +2 -2
  4. package/dist/{chunk-XUV5B27P.js → chunk-4DDD65QF.js} +2 -2
  5. package/dist/{chunk-DRTPCCEI.js → chunk-4FZXI4FI.js} +2 -2
  6. package/dist/chunk-5AM23TC7.js +42 -0
  7. package/dist/chunk-5AM23TC7.js.map +1 -0
  8. package/dist/{chunk-CNFHKQ42.js → chunk-BFNH475L.js} +2 -2
  9. package/dist/{chunk-ZG3YLRR5.js → chunk-CFCNSELX.js} +8 -2
  10. package/dist/chunk-CFCNSELX.js.map +1 -0
  11. package/dist/{chunk-NKUGRAYU.js → chunk-CRU3FQ54.js} +2 -2
  12. package/dist/{chunk-DXMNKPB6.js → chunk-DKPC5ZVX.js} +2 -2
  13. package/dist/{chunk-PWGBAVQ5.js → chunk-DVCIADH3.js} +2 -2
  14. package/dist/{chunk-LECHLXI4.js → chunk-EAIAZ2GD.js} +17 -6
  15. package/dist/chunk-EAIAZ2GD.js.map +1 -0
  16. package/dist/{chunk-4GQNYJBB.js → chunk-ECELX2KF.js} +9 -12
  17. package/dist/chunk-ECELX2KF.js.map +1 -0
  18. package/dist/{chunk-YRHM3RCQ.js → chunk-EPYCKNQ3.js} +2 -2
  19. package/dist/{chunk-OOE2TKKY.js → chunk-MRYULNMU.js} +12 -21
  20. package/dist/chunk-MRYULNMU.js.map +1 -0
  21. package/dist/{chunk-4U5JFT6X.js → chunk-MVMB6GBY.js} +33 -26
  22. package/dist/{chunk-4U5JFT6X.js.map → chunk-MVMB6GBY.js.map} +1 -1
  23. package/dist/{chunk-UKT3CKC7.js → chunk-N4SSQFYN.js} +2 -2
  24. package/dist/{chunk-7QMX45QD.js → chunk-NKFMGSUH.js} +33 -6
  25. package/dist/chunk-NKFMGSUH.js.map +1 -0
  26. package/dist/{chunk-LZQBVEY2.js → chunk-NMRQWMTH.js} +35 -27
  27. package/dist/chunk-NMRQWMTH.js.map +1 -0
  28. package/dist/{chunk-UVRC4LKZ.js → chunk-Q7XZ6JGW.js} +2 -2
  29. package/dist/{chunk-UZX7SY33.js → chunk-RR7P4SMP.js} +2 -2
  30. package/dist/{chunk-UETFIUIG.js → chunk-VCFUU5TL.js} +2 -2
  31. package/dist/{chunk-5XTA7GCY.js → chunk-VDMF4WWF.js} +2 -2
  32. package/dist/{chunk-YBKT2UOK.js → chunk-XULEBEBX.js} +2 -2
  33. package/dist/{chunk-Y4NYT5L6.js → chunk-YOF3N2EL.js} +11 -26
  34. package/dist/chunk-YOF3N2EL.js.map +1 -0
  35. package/dist/{chunk-4Q6VFODP.js → chunk-ZEEHRQYJ.js} +2 -2
  36. package/dist/{chunk-VQSLLYKE.js → chunk-ZEMLB2KV.js} +2 -2
  37. package/dist/client.cjs +185 -115
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.ts +1 -1
  40. package/dist/client.js +25 -24
  41. package/dist/edge.cjs +83 -50
  42. package/dist/edge.cjs.map +1 -1
  43. package/dist/edge.js +5 -4
  44. package/dist/index.cjs +187 -115
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +29 -28
  48. package/dist/modelrouter/core.cjs +51 -25
  49. package/dist/modelrouter/core.cjs.map +1 -1
  50. package/dist/modelrouter/core.js +4 -3
  51. package/dist/modelrouter/index.cjs +51 -25
  52. package/dist/modelrouter/index.cjs.map +1 -1
  53. package/dist/modelrouter/index.js +4 -3
  54. package/dist/subagents/anthropic.cjs +86 -12
  55. package/dist/subagents/anthropic.cjs.map +1 -1
  56. package/dist/subagents/anthropic.js +5 -4
  57. package/dist/subagents/vercel.cjs +86 -12
  58. package/dist/subagents/vercel.cjs.map +1 -1
  59. package/dist/subagents/vercel.js +5 -4
  60. package/dist/tools/browser/anthropic.cjs +48 -9
  61. package/dist/tools/browser/anthropic.cjs.map +1 -1
  62. package/dist/tools/browser/anthropic.js +6 -5
  63. package/dist/tools/browser/core.cjs +51 -19
  64. package/dist/tools/browser/core.cjs.map +1 -1
  65. package/dist/tools/browser/core.js +5 -4
  66. package/dist/tools/browser/index.cjs +51 -19
  67. package/dist/tools/browser/index.cjs.map +1 -1
  68. package/dist/tools/browser/index.js +10 -9
  69. package/dist/tools/browser/index.js.map +1 -1
  70. package/dist/tools/browser/openai.cjs +48 -9
  71. package/dist/tools/browser/openai.cjs.map +1 -1
  72. package/dist/tools/browser/openai.js +6 -5
  73. package/dist/tools/browser/profiles/core.cjs +7 -1
  74. package/dist/tools/browser/profiles/core.cjs.map +1 -1
  75. package/dist/tools/browser/profiles/core.js +3 -3
  76. package/dist/tools/browser/profiles/index.cjs +7 -1
  77. package/dist/tools/browser/profiles/index.cjs.map +1 -1
  78. package/dist/tools/browser/profiles/index.js +3 -3
  79. package/dist/tools/browser/vercel.cjs +48 -9
  80. package/dist/tools/browser/vercel.cjs.map +1 -1
  81. package/dist/tools/browser/vercel.js +6 -5
  82. package/dist/tools/codebase_search/anthropic.cjs +49 -11
  83. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  84. package/dist/tools/codebase_search/anthropic.js +5 -4
  85. package/dist/tools/codebase_search/core.cjs +49 -11
  86. package/dist/tools/codebase_search/core.cjs.map +1 -1
  87. package/dist/tools/codebase_search/core.js +4 -3
  88. package/dist/tools/codebase_search/index.cjs +49 -11
  89. package/dist/tools/codebase_search/index.cjs.map +1 -1
  90. package/dist/tools/codebase_search/index.js +9 -8
  91. package/dist/tools/codebase_search/openai.cjs +49 -11
  92. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  93. package/dist/tools/codebase_search/openai.js +5 -4
  94. package/dist/tools/codebase_search/vercel.cjs +49 -11
  95. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  96. package/dist/tools/codebase_search/vercel.js +5 -4
  97. package/dist/tools/fastapply/anthropic.cjs +95 -31
  98. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  99. package/dist/tools/fastapply/anthropic.js +5 -4
  100. package/dist/tools/fastapply/apply.cjs +75 -26
  101. package/dist/tools/fastapply/apply.cjs.map +1 -1
  102. package/dist/tools/fastapply/apply.js +3 -2
  103. package/dist/tools/fastapply/core.cjs +95 -31
  104. package/dist/tools/fastapply/core.cjs.map +1 -1
  105. package/dist/tools/fastapply/core.js +4 -3
  106. package/dist/tools/fastapply/index.cjs +95 -31
  107. package/dist/tools/fastapply/index.cjs.map +1 -1
  108. package/dist/tools/fastapply/index.js +9 -8
  109. package/dist/tools/fastapply/openai.cjs +95 -31
  110. package/dist/tools/fastapply/openai.cjs.map +1 -1
  111. package/dist/tools/fastapply/openai.js +5 -4
  112. package/dist/tools/fastapply/vercel.cjs +95 -31
  113. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  114. package/dist/tools/fastapply/vercel.js +5 -4
  115. package/dist/tools/index.cjs +95 -31
  116. package/dist/tools/index.cjs.map +1 -1
  117. package/dist/tools/index.js +9 -8
  118. package/dist/tools/utils/resilience.cjs +7 -1
  119. package/dist/tools/utils/resilience.cjs.map +1 -1
  120. package/dist/tools/utils/resilience.js +2 -2
  121. package/dist/tools/warp_grep/agent/runner.cjs +75 -5
  122. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  123. package/dist/tools/warp_grep/agent/runner.js +3 -2
  124. package/dist/tools/warp_grep/anthropic.cjs +86 -12
  125. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  126. package/dist/tools/warp_grep/anthropic.js +5 -4
  127. package/dist/tools/warp_grep/client.cjs +86 -12
  128. package/dist/tools/warp_grep/client.cjs.map +1 -1
  129. package/dist/tools/warp_grep/client.js +4 -3
  130. package/dist/tools/warp_grep/gemini.cjs +86 -12
  131. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  132. package/dist/tools/warp_grep/gemini.js +4 -3
  133. package/dist/tools/warp_grep/gemini.js.map +1 -1
  134. package/dist/tools/warp_grep/index.cjs +86 -12
  135. package/dist/tools/warp_grep/index.cjs.map +1 -1
  136. package/dist/tools/warp_grep/index.js +4 -3
  137. package/dist/tools/warp_grep/openai.cjs +86 -12
  138. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  139. package/dist/tools/warp_grep/openai.js +5 -4
  140. package/dist/tools/warp_grep/vercel.cjs +86 -12
  141. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  142. package/dist/tools/warp_grep/vercel.d.ts +1 -1
  143. package/dist/tools/warp_grep/vercel.js +5 -4
  144. package/dist/version.cjs +7 -1
  145. package/dist/version.cjs.map +1 -1
  146. package/dist/version.js +1 -1
  147. package/package.json +7 -1
  148. package/dist/chunk-4GQNYJBB.js.map +0 -1
  149. package/dist/chunk-7QMX45QD.js.map +0 -1
  150. package/dist/chunk-LECHLXI4.js.map +0 -1
  151. package/dist/chunk-LZQBVEY2.js.map +0 -1
  152. package/dist/chunk-OGMHU4PJ.js.map +0 -1
  153. package/dist/chunk-OOE2TKKY.js.map +0 -1
  154. package/dist/chunk-Y4NYT5L6.js.map +0 -1
  155. package/dist/chunk-ZG3YLRR5.js.map +0 -1
  156. package/dist/{chunk-JVKGSMEF.js.map → chunk-3NWJ74R4.js.map} +0 -0
  157. package/dist/{chunk-XUV5B27P.js.map → chunk-4DDD65QF.js.map} +0 -0
  158. package/dist/{chunk-DRTPCCEI.js.map → chunk-4FZXI4FI.js.map} +0 -0
  159. package/dist/{chunk-CNFHKQ42.js.map → chunk-BFNH475L.js.map} +0 -0
  160. package/dist/{chunk-NKUGRAYU.js.map → chunk-CRU3FQ54.js.map} +0 -0
  161. package/dist/{chunk-DXMNKPB6.js.map → chunk-DKPC5ZVX.js.map} +0 -0
  162. package/dist/{chunk-PWGBAVQ5.js.map → chunk-DVCIADH3.js.map} +0 -0
  163. package/dist/{chunk-YRHM3RCQ.js.map → chunk-EPYCKNQ3.js.map} +0 -0
  164. package/dist/{chunk-UKT3CKC7.js.map → chunk-N4SSQFYN.js.map} +0 -0
  165. package/dist/{chunk-UVRC4LKZ.js.map → chunk-Q7XZ6JGW.js.map} +0 -0
  166. package/dist/{chunk-UZX7SY33.js.map → chunk-RR7P4SMP.js.map} +0 -0
  167. package/dist/{chunk-UETFIUIG.js.map → chunk-VCFUU5TL.js.map} +0 -0
  168. package/dist/{chunk-5XTA7GCY.js.map → chunk-VDMF4WWF.js.map} +0 -0
  169. package/dist/{chunk-YBKT2UOK.js.map → chunk-XULEBEBX.js.map} +0 -0
  170. package/dist/{chunk-4Q6VFODP.js.map → chunk-ZEEHRQYJ.js.map} +0 -0
  171. package/dist/{chunk-VQSLLYKE.js.map → chunk-ZEMLB2KV.js.map} +0 -0
  172. package/dist/{client-PkB7g9SA.d.ts → client-DsAAqupx.d.ts} +1 -1
package/dist/index.cjs CHANGED
@@ -36,7 +36,7 @@ var init_package = __esm({
36
36
  "package.json"() {
37
37
  package_default = {
38
38
  name: "@morphllm/morphsdk",
39
- version: "0.2.162",
39
+ version: "0.2.164",
40
40
  description: "TypeScript SDK and CLI for Morph Fast Apply integration",
41
41
  type: "module",
42
42
  main: "./dist/index.cjs",
@@ -48,6 +48,11 @@ var init_package = __esm({
48
48
  import: "./dist/index.js",
49
49
  require: "./dist/index.cjs"
50
50
  },
51
+ "./logger": {
52
+ types: "./dist/logger.d.ts",
53
+ import: "./dist/logger.js",
54
+ require: "./dist/logger.cjs"
55
+ },
51
56
  "./edge": {
52
57
  types: "./dist/edge.d.ts",
53
58
  import: "./dist/edge.js",
@@ -206,6 +211,7 @@ var init_package = __esm({
206
211
  "test:browser": "vitest run browser",
207
212
  "test:agent": "npx tsx tests/fullAgentTest.ts",
208
213
  "test:integration": "npx tsx tests/fullIntegrationTest.ts",
214
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
209
215
  "release:patch": "npm version patch && npm publish",
210
216
  "release:minor": "npm version minor && npm publish",
211
217
  "release:major": "npm version major && npm publish"
@@ -283,6 +289,50 @@ var init_version = __esm({
283
289
  }
284
290
  });
285
291
 
292
+ // logger.ts
293
+ var import_fs, MorphLogger, logger;
294
+ var init_logger = __esm({
295
+ "logger.ts"() {
296
+ "use strict";
297
+ import_fs = require("fs");
298
+ MorphLogger = class {
299
+ enabled;
300
+ fileStream;
301
+ constructor() {
302
+ this.enabled = process.env.MORPH_DEBUG === "1" || !!process.env.MORPH_LOG_FILE;
303
+ const f = process.env.MORPH_LOG_FILE;
304
+ this.fileStream = f ? (0, import_fs.createWriteStream)(f, { flags: "a" }) : null;
305
+ }
306
+ debug(component, msg, data) {
307
+ this._log("debug", component, msg, data);
308
+ }
309
+ info(component, msg, data) {
310
+ this._log("info", component, msg, data);
311
+ }
312
+ warn(component, msg, data) {
313
+ this._log("warn", component, msg, data);
314
+ }
315
+ error(component, msg, data) {
316
+ this._log("error", component, msg, data);
317
+ }
318
+ enable() {
319
+ this.enabled = true;
320
+ }
321
+ get isEnabled() {
322
+ return this.enabled;
323
+ }
324
+ _log(level, component, msg, data) {
325
+ if (level !== "error" && !this.enabled) return;
326
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
327
+ const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;
328
+ console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);
329
+ this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...data && { data } }) + "\n");
330
+ }
331
+ };
332
+ logger = new MorphLogger();
333
+ }
334
+ });
335
+
286
336
  // tools/fastapply/apply.ts
287
337
  var apply_exports = {};
288
338
  __export(apply_exports, {
@@ -335,11 +385,14 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
335
385
  const message = `<instruction>${instructions}</instruction>
336
386
  <code>${originalCode}</code>
337
387
  <update>${codeEdit}</update>`;
338
- if (debug) {
339
- console.log(`[FastApply] Calling ${apiUrl}/v1/chat/completions`);
340
- console.log(`[FastApply] File: ${filepath}, Instructions: ${instructions.slice(0, 60)}...`);
341
- console.log(`[FastApply] Original: ${originalCode.length} chars, Edit: ${codeEdit.length} chars`);
342
- }
388
+ logger.debug("FastApply", "http_request", {
389
+ url: `${apiUrl}/v1/chat/completions`,
390
+ model,
391
+ filepath,
392
+ instruction_len: instructions.length,
393
+ original_len: originalCode.length,
394
+ code_edit_len: codeEdit.length
395
+ });
343
396
  const startTime = Date.now();
344
397
  const client = new import_openai.default({
345
398
  apiKey,
@@ -348,30 +401,32 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
348
401
  maxRetries: config.retryConfig?.maxRetries ?? 3,
349
402
  defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
350
403
  });
351
- if (debug) {
352
- console.log(`[FastApply] Using model: ${model}`);
353
- }
354
- const completion = await client.chat.completions.create({
355
- model,
356
- messages: [{ role: "user", content: message }]
357
- });
358
- const content = completion.choices[0]?.message?.content;
359
- if (!content) {
360
- throw new Error("Morph API returned empty response");
361
- }
362
- const elapsed = Date.now() - startTime;
363
- if (debug) {
364
- console.log(`[FastApply] Success in ${elapsed}ms, merged: ${content.length} chars`);
404
+ try {
405
+ const completion = await client.chat.completions.create({
406
+ model,
407
+ messages: [{ role: "user", content: message }]
408
+ });
409
+ const content = completion.choices[0]?.message?.content;
410
+ if (!content) {
411
+ throw new Error("Morph API returned empty response");
412
+ }
413
+ const elapsed = Date.now() - startTime;
414
+ logger.debug("FastApply", "http_response", { status: 200, completion_id: completion.id, content_len: content.length, latency_ms: elapsed });
415
+ return { content, completionId: completion.id };
416
+ } catch (error) {
417
+ const elapsed = Date.now() - startTime;
418
+ logger.error("FastApply", "http_error", {
419
+ status: error?.status || error?.response?.status,
420
+ error: error?.message,
421
+ latency_ms: elapsed
422
+ });
423
+ throw error;
365
424
  }
366
- return { content, completionId: completion.id };
367
425
  }
368
426
  async function applyEdit(input, config = {}) {
369
- const debug = config.debug || false;
370
427
  const filepath = input.filepath || "file";
371
428
  try {
372
- if (debug) {
373
- console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);
374
- }
429
+ logger.debug("FastApply", "apply_edit_start", { original_len: input.originalCode.length, code_edit_len: input.codeEdit.length });
375
430
  const instruction = input.instruction ?? input.instructions ?? "";
376
431
  const { content: mergedCode, completionId } = await callMorphAPI(
377
432
  input.originalCode,
@@ -391,7 +446,7 @@ async function applyEdit(input, config = {}) {
391
446
  };
392
447
  } catch (error) {
393
448
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
394
- if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
449
+ logger.error("FastApply", "apply_edit_error", { error: errorMessage });
395
450
  return {
396
451
  success: false,
397
452
  changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },
@@ -406,6 +461,7 @@ var init_apply = __esm({
406
461
  import_diff = require("diff");
407
462
  import_openai = __toESM(require("openai"), 1);
408
463
  init_version();
464
+ init_logger();
409
465
  DEFAULT_API_URL = "https://api.morphllm.com";
410
466
  DEFAULT_TIMEOUT = 3e4;
411
467
  }
@@ -601,7 +657,7 @@ function toRepoRelative(repoRoot, absPath) {
601
657
  }
602
658
  function isSymlink(p) {
603
659
  try {
604
- const st = import_fs.default.lstatSync(p);
660
+ const st = import_fs2.default.lstatSync(p);
605
661
  return st.isSymbolicLink();
606
662
  } catch {
607
663
  return false;
@@ -624,13 +680,13 @@ function fixPathRepetition(fullPath) {
624
680
  }
625
681
  function isTextualFile(filePath, maxBytes = 2e6) {
626
682
  try {
627
- const st = import_fs.default.statSync(filePath);
683
+ const st = import_fs2.default.statSync(filePath);
628
684
  if (!st.isFile()) return false;
629
685
  if (st.size > maxBytes) return false;
630
- const fd = import_fs.default.openSync(filePath, "r");
686
+ const fd = import_fs2.default.openSync(filePath, "r");
631
687
  const buf = Buffer.alloc(512);
632
- const read = import_fs.default.readSync(fd, buf, 0, buf.length, 0);
633
- import_fs.default.closeSync(fd);
688
+ const read = import_fs2.default.readSync(fd, buf, 0, buf.length, 0);
689
+ import_fs2.default.closeSync(fd);
634
690
  for (let i = 0; i < read; i++) {
635
691
  const c = buf[i];
636
692
  if (c === 0) return false;
@@ -640,11 +696,11 @@ function isTextualFile(filePath, maxBytes = 2e6) {
640
696
  return false;
641
697
  }
642
698
  }
643
- var import_fs, import_path5;
699
+ var import_fs2, import_path5;
644
700
  var init_paths = __esm({
645
701
  "tools/warp_grep/utils/paths.ts"() {
646
702
  "use strict";
647
- import_fs = __toESM(require("fs"), 1);
703
+ import_fs2 = __toESM(require("fs"), 1);
648
704
  import_path5 = __toESM(require("path"), 1);
649
705
  }
650
706
  });
@@ -1027,8 +1083,12 @@ __export(index_exports, {
1027
1083
  module.exports = __toCommonJS(index_exports);
1028
1084
  init_version();
1029
1085
 
1086
+ // client.ts
1087
+ init_logger();
1088
+
1030
1089
  // tools/fastapply/core.ts
1031
1090
  var import_path = require("path");
1091
+ init_logger();
1032
1092
  init_apply();
1033
1093
  var DEFAULT_CONFIG = {
1034
1094
  morphApiUrl: "https://api.morphllm.com",
@@ -1089,9 +1149,10 @@ var FastApplyClient = class {
1089
1149
  async function executeEditFile(input, config = {}) {
1090
1150
  const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;
1091
1151
  const fullPath = (0, import_path.resolve)((0, import_path.join)(baseDir, input.target_filepath));
1092
- const debug = config.debug || false;
1152
+ logger.debug("FastApply", "execute_start", { target_filepath: input.target_filepath, baseDir, autoWrite: config.autoWrite !== false });
1093
1153
  const relativePath = (0, import_path.relative)(baseDir, fullPath);
1094
1154
  if (relativePath.startsWith("..") || fullPath === baseDir) {
1155
+ logger.warn("FastApply", "security_check_failed", { target_filepath: input.target_filepath, relative: relativePath });
1095
1156
  return {
1096
1157
  success: false,
1097
1158
  filepath: input.target_filepath,
@@ -1099,27 +1160,33 @@ async function executeEditFile(input, config = {}) {
1099
1160
  error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`
1100
1161
  };
1101
1162
  }
1163
+ logger.debug("FastApply", "security_check", { resolved: fullPath, relative: relativePath });
1102
1164
  try {
1103
- if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);
1104
1165
  const { readFile, writeFile } = await import("fs/promises");
1105
1166
  const { callMorphAPI: callMorphAPI2, generateUdiff: generateUdiff2, countChanges: countChanges2 } = await Promise.resolve().then(() => (init_apply(), apply_exports));
1106
1167
  let originalCode = "";
1168
+ let fileExists = true;
1107
1169
  try {
1108
1170
  originalCode = await readFile(fullPath, "utf-8");
1171
+ logger.debug("FastApply", "file_read", { path: fullPath, exists: true, size_bytes: originalCode.length });
1109
1172
  } catch (error) {
1110
1173
  if (error.code !== "ENOENT") {
1111
1174
  throw error;
1112
1175
  }
1113
- if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);
1176
+ fileExists = false;
1177
+ logger.debug("FastApply", "file_read", { path: fullPath, exists: false });
1114
1178
  }
1115
1179
  const instruction = input.instruction ?? input.instructions ?? "";
1180
+ logger.debug("FastApply", "api_call", { instruction_len: instruction.length, code_edit_len: input.code_edit.length, original_len: originalCode.length });
1116
1181
  const { content: mergedCode, completionId } = await callMorphAPI2(originalCode, input.code_edit, instruction, input.target_filepath, config);
1182
+ logger.debug("FastApply", "api_response", { completion_id: completionId, merged_len: mergedCode.length });
1117
1183
  const udiff = config.generateUdiff !== false ? generateUdiff2(originalCode, mergedCode, input.target_filepath) : void 0;
1118
1184
  if (config.autoWrite !== false) {
1119
1185
  await writeFile(fullPath, mergedCode, "utf-8");
1120
- if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);
1186
+ logger.debug("FastApply", "file_write", { path: fullPath, size_bytes: mergedCode.length });
1121
1187
  }
1122
1188
  const changes = countChanges2(originalCode, mergedCode);
1189
+ logger.debug("FastApply", "changes", { added: changes.linesAdded, removed: changes.linesRemoved, modified: changes.linesModified });
1123
1190
  return {
1124
1191
  success: true,
1125
1192
  filepath: input.target_filepath,
@@ -1129,7 +1196,7 @@ async function executeEditFile(input, config = {}) {
1129
1196
  };
1130
1197
  } catch (error) {
1131
1198
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
1132
- if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
1199
+ logger.error("FastApply", "execute_error", { error: errorMessage, target_filepath: input.target_filepath, stack: error instanceof Error ? error.stack : void 0 });
1133
1200
  return {
1134
1201
  success: false,
1135
1202
  filepath: input.target_filepath,
@@ -1216,6 +1283,7 @@ function sleep(ms) {
1216
1283
  }
1217
1284
 
1218
1285
  // tools/codebase_search/core.ts
1286
+ init_logger();
1219
1287
  var CodebaseSearchClient = class {
1220
1288
  config;
1221
1289
  constructor(config = {}) {
@@ -1253,11 +1321,7 @@ async function executeCodebaseSearch(input, config) {
1253
1321
  }
1254
1322
  const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "https://repos.morphllm.com";
1255
1323
  const timeout = config.timeout || 3e4;
1256
- const debug = config.debug || false;
1257
- if (debug) {
1258
- console.log(`[CodebaseSearch] Query: "${input.query.slice(0, 60)}..." repo=${config.repoId}`);
1259
- console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);
1260
- }
1324
+ logger.debug("CodebaseSearch", "request", { query: input.query.slice(0, 100), repo_id: config.repoId, url: `${searchUrl}/v1/codebase_search` });
1261
1325
  const startTime = Date.now();
1262
1326
  try {
1263
1327
  const fetchPromise = fetchWithRetry(
@@ -1281,7 +1345,7 @@ async function executeCodebaseSearch(input, config) {
1281
1345
  const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);
1282
1346
  if (!response.ok) {
1283
1347
  const errorText = await response.text();
1284
- if (debug) console.error(`[CodebaseSearch] Error: ${response.status} - ${errorText}`);
1348
+ logger.error("CodebaseSearch", "response_error", { status: response.status, error: errorText, latency_ms: Date.now() - startTime });
1285
1349
  return {
1286
1350
  success: false,
1287
1351
  results: [],
@@ -1291,16 +1355,14 @@ async function executeCodebaseSearch(input, config) {
1291
1355
  }
1292
1356
  const data = await response.json();
1293
1357
  const elapsed = Date.now() - startTime;
1294
- if (debug) {
1295
- console.log(`[CodebaseSearch] \u2705 ${data.results?.length || 0} results in ${elapsed}ms`);
1296
- }
1358
+ logger.debug("CodebaseSearch", "response", { results_count: data.results?.length || 0, latency_ms: elapsed });
1297
1359
  return {
1298
1360
  success: true,
1299
1361
  results: data.results || [],
1300
1362
  stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed }
1301
1363
  };
1302
1364
  } catch (error) {
1303
- if (debug) console.error(`[CodebaseSearch] Exception: ${error instanceof Error ? error.message : error}`);
1365
+ logger.error("CodebaseSearch", "exception", { error: error instanceof Error ? error.message : String(error), latency_ms: Date.now() - startTime });
1304
1366
  return {
1305
1367
  success: false,
1306
1368
  results: [],
@@ -1310,6 +1372,9 @@ async function executeCodebaseSearch(input, config) {
1310
1372
  }
1311
1373
  }
1312
1374
 
1375
+ // tools/browser/core.ts
1376
+ init_logger();
1377
+
1313
1378
  // tools/browser/live.ts
1314
1379
  var LIVE_PRESETS = {
1315
1380
  /** Read-only monitoring (no interaction) */
@@ -2006,11 +2071,7 @@ var BrowserClient = class {
2006
2071
  if (!hasTask && !hasDiff) {
2007
2072
  throw new Error('Browser task requires either "task" (natural language) or "diff" (PR-review planning)');
2008
2073
  }
2009
- if (debug) {
2010
- const preview = (input.task ?? "").slice(0, 60);
2011
- console.log(`[Browser] createTask: "${preview}..." url=${input.url || "none"}`);
2012
- console.log(`[Browser] Calling async endpoint: ${apiUrl}/browser-task/async`);
2013
- }
2074
+ logger.debug("Browser", "create_task", { task: (input.task ?? "").slice(0, 100), url: input.url, endpoint: `${apiUrl}/browser-task/async` });
2014
2075
  const headers = { "Content-Type": "application/json" };
2015
2076
  if (this.config.apiKey) headers["Authorization"] = `Bearer ${this.config.apiKey}`;
2016
2077
  const response = await fetch(`${apiUrl}/browser-task/async`, {
@@ -2040,14 +2101,11 @@ var BrowserClient = class {
2040
2101
  });
2041
2102
  if (!response.ok) {
2042
2103
  const errorText = await response.text().catch(() => response.statusText);
2043
- if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
2104
+ logger.error("Browser", "create_task_error", { status: response.status, error: errorText });
2044
2105
  throw new Error(`HTTP ${response.status}: ${errorText}`);
2045
2106
  }
2046
2107
  const result = mapTaskResult(await response.json());
2047
- if (debug) {
2048
- const debugUrl = result.debugUrl;
2049
- console.log(`[Browser] \u2705 Task created: recordingId=${result.recordingId ?? "none"} debugUrl=${debugUrl ? "available" : "none"}`);
2050
- }
2108
+ logger.debug("Browser", "task_created", { recording_id: result.recordingId, task_id: result.taskId, debug_url: !!result.debugUrl });
2051
2109
  if ("schema" in input) {
2052
2110
  return wrapTaskResponseWithSchema(result, this.config, input.schema);
2053
2111
  } else {
@@ -2107,10 +2165,7 @@ async function executeBrowserTask(input, config = {}) {
2107
2165
  error: "maxSteps must be between 1 and 50. Use more steps for complex multi-page flows."
2108
2166
  };
2109
2167
  }
2110
- if (debug) {
2111
- console.log(`[Browser] Task: "${input.task.slice(0, 60)}..." url=${input.url || "none"} maxSteps=${input.maxSteps ?? 10}`);
2112
- console.log(`[Browser] Recording: ${input.recordVideo ? "yes" : "no"} | Calling ${apiUrl}/browser-task`);
2113
- }
2168
+ logger.debug("Browser", "execute_start", { task: input.task.slice(0, 100), url: input.url, max_steps: input.maxSteps ?? 10, record_video: input.recordVideo ?? false });
2114
2169
  const startTime = Date.now();
2115
2170
  try {
2116
2171
  const headers = { "Content-Type": "application/json" };
@@ -2149,14 +2204,12 @@ async function executeBrowserTask(input, config = {}) {
2149
2204
  );
2150
2205
  if (!response.ok) {
2151
2206
  const errorText = await response.text().catch(() => response.statusText);
2152
- if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
2207
+ logger.error("Browser", "execute_error", { status: response.status, error: errorText });
2153
2208
  throw new Error(`HTTP ${response.status}: ${errorText}`);
2154
2209
  }
2155
2210
  const result = mapTaskResult(await response.json());
2156
2211
  const elapsed = Date.now() - startTime;
2157
- if (debug) {
2158
- console.log(`[Browser] \u2705 ${result.success ? "Success" : "Failed"} in ${elapsed}ms | steps=${result.stepsTaken ?? 0} recordingId=${result.recordingId ?? "none"}`);
2159
- }
2212
+ logger.debug("Browser", "execute_complete", { success: result.success, latency_ms: elapsed, steps: result.stepsTaken ?? 0, recording_id: result.recordingId });
2160
2213
  return result;
2161
2214
  } catch (error) {
2162
2215
  if (error instanceof Error) {
@@ -2867,6 +2920,7 @@ function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS
2867
2920
  var import_openai2 = __toESM(require("openai"), 1);
2868
2921
  init_version();
2869
2922
  var import_path4 = __toESM(require("path"), 1);
2923
+ init_logger();
2870
2924
  var DEFAULT_API_URL3 = "https://api.morphllm.com";
2871
2925
  var TOOL_SPECS = [
2872
2926
  {
@@ -2989,6 +3043,8 @@ async function callModel(messages, model, options = {}) {
2989
3043
  defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
2990
3044
  });
2991
3045
  const MAX_EMPTY_RETRIES = 1;
3046
+ logger.debug("WarpGrep", "model_call", { url: baseURL, model, message_count: messages.length });
3047
+ const callStartTime = Date.now();
2992
3048
  for (let attempt = 0; attempt <= MAX_EMPTY_RETRIES; attempt++) {
2993
3049
  let data;
2994
3050
  try {
@@ -3001,10 +3057,16 @@ async function callModel(messages, model, options = {}) {
3001
3057
  ...options.search_type ? { search_type: options.search_type } : {}
3002
3058
  });
3003
3059
  } catch (error) {
3004
- if (error instanceof import_openai2.default.APIError && error.status === 404) {
3005
- const defaultMsg = "The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp";
3006
- const errorText = error.message?.trim();
3007
- throw new Error(errorText || defaultMsg);
3060
+ const callLatencyMs = Date.now() - callStartTime;
3061
+ if (error instanceof import_openai2.default.APIError) {
3062
+ logger.error("WarpGrep", "model_call_error", { status: error.status, error: error.message, latency_ms: callLatencyMs });
3063
+ if (error.status === 404) {
3064
+ const defaultMsg = "The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp";
3065
+ const errorText = error.message?.trim();
3066
+ throw new Error(errorText || defaultMsg);
3067
+ }
3068
+ } else {
3069
+ logger.error("WarpGrep", "model_call_error", { status: void 0, error: error instanceof Error ? error.message : String(error), latency_ms: callLatencyMs });
3008
3070
  }
3009
3071
  throw error;
3010
3072
  }
@@ -3023,6 +3085,7 @@ async function callModel(messages, model, options = {}) {
3023
3085
  function: { name: tc.function.name, arguments: tc.function.arguments }
3024
3086
  }));
3025
3087
  if (message.content || toolCalls.length > 0) {
3088
+ logger.debug("WarpGrep", "model_call_complete", { latency_ms: Date.now() - callStartTime, tool_calls_count: toolCalls.length, finish_reason: choice?.finish_reason ?? "unknown" });
3026
3089
  return { content: message.content ?? null, tool_calls: toolCalls };
3027
3090
  }
3028
3091
  if (attempt === MAX_EMPTY_RETRIES) {
@@ -3093,9 +3156,11 @@ async function* runWarpGrepStreaming(config) {
3093
3156
  const model = config.model || DEFAULT_MODEL;
3094
3157
  const messages = [];
3095
3158
  const maxTurns = AGENT_CONFIG.MAX_TURNS;
3159
+ logger.debug("WarpGrep", "session_start", { search_term: config.searchTerm, model, max_turns: maxTurns });
3096
3160
  const initialStateStart = Date.now();
3097
3161
  const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });
3098
3162
  timings.initial_state_ms = Date.now() - initialStateStart;
3163
+ logger.debug("WarpGrep", "initial_state", { system_prompt_len: initialState.length, user_message_len: initialState.length });
3099
3164
  messages.push({ role: "user", content: initialState });
3100
3165
  const provider = config.provider;
3101
3166
  const errors = [];
@@ -3103,7 +3168,13 @@ async function* runWarpGrepStreaming(config) {
3103
3168
  let terminationReason = "terminated";
3104
3169
  for (let turn = 1; turn <= maxTurns; turn += 1) {
3105
3170
  const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
3171
+ logger.debug("WarpGrep", "turn_start", { turn, message_count: messages.length });
3172
+ const beforeChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
3106
3173
  enforceContextLimit(messages);
3174
+ const afterChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
3175
+ if (afterChars < beforeChars) {
3176
+ logger.debug("WarpGrep", "context_truncated", { before_chars: beforeChars, after_chars: afterChars });
3177
+ }
3107
3178
  const modelCallStart = Date.now();
3108
3179
  const response = await callModel(messages, model, {
3109
3180
  morphApiKey: config.morphApiKey,
@@ -3114,6 +3185,7 @@ async function* runWarpGrepStreaming(config) {
3114
3185
  }).catch((e) => {
3115
3186
  const errMsg = e instanceof Error ? e.message : String(e);
3116
3187
  console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
3188
+ logger.error("WarpGrep", "error", { turn, error: errMsg, phase: "model_call" });
3117
3189
  errors.push({ message: errMsg });
3118
3190
  return null;
3119
3191
  });
@@ -3123,6 +3195,7 @@ async function* runWarpGrepStreaming(config) {
3123
3195
  break;
3124
3196
  }
3125
3197
  const toolCalls = response.tool_calls;
3198
+ logger.debug("WarpGrep", "model_response", { turn, tool_calls: toolCalls.map((tc) => tc.function.name), latency_ms: turnMetrics.morph_api_ms });
3126
3199
  messages.push({
3127
3200
  role: "assistant",
3128
3201
  content: response.content,
@@ -3149,6 +3222,7 @@ async function* runWarpGrepStreaming(config) {
3149
3222
  const files = parseFinishFiles(filesStr);
3150
3223
  finishMeta = { files };
3151
3224
  terminationReason = "completed";
3225
+ logger.debug("WarpGrep", "finish", { turns: turn, files: files.map((f) => f.path) });
3152
3226
  if (files.length === 0) {
3153
3227
  const payload2 = filesStr || "No relevant code found.";
3154
3228
  timings.turns.push(turnMetrics);
@@ -3167,7 +3241,11 @@ async function* runWarpGrepStreaming(config) {
3167
3241
  const results = await Promise.all(
3168
3242
  toolCalls.map(async (tc) => {
3169
3243
  const args = safeParseJSON(tc.function.arguments);
3244
+ const argsSummary = Object.fromEntries(Object.entries(args).map(([k, v]) => [k, typeof v === "string" && v.length > 100 ? v.slice(0, 100) + "..." : v]));
3245
+ logger.debug("WarpGrep", "tool_exec", { turn, tool: tc.function.name, args_summary: argsSummary });
3246
+ const toolStart = Date.now();
3170
3247
  const output = await executeTool(provider, tc.function.name, args, repoRoot).catch((err) => String(err));
3248
+ logger.debug("WarpGrep", "tool_result", { turn, tool: tc.function.name, result_len: output.length, latency_ms: Date.now() - toolStart });
3171
3249
  return { tool_call_id: tc.id, content: output };
3172
3250
  })
3173
3251
  );
@@ -3236,6 +3314,9 @@ async function runWarpGrep(config) {
3236
3314
  return result.value;
3237
3315
  }
3238
3316
 
3317
+ // tools/warp_grep/client.ts
3318
+ init_logger();
3319
+
3239
3320
  // tools/warp_grep/providers/remote.ts
3240
3321
  init_config();
3241
3322
  var SKIP_NAMES = /* @__PURE__ */ new Set([
@@ -3675,12 +3756,16 @@ var WarpGrepClient = class {
3675
3756
  async _resolveGitHubRepo(input) {
3676
3757
  const { owner, repo } = parseGitHubUrl(input.github);
3677
3758
  const baseUrl = this.config.codeSearchUrl || DEFAULT_CODE_SEARCH_URL;
3759
+ logger.debug("WarpGrep", "github_resolve", { owner_repo: `${owner}/${repo}`, branch: input.branch });
3760
+ const resolveStart = Date.now();
3678
3761
  const importRes = await fetch(`${baseUrl}/api/code-search/get-or-create?url=${encodeURIComponent(`${owner}/${repo}`)}`);
3679
3762
  if (!importRes.ok) {
3680
3763
  const text = await importRes.text().catch(() => importRes.statusText);
3764
+ logger.error("WarpGrep", "github_resolve_failed", { owner_repo: `${owner}/${repo}`, status: importRes.status, error: text });
3681
3765
  throw new Error(`Failed to import repo ${owner}/${repo}: ${text}`);
3682
3766
  }
3683
3767
  const { repoId, defaultBranch } = await importRes.json();
3768
+ logger.debug("WarpGrep", "github_repo_fetched", { repo_id: repoId, default_branch: defaultBranch, latency_ms: Date.now() - resolveStart });
3684
3769
  return {
3685
3770
  repo,
3686
3771
  remoteCommands: createCodeStorageHttpCommands({ baseUrl, repoId, branch: input.branch || defaultBranch })
@@ -4221,7 +4306,7 @@ var GitHubClient = class {
4221
4306
  // git/client.ts
4222
4307
  var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
4223
4308
  var import_node = __toESM(require("isomorphic-git/http/node"), 1);
4224
- var import_fs2 = __toESM(require("fs"), 1);
4309
+ var import_fs3 = __toESM(require("fs"), 1);
4225
4310
  var DEFAULT_PROXY_URL = "https://repos.morphllm.com";
4226
4311
  var MorphGit = class {
4227
4312
  apiKey;
@@ -4278,12 +4363,12 @@ var MorphGit = class {
4278
4363
  throw new Error(`Failed to create repository: ${error}`);
4279
4364
  }
4280
4365
  await import_isomorphic_git.default.init({
4281
- fs: import_fs2.default,
4366
+ fs: import_fs3.default,
4282
4367
  dir,
4283
4368
  defaultBranch
4284
4369
  });
4285
4370
  await import_isomorphic_git.default.addRemote({
4286
- fs: import_fs2.default,
4371
+ fs: import_fs3.default,
4287
4372
  dir,
4288
4373
  remote: "origin",
4289
4374
  url: `${this.proxyUrl}/v1/repos/${repoId}`
@@ -4304,7 +4389,7 @@ var MorphGit = class {
4304
4389
  async clone(options) {
4305
4390
  const { repoId, dir, branch = "main", depth, singleBranch = true } = options;
4306
4391
  await import_isomorphic_git.default.clone({
4307
- fs: import_fs2.default,
4392
+ fs: import_fs3.default,
4308
4393
  http: import_node.default,
4309
4394
  dir,
4310
4395
  url: `${this.proxyUrl}/v1/repos/${repoId}`,
@@ -4333,9 +4418,9 @@ var MorphGit = class {
4333
4418
  'branch is required for push operations. Specify the branch explicitly: { dir: "./my-project", branch: "main" }'
4334
4419
  );
4335
4420
  }
4336
- const commitHash = await import_isomorphic_git.default.resolveRef({ fs: import_fs2.default, dir, ref: "HEAD" });
4421
+ const commitHash = await import_isomorphic_git.default.resolveRef({ fs: import_fs3.default, dir, ref: "HEAD" });
4337
4422
  let repoId;
4338
- const remotes = await import_isomorphic_git.default.listRemotes({ fs: import_fs2.default, dir });
4423
+ const remotes = await import_isomorphic_git.default.listRemotes({ fs: import_fs3.default, dir });
4339
4424
  const originRemote = remotes.find((r) => r.remote === remote);
4340
4425
  if (originRemote) {
4341
4426
  const match = originRemote.url.match(/\/repos\/([^\/]+)$/);
@@ -4344,7 +4429,7 @@ var MorphGit = class {
4344
4429
  }
4345
4430
  }
4346
4431
  await import_isomorphic_git.default.push({
4347
- fs: import_fs2.default,
4432
+ fs: import_fs3.default,
4348
4433
  http: import_node.default,
4349
4434
  dir,
4350
4435
  remote,
@@ -4399,7 +4484,7 @@ var MorphGit = class {
4399
4484
  );
4400
4485
  }
4401
4486
  await import_isomorphic_git.default.pull({
4402
- fs: import_fs2.default,
4487
+ fs: import_fs3.default,
4403
4488
  http: import_node.default,
4404
4489
  dir,
4405
4490
  remote,
@@ -4468,7 +4553,7 @@ var MorphGit = class {
4468
4553
  async add(options) {
4469
4554
  const { dir, filepath } = options;
4470
4555
  await import_isomorphic_git.default.add({
4471
- fs: import_fs2.default,
4556
+ fs: import_fs3.default,
4472
4557
  dir,
4473
4558
  filepath
4474
4559
  });
@@ -4487,7 +4572,7 @@ var MorphGit = class {
4487
4572
  async remove(options) {
4488
4573
  const { dir, filepath } = options;
4489
4574
  await import_isomorphic_git.default.remove({
4490
- fs: import_fs2.default,
4575
+ fs: import_fs3.default,
4491
4576
  dir,
4492
4577
  filepath
4493
4578
  });
@@ -4520,7 +4605,7 @@ var MorphGit = class {
4520
4605
  email: "sdk@morphllm.com"
4521
4606
  };
4522
4607
  const sha = await import_isomorphic_git.default.commit({
4523
- fs: import_fs2.default,
4608
+ fs: import_fs3.default,
4524
4609
  dir,
4525
4610
  message,
4526
4611
  author: commitAuthor
@@ -4533,7 +4618,7 @@ var MorphGit = class {
4533
4618
  _version: 1
4534
4619
  };
4535
4620
  await import_isomorphic_git.default.addNote({
4536
- fs: import_fs2.default,
4621
+ fs: import_fs3.default,
4537
4622
  dir,
4538
4623
  ref: "refs/notes/morph-metadata",
4539
4624
  oid: sha,
@@ -4561,7 +4646,7 @@ var MorphGit = class {
4561
4646
  throw new Error("filepath is required for status check");
4562
4647
  }
4563
4648
  const status = await import_isomorphic_git.default.status({
4564
- fs: import_fs2.default,
4649
+ fs: import_fs3.default,
4565
4650
  dir,
4566
4651
  filepath
4567
4652
  });
@@ -4581,7 +4666,7 @@ var MorphGit = class {
4581
4666
  async log(options) {
4582
4667
  const { dir, depth, ref } = options;
4583
4668
  const commits = await import_isomorphic_git.default.log({
4584
- fs: import_fs2.default,
4669
+ fs: import_fs3.default,
4585
4670
  dir,
4586
4671
  depth,
4587
4672
  ref
@@ -4602,7 +4687,7 @@ var MorphGit = class {
4602
4687
  async checkout(options) {
4603
4688
  const { dir, ref } = options;
4604
4689
  await import_isomorphic_git.default.checkout({
4605
- fs: import_fs2.default,
4690
+ fs: import_fs3.default,
4606
4691
  dir,
4607
4692
  ref
4608
4693
  });
@@ -4622,7 +4707,7 @@ var MorphGit = class {
4622
4707
  async branch(options) {
4623
4708
  const { dir, name, checkout = false } = options;
4624
4709
  await import_isomorphic_git.default.branch({
4625
- fs: import_fs2.default,
4710
+ fs: import_fs3.default,
4626
4711
  dir,
4627
4712
  ref: name,
4628
4713
  checkout
@@ -4641,7 +4726,7 @@ var MorphGit = class {
4641
4726
  async listBranches(options) {
4642
4727
  const { dir } = options;
4643
4728
  const branches = await import_isomorphic_git.default.listBranches({
4644
- fs: import_fs2.default,
4729
+ fs: import_fs3.default,
4645
4730
  dir
4646
4731
  });
4647
4732
  return branches;
@@ -4659,7 +4744,7 @@ var MorphGit = class {
4659
4744
  async currentBranch(options) {
4660
4745
  const { dir } = options;
4661
4746
  const branch = await import_isomorphic_git.default.currentBranch({
4662
- fs: import_fs2.default,
4747
+ fs: import_fs3.default,
4663
4748
  dir
4664
4749
  });
4665
4750
  return branch || void 0;
@@ -4677,7 +4762,7 @@ var MorphGit = class {
4677
4762
  async statusMatrix(options) {
4678
4763
  const { dir } = options;
4679
4764
  const matrix = await import_isomorphic_git.default.statusMatrix({
4680
- fs: import_fs2.default,
4765
+ fs: import_fs3.default,
4681
4766
  dir
4682
4767
  });
4683
4768
  return matrix.map(([filepath, HEADStatus, workdirStatus, stageStatus]) => {
@@ -4719,7 +4804,7 @@ var MorphGit = class {
4719
4804
  async resolveRef(options) {
4720
4805
  const { dir, ref } = options;
4721
4806
  const oid = await import_isomorphic_git.default.resolveRef({
4722
- fs: import_fs2.default,
4807
+ fs: import_fs3.default,
4723
4808
  dir,
4724
4809
  ref
4725
4810
  });
@@ -4745,7 +4830,7 @@ var MorphGit = class {
4745
4830
  async getCommitMetadata(options) {
4746
4831
  try {
4747
4832
  const note = await import_isomorphic_git.default.readNote({
4748
- fs: import_fs2.default,
4833
+ fs: import_fs3.default,
4749
4834
  dir: options.dir,
4750
4835
  ref: "refs/notes/morph-metadata",
4751
4836
  oid: options.commitSha
@@ -4763,6 +4848,7 @@ var import_isomorphic_git2 = __toESM(require("isomorphic-git"), 1);
4763
4848
  var import_node2 = __toESM(require("isomorphic-git/http/node"), 1);
4764
4849
 
4765
4850
  // modelrouter/core.ts
4851
+ init_logger();
4766
4852
  var DEFAULT_CONFIG3 = {
4767
4853
  apiUrl: "https://api.morphllm.com",
4768
4854
  timeout: 5e3,
@@ -4798,12 +4884,7 @@ var BaseRouter = class {
4798
4884
  input: input.input,
4799
4885
  mode
4800
4886
  };
4801
- if (this.config.debug) {
4802
- console.log(`[ModelRouter] Requesting ${this.provider} model selection:`, {
4803
- mode,
4804
- inputLength: input.input.length
4805
- });
4806
- }
4887
+ logger.debug("ModelRouter", "request", { provider: this.provider, mode, input_len: input.input.length, url });
4807
4888
  try {
4808
4889
  const fetchPromise = fetchWithRetry(
4809
4890
  url,
@@ -4832,14 +4913,10 @@ var BaseRouter = class {
4832
4913
  const result = {
4833
4914
  model: apiResult.model
4834
4915
  };
4835
- if (this.config.debug) {
4836
- console.log(`[ModelRouter] Selected model: ${apiResult.model}, Confidence: ${apiResult.confidence?.toFixed(3)}`);
4837
- }
4916
+ logger.debug("ModelRouter", "selected", { provider: this.provider, model: apiResult.model, confidence: apiResult.confidence });
4838
4917
  return result;
4839
4918
  } catch (error) {
4840
- if (this.config.debug) {
4841
- console.error(`[ModelRouter] Error selecting model:`, error);
4842
- }
4919
+ logger.error("ModelRouter", "error", { provider: this.provider, error: error instanceof Error ? error.message : String(error) });
4843
4920
  throw error;
4844
4921
  }
4845
4922
  }
@@ -4909,12 +4986,7 @@ var RawRouter = class extends BaseRouter {
4909
4986
  input: input.input,
4910
4987
  mode
4911
4988
  };
4912
- if (this.config.debug) {
4913
- console.log(`[RawRouter] Requesting raw difficulty classification:`, {
4914
- mode,
4915
- inputLength: input.input.length
4916
- });
4917
- }
4989
+ logger.debug("RawRouter", "request", { mode, input_len: input.input.length, url });
4918
4990
  try {
4919
4991
  const fetchPromise = fetchWithRetry(
4920
4992
  url,
@@ -4949,14 +5021,10 @@ var RawRouter = class extends BaseRouter {
4949
5021
  const result = {
4950
5022
  difficulty
4951
5023
  };
4952
- if (this.config.debug) {
4953
- console.log(`[RawRouter] Classified as: ${difficulty}`);
4954
- }
5024
+ logger.debug("RawRouter", "classified", { difficulty });
4955
5025
  return result;
4956
5026
  } catch (error) {
4957
- if (this.config.debug) {
4958
- console.error(`[RawRouter] Error classifying:`, error);
4959
- }
5027
+ logger.error("RawRouter", "error", { error: error instanceof Error ? error.message : String(error) });
4960
5028
  throw error;
4961
5029
  }
4962
5030
  }
@@ -6382,6 +6450,10 @@ var MorphClient = class {
6382
6450
  */
6383
6451
  constructor(config = {}) {
6384
6452
  this.config = config;
6453
+ if (config.debug) {
6454
+ logger.enable();
6455
+ }
6456
+ logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
6385
6457
  this.fastApply = new FastApplyClient({
6386
6458
  apiKey: config.apiKey,
6387
6459
  debug: config.debug,