@mastra/core 1.16.1-alpha.0 → 1.17.0-alpha.2

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 (192) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/dist/agent/index.cjs +8 -8
  3. package/dist/agent/index.js +1 -1
  4. package/dist/{chunk-XKOCRXCP.js → chunk-4UTQD6B5.js} +3 -3
  5. package/dist/{chunk-XKOCRXCP.js.map → chunk-4UTQD6B5.js.map} +1 -1
  6. package/dist/{chunk-WJEUD4JG.js → chunk-5TKRQNGW.js} +4 -4
  7. package/dist/{chunk-WJEUD4JG.js.map → chunk-5TKRQNGW.js.map} +1 -1
  8. package/dist/{chunk-BEDQJNIR.cjs → chunk-6HSR64XA.cjs} +15 -5
  9. package/dist/chunk-6HSR64XA.cjs.map +1 -0
  10. package/dist/{chunk-LFZXBZR5.cjs → chunk-76NWBCBU.cjs} +9 -9
  11. package/dist/{chunk-LFZXBZR5.cjs.map → chunk-76NWBCBU.cjs.map} +1 -1
  12. package/dist/{chunk-J3NJXIJ4.js → chunk-ABA3KD3X.js} +524 -246
  13. package/dist/chunk-ABA3KD3X.js.map +1 -0
  14. package/dist/{chunk-SNASZNHI.js → chunk-AGEYVARR.js} +2 -2
  15. package/dist/{chunk-SNASZNHI.js.map → chunk-AGEYVARR.js.map} +1 -1
  16. package/dist/{chunk-RQBBPR64.cjs → chunk-AH2ZNH4Y.cjs} +30 -28
  17. package/dist/chunk-AH2ZNH4Y.cjs.map +1 -0
  18. package/dist/{chunk-EXIQD6L3.cjs → chunk-AX5EPGND.cjs} +51 -51
  19. package/dist/{chunk-EXIQD6L3.cjs.map → chunk-AX5EPGND.cjs.map} +1 -1
  20. package/dist/{chunk-BSMSIRKQ.js → chunk-E7L2JB4A.js} +8 -8
  21. package/dist/{chunk-BSMSIRKQ.js.map → chunk-E7L2JB4A.js.map} +1 -1
  22. package/dist/{chunk-RLAMKAFZ.js → chunk-FLW4344C.js} +3 -3
  23. package/dist/{chunk-RLAMKAFZ.js.map → chunk-FLW4344C.js.map} +1 -1
  24. package/dist/{chunk-DKQA3ER2.cjs → chunk-I2Z4GKQ6.cjs} +15 -15
  25. package/dist/{chunk-DKQA3ER2.cjs.map → chunk-I2Z4GKQ6.cjs.map} +1 -1
  26. package/dist/{chunk-LO7V2FG6.cjs → chunk-ID5X55KA.cjs} +7 -7
  27. package/dist/{chunk-LO7V2FG6.cjs.map → chunk-ID5X55KA.cjs.map} +1 -1
  28. package/dist/{chunk-53YOAG3E.js → chunk-JMYTEYXJ.js} +5 -5
  29. package/dist/{chunk-53YOAG3E.js.map → chunk-JMYTEYXJ.js.map} +1 -1
  30. package/dist/{chunk-5TZP6NN4.js → chunk-K76OKOAK.js} +3 -3
  31. package/dist/{chunk-5TZP6NN4.js.map → chunk-K76OKOAK.js.map} +1 -1
  32. package/dist/{chunk-ZJMETLCP.js → chunk-LOGX3EQD.js} +30 -28
  33. package/dist/chunk-LOGX3EQD.js.map +1 -0
  34. package/dist/{chunk-BLBX5SP3.js → chunk-MNIWCQYZ.js} +4 -4
  35. package/dist/{chunk-BLBX5SP3.js.map → chunk-MNIWCQYZ.js.map} +1 -1
  36. package/dist/{chunk-DSFXGE5Y.cjs → chunk-O54IMECL.cjs} +185 -185
  37. package/dist/{chunk-DSFXGE5Y.cjs.map → chunk-O54IMECL.cjs.map} +1 -1
  38. package/dist/{chunk-OC5SNZ6R.cjs → chunk-OBHOUEDZ.cjs} +83 -83
  39. package/dist/{chunk-OC5SNZ6R.cjs.map → chunk-OBHOUEDZ.cjs.map} +1 -1
  40. package/dist/{chunk-OTQY4UJ4.js → chunk-OIZT4TON.js} +476 -27
  41. package/dist/chunk-OIZT4TON.js.map +1 -0
  42. package/dist/{chunk-LIVMJB3N.cjs → chunk-P54SNCAD.cjs} +3 -3
  43. package/dist/{chunk-LIVMJB3N.cjs.map → chunk-P54SNCAD.cjs.map} +1 -1
  44. package/dist/{chunk-DXRM6H35.js → chunk-PICHLY3C.js} +4 -4
  45. package/dist/{chunk-DXRM6H35.js.map → chunk-PICHLY3C.js.map} +1 -1
  46. package/dist/{chunk-7L2ICIDI.cjs → chunk-PQ4CVQXD.cjs} +6 -6
  47. package/dist/{chunk-7L2ICIDI.cjs.map → chunk-PQ4CVQXD.cjs.map} +1 -1
  48. package/dist/{chunk-O7JQYUXP.cjs → chunk-PTRJHO2K.cjs} +7 -7
  49. package/dist/{chunk-O7JQYUXP.cjs.map → chunk-PTRJHO2K.cjs.map} +1 -1
  50. package/dist/{chunk-SQACXTWK.cjs → chunk-QVQ3PGG2.cjs} +2 -2
  51. package/dist/{chunk-SQACXTWK.cjs.map → chunk-QVQ3PGG2.cjs.map} +1 -1
  52. package/dist/{chunk-XW4B2RAG.cjs → chunk-QVVWKMFM.cjs} +525 -248
  53. package/dist/chunk-QVVWKMFM.cjs.map +1 -0
  54. package/dist/{chunk-5S7MQ37C.cjs → chunk-R47HLGU7.cjs} +512 -61
  55. package/dist/chunk-R47HLGU7.cjs.map +1 -0
  56. package/dist/{chunk-R67VVUDR.cjs → chunk-SDSIVJMT.cjs} +16 -16
  57. package/dist/{chunk-R67VVUDR.cjs.map → chunk-SDSIVJMT.cjs.map} +1 -1
  58. package/dist/{chunk-UGXRRSSU.js → chunk-UOCBF4IP.js} +3 -3
  59. package/dist/{chunk-UGXRRSSU.js.map → chunk-UOCBF4IP.js.map} +1 -1
  60. package/dist/{chunk-GVHOPNRI.js → chunk-X234OVG3.js} +14 -4
  61. package/dist/chunk-X234OVG3.js.map +1 -0
  62. package/dist/{chunk-XVP3C4KW.cjs → chunk-XTN63GKI.cjs} +7 -7
  63. package/dist/{chunk-XVP3C4KW.cjs.map → chunk-XTN63GKI.cjs.map} +1 -1
  64. package/dist/{chunk-NJONWVEJ.js → chunk-YBNI2A6Y.js} +8 -8
  65. package/dist/{chunk-NJONWVEJ.js.map → chunk-YBNI2A6Y.js.map} +1 -1
  66. package/dist/{chunk-UXFQJJQG.js → chunk-ZT26XXEB.js} +5 -5
  67. package/dist/{chunk-UXFQJJQG.js.map → chunk-ZT26XXEB.js.map} +1 -1
  68. package/dist/datasets/index.cjs +17 -17
  69. package/dist/datasets/index.js +2 -2
  70. package/dist/docs/SKILL.md +4 -1
  71. package/dist/docs/assets/SOURCE_MAP.json +364 -354
  72. package/dist/docs/references/docs-memory-observational-memory.md +7 -5
  73. package/dist/docs/references/docs-observability-tracing-bridges-otel.md +3 -3
  74. package/dist/docs/references/docs-workspace-lsp.md +116 -0
  75. package/dist/docs/references/docs-workspace-overview.md +15 -1
  76. package/dist/docs/references/guides-agent-frameworks-ai-sdk.md +3 -3
  77. package/dist/docs/references/reference-ai-sdk-with-mastra.md +2 -2
  78. package/dist/docs/references/reference-auth-okta.md +162 -0
  79. package/dist/docs/references/reference-client-js-agents.md +2 -2
  80. package/dist/docs/references/reference-harness-harness-class.md +2 -0
  81. package/dist/docs/references/reference-memory-observational-memory.md +2 -2
  82. package/dist/docs/references/reference-observability-tracing-interfaces.md +1 -1
  83. package/dist/docs/references/reference-processors-message-history-processor.md +1 -1
  84. package/dist/docs/references/reference-processors-processor-interface.md +3 -3
  85. package/dist/docs/references/reference-processors-semantic-recall-processor.md +1 -1
  86. package/dist/docs/references/reference-processors-skill-search-processor.md +93 -0
  87. package/dist/docs/references/reference-processors-tool-call-filter.md +2 -2
  88. package/dist/docs/references/reference-processors-working-memory-processor.md +1 -1
  89. package/dist/docs/references/reference-tools-mcp-client.md +1 -1
  90. package/dist/docs/references/reference.md +2 -0
  91. package/dist/evals/index.cjs +20 -20
  92. package/dist/evals/index.js +3 -3
  93. package/dist/evals/scoreTraces/index.cjs +5 -5
  94. package/dist/evals/scoreTraces/index.js +2 -2
  95. package/dist/harness/harness.d.ts +4 -5
  96. package/dist/harness/harness.d.ts.map +1 -1
  97. package/dist/harness/index.cjs +44 -12
  98. package/dist/harness/index.cjs.map +1 -1
  99. package/dist/harness/index.d.ts +1 -1
  100. package/dist/harness/index.d.ts.map +1 -1
  101. package/dist/harness/index.js +39 -7
  102. package/dist/harness/index.js.map +1 -1
  103. package/dist/harness/types.d.ts +18 -4
  104. package/dist/harness/types.d.ts.map +1 -1
  105. package/dist/index.cjs +2 -2
  106. package/dist/index.js +1 -1
  107. package/dist/llm/index.cjs +16 -16
  108. package/dist/llm/index.js +5 -5
  109. package/dist/llm/model/provider-types.generated.d.ts +5 -0
  110. package/dist/loop/index.cjs +14 -14
  111. package/dist/loop/index.js +1 -1
  112. package/dist/mastra/index.cjs +2 -2
  113. package/dist/mastra/index.js +1 -1
  114. package/dist/memory/index.cjs +14 -14
  115. package/dist/memory/index.js +1 -1
  116. package/dist/memory/types.d.ts +4 -0
  117. package/dist/memory/types.d.ts.map +1 -1
  118. package/dist/models-dev-DYILKQKY.js +3 -0
  119. package/dist/{models-dev-DMH6Y26P.js.map → models-dev-DYILKQKY.js.map} +1 -1
  120. package/dist/models-dev-EX67IAAF.cjs +12 -0
  121. package/dist/{models-dev-YEVVUBSG.cjs.map → models-dev-EX67IAAF.cjs.map} +1 -1
  122. package/dist/netlify-EDK4WKCW.cjs +12 -0
  123. package/dist/{netlify-CQVRCF2F.cjs.map → netlify-EDK4WKCW.cjs.map} +1 -1
  124. package/dist/netlify-RQLBHLLX.js +3 -0
  125. package/dist/{netlify-IAN7GQOF.js.map → netlify-RQLBHLLX.js.map} +1 -1
  126. package/dist/processor-provider/index.cjs +10 -10
  127. package/dist/processor-provider/index.js +1 -1
  128. package/dist/processors/index.cjs +50 -42
  129. package/dist/processors/index.js +1 -1
  130. package/dist/processors/processors/index.d.ts +2 -0
  131. package/dist/processors/processors/index.d.ts.map +1 -1
  132. package/dist/processors/processors/skill-search.d.ts +111 -0
  133. package/dist/processors/processors/skill-search.d.ts.map +1 -0
  134. package/dist/processors/tool-result-reminder.d.ts +32 -0
  135. package/dist/processors/tool-result-reminder.d.ts.map +1 -0
  136. package/dist/provider-registry-3RCP7DTQ.js +3 -0
  137. package/dist/{provider-registry-PBDYA2JQ.js.map → provider-registry-3RCP7DTQ.js.map} +1 -1
  138. package/dist/provider-registry-MBXOBTD4.cjs +40 -0
  139. package/dist/{provider-registry-CCLGCN3B.cjs.map → provider-registry-MBXOBTD4.cjs.map} +1 -1
  140. package/dist/provider-registry.json +10 -0
  141. package/dist/relevance/index.cjs +3 -3
  142. package/dist/relevance/index.js +1 -1
  143. package/dist/storage/constants.cjs +56 -56
  144. package/dist/storage/constants.js +1 -1
  145. package/dist/storage/index.cjs +160 -160
  146. package/dist/storage/index.js +2 -2
  147. package/dist/storage/types.d.ts +2 -0
  148. package/dist/storage/types.d.ts.map +1 -1
  149. package/dist/stream/index.cjs +8 -8
  150. package/dist/stream/index.js +1 -1
  151. package/dist/test-utils/llm-mock.cjs +4 -4
  152. package/dist/test-utils/llm-mock.js +1 -1
  153. package/dist/tool-loop-agent/index.cjs +4 -4
  154. package/dist/tool-loop-agent/index.js +1 -1
  155. package/dist/tools/tool-builder/builder.d.ts.map +1 -1
  156. package/dist/utils.cjs +23 -23
  157. package/dist/utils.js +1 -1
  158. package/dist/vector/index.cjs +7 -7
  159. package/dist/vector/index.js +1 -1
  160. package/dist/workflows/evented/index.cjs +10 -10
  161. package/dist/workflows/evented/index.js +1 -1
  162. package/dist/workflows/index.cjs +24 -24
  163. package/dist/workflows/index.js +1 -1
  164. package/dist/workspace/constants/index.d.ts +4 -1
  165. package/dist/workspace/constants/index.d.ts.map +1 -1
  166. package/dist/workspace/index.cjs +68 -68
  167. package/dist/workspace/index.js +1 -1
  168. package/dist/workspace/lsp/client.d.ts +30 -0
  169. package/dist/workspace/lsp/client.d.ts.map +1 -1
  170. package/dist/workspace/lsp/manager.d.ts +11 -0
  171. package/dist/workspace/lsp/manager.d.ts.map +1 -1
  172. package/dist/workspace/tools/index.d.ts +1 -0
  173. package/dist/workspace/tools/index.d.ts.map +1 -1
  174. package/dist/workspace/tools/lsp-inspect.d.ts +13 -0
  175. package/dist/workspace/tools/lsp-inspect.d.ts.map +1 -0
  176. package/dist/workspace/tools/tools.d.ts.map +1 -1
  177. package/package.json +4 -4
  178. package/src/llm/model/provider-types.generated.d.ts +5 -0
  179. package/dist/chunk-5S7MQ37C.cjs.map +0 -1
  180. package/dist/chunk-BEDQJNIR.cjs.map +0 -1
  181. package/dist/chunk-GVHOPNRI.js.map +0 -1
  182. package/dist/chunk-J3NJXIJ4.js.map +0 -1
  183. package/dist/chunk-OTQY4UJ4.js.map +0 -1
  184. package/dist/chunk-RQBBPR64.cjs.map +0 -1
  185. package/dist/chunk-XW4B2RAG.cjs.map +0 -1
  186. package/dist/chunk-ZJMETLCP.js.map +0 -1
  187. package/dist/models-dev-DMH6Y26P.js +0 -3
  188. package/dist/models-dev-YEVVUBSG.cjs +0 -12
  189. package/dist/netlify-CQVRCF2F.cjs +0 -12
  190. package/dist/netlify-IAN7GQOF.js +0 -3
  191. package/dist/provider-registry-CCLGCN3B.cjs +0 -40
  192. package/dist/provider-registry-PBDYA2JQ.js +0 -3
