@theokit/sdk-tools 0.11.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/README.md +1 -1
- package/dist/index.cjs +119 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -3
- package/dist/index.d.ts +42 -3
- package/dist/index.js +117 -15
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.d.cts
CHANGED
|
@@ -182,6 +182,34 @@ declare function commandDenialReason(command: string, policies: CommandPolicy[])
|
|
|
182
182
|
/** `true` when no policy denies `command` (an empty policy array allows everything). */
|
|
183
183
|
declare function isCommandAllowed(command: string, policies: CommandPolicy[]): boolean;
|
|
184
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Context-tolerant single-occurrence text matching (`seek_sequence` parity, ported
|
|
187
|
+
* from the AgentBuilder Codex clone, M10/M13). Where a naive `edit_file` matches
|
|
188
|
+
* `old_string` byte-for-byte (or with a single whitespace-normalized fallback),
|
|
189
|
+
* this matcher is safe AND forgiving:
|
|
190
|
+
*
|
|
191
|
+
* Stage 1 — exact byte substring, with an **ambiguity guard**: if the target
|
|
192
|
+
* appears more than once it throws instead of silently editing the first hit
|
|
193
|
+
* (a too-short `old_string` editing the wrong location is the classic footgun).
|
|
194
|
+
* Stage 2 — line-based match down a **strictness ladder** (exact → rstrip → trim
|
|
195
|
+
* → unicode-normalize), stopping at the first rung that yields exactly ONE
|
|
196
|
+
* match; a rung matching 2+ positions throws (ambiguous), never picks one.
|
|
197
|
+
*
|
|
198
|
+
* Pure. Preserves the file's CRLF/LF style on the replaced region. Throws typed
|
|
199
|
+
* {@link ContextMatchError} (`empty | ambiguous | not_found`) so the caller maps to
|
|
200
|
+
* its own `{ ok: false, error }` shape.
|
|
201
|
+
*/
|
|
202
|
+
type ContextMatchReason = "empty" | "ambiguous" | "not_found";
|
|
203
|
+
declare class ContextMatchError extends Error {
|
|
204
|
+
readonly reason: ContextMatchReason;
|
|
205
|
+
constructor(reason: ContextMatchReason, message: string);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Return `content` with the single occurrence of `find` replaced by `replace`, using the two-stage
|
|
209
|
+
* context-tolerant matcher. Throws {@link ContextMatchError} on empty/ambiguous/not-found.
|
|
210
|
+
*/
|
|
211
|
+
declare function replaceUnique(content: string, find: string, replace: string): string;
|
|
212
|
+
|
|
185
213
|
/**
|
|
186
214
|
* SSRF guard for network tools (M3-1).
|
|
187
215
|
*
|
|
@@ -339,6 +367,17 @@ declare function catastrophicShellReason(command: string): string | null;
|
|
|
339
367
|
* name/inputSchema/handler; does NOT mutate the original tool.
|
|
340
368
|
*/
|
|
341
369
|
declare function withDescription(tool: CustomTool, description: string): CustomTool;
|
|
370
|
+
/**
|
|
371
|
+
* Return a new `CustomTool` exposed under a different `name`, sharing the SAME
|
|
372
|
+
* `inputSchema` + `handler` (alias parity). Preserves description; does NOT mutate
|
|
373
|
+
* the original. This is how an agent exposes a built-in under its preferred name —
|
|
374
|
+
* e.g. a Codex-style agent aliases `search_text` → `grep`, `shell_exec` → `run_shell`
|
|
375
|
+
* — without re-implementing the tool. Pure, never throws: the final `name` is
|
|
376
|
+
* validated by the SDK at tool-registration time (the single authority for the
|
|
377
|
+
* `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` + reserved-name rules), so this helper does not
|
|
378
|
+
* re-validate (no duplicated contract).
|
|
379
|
+
*/
|
|
380
|
+
declare function withName(tool: CustomTool, name: string): CustomTool;
|
|
342
381
|
/** Render mode for {@link renderToolList}. Local — the published `renderToolList`
|
|
343
382
|
* signature inlines this union into its `.d.ts`, so consumers pass the literal
|
|
344
383
|
* ("summary" | "names" | "full") without needing the named type exported. */
|
|
@@ -580,7 +619,7 @@ declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool
|
|
|
580
619
|
* SE37 — the public reasoning toolkit: `ReasoningTools.create()` returns a
|
|
581
620
|
* `think` + `analyze` scratchpad (no-side-effect tools that echo the model's
|
|
582
621
|
* structured reasoning back as an observation, so the ReAct loop feeds it
|
|
583
|
-
* forward). Mirrors Anthropic's "think" tool +
|
|
622
|
+
* forward). Mirrors Anthropic's "think" tool + a peer's `ReasoningTools`.
|
|
584
623
|
*
|
|
585
624
|
* Lives in `@theokit/sdk-tools` (not core) so the full toolkit stays out of the
|
|
586
625
|
* core bundle. The `reasoning: true` agent flag auto-attaches an equivalent
|
|
@@ -700,7 +739,7 @@ declare function createShellTool(opts: CreateShellToolOptions): CustomTool;
|
|
|
700
739
|
* `todolist` — in-session task tracking for multi-step work.
|
|
701
740
|
*
|
|
702
741
|
* The agent uses this to plan complex tasks and track progress.
|
|
703
|
-
* Inspired by
|
|
742
|
+
* Inspired by a peer project's todo.ts and Claude Code's TodoWrite.
|
|
704
743
|
*
|
|
705
744
|
* Actions:
|
|
706
745
|
* - add(title) → add a new todo item
|
|
@@ -964,4 +1003,4 @@ interface CreateWriteFileToolOptions {
|
|
|
964
1003
|
}
|
|
965
1004
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
966
1005
|
|
|
967
|
-
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
1006
|
+
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
package/dist/index.d.ts
CHANGED
|
@@ -182,6 +182,34 @@ declare function commandDenialReason(command: string, policies: CommandPolicy[])
|
|
|
182
182
|
/** `true` when no policy denies `command` (an empty policy array allows everything). */
|
|
183
183
|
declare function isCommandAllowed(command: string, policies: CommandPolicy[]): boolean;
|
|
184
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Context-tolerant single-occurrence text matching (`seek_sequence` parity, ported
|
|
187
|
+
* from the AgentBuilder Codex clone, M10/M13). Where a naive `edit_file` matches
|
|
188
|
+
* `old_string` byte-for-byte (or with a single whitespace-normalized fallback),
|
|
189
|
+
* this matcher is safe AND forgiving:
|
|
190
|
+
*
|
|
191
|
+
* Stage 1 — exact byte substring, with an **ambiguity guard**: if the target
|
|
192
|
+
* appears more than once it throws instead of silently editing the first hit
|
|
193
|
+
* (a too-short `old_string` editing the wrong location is the classic footgun).
|
|
194
|
+
* Stage 2 — line-based match down a **strictness ladder** (exact → rstrip → trim
|
|
195
|
+
* → unicode-normalize), stopping at the first rung that yields exactly ONE
|
|
196
|
+
* match; a rung matching 2+ positions throws (ambiguous), never picks one.
|
|
197
|
+
*
|
|
198
|
+
* Pure. Preserves the file's CRLF/LF style on the replaced region. Throws typed
|
|
199
|
+
* {@link ContextMatchError} (`empty | ambiguous | not_found`) so the caller maps to
|
|
200
|
+
* its own `{ ok: false, error }` shape.
|
|
201
|
+
*/
|
|
202
|
+
type ContextMatchReason = "empty" | "ambiguous" | "not_found";
|
|
203
|
+
declare class ContextMatchError extends Error {
|
|
204
|
+
readonly reason: ContextMatchReason;
|
|
205
|
+
constructor(reason: ContextMatchReason, message: string);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Return `content` with the single occurrence of `find` replaced by `replace`, using the two-stage
|
|
209
|
+
* context-tolerant matcher. Throws {@link ContextMatchError} on empty/ambiguous/not-found.
|
|
210
|
+
*/
|
|
211
|
+
declare function replaceUnique(content: string, find: string, replace: string): string;
|
|
212
|
+
|
|
185
213
|
/**
|
|
186
214
|
* SSRF guard for network tools (M3-1).
|
|
187
215
|
*
|
|
@@ -339,6 +367,17 @@ declare function catastrophicShellReason(command: string): string | null;
|
|
|
339
367
|
* name/inputSchema/handler; does NOT mutate the original tool.
|
|
340
368
|
*/
|
|
341
369
|
declare function withDescription(tool: CustomTool, description: string): CustomTool;
|
|
370
|
+
/**
|
|
371
|
+
* Return a new `CustomTool` exposed under a different `name`, sharing the SAME
|
|
372
|
+
* `inputSchema` + `handler` (alias parity). Preserves description; does NOT mutate
|
|
373
|
+
* the original. This is how an agent exposes a built-in under its preferred name —
|
|
374
|
+
* e.g. a Codex-style agent aliases `search_text` → `grep`, `shell_exec` → `run_shell`
|
|
375
|
+
* — without re-implementing the tool. Pure, never throws: the final `name` is
|
|
376
|
+
* validated by the SDK at tool-registration time (the single authority for the
|
|
377
|
+
* `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` + reserved-name rules), so this helper does not
|
|
378
|
+
* re-validate (no duplicated contract).
|
|
379
|
+
*/
|
|
380
|
+
declare function withName(tool: CustomTool, name: string): CustomTool;
|
|
342
381
|
/** Render mode for {@link renderToolList}. Local — the published `renderToolList`
|
|
343
382
|
* signature inlines this union into its `.d.ts`, so consumers pass the literal
|
|
344
383
|
* ("summary" | "names" | "full") without needing the named type exported. */
|
|
@@ -580,7 +619,7 @@ declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool
|
|
|
580
619
|
* SE37 — the public reasoning toolkit: `ReasoningTools.create()` returns a
|
|
581
620
|
* `think` + `analyze` scratchpad (no-side-effect tools that echo the model's
|
|
582
621
|
* structured reasoning back as an observation, so the ReAct loop feeds it
|
|
583
|
-
* forward). Mirrors Anthropic's "think" tool +
|
|
622
|
+
* forward). Mirrors Anthropic's "think" tool + a peer's `ReasoningTools`.
|
|
584
623
|
*
|
|
585
624
|
* Lives in `@theokit/sdk-tools` (not core) so the full toolkit stays out of the
|
|
586
625
|
* core bundle. The `reasoning: true` agent flag auto-attaches an equivalent
|
|
@@ -700,7 +739,7 @@ declare function createShellTool(opts: CreateShellToolOptions): CustomTool;
|
|
|
700
739
|
* `todolist` — in-session task tracking for multi-step work.
|
|
701
740
|
*
|
|
702
741
|
* The agent uses this to plan complex tasks and track progress.
|
|
703
|
-
* Inspired by
|
|
742
|
+
* Inspired by a peer project's todo.ts and Claude Code's TodoWrite.
|
|
704
743
|
*
|
|
705
744
|
* Actions:
|
|
706
745
|
* - add(title) → add a new todo item
|
|
@@ -964,4 +1003,4 @@ interface CreateWriteFileToolOptions {
|
|
|
964
1003
|
}
|
|
965
1004
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
966
1005
|
|
|
967
|
-
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
1006
|
+
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
package/dist/index.js
CHANGED
|
@@ -263,6 +263,90 @@ function createSessionArtifactStore(options) {
|
|
|
263
263
|
}
|
|
264
264
|
return { write, read, has, list, path };
|
|
265
265
|
}
|
|
266
|
+
|
|
267
|
+
// src/internal/context-match.ts
|
|
268
|
+
var ContextMatchError = class extends Error {
|
|
269
|
+
reason;
|
|
270
|
+
constructor(reason, message) {
|
|
271
|
+
super(message);
|
|
272
|
+
this.name = "ContextMatchError";
|
|
273
|
+
this.reason = reason;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
function normalizeUnicode(s) {
|
|
277
|
+
return s.replace(/[‐-―−]/g, "-").replace(/[‘-‛]/g, "'").replace(/[“-‟]/g, '"').replace(/[ - ]/g, " ");
|
|
278
|
+
}
|
|
279
|
+
var LINE_MATCH_LADDER = [
|
|
280
|
+
(s) => s,
|
|
281
|
+
// exact
|
|
282
|
+
(s) => s.replace(/\s+$/, ""),
|
|
283
|
+
// rstrip (ignore trailing whitespace)
|
|
284
|
+
(s) => s.trim(),
|
|
285
|
+
// trim (ignore leading + trailing)
|
|
286
|
+
(s) => normalizeUnicode(s).trim()
|
|
287
|
+
// unicode + trim (loosest)
|
|
288
|
+
];
|
|
289
|
+
function matchesAt(lines, pattern, i, norm) {
|
|
290
|
+
for (let p = 0; p < pattern.length; p++) {
|
|
291
|
+
const lineAt = lines[i + p];
|
|
292
|
+
const patAt = pattern[p];
|
|
293
|
+
if (lineAt === void 0 || patAt === void 0 || norm(lineAt) !== norm(patAt)) return false;
|
|
294
|
+
}
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
function findHits(lines, pattern, norm) {
|
|
298
|
+
const hits = [];
|
|
299
|
+
for (let i = 0; i + pattern.length <= lines.length; i++) {
|
|
300
|
+
if (matchesAt(lines, pattern, i, norm)) hits.push(i);
|
|
301
|
+
}
|
|
302
|
+
return hits;
|
|
303
|
+
}
|
|
304
|
+
function seekUniqueLineMatch(lines, pattern, find) {
|
|
305
|
+
if (pattern.length === 0 || pattern.length > lines.length) return null;
|
|
306
|
+
for (const norm of LINE_MATCH_LADDER) {
|
|
307
|
+
const hits = findHits(lines, pattern, norm);
|
|
308
|
+
if (hits.length === 1) return hits[0] ?? null;
|
|
309
|
+
if (hits.length > 1) {
|
|
310
|
+
throw new ContextMatchError(
|
|
311
|
+
"ambiguous",
|
|
312
|
+
`target text is ambiguous (multiple matches); include more context:
|
|
313
|
+
${find}`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
function replaceUnique(content, find, replace) {
|
|
320
|
+
if (find === "") {
|
|
321
|
+
throw new ContextMatchError(
|
|
322
|
+
"empty",
|
|
323
|
+
"empty find is not a valid target; provide the text to replace"
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
const first = content.indexOf(find);
|
|
327
|
+
if (first !== -1) {
|
|
328
|
+
if (content.indexOf(find, first + 1) !== -1) {
|
|
329
|
+
throw new ContextMatchError(
|
|
330
|
+
"ambiguous",
|
|
331
|
+
`target text is ambiguous (multiple matches); include more context:
|
|
332
|
+
${find}`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
return content.slice(0, first) + replace + content.slice(first + find.length);
|
|
336
|
+
}
|
|
337
|
+
const lines = content.split("\n");
|
|
338
|
+
const at = seekUniqueLineMatch(lines, find.split("\n"), find);
|
|
339
|
+
if (at === null) {
|
|
340
|
+
throw new ContextMatchError("not_found", `target text not found:
|
|
341
|
+
${find}`);
|
|
342
|
+
}
|
|
343
|
+
const patternLen = find.split("\n").length;
|
|
344
|
+
const matchedCrlf = patternLen > 0 && lines.slice(at, at + patternLen).every((l) => l.endsWith("\r"));
|
|
345
|
+
const replaceLines = matchedCrlf ? replace.split("\n").map((l) => l.endsWith("\r") ? l : `${l}\r`) : replace.split("\n");
|
|
346
|
+
return [...lines.slice(0, at), ...replaceLines, ...lines.slice(at + patternLen)].join("\n");
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/edit-file.ts
|
|
266
350
|
function createEditFileTool(opts) {
|
|
267
351
|
const { projectRoot } = opts;
|
|
268
352
|
return Tool.create({
|
|
@@ -304,26 +388,36 @@ function createEditFileTool(opts) {
|
|
|
304
388
|
const exactIdx = content.indexOf(old_string);
|
|
305
389
|
if (exactIdx !== -1) {
|
|
306
390
|
await copyFile(absolutePath, `${absolutePath}.bak`);
|
|
307
|
-
const
|
|
308
|
-
await writeFile(absolutePath,
|
|
391
|
+
const result = content.slice(0, exactIdx) + new_string + content.slice(exactIdx + old_string.length);
|
|
392
|
+
await writeFile(absolutePath, result, "utf-8");
|
|
309
393
|
return JSON.stringify({ ok: true, replacements: 1 });
|
|
310
394
|
}
|
|
311
395
|
const normalizedContent = normalizeWhitespace(content);
|
|
312
396
|
const normalizedOld = normalizeWhitespace(old_string);
|
|
313
397
|
const normalizedIdx = normalizedContent.indexOf(normalizedOld);
|
|
314
|
-
if (normalizedIdx
|
|
315
|
-
|
|
398
|
+
if (normalizedIdx !== -1) {
|
|
399
|
+
const span = findOriginalSpan(
|
|
400
|
+
content,
|
|
401
|
+
normalizedContent,
|
|
402
|
+
normalizedIdx,
|
|
403
|
+
normalizedOld.length
|
|
404
|
+
);
|
|
405
|
+
await copyFile(absolutePath, `${absolutePath}.bak`);
|
|
406
|
+
const result = content.slice(0, span.start) + new_string + content.slice(span.end);
|
|
407
|
+
await writeFile(absolutePath, result, "utf-8");
|
|
408
|
+
return JSON.stringify({ ok: true, replacements: 1 });
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
const result = replaceUnique(content, old_string, new_string);
|
|
412
|
+
await copyFile(absolutePath, `${absolutePath}.bak`);
|
|
413
|
+
await writeFile(absolutePath, result, "utf-8");
|
|
414
|
+
return JSON.stringify({ ok: true, replacements: 1 });
|
|
415
|
+
} catch (err) {
|
|
416
|
+
if (err instanceof ContextMatchError) {
|
|
417
|
+
return JSON.stringify({ ok: false, error: "no_match", path });
|
|
418
|
+
}
|
|
419
|
+
throw err;
|
|
316
420
|
}
|
|
317
|
-
const span = findOriginalSpan(
|
|
318
|
-
content,
|
|
319
|
-
normalizedContent,
|
|
320
|
-
normalizedIdx,
|
|
321
|
-
normalizedOld.length
|
|
322
|
-
);
|
|
323
|
-
await copyFile(absolutePath, `${absolutePath}.bak`);
|
|
324
|
-
const result = content.slice(0, span.start) + new_string + content.slice(span.end);
|
|
325
|
-
await writeFile(absolutePath, result, "utf-8");
|
|
326
|
-
return JSON.stringify({ ok: true, replacements: 1 });
|
|
327
421
|
}
|
|
328
422
|
});
|
|
329
423
|
}
|
|
@@ -988,6 +1082,14 @@ function withDescription(tool, description) {
|
|
|
988
1082
|
handler: tool.handler
|
|
989
1083
|
};
|
|
990
1084
|
}
|
|
1085
|
+
function withName(tool, name) {
|
|
1086
|
+
return {
|
|
1087
|
+
name,
|
|
1088
|
+
description: tool.description,
|
|
1089
|
+
inputSchema: tool.inputSchema,
|
|
1090
|
+
handler: tool.handler
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
991
1093
|
function esc(s) {
|
|
992
1094
|
return String(s).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
993
1095
|
}
|
|
@@ -2239,6 +2341,6 @@ async function isBinaryFile(absolutePath) {
|
|
|
2239
2341
|
}
|
|
2240
2342
|
}
|
|
2241
2343
|
|
|
2242
|
-
export { CatastrophicCommandError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
2344
|
+
export { CatastrophicCommandError, ContextMatchError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
|
2243
2345
|
//# sourceMappingURL=index.js.map
|
|
2244
2346
|
//# sourceMappingURL=index.js.map
|