summaryrefslogtreecommitdiffhomepage
path: root/js/src/tool/view.ts
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-05-30 20:47:56 -0400
committerDax Raad <[email protected]>2025-05-30 20:48:36 -0400
commitf3da73553c45f17e04b1e77cb13eb0fca714d1bd (patch)
treea24317a19e1ab2a89da50db669dc6894f15d00d1 /js/src/tool/view.ts
parent9a26b3058ffc1023e5c7e54b6d571c903d15888e (diff)
downloadopencode-f3da73553c45f17e04b1e77cb13eb0fca714d1bd.tar.gz
opencode-f3da73553c45f17e04b1e77cb13eb0fca714d1bd.zip
sync
Diffstat (limited to 'js/src/tool/view.ts')
-rw-r--r--js/src/tool/view.ts152
1 files changed, 0 insertions, 152 deletions
diff --git a/js/src/tool/view.ts b/js/src/tool/view.ts
deleted file mode 100644
index ee11881d3..000000000
--- a/js/src/tool/view.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import { z } from "zod";
-import * as fs from "fs";
-import * as path from "path";
-import { Tool } from "./tool";
-import { LSP } from "../lsp";
-import { FileTimes } from "./util/file-times";
-
-const MAX_READ_SIZE = 250 * 1024;
-const DEFAULT_READ_LIMIT = 2000;
-const MAX_LINE_LENGTH = 2000;
-
-const DESCRIPTION = `File viewing tool that reads and displays the contents of files with line numbers, allowing you to examine code, logs, or text data.
-
-WHEN TO USE THIS TOOL:
-- Use when you need to read the contents of a specific file
-- Helpful for examining source code, configuration files, or log files
-- Perfect for looking at text-based file formats
-
-HOW TO USE:
-- Provide the path to the file you want to view
-- Optionally specify an offset to start reading from a specific line
-- Optionally specify a limit to control how many lines are read
-
-FEATURES:
-- Displays file contents with line numbers for easy reference
-- Can read from any position in a file using the offset parameter
-- Handles large files by limiting the number of lines read
-- Automatically truncates very long lines for better display
-- Suggests similar file names when the requested file isn't found
-
-LIMITATIONS:
-- Maximum file size is 250KB
-- Default reading limit is 2000 lines
-- Lines longer than 2000 characters are truncated
-- Cannot display binary files or images
-- Images can be identified but not displayed
-
-TIPS:
-- Use with Glob tool to first find files you want to view
-- For code exploration, first use Grep to find relevant files, then View to examine them
-- When viewing large files, use the offset parameter to read specific sections`;
-
-export const view = Tool.define({
- name: "opencode.view",
- description: DESCRIPTION,
- parameters: z.object({
- filePath: z.string().describe("The path to the file to read"),
- offset: z
- .number()
- .describe("The line number to start reading from (0-based)")
- .optional(),
- limit: z
- .number()
- .describe("The number of lines to read (defaults to 2000)")
- .optional(),
- }),
- async execute(params) {
- let filePath = params.filePath;
- if (!path.isAbsolute(filePath)) {
- filePath = path.join(process.cwd(), filePath);
- }
-
- const file = Bun.file(filePath);
- if (!(await file.exists())) {
- const dir = path.dirname(filePath);
- const base = path.basename(filePath);
-
- const dirEntries = fs.readdirSync(dir);
- const suggestions = dirEntries
- .filter(
- (entry) =>
- entry.toLowerCase().includes(base.toLowerCase()) ||
- base.toLowerCase().includes(entry.toLowerCase()),
- )
- .map((entry) => path.join(dir, entry))
- .slice(0, 3);
-
- if (suggestions.length > 0) {
- throw new Error(
- `File not found: ${filePath}\n\nDid you mean one of these?\n${suggestions.join("\n")}`,
- );
- }
-
- throw new Error(`File not found: ${filePath}`);
- }
- const stats = await file.stat();
-
- if (stats.size > MAX_READ_SIZE)
- throw new Error(
- `File is too large (${stats.size} bytes). Maximum size is ${MAX_READ_SIZE} bytes`,
- );
- const limit = params.limit ?? DEFAULT_READ_LIMIT;
- const offset = params.offset || 0;
- const isImage = isImageFile(filePath);
- if (isImage)
- throw new Error(
- `This is an image file of type: ${isImage}\nUse a different tool to process images`,
- );
- const lines = await file.text().then((text) => text.split("\n"));
- const raw = lines.slice(offset, offset + limit).map((line) => {
- return line.length > MAX_LINE_LENGTH
- ? line.substring(0, MAX_LINE_LENGTH) + "..."
- : line;
- });
- const content = raw.map((line, index) => {
- return `${(index + offset + 1).toString().padStart(5, "0")}| ${line}`;
- });
- const preview = raw.slice(0, 20).join("\n");
-
- let output = "<file>\n";
- output += content.join("\n");
-
- if (lines.length > offset + content.length) {
- output += `\n\n(File has more lines. Use 'offset' parameter to read beyond line ${
- offset + content.length
- })`;
- }
- output += "\n</file>";
-
- // just warms the lsp client
- LSP.file(filePath);
- FileTimes.read(filePath);
-
- return {
- output,
- metadata: {
- preview,
- },
- };
- },
-});
-
-function isImageFile(filePath: string): string | false {
- const ext = path.extname(filePath).toLowerCase();
- switch (ext) {
- case ".jpg":
- case ".jpeg":
- return "JPEG";
- case ".png":
- return "PNG";
- case ".gif":
- return "GIF";
- case ".bmp":
- return "BMP";
- case ".svg":
- return "SVG";
- case ".webp":
- return "WebP";
- default:
- return false;
- }
-}