@morphllm/morphsdk 0.2.162 → 0.2.163

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-YBKT2UOK.js → chunk-2KDJKRZG.js} +2 -2
  2. package/dist/chunk-5AM23TC7.js +42 -0
  3. package/dist/chunk-5AM23TC7.js.map +1 -0
  4. package/dist/{chunk-UETFIUIG.js → chunk-5BMWOPYW.js} +2 -2
  5. package/dist/{chunk-UKT3CKC7.js → chunk-5FYJMU6H.js} +2 -2
  6. package/dist/{chunk-DRTPCCEI.js → chunk-6PFGM4CM.js} +2 -2
  7. package/dist/{chunk-YRHM3RCQ.js → chunk-6YOSNPHS.js} +2 -2
  8. package/dist/{chunk-XUV5B27P.js → chunk-6YTCBLRI.js} +2 -2
  9. package/dist/{chunk-VQSLLYKE.js → chunk-COUYHTIO.js} +2 -2
  10. package/dist/{chunk-Y4NYT5L6.js → chunk-CUMC7Z5R.js} +11 -26
  11. package/dist/chunk-CUMC7Z5R.js.map +1 -0
  12. package/dist/{chunk-4Q6VFODP.js → chunk-EJBWDGTH.js} +2 -2
  13. package/dist/{chunk-UZX7SY33.js → chunk-FNCPPCPV.js} +2 -2
  14. package/dist/{chunk-4GQNYJBB.js → chunk-FQXUOZBX.js} +9 -12
  15. package/dist/chunk-FQXUOZBX.js.map +1 -0
  16. package/dist/{chunk-DXMNKPB6.js → chunk-HBH56DLN.js} +2 -2
  17. package/dist/{chunk-JVKGSMEF.js → chunk-HFN3YCF4.js} +2 -2
  18. package/dist/{chunk-NKUGRAYU.js → chunk-HMGC7FLZ.js} +2 -2
  19. package/dist/{chunk-4U5JFT6X.js → chunk-KHR4CZMX.js} +24 -17
  20. package/dist/{chunk-4U5JFT6X.js.map → chunk-KHR4CZMX.js.map} +1 -1
  21. package/dist/{chunk-OGMHU4PJ.js → chunk-LSHQISAX.js} +9 -2
  22. package/dist/chunk-LSHQISAX.js.map +1 -0
  23. package/dist/{chunk-ZG3YLRR5.js → chunk-LST7MZOZ.js} +7 -2
  24. package/dist/chunk-LST7MZOZ.js.map +1 -0
  25. package/dist/{chunk-5XTA7GCY.js → chunk-LW5EAPZ6.js} +2 -2
  26. package/dist/{chunk-UVRC4LKZ.js → chunk-NNATBEOF.js} +2 -2
  27. package/dist/{chunk-CNFHKQ42.js → chunk-OKFW4KGU.js} +2 -2
  28. package/dist/{chunk-PWGBAVQ5.js → chunk-QXGOEDZD.js} +2 -2
  29. package/dist/{chunk-OOE2TKKY.js → chunk-SELI567A.js} +12 -21
  30. package/dist/chunk-SELI567A.js.map +1 -0
  31. package/dist/{chunk-LECHLXI4.js → chunk-VMNEYCFP.js} +17 -6
  32. package/dist/chunk-VMNEYCFP.js.map +1 -0
  33. package/dist/{chunk-LZQBVEY2.js → chunk-WM6SBI4B.js} +35 -27
  34. package/dist/chunk-WM6SBI4B.js.map +1 -0
  35. package/dist/{chunk-7QMX45QD.js → chunk-ZMCDGAGF.js} +33 -6
  36. package/dist/chunk-ZMCDGAGF.js.map +1 -0
  37. package/dist/client.cjs +184 -115
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.ts +1 -1
  40. package/dist/client.js +23 -22
  41. package/dist/edge.cjs +82 -50
  42. package/dist/edge.cjs.map +1 -1
  43. package/dist/edge.js +5 -4
  44. package/dist/index.cjs +186 -115
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +23 -22
  48. package/dist/modelrouter/core.cjs +50 -25
  49. package/dist/modelrouter/core.cjs.map +1 -1
  50. package/dist/modelrouter/core.js +4 -3
  51. package/dist/modelrouter/index.cjs +50 -25
  52. package/dist/modelrouter/index.cjs.map +1 -1
  53. package/dist/modelrouter/index.js +4 -3
  54. package/dist/subagents/anthropic.cjs +85 -12
  55. package/dist/subagents/anthropic.cjs.map +1 -1
  56. package/dist/subagents/anthropic.js +5 -4
  57. package/dist/subagents/vercel.cjs +85 -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 +47 -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 +50 -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 +50 -19
  67. package/dist/tools/browser/index.cjs.map +1 -1
  68. package/dist/tools/browser/index.js +8 -7
  69. package/dist/tools/browser/index.js.map +1 -1
  70. package/dist/tools/browser/openai.cjs +47 -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 +6 -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 +6 -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 +47 -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 +48 -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 +48 -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 +48 -11
  89. package/dist/tools/codebase_search/index.cjs.map +1 -1
  90. package/dist/tools/codebase_search/index.js +7 -6
  91. package/dist/tools/codebase_search/openai.cjs +48 -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 +48 -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 +94 -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 +74 -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 +94 -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 +94 -31
  107. package/dist/tools/fastapply/index.cjs.map +1 -1
  108. package/dist/tools/fastapply/index.js +7 -6
  109. package/dist/tools/fastapply/openai.cjs +94 -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 +94 -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 +94 -31
  116. package/dist/tools/index.cjs.map +1 -1
  117. package/dist/tools/index.js +7 -6
  118. package/dist/tools/utils/resilience.cjs +6 -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 +74 -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 +85 -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 +85 -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 +85 -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 +85 -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 +85 -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 +85 -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 +6 -1
  145. package/dist/version.cjs.map +1 -1
  146. package/dist/version.js +1 -1
  147. package/package.json +6 -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-YBKT2UOK.js.map → chunk-2KDJKRZG.js.map} +0 -0
  157. package/dist/{chunk-UETFIUIG.js.map → chunk-5BMWOPYW.js.map} +0 -0
  158. package/dist/{chunk-UKT3CKC7.js.map → chunk-5FYJMU6H.js.map} +0 -0
  159. package/dist/{chunk-DRTPCCEI.js.map → chunk-6PFGM4CM.js.map} +0 -0
  160. package/dist/{chunk-YRHM3RCQ.js.map → chunk-6YOSNPHS.js.map} +0 -0
  161. package/dist/{chunk-XUV5B27P.js.map → chunk-6YTCBLRI.js.map} +0 -0
  162. package/dist/{chunk-VQSLLYKE.js.map → chunk-COUYHTIO.js.map} +0 -0
  163. package/dist/{chunk-4Q6VFODP.js.map → chunk-EJBWDGTH.js.map} +0 -0
  164. package/dist/{chunk-UZX7SY33.js.map → chunk-FNCPPCPV.js.map} +0 -0
  165. package/dist/{chunk-DXMNKPB6.js.map → chunk-HBH56DLN.js.map} +0 -0
  166. package/dist/{chunk-JVKGSMEF.js.map → chunk-HFN3YCF4.js.map} +0 -0
  167. package/dist/{chunk-NKUGRAYU.js.map → chunk-HMGC7FLZ.js.map} +0 -0
  168. package/dist/{chunk-5XTA7GCY.js.map → chunk-LW5EAPZ6.js.map} +0 -0
  169. package/dist/{chunk-UVRC4LKZ.js.map → chunk-NNATBEOF.js.map} +0 -0
  170. package/dist/{chunk-CNFHKQ42.js.map → chunk-OKFW4KGU.js.map} +0 -0
  171. package/dist/{chunk-PWGBAVQ5.js.map → chunk-QXGOEDZD.js.map} +0 -0
  172. package/dist/{client-PkB7g9SA.d.ts → client-DsAAqupx.d.ts} +1 -1