@@ -100,68 +100,68 @@ var WorkspaceReadOnlyError = class extends WorkspaceError {
100
100
  }
101
101
  };
102
102
  var FilesystemError = class extends Error {
103
- constructor(message, code, path7) {
103
+ constructor(message, code, path8) {
104
104
  super(message);
105
105
  this.code = code;
106
- this.path = path7;
106
+ this.path = path8;
107
107
  this.name = "FilesystemError";
108
108
  }
109
109
  };
110
110
  var FileNotFoundError = class extends FilesystemError {
111
- constructor(path7) {
112
- super(`File not found: ${path7}`, "ENOENT", path7);
111
+ constructor(path8) {
112
+ super(`File not found: ${path8}`, "ENOENT", path8);
113
113
  this.name = "FileNotFoundError";
114
114
  }
115
115
  };
116
116
  var DirectoryNotFoundError = class extends FilesystemError {
117
- constructor(path7) {
118
- super(`Directory not found: ${path7}`, "ENOENT", path7);
117
+ constructor(path8) {
118
+ super(`Directory not found: ${path8}`, "ENOENT", path8);
119
119
  this.name = "DirectoryNotFoundError";
120
120
  }
121
121
  };
122
122
  var FileExistsError = class extends FilesystemError {
123
- constructor(path7) {
124
- super(`File already exists: ${path7}`, "EEXIST", path7);
123
+ constructor(path8) {
124
+ super(`File already exists: ${path8}`, "EEXIST", path8);
125
125
  this.name = "FileExistsError";
126
126
  }
127
127
  };
128
128
  var IsDirectoryError = class extends FilesystemError {
129
- constructor(path7) {
130
- super(`Path is a directory: ${path7}`, "EISDIR", path7);
129
+ constructor(path8) {
130
+ super(`Path is a directory: ${path8}`, "EISDIR", path8);
131
131
  this.name = "IsDirectoryError";
132
132
  }
133
133
  };
134
134
  var NotDirectoryError = class extends FilesystemError {
135
- constructor(path7) {
136
- super(`Path is not a directory: ${path7}`, "ENOTDIR", path7);
135
+ constructor(path8) {
136
+ super(`Path is not a directory: ${path8}`, "ENOTDIR", path8);
137
137
  this.name = "NotDirectoryError";
138
138
  }
139
139
  };
140
140
  var DirectoryNotEmptyError = class extends FilesystemError {
141
- constructor(path7) {
142
- super(`Directory not empty: ${path7}`, "ENOTEMPTY", path7);
141
+ constructor(path8) {
142
+ super(`Directory not empty: ${path8}`, "ENOTEMPTY", path8);
143
143
  this.name = "DirectoryNotEmptyError";
144
144
  }
145
145
  };
146
146
  var PermissionError = class extends FilesystemError {
147
- constructor(path7, operation) {
148
- super(`Permission denied: ${operation} on ${path7}`, "EACCES", path7);
147
+ constructor(path8, operation) {
148
+ super(`Permission denied: ${operation} on ${path8}`, "EACCES", path8);
149
149
  this.operation = operation;
150
150
  this.name = "PermissionError";
151
151
  }
152
152
  };
153
153
  var FileReadRequiredError = class extends FilesystemError {
154
- constructor(path7, reason) {
155
- super(reason, "EREAD_REQUIRED", path7);
154
+ constructor(path8, reason) {
155
+ super(reason, "EREAD_REQUIRED", path8);
156
156
  this.name = "FileReadRequiredError";
157
157
  }
158
158
  };
159
159
  var StaleFileError = class extends FilesystemError {
160
- constructor(path7, expectedMtime, actualMtime) {
160
+ constructor(path8, expectedMtime, actualMtime) {
161
161
  super(
162
- `File was modified externally: ${path7} (expected mtime ${expectedMtime.toISOString()}, actual ${actualMtime.toISOString()})`,
162
+ `File was modified externally: ${path8} (expected mtime ${expectedMtime.toISOString()}, actual ${actualMtime.toISOString()})`,
163
163
  "ESTALE",
164
- path7
164
+ path8
165
165
  );
166
166
  this.expectedMtime = expectedMtime;
167
167
  this.actualMtime = actualMtime;
@@ -200,14 +200,14 @@ var CompositeFilesystem = class {
200
200
  constructor(config) {
201
201
  this.id = `cfs-${Date.now().toString(36)}`;
202
202
  this._mounts = /* @__PURE__ */ new Map();
203
- for (const [path7, fs5] of Object.entries(config.mounts)) {
204
- const normalized = this.normalizePath(path7);
205
- this._mounts.set(normalized, fs5);
203
+ for (const [path8, fs6] of Object.entries(config.mounts)) {
204
+ const normalized = this.normalizePath(path8);
205
+ this._mounts.set(normalized, fs6);
206
206
  }
207
207
  if (this._mounts.size === 0) {
208
208
  throw new Error("CompositeFilesystem requires at least one mount");
209
209
  }
210
- this.readOnly = [...this._mounts.values()].every((fs5) => fs5.readOnly) || void 0;
210
+ this.readOnly = [...this._mounts.values()].every((fs6) => fs6.readOnly) || void 0;
211
211
  const mountPaths = [...this._mounts.keys()];
212
212
  for (const a of mountPaths) {
213
213
  for (const b of mountPaths) {
@@ -236,8 +236,8 @@ var CompositeFilesystem = class {
236
236
  */
237
237
  async getInfo() {
238
238
  const mounts = {};
239
- for (const [mountPath, fs5] of this._mounts) {
240
- mounts[mountPath] = await fs5.getInfo?.() ?? null;
239
+ for (const [mountPath, fs6] of this._mounts) {
240
+ mounts[mountPath] = await fs6.getInfo?.() ?? null;
241
241
  }
242
242
  return {
243
243
  id: this.id,
@@ -252,42 +252,42 @@ var CompositeFilesystem = class {
252
252
  * Get the underlying filesystem for a given path.
253
253
  * Returns undefined if the path doesn't resolve to any mount.
254
254
  */
255
- getFilesystemForPath(path7) {
256
- const resolved = this.resolveMount(path7);
255
+ getFilesystemForPath(path8) {
256
+ const resolved = this.resolveMount(path8);
257
257
  return resolved?.fs;
258
258
  }
259
259
  /**
260
260
  * Get the mount path for a given path.
261
261
  * Returns undefined if the path doesn't resolve to any mount.
262
262
  */
263
- getMountPathForPath(path7) {
264
- const resolved = this.resolveMount(path7);
263
+ getMountPathForPath(path8) {
264
+ const resolved = this.resolveMount(path8);
265
265
  return resolved?.mountPath;
266
266
  }
267
267
  /**
268
268
  * Resolve a workspace-relative path to an absolute disk path.
269
269
  * Strips the mount prefix and delegates to the underlying filesystem.
270
270
  */
271
- resolveAbsolutePath(path7) {
272
- const r = this.resolveMount(path7);
271
+ resolveAbsolutePath(path8) {
272
+ const r = this.resolveMount(path8);
273
273
  if (!r) return void 0;
274
274
  return r.fs.resolveAbsolutePath?.(r.fsPath);
275
275
  }
276
- normalizePath(path7) {
277
- if (!path7 || path7 === "/" || path7 === ".") return "/";
278
- let n = posixPath__default.default.normalize(path7);
276
+ normalizePath(path8) {
277
+ if (!path8 || path8 === "/" || path8 === ".") return "/";
278
+ let n = posixPath__default.default.normalize(path8);
279
279
  if (n === ".") return "/";
280
280
  if (!n.startsWith("/")) n = `/${n}`;
281
281
  if (n.length > 1 && n.endsWith("/")) n = n.slice(0, -1);
282
282
  return n;
283
283
  }
284
- resolveMount(path7) {
285
- const normalized = this.normalizePath(path7);
284
+ resolveMount(path8) {
285
+ const normalized = this.normalizePath(path8);
286
286
  let best = null;
287
- for (const [mountPath, fs5] of this._mounts) {
287
+ for (const [mountPath, fs6] of this._mounts) {
288
288
  if (normalized === mountPath || normalized.startsWith(mountPath + "/")) {
289
289
  if (!best || mountPath.length > best.mountPath.length) {
290
- best = { mountPath, fs: fs5 };
290
+ best = { mountPath, fs: fs6 };
291
291
  }
292
292
  }
293
293
  }
@@ -297,11 +297,11 @@ var CompositeFilesystem = class {
297
297
  else if (fsPath.startsWith("/")) fsPath = fsPath.slice(1);
298
298
  return { fs: best.fs, fsPath, mountPath: best.mountPath };
299
299
  }
300
- getVirtualEntries(path7) {
301
- const normalized = this.normalizePath(path7);
300
+ getVirtualEntries(path8) {
301
+ const normalized = this.normalizePath(path8);
302
302
  if (this.resolveMount(normalized)) return null;
303
303
  const entriesMap = /* @__PURE__ */ new Map();
304
- for (const [mountPath, fs5] of this._mounts.entries()) {
304
+ for (const [mountPath, fs6] of this._mounts.entries()) {
305
305
  const isUnder = normalized === "/" ? mountPath.startsWith("/") : mountPath.startsWith(normalized + "/");
306
306
  if (isUnder) {
307
307
  const remaining = normalized === "/" ? mountPath.slice(1) : mountPath.slice(normalized.length + 1);
@@ -311,12 +311,12 @@ var CompositeFilesystem = class {
311
311
  const entry = { name: next, type: "directory" };
312
312
  if (isDirectMount) {
313
313
  entry.mount = {
314
- provider: fs5.provider,
315
- icon: fs5.icon,
316
- displayName: fs5.displayName,
317
- description: fs5.description,
318
- status: fs5.status,
319
- error: fs5.error
314
+ provider: fs6.provider,
315
+ icon: fs6.icon,
316
+ displayName: fs6.displayName,
317
+ description: fs6.description,
318
+ status: fs6.status,
319
+ error: fs6.error
320
320
  };
321
321
  }
322
322
  entriesMap.set(next, entry);
@@ -325,8 +325,8 @@ var CompositeFilesystem = class {
325
325
  }
326
326
  return entriesMap.size > 0 ? Array.from(entriesMap.values()) : null;
327
327
  }
328
- isVirtualPath(path7) {
329
- const normalized = this.normalizePath(path7);
328
+ isVirtualPath(path8) {
329
+ const normalized = this.normalizePath(path8);
330
330
  if (normalized === "/" && !this._mounts.has("/")) return true;
331
331
  for (const mountPath of this._mounts.keys()) {
332
332
  if (mountPath.startsWith(normalized + "/")) return true;
@@ -337,9 +337,9 @@ var CompositeFilesystem = class {
337
337
  * Assert that a filesystem is writable (not read-only).
338
338
  * @throws {PermissionError} if the filesystem is read-only
339
339
  */
340
- assertWritable(fs5, path7, operation) {
341
- if (fs5.readOnly) {
342
- throw new PermissionError(path7, `${operation} (filesystem is read-only)`);
340
+ assertWritable(fs6, path8, operation) {
341
+ if (fs6.readOnly) {
342
+ throw new PermissionError(path8, `${operation} (filesystem is read-only)`);
343
343
  }
344
344
  }
345
345
  // ===========================================================================
@@ -347,9 +347,9 @@ var CompositeFilesystem = class {
347
347
  // ===========================================================================
348
348
  async init() {
349
349
  this.status = "initializing";
350
- for (const [mountPath, fs5] of this._mounts.entries()) {
350
+ for (const [mountPath, fs6] of this._mounts.entries()) {
351
351
  try {
352
- await callLifecycle(fs5, "init");
352
+ await callLifecycle(fs6, "init");
353
353
  } catch (e) {
354
354
  const message = e instanceof Error ? e.message : String(e);
355
355
  console.warn(`[CompositeFilesystem] Mount "${mountPath}" failed to initialize: ${message}`);
@@ -360,9 +360,9 @@ var CompositeFilesystem = class {
360
360
  async destroy() {
361
361
  this.status = "destroying";
362
362
  const errors = [];
363
- for (const fs5 of this._mounts.values()) {
363
+ for (const fs6 of this._mounts.values()) {
364
364
  try {
365
- await callLifecycle(fs5, "destroy");
365
+ await callLifecycle(fs6, "destroy");
366
366
  } catch (e) {
367
367
  errors.push(e instanceof Error ? e : new Error(String(e)));
368
368
  }
@@ -373,27 +373,27 @@ var CompositeFilesystem = class {
373
373
  }
374
374
  this.status = "destroyed";
375
375
  }
376
- async readFile(path7, options) {
377
- const r = this.resolveMount(path7);
378
- if (!r) throw new Error(`No mount for path: ${path7}`);
376
+ async readFile(path8, options) {
377
+ const r = this.resolveMount(path8);
378
+ if (!r) throw new Error(`No mount for path: ${path8}`);
379
379
  return r.fs.readFile(r.fsPath, options);
380
380
  }
381
- async writeFile(path7, content, options) {
382
- const r = this.resolveMount(path7);
383
- if (!r) throw new Error(`No mount for path: ${path7}`);
384
- this.assertWritable(r.fs, path7, "writeFile");
381
+ async writeFile(path8, content, options) {
382
+ const r = this.resolveMount(path8);
383
+ if (!r) throw new Error(`No mount for path: ${path8}`);
384
+ this.assertWritable(r.fs, path8, "writeFile");
385
385
  return r.fs.writeFile(r.fsPath, content, options);
386
386
  }
387
- async appendFile(path7, content) {
388
- const r = this.resolveMount(path7);
389
- if (!r) throw new Error(`No mount for path: ${path7}`);
390
- this.assertWritable(r.fs, path7, "appendFile");
387
+ async appendFile(path8, content) {
388
+ const r = this.resolveMount(path8);
389
+ if (!r) throw new Error(`No mount for path: ${path8}`);
390
+ this.assertWritable(r.fs, path8, "appendFile");
391
391
  return r.fs.appendFile(r.fsPath, content);
392
392
  }
393
- async deleteFile(path7, options) {
394
- const r = this.resolveMount(path7);
395
- if (!r) throw new Error(`No mount for path: ${path7}`);
396
- this.assertWritable(r.fs, path7, "deleteFile");
393
+ async deleteFile(path8, options) {
394
+ const r = this.resolveMount(path8);
395
+ if (!r) throw new Error(`No mount for path: ${path8}`);
396
+ this.assertWritable(r.fs, path8, "deleteFile");
397
397
  return r.fs.deleteFile(r.fsPath, options);
398
398
  }
399
399
  async copyFile(src, dest, options) {
@@ -421,35 +421,35 @@ var CompositeFilesystem = class {
421
421
  await this.copyFile(src, dest, options);
422
422
  await srcR.fs.deleteFile(srcR.fsPath);
423
423
  }
424
- async readdir(path7, options) {
425
- const virtual = this.getVirtualEntries(path7);
424
+ async readdir(path8, options) {
425
+ const virtual = this.getVirtualEntries(path8);
426
426
  if (virtual) return virtual;
427
- const r = this.resolveMount(path7);
428
- if (!r) throw new Error(`No mount for path: ${path7}`);
427
+ const r = this.resolveMount(path8);
428
+ if (!r) throw new Error(`No mount for path: ${path8}`);
429
429
  return r.fs.readdir(r.fsPath, options);
430
430
  }
431
- async mkdir(path7, options) {
432
- const r = this.resolveMount(path7);
433
- if (!r) throw new Error(`No mount for path: ${path7}`);
434
- this.assertWritable(r.fs, path7, "mkdir");
431
+ async mkdir(path8, options) {
432
+ const r = this.resolveMount(path8);
433
+ if (!r) throw new Error(`No mount for path: ${path8}`);
434
+ this.assertWritable(r.fs, path8, "mkdir");
435
435
  return r.fs.mkdir(r.fsPath, options);
436
436
  }
437
- async rmdir(path7, options) {
438
- const r = this.resolveMount(path7);
439
- if (!r) throw new Error(`No mount for path: ${path7}`);
440
- this.assertWritable(r.fs, path7, "rmdir");
437
+ async rmdir(path8, options) {
438
+ const r = this.resolveMount(path8);
439
+ if (!r) throw new Error(`No mount for path: ${path8}`);
440
+ this.assertWritable(r.fs, path8, "rmdir");
441
441
  return r.fs.rmdir(r.fsPath, options);
442
442
  }
443
- async exists(path7) {
444
- if (this.isVirtualPath(path7)) return true;
445
- const r = this.resolveMount(path7);
443
+ async exists(path8) {
444
+ if (this.isVirtualPath(path8)) return true;
445
+ const r = this.resolveMount(path8);
446
446
  if (!r) return false;
447
447
  if (r.fsPath === "") return true;
448
448
  return r.fs.exists(r.fsPath);
449
449
  }
450
- async stat(path7) {
451
- const normalized = this.normalizePath(path7);
452
- if (this.isVirtualPath(path7)) {
450
+ async stat(path8) {
451
+ const normalized = this.normalizePath(path8);
452
+ if (this.isVirtualPath(path8)) {
453
453
  const parts = normalized.split("/").filter(Boolean);
454
454
  const now = /* @__PURE__ */ new Date();
455
455
  return {
@@ -461,8 +461,8 @@ var CompositeFilesystem = class {
461
461
  modifiedAt: now
462
462
  };
463
463
  }
464
- const r = this.resolveMount(path7);
465
- if (!r) throw new Error(`No mount for path: ${path7}`);
464
+ const r = this.resolveMount(path8);
465
+ if (!r) throw new Error(`No mount for path: ${path8}`);
466
466
  if (r.fsPath === "") {
467
467
  const parts = normalized.split("/").filter(Boolean);
468
468
  const now = /* @__PURE__ */ new Date();
@@ -477,9 +477,9 @@ var CompositeFilesystem = class {
477
477
  }
478
478
  return r.fs.stat(r.fsPath);
479
479
  }
480
- async isFile(path7) {
481
- if (this.isVirtualPath(path7)) return false;
482
- const r = this.resolveMount(path7);
480
+ async isFile(path8) {
481
+ if (this.isVirtualPath(path8)) return false;
482
+ const r = this.resolveMount(path8);
483
483
  if (!r) return false;
484
484
  try {
485
485
  const stat3 = await r.fs.stat(r.fsPath);
@@ -488,9 +488,9 @@ var CompositeFilesystem = class {
488
488
  return false;
489
489
  }
490
490
  }
491
- async isDirectory(path7) {
492
- if (this.isVirtualPath(path7)) return true;
493
- const r = this.resolveMount(path7);
491
+ async isDirectory(path8) {
492
+ if (this.isVirtualPath(path8)) return true;
493
+ const r = this.resolveMount(path8);
494
494
  if (!r) return false;
495
495
  if (r.fsPath === "") return true;
496
496
  try {
@@ -505,9 +505,9 @@ var CompositeFilesystem = class {
505
505
  * Used by agents to understand available storage locations.
506
506
  */
507
507
  getInstructions(_opts) {
508
- const mountDescriptions = Array.from(this._mounts.entries()).map(([mountPath, fs5]) => {
509
- const name = fs5.displayName || fs5.provider;
510
- const access3 = fs5.readOnly ? "(read-only)" : "(read-write)";
508
+ const mountDescriptions = Array.from(this._mounts.entries()).map(([mountPath, fs6]) => {
509
+ const name = fs6.displayName || fs6.provider;
510
+ const access3 = fs6.readOnly ? "(read-only)" : "(read-write)";
511
511
  return `- ${mountPath}: ${name} ${access3}`;
512
512
  }).join("\n");
513
513
  return `Filesystem mount points:
@@ -1375,35 +1375,35 @@ var LocalFilesystem = class extends MastraFilesystem {
1375
1375
  };
1376
1376
  var InMemoryFileReadTracker = class {
1377
1377
  records = /* @__PURE__ */ new Map();
1378
- recordRead(path7, modifiedAt) {
1379
- const normalizedPath = this.normalizePath(path7);
1378
+ recordRead(path8, modifiedAt) {
1379
+ const normalizedPath = this.normalizePath(path8);
1380
1380
  this.records.set(normalizedPath, {
1381
1381
  path: normalizedPath,
1382
1382
  readAt: /* @__PURE__ */ new Date(),
1383
1383
  modifiedAtRead: modifiedAt
1384
1384
  });
1385
1385
  }
1386
- getReadRecord(path7) {
1387
- return this.records.get(this.normalizePath(path7));
1386
+ getReadRecord(path8) {
1387
+ return this.records.get(this.normalizePath(path8));
1388
1388
  }
1389
- needsReRead(path7, currentModifiedAt) {
1390
- const record = this.getReadRecord(path7);
1389
+ needsReRead(path8, currentModifiedAt) {
1390
+ const record = this.getReadRecord(path8);
1391
1391
  if (!record) {
1392
1392
  return {
1393
1393
  needsReRead: true,
1394
- reason: `File "${path7}" has not been read. You must read a file before writing to it.`
1394
+ reason: `File "${path8}" has not been read. You must read a file before writing to it.`
1395
1395
  };
1396
1396
  }
1397
1397
  if (currentModifiedAt.getTime() > record.modifiedAtRead.getTime()) {
1398
1398
  return {
1399
1399
  needsReRead: true,
1400
- reason: `File "${path7}" was modified since last read (read at: ${record.modifiedAtRead.toISOString()}, current: ${currentModifiedAt.toISOString()}). Please re-read the file to get the latest contents.`
1400
+ reason: `File "${path8}" was modified since last read (read at: ${record.modifiedAtRead.toISOString()}, current: ${currentModifiedAt.toISOString()}). Please re-read the file to get the latest contents.`
1401
1401
  };
1402
1402
  }
1403
1403
  return { needsReRead: false };
1404
1404
  }
1405
- clearReadRecord(path7) {
1406
- this.records.delete(this.normalizePath(path7));
1405
+ clearReadRecord(path8) {
1406
+ this.records.delete(this.normalizePath(path8));
1407
1407
  }
1408
1408
  clear() {
1409
1409
  this.records.clear();
@@ -1491,10 +1491,10 @@ function createGlobMatcher(patterns, options) {
1491
1491
  posix: true,
1492
1492
  dot: options?.dot ?? false
1493
1493
  });
1494
- return (path7) => matcher(normalizeForMatch(path7));
1494
+ return (path8) => matcher(normalizeForMatch(path8));
1495
1495
  }
1496
- function matchGlob(path7, pattern, options) {
1497
- return createGlobMatcher(pattern, options)(path7);
1496
+ function matchGlob(path8, pattern, options) {
1497
+ return createGlobMatcher(pattern, options)(path8);
1498
1498
  }
1499
1499
  async function walkAll(readdir4, dir, depth, maxDepth) {
1500
1500
  if (depth >= maxDepth) return [];
@@ -1584,7 +1584,7 @@ function isLSPAvailable() {
1584
1584
  return jsonrpcModule !== null;
1585
1585
  }
1586
1586
  try {
1587
- const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-XW4B2RAG.cjs', document.baseURI).href)));
1587
+ const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-QVVWKMFM.cjs', document.baseURI).href)));
1588
1588
  req.resolve("vscode-jsonrpc/node");
1589
1589
  req.resolve("vscode-languageserver-protocol");
1590
1590
  return true;
@@ -1598,7 +1598,7 @@ async function loadLSPDeps() {
1598
1598
  return { ...jsonrpcModule, ...lspProtocolModule };
1599
1599
  }
1600
1600
  try {
1601
- const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-XW4B2RAG.cjs', document.baseURI).href)));
1601
+ const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-QVVWKMFM.cjs', document.baseURI).href)));
1602
1602
  const jsonrpc = req("vscode-jsonrpc/node");
1603
1603
  const protocol = req("vscode-languageserver-protocol");
1604
1604
  jsonrpcModule = {
@@ -1620,6 +1620,15 @@ async function loadLSPDeps() {
1620
1620
  function toFileUri(fsPath) {
1621
1621
  return url.pathToFileURL(fsPath).toString();
1622
1622
  }
1623
+ async function withTimeout(promise, ms, errorMessage) {
1624
+ let timer;
1625
+ return Promise.race([
1626
+ promise,
1627
+ new Promise((_, reject) => {
1628
+ timer = setTimeout(() => reject(new Error(errorMessage)), ms);
1629
+ })
1630
+ ]).finally(() => clearTimeout(timer));
1631
+ }
1623
1632
  var LSPClient = class {
1624
1633
  connection = null;
1625
1634
  handle = null;
@@ -1637,6 +1646,10 @@ var LSPClient = class {
1637
1646
  get isAlive() {
1638
1647
  return this.handle !== null && this.handle.exitCode === void 0;
1639
1648
  }
1649
+ /** Name of the LSP server. */
1650
+ get serverName() {
1651
+ return this.serverDef.name;
1652
+ }
1640
1653
  /**
1641
1654
  * Initialize the LSP connection — spawns the server and performs the handshake.
1642
1655
  */
@@ -1808,6 +1821,56 @@ var LSPClient = class {
1808
1821
  textDocument: { uri }
1809
1822
  });
1810
1823
  }
1824
+ /**
1825
+ * Query hover information at a position.
1826
+ */
1827
+ async queryHover(uri, position, timeoutMs = 5e3) {
1828
+ if (!this.connection) return null;
1829
+ return withTimeout(
1830
+ this.connection.sendRequest("textDocument/hover", { textDocument: { uri }, position }),
1831
+ timeoutMs,
1832
+ "Hover request timed out"
1833
+ );
1834
+ }
1835
+ /**
1836
+ * Query definition(s) at a position.
1837
+ */
1838
+ async queryDefinition(uri, position, timeoutMs = 5e3) {
1839
+ if (!this.connection) return [];
1840
+ const result = await withTimeout(
1841
+ this.connection.sendRequest("textDocument/definition", { textDocument: { uri }, position }),
1842
+ timeoutMs,
1843
+ "Definition request timed out"
1844
+ );
1845
+ if (!result) return [];
1846
+ return Array.isArray(result) ? result : result.uri ? [result] : [];
1847
+ }
1848
+ /**
1849
+ * Query type definition(s) at a position.
1850
+ */
1851
+ async queryTypeDefinition(uri, position, timeoutMs = 5e3) {
1852
+ if (!this.connection) return [];
1853
+ const result = await withTimeout(
1854
+ this.connection.sendRequest("textDocument/typeDefinition", { textDocument: { uri }, position }),
1855
+ timeoutMs,
1856
+ "Type definition request timed out"
1857
+ );
1858
+ if (!result) return [];
1859
+ return Array.isArray(result) ? result : result.uri ? [result] : [];
1860
+ }
1861
+ /**
1862
+ * Query implementation(s) at a position.
1863
+ */
1864
+ async queryImplementation(uri, position, timeoutMs = 5e3) {
1865
+ if (!this.connection) return [];
1866
+ const result = await withTimeout(
1867
+ this.connection.sendRequest("textDocument/implementation", { textDocument: { uri }, position }),
1868
+ timeoutMs,
1869
+ "Implementation request timed out"
1870
+ );
1871
+ if (!result) return [];
1872
+ return Array.isArray(result) ? result : result.uri ? [result] : [];
1873
+ }
1811
1874
  /**
1812
1875
  * Shutdown the connection and kill the process.
1813
1876
  */
@@ -1903,12 +1966,12 @@ function walkUp(startDir, markers) {
1903
1966
  }
1904
1967
  return null;
1905
1968
  }
1906
- async function walkUpAsync(startDir, markers, fs5) {
1969
+ async function walkUpAsync(startDir, markers, fs6) {
1907
1970
  let current = startDir;
1908
1971
  const fsRoot = nodePath.parse(current).root;
1909
1972
  while (true) {
1910
1973
  for (const marker of markers) {
1911
- if (await fs5.exists(nodePath.join(current, marker))) {
1974
+ if (await fs6.exists(nodePath.join(current, marker))) {
1912
1975
  return current;
1913
1976
  }
1914
1977
  }
@@ -2155,6 +2218,28 @@ var LSPManager = class {
2155
2218
  }
2156
2219
  return this.initClient(serverDef, projectRoot, key);
2157
2220
  }
2221
+ /**
2222
+ * Get LSP client ready to query a file.
2223
+ * Opens the file in the client so queries can be made.
2224
+ * Returns null when no LSP client is available.
2225
+ */
2226
+ async prepareQuery(filePath) {
2227
+ const client = await this.getClient(filePath);
2228
+ if (!client) return null;
2229
+ const languageId = getLanguageId(filePath);
2230
+ if (!languageId) return null;
2231
+ const fs6 = await import('fs/promises');
2232
+ let content = "";
2233
+ try {
2234
+ content = await fs6.readFile(filePath, "utf-8");
2235
+ } catch {
2236
+ content = "";
2237
+ }
2238
+ client.notifyOpen(filePath, content, languageId);
2239
+ const { pathToFileURL: pathToFileURL3 } = await import('url');
2240
+ const uri = pathToFileURL3(filePath).toString();
2241
+ return { client, uri, languageId, serverName: client.serverName };
2242
+ }
2158
2243
  /**
2159
2244
  * Convenience method: open file, send content, wait for diagnostics, return normalized results.
2160
2245
  * Returns null when no LSP client is available; otherwise returns diagnostics
@@ -2738,14 +2823,14 @@ var MountManager = class {
2738
2823
  /**
2739
2824
  * Get a mount entry by path.
2740
2825
  */
2741
- get(path7) {
2742
- return this._entries.get(path7);
2826
+ get(path8) {
2827
+ return this._entries.get(path8);
2743
2828
  }
2744
2829
  /**
2745
2830
  * Check if a mount exists at the given path.
2746
2831
  */
2747
- has(path7) {
2748
- return this._entries.has(path7);
2832
+ has(path8) {
2833
+ return this._entries.has(path8);
2749
2834
  }
2750
2835
  // ---------------------------------------------------------------------------
2751
2836
  // Entry Modification
@@ -2757,8 +2842,8 @@ var MountManager = class {
2757
2842
  add(mounts) {
2758
2843
  const paths = Object.keys(mounts);
2759
2844
  this.logger.debug(`Adding ${paths.length} pending mount(s)`, { paths });
2760
- for (const [path7, filesystem] of Object.entries(mounts)) {
2761
- this._entries.set(path7, {
2845
+ for (const [path8, filesystem] of Object.entries(mounts)) {
2846
+ this._entries.set(path8, {
2762
2847
  filesystem,
2763
2848
  state: "pending"
2764
2849
  });
@@ -2768,8 +2853,8 @@ var MountManager = class {
2768
2853
  * Update a mount entry's state.
2769
2854
  * Creates the entry if it doesn't exist.
2770
2855
  */
2771
- set(path7, updates) {
2772
- const existing = this._entries.get(path7);
2856
+ set(path8, updates) {
2857
+ const existing = this._entries.get(path8);
2773
2858
  if (existing) {
2774
2859
  existing.state = updates.state;
2775
2860
  if (updates.config) {
@@ -2780,7 +2865,7 @@ var MountManager = class {
2780
2865
  existing.error = updates.error;
2781
2866
  }
2782
2867
  } else if (updates.filesystem) {
2783
- this._entries.set(path7, {
2868
+ this._entries.set(path8, {
2784
2869
  filesystem: updates.filesystem,
2785
2870
  state: updates.state,
2786
2871
  config: updates.config,
@@ -2788,14 +2873,14 @@ var MountManager = class {
2788
2873
  error: updates.error
2789
2874
  });
2790
2875
  } else {
2791
- this.logger.debug(`set() called for unknown path "${path7}" without filesystem \u2014 no entry created`);
2876
+ this.logger.debug(`set() called for unknown path "${path8}" without filesystem \u2014 no entry created`);
2792
2877
  }
2793
2878
  }
2794
2879
  /**
2795
2880
  * Delete a mount entry.
2796
2881
  */
2797
- delete(path7) {
2798
- return this._entries.delete(path7);
2882
+ delete(path8) {
2883
+ return this._entries.delete(path8);
2799
2884
  }
2800
2885
  /**
2801
2886
  * Clear all mount entries.
@@ -2816,7 +2901,7 @@ var MountManager = class {
2816
2901
  return;
2817
2902
  }
2818
2903
  this.logger.debug(`Processing ${pendingCount} pending mount(s)`);
2819
- for (const [path7, entry] of this._entries) {
2904
+ for (const [path8, entry] of this._entries) {
2820
2905
  if (entry.state !== "pending") {
2821
2906
  continue;
2822
2907
  }
@@ -2826,7 +2911,7 @@ var MountManager = class {
2826
2911
  try {
2827
2912
  const hookResult = await this._onMount({
2828
2913
  filesystem: entry.filesystem,
2829
- mountPath: path7,
2914
+ mountPath: path8,
2830
2915
  config,
2831
2916
  sandbox: this._sandbox,
2832
2917
  workspace: this._workspace
@@ -2834,7 +2919,7 @@ var MountManager = class {
2834
2919
  if (hookResult === false) {
2835
2920
  entry.state = "unsupported";
2836
2921
  entry.error = "Skipped by onMount hook";
2837
- this.logger.debug(`Mount skipped by onMount hook`, { path: path7, provider: fsProvider });
2922
+ this.logger.debug(`Mount skipped by onMount hook`, { path: path8, provider: fsProvider });
2838
2923
  continue;
2839
2924
  }
2840
2925
  if (hookResult && typeof hookResult === "object") {
@@ -2842,54 +2927,54 @@ var MountManager = class {
2842
2927
  entry.state = "mounted";
2843
2928
  entry.config = config;
2844
2929
  entry.configHash = config ? this.hashConfig(config) : void 0;
2845
- this.logger.info(`Mount handled by onMount hook`, { path: path7, provider: fsProvider });
2930
+ this.logger.info(`Mount handled by onMount hook`, { path: path8, provider: fsProvider });
2846
2931
  } else {
2847
2932
  entry.state = "error";
2848
2933
  entry.error = hookResult.error ?? "Mount hook failed";
2849
- this.logger.error(`Mount hook failed`, { path: path7, provider: fsProvider, error: entry.error });
2934
+ this.logger.error(`Mount hook failed`, { path: path8, provider: fsProvider, error: entry.error });
2850
2935
  }
2851
2936
  continue;
2852
2937
  }
2853
2938
  } catch (err) {
2854
2939
  entry.state = "error";
2855
2940
  entry.error = `Mount hook error: ${String(err)}`;
2856
- this.logger.error(`Mount hook threw error`, { path: path7, provider: fsProvider, error: entry.error });
2941
+ this.logger.error(`Mount hook threw error`, { path: path8, provider: fsProvider, error: entry.error });
2857
2942
  continue;
2858
2943
  }
2859
2944
  }
2860
2945
  if (!config) {
2861
2946
  entry.state = "unsupported";
2862
2947
  entry.error = "Filesystem does not support mounting";
2863
- this.logger.debug(`Filesystem does not support mounting`, { path: path7, provider: fsProvider });
2948
+ this.logger.debug(`Filesystem does not support mounting`, { path: path8, provider: fsProvider });
2864
2949
  continue;
2865
2950
  }
2866
2951
  entry.config = config;
2867
2952
  entry.configHash = this.hashConfig(config);
2868
2953
  entry.state = "mounting";
2869
- this.logger.debug(`Mounting filesystem`, { path: path7, provider: fsProvider, type: config.type });
2954
+ this.logger.debug(`Mounting filesystem`, { path: path8, provider: fsProvider, type: config.type });
2870
2955
  try {
2871
- const result = await this._mountFn(entry.filesystem, path7);
2956
+ const result = await this._mountFn(entry.filesystem, path8);
2872
2957
  if (result.success) {
2873
2958
  entry.state = "mounted";
2874
- this.logger.info(`Mount successful`, { path: path7, provider: fsProvider });
2959
+ this.logger.info(`Mount successful`, { path: path8, provider: fsProvider });
2875
2960
  } else if (result.unavailable) {
2876
2961
  entry.state = "unavailable";
2877
2962
  entry.error = result.error ?? "FUSE tool not installed";
2878
- this.logger.warn(`FUSE mount unavailable`, { path: path7, provider: fsProvider, error: entry.error });
2963
+ this.logger.warn(`FUSE mount unavailable`, { path: path8, provider: fsProvider, error: entry.error });
2879
2964
  } else {
2880
2965
  entry.state = "error";
2881
2966
  entry.error = result.error ?? "Mount failed";
2882
- this.logger.error(`Mount failed`, { path: path7, provider: fsProvider, error: entry.error });
2967
+ this.logger.error(`Mount failed`, { path: path8, provider: fsProvider, error: entry.error });
2883
2968
  }
2884
2969
  } catch (err) {
2885
2970
  if (err instanceof MountToolNotFoundError) {
2886
2971
  entry.state = "unavailable";
2887
2972
  entry.error = String(err);
2888
- this.logger.warn(`FUSE mount unavailable`, { path: path7, provider: fsProvider, error: entry.error });
2973
+ this.logger.warn(`FUSE mount unavailable`, { path: path8, provider: fsProvider, error: entry.error });
2889
2974
  } else {
2890
2975
  entry.state = "error";
2891
2976
  entry.error = String(err);
2892
- this.logger.error(`Mount threw error`, { path: path7, provider: fsProvider, error: entry.error });
2977
+ this.logger.error(`Mount threw error`, { path: path8, provider: fsProvider, error: entry.error });
2893
2978
  }
2894
2979
  }
2895
2980
  }
@@ -2938,10 +3023,10 @@ var MountManager = class {
2938
3023
  if (separatorIndex <= 0) {
2939
3024
  return null;
2940
3025
  }
2941
- const path7 = content.slice(0, separatorIndex);
3026
+ const path8 = content.slice(0, separatorIndex);
2942
3027
  const configHash = content.slice(separatorIndex + 1);
2943
- if (!path7 || !configHash) return null;
2944
- return { path: path7, configHash };
3028
+ if (!path8 || !configHash) return null;
3029
+ return { path: path8, configHash };
2945
3030
  }
2946
3031
  /**
2947
3032
  * Check if a config hash matches the expected hash for a mount path.
@@ -3427,11 +3512,11 @@ function buildBwrapCommand(command, workspacePath, config) {
3427
3512
  }
3428
3513
  bwrapArgs.push("--proc", "/proc");
3429
3514
  bwrapArgs.push("--tmpfs", "/tmp");
3430
- for (const path7 of DEFAULT_READONLY_BINDS) {
3431
- bwrapArgs.push("--ro-bind-try", path7, path7);
3515
+ for (const path8 of DEFAULT_READONLY_BINDS) {
3516
+ bwrapArgs.push("--ro-bind-try", path8, path8);
3432
3517
  }
3433
- for (const path7 of config.readOnlyPaths ?? []) {
3434
- bwrapArgs.push("--ro-bind", path7, path7);
3518
+ for (const path8 of config.readOnlyPaths ?? []) {
3519
+ bwrapArgs.push("--ro-bind", path8, path8);
3435
3520
  }
3436
3521
  if (config.allowSystemBinaries !== false) {
3437
3522
  const nodePath4 = process.execPath;
@@ -3443,8 +3528,8 @@ function buildBwrapCommand(command, workspacePath, config) {
3443
3528
  bwrapArgs.push("--ro-bind-try", "/snap", "/snap");
3444
3529
  }
3445
3530
  bwrapArgs.push("--bind", workspacePath, workspacePath);
3446
- for (const path7 of config.readWritePaths ?? []) {
3447
- bwrapArgs.push("--bind", path7, path7);
3531
+ for (const path8 of config.readWritePaths ?? []) {
3532
+ bwrapArgs.push("--bind", path8, path8);
3448
3533
  }
3449
3534
  bwrapArgs.push("--chdir", workspacePath);
3450
3535
  bwrapArgs.push("--die-with-parent");
@@ -4852,18 +4937,18 @@ var VersionedSkillSource = class {
4852
4937
  /**
4853
4938
  * Normalize a path by stripping leading/trailing slashes and dots.
4854
4939
  */
4855
- #normalizePath(path7) {
4856
- let normalized = path7.replace(/^[./\\]+|[/\\]+$/g, "");
4940
+ #normalizePath(path8) {
4941
+ let normalized = path8.replace(/^[./\\]+|[/\\]+$/g, "");
4857
4942
  if (normalized === "") return "";
4858
4943
  return normalized;
4859
4944
  }
4860
- async exists(path7) {
4861
- const normalized = this.#normalizePath(path7);
4945
+ async exists(path8) {
4946
+ const normalized = this.#normalizePath(path8);
4862
4947
  if (this.#tree.entries[normalized]) return true;
4863
4948
  return this.#directories.has(normalized);
4864
4949
  }
4865
- async stat(path7) {
4866
- const normalized = this.#normalizePath(path7);
4950
+ async stat(path8) {
4951
+ const normalized = this.#normalizePath(path8);
4867
4952
  const name = normalized.split("/").pop() || normalized || ".";
4868
4953
  const entry = this.#tree.entries[normalized];
4869
4954
  if (entry) {
@@ -4885,27 +4970,27 @@ var VersionedSkillSource = class {
4885
4970
  modifiedAt: this.#versionCreatedAt
4886
4971
  };
4887
4972
  }
4888
- throw new Error(`Path not found in skill version tree: ${path7}`);
4973
+ throw new Error(`Path not found in skill version tree: ${path8}`);
4889
4974
  }
4890
- async readFile(path7) {
4891
- const normalized = this.#normalizePath(path7);
4975
+ async readFile(path8) {
4976
+ const normalized = this.#normalizePath(path8);
4892
4977
  const entry = this.#tree.entries[normalized];
4893
4978
  if (!entry) {
4894
- throw new Error(`File not found in skill version tree: ${path7}`);
4979
+ throw new Error(`File not found in skill version tree: ${path8}`);
4895
4980
  }
4896
4981
  const blob = await this.#blobStore.get(entry.blobHash);
4897
4982
  if (!blob) {
4898
- throw new Error(`Blob not found for hash ${entry.blobHash} (file: ${path7})`);
4983
+ throw new Error(`Blob not found for hash ${entry.blobHash} (file: ${path8})`);
4899
4984
  }
4900
4985
  if (entry.encoding === "base64") {
4901
4986
  return Buffer.from(blob.content, "base64");
4902
4987
  }
4903
4988
  return blob.content;
4904
4989
  }
4905
- async readdir(path7) {
4906
- const normalized = this.#normalizePath(path7);
4990
+ async readdir(path8) {
4991
+ const normalized = this.#normalizePath(path8);
4907
4992
  if (!this.#directories.has(normalized)) {
4908
- throw new Error(`Directory not found in skill version tree: ${path7}`);
4993
+ throw new Error(`Directory not found in skill version tree: ${path8}`);
4909
4994
  }
4910
4995
  const prefix = normalized === "" ? "" : normalized + "/";
4911
4996
  const seen = /* @__PURE__ */ new Set();
@@ -4938,15 +5023,15 @@ var CompositeVersionedSkillSource = class {
4938
5023
  this.#fallback = options?.fallback;
4939
5024
  this.#fallbackSkills = new Set(options?.fallbackSkills ?? []);
4940
5025
  }
4941
- #normalizePath(path7) {
4942
- return path7.replace(/^[./\\]+|[/\\]+$/g, "");
5026
+ #normalizePath(path8) {
5027
+ return path8.replace(/^[./\\]+|[/\\]+$/g, "");
4943
5028
  }
4944
5029
  /**
4945
5030
  * Route a path to the correct source.
4946
5031
  * Returns the source and the remaining path within that source.
4947
5032
  */
4948
- #routePath(path7) {
4949
- const normalized = this.#normalizePath(path7);
5033
+ #routePath(path8) {
5034
+ const normalized = this.#normalizePath(path8);
4950
5035
  if (normalized === "") return null;
4951
5036
  const segments = normalized.split("/");
4952
5037
  const skillDir = segments[0];
@@ -4963,15 +5048,15 @@ var CompositeVersionedSkillSource = class {
4963
5048
  }
4964
5049
  return null;
4965
5050
  }
4966
- async exists(path7) {
4967
- const normalized = this.#normalizePath(path7);
5051
+ async exists(path8) {
5052
+ const normalized = this.#normalizePath(path8);
4968
5053
  if (normalized === "") return true;
4969
- const route = this.#routePath(path7);
5054
+ const route = this.#routePath(path8);
4970
5055
  if (!route) return false;
4971
5056
  return route.source.exists(route.subPath);
4972
5057
  }
4973
- async stat(path7) {
4974
- const normalized = this.#normalizePath(path7);
5058
+ async stat(path8) {
5059
+ const normalized = this.#normalizePath(path8);
4975
5060
  if (normalized === "") {
4976
5061
  return {
4977
5062
  name: ".",
@@ -4981,21 +5066,21 @@ var CompositeVersionedSkillSource = class {
4981
5066
  modifiedAt: /* @__PURE__ */ new Date()
4982
5067
  };
4983
5068
  }
4984
- const route = this.#routePath(path7);
5069
+ const route = this.#routePath(path8);
4985
5070
  if (!route) {
4986
- throw new Error(`Path not found in composite skill source: ${path7}`);
5071
+ throw new Error(`Path not found in composite skill source: ${path8}`);
4987
5072
  }
4988
5073
  return route.source.stat(route.subPath);
4989
5074
  }
4990
- async readFile(path7) {
4991
- const route = this.#routePath(path7);
5075
+ async readFile(path8) {
5076
+ const route = this.#routePath(path8);
4992
5077
  if (!route) {
4993
- throw new Error(`File not found in composite skill source: ${path7}`);
5078
+ throw new Error(`File not found in composite skill source: ${path8}`);
4994
5079
  }
4995
5080
  return route.source.readFile(route.subPath);
4996
5081
  }
4997
- async readdir(path7) {
4998
- const normalized = this.#normalizePath(path7);
5082
+ async readdir(path8) {
5083
+ const normalized = this.#normalizePath(path8);
4999
5084
  if (normalized === "") {
5000
5085
  const entries = [];
5001
5086
  const seen = /* @__PURE__ */ new Set();
@@ -5011,9 +5096,9 @@ var CompositeVersionedSkillSource = class {
5011
5096
  }
5012
5097
  return entries;
5013
5098
  }
5014
- const route = this.#routePath(path7);
5099
+ const route = this.#routePath(path8);
5015
5100
  if (!route) {
5016
- throw new Error(`Directory not found in composite skill source: ${path7}`);
5101
+ throw new Error(`Directory not found in composite skill source: ${path8}`);
5017
5102
  }
5018
5103
  return route.source.readdir(route.subPath);
5019
5104
  }
@@ -5213,7 +5298,7 @@ var WorkspaceSkillsImpl = class _WorkspaceSkillsImpl {
5213
5298
  if (a.length !== b.length) return false;
5214
5299
  const sortedA = [...a].sort();
5215
5300
  const sortedB = [...b].sort();
5216
- return sortedA.every((path7, i) => path7 === sortedB[i]);
5301
+ return sortedA.every((path8, i) => path8 === sortedB[i]);
5217
5302
  }
5218
5303
  // ===========================================================================
5219
5304
  // Search
@@ -5819,9 +5904,9 @@ ${validation.errors.join("\n")}`);
5819
5904
  /**
5820
5905
  * Get parent path
5821
5906
  */
5822
- #getParentPath(path7) {
5823
- const lastSlash = path7.lastIndexOf("/");
5824
- return lastSlash > 0 ? path7.substring(0, lastSlash) : "/";
5907
+ #getParentPath(path8) {
5908
+ const lastSlash = path8.lastIndexOf("/");
5909
+ return lastSlash > 0 ? path8.substring(0, lastSlash) : "/";
5825
5910
  }
5826
5911
  };
5827
5912
  function hashContent(content) {
@@ -6052,14 +6137,14 @@ function createSkillReadTool(skills) {
6052
6137
  startLine: v4.z.number().optional().describe("Starting line number (1-indexed). If omitted, starts from the beginning."),
6053
6138
  endLine: v4.z.number().optional().describe("Ending line number (1-indexed, inclusive). If omitted, reads to the end.")
6054
6139
  }),
6055
- execute: async ({ skillName, path: path7, startLine, endLine }) => {
6140
+ execute: async ({ skillName, path: path8, startLine, endLine }) => {
6056
6141
  const resolved = await resolveSkill(skills, skillName);
6057
6142
  if ("notFound" in resolved) return resolved.notFound;
6058
6143
  const resolvedPath = resolved.skill.path;
6059
6144
  let content = null;
6060
- content = await skills.getReference(resolvedPath, path7);
6061
- if (content === null) content = await skills.getScript(resolvedPath, path7);
6062
- if (content === null) content = await skills.getAsset(resolvedPath, path7);
6145
+ content = await skills.getReference(resolvedPath, path8);
6146
+ if (content === null) content = await skills.getScript(resolvedPath, path8);
6147
+ if (content === null) content = await skills.getAsset(resolvedPath, path8);
6063
6148
  if (content === null) {
6064
6149
  const refs = (await skills.listReferences(resolvedPath)).map((f) => `references/${f}`);
6065
6150
  const scriptsList = (await skills.listScripts(resolvedPath)).map((f) => `scripts/${f}`);
@@ -6067,11 +6152,11 @@ function createSkillReadTool(skills) {
6067
6152
  const allFiles = [...refs, ...scriptsList, ...assets];
6068
6153
  const fileList = allFiles.length > 0 ? `
6069
6154
  Available files: ${allFiles.join(", ")}` : "";
6070
- return `File "${path7}" not found in skill "${skillName}".${fileList}`;
6155
+ return `File "${path8}" not found in skill "${skillName}".${fileList}`;
6071
6156
  }
6072
6157
  const textContent = typeof content === "string" ? content : content.toString("utf-8");
6073
6158
  if (textContent.slice(0, 1e3).includes("\0")) {
6074
- const fullPath = `${resolved.skill.path}/${path7}`;
6159
+ const fullPath = `${resolved.skill.path}/${path8}`;
6075
6160
  const size = typeof content === "string" ? Buffer.byteLength(content) : content.length;
6076
6161
  return `Binary file: ${fullPath} (${size} bytes)`;
6077
6162
  }
@@ -6107,8 +6192,8 @@ var Workspace = class {
6107
6192
  if (config.filesystem) {
6108
6193
  throw new WorkspaceError('Cannot use both "filesystem" and "mounts"', "INVALID_CONFIG");
6109
6194
  }
6110
- for (const [mountPath, fs5] of Object.entries(config.mounts)) {
6111
- if (fs5 instanceof LocalFilesystem && !fs5.contained) {
6195
+ for (const [mountPath, fs6] of Object.entries(config.mounts)) {
6196
+ if (fs6 instanceof LocalFilesystem && !fs6.contained) {
6112
6197
  console.warn(
6113
6198
  `[Workspace] LocalFilesystem at mount "${mountPath}" has contained: false, which is incompatible with mounts. CompositeFilesystem strips mount prefixes and produces absolute paths (e.g. "/file.txt"), which a non-contained LocalFilesystem interprets as real host paths instead of paths relative to basePath. Use contained: true (default) or allowedPaths for specific exceptions.`
6114
6199
  );
@@ -6304,13 +6389,13 @@ var Workspace = class {
6304
6389
  * @param options - Index options (metadata, type hints)
6305
6390
  * @throws {SearchNotAvailableError} if search is not configured
6306
6391
  */
6307
- async index(path7, content, options) {
6392
+ async index(path8, content, options) {
6308
6393
  if (!this._searchEngine) {
6309
6394
  throw new SearchNotAvailableError();
6310
6395
  }
6311
6396
  this.lastAccessedAt = /* @__PURE__ */ new Date();
6312
6397
  const doc = {
6313
- id: path7,
6398
+ id: path8,
6314
6399
  content,
6315
6400
  metadata: {
6316
6401
  type: options?.type,
@@ -6619,6 +6704,9 @@ var WORKSPACE_TOOLS = {
6619
6704
  SEARCH: {
6620
6705
  SEARCH: `${WORKSPACE_TOOLS_PREFIX}_search`,
6621
6706
  INDEX: `${WORKSPACE_TOOLS_PREFIX}_index`
6707
+ },
6708
+ LSP: {
6709
+ LSP_INSPECT: `${WORKSPACE_TOOLS_PREFIX}_lsp_inspect`
6622
6710
  }
6623
6711
  };
6624
6712
  function requireWorkspace(context) {
@@ -6740,7 +6828,7 @@ function isAstGrepAvailable() {
6740
6828
  return astGrepModule !== null;
6741
6829
  }
6742
6830
  try {
6743
- const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-XW4B2RAG.cjs', document.baseURI).href)));
6831
+ const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-QVVWKMFM.cjs', document.baseURI).href)));
6744
6832
  req.resolve("@ast-grep/napi");
6745
6833
  return true;
6746
6834
  } catch {
@@ -6941,7 +7029,7 @@ Pattern replace (for everything else):
6941
7029
  isDefault: v4.z.boolean().optional().describe("Whether the first name is a default import")
6942
7030
  }).optional().describe("Required for add-import transform. Specifies the module and names to import.")
6943
7031
  }),
6944
- execute: async ({ path: path7, pattern, replacement, transform, targetName, newName, importSpec }, context) => {
7032
+ execute: async ({ path: path8, pattern, replacement, transform, targetName, newName, importSpec }, context) => {
6945
7033
  const { workspace, filesystem } = requireFilesystem(context);
6946
7034
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT);
6947
7035
  if (filesystem.readOnly) {
@@ -6954,19 +7042,19 @@ Pattern replace (for everything else):
6954
7042
  const { parse: parse2, Lang } = astGrep;
6955
7043
  let content;
6956
7044
  try {
6957
- content = await filesystem.readFile(path7, { encoding: "utf-8" });
7045
+ content = await filesystem.readFile(path8, { encoding: "utf-8" });
6958
7046
  } catch (error) {
6959
7047
  if (error instanceof FileNotFoundError) {
6960
- return `File not found: ${path7}. Use the write file tool to create it first.`;
7048
+ return `File not found: ${path8}. Use the write file tool to create it first.`;
6961
7049
  }
6962
7050
  throw error;
6963
7051
  }
6964
7052
  if (typeof content !== "string") {
6965
7053
  return `Cannot perform AST edits on binary files. Use the write file tool instead.`;
6966
7054
  }
6967
- const lang = getLanguageFromPath(path7, Lang);
7055
+ const lang = getLanguageFromPath(path8, Lang);
6968
7056
  if (!lang) {
6969
- return `Unsupported file type for AST editing: ${path7}`;
7057
+ return `Unsupported file type for AST editing: ${path8}`;
6970
7058
  }
6971
7059
  const ast = parse2(lang, content);
6972
7060
  const root = ast.root();
@@ -7016,16 +7104,16 @@ Pattern replace (for everything else):
7016
7104
  }
7017
7105
  const wasModified = modifiedContent !== content;
7018
7106
  if (wasModified) {
7019
- await filesystem.writeFile(path7, modifiedContent, {
7107
+ await filesystem.writeFile(path8, modifiedContent, {
7020
7108
  overwrite: true,
7021
7109
  expectedMtime: context?.__expectedMtime
7022
7110
  });
7023
7111
  }
7024
7112
  if (!wasModified) {
7025
- return `No changes made to ${path7} (${changes.join("; ")})`;
7113
+ return `No changes made to ${path8} (${changes.join("; ")})`;
7026
7114
  }
7027
- let output = `${path7}: ${changes.join("; ")}`;
7028
- output += await getEditDiagnosticsText(workspace, path7, modifiedContent);
7115
+ let output = `${path8}: ${changes.join("; ")}`;
7116
+ output += await getEditDiagnosticsText(workspace, path8, modifiedContent);
7029
7117
  return output;
7030
7118
  }
7031
7119
  });
@@ -7036,19 +7124,19 @@ var deleteFileTool = chunkK4NN2KQQ_cjs.createTool({
7036
7124
  path: v4.z.string().describe("The path to the file or directory to delete"),
7037
7125
  recursive: v4.z.boolean().optional().default(false).describe("If true, delete directories and their contents recursively. Required for non-empty directories.")
7038
7126
  }),
7039
- execute: async ({ path: path7, recursive }, context) => {
7127
+ execute: async ({ path: path8, recursive }, context) => {
7040
7128
  const { filesystem } = requireFilesystem(context);
7041
7129
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.DELETE);
7042
7130
  if (filesystem.readOnly) {
7043
7131
  throw new WorkspaceReadOnlyError("delete");
7044
7132
  }
7045
- const stat3 = await filesystem.stat(path7);
7133
+ const stat3 = await filesystem.stat(path8);
7046
7134
  if (stat3.type === "directory") {
7047
- await filesystem.rmdir(path7, { recursive, force: recursive });
7135
+ await filesystem.rmdir(path8, { recursive, force: recursive });
7048
7136
  } else {
7049
- await filesystem.deleteFile(path7);
7137
+ await filesystem.deleteFile(path8);
7050
7138
  }
7051
- return `Deleted ${path7}`;
7139
+ return `Deleted ${path8}`;
7052
7140
  }
7053
7141
  });
7054
7142
  var editFileTool = chunkK4NN2KQQ_cjs.createTool({
@@ -7066,24 +7154,24 @@ Usage:
7066
7154
  new_string: v4.z.string().describe("The text to replace old_string with"),
7067
7155
  replace_all: v4.z.boolean().optional().default(false).describe("If true, replace all occurrences. If false (default), old_string must be unique.")
7068
7156
  }),
7069
- execute: async ({ path: path7, old_string, new_string, replace_all }, context) => {
7157
+ execute: async ({ path: path8, old_string, new_string, replace_all }, context) => {
7070
7158
  const { workspace, filesystem } = requireFilesystem(context);
7071
7159
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE);
7072
7160
  if (filesystem.readOnly) {
7073
7161
  throw new WorkspaceReadOnlyError("edit_file");
7074
7162
  }
7075
7163
  try {
7076
- const content = await filesystem.readFile(path7, { encoding: "utf-8" });
7164
+ const content = await filesystem.readFile(path8, { encoding: "utf-8" });
7077
7165
  if (typeof content !== "string") {
7078
7166
  return `Cannot edit binary files. Use the write file tool instead.`;
7079
7167
  }
7080
7168
  const result = replaceString(content, old_string, new_string, replace_all);
7081
- await filesystem.writeFile(path7, result.content, {
7169
+ await filesystem.writeFile(path8, result.content, {
7082
7170
  overwrite: true,
7083
7171
  expectedMtime: context?.__expectedMtime
7084
7172
  });
7085
- let output = `Replaced ${result.replacements} occurrence${result.replacements !== 1 ? "s" : ""} in ${path7}`;
7086
- output += await getEditDiagnosticsText(workspace, path7, result.content);
7173
+ let output = `Replaced ${result.replacements} occurrence${result.replacements !== 1 ? "s" : ""} in ${path8}`;
7174
+ output += await getEditDiagnosticsText(workspace, path8, result.content);
7087
7175
  return output;
7088
7176
  } catch (error) {
7089
7177
  if (error instanceof StringNotFoundError) {
@@ -7335,19 +7423,19 @@ var fileStatTool = chunkK4NN2KQQ_cjs.createTool({
7335
7423
  inputSchema: v4.z.object({
7336
7424
  path: v4.z.string().describe("The path to check")
7337
7425
  }),
7338
- execute: async ({ path: path7 }, context) => {
7426
+ execute: async ({ path: path8 }, context) => {
7339
7427
  const { filesystem } = requireFilesystem(context);
7340
7428
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT);
7341
7429
  try {
7342
- const stat3 = await filesystem.stat(path7);
7430
+ const stat3 = await filesystem.stat(path8);
7343
7431
  const modifiedAt = stat3.modifiedAt.toISOString();
7344
- const parts = [`${path7}`, `Type: ${stat3.type}`];
7432
+ const parts = [`${path8}`, `Type: ${stat3.type}`];
7345
7433
  if (stat3.size !== void 0) parts.push(`Size: ${stat3.size} bytes`);
7346
7434
  parts.push(`Modified: ${modifiedAt}`);
7347
7435
  return parts.join(" ");
7348
7436
  } catch (error) {
7349
7437
  if (error instanceof FileNotFoundError) {
7350
- return `${path7}: not found`;
7438
+ return `${path8}: not found`;
7351
7439
  }
7352
7440
  throw error;
7353
7441
  }
@@ -7613,11 +7701,11 @@ var indexContentTool = chunkK4NN2KQQ_cjs.createTool({
7613
7701
  content: v4.z.string().describe("The text content to index"),
7614
7702
  metadata: v4.z.record(v4.z.string(), v4.z.unknown()).optional().describe("Optional metadata to store with the document")
7615
7703
  }),
7616
- execute: async ({ path: path7, content, metadata }, context) => {
7704
+ execute: async ({ path: path8, content, metadata }, context) => {
7617
7705
  const workspace = requireWorkspace(context);
7618
7706
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.SEARCH.INDEX);
7619
- await workspace.index(path7, content, { metadata });
7620
- return `Indexed ${path7}`;
7707
+ await workspace.index(path8, content, { metadata });
7708
+ return `Indexed ${path8}`;
7621
7709
  }
7622
7710
  });
7623
7711
  var KILL_TAIL_LINES = 50;
@@ -7673,7 +7761,7 @@ Use this to stop a long-running background process that was started with execute
7673
7761
  });
7674
7762
 
7675
7763
  // src/workspace/tools/tree-formatter.ts
7676
- async function formatAsTree(fs5, path7, options) {
7764
+ async function formatAsTree(fs6, path8, options) {
7677
7765
  const maxDepth = options?.maxDepth ?? Infinity;
7678
7766
  const showHidden = options?.showHidden ?? false;
7679
7767
  const dirsOnly = options?.dirsOnly ?? false;
@@ -7683,9 +7771,9 @@ async function formatAsTree(fs5, path7, options) {
7683
7771
  const respectGitignore = options?.respectGitignore ?? true;
7684
7772
  let ignoreFilter = options?.ignoreFilter;
7685
7773
  if (!ignoreFilter && respectGitignore) {
7686
- const rawFilter = await loadGitignore(fs5);
7774
+ const rawFilter = await loadGitignore(fs6);
7687
7775
  if (rawFilter) {
7688
- const normalizedPath = path7.replace(/^\.\//, "").replace(/^\//, "").replace(/\/$/, "");
7776
+ const normalizedPath = path8.replace(/^\.\//, "").replace(/^\//, "").replace(/\/$/, "");
7689
7777
  const targetIsIgnored = normalizedPath && rawFilter(normalizedPath + "/");
7690
7778
  ignoreFilter = targetIsIgnored ? void 0 : rawFilter;
7691
7779
  }
@@ -7707,7 +7795,7 @@ async function formatAsTree(fs5, path7, options) {
7707
7795
  }
7708
7796
  let entries;
7709
7797
  try {
7710
- entries = await fs5.readdir(currentPath);
7798
+ entries = await fs6.readdir(currentPath);
7711
7799
  } catch (error) {
7712
7800
  if (depth === 0) {
7713
7801
  throw error;
@@ -7747,7 +7835,7 @@ async function formatAsTree(fs5, path7, options) {
7747
7835
  if (globMatcher && !dirsOnly) {
7748
7836
  filtered = filtered.filter((e) => {
7749
7837
  if (e.type === "directory") return true;
7750
- const relativePath = getRelativePath(path7, currentPath, e.name);
7838
+ const relativePath = getRelativePath(path8, currentPath, e.name);
7751
7839
  return globMatcher(relativePath);
7752
7840
  });
7753
7841
  }
@@ -7761,7 +7849,7 @@ async function formatAsTree(fs5, path7, options) {
7761
7849
  const entry = filtered[i];
7762
7850
  const displayName = entry.isSymlink && entry.symlinkTarget ? `${entry.name} -> ${entry.symlinkTarget}` : entry.name;
7763
7851
  lines.push(`${indent}${displayName}`);
7764
- paths.push(getRelativePath(path7, currentPath, entry.name));
7852
+ paths.push(getRelativePath(path8, currentPath, entry.name));
7765
7853
  if (entry.type === "directory") {
7766
7854
  dirCount++;
7767
7855
  if (!entry.isSymlink) {
@@ -7773,7 +7861,7 @@ async function formatAsTree(fs5, path7, options) {
7773
7861
  }
7774
7862
  }
7775
7863
  }
7776
- await buildTree(path7, 0);
7864
+ await buildTree(path8, 0);
7777
7865
  const dirPart = dirCount === 1 ? "1 directory" : `${dirCount} directories`;
7778
7866
  const filePart = fileCount === 1 ? "1 file" : `${fileCount} files`;
7779
7867
  let summary = `${dirPart}, ${filePart}`;
@@ -7836,10 +7924,10 @@ Examples:
7836
7924
  ),
7837
7925
  respectGitignore: v4.z.boolean().optional().default(true).describe("Respect .gitignore in the listed directory (default: true).")
7838
7926
  }),
7839
- execute: async ({ path: path7 = ".", maxDepth = 2, showHidden, dirsOnly, exclude, extension, pattern, respectGitignore }, context) => {
7927
+ execute: async ({ path: path8 = ".", maxDepth = 2, showHidden, dirsOnly, exclude, extension, pattern, respectGitignore }, context) => {
7840
7928
  const { workspace, filesystem } = requireFilesystem(context);
7841
7929
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES);
7842
- const result = await formatAsTree(filesystem, path7, {
7930
+ const result = await formatAsTree(filesystem, path8, {
7843
7931
  maxDepth,
7844
7932
  showHidden,
7845
7933
  dirsOnly,
@@ -7857,6 +7945,194 @@ ${result.summary}`,
7857
7945
  );
7858
7946
  }
7859
7947
  });
7948
+ var CURSOR_MARKER = "<<<";
7949
+ async function getLinePreview(filePath, lineNumber) {
7950
+ try {
7951
+ const content = await fs2__namespace.default.readFile(filePath, "utf-8");
7952
+ const lines = content.split("\n");
7953
+ const line = lines[lineNumber - 1];
7954
+ return line?.trim() ?? null;
7955
+ } catch {
7956
+ return null;
7957
+ }
7958
+ }
7959
+ function getAbsolutePath(workspacePath, lspRoot, resolveAbsolutePath) {
7960
+ const resolvedPath = resolveAbsolutePath?.(workspacePath);
7961
+ if (resolvedPath) {
7962
+ return resolvedPath;
7963
+ }
7964
+ if (nodePath__namespace.default.isAbsolute(workspacePath)) {
7965
+ return workspacePath;
7966
+ }
7967
+ return nodePath__namespace.default.resolve(lspRoot, workspacePath);
7968
+ }
7969
+ function locationUriToPath(uri) {
7970
+ if (!uri.startsWith("file://")) {
7971
+ return null;
7972
+ }
7973
+ try {
7974
+ return url.fileURLToPath(uri);
7975
+ } catch {
7976
+ return null;
7977
+ }
7978
+ }
7979
+ function locationKey(location) {
7980
+ return `${location.path}:L${location.line}`;
7981
+ }
7982
+ function compressPath(filePath) {
7983
+ const cwd = process.cwd();
7984
+ if (filePath.startsWith(cwd)) {
7985
+ return "$cwd" + filePath.slice(cwd.length);
7986
+ }
7987
+ return filePath;
7988
+ }
7989
+ var lspInspectTool = chunkK4NN2KQQ_cjs.createTool({
7990
+ id: WORKSPACE_TOOLS.LSP.LSP_INSPECT,
7991
+ description: "Inspect code at a specific symbol position using the Language Server Protocol. Provide an absolute file path, a 1-indexed line number, and the exact line content with <<< marking the cursor position. Exactly one <<< marker is required. Returns hover information, any diagnostics reported on that line, plus definition and implementation locations when available. Use this for type information, symbol navigation, and go-to-definition; use view to read the surrounding implementation.",
7992
+ inputSchema: v4.z.object({
7993
+ path: v4.z.string().describe("Absolute path to the file"),
7994
+ line: v4.z.number().int().positive().describe("Line number (1-indexed)"),
7995
+ match: v4.z.string().describe(
7996
+ 'Line content with <<< marking the cursor position. Exactly one <<< marker is required. Example: "const foo = <<<bar()" means cursor is at bar'
7997
+ )
7998
+ }),
7999
+ execute: async ({ path: filePath, line, match }, context) => {
8000
+ const workspace = requireWorkspace(context);
8001
+ await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.LSP.LSP_INSPECT);
8002
+ const cursorPositions = [];
8003
+ let searchStart = 0;
8004
+ while (true) {
8005
+ const pos = match.indexOf(CURSOR_MARKER, searchStart);
8006
+ if (pos === -1) break;
8007
+ cursorPositions.push(pos);
8008
+ searchStart = pos + CURSOR_MARKER.length;
8009
+ }
8010
+ if (cursorPositions.length === 0) {
8011
+ return {
8012
+ error: `No <<< cursor marker found in match`
8013
+ };
8014
+ }
8015
+ if (cursorPositions.length > 1) {
8016
+ return {
8017
+ error: `Multiple <<< markers found (found ${cursorPositions.length}, expected 1)`
8018
+ };
8019
+ }
8020
+ const character = cursorPositions[0] + 1;
8021
+ const lspManager = workspace.lsp;
8022
+ if (!lspManager) {
8023
+ return {
8024
+ error: "LSP is not configured for this workspace. Enable LSP in workspace config to use this tool."
8025
+ };
8026
+ }
8027
+ const absolutePath = getAbsolutePath(
8028
+ filePath,
8029
+ lspManager.root,
8030
+ workspace.filesystem?.resolveAbsolutePath?.bind(workspace.filesystem)
8031
+ );
8032
+ let fileContent = "";
8033
+ try {
8034
+ fileContent = await fs2__namespace.default.readFile(absolutePath, "utf-8");
8035
+ } catch {
8036
+ fileContent = "";
8037
+ }
8038
+ let queryResult;
8039
+ try {
8040
+ queryResult = await lspManager.prepareQuery(absolutePath);
8041
+ } catch (err) {
8042
+ return {
8043
+ error: `Failed to initialize LSP client: ${err instanceof Error ? err.message : String(err)}`
8044
+ };
8045
+ }
8046
+ if (!queryResult) {
8047
+ return {
8048
+ error: `No language server available for files of this type: ${filePath}`
8049
+ };
8050
+ }
8051
+ const { client, uri } = queryResult;
8052
+ const position = { line: line - 1, character: character - 1 };
8053
+ const result = {};
8054
+ try {
8055
+ const hoverResult = await client.queryHover(uri, position).catch(() => null);
8056
+ if (hoverResult) {
8057
+ const contents = hoverResult.contents;
8058
+ if (contents) {
8059
+ if (typeof contents === "string") {
8060
+ result.hover = { value: contents, kind: "plaintext" };
8061
+ } else if (Array.isArray(contents)) {
8062
+ const first = contents[0];
8063
+ if (typeof first === "string") {
8064
+ result.hover = { value: first, kind: "plaintext" };
8065
+ } else if (first?.value) {
8066
+ result.hover = { value: first.value, kind: first.kind ?? "markdown" };
8067
+ }
8068
+ } else if (contents.value) {
8069
+ result.hover = { value: contents.value, kind: contents.kind ?? "markdown" };
8070
+ }
8071
+ }
8072
+ }
8073
+ const diagnosticsPromise = fileContent ? Promise.resolve().then(() => {
8074
+ client.notifyChange(absolutePath, fileContent, 1);
8075
+ return client.waitForDiagnostics(absolutePath, 5e3, true);
8076
+ }).catch(() => []) : Promise.resolve([]);
8077
+ const [diagnosticsResult, definitionResult, implResult] = await Promise.all([
8078
+ diagnosticsPromise,
8079
+ client.queryDefinition(uri, position).catch(() => []),
8080
+ client.queryImplementation(uri, position).catch(() => [])
8081
+ ]);
8082
+ if (diagnosticsResult && diagnosticsResult.length > 0) {
8083
+ const lineDiagnostics = diagnosticsResult.map((diagnostic) => ({
8084
+ line: typeof diagnostic.line === "number" ? diagnostic.line : (diagnostic.range?.start?.line ?? -1) + 1,
8085
+ severity: typeof diagnostic.severity === "number" ? diagnostic.severity === 1 ? "error" : diagnostic.severity === 2 ? "warning" : diagnostic.severity === 3 ? "info" : "hint" : diagnostic.severity,
8086
+ message: diagnostic.message,
8087
+ source: diagnostic.source ?? null
8088
+ })).filter((diagnostic) => diagnostic.line === line).map(({ severity, message, source }) => ({ severity, message, source }));
8089
+ if (lineDiagnostics.length > 0) {
8090
+ result.diagnostics = lineDiagnostics;
8091
+ }
8092
+ }
8093
+ const definitionLocations = definitionResult.map((loc) => ({
8094
+ uri: loc.uri ?? loc.targetUri,
8095
+ range: loc.range ?? loc.targetRange
8096
+ })).map((loc) => {
8097
+ const resolvedPath = loc.uri ? locationUriToPath(String(loc.uri)) : null;
8098
+ return resolvedPath ? {
8099
+ path: resolvedPath,
8100
+ line: (loc.range?.start?.line ?? 0) + 1,
8101
+ character: (loc.range?.start?.character ?? 0) + 1
8102
+ } : null;
8103
+ }).filter((loc) => Boolean(loc)).filter((loc) => !(loc.path === absolutePath && loc.line === line));
8104
+ if (definitionLocations.length > 0) {
8105
+ const previews = await Promise.all(definitionLocations.map((loc) => getLinePreview(loc.path, loc.line)));
8106
+ result.definition = definitionLocations.map((loc, i) => ({
8107
+ location: `${compressPath(loc.path)}:L${loc.line}:C${loc.character}`,
8108
+ preview: previews[i]
8109
+ }));
8110
+ }
8111
+ const definitionKeys = new Set(definitionLocations.map(locationKey));
8112
+ const implementationLocations = implResult.map((loc) => ({
8113
+ uri: loc.uri ?? loc.targetUri,
8114
+ range: loc.range ?? loc.targetRange
8115
+ })).map((loc) => {
8116
+ const resolvedPath = loc.uri ? locationUriToPath(String(loc.uri)) : null;
8117
+ return resolvedPath ? {
8118
+ path: resolvedPath,
8119
+ line: (loc.range?.start?.line ?? 0) + 1,
8120
+ character: (loc.range?.start?.character ?? 0) + 1
8121
+ } : null;
8122
+ }).filter((loc) => Boolean(loc)).filter((loc) => !definitionKeys.has(locationKey(loc)) && !(loc.path === absolutePath && loc.line === line));
8123
+ if (implementationLocations.length > 0) {
8124
+ result.implementation = implementationLocations.map(
8125
+ (loc) => `${compressPath(loc.path)}:L${loc.line}:C${loc.character}`
8126
+ );
8127
+ }
8128
+ } catch (err) {
8129
+ result.error = `LSP query failed: ${err instanceof Error ? err.message : String(err)}`;
8130
+ } finally {
8131
+ client.notifyClose(absolutePath);
8132
+ }
8133
+ return result;
8134
+ }
8135
+ });
7860
8136
  var mkdirTool = chunkK4NN2KQQ_cjs.createTool({
7861
8137
  id: WORKSPACE_TOOLS.FILESYSTEM.MKDIR,
7862
8138
  description: "Create a directory in the workspace filesystem",
@@ -7864,14 +8140,14 @@ var mkdirTool = chunkK4NN2KQQ_cjs.createTool({
7864
8140
  path: v4.z.string().describe("The path of the directory to create"),
7865
8141
  recursive: v4.z.boolean().optional().default(true).describe("Whether to create parent directories if they do not exist")
7866
8142
  }),
7867
- execute: async ({ path: path7, recursive }, context) => {
8143
+ execute: async ({ path: path8, recursive }, context) => {
7868
8144
  const { filesystem } = requireFilesystem(context);
7869
8145
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.MKDIR);
7870
8146
  if (filesystem.readOnly) {
7871
8147
  throw new WorkspaceReadOnlyError("mkdir");
7872
8148
  }
7873
- await filesystem.mkdir(path7, { recursive });
7874
- return `Created directory ${path7}`;
8149
+ await filesystem.mkdir(path8, { recursive });
8150
+ return `Created directory ${path8}`;
7875
8151
  }
7876
8152
  });
7877
8153
  var readFileTool = chunkK4NN2KQQ_cjs.createTool({
@@ -7884,12 +8160,12 @@ var readFileTool = chunkK4NN2KQQ_cjs.createTool({
7884
8160
  limit: v4.z.number().optional().describe("Maximum number of lines to read. If omitted, reads to the end of the file."),
7885
8161
  showLineNumbers: v4.z.boolean().optional().default(true).describe("Whether to prefix each line with its line number (default: true)")
7886
8162
  }),
7887
- execute: async ({ path: path7, encoding, offset, limit, showLineNumbers }, context) => {
8163
+ execute: async ({ path: path8, encoding, offset, limit, showLineNumbers }, context) => {
7888
8164
  const { workspace, filesystem } = requireFilesystem(context);
7889
8165
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.READ_FILE);
7890
8166
  const effectiveEncoding = encoding ?? "utf-8";
7891
- const fullContent = await filesystem.readFile(path7, { encoding: effectiveEncoding });
7892
- const stat3 = await filesystem.stat(path7);
8167
+ const fullContent = await filesystem.readFile(path8, { encoding: effectiveEncoding });
8168
+ const stat3 = await filesystem.stat(path8);
7893
8169
  const isTextEncoding = !encoding || encoding === "utf-8" || encoding === "utf8";
7894
8170
  const tokenLimit = workspace.getToolsConfig()?.[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]?.maxOutputTokens;
7895
8171
  if (!isTextEncoding) {
@@ -7957,19 +8233,19 @@ var writeFileTool = chunkK4NN2KQQ_cjs.createTool({
7957
8233
  content: v4.z.string().describe("The content to write to the file"),
7958
8234
  overwrite: v4.z.boolean().optional().default(true).describe("Whether to overwrite the file if it already exists")
7959
8235
  }),
7960
- execute: async ({ path: path7, content, overwrite }, context) => {
8236
+ execute: async ({ path: path8, content, overwrite }, context) => {
7961
8237
  const { workspace, filesystem } = requireFilesystem(context);
7962
8238
  await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE);
7963
8239
  if (filesystem.readOnly) {
7964
8240
  throw new WorkspaceReadOnlyError("write_file");
7965
8241
  }
7966
- await filesystem.writeFile(path7, content, {
8242
+ await filesystem.writeFile(path8, content, {
7967
8243
  overwrite,
7968
8244
  expectedMtime: context?.__expectedMtime
7969
8245
  });
7970
8246
  const size = Buffer.byteLength(content, "utf-8");
7971
- let output = `Wrote ${size} bytes to ${path7}`;
7972
- output += await getEditDiagnosticsText(workspace, path7, content);
8247
+ let output = `Wrote ${size} bytes to ${path8}`;
8248
+ output += await getEditDiagnosticsText(workspace, path8, content);
7973
8249
  return output;
7974
8250
  }
7975
8251
  });
@@ -8124,6 +8400,7 @@ function createWorkspaceTools(workspace) {
8124
8400
  addTool(WORKSPACE_TOOLS.SANDBOX.KILL_PROCESS, killProcessTool);
8125
8401
  }
8126
8402
  }
8403
+ addTool(WORKSPACE_TOOLS.LSP.LSP_INSPECT, lspInspectTool);
8127
8404
  return tools;
8128
8405
  }
8129
8406
 
@@ -8196,5 +8473,5 @@ exports.requireWorkspace = requireWorkspace;
8196
8473
  exports.resolveToolConfig = resolveToolConfig;
8197
8474
  exports.searchTool = searchTool;
8198
8475
  exports.writeFileTool = writeFileTool;
8199
- //# sourceMappingURL=chunk-XW4B2RAG.cjs.map
8200
- //# sourceMappingURL=chunk-XW4B2RAG.cjs.map
8476
+ //# sourceMappingURL=chunk-QVVWKMFM.cjs.map
8477
+ //# sourceMappingURL=chunk-QVVWKMFM.cjs.map