@theokit/sdk-tools 0.16.0 → 0.18.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 +23 -0
- package/dist/index.cjs +75 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +74 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -671,6 +671,18 @@ interface CreateReadFileToolOptions {
|
|
|
671
671
|
* identical current behavior (multi-tenant / per-request roots).
|
|
672
672
|
*/
|
|
673
673
|
filesystem?: FilesystemProvider;
|
|
674
|
+
/**
|
|
675
|
+
* M17 — render a `cat -n`-style numbered view (`<n>\t<line>`) instead of raw content, so the model can
|
|
676
|
+
* cite / edit by line number (Codex / Claude-Code read idiom). Default `false` ⇒ raw content (unchanged).
|
|
677
|
+
*/
|
|
678
|
+
lineNumbers?: boolean;
|
|
679
|
+
/**
|
|
680
|
+
* M17 — opt-in "reads-anywhere" (Codex read-only sandbox): honor an ABSOLUTE `path` outside `projectRoot`
|
|
681
|
+
* instead of rejecting it as traversal. The `isForbiddenPath` secret guard STILL fires first, so `.env`/
|
|
682
|
+
* `.git`/lock files remain blocked. Default `false` ⇒ absolute paths rejected (unchanged). Opt-in only —
|
|
683
|
+
* this widens the read boundary to the whole filesystem; enable only for a trusted local agent.
|
|
684
|
+
*/
|
|
685
|
+
allowAbsolute?: boolean;
|
|
674
686
|
}
|
|
675
687
|
declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool;
|
|
676
688
|
|
|
@@ -910,6 +922,22 @@ interface TruncationResult {
|
|
|
910
922
|
}
|
|
911
923
|
declare function truncateOutput(output: string, opts?: TruncationOptions): TruncationResult;
|
|
912
924
|
|
|
925
|
+
/**
|
|
926
|
+
* `update_plan` — built-in tool for coding agents.
|
|
927
|
+
*
|
|
928
|
+
* Codex-faithful: the model posts a DECLARATIVE plan — an ordered list of short steps, each
|
|
929
|
+
* `pending | in_progress | completed` — and refreshes it as work proceeds. Codex's invariant is
|
|
930
|
+
* "exactly one step in_progress until everything is done"; this tool WARNS (never rejects) when that
|
|
931
|
+
* doesn't hold, so the agent self-corrects on the next update rather than failing the turn.
|
|
932
|
+
*
|
|
933
|
+
* Surface-agnostic by design (M17 DX): the result is STRUCTURED (`{ ok, steps, warning? }`) — each
|
|
934
|
+
* surface (terminal TUI, desktop, web) renders the checklist however it likes, rather than the package
|
|
935
|
+
* hard-coding glyphs. Result shape (always a JSON string):
|
|
936
|
+
* - `{ ok: true, explanation: string | null, steps: PlanStep[], warning?: string }`
|
|
937
|
+
*/
|
|
938
|
+
|
|
939
|
+
declare function createUpdatePlanTool(): CustomTool;
|
|
940
|
+
|
|
913
941
|
/**
|
|
914
942
|
* `web_fetch` — built-in tool for coding agents.
|
|
915
943
|
*
|
|
@@ -1073,4 +1101,4 @@ interface CreateWriteFileToolOptions {
|
|
|
1073
1101
|
}
|
|
1074
1102
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
1075
1103
|
|
|
1076
|
-
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, 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, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
|
1104
|
+
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, 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, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, 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
|
@@ -671,6 +671,18 @@ interface CreateReadFileToolOptions {
|
|
|
671
671
|
* identical current behavior (multi-tenant / per-request roots).
|
|
672
672
|
*/
|
|
673
673
|
filesystem?: FilesystemProvider;
|
|
674
|
+
/**
|
|
675
|
+
* M17 — render a `cat -n`-style numbered view (`<n>\t<line>`) instead of raw content, so the model can
|
|
676
|
+
* cite / edit by line number (Codex / Claude-Code read idiom). Default `false` ⇒ raw content (unchanged).
|
|
677
|
+
*/
|
|
678
|
+
lineNumbers?: boolean;
|
|
679
|
+
/**
|
|
680
|
+
* M17 — opt-in "reads-anywhere" (Codex read-only sandbox): honor an ABSOLUTE `path` outside `projectRoot`
|
|
681
|
+
* instead of rejecting it as traversal. The `isForbiddenPath` secret guard STILL fires first, so `.env`/
|
|
682
|
+
* `.git`/lock files remain blocked. Default `false` ⇒ absolute paths rejected (unchanged). Opt-in only —
|
|
683
|
+
* this widens the read boundary to the whole filesystem; enable only for a trusted local agent.
|
|
684
|
+
*/
|
|
685
|
+
allowAbsolute?: boolean;
|
|
674
686
|
}
|
|
675
687
|
declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool;
|
|
676
688
|
|
|
@@ -910,6 +922,22 @@ interface TruncationResult {
|
|
|
910
922
|
}
|
|
911
923
|
declare function truncateOutput(output: string, opts?: TruncationOptions): TruncationResult;
|
|
912
924
|
|
|
925
|
+
/**
|
|
926
|
+
* `update_plan` — built-in tool for coding agents.
|
|
927
|
+
*
|
|
928
|
+
* Codex-faithful: the model posts a DECLARATIVE plan — an ordered list of short steps, each
|
|
929
|
+
* `pending | in_progress | completed` — and refreshes it as work proceeds. Codex's invariant is
|
|
930
|
+
* "exactly one step in_progress until everything is done"; this tool WARNS (never rejects) when that
|
|
931
|
+
* doesn't hold, so the agent self-corrects on the next update rather than failing the turn.
|
|
932
|
+
*
|
|
933
|
+
* Surface-agnostic by design (M17 DX): the result is STRUCTURED (`{ ok, steps, warning? }`) — each
|
|
934
|
+
* surface (terminal TUI, desktop, web) renders the checklist however it likes, rather than the package
|
|
935
|
+
* hard-coding glyphs. Result shape (always a JSON string):
|
|
936
|
+
* - `{ ok: true, explanation: string | null, steps: PlanStep[], warning?: string }`
|
|
937
|
+
*/
|
|
938
|
+
|
|
939
|
+
declare function createUpdatePlanTool(): CustomTool;
|
|
940
|
+
|
|
913
941
|
/**
|
|
914
942
|
* `web_fetch` — built-in tool for coding agents.
|
|
915
943
|
*
|
|
@@ -1073,4 +1101,4 @@ interface CreateWriteFileToolOptions {
|
|
|
1073
1101
|
}
|
|
1074
1102
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
1075
1103
|
|
|
1076
|
-
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, 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, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
|
1104
|
+
export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, 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, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, copyFile, mkdir, writeFile, readdir, open, stat } from 'fs/promises';
|
|
2
|
-
import { dirname, join, relative, resolve, sep } from 'path';
|
|
2
|
+
import { dirname, join, relative, isAbsolute, resolve, sep } from 'path';
|
|
3
3
|
import { Tool, ConfigurationError } from '@theokit/sdk';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { existsSync, statSync, mkdirSync, writeFileSync, realpathSync, readFileSync, lstatSync, readlinkSync, readdirSync } from 'fs';
|
|
@@ -1577,23 +1577,53 @@ function createQuestionTool(opts) {
|
|
|
1577
1577
|
}
|
|
1578
1578
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
1579
1579
|
var BINARY_PROBE_BYTES = 8 * 1024;
|
|
1580
|
+
var SENSITIVE_SEGMENTS = /* @__PURE__ */ new Set([".env", ".git", "node_modules", ".theo"]);
|
|
1581
|
+
function isForbiddenAtAnyDepth(path) {
|
|
1582
|
+
const segs = path.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
1583
|
+
return segs.some((s) => {
|
|
1584
|
+
if (s === ".env.example") return false;
|
|
1585
|
+
return SENSITIVE_SEGMENTS.has(s) || /^\.env\./.test(s);
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
function forbiddenReadError(path, allowAbsolute) {
|
|
1589
|
+
if (isForbiddenPath(path)) {
|
|
1590
|
+
return JSON.stringify({ ok: false, error: "forbidden_path", path });
|
|
1591
|
+
}
|
|
1592
|
+
if (allowAbsolute && isAbsolute(path) && isForbiddenAtAnyDepth(path)) {
|
|
1593
|
+
return JSON.stringify({ ok: false, error: "forbidden_path", path });
|
|
1594
|
+
}
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
function renderView(content, opts) {
|
|
1598
|
+
const paginated = opts.offset !== void 0 || opts.limit !== void 0;
|
|
1599
|
+
if (!opts.lineNumbers && !paginated) return content;
|
|
1600
|
+
const lines = content.split("\n");
|
|
1601
|
+
const start = Math.max(1, opts.offset ?? 1);
|
|
1602
|
+
const end = opts.limit !== void 0 ? Math.min(lines.length, start - 1 + opts.limit) : lines.length;
|
|
1603
|
+
const slice = lines.slice(start - 1, end);
|
|
1604
|
+
return opts.lineNumbers ? slice.map((l, i) => `${start + i} ${l}`).join("\n") : slice.join("\n");
|
|
1605
|
+
}
|
|
1580
1606
|
function createReadFileTool(opts) {
|
|
1581
|
-
const { projectRoot, readTracker, filesystem } = opts;
|
|
1607
|
+
const { projectRoot, readTracker, filesystem, lineNumbers, allowAbsolute } = opts;
|
|
1608
|
+
const numbered = lineNumbers === true ? " Returns a cat -n numbered view (`<n>\\t<line>`)." : "";
|
|
1609
|
+
const abs = allowAbsolute === true ? " Absolute paths outside the project are honored." : "";
|
|
1582
1610
|
return Tool.create({
|
|
1583
1611
|
name: "read_file",
|
|
1584
|
-
description: "Read a
|
|
1612
|
+
description: "Read a text file as UTF-8. ALWAYS read a file before you edit it (edit_file) or overwrite it (write_file), so your old_string / new content matches the real bytes exactly." + numbered + abs + " By default returns the whole file; use the optional offset (1-based first line) + limit to page through a large file, or search_text to locate a symbol. Refuses sensitive files (.env, .git/, node_modules/, .theo/, lock files) and binary files (null byte in the first 8 KB); caps at 5 MB. Returns { ok, content, size } or { ok: false, error }.",
|
|
1585
1613
|
inputSchema: z.object({
|
|
1586
|
-
path: z.string().min(1).describe("
|
|
1614
|
+
path: z.string().min(1).describe("File path (project-relative; absolute when allowed)."),
|
|
1615
|
+
offset: z.number().int().min(1).optional().describe("1-based first line to read (default 1)."),
|
|
1616
|
+
limit: z.number().int().min(1).optional().describe("Max number of lines to read (default: all).")
|
|
1587
1617
|
}),
|
|
1588
|
-
handler: async ({ path }, ctx) => {
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
}
|
|
1618
|
+
handler: async ({ path, offset, limit }, ctx) => {
|
|
1619
|
+
const forbidden = forbiddenReadError(path, allowAbsolute === true);
|
|
1620
|
+
if (forbidden !== null) return forbidden;
|
|
1621
|
+
const view = { lineNumbers, offset, limit };
|
|
1592
1622
|
if (filesystem) {
|
|
1593
1623
|
const backend = await resolveFilesystem(filesystem, ctx ?? {});
|
|
1594
|
-
return readViaBackend(backend, path, (mtimeMs) => readTracker?.record(path, mtimeMs));
|
|
1624
|
+
return readViaBackend(backend, path, view, (mtimeMs) => readTracker?.record(path, mtimeMs));
|
|
1595
1625
|
}
|
|
1596
|
-
const boundary = resolveBoundary(path, projectRoot);
|
|
1626
|
+
const boundary = resolveBoundary(path, projectRoot, allowAbsolute === true);
|
|
1597
1627
|
if ("error" in boundary) return boundary.error;
|
|
1598
1628
|
const opened = await openHandleSafe(boundary.absolutePath, path);
|
|
1599
1629
|
if ("error" in opened) return opened.error;
|
|
@@ -1601,6 +1631,7 @@ function createReadFileTool(opts) {
|
|
|
1601
1631
|
return await readContent(
|
|
1602
1632
|
opened.handle,
|
|
1603
1633
|
path,
|
|
1634
|
+
view,
|
|
1604
1635
|
(mtimeMs) => readTracker?.record(path, mtimeMs)
|
|
1605
1636
|
);
|
|
1606
1637
|
} finally {
|
|
@@ -1609,7 +1640,7 @@ function createReadFileTool(opts) {
|
|
|
1609
1640
|
}
|
|
1610
1641
|
});
|
|
1611
1642
|
}
|
|
1612
|
-
async function readViaBackend(backend, path, onRead) {
|
|
1643
|
+
async function readViaBackend(backend, path, view, onRead) {
|
|
1613
1644
|
try {
|
|
1614
1645
|
const stat2 = await backend.stat(path);
|
|
1615
1646
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
@@ -1621,12 +1652,12 @@ async function readViaBackend(backend, path, onRead) {
|
|
|
1621
1652
|
limit: MAX_FILE_SIZE
|
|
1622
1653
|
});
|
|
1623
1654
|
}
|
|
1624
|
-
const
|
|
1625
|
-
if (
|
|
1655
|
+
const raw = await backend.readFile(path);
|
|
1656
|
+
if (raw.includes("\0")) {
|
|
1626
1657
|
return JSON.stringify({ ok: false, error: "binary_file", path, size: stat2.size });
|
|
1627
1658
|
}
|
|
1628
1659
|
onRead?.(stat2.mtimeMs);
|
|
1629
|
-
return JSON.stringify({ ok: true, content, size: stat2.size });
|
|
1660
|
+
return JSON.stringify({ ok: true, content: renderView(raw, view), size: stat2.size });
|
|
1630
1661
|
} catch (err) {
|
|
1631
1662
|
if (err instanceof FileNotFoundError) {
|
|
1632
1663
|
return JSON.stringify({ ok: false, error: "not_found", path });
|
|
@@ -1637,7 +1668,10 @@ async function readViaBackend(backend, path, onRead) {
|
|
|
1637
1668
|
throw err;
|
|
1638
1669
|
}
|
|
1639
1670
|
}
|
|
1640
|
-
function resolveBoundary(path, projectRoot) {
|
|
1671
|
+
function resolveBoundary(path, projectRoot, allowAbsolute) {
|
|
1672
|
+
if (allowAbsolute && isAbsolute(path)) {
|
|
1673
|
+
return { absolutePath: path };
|
|
1674
|
+
}
|
|
1641
1675
|
try {
|
|
1642
1676
|
const absolutePath = safePathJoin(projectRoot, path);
|
|
1643
1677
|
assertNoSymlinkEscape(absolutePath, projectRoot);
|
|
@@ -1661,7 +1695,7 @@ async function openHandleSafe(absolutePath, path) {
|
|
|
1661
1695
|
throw err;
|
|
1662
1696
|
}
|
|
1663
1697
|
}
|
|
1664
|
-
async function readContent(handle, path, onRead) {
|
|
1698
|
+
async function readContent(handle, path, view, onRead) {
|
|
1665
1699
|
const stat2 = await handle.stat();
|
|
1666
1700
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
1667
1701
|
return JSON.stringify({
|
|
@@ -1675,9 +1709,9 @@ async function readContent(handle, path, onRead) {
|
|
|
1675
1709
|
if (await isBinaryProbe(handle, Number(stat2.size))) {
|
|
1676
1710
|
return JSON.stringify({ ok: false, error: "binary_file", path, size: stat2.size });
|
|
1677
1711
|
}
|
|
1678
|
-
const
|
|
1712
|
+
const raw = await handle.readFile({ encoding: "utf-8" });
|
|
1679
1713
|
onRead?.(stat2.mtimeMs);
|
|
1680
|
-
return JSON.stringify({ ok: true, content, size: stat2.size });
|
|
1714
|
+
return JSON.stringify({ ok: true, content: renderView(raw, view), size: stat2.size });
|
|
1681
1715
|
}
|
|
1682
1716
|
async function isBinaryProbe(handle, size) {
|
|
1683
1717
|
const probeLen = Math.min(BINARY_PROBE_BYTES, size);
|
|
@@ -2295,6 +2329,27 @@ function truncateOutput(output, opts) {
|
|
|
2295
2329
|
overflowPath
|
|
2296
2330
|
};
|
|
2297
2331
|
}
|
|
2332
|
+
var STATUS = ["pending", "in_progress", "completed"];
|
|
2333
|
+
var planStepSchema = z.object({
|
|
2334
|
+
step: z.string().min(1).max(100).describe("A short step, \u2264 ~7 words."),
|
|
2335
|
+
status: z.enum(STATUS)
|
|
2336
|
+
});
|
|
2337
|
+
function createUpdatePlanTool() {
|
|
2338
|
+
return Tool.create({
|
|
2339
|
+
name: "update_plan",
|
|
2340
|
+
description: "Post or refresh a short plan so the user sees your progress on a multi-step task. Pass an ordered `plan` of steps, each with a status (pending | in_progress | completed); keep exactly one step in_progress at a time and mark steps completed as you finish. Returns { ok, steps, warning? } as a JSON string \u2014 the surface renders the checklist. A `warning` is returned (not an error) if the one-in_progress invariant is violated, so you can self-correct on the next update.",
|
|
2341
|
+
inputSchema: z.object({
|
|
2342
|
+
explanation: z.string().max(200).optional().describe("One line on what changed / why (optional)."),
|
|
2343
|
+
plan: z.array(planStepSchema).min(1).describe("The ordered steps.")
|
|
2344
|
+
}),
|
|
2345
|
+
handler: ({ explanation, plan }) => {
|
|
2346
|
+
const inProgress = plan.filter((s) => s.status === "in_progress").length;
|
|
2347
|
+
const allDone = plan.every((s) => s.status === "completed");
|
|
2348
|
+
const warning = !allDone && inProgress !== 1 ? `keep exactly one step in_progress until all are completed \u2014 found ${inProgress}` : void 0;
|
|
2349
|
+
return JSON.stringify({ ok: true, explanation: explanation ?? null, steps: plan, warning });
|
|
2350
|
+
}
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2298
2353
|
var DEFAULT_TIMEOUT_MS4 = 3e4;
|
|
2299
2354
|
var MAX_BODY_BYTES = 1 * 1024 * 1024;
|
|
2300
2355
|
function createWebFetchTool(opts) {
|
|
@@ -2597,6 +2652,6 @@ async function isBinaryFile(absolutePath) {
|
|
|
2597
2652
|
}
|
|
2598
2653
|
}
|
|
2599
2654
|
|
|
2600
|
-
export { CatastrophicCommandError, ContextMatchError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
|
2655
|
+
export { CatastrophicCommandError, ContextMatchError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
|
|
2601
2656
|
//# sourceMappingURL=index.js.map
|
|
2602
2657
|
//# sourceMappingURL=index.js.map
|