@cryer/star-cli 0.3.8 → 0.3.10
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/README.md +16 -2
- package/README.zh-CN.md +15 -2
- package/dist/chunk-4IRY44TG.js +34 -0
- package/dist/chunk-4IRY44TG.js.map +1 -0
- package/dist/chunk-A5PXPWHB.js +2014 -0
- package/dist/chunk-A5PXPWHB.js.map +1 -0
- package/dist/chunk-IJGUW4PM.js +504 -0
- package/dist/chunk-IJGUW4PM.js.map +1 -0
- package/dist/chunk-MNVCCOI2.js +3510 -0
- package/dist/chunk-MNVCCOI2.js.map +1 -0
- package/dist/chunk-MVAMPVTA.js +232 -0
- package/dist/chunk-MVAMPVTA.js.map +1 -0
- package/dist/{chunk-IYWYSFSF.js → chunk-PDFC7QVW.js} +339 -218
- package/dist/chunk-PDFC7QVW.js.map +1 -0
- package/dist/chunk-URC7JXKX.js +1414 -0
- package/dist/chunk-URC7JXKX.js.map +1 -0
- package/dist/loop-TW2FHL7J.js +17 -0
- package/dist/main.js +257 -79
- package/dist/main.js.map +1 -1
- package/dist/provider-EWMUPBLH.js +11 -0
- package/dist/provider-EWMUPBLH.js.map +1 -0
- package/dist/{repl-YA23CK5R.js → repl-GBVIW5QR.js} +435 -262
- package/dist/repl-GBVIW5QR.js.map +1 -0
- package/dist/tools-7EBGCYYE.js +18 -0
- package/dist/tools-7EBGCYYE.js.map +1 -0
- package/package.json +18 -26
- package/dist/chunk-IYWYSFSF.js.map +0 -1
- package/dist/chunk-OHLA2DP7.js +0 -5849
- package/dist/chunk-OHLA2DP7.js.map +0 -1
- package/dist/loop-2MOFLXTG.js +0 -12
- package/dist/repl-YA23CK5R.js.map +0 -1
- /package/dist/{loop-2MOFLXTG.js.map → loop-TW2FHL7J.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/fs/edit.ts","../src/tools/fs/glob.ts","../src/tools/fs/grep.ts","../src/tools/fs/outline.ts","../src/tools/fs/read.ts","../src/tools/fs/read-image.ts","../src/tools/fs/write.ts","../src/tools/screenshot.ts","../src/core/screenshot.ts","../src/tools/tasks.ts","../src/tasks/format.ts","../src/tools/web/search.ts","../src/llm/debug.ts","../src/tools/registry.ts","../src/tools/index.ts"],"sourcesContent":["import { readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport {\n MAX_SNAPSHOT_CONTENT_BYTES,\n currentTurnMessageIndex,\n currentTurnSeq,\n nextSnapshotId,\n pushSnapshot,\n} from \"./snapshots\";\n\n// Same heuristic as read_file: a NUL in the first 8KB marks a binary file.\n// edit_file writes back as UTF-8, so an ASCII old_string that happens to\n// match inside a binary file would corrupt it irreversibly (U+FFFD\n// replacement on undecodable bytes), and snapshots cannot restore it.\nconst BINARY_PROBE_BYTES = 8192;\n\nfunction countOccurrences(haystack: string, needle: string): number {\n let count = 0;\n let idx = haystack.indexOf(needle);\n while (idx !== -1) {\n count += 1;\n idx = haystack.indexOf(needle, idx + needle.length);\n }\n return count;\n}\n\nfunction normalizeEol(text: string): string {\n return text.replace(/\\r\\n/g, \"\\n\");\n}\n\nconst schema = z.object({\n path: z.string().describe(\"File path, absolute or relative to the working directory\"),\n old_string: z.string().min(1).describe(\"Exact text to replace\"),\n new_string: z.string().describe(\"Replacement text\"),\n replace_all: z\n .boolean()\n .optional()\n .describe(\"Replace every occurrence instead of requiring a unique match\"),\n});\n\nexport const editFileTool: Tool<typeof schema> = {\n name: \"edit_file\",\n description:\n \"Replace an exact string in a file. Fails if old_string is not found or matches multiple locations unless replace_all is set. Refuses binary files and files over 5MB.\",\n permission: \"write\",\n parameters: schema,\n async execute(args, ctx) {\n const filePath = path.resolve(ctx.cwd, args.path);\n let content: string;\n let readMtimeMs: number;\n try {\n const st = await stat(filePath);\n // Past the snapshot content cap /undo keeps only metadata, so an edit\n // would be unrecoverable — refuse instead of writing blind.\n if (st.size > MAX_SNAPSHOT_CONTENT_BYTES) {\n return {\n content: `Refused to edit ${args.path}: file is ${st.size} bytes, over the 5MB limit (edits past it could not be restored by /undo)`,\n isError: true,\n };\n }\n readMtimeMs = st.mtimeMs;\n const buf = await readFile(filePath);\n if (buf.subarray(0, BINARY_PROBE_BYTES).includes(0)) {\n return { content: `Refused to edit binary file: ${args.path}`, isError: true };\n }\n content = buf.toString(\"utf8\");\n } catch (err) {\n return { content: `Failed to read ${args.path}: ${(err as Error).message}`, isError: true };\n }\n // Dual-path matching: exact first. When that finds nothing, retry in an\n // LF-normalized space — read_file strips \\r for display, so on a CRLF\n // file the model can only phrase a multi-line old_string with \\n, which\n // never matches the raw bytes. Uniqueness/replace_all counts are judged\n // in the normalized space; after replacing there, the text is converted\n // back to the original file's dominant line ending before writing.\n let working = content;\n let oldString = args.old_string;\n let newString = args.new_string;\n let restoreEol: ((text: string) => string) | null = null;\n let count = countOccurrences(working, oldString);\n if (count === 0) {\n const normalizedContent = normalizeEol(content);\n const normalizedOld = normalizeEol(oldString);\n const normalizedCount = countOccurrences(normalizedContent, normalizedOld);\n if (normalizedCount > 0) {\n const crlfCount = countOccurrences(content, \"\\r\\n\");\n const loneLfCount = countOccurrences(content.replace(/\\r\\n/g, \"\"), \"\\n\");\n restoreEol =\n crlfCount > 0 && crlfCount >= loneLfCount ? (text) => text.replace(/\\n/g, \"\\r\\n\") : null;\n working = normalizedContent;\n oldString = normalizedOld;\n newString = normalizeEol(newString);\n count = normalizedCount;\n }\n }\n if (count === 0) {\n return { content: `old_string not found in ${args.path}`, isError: true };\n }\n if (count > 1 && !args.replace_all) {\n return {\n content: `old_string matches ${count} locations in ${args.path}; provide more surrounding context or set replace_all`,\n isError: true,\n };\n }\n let updated = args.replace_all\n ? working.split(oldString).join(newString)\n : working.replace(oldString, () => newString);\n if (restoreEol) {\n updated = restoreEol(updated);\n }\n try {\n // Guard against a silent overwrite when the file changed on disk\n // between our read and our write.\n const now = await stat(filePath).catch(() => null);\n if (!now || now.mtimeMs !== readMtimeMs) {\n return {\n content: `Failed to edit ${args.path}: file changed since it was read; re-read and retry`,\n isError: true,\n };\n }\n await writeFile(filePath, updated, \"utf8\");\n } catch (err) {\n return { content: `Failed to write ${args.path}: ${(err as Error).message}`, isError: true };\n }\n const contentTooLarge = Buffer.byteLength(content, \"utf8\") > MAX_SNAPSHOT_CONTENT_BYTES;\n await pushSnapshot({\n id: nextSnapshotId(),\n path: filePath,\n existed: true,\n content: contentTooLarge ? null : content,\n contentTooLarge: contentTooLarge || undefined,\n toolName: \"edit_file\",\n timestamp: Date.now(),\n turn: ctx.snapshotContext?.turn ?? currentTurnSeq(),\n messageIndex: ctx.snapshotContext?.messageIndex ?? currentTurnMessageIndex(),\n owner: ctx.snapshotContext?.owner ?? \"root\",\n });\n return { content: `Edited ${args.path}: ${count} replacement${count > 1 ? \"s\" : \"\"}` };\n },\n};\n","import path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport { createIgnorePredicate, matchesGlob, walkFiles } from \"./util\";\n\nconst MAX_RESULTS = 100;\n\nconst GLOB_MAGIC = /[*?[{]/;\n\n// Leading directory segments without glob magic (everything before the final\n// segment, which may name a file) let src/**/*.ts walk <root>/src directly\n// instead of descending the whole tree. Matched paths are re-prefixed before\n// matching and display so output stays relative to the requested root.\nfunction literalDirPrefix(pattern: string): string[] {\n const segments = pattern.replace(/\\\\/g, \"/\").split(\"/\").slice(0, -1);\n const out: string[] = [];\n for (const segment of segments) {\n if (segment === \"\" || GLOB_MAGIC.test(segment)) {\n break;\n }\n out.push(segment);\n }\n return out;\n}\n\nconst schema = z.object({\n pattern: z\n .string()\n .describe(\n \"Glob pattern, e.g. 'src/**/*.ts'. Supports **, *, ?, {a,b} braces and [abc] character classes. A bare pattern like '*.ts' matches basenames recursively.\",\n ),\n path: z.string().optional().describe(\"Directory to search, defaults to the working directory\"),\n});\n\n// A \"..\" segment would walk above the requested root (the literal-prefix\n// optimization resolves it against the search root), escaping the cwd\n// boundary the permission gate enforces on the path argument.\nfunction hasParentSegment(pattern: string): boolean {\n return pattern\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .some((segment) => segment === \"..\");\n}\n\nexport const globTool: Tool<typeof schema> = {\n name: \"glob\",\n description:\n \"Find files by glob pattern. Skips node_modules, .git and dist. Follows symlinks that stay inside the working directory. Returns paths sorted by modification time, newest first, up to 100 results.\",\n permission: \"read\",\n parameters: schema,\n async execute(args, ctx) {\n if (hasParentSegment(args.pattern)) {\n return {\n content: `Refused glob pattern with '..' segment: ${args.pattern}`,\n isError: true,\n };\n }\n const root = path.resolve(ctx.cwd, args.path ?? \".\");\n const prefixSegments = literalDirPrefix(args.pattern);\n const walkRoot = prefixSegments.length > 0 ? path.join(root, ...prefixSegments) : root;\n const prefix = prefixSegments.length > 0 ? `${prefixSegments.join(\"/\")}/` : \"\";\n const { files, aborted } = await walkFiles(walkRoot, undefined, {\n ignore: createIgnorePredicate(ctx.cwd),\n signal: ctx.abortSignal,\n symlinkBoundary: ctx.cwd,\n nestedIgnore: true,\n });\n const matched = files\n .filter((f) => matchesGlob(args.pattern, `${prefix}${f.rel}`))\n .sort((a, b) => b.mtimeMs - a.mtimeMs)\n .slice(0, MAX_RESULTS);\n if (matched.length === 0) {\n return {\n content: aborted\n ? `Search interrupted before any files matched pattern: ${args.pattern}`\n : `No files matched pattern: ${args.pattern}`,\n };\n }\n const lines = matched.map((f) => `${prefix}${f.rel}`);\n if (aborted) {\n lines.push(\"... (interrupted: partial results)\");\n }\n return { content: lines.join(\"\\n\") };\n },\n};\n","import { readFile, realpath, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport {\n WALK_CONCURRENCY,\n type WalkedFile,\n createIgnorePredicate,\n isSensitivePath,\n matchesGlob,\n walkFiles,\n} from \"./util\";\n\nconst MAX_MATCHES = 250;\nconst MAX_LINE_CHARS = 500;\nconst MAX_PATTERN_CHARS = 200;\nconst MAX_FILE_BYTES = 5 * 1024 * 1024;\n\n// Very long patterns are usually pasted blobs, and a quantified group is the\n// classic catastrophic-backtracking shape — reject both before they hang the\n// process on a large tree.\nfunction isTooComplexPattern(pattern: string): boolean {\n return (\n pattern.length > MAX_PATTERN_CHARS || /\\)[+*]/.test(pattern) || /\\)\\{\\d+(,\\d*)?\\}/.test(pattern)\n );\n}\n\nconst schema = z.object({\n pattern: z.string().describe(\"Regular expression to search for\"),\n path: z\n .string()\n .optional()\n .describe(\"File or directory to search, defaults to the working directory\"),\n glob: z\n .string()\n .optional()\n .describe(\"Glob pattern to filter which files are searched, e.g. '*.ts'\"),\n ignoreCase: z.boolean().optional().describe(\"Case-insensitive matching\"),\n});\n\nexport const grepTool: Tool<typeof schema> = {\n name: \"grep\",\n description:\n \"Search file contents with a regular expression. Outputs 'file:line:content', up to 250 matches. Skips binary files, files over 5MB, sensitive files, node_modules and .git. Follows symlinks that stay inside the working directory.\",\n permission: \"read\",\n parameters: schema,\n async execute(args, ctx) {\n if (isTooComplexPattern(args.pattern)) {\n return {\n content: `pattern too complex: keep it under ${MAX_PATTERN_CHARS} characters and avoid quantified groups like (a+)+`,\n isError: true,\n };\n }\n let re: RegExp;\n try {\n re = new RegExp(args.pattern, args.ignoreCase ? \"i\" : \"\");\n } catch (err) {\n return { content: `Invalid regular expression: ${(err as Error).message}`, isError: true };\n }\n const root = path.resolve(ctx.cwd, args.path ?? \".\");\n let files: WalkedFile[];\n let interrupted = false;\n try {\n const st = await stat(root);\n if (st.isFile()) {\n // Symlink targets are checked too: a link named notes.txt can point\n // at a sensitive file whose resolved basename is on the blocklist.\n const resolved = await realpath(root).catch(() => null);\n if (isSensitivePath(root) || (resolved !== null && isSensitivePath(resolved))) {\n return {\n content: `Refused to grep sensitive file: ${args.path ?? \".\"}`,\n isError: true,\n };\n }\n files = [{ abs: root, rel: path.basename(root), mtimeMs: st.mtimeMs }];\n } else {\n const walked = await walkFiles(root, undefined, {\n ignore: createIgnorePredicate(ctx.cwd),\n withMtime: false,\n signal: ctx.abortSignal,\n symlinkBoundary: ctx.cwd,\n nestedIgnore: true,\n });\n interrupted = walked.aborted;\n // A link named notes.txt can resolve to a sensitive target inside the\n // cwd; check the resolved path as well as the link path.\n files = walked.files.filter(\n (f) =>\n !isSensitivePath(f.abs) && (f.resolved === undefined || !isSensitivePath(f.resolved)),\n );\n }\n } catch {\n return { content: `Path not found: ${args.path ?? \".\"}`, isError: true };\n }\n if (args.glob) {\n const glob = args.glob;\n files = files.filter((f) => matchesGlob(glob, f.rel));\n }\n // Files are scanned in concurrent chunks; matches are appended in file\n // order so output stays deterministic and the 250-match cut is stable.\n const scanFile = async (file: WalkedFile): Promise<string[] | null> => {\n const st = await stat(file.abs).catch(() => null);\n if (!st) {\n return null;\n }\n if (st.size > MAX_FILE_BYTES) {\n skippedLarge += 1;\n return null;\n }\n let buf: Buffer;\n try {\n buf = await readFile(file.abs);\n } catch {\n return null;\n }\n if (buf.includes(0)) {\n return null;\n }\n const hits: string[] = [];\n const lines = buf.toString(\"utf8\").split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (re.test(line)) {\n const shown = line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line;\n hits.push(`${file.rel}:${i + 1}:${shown}`);\n }\n }\n return hits;\n };\n const out: string[] = [];\n let truncated = false;\n let skippedLarge = 0;\n outer: for (let i = 0; i < files.length; i += WALK_CONCURRENCY) {\n if (ctx.abortSignal?.aborted) {\n interrupted = true;\n break;\n }\n const chunk = await Promise.all(\n files.slice(i, i + WALK_CONCURRENCY).map((file) => scanFile(file)),\n );\n for (const hits of chunk) {\n if (!hits) {\n continue;\n }\n for (const hit of hits) {\n out.push(hit);\n if (out.length >= MAX_MATCHES) {\n truncated = true;\n break outer;\n }\n }\n }\n }\n const skippedNote =\n skippedLarge > 0 ? `(skipped ${skippedLarge} file(s) larger than 5MB)` : null;\n if (out.length === 0) {\n return {\n content: `No matches for pattern: ${args.pattern}${skippedNote ? ` ${skippedNote}` : \"\"}${interrupted ? \" (search interrupted)\" : \"\"}`,\n };\n }\n if (truncated) {\n out.push(`... (truncated: more than ${MAX_MATCHES} matches)`);\n } else if (interrupted) {\n out.push(\"... (interrupted: partial results)\");\n }\n if (skippedNote) {\n out.push(`... ${skippedNote}`);\n }\n return { content: out.join(\"\\n\") };\n },\n};\n","import { readFile, realpath, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport {\n WALK_CONCURRENCY,\n type WalkedFile,\n createIgnorePredicate,\n isSensitivePath,\n walkFiles,\n} from \"./util\";\n\nconst MAX_DIR_FILES = 60;\nconst MAX_FILE_BYTES = 2 * 1024 * 1024;\nconst MAX_SYMBOLS_PER_FILE = 150;\nconst MAX_LINE_CHARS = 200;\nconst MAX_OUT_CHARS = 30 * 1024;\n// Nesting is shown through original indentation, capped so deep nesting\n// cannot push the signature out of view.\nconst MAX_INDENT_CHARS = 8;\n\n// Declaration-spotting regexes per language family. This is deliberately a\n// lightweight skeleton extractor, not a parser: it misses some declarations\n// (multi-line signatures, macros) and that is fine — the outline exists so\n// the model can navigate to line ranges cheaply; read_file still owns exact\n// content. Patterns are anchored to declaration shapes (leading modifiers,\n// trailing \"{\"/\";\"/end-of-line) so ordinary calls and control flow don't\n// match, and are tested against the raw line because member rules key on\n// indentation (methods are indented, top-level declarations are not).\nconst KEYWORD_EXCLUSION =\n \"(?!if\\\\b|for\\\\b|while\\\\b|switch\\\\b|catch\\\\b|return\\\\b|else\\\\b|do\\\\b|new\\\\b|throw\\\\b)\";\n\nconst TS_MEMBER_MODIFIERS =\n \"(?:public|private|protected|static|async|readonly|get|set|override|abstract)\";\n\nconst TS_LIKE = [\n /^(?:export\\s+)?(?:default\\s+)?(?:async\\s+)?function\\*?\\s+[\\w$]+/,\n /^(?:export\\s+)?(?:abstract\\s+)?class\\s+[\\w$]+/,\n /^(?:export\\s+)?interface\\s+[\\w$]+/,\n /^(?:export\\s+)?type\\s+[\\w$]+\\s*=/,\n /^(?:export\\s+)?(?:const\\s+)?enum\\s+[\\w$]+/,\n // const handler = (a, b) => / const handler = async (a) => — top level\n // only; locals inside functions are navigation noise.\n /^(?:export\\s+)?(?:const|let|var)\\s+[\\w$]+\\s*=\\s*(?:async\\s*)?(?:\\([^)]*\\)|[\\w$]+)\\s*=>/,\n // Indented class/object members with a body: name<T>(args): ReturnType {\n // — control flow excluded by the keyword lookahead, dotted calls\n // (this.x()) fail the anchored name-then-paren shape.\n new RegExp(\n `^\\\\s+(?:${TS_MEMBER_MODIFIERS}\\\\s+)*${KEYWORD_EXCLUSION}[\\\\w$]+(?:<[^>]*>)?\\\\s*\\\\([^)]*\\\\)\\\\s*(?::\\\\s*[^{}=;]+?)?\\\\s*(?:\\\\{\\\\s*)?\\\\}?\\\\s*$`,\n ),\n // Bodyless signatures (interface members, overloads): only when the\n // parens carry type annotations or an explicit return type follows —\n // otherwise indented calls like clearTimeout(timer); or finalize();\n // would leak into the outline.\n new RegExp(\n `^\\\\s+(?:${TS_MEMBER_MODIFIERS}\\\\s+)*${KEYWORD_EXCLUSION}[\\\\w$]+(?:<[^>]*>)?\\\\s*(?:\\\\([^)]*:[^)]*\\\\)\\\\s*(?::\\\\s*[^{}=;]+?)?|\\\\([^)]*\\\\)\\\\s*:\\\\s*[^{}=;]+?)\\\\s*;\\\\s*$`,\n ),\n];\n\nconst LANGUAGE_PATTERNS: Record<string, RegExp[]> = {\n ts: TS_LIKE,\n python: [/^\\s*(?:async\\s+)?def\\s+\\w+\\s*\\(/, /^\\s*class\\s+\\w+/],\n go: [/^func\\s+(?:\\([^)]*\\)\\s*)?\\w+\\s*\\(/, /^type\\s+\\w+\\s+(?:struct|interface)\\b/],\n rust: [\n /^\\s*(?:pub(?:\\([^)]*\\))?\\s+)?(?:async\\s+)?fn\\s+\\w+/,\n /^\\s*(?:pub\\s+)?(?:struct|enum|trait|union)\\s+\\w+/,\n ],\n jvm: [\n /^\\s*(?:(?:public|private|protected|internal|static|final|abstract|sealed|open|suspend|inline|override|async|partial|virtual|extern)\\s+)*(?:class|interface|enum|struct|record|object)\\s+\\w+/,\n /^\\s*(?:(?:public|private|protected|internal|open|suspend|inline|override)\\s+)*fun\\s+\\w+\\s*\\(/,\n new RegExp(\n `^\\\\s+(?:(?:public|private|protected|internal|static|final|abstract|sealed|open|suspend|inline|override|async|partial|virtual)\\\\s+)*[\\\\w<>[\\\\],.?]+\\\\s+${KEYWORD_EXCLUSION}\\\\w+\\\\s*\\\\([^;{}]*\\\\)\\\\s*(?:\\\\{|;|=>|$)`,\n ),\n ],\n cpp: [\n /^\\s*(?:class|struct|enum|union|namespace)\\s+\\w+/,\n new RegExp(\n `^\\\\s*(?:(?:static|inline|virtual|constexpr|extern|friend|explicit)\\\\s+)*[\\\\w:<>,~*&\\\\s]+?\\\\s+${KEYWORD_EXCLUSION}[\\\\w:~]+\\\\s*\\\\([^;]*\\\\)\\\\s*(?:const\\\\s*)?(?:noexcept\\\\s*)?(?:\\\\{|;|$)`,\n ),\n ],\n ruby: [/^\\s*def\\s+[\\w.=!?]+/, /^\\s*(?:class|module)\\s+[\\w:]+/],\n php: [\n /^\\s*(?:(?:public|private|protected|static|abstract|final)\\s+)*function\\s+\\w+\\s*\\(/,\n /^\\s*(?:(?:abstract|final)\\s+)?(?:class|interface|trait|enum)\\s+\\w+/,\n ],\n shell: [/^\\s*(?:function\\s+)?[\\w.-]+\\s*\\(\\s*\\)\\s*(?:\\{|$)/],\n swift: [\n /^\\s*(?:(?:public|private|internal|open|fileprivate|static|class|override|mutating|final)\\s+)*func\\s+\\w+\\s*\\(/,\n /^\\s*(?:(?:public|private|internal|open|final)\\s+)*(?:class|struct|enum|protocol|extension)\\s+\\w+/,\n ],\n scala: [\n /^\\s*(?:(?:private|protected|override|final|abstract|implicit)\\s+)*def\\s+\\w+\\s*[(\\[]/,\n /^\\s*(?:(?:abstract|final|sealed)\\s+)*(?:class|trait|object)\\s+\\w+/,\n ],\n};\n\nconst EXT_TO_LANGUAGE: Record<string, keyof typeof LANGUAGE_PATTERNS> = {\n ts: \"ts\",\n tsx: \"ts\",\n mts: \"ts\",\n cts: \"ts\",\n js: \"ts\",\n jsx: \"ts\",\n mjs: \"ts\",\n cjs: \"ts\",\n py: \"python\",\n pyi: \"python\",\n go: \"go\",\n rs: \"rust\",\n java: \"jvm\",\n kt: \"jvm\",\n kts: \"jvm\",\n cs: \"jvm\",\n c: \"cpp\",\n h: \"cpp\",\n cc: \"cpp\",\n cpp: \"cpp\",\n cxx: \"cpp\",\n hpp: \"cpp\",\n hh: \"cpp\",\n rb: \"ruby\",\n php: \"php\",\n sh: \"shell\",\n bash: \"shell\",\n zsh: \"shell\",\n swift: \"swift\",\n scala: \"scala\",\n sc: \"scala\",\n};\n\nfunction languageOf(filePath: string): RegExp[] | undefined {\n const name = path.basename(filePath);\n // Minified and machine-generated bundles are declaration soup; outlining\n // a bundled dependency is never useful navigation.\n if (/\\.(min|bundle|generated)\\.[^.]+$/.test(name)) return undefined;\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\";\n const lang = EXT_TO_LANGUAGE[ext];\n return lang === undefined ? undefined : LANGUAGE_PATTERNS[lang];\n}\n\ninterface SymbolLine {\n line: number;\n indent: string;\n text: string;\n}\n\nfunction extractSymbols(text: string, patterns: RegExp[]): SymbolLine[] {\n const out: SymbolLine[] = [];\n const lines = text.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const raw = (lines[i] ?? \"\").replace(/\\r$/, \"\");\n const trimmed = raw.trim();\n if (trimmed === \"\") continue;\n if (!patterns.some((re) => re.test(raw))) continue;\n const indent = raw.slice(0, raw.length - raw.trimStart().length).slice(0, MAX_INDENT_CHARS);\n const shown =\n trimmed.length > MAX_LINE_CHARS ? `${trimmed.slice(0, MAX_LINE_CHARS)}…` : trimmed;\n out.push({ line: i + 1, indent, text: shown });\n }\n return out;\n}\n\nasync function outlineFile(\n abs: string,\n): Promise<{ symbols: SymbolLine[]; total: number } | { binary: true } | { unreadable: true }> {\n const st = await stat(abs).catch(() => null);\n if (!st || st.size > MAX_FILE_BYTES) return { unreadable: true };\n const buf = await readFile(abs).catch(() => null);\n if (!buf) return { unreadable: true };\n if (buf.includes(0)) return { binary: true };\n const patterns = languageOf(abs);\n if (!patterns) return { unreadable: true };\n const all = extractSymbols(buf.toString(\"utf8\"), patterns);\n return { symbols: all.slice(0, MAX_SYMBOLS_PER_FILE), total: all.length };\n}\n\nfunction formatSymbols(symbols: SymbolLine[], total: number): string[] {\n const out = symbols.map((s) => `${s.line}\\t${s.indent}${s.text}`);\n if (total > symbols.length) {\n out.push(`... (${total - symbols.length} more declarations)`);\n }\n return out;\n}\n\nconst schema = z.object({\n path: z\n .string()\n .optional()\n .describe(\"Source file or directory to outline (default: the working directory)\"),\n maxFiles: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(`Directory mode: maximum files to include (default ${MAX_DIR_FILES})`),\n});\n\nexport const codeOutlineTool: Tool<typeof schema> = {\n name: \"code_outline\",\n description:\n \"List the declaration skeleton of a source file or directory (functions, classes, methods, types) with line numbers, without reading the bodies. Cheaper than read_file for navigating unfamiliar code: outline first, then read_file the exact line ranges you need. Supports TS/JS, Python, Go, Rust, Java/Kotlin/C#, C/C++, Ruby, PHP, Shell, Swift, Scala.\",\n permission: \"read\",\n parameters: schema,\n async execute(args, ctx) {\n const root = path.resolve(ctx.cwd, args.path ?? \".\");\n const st = await stat(root).catch(() => null);\n if (!st) {\n return { content: `Path not found: ${args.path ?? \".\"}`, isError: true };\n }\n\n if (st.isFile()) {\n // Same refusal as read_file: the raw name and the symlink target both\n // count, so a planted link cannot launder a sensitive basename.\n const resolved = await realpath(root).catch(() => null);\n if (isSensitivePath(root) || (resolved !== null && isSensitivePath(resolved))) {\n return { content: `Refused to outline sensitive file: ${args.path ?? \".\"}`, isError: true };\n }\n if (languageOf(root) === undefined) {\n return {\n content: `No supported source language for: ${args.path ?? \".\"} (supported: TS/JS, Python, Go, Rust, Java/Kotlin/C#, C/C++, Ruby, PHP, Shell, Swift, Scala)`,\n };\n }\n const result = await outlineFile(root);\n if (\"binary\" in result) {\n return { content: `Cannot outline binary file: ${args.path ?? \".\"}`, isError: true };\n }\n if (\"unreadable\" in result) {\n return {\n content: `Cannot outline ${args.path ?? \".\"}: unreadable or larger than 2MB`,\n isError: true,\n };\n }\n if (result.symbols.length === 0) {\n return { content: `(no recognizable declarations in ${args.path ?? \".\"})` };\n }\n return { content: formatSymbols(result.symbols, result.total).join(\"\\n\") };\n }\n\n const walked = await walkFiles(root, undefined, {\n ignore: createIgnorePredicate(ctx.cwd),\n withMtime: false,\n signal: ctx.abortSignal,\n symlinkBoundary: ctx.cwd,\n nestedIgnore: true,\n });\n const candidates = walked.files.filter(\n (f) =>\n languageOf(f.abs) !== undefined &&\n !isSensitivePath(f.abs) &&\n (f.resolved === undefined || !isSensitivePath(f.resolved)),\n );\n const maxFiles = args.maxFiles ?? MAX_DIR_FILES;\n\n const scan = async (\n file: WalkedFile,\n ): Promise<{ rel: string; lines: string[]; chars: number } | null> => {\n const result = await outlineFile(file.abs);\n if (\"symbols\" in result && result.symbols.length > 0) {\n const lines = formatSymbols(result.symbols, result.total);\n const chars = lines.reduce((n, l) => n + l.length + 1, file.rel.length + 2);\n return { rel: file.rel, lines, chars };\n }\n return null;\n };\n\n const out: string[] = [];\n let size = 0;\n let included = 0;\n let hitLimit = false;\n for (let i = 0; i < candidates.length && included < maxFiles; i += WALK_CONCURRENCY) {\n if (ctx.abortSignal?.aborted) break;\n const chunk = await Promise.all(\n candidates.slice(i, i + WALK_CONCURRENCY).map((file) => scan(file)),\n );\n for (const block of chunk) {\n if (!block) continue;\n if (size + block.chars > MAX_OUT_CHARS || included >= maxFiles) {\n hitLimit = true;\n break;\n }\n if (out.length > 0) out.push(\"\");\n out.push(`${block.rel}:`);\n out.push(...block.lines);\n size += block.chars;\n included += 1;\n }\n if (hitLimit) break;\n }\n if (included === 0) {\n return {\n content: `No recognizable declarations under ${args.path ?? \".\"} (${candidates.length} source file(s) scanned)`,\n };\n }\n if (hitLimit) {\n out.push(\"... (truncated: output limit reached, more files not outlined)\");\n } else if (walked.aborted || ctx.abortSignal?.aborted) {\n out.push(\"... (interrupted: partial results)\");\n }\n return { content: out.join(\"\\n\") };\n },\n};\n","import { open, realpath, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport { isSensitivePath } from \"./util\";\n\nconst DEFAULT_LIMIT = 2000;\nconst MAX_CHARS = 100 * 1024;\n// Output is capped at 100KB anyway, so reading past 1MB can never be shown.\nconst MAX_READ_BYTES = 1024 * 1024;\nconst BINARY_PROBE_BYTES = 8192;\n\nfunction decodeUtf16be(buf: Buffer): string {\n const len = buf.length - (buf.length % 2);\n const swapped = Buffer.allocUnsafe(len);\n for (let k = 0; k < len; k += 2) {\n swapped[k] = buf[k + 1] ?? 0;\n swapped[k + 1] = buf[k] ?? 0;\n }\n return swapped.toString(\"utf16le\");\n}\n\n// A UTF-16 BOM means the file is text (its NUL bytes are expected); without a\n// BOM, a NUL in the first 8KB marks a binary file.\nfunction decodeTextBuffer(buf: Buffer): { text: string } | { binary: true } {\n if (buf.length >= 2 && buf[0] === 0xff && buf[1] === 0xfe) {\n return { text: buf.subarray(2).toString(\"utf16le\") };\n }\n if (buf.length >= 2 && buf[0] === 0xfe && buf[1] === 0xff) {\n return { text: decodeUtf16be(buf.subarray(2)) };\n }\n if (buf.subarray(0, BINARY_PROBE_BYTES).includes(0)) {\n return { binary: true };\n }\n return { text: buf.toString(\"utf8\") };\n}\n\nconst schema = z.object({\n path: z.string().describe(\"File path, absolute or relative to the working directory\"),\n offset: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"1-based line number to start reading from\"),\n limit: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Maximum number of lines to read (default 2000)\"),\n});\n\n// Per-tool-instance cache of what was already sent to the model, so a re-read\n// of an unchanged file (same mtime + size) whose requested line range was\n// already returned answers with a one-line note instead of re-billing the\n// full content (aider's read-file dedup). Keyed by realpath when resolvable.\ninterface ReadCacheEntry {\n mtimeMs: number;\n size: number;\n totalLines: number;\n start: number;\n end: number;\n}\nconst READ_CACHE_MAX_ENTRIES = 200;\n\nexport function createReadFileTool(): Tool<typeof schema> {\n const cache = new Map<string, ReadCacheEntry>();\n return {\n name: \"read_file\",\n description:\n \"Read a text file and return its contents with line numbers. Output is truncated to 2000 lines or 100KB by default. Re-reading an unchanged file range returns a short note instead of the content.\",\n permission: \"read\",\n parameters: schema,\n reset: () => cache.clear(),\n async execute(args, ctx) {\n const filePath = path.resolve(ctx.cwd, args.path);\n // Check both the given path and its symlink target: a repo can plant a\n // harmless-looking link (notes.txt -> ~/.ssh/id_rsa) whose resolved name\n // is on the sensitive list. Unresolvable paths keep the raw-path check.\n const resolvedPath = await realpath(filePath).catch(() => null);\n if (isSensitivePath(filePath) || (resolvedPath !== null && isSensitivePath(resolvedPath))) {\n return { content: `Refused to read sensitive file: ${args.path}`, isError: true };\n }\n const st = await stat(filePath).catch(() => null);\n if (!st) {\n return { content: `File not found: ${args.path}`, isError: true };\n }\n if (st.isDirectory()) {\n return { content: `Path is a directory, not a file: ${args.path}`, isError: true };\n }\n const start = args.offset ?? 1;\n const limit = args.limit ?? DEFAULT_LIMIT;\n const cacheKey = resolvedPath ?? filePath;\n const hit = cache.get(cacheKey);\n if (hit && hit.mtimeMs === st.mtimeMs && hit.size === st.size) {\n const requestedEnd = Math.min(hit.totalLines, start - 1 + limit);\n if (start >= hit.start && requestedEnd <= hit.end && start <= hit.totalLines) {\n return {\n content: `[unchanged since last read: ${args.path} — lines ${start}-${requestedEnd} of ${hit.totalLines} are already in context and the file has not changed]`,\n };\n }\n }\n const bytesToRead = Math.min(st.size, MAX_READ_BYTES);\n const fileCapped = st.size > MAX_READ_BYTES;\n const handle = await open(filePath, \"r\").catch(() => null);\n if (!handle) {\n return { content: `Failed to read ${args.path}`, isError: true };\n }\n let buf: Buffer;\n try {\n const { bytesRead, buffer } = await handle.read(\n Buffer.alloc(bytesToRead),\n 0,\n bytesToRead,\n 0,\n );\n buf = buffer.subarray(0, bytesRead);\n } finally {\n await handle.close().catch(() => {});\n }\n const decoded = decodeTextBuffer(buf);\n if (\"binary\" in decoded) {\n return { content: `Cannot read binary file: ${args.path}`, isError: true };\n }\n const lines = decoded.text.split(\"\\n\");\n const totalDesc = fileCapped ? `at least ${lines.length}` : `${lines.length}`;\n if (start > lines.length) {\n return { content: `(offset ${start} beyond end of file; file has ${totalDesc} lines)` };\n }\n const end = Math.min(lines.length, start - 1 + limit);\n const out: string[] = [];\n let size = 0;\n let truncatedBySize = false;\n for (let i = start - 1; i < end; i++) {\n const line = (lines[i] ?? \"\").replace(/\\r$/, \"\");\n const numbered = `${i + 1}\\t${line}`;\n if (size + numbered.length > MAX_CHARS) {\n truncatedBySize = true;\n break;\n }\n out.push(numbered);\n size += numbered.length;\n }\n const lastShown = start - 1 + out.length;\n if (truncatedBySize) {\n out.push(\n `... (truncated: output exceeds 100KB, showing lines ${start}-${lastShown} of ${totalDesc})`,\n );\n } else if (end < lines.length || fileCapped) {\n out.push(`... (truncated: showing lines ${start}-${end} of ${totalDesc})`);\n }\n if (out.length > 0) {\n if (cache.size >= READ_CACHE_MAX_ENTRIES) cache.clear();\n const prev = hit?.mtimeMs === st.mtimeMs && hit.size === st.size ? hit : undefined;\n cache.set(cacheKey, {\n mtimeMs: st.mtimeMs,\n size: st.size,\n totalLines: lines.length,\n // Extend the remembered range when the new read overlaps or abuts\n // the previous one; disjoint ranges replace it.\n start: prev && start <= prev.end + 1 ? Math.min(prev.start, start) : start,\n end: prev && lastShown >= prev.start - 1 ? Math.max(prev.end, lastShown) : lastShown,\n });\n }\n return { content: out.join(\"\\n\") };\n },\n };\n}\n\n// Shared instance for direct consumers (tests); the tool registry creates a\n// fresh one per agent loop so a subagent's cache never claims content that\n// only the parent's context holds.\nexport const readFileTool = createReadFileTool();\n","import { readFile, realpath, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { probeImageDimensions } from \"../../core/image\";\nimport { downsampleImageIfNeeded } from \"../../core/image-resize\";\nimport type { ImageInput } from \"../../core/messages\";\nimport type { Tool } from \"../types\";\nimport { isSensitivePath } from \"./util\";\n\n// Same ceiling as @-mention image reads (src/cli/mentions.ts).\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\nconst IMAGE_MIME_TYPES: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n};\n\nconst schema = z.object({\n path: z\n .string()\n .describe(\n \"Image file path (png/jpg/jpeg/gif/webp), absolute or relative to the working directory\",\n ),\n});\n\n// Lets the model pull an image into the conversation mid-session (a screenshot\n// the user mentioned, a generated asset, a UI mock). The image itself is not\n// in the text result — the loop attaches it to the history as a user message\n// with image parts (see ToolResult.images), so every protocol sees it the same\n// way as a pasted image.\nexport const readImageTool: Tool<typeof schema> = {\n name: \"read_image\",\n description:\n \"Read an image file (png, jpg, gif, webp) and show it to the model. Use this whenever the user references a screenshot, diagram, or picture file you need to see. Images larger than 2000px are downsampled automatically.\",\n permission: \"read\",\n parameters: schema,\n async execute(args, ctx) {\n if (ctx.visionEnabled === false) {\n return {\n content:\n \"The active model does not support image input (vision = false), so the image was not read. Work from text instead, or ask the user to describe the image.\",\n isError: true,\n };\n }\n const filePath = path.resolve(ctx.cwd, args.path);\n // Same symlink-aware sensitive check as read_file.\n const resolvedPath = await realpath(filePath).catch(() => null);\n if (isSensitivePath(filePath) || (resolvedPath !== null && isSensitivePath(resolvedPath))) {\n return { content: `Refused to read sensitive file: ${args.path}`, isError: true };\n }\n const mimeType = IMAGE_MIME_TYPES[path.extname(filePath).toLowerCase()];\n if (!mimeType) {\n return {\n content: `Not a supported image (png/jpg/jpeg/gif/webp): ${args.path}`,\n isError: true,\n };\n }\n const st = await stat(filePath).catch(() => null);\n if (!st || !st.isFile()) {\n return { content: `File not found: ${args.path}`, isError: true };\n }\n if (st.size > MAX_IMAGE_BYTES) {\n return {\n content: `Image too large (${Math.round(st.size / 1024)}KB > ${MAX_IMAGE_BYTES / 1024}KB): ${args.path}`,\n isError: true,\n };\n }\n const buf = await readFile(filePath).catch(() => null);\n if (!buf || buf.length === 0) {\n return { content: `Failed to read ${args.path}`, isError: true };\n }\n if (!probeImageDimensions(buf)) {\n return {\n content: `File is not a valid image (unrecognized header): ${args.path}`,\n isError: true,\n };\n }\n const downsampled = await downsampleImageIfNeeded({\n path: args.path,\n mimeType,\n data: buf.toString(\"base64\"),\n });\n if (downsampled.oversized && !downsampled.resized) {\n return {\n content: `Image exceeds 2000px and could not be downsampled on this platform: ${args.path}`,\n isError: true,\n };\n }\n const image: ImageInput = downsampled.image;\n const dims = probeImageDimensions(Buffer.from(image.data, \"base64\"));\n const sizeKB = Math.round(image.data.length / 1024);\n const desc = dims ? `${dims.width}x${dims.height}` : \"unknown dimensions\";\n const resizedNote = downsampled.resized ? \" (downsampled to fit 2000px)\" : \"\";\n return {\n content: `Image loaded: ${args.path} (${desc}, ~${sizeKB}KB)${resizedNote}. The image is attached below — look at it now.`,\n images: [image],\n };\n },\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport type { Tool } from \"../types\";\nimport { MAX_SNAPSHOT_CONTENT_BYTES, captureSnapshot, pushSnapshot } from \"./snapshots\";\n\nconst schema = z.object({\n path: z.string().describe(\"File path, absolute or relative to the working directory\"),\n content: z.string().describe(\"Full content to write to the file\"),\n});\n\nexport const writeFileTool: Tool<typeof schema> = {\n name: \"write_file\",\n description:\n \"Write content to a file, creating parent directories as needed. Overwrites existing files. Refuses content with NUL bytes (binary) or over 5MB.\",\n permission: \"write\",\n parameters: schema,\n async execute(args, ctx) {\n const filePath = path.resolve(ctx.cwd, args.path);\n // write_file writes UTF-8 text: NUL bytes mean the model is pushing\n // binary content that would land corrupted, and past the snapshot cap\n // /undo keeps only metadata, so the overwritten file would be\n // unrecoverable — same limits as edit_file.\n if (args.content.includes(\"\\0\")) {\n return {\n content: `Refused to write ${args.path}: content contains NUL bytes (write_file is text-only)`,\n isError: true,\n };\n }\n const bytes = Buffer.byteLength(args.content, \"utf8\");\n if (bytes > MAX_SNAPSHOT_CONTENT_BYTES) {\n return {\n content: `Refused to write ${args.path}: content is ${bytes} bytes, over the 5MB limit (writes past it could not be restored by /undo)`,\n isError: true,\n };\n }\n const snapshot = await captureSnapshot(filePath, \"write_file\", ctx.snapshotContext);\n try {\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, args.content, \"utf8\");\n } catch (err) {\n return { content: `Failed to write ${args.path}: ${(err as Error).message}`, isError: true };\n }\n await pushSnapshot(snapshot);\n return { content: `Wrote ${bytes} bytes to ${args.path}` };\n },\n};\n","import { z } from \"zod\";\nimport { probeImageDimensions } from \"../core/image\";\nimport { type ScreenshotResult, captureScreenshot } from \"../core/screenshot\";\nimport type { Tool } from \"./types\";\n\nconst schema = z.object({});\n\n// Lets the model look at the actual screen mid-session — the visual debugging\n// counterpart of read_image: start a dev server or GUI program, screenshot,\n// then judge the real rendered output instead of guessing from code. The\n// capture function is injectable so tests never touch a real display.\nexport function createScreenshotTool(\n capture: () => Promise<ScreenshotResult> = captureScreenshot,\n): Tool<typeof schema> {\n return {\n name: \"screenshot\",\n description:\n \"Capture a screenshot of the primary display and see it. Use this to check the actual visual result of a running program (web page, GUI) — e.g. after starting a dev server — instead of inferring from code. The capture shows exactly what is visible on screen, including overlapping windows: content hidden behind other windows cannot be seen, so if a specific window matters ask the user to bring it to the front first. Note the capture may include anything else currently on screen.\",\n permission: \"read\",\n parameters: schema,\n async execute(_args, ctx) {\n if (ctx.visionEnabled === false) {\n return {\n content:\n \"The active model does not support image input (vision = false), so no screenshot was taken. Work from text instead, or ask the user to describe what is on screen.\",\n isError: true,\n };\n }\n const result = await capture();\n if (!result.ok) {\n return { content: `Screenshot failed: ${result.error}`, isError: true };\n }\n const image = result.image;\n const dims = probeImageDimensions(Buffer.from(image.data, \"base64\"));\n const sizeKB = Math.round(image.data.length / 1024);\n const desc = dims ? `${dims.width}x${dims.height}` : \"unknown dimensions\";\n return {\n content: `Screenshot captured (${desc}, ~${sizeKB}KB). The image is attached below — look at it now.`,\n images: [image],\n };\n },\n };\n}\n\nexport const screenshotTool = createScreenshotTool();\n","import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { probeImageDimensions } from \"./image\";\nimport { downsampleImageIfNeeded } from \"./image-resize\";\nimport type { ImageInput } from \"./messages\";\n\nexport const SCREENSHOT_TIMEOUT_MS = 20_000;\n\nconst execFileAsync = promisify(execFile);\n\nexport interface ScreenshotCommand {\n command: string;\n args: string[];\n}\n\nexport type ScreenshotResult = { ok: true; image: ImageInput } | { ok: false; error: string };\n\n// Windows capture script: copies the primary screen into a PNG. The position\n// problem on Windows is DPI virtualization — when the process is not truly\n// per-monitor DPI aware, the Bounds Forms reports and the pixels CopyFromScreen\n// reads live in different coordinate spaces, so at 125%/150% scaling the\n// capture comes out offset and wrongly sized. Setting per-monitor-V2 awareness\n// before touching Forms/Drawing makes both sides physical pixels; the call\n// fails harmlessly when the host manifest already pinned awareness (system\n// awareness is still physically correct on the primary display).\nexport function windowsScreenshotScript(outputFile: string): string {\n const output = outputFile.replace(/'/g, \"''\");\n return [\n \"try { Add-Type -MemberDefinition '[DllImport(\\\"user32.dll\\\")] public static extern bool SetProcessDpiAwarenessContext(int v);' -Name Dpi -Namespace StarShot -ErrorAction Stop; [void][StarShot.Dpi]::SetProcessDpiAwarenessContext(-4) } catch { }\",\n \"Add-Type -AssemblyName System.Windows.Forms,System.Drawing\",\n \"$b = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds\",\n \"$bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height)\",\n \"$g = [System.Drawing.Graphics]::FromImage($bmp)\",\n \"$g.CopyFromScreen($b.Left, $b.Top, 0, 0, $bmp.Size)\",\n `$bmp.Save('${output}', [System.Drawing.Imaging.ImageFormat]::Png)`,\n \"$g.Dispose(); $bmp.Dispose()\",\n ].join(\"; \");\n}\n\n// Platform-native capture command writing a PNG to outputFile, or null when\n// this platform/session cannot take screenshots. Windows/macOS capture the\n// primary display only — one deterministic file and physically exact bounds,\n// even on mixed-DPI multi-monitor setups; Linux tools capture the whole\n// compositor/root window (all monitors composited).\nexport function screenshotPlan(\n platform: NodeJS.Platform,\n outputFile: string,\n env: NodeJS.ProcessEnv = process.env,\n tools: Record<string, boolean> = {},\n): ScreenshotCommand | null {\n if (platform === \"win32\") {\n return {\n command: \"powershell.exe\",\n args: [\"-NoProfile\", \"-NonInteractive\", \"-Command\", windowsScreenshotScript(outputFile)],\n };\n }\n if (platform === \"darwin\") {\n // -x silences the shutter sound; -D 1 pins the main display so a single\n // output file is deterministic no matter how many monitors are attached.\n return { command: \"screencapture\", args: [\"-x\", \"-D\", \"1\", outputFile] };\n }\n if (platform === \"linux\") {\n if (env.WAYLAND_DISPLAY) {\n if (tools.grim) return { command: \"grim\", args: [outputFile] };\n if (tools[\"gnome-screenshot\"]) {\n return { command: \"gnome-screenshot\", args: [\"-f\", outputFile] };\n }\n if (tools.spectacle) {\n return { command: \"spectacle\", args: [\"-b\", \"-n\", \"-o\", outputFile] };\n }\n return null;\n }\n if (env.DISPLAY) {\n if (tools.import) return { command: \"import\", args: [\"-window\", \"root\", outputFile] };\n if (tools.scrot) return { command: \"scrot\", args: [\"--overwrite\", outputFile] };\n if (tools[\"gnome-screenshot\"]) {\n return { command: \"gnome-screenshot\", args: [\"-f\", outputFile] };\n }\n if (tools.spectacle) {\n return { command: \"spectacle\", args: [\"-b\", \"-n\", \"-o\", outputFile] };\n }\n return null;\n }\n return null;\n }\n return null;\n}\n\nexport function noScreenshotToolMessage(\n platform: NodeJS.Platform,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n if (platform === \"linux\") {\n if (!env.WAYLAND_DISPLAY && !env.DISPLAY) {\n return \"no display server (neither DISPLAY nor WAYLAND_DISPLAY is set) — this session is headless (e.g. SSH), there is no screen to capture\";\n }\n return \"no screenshot tool found — install one of: grim or spectacle (Wayland), scrot or ImageMagick's import (X11), or gnome-screenshot\";\n }\n return `screenshots are not supported on this platform (${platform})`;\n}\n\nasync function commandExists(command: string): Promise<boolean> {\n const checker = process.platform === \"win32\" ? \"where\" : \"which\";\n try {\n await execFileAsync(checker, [command], { timeout: SCREENSHOT_TIMEOUT_MS });\n return true;\n } catch {\n return false;\n }\n}\n\nconst LINUX_TOOL_NAMES = [\"grim\", \"gnome-screenshot\", \"spectacle\", \"import\", \"scrot\"];\n\n// Captures the screen into a temp PNG via platform-native tools (no npm image\n// dependency), downsamples past 2000px like read_image, and returns the image\n// for the loop to attach to the history. Failures come back as messages the\n// model can act on instead of exceptions.\nexport async function captureScreenshot(): Promise<ScreenshotResult> {\n const outputFile = path.join(os.tmpdir(), `star-screenshot-${randomUUID()}.png`);\n try {\n const tools: Record<string, boolean> = {};\n if (process.platform === \"linux\") {\n const found = await Promise.all(LINUX_TOOL_NAMES.map(commandExists));\n for (const [i, name] of LINUX_TOOL_NAMES.entries()) {\n tools[name] = found[i] ?? false;\n }\n }\n const plan = screenshotPlan(process.platform, outputFile, process.env, tools);\n if (!plan) {\n return { ok: false, error: noScreenshotToolMessage(process.platform) };\n }\n try {\n await execFileAsync(plan.command, plan.args, { timeout: SCREENSHOT_TIMEOUT_MS });\n } catch (err) {\n const detail = err instanceof Error && err.message ? ` (${err.message})` : \"\";\n return { ok: false, error: `${plan.command} failed to capture the screen${detail}` };\n }\n const buf = await readFile(outputFile).catch(() => null);\n if (!buf || buf.length === 0) {\n return { ok: false, error: `${plan.command} produced no image file` };\n }\n if (!probeImageDimensions(buf)) {\n return { ok: false, error: `${plan.command} produced an unrecognized image file` };\n }\n const downsampled = await downsampleImageIfNeeded({\n path: \"screen\",\n mimeType: \"image/png\",\n data: buf.toString(\"base64\"),\n });\n if (downsampled.oversized && !downsampled.resized) {\n return {\n ok: false,\n error: \"screenshot exceeds 2000px and could not be downsampled on this platform\",\n };\n }\n return { ok: true, image: downsampled.image };\n } finally {\n await unlink(outputFile).catch(() => {});\n }\n}\n","import { z } from \"zod\";\nimport { type AgentTaskSnapshot, defaultAgentTasks } from \"../agent/agent-tasks\";\nimport { formatDuration, formatTaskLine, formatTaskList } from \"../tasks/format\";\nimport { type TaskSnapshot, defaultTaskManager } from \"../tasks/manager\";\nimport { MAX_OUTPUT } from \"./bash\";\nimport type { Tool, ToolContext } from \"./types\";\n\nconst idSchema = z.object({\n id: z.string().describe(\"Task id, e.g. task-1 or agent-1\"),\n});\n\n// Aligns with the foreground bash output cap: keep the tail, note the cut.\nfunction truncateOutput(s: string): string {\n if (s.length <= MAX_OUTPUT) return s;\n return `[... earlier output truncated; showing the last ${MAX_OUTPUT} characters ...]\\n${s.slice(-MAX_OUTPUT)}`;\n}\n\n// Shell tasks are owned by the agent that started them: root sees and\n// controls everything, a subagent only its own tasks — otherwise one\n// subagent could kill the parent's (or a sibling's) background work.\n// Unowned/foreign tasks answer \"Unknown task\" so their existence doesn't\n// leak either. Background subagents (agent-*) always belong to root:\n// subagents can't spawn subagents.\nfunction callerId(ctx: ToolContext): string {\n return ctx.agentId ?? \"root\";\n}\n\nfunction accessibleShellTask(ctx: ToolContext, id: string): TaskSnapshot | undefined {\n const task = defaultTaskManager.get(id);\n if (!task) return undefined;\n const caller = callerId(ctx);\n return caller === \"root\" || task.ownerId === caller ? task : undefined;\n}\n\nfunction formatAgentTaskLine(task: AgentTaskSnapshot): string {\n const duration = formatDuration(task.startedAt, task.endedAt);\n const label = task.description ?? task.prompt.slice(0, 60);\n const status =\n task.status === \"running\" ? `running ${duration}` : `${task.status} after ${duration}`;\n return `${task.id} [${status}] ${label}`;\n}\n\nexport const taskListTool: Tool = {\n name: \"task_list\",\n description: \"List background tasks (shell commands and subagents) with status and runtime.\",\n permission: \"read\",\n parameters: z.object({}),\n execute(_args, ctx) {\n const caller = callerId(ctx);\n const shell = formatTaskList(\n defaultTaskManager.list().filter((t) => caller === \"root\" || t.ownerId === caller),\n );\n const agents = caller === \"root\" ? defaultAgentTasks.list() : [];\n const agentLines =\n agents.length === 0\n ? \"No background subagents.\"\n : `Background subagents:\\n${agents.map(formatAgentTaskLine).join(\"\\n\")}`;\n return Promise.resolve({ content: `${shell}\\n${agentLines}` });\n },\n};\n\nexport const taskOutputTool: Tool<typeof idSchema> = {\n name: \"task_output\",\n description:\n \"Read the current output of a background task (shell command or subagent; works while still running).\",\n permission: \"read\",\n parameters: idSchema,\n execute(args, ctx) {\n const shell = accessibleShellTask(ctx, args.id);\n if (shell) {\n const body = truncateOutput(shell.output.replace(/\\s+$/, \"\") || \"(no output yet)\");\n return Promise.resolve({ content: `${formatTaskLine(shell)}\\n${body}` });\n }\n const agent = callerId(ctx) === \"root\" ? defaultAgentTasks.get(args.id) : undefined;\n if (agent) {\n const body =\n agent.status === \"running\"\n ? \"(still running)\"\n : truncateOutput(agent.result.replace(/\\s+$/, \"\") || \"(no report)\");\n return Promise.resolve({ content: `${formatAgentTaskLine(agent)}\\n${body}` });\n }\n return Promise.resolve({ content: `Unknown task: ${args.id}`, isError: true });\n },\n};\n\nexport const taskKillTool: Tool<typeof idSchema> = {\n name: \"task_kill\",\n description: \"Stop a running background task (shell command process tree or subagent).\",\n permission: \"exec\",\n parameters: idSchema,\n execute(args, ctx) {\n const shell = accessibleShellTask(ctx, args.id);\n const agent = shell || callerId(ctx) !== \"root\" ? undefined : defaultAgentTasks.get(args.id);\n const task = shell ?? agent;\n if (!task) {\n return Promise.resolve({ content: `Unknown task: ${args.id}`, isError: true });\n }\n if (task.status !== \"running\") {\n return Promise.resolve({\n content: `Task ${args.id} is not running (status: ${task.status}).`,\n isError: true,\n });\n }\n if (shell) {\n defaultTaskManager.kill(args.id);\n } else {\n defaultAgentTasks.kill(args.id);\n }\n return Promise.resolve({ content: `Task ${args.id} stopped.` });\n },\n};\n","import type { TaskSnapshot } from \"./manager\";\n\nexport function formatDuration(startedAt: number, endedAt?: number): string {\n const seconds = Math.max(0, Math.round(((endedAt ?? Date.now()) - startedAt) / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m${seconds % 60}s`;\n return `${Math.floor(minutes / 60)}h${minutes % 60}m`;\n}\n\nfunction formatStatus(task: TaskSnapshot): string {\n const duration = formatDuration(task.startedAt, task.endedAt);\n if (task.status === \"running\") return `running ${duration}`;\n const exit =\n task.exitCode === null || task.exitCode === undefined ? \"\" : `, exit ${task.exitCode}`;\n return `${task.status}${exit} after ${duration}`;\n}\n\nexport function formatTaskLine(task: TaskSnapshot): string {\n const label = task.description ? `${task.description} (${task.command})` : task.command;\n return `${task.id} [${formatStatus(task)}] ${label}`;\n}\n\nexport function formatTaskList(tasks: TaskSnapshot[]): string {\n if (tasks.length === 0) return \"No background tasks.\";\n return `Background tasks:\\n${tasks.map(formatTaskLine).join(\"\\n\")}`;\n}\n\nexport function formatTaskStarted(task: TaskSnapshot): string {\n const label = task.description ? `${task.description} (${task.command})` : task.command;\n return `Background task ${task.id} started: ${label}`;\n}\n\nexport function formatTaskFinished(task: TaskSnapshot): string {\n const exit =\n task.exitCode === null || task.exitCode === undefined ? \"\" : ` (exit ${task.exitCode})`;\n switch (task.status) {\n case \"completed\":\n return `Background task ${task.id} finished${exit}: ${task.command}`;\n case \"failed\":\n return `Background task ${task.id} failed${exit}: ${task.command}`;\n case \"timed_out\":\n return `Background task ${task.id} timed out: ${task.command}`;\n case \"stopped\":\n return `Background task ${task.id} stopped: ${task.command}`;\n default:\n return `Background task ${task.id}: ${task.command}`;\n }\n}\n","import { z } from \"zod\";\nimport { debugStreamLog } from \"../../llm/debug\";\nimport type { Tool } from \"../types\";\nimport { decodeEntities } from \"./fetch\";\n\nconst TIMEOUT_MS = 15000;\nconst DEFAULT_MAX_RESULTS = 5;\nconst MAX_RESULTS_LIMIT = 10;\nconst USER_AGENT =\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36\";\n\nconst schema = z.object({\n query: z.string().min(1).describe(\"The search query\"),\n maxResults: z\n .number()\n .int()\n .min(1)\n .max(MAX_RESULTS_LIMIT)\n .optional()\n .describe(\n `Maximum number of results to return (default ${DEFAULT_MAX_RESULTS}, max ${MAX_RESULTS_LIMIT})`,\n ),\n});\n\nexport interface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\n// A search backend: builds the request URL for a query and parses its HTML\n// into the unified {title, url, snippet} shape. Sources are tried in order;\n// a network error, non-2xx status or zero parsed results falls through to\n// the next one.\ninterface SearchSource {\n name: string;\n buildUrl: (query: string) => string;\n parse: (html: string) => SearchResult[];\n}\n\nfunction stripTags(s: string): string {\n return decodeEntities(s.replace(/<[^>]+>/g, \" \"))\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction normalizeUrl(href: string): string {\n const decoded = decodeEntities(href);\n const uddg = decoded.match(/[?&]uddg=([^&]+)/);\n if (uddg?.[1]) {\n try {\n return decodeURIComponent(uddg[1]);\n } catch {\n return decoded;\n }\n }\n if (decoded.startsWith(\"//\")) {\n return `https:${decoded}`;\n }\n return decoded;\n}\n\nfunction hrefOf(tag: string): string | undefined {\n const match = tag.match(/href\\s*=\\s*\"([^\"]*)\"/i) ?? tag.match(/href\\s*=\\s*'([^']*)'/i);\n return match?.[1];\n}\n\nexport function parseResults(html: string): SearchResult[] {\n const results: SearchResult[] = [];\n const anchorRe = /<a\\b[^>]*\\bclass\\s*=\\s*\"[^\"]*\\bresult__a\\b[^\"]*\"[^>]*>[\\s\\S]*?<\\/a>/gi;\n const anchors = [...html.matchAll(anchorRe)];\n for (const [i, anchor] of anchors.entries()) {\n const full = anchor[0];\n const href = hrefOf(full);\n if (!href) {\n continue;\n }\n const url = normalizeUrl(href);\n const title = stripTags(full.replace(/^<a\\b[^>]*>/i, \"\").replace(/<\\/a>\\s*$/i, \"\"));\n const blockStart = (anchor.index ?? 0) + full.length;\n const blockEnd = i + 1 < anchors.length ? (anchors[i + 1]?.index ?? html.length) : html.length;\n const block = html.slice(blockStart, blockEnd);\n const snippetMatch = block.match(\n /<(?:a|div)\\b[^>]*\\bclass\\s*=\\s*\"[^\"]*\\bresult__snippet\\b[^\"]*\"[^>]*>([\\s\\S]*?)<\\/(?:a|div)>/i,\n );\n const snippet = snippetMatch?.[1] ? stripTags(snippetMatch[1]) : \"\";\n if (title && url) {\n results.push({ title, url, snippet });\n }\n }\n return results;\n}\n\n// lite.duckduckgo.com serves a different (table-based) layout: titles in\n// <a class=\"result-link\">, snippets in the following <td class=\"result-snippet\">.\nexport function parseDdgLiteResults(html: string): SearchResult[] {\n const results: SearchResult[] = [];\n const anchorRe =\n /<a\\b[^>]*\\bclass\\s*=\\s*[\"'][^\"']*\\bresult-link\\b[^\"']*[\"'][^>]*>[\\s\\S]*?<\\/a>/gi;\n const anchors = [...html.matchAll(anchorRe)];\n for (const [i, anchor] of anchors.entries()) {\n const full = anchor[0];\n const href = hrefOf(full);\n if (!href) {\n continue;\n }\n const url = normalizeUrl(href);\n const title = stripTags(full.replace(/^<a\\b[^>]*>/i, \"\").replace(/<\\/a>\\s*$/i, \"\"));\n const blockStart = (anchor.index ?? 0) + full.length;\n const blockEnd = i + 1 < anchors.length ? (anchors[i + 1]?.index ?? html.length) : html.length;\n const block = html.slice(blockStart, blockEnd);\n const snippetMatch = block.match(\n /<td\\b[^>]*\\bclass\\s*=\\s*[\"'][^\"']*\\bresult-snippet\\b[^\"']*[\"'][^>]*>([\\s\\S]*?)<\\/td>/i,\n );\n const snippet = snippetMatch?.[1] ? stripTags(snippetMatch[1]) : \"\";\n if (title && url) {\n results.push({ title, url, snippet });\n }\n }\n return results;\n}\n\n// www.bing.com/search needs no key: results are <li class=\"b_algo\"> blocks\n// with the title link in <h2><a> and the snippet in the block's first <p>.\nexport function parseBingResults(html: string): SearchResult[] {\n const results: SearchResult[] = [];\n const blockRe = /<li\\b[^>]*\\bclass\\s*=\\s*\"[^\"]*\\bb_algo\\b[^\"]*\"[^>]*>/gi;\n const blocks = [...html.matchAll(blockRe)];\n for (const [i, block] of blocks.entries()) {\n const start = block.index ?? 0;\n const end = i + 1 < blocks.length ? (blocks[i + 1]?.index ?? html.length) : html.length;\n const slice = html.slice(start, end);\n const headMatch = slice.match(\n /<h2\\b[^>]*>[\\s\\S]*?<a\\b[^>]*?\\shref\\s*=\\s*\"([^\"]*)\"[^>]*>([\\s\\S]*?)<\\/a>[\\s\\S]*?<\\/h2>/i,\n );\n if (!headMatch) {\n continue;\n }\n const url = decodeEntities(headMatch[1] ?? \"\").trim();\n const title = stripTags(headMatch[2] ?? \"\");\n const snippetMatch = slice.match(/<p\\b[^>]*>([\\s\\S]*?)<\\/p>/i);\n const snippet = snippetMatch?.[1] ? stripTags(snippetMatch[1]) : \"\";\n if (title && /^https?:\\/\\//.test(url)) {\n results.push({ title, url, snippet });\n }\n }\n return results;\n}\n\nconst SEARCH_SOURCES: SearchSource[] = [\n {\n name: \"duckduckgo-html\",\n buildUrl: (query) => `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`,\n parse: parseResults,\n },\n {\n name: \"duckduckgo-lite\",\n buildUrl: (query) => `https://lite.duckduckgo.com/lite/?q=${encodeURIComponent(query)}`,\n parse: parseDdgLiteResults,\n },\n {\n name: \"bing\",\n buildUrl: (query) => `https://www.bing.com/search?q=${encodeURIComponent(query)}`,\n parse: parseBingResults,\n },\n];\n\nexport const webSearchTool: Tool<typeof schema> = {\n name: \"web_search\",\n description:\n \"Search the web and return a numbered list of results with title, URL and snippet. Uses DuckDuckGo with automatic fallback to DuckDuckGo Lite and Bing when a source fails or returns nothing. No API key required. Use web_fetch to read a result's full page.\",\n permission: \"read\",\n parameters: schema,\n async execute(args, ctx) {\n const maxResults = Math.min(args.maxResults ?? DEFAULT_MAX_RESULTS, MAX_RESULTS_LIMIT);\n const failures: string[] = [];\n for (const source of SEARCH_SOURCES) {\n const timeoutSignal = AbortSignal.timeout(TIMEOUT_MS);\n const signal = ctx.abortSignal\n ? AbortSignal.any([timeoutSignal, ctx.abortSignal])\n : timeoutSignal;\n let res: Response;\n try {\n res = await fetch(source.buildUrl(args.query), {\n signal,\n redirect: \"follow\",\n headers: { \"user-agent\": USER_AGENT, accept: \"text/html\" },\n });\n } catch (err) {\n if (ctx.abortSignal?.aborted) {\n return { content: \"ERROR: request aborted\", isError: true };\n }\n const name = err instanceof Error ? err.name : \"\";\n if (timeoutSignal.aborted || name === \"TimeoutError\") {\n failures.push(`${source.name}: search timed out after ${TIMEOUT_MS / 1000}s`);\n } else {\n const message = err instanceof Error ? err.message : String(err);\n failures.push(`${source.name}: search request failed: ${message}`);\n }\n continue;\n }\n if (!res.ok) {\n await res.body?.cancel().catch(() => {});\n failures.push(`${source.name}: HTTP ${res.status} ${res.statusText}`);\n continue;\n }\n let html: string;\n try {\n html = await res.text();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n failures.push(`${source.name}: failed to read search response: ${message}`);\n continue;\n }\n const results = source.parse(html).slice(0, maxResults);\n if (results.length === 0) {\n failures.push(\n `${source.name}: no results found (the response may have been blocked or the page layout changed)`,\n );\n continue;\n }\n debugStreamLog(\"web_search\", {\n source: source.name,\n query: args.query,\n results: results.length,\n failures,\n });\n const lines = results.map(\n (r, i) => `${i + 1}. ${r.title}\\n ${r.url}${r.snippet ? `\\n ${r.snippet}` : \"\"}`,\n );\n return { content: lines.join(\"\\n\") };\n }\n debugStreamLog(\"web_search_failed\", { query: args.query, failures });\n return {\n content: `ERROR: web search failed for \"${args.query}\" — ${failures.join(\"; \")}`,\n isError: true,\n };\n },\n};\n","import { appendFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { starHome } from \"../config/paths\";\n\n// STAR_DEBUG-gated JSONL log of stream internals (~/.star-cli/debug.log):\n// what the provider actually sent — finish reasons, usage, error details —\n// so a misbehaving relay can be diagnosed from the client side. All write\n// failures are silent; logging must never break a turn.\nexport function debugStreamLog(event: string, data?: Record<string, unknown>): void {\n if (!process.env.STAR_DEBUG) return;\n try {\n const line = `${JSON.stringify({ ts: new Date().toISOString(), event, ...data })}\\n`;\n appendFileSync(path.join(starHome(), \"debug.log\"), line);\n } catch {\n // best-effort only\n }\n}\n","import { bashTool } from \"./bash\";\nimport { editFileTool } from \"./fs/edit\";\nimport { globTool } from \"./fs/glob\";\nimport { grepTool } from \"./fs/grep\";\nimport { codeOutlineTool } from \"./fs/outline\";\nimport { createReadFileTool } from \"./fs/read\";\nimport { readImageTool } from \"./fs/read-image\";\nimport { writeFileTool } from \"./fs/write\";\nimport { screenshotTool } from \"./screenshot\";\nimport { taskKillTool, taskListTool, taskOutputTool } from \"./tasks\";\nimport { type TodoStore, createTodoTools } from \"./todo\";\nimport type { Tool } from \"./types\";\nimport { webFetchTool } from \"./web/fetch\";\nimport { webSearchTool } from \"./web/search\";\n\nexport class ToolRegistry {\n private tools = new Map<string, Tool>();\n\n // todoStore defaults to the module-level shared store; subagent loops pass\n // their own instance so a child's todo_write cannot clobber the parent list.\n constructor(todoStore?: TodoStore) {\n for (const tool of [\n // Fresh per registry (i.e. per agent loop): the unchanged-since-last-\n // read cache must not leak across loops, whose contexts differ.\n createReadFileTool(),\n readImageTool,\n screenshotTool,\n writeFileTool,\n editFileTool,\n globTool,\n grepTool,\n codeOutlineTool,\n bashTool,\n webFetchTool,\n webSearchTool,\n taskListTool,\n taskOutputTool,\n taskKillTool,\n ...createTodoTools(todoStore),\n ]) {\n this.register(tool);\n }\n }\n\n register(tool: Tool): void {\n this.tools.set(tool.name, tool);\n }\n\n // Drops every tool the predicate rejects. Used to restrict a read-only\n // subagent loop's tool set; the agent loop reads list() lazily per\n // request, so a retain right after loop construction still shapes the\n // first request. The permission gate stays as backstop for anything\n // attempted outside the model's tool map.\n retain(predicate: (tool: Tool) => boolean): void {\n for (const [name, tool] of this.tools) {\n if (!predicate(tool)) this.tools.delete(name);\n }\n }\n\n // Drops per-session volatile tool state after a wholesale history rewrite\n // (compaction, /undo, resume): anything a tool remembers as \"already sent\n // to the model\" may no longer be in the context.\n resetVolatileState(): void {\n for (const tool of this.tools.values()) tool.reset?.();\n }\n\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n list(): Tool[] {\n return [...this.tools.values()];\n }\n\n names(): string[] {\n return [...this.tools.keys()];\n }\n}\n","import { ToolRegistry } from \"./registry\";\nimport type { TodoStore } from \"./todo\";\n\nexport { ToolRegistry } from \"./registry\";\nexport { TodoStore, createTodoTools, setTodoPersistGuard } from \"./todo\";\nexport type { TodoItem } from \"./todo\";\nexport type { PermissionLevel, Tool, ToolContext, ToolResult } from \"./types\";\n\n// The registry constructor registers every built-in tool (todo tools\n// included); this helper only forwards the optional per-loop todo store.\nexport function createDefaultRegistry(todoStore?: TodoStore): ToolRegistry {\n return new ToolRegistry(todoStore);\n}\n"],"mappings":"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","names":["path","z","schema","z","path","readFile","stat","path","z","schema","z","path","stat","readFile","readFile","realpath","stat","path","z","MAX_FILE_BYTES","MAX_LINE_CHARS","path","stat","readFile","schema","z","realpath","realpath","stat","path","z","BINARY_PROBE_BYTES","schema","z","path","realpath","stat","readFile","realpath","stat","path","z","schema","z","path","realpath","stat","readFile","writeFile","path","z","schema","z","path","writeFile","z","readFile","path","path","readFile","schema","z","z","z","z","path","path","schema","z"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
AgentLoop,
|
|
4
|
+
PLAN_MODE_PROMPT,
|
|
5
|
+
attachTurnContext
|
|
6
|
+
} from "./chunk-MNVCCOI2.js";
|
|
7
|
+
import "./chunk-IJGUW4PM.js";
|
|
8
|
+
import "./chunk-MVAMPVTA.js";
|
|
9
|
+
import "./chunk-4IRY44TG.js";
|
|
10
|
+
import "./chunk-URC7JXKX.js";
|
|
11
|
+
import "./chunk-A5PXPWHB.js";
|
|
12
|
+
export {
|
|
13
|
+
AgentLoop,
|
|
14
|
+
PLAN_MODE_PROMPT,
|
|
15
|
+
attachTurnContext
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=loop-TW2FHL7J.js.map
|