package/dist/client.cjs CHANGED
@@ -30,13 +30,57 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // logger.ts
34
+ var import_fs, MorphLogger, logger;
35
+ var init_logger = __esm({
36
+ "logger.ts"() {
37
+ "use strict";
38
+ import_fs = require("fs");
39
+ MorphLogger = class {
40
+ enabled;
41
+ fileStream;
42
+ constructor() {
43
+ this.enabled = process.env.MORPH_DEBUG === "1" || !!process.env.MORPH_LOG_FILE;
44
+ const f = process.env.MORPH_LOG_FILE;
45
+ this.fileStream = f ? (0, import_fs.createWriteStream)(f, { flags: "a" }) : null;
46
+ }
47
+ debug(component, msg, data) {
48
+ this._log("debug", component, msg, data);
49
+ }
50
+ info(component, msg, data) {
51
+ this._log("info", component, msg, data);
52
+ }
53
+ warn(component, msg, data) {
54
+ this._log("warn", component, msg, data);
55
+ }
56
+ error(component, msg, data) {
57
+ this._log("error", component, msg, data);
58
+ }
59
+ enable() {
60
+ this.enabled = true;
61
+ }
62
+ get isEnabled() {
63
+ return this.enabled;
64
+ }
65
+ _log(level, component, msg, data) {
66
+ if (level !== "error" && !this.enabled) return;
67
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
68
+ const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;
69
+ console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);
70
+ this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...data && { data } }) + "\n");
71
+ }
72
+ };
73
+ logger = new MorphLogger();
74
+ }
75
+ });
76
+
33
77
  // package.json
34
78
  var package_default;
35
79
  var init_package = __esm({
36
80
  "package.json"() {
37
81
  package_default = {
38
82
  name: "@morphllm/morphsdk",
39
- version: "0.2.162",
83
+ version: "0.2.163",
40
84
  description: "TypeScript SDK and CLI for Morph Fast Apply integration",
41
85
  type: "module",
42
86
  main: "./dist/index.cjs",
@@ -48,6 +92,11 @@ var init_package = __esm({
48
92
  import: "./dist/index.js",
49
93
  require: "./dist/index.cjs"
50
94
  },
95
+ "./logger": {
96
+ types: "./dist/logger.d.ts",
97
+ import: "./dist/logger.js",
98
+ require: "./dist/logger.cjs"
99
+ },
51
100
  "./edge": {
52
101
  types: "./dist/edge.d.ts",
53
102
  import: "./dist/edge.js",
@@ -335,11 +384,14 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
335
384
  const message = `<instruction>${instructions}</instruction>
336
385
  <code>${originalCode}</code>
337
386
  <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
- }
387
+ logger.debug("FastApply", "http_request", {
388
+ url: `${apiUrl}/v1/chat/completions`,
389
+ model,
390
+ filepath,
391
+ instruction_len: instructions.length,
392
+ original_len: originalCode.length,
393
+ code_edit_len: codeEdit.length
394
+ });
343
395
  const startTime = Date.now();
344
396
  const client = new import_openai.default({
345
397
  apiKey,
@@ -348,30 +400,32 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
348
400
  maxRetries: config.retryConfig?.maxRetries ?? 3,
349
401
  defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
350
402
  });
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`);
403
+ try {
404
+ const completion = await client.chat.completions.create({
405
+ model,
406
+ messages: [{ role: "user", content: message }]
407
+ });
408
+ const content = completion.choices[0]?.message?.content;
409
+ if (!content) {
410
+ throw new Error("Morph API returned empty response");
411
+ }
412
+ const elapsed = Date.now() - startTime;
413
+ logger.debug("FastApply", "http_response", { status: 200, completion_id: completion.id, content_len: content.length, latency_ms: elapsed });
414
+ return { content, completionId: completion.id };
415
+ } catch (error) {
416
+ const elapsed = Date.now() - startTime;
417
+ logger.error("FastApply", "http_error", {
418
+ status: error?.status || error?.response?.status,
419
+ error: error?.message,
420
+ latency_ms: elapsed
421
+ });
422
+ throw error;
365
423
  }
366
- return { content, completionId: completion.id };
367
424
  }
368
425
  async function applyEdit(input, config = {}) {
369
- const debug = config.debug || false;
370
426
  const filepath = input.filepath || "file";
371
427
  try {
372
- if (debug) {
373
- console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);
374
- }
428
+ logger.debug("FastApply", "apply_edit_start", { original_len: input.originalCode.length, code_edit_len: input.codeEdit.length });
375
429
  const instruction = input.instruction ?? input.instructions ?? "";
376
430
  const { content: mergedCode, completionId } = await callMorphAPI(
377
431
  input.originalCode,
@@ -391,7 +445,7 @@ async function applyEdit(input, config = {}) {
391
445
  };
392
446
  } catch (error) {
393
447
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
394
- if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
448
+ logger.error("FastApply", "apply_edit_error", { error: errorMessage });
395
449
  return {
396
450
  success: false,
397
451
  changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },
@@ -406,6 +460,7 @@ var init_apply = __esm({
406
460
  import_diff = require("diff");
407
461
  import_openai = __toESM(require("openai"), 1);
408
462
  init_version();
463
+ init_logger();
409
464
  DEFAULT_API_URL = "https://api.morphllm.com";
410
465
  DEFAULT_TIMEOUT = 3e4;
411
466
  }
@@ -601,7 +656,7 @@ function toRepoRelative(repoRoot, absPath) {
601
656
  }
602
657
  function isSymlink(p) {
603
658
  try {
604
- const st = import_fs.default.lstatSync(p);
659
+ const st = import_fs2.default.lstatSync(p);
605
660
  return st.isSymbolicLink();
606
661
  } catch {
607
662
  return false;
@@ -624,13 +679,13 @@ function fixPathRepetition(fullPath) {
624
679
  }
625
680
  function isTextualFile(filePath, maxBytes = 2e6) {
626
681
  try {
627
- const st = import_fs.default.statSync(filePath);
682
+ const st = import_fs2.default.statSync(filePath);
628
683
  if (!st.isFile()) return false;
629
684
  if (st.size > maxBytes) return false;
630
- const fd = import_fs.default.openSync(filePath, "r");
685
+ const fd = import_fs2.default.openSync(filePath, "r");
631
686
  const buf = Buffer.alloc(512);
632
- const read = import_fs.default.readSync(fd, buf, 0, buf.length, 0);
633
- import_fs.default.closeSync(fd);
687
+ const read = import_fs2.default.readSync(fd, buf, 0, buf.length, 0);
688
+ import_fs2.default.closeSync(fd);
634
689
  for (let i = 0; i < read; i++) {
635
690
  const c = buf[i];
636
691
  if (c === 0) return false;
@@ -640,11 +695,11 @@ function isTextualFile(filePath, maxBytes = 2e6) {
640
695
  return false;
641
696
  }
642
697
  }
643
- var import_fs, import_path5;
698
+ var import_fs2, import_path5;
644
699
  var init_paths = __esm({
645
700
  "tools/warp_grep/utils/paths.ts"() {
646
701
  "use strict";
647
- import_fs = __toESM(require("fs"), 1);
702
+ import_fs2 = __toESM(require("fs"), 1);
648
703
  import_path5 = __toESM(require("path"), 1);
649
704
  }
650
705
  });
@@ -1004,9 +1059,11 @@ __export(client_exports, {
1004
1059
  MorphClient: () => MorphClient
1005
1060
  });
1006
1061
  module.exports = __toCommonJS(client_exports);
1062
+ init_logger();
1007
1063
 
1008
1064
  // tools/fastapply/core.ts
1009
1065
  var import_path = require("path");
1066
+ init_logger();
1010
1067
  init_apply();
1011
1068
  var DEFAULT_CONFIG = {
1012
1069
  morphApiUrl: "https://api.morphllm.com",
@@ -1067,9 +1124,10 @@ var FastApplyClient = class {
1067
1124
  async function executeEditFile(input, config = {}) {
1068
1125
  const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;
1069
1126
  const fullPath = (0, import_path.resolve)((0, import_path.join)(baseDir, input.target_filepath));
1070
- const debug = config.debug || false;
1127
+ logger.debug("FastApply", "execute_start", { target_filepath: input.target_filepath, baseDir, autoWrite: config.autoWrite !== false });
1071
1128
  const relativePath = (0, import_path.relative)(baseDir, fullPath);
1072
1129
  if (relativePath.startsWith("..") || fullPath === baseDir) {
1130
+ logger.warn("FastApply", "security_check_failed", { target_filepath: input.target_filepath, relative: relativePath });
1073
1131
  return {
1074
1132
  success: false,
1075
1133
  filepath: input.target_filepath,
@@ -1077,27 +1135,33 @@ async function executeEditFile(input, config = {}) {
1077
1135
  error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`
1078
1136
  };
1079
1137
  }
1138
+ logger.debug("FastApply", "security_check", { resolved: fullPath, relative: relativePath });
1080
1139
  try {
1081
- if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);
1082
1140
  const { readFile, writeFile } = await import("fs/promises");
1083
1141
  const { callMorphAPI: callMorphAPI2, generateUdiff: generateUdiff2, countChanges: countChanges2 } = await Promise.resolve().then(() => (init_apply(), apply_exports));
1084
1142
  let originalCode = "";
1143
+ let fileExists = true;
1085
1144
  try {
1086
1145
  originalCode = await readFile(fullPath, "utf-8");
1146
+ logger.debug("FastApply", "file_read", { path: fullPath, exists: true, size_bytes: originalCode.length });
1087
1147
  } catch (error) {
1088
1148
  if (error.code !== "ENOENT") {
1089
1149
  throw error;
1090
1150
  }
1091
- if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);
1151
+ fileExists = false;
1152
+ logger.debug("FastApply", "file_read", { path: fullPath, exists: false });
1092
1153
  }
1093
1154
  const instruction = input.instruction ?? input.instructions ?? "";
1155
+ logger.debug("FastApply", "api_call", { instruction_len: instruction.length, code_edit_len: input.code_edit.length, original_len: originalCode.length });
1094
1156
  const { content: mergedCode, completionId } = await callMorphAPI2(originalCode, input.code_edit, instruction, input.target_filepath, config);
1157
+ logger.debug("FastApply", "api_response", { completion_id: completionId, merged_len: mergedCode.length });
1095
1158
  const udiff = config.generateUdiff !== false ? generateUdiff2(originalCode, mergedCode, input.target_filepath) : void 0;
1096
1159
  if (config.autoWrite !== false) {
1097
1160
  await writeFile(fullPath, mergedCode, "utf-8");
1098
- if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);
1161
+ logger.debug("FastApply", "file_write", { path: fullPath, size_bytes: mergedCode.length });
1099
1162
  }
1100
1163
  const changes = countChanges2(originalCode, mergedCode);
1164
+ logger.debug("FastApply", "changes", { added: changes.linesAdded, removed: changes.linesRemoved, modified: changes.linesModified });
1101
1165
  return {
1102
1166
  success: true,
1103
1167
  filepath: input.target_filepath,
@@ -1107,7 +1171,7 @@ async function executeEditFile(input, config = {}) {
1107
1171
  };
1108
1172
  } catch (error) {
1109
1173
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
1110
- if (debug) console.error(`[FastApply] Error: ${errorMessage}`);
1174
+ logger.error("FastApply", "execute_error", { error: errorMessage, target_filepath: input.target_filepath, stack: error instanceof Error ? error.stack : void 0 });
1111
1175
  return {
1112
1176
  success: false,
1113
1177
  filepath: input.target_filepath,
@@ -1194,6 +1258,7 @@ function sleep(ms) {
1194
1258
  }
1195
1259
 
1196
1260
  // tools/codebase_search/core.ts
1261
+ init_logger();
1197
1262
  var CodebaseSearchClient = class {
1198
1263
  config;
1199
1264
  constructor(config = {}) {
@@ -1231,11 +1296,7 @@ async function executeCodebaseSearch(input, config) {
1231
1296
  }
1232
1297
  const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "https://repos.morphllm.com";
1233
1298
  const timeout = config.timeout || 3e4;
1234
- const debug = config.debug || false;
1235
- if (debug) {
1236
- console.log(`[CodebaseSearch] Query: "${input.query.slice(0, 60)}..." repo=${config.repoId}`);
1237
- console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);
1238
- }
1299
+ logger.debug("CodebaseSearch", "request", { query: input.query.slice(0, 100), repo_id: config.repoId, url: `${searchUrl}/v1/codebase_search` });
1239
1300
  const startTime = Date.now();
1240
1301
  try {
1241
1302
  const fetchPromise = fetchWithRetry(
@@ -1259,7 +1320,7 @@ async function executeCodebaseSearch(input, config) {
1259
1320
  const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);
1260
1321
  if (!response.ok) {
1261
1322
  const errorText = await response.text();
1262
- if (debug) console.error(`[CodebaseSearch] Error: ${response.status} - ${errorText}`);
1323
+ logger.error("CodebaseSearch", "response_error", { status: response.status, error: errorText, latency_ms: Date.now() - startTime });
1263
1324
  return {
1264
1325
  success: false,
1265
1326
  results: [],
@@ -1269,16 +1330,14 @@ async function executeCodebaseSearch(input, config) {
1269
1330
  }
1270
1331
  const data = await response.json();
1271
1332
  const elapsed = Date.now() - startTime;
1272
- if (debug) {
1273
- console.log(`[CodebaseSearch] \u2705 ${data.results?.length || 0} results in ${elapsed}ms`);
1274
- }
1333
+ logger.debug("CodebaseSearch", "response", { results_count: data.results?.length || 0, latency_ms: elapsed });
1275
1334
  return {
1276
1335
  success: true,
1277
1336
  results: data.results || [],
1278
1337
  stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed }
1279
1338
  };
1280
1339
  } catch (error) {
1281
- if (debug) console.error(`[CodebaseSearch] Exception: ${error instanceof Error ? error.message : error}`);
1340
+ logger.error("CodebaseSearch", "exception", { error: error instanceof Error ? error.message : String(error), latency_ms: Date.now() - startTime });
1282
1341
  return {
1283
1342
  success: false,
1284
1343
  results: [],
@@ -1288,6 +1347,9 @@ async function executeCodebaseSearch(input, config) {
1288
1347
  }
1289
1348
  }
1290
1349
 
1350
+ // tools/browser/core.ts
1351
+ init_logger();
1352
+
1291
1353
  // tools/browser/live.ts
1292
1354
  var LIVE_PRESETS = {
1293
1355
  /** Read-only monitoring (no interaction) */
@@ -1984,11 +2046,7 @@ var BrowserClient = class {
1984
2046
  if (!hasTask && !hasDiff) {
1985
2047
  throw new Error('Browser task requires either "task" (natural language) or "diff" (PR-review planning)');
1986
2048
  }
1987
- if (debug) {
1988
- const preview = (input.task ?? "").slice(0, 60);
1989
- console.log(`[Browser] createTask: "${preview}..." url=${input.url || "none"}`);
1990
- console.log(`[Browser] Calling async endpoint: ${apiUrl}/browser-task/async`);
1991
- }
2049
+ logger.debug("Browser", "create_task", { task: (input.task ?? "").slice(0, 100), url: input.url, endpoint: `${apiUrl}/browser-task/async` });
1992
2050
  const headers = { "Content-Type": "application/json" };
1993
2051
  if (this.config.apiKey) headers["Authorization"] = `Bearer ${this.config.apiKey}`;
1994
2052
  const response = await fetch(`${apiUrl}/browser-task/async`, {
@@ -2018,14 +2076,11 @@ var BrowserClient = class {
2018
2076
  });
2019
2077
  if (!response.ok) {
2020
2078
  const errorText = await response.text().catch(() => response.statusText);
2021
- if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
2079
+ logger.error("Browser", "create_task_error", { status: response.status, error: errorText });
2022
2080
  throw new Error(`HTTP ${response.status}: ${errorText}`);
2023
2081
  }
2024
2082
  const result = mapTaskResult(await response.json());
2025
- if (debug) {
2026
- const debugUrl = result.debugUrl;
2027
- console.log(`[Browser] \u2705 Task created: recordingId=${result.recordingId ?? "none"} debugUrl=${debugUrl ? "available" : "none"}`);
2028
- }
2083
+ logger.debug("Browser", "task_created", { recording_id: result.recordingId, task_id: result.taskId, debug_url: !!result.debugUrl });
2029
2084
  if ("schema" in input) {
2030
2085
  return wrapTaskResponseWithSchema(result, this.config, input.schema);
2031
2086
  } else {
@@ -2085,10 +2140,7 @@ async function executeBrowserTask(input, config = {}) {
2085
2140
  error: "maxSteps must be between 1 and 50. Use more steps for complex multi-page flows."
2086
2141
  };
2087
2142
  }
2088
- if (debug) {
2089
- console.log(`[Browser] Task: "${input.task.slice(0, 60)}..." url=${input.url || "none"} maxSteps=${input.maxSteps ?? 10}`);
2090
- console.log(`[Browser] Recording: ${input.recordVideo ? "yes" : "no"} | Calling ${apiUrl}/browser-task`);
2091
- }
2143
+ logger.debug("Browser", "execute_start", { task: input.task.slice(0, 100), url: input.url, max_steps: input.maxSteps ?? 10, record_video: input.recordVideo ?? false });
2092
2144
  const startTime = Date.now();
2093
2145
  try {
2094
2146
  const headers = { "Content-Type": "application/json" };
@@ -2127,14 +2179,12 @@ async function executeBrowserTask(input, config = {}) {
2127
2179
  );
2128
2180
  if (!response.ok) {
2129
2181
  const errorText = await response.text().catch(() => response.statusText);
2130
- if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
2182
+ logger.error("Browser", "execute_error", { status: response.status, error: errorText });
2131
2183
  throw new Error(`HTTP ${response.status}: ${errorText}`);
2132
2184
  }
2133
2185
  const result = mapTaskResult(await response.json());
2134
2186
  const elapsed = Date.now() - startTime;
2135
- if (debug) {
2136
- console.log(`[Browser] \u2705 ${result.success ? "Success" : "Failed"} in ${elapsed}ms | steps=${result.stepsTaken ?? 0} recordingId=${result.recordingId ?? "none"}`);
2137
- }
2187
+ logger.debug("Browser", "execute_complete", { success: result.success, latency_ms: elapsed, steps: result.stepsTaken ?? 0, recording_id: result.recordingId });
2138
2188
  return result;
2139
2189
  } catch (error) {
2140
2190
  if (error instanceof Error) {
@@ -2845,6 +2895,7 @@ function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS
2845
2895
  var import_openai2 = __toESM(require("openai"), 1);
2846
2896
  init_version();
2847
2897
  var import_path4 = __toESM(require("path"), 1);
2898
+ init_logger();
2848
2899
  var DEFAULT_API_URL3 = "https://api.morphllm.com";
2849
2900
  var TOOL_SPECS = [
2850
2901
  {
@@ -2967,6 +3018,8 @@ async function callModel(messages, model, options = {}) {
2967
3018
  defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
2968
3019
  });
2969
3020
  const MAX_EMPTY_RETRIES = 1;
3021
+ logger.debug("WarpGrep", "model_call", { url: baseURL, model, message_count: messages.length });
3022
+ const callStartTime = Date.now();
2970
3023
  for (let attempt = 0; attempt <= MAX_EMPTY_RETRIES; attempt++) {
2971
3024
  let data;
2972
3025
  try {
@@ -2979,10 +3032,16 @@ async function callModel(messages, model, options = {}) {
2979
3032
  ...options.search_type ? { search_type: options.search_type } : {}
2980
3033
  });
2981
3034
  } catch (error) {
2982
- if (error instanceof import_openai2.default.APIError && error.status === 404) {
2983
- 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";
2984
- const errorText = error.message?.trim();
2985
- throw new Error(errorText || defaultMsg);
3035
+ const callLatencyMs = Date.now() - callStartTime;
3036
+ if (error instanceof import_openai2.default.APIError) {
3037
+ logger.error("WarpGrep", "model_call_error", { status: error.status, error: error.message, latency_ms: callLatencyMs });
3038
+ if (error.status === 404) {
3039
+ 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";
3040
+ const errorText = error.message?.trim();
3041
+ throw new Error(errorText || defaultMsg);
3042
+ }
3043
+ } else {
3044
+ logger.error("WarpGrep", "model_call_error", { status: void 0, error: error instanceof Error ? error.message : String(error), latency_ms: callLatencyMs });
2986
3045
  }
2987
3046
  throw error;
2988
3047
  }
@@ -3001,6 +3060,7 @@ async function callModel(messages, model, options = {}) {
3001
3060
  function: { name: tc.function.name, arguments: tc.function.arguments }
3002
3061
  }));
3003
3062
  if (message.content || toolCalls.length > 0) {
3063
+ logger.debug("WarpGrep", "model_call_complete", { latency_ms: Date.now() - callStartTime, tool_calls_count: toolCalls.length, finish_reason: choice?.finish_reason ?? "unknown" });
3004
3064
  return { content: message.content ?? null, tool_calls: toolCalls };
3005
3065
  }
3006
3066
  if (attempt === MAX_EMPTY_RETRIES) {
@@ -3071,9 +3131,11 @@ async function* runWarpGrepStreaming(config) {
3071
3131
  const model = config.model || DEFAULT_MODEL;
3072
3132
  const messages = [];
3073
3133
  const maxTurns = AGENT_CONFIG.MAX_TURNS;
3134
+ logger.debug("WarpGrep", "session_start", { search_term: config.searchTerm, model, max_turns: maxTurns });
3074
3135
  const initialStateStart = Date.now();
3075
3136
  const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });
3076
3137
  timings.initial_state_ms = Date.now() - initialStateStart;
3138
+ logger.debug("WarpGrep", "initial_state", { system_prompt_len: initialState.length, user_message_len: initialState.length });
3077
3139
  messages.push({ role: "user", content: initialState });
3078
3140
  const provider = config.provider;
3079
3141
  const errors = [];
@@ -3081,7 +3143,13 @@ async function* runWarpGrepStreaming(config) {
3081
3143
  let terminationReason = "terminated";
3082
3144
  for (let turn = 1; turn <= maxTurns; turn += 1) {
3083
3145
  const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
3146
+ logger.debug("WarpGrep", "turn_start", { turn, message_count: messages.length });
3147
+ const beforeChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
3084
3148
  enforceContextLimit(messages);
3149
+ const afterChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
3150
+ if (afterChars < beforeChars) {
3151
+ logger.debug("WarpGrep", "context_truncated", { before_chars: beforeChars, after_chars: afterChars });
3152
+ }
3085
3153
  const modelCallStart = Date.now();
3086
3154
  const response = await callModel(messages, model, {
3087
3155
  morphApiKey: config.morphApiKey,
@@ -3092,6 +3160,7 @@ async function* runWarpGrepStreaming(config) {
3092
3160
  }).catch((e) => {
3093
3161
  const errMsg = e instanceof Error ? e.message : String(e);
3094
3162
  console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
3163
+ logger.error("WarpGrep", "error", { turn, error: errMsg, phase: "model_call" });
3095
3164
  errors.push({ message: errMsg });
3096
3165
  return null;
3097
3166
  });
@@ -3101,6 +3170,7 @@ async function* runWarpGrepStreaming(config) {
3101
3170
  break;
3102
3171
  }
3103
3172
  const toolCalls = response.tool_calls;
3173
+ logger.debug("WarpGrep", "model_response", { turn, tool_calls: toolCalls.map((tc) => tc.function.name), latency_ms: turnMetrics.morph_api_ms });
3104
3174
  messages.push({
3105
3175
  role: "assistant",
3106
3176
  content: response.content,
@@ -3127,6 +3197,7 @@ async function* runWarpGrepStreaming(config) {
3127
3197
  const files = parseFinishFiles(filesStr);
3128
3198
  finishMeta = { files };
3129
3199
  terminationReason = "completed";
3200
+ logger.debug("WarpGrep", "finish", { turns: turn, files: files.map((f) => f.path) });
3130
3201
  if (files.length === 0) {
3131
3202
  const payload2 = filesStr || "No relevant code found.";
3132
3203
  timings.turns.push(turnMetrics);
@@ -3145,7 +3216,11 @@ async function* runWarpGrepStreaming(config) {
3145
3216
  const results = await Promise.all(
3146
3217
  toolCalls.map(async (tc) => {
3147
3218
  const args = safeParseJSON(tc.function.arguments);
3219
+ const argsSummary = Object.fromEntries(Object.entries(args).map(([k, v]) => [k, typeof v === "string" && v.length > 100 ? v.slice(0, 100) + "..." : v]));
3220
+ logger.debug("WarpGrep", "tool_exec", { turn, tool: tc.function.name, args_summary: argsSummary });
3221
+ const toolStart = Date.now();
3148
3222
  const output = await executeTool(provider, tc.function.name, args, repoRoot).catch((err) => String(err));
3223
+ logger.debug("WarpGrep", "tool_result", { turn, tool: tc.function.name, result_len: output.length, latency_ms: Date.now() - toolStart });
3149
3224
  return { tool_call_id: tc.id, content: output };
3150
3225
  })
3151
3226
  );
@@ -3214,6 +3289,9 @@ async function runWarpGrep(config) {
3214
3289
  return result.value;
3215
3290
  }
3216
3291
 
3292
+ // tools/warp_grep/client.ts
3293
+ init_logger();
3294
+
3217
3295
  // tools/warp_grep/providers/remote.ts
3218
3296
  init_config();
3219
3297
  var SKIP_NAMES = /* @__PURE__ */ new Set([
@@ -3653,12 +3731,16 @@ var WarpGrepClient = class {
3653
3731
  async _resolveGitHubRepo(input) {
3654
3732
  const { owner, repo } = parseGitHubUrl(input.github);
3655
3733
  const baseUrl = this.config.codeSearchUrl || DEFAULT_CODE_SEARCH_URL;
3734
+ logger.debug("WarpGrep", "github_resolve", { owner_repo: `${owner}/${repo}`, branch: input.branch });
3735
+ const resolveStart = Date.now();
3656
3736
  const importRes = await fetch(`${baseUrl}/api/code-search/get-or-create?url=${encodeURIComponent(`${owner}/${repo}`)}`);
3657
3737
  if (!importRes.ok) {
3658
3738
  const text = await importRes.text().catch(() => importRes.statusText);
3739
+ logger.error("WarpGrep", "github_resolve_failed", { owner_repo: `${owner}/${repo}`, status: importRes.status, error: text });
3659
3740
  throw new Error(`Failed to import repo ${owner}/${repo}: ${text}`);
3660
3741
  }
3661
3742
  const { repoId, defaultBranch } = await importRes.json();
3743
+ logger.debug("WarpGrep", "github_repo_fetched", { repo_id: repoId, default_branch: defaultBranch, latency_ms: Date.now() - resolveStart });
3662
3744
  return {
3663
3745
  repo,
3664
3746
  remoteCommands: createCodeStorageHttpCommands({ baseUrl, repoId, branch: input.branch || defaultBranch })
@@ -4199,7 +4281,7 @@ var GitHubClient = class {
4199
4281
  // git/client.ts
4200
4282
  var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
4201
4283
  var import_node = __toESM(require("isomorphic-git/http/node"), 1);
4202
- var import_fs2 = __toESM(require("fs"), 1);
4284
+ var import_fs3 = __toESM(require("fs"), 1);
4203
4285
  var DEFAULT_PROXY_URL = "https://repos.morphllm.com";
4204
4286
  var MorphGit = class {
4205
4287
  apiKey;
@@ -4256,12 +4338,12 @@ var MorphGit = class {
4256
4338
  throw new Error(`Failed to create repository: ${error}`);
4257
4339
  }
4258
4340
  await import_isomorphic_git.default.init({
4259
- fs: import_fs2.default,
4341
+ fs: import_fs3.default,
4260
4342
  dir,
4261
4343
  defaultBranch
4262
4344
  });
4263
4345
  await import_isomorphic_git.default.addRemote({
4264
- fs: import_fs2.default,
4346
+ fs: import_fs3.default,
4265
4347
  dir,
4266
4348
  remote: "origin",
4267
4349
  url: `${this.proxyUrl}/v1/repos/${repoId}`
@@ -4282,7 +4364,7 @@ var MorphGit = class {
4282
4364
  async clone(options) {
4283
4365
  const { repoId, dir, branch = "main", depth, singleBranch = true } = options;
4284
4366
  await import_isomorphic_git.default.clone({
4285
- fs: import_fs2.default,
4367
+ fs: import_fs3.default,
4286
4368
  http: import_node.default,
4287
4369
  dir,
4288
4370
  url: `${this.proxyUrl}/v1/repos/${repoId}`,
@@ -4311,9 +4393,9 @@ var MorphGit = class {
4311
4393
  'branch is required for push operations. Specify the branch explicitly: { dir: "./my-project", branch: "main" }'
4312
4394
  );
4313
4395
  }
4314
- const commitHash = await import_isomorphic_git.default.resolveRef({ fs: import_fs2.default, dir, ref: "HEAD" });
4396
+ const commitHash = await import_isomorphic_git.default.resolveRef({ fs: import_fs3.default, dir, ref: "HEAD" });
4315
4397
  let repoId;
4316
- const remotes = await import_isomorphic_git.default.listRemotes({ fs: import_fs2.default, dir });
4398
+ const remotes = await import_isomorphic_git.default.listRemotes({ fs: import_fs3.default, dir });
4317
4399
  const originRemote = remotes.find((r) => r.remote === remote);
4318
4400
  if (originRemote) {
4319
4401
  const match = originRemote.url.match(/\/repos\/([^\/]+)$/);
@@ -4322,7 +4404,7 @@ var MorphGit = class {
4322
4404
  }
4323
4405
  }
4324
4406
  await import_isomorphic_git.default.push({
4325
- fs: import_fs2.default,
4407
+ fs: import_fs3.default,
4326
4408
  http: import_node.default,
4327
4409
  dir,
4328
4410
  remote,
@@ -4377,7 +4459,7 @@ var MorphGit = class {
4377
4459
  );
4378
4460
  }
4379
4461
  await import_isomorphic_git.default.pull({
4380
- fs: import_fs2.default,
4462
+ fs: import_fs3.default,
4381
4463
  http: import_node.default,
4382
4464
  dir,
4383
4465
  remote,
@@ -4446,7 +4528,7 @@ var MorphGit = class {
4446
4528
  async add(options) {
4447
4529
  const { dir, filepath } = options;
4448
4530
  await import_isomorphic_git.default.add({
4449
- fs: import_fs2.default,
4531
+ fs: import_fs3.default,
4450
4532
  dir,
4451
4533
  filepath
4452
4534
  });
@@ -4465,7 +4547,7 @@ var MorphGit = class {
4465
4547
  async remove(options) {
4466
4548
  const { dir, filepath } = options;
4467
4549
  await import_isomorphic_git.default.remove({
4468
- fs: import_fs2.default,
4550
+ fs: import_fs3.default,
4469
4551
  dir,
4470
4552
  filepath
4471
4553
  });
@@ -4498,7 +4580,7 @@ var MorphGit = class {
4498
4580
  email: "sdk@morphllm.com"
4499
4581
  };
4500
4582
  const sha = await import_isomorphic_git.default.commit({
4501
- fs: import_fs2.default,
4583
+ fs: import_fs3.default,
4502
4584
  dir,
4503
4585
  message,
4504
4586
  author: commitAuthor
@@ -4511,7 +4593,7 @@ var MorphGit = class {
4511
4593
  _version: 1
4512
4594
  };
4513
4595
  await import_isomorphic_git.default.addNote({
4514
- fs: import_fs2.default,
4596
+ fs: import_fs3.default,
4515
4597
  dir,
4516
4598
  ref: "refs/notes/morph-metadata",
4517
4599
  oid: sha,
@@ -4539,7 +4621,7 @@ var MorphGit = class {
4539
4621
  throw new Error("filepath is required for status check");
4540
4622
  }
4541
4623
  const status = await import_isomorphic_git.default.status({
4542
- fs: import_fs2.default,
4624
+ fs: import_fs3.default,
4543
4625
  dir,
4544
4626
  filepath
4545
4627
  });
@@ -4559,7 +4641,7 @@ var MorphGit = class {
4559
4641
  async log(options) {
4560
4642
  const { dir, depth, ref } = options;
4561
4643
  const commits = await import_isomorphic_git.default.log({
4562
- fs: import_fs2.default,
4644
+ fs: import_fs3.default,
4563
4645
  dir,
4564
4646
  depth,
4565
4647
  ref
@@ -4580,7 +4662,7 @@ var MorphGit = class {
4580
4662
  async checkout(options) {
4581
4663
  const { dir, ref } = options;
4582
4664
  await import_isomorphic_git.default.checkout({
4583
- fs: import_fs2.default,
4665
+ fs: import_fs3.default,
4584
4666
  dir,
4585
4667
  ref
4586
4668
  });
@@ -4600,7 +4682,7 @@ var MorphGit = class {
4600
4682
  async branch(options) {
4601
4683
  const { dir, name, checkout = false } = options;
4602
4684
  await import_isomorphic_git.default.branch({
4603
- fs: import_fs2.default,
4685
+ fs: import_fs3.default,
4604
4686
  dir,
4605
4687
  ref: name,
4606
4688
  checkout
@@ -4619,7 +4701,7 @@ var MorphGit = class {
4619
4701
  async listBranches(options) {
4620
4702
  const { dir } = options;
4621
4703
  const branches = await import_isomorphic_git.default.listBranches({
4622
- fs: import_fs2.default,
4704
+ fs: import_fs3.default,
4623
4705
  dir
4624
4706
  });
4625
4707
  return branches;
@@ -4637,7 +4719,7 @@ var MorphGit = class {
4637
4719
  async currentBranch(options) {
4638
4720
  const { dir } = options;
4639
4721
  const branch = await import_isomorphic_git.default.currentBranch({
4640
- fs: import_fs2.default,
4722
+ fs: import_fs3.default,
4641
4723
  dir
4642
4724
  });
4643
4725
  return branch || void 0;
@@ -4655,7 +4737,7 @@ var MorphGit = class {
4655
4737
  async statusMatrix(options) {
4656
4738
  const { dir } = options;
4657
4739
  const matrix = await import_isomorphic_git.default.statusMatrix({
4658
- fs: import_fs2.default,
4740
+ fs: import_fs3.default,
4659
4741
  dir
4660
4742
  });
4661
4743
  return matrix.map(([filepath, HEADStatus, workdirStatus, stageStatus]) => {
@@ -4697,7 +4779,7 @@ var MorphGit = class {
4697
4779
  async resolveRef(options) {
4698
4780
  const { dir, ref } = options;
4699
4781
  const oid = await import_isomorphic_git.default.resolveRef({
4700
- fs: import_fs2.default,
4782
+ fs: import_fs3.default,
4701
4783
  dir,
4702
4784
  ref
4703
4785
  });
@@ -4723,7 +4805,7 @@ var MorphGit = class {
4723
4805
  async getCommitMetadata(options) {
4724
4806
  try {
4725
4807
  const note = await import_isomorphic_git.default.readNote({
4726
- fs: import_fs2.default,
4808
+ fs: import_fs3.default,
4727
4809
  dir: options.dir,
4728
4810
  ref: "refs/notes/morph-metadata",
4729
4811
  oid: options.commitSha
@@ -4741,6 +4823,7 @@ var import_isomorphic_git2 = __toESM(require("isomorphic-git"), 1);
4741
4823
  var import_node2 = __toESM(require("isomorphic-git/http/node"), 1);
4742
4824
 
4743
4825
  // modelrouter/core.ts
4826
+ init_logger();
4744
4827
  var DEFAULT_CONFIG3 = {
4745
4828
  apiUrl: "https://api.morphllm.com",
4746
4829
  timeout: 5e3,
@@ -4776,12 +4859,7 @@ var BaseRouter = class {
4776
4859
  input: input.input,
4777
4860
  mode
4778
4861
  };
4779
- if (this.config.debug) {
4780
- console.log(`[ModelRouter] Requesting ${this.provider} model selection:`, {
4781
- mode,
4782
- inputLength: input.input.length
4783
- });
4784
- }
4862
+ logger.debug("ModelRouter", "request", { provider: this.provider, mode, input_len: input.input.length, url });
4785
4863
  try {
4786
4864
  const fetchPromise = fetchWithRetry(
4787
4865
  url,
@@ -4810,14 +4888,10 @@ var BaseRouter = class {
4810
4888
  const result = {
4811
4889
  model: apiResult.model
4812
4890
  };
4813
- if (this.config.debug) {
4814
- console.log(`[ModelRouter] Selected model: ${apiResult.model}, Confidence: ${apiResult.confidence?.toFixed(3)}`);
4815
- }
4891
+ logger.debug("ModelRouter", "selected", { provider: this.provider, model: apiResult.model, confidence: apiResult.confidence });
4816
4892
  return result;
4817
4893
  } catch (error) {
4818
- if (this.config.debug) {
4819
- console.error(`[ModelRouter] Error selecting model:`, error);
4820
- }
4894
+ logger.error("ModelRouter", "error", { provider: this.provider, error: error instanceof Error ? error.message : String(error) });
4821
4895
  throw error;
4822
4896
  }
4823
4897
  }
@@ -4887,12 +4961,7 @@ var RawRouter = class extends BaseRouter {
4887
4961
  input: input.input,
4888
4962
  mode
4889
4963
  };
4890
- if (this.config.debug) {
4891
- console.log(`[RawRouter] Requesting raw difficulty classification:`, {
4892
- mode,
4893
- inputLength: input.input.length
4894
- });
4895
- }
4964
+ logger.debug("RawRouter", "request", { mode, input_len: input.input.length, url });
4896
4965
  try {
4897
4966
  const fetchPromise = fetchWithRetry(
4898
4967
  url,
@@ -4927,14 +4996,10 @@ var RawRouter = class extends BaseRouter {
4927
4996
  const result = {
4928
4997
  difficulty
4929
4998
  };
4930
- if (this.config.debug) {
4931
- console.log(`[RawRouter] Classified as: ${difficulty}`);
4932
- }
4999
+ logger.debug("RawRouter", "classified", { difficulty });
4933
5000
  return result;
4934
5001
  } catch (error) {
4935
- if (this.config.debug) {
4936
- console.error(`[RawRouter] Error classifying:`, error);
4937
- }
5002
+ logger.error("RawRouter", "error", { error: error instanceof Error ? error.message : String(error) });
4938
5003
  throw error;
4939
5004
  }
4940
5005
  }
@@ -6360,6 +6425,10 @@ var MorphClient = class {
6360
6425
  */
6361
6426
  constructor(config = {}) {
6362
6427
  this.config = config;
6428
+ if (config.debug) {
6429
+ logger.enable();
6430
+ }
6431
+ logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
6363
6432
  this.fastApply = new FastApplyClient({
6364
6433
  apiKey: config.apiKey,
6365
6434
  debug: config.debug,