mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
code highlighting WIP (#2885)
Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Dax <mail@thdxr.com>
This commit is contained in:
parent
cc5cfc6b7d
commit
5cfec2ef9d
8 changed files with 234 additions and 128 deletions
24
bun.lock
24
bun.lock
|
|
@ -156,8 +156,8 @@
|
|||
"@openauthjs/openauth": "catalog:",
|
||||
"@opencode-ai/plugin": "workspace:*",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@opentui/core": "0.0.0-20251001-886e38c1",
|
||||
"@opentui/solid": "0.0.0-20251001-886e38c1",
|
||||
"@opentui/core": "0.0.0-20251001-d57654da",
|
||||
"@opentui/solid": "0.0.0-20251001-d57654da",
|
||||
"@standard-schema/spec": "1.0.0",
|
||||
"@zip.js/zip.js": "2.7.62",
|
||||
"ai": "catalog:",
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
"turndown": "7.2.0",
|
||||
"ulid": "catalog:",
|
||||
"vscode-jsonrpc": "8.2.1",
|
||||
"web-tree-sitter": "0.22.6",
|
||||
"web-tree-sitter": "0.26.0",
|
||||
"xdg-basedir": "5.1.0",
|
||||
"yargs": "18.0.0",
|
||||
"zod": "catalog:",
|
||||
|
|
@ -835,21 +835,21 @@
|
|||
|
||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
"@opentui/core": ["@opentui/core@0.0.0-20251001-886e38c1", "", { "dependencies": { "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.0.0-20251001-886e38c1", "@opentui/core-darwin-x64": "0.0.0-20251001-886e38c1", "@opentui/core-linux-arm64": "0.0.0-20251001-886e38c1", "@opentui/core-linux-x64": "0.0.0-20251001-886e38c1", "@opentui/core-win32-arm64": "0.0.0-20251001-886e38c1", "@opentui/core-win32-x64": "0.0.0-20251001-886e38c1", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": ">=0.25.0" } }, "sha512-mbElYuirjjWynIpc4pkNTtIYxK9zmEmEjgaV5Z1wyrSy/e5Ld5nKs39wBLKPFzx/u9XcIIz31YRLNW3hHXlxEQ=="],
|
||||
"@opentui/core": ["@opentui/core@0.0.0-20251001-d57654da", "", { "dependencies": { "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.0.0-20251001-d57654da", "@opentui/core-darwin-x64": "0.0.0-20251001-d57654da", "@opentui/core-linux-arm64": "0.0.0-20251001-d57654da", "@opentui/core-linux-x64": "0.0.0-20251001-d57654da", "@opentui/core-win32-arm64": "0.0.0-20251001-d57654da", "@opentui/core-win32-x64": "0.0.0-20251001-d57654da", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": ">=0.26.0" } }, "sha512-xDERJfK0+xn3atLPPyjliCPTZOGMZ3Is5NOKuCMZnpICm3zNirJMa02/8FGmxz0fbPL+ll1MTO1qdpl2DZBb6g=="],
|
||||
|
||||
"@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.0.0-20251001-886e38c1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b5+wxaIaEnT0qdCxeOXgW5q0DP/y1r1dTVEVwT0JUK/NXkTa+MPIkHfPg8Ns82v/Bpv2pdvgZkcgBb8f8F0Zvg=="],
|
||||
"@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.0.0-20251001-d57654da", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1Q2F9VYRQO/nZioOQmbJf3gpouBUDYE8fC5oeiw9p0fnOmcxPSN0LiS7YJbQcD+x5cK5N5Sv7jxe9ar44Wjivg=="],
|
||||
|
||||
"@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.0.0-20251001-886e38c1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ct2HbxYp9RTXbESilA+ypLG/1mZXn8fAnMUzrxJ77T10yEIzQx5AQPkMJkIwx1hMDmVVgK5M+Eryuk9/IWagAQ=="],
|
||||
"@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.0.0-20251001-d57654da", "", { "os": "darwin", "cpu": "x64" }, "sha512-d1iXRP2QdQe2k4Dwwq9QGDay1b2//YIua7N8DOjWztVHDGDKO/doBWfM6f4+HYEEiXegmZX+1hX/VXYEEKTxWA=="],
|
||||
|
||||
"@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.0.0-20251001-886e38c1", "", { "os": "linux", "cpu": "arm64" }, "sha512-DVimZeRZNmMXdLmziiKGlT04J9NBk1VhkjUcWNz1xKNJz3e0VAJHGE9+B4aUCT7iT06bj6bnmfZuZDlCtmLEyg=="],
|
||||
"@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.0.0-20251001-d57654da", "", { "os": "linux", "cpu": "arm64" }, "sha512-dc2C1yZlE5o0NfNzV7rqYCqqRBp5TRIGje3u2QEY2xDY4qlti4dS8cSOrLTWrYWrIoCmuN7W+eGrOH4NuUF+fw=="],
|
||||
|
||||
"@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.0.0-20251001-886e38c1", "", { "os": "linux", "cpu": "x64" }, "sha512-obw90FMU9FXnSgL+4DYBaiEPW6PNz7TIFu7Vc39yXRFfLU9eM6Jrj+KRgmEzbsLAqWB246rmAAHnAX8y0T3qpQ=="],
|
||||
"@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.0.0-20251001-d57654da", "", { "os": "linux", "cpu": "x64" }, "sha512-sjzj1Jos7VRIl0I7JjZcOu7T4jmMdJgoRTV+U1q9wBMSVQpV9Prb50N/egGeX8D0bEF0V1T6bWkph9xgCMNKsg=="],
|
||||
|
||||
"@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.0.0-20251001-886e38c1", "", { "os": "win32", "cpu": "arm64" }, "sha512-me60jLhjwmGrKS18ny0quBk3eatCR5uKTTzkxnqxgqdHXaM/tbC2S9SoIOkOLWwySLjj69n8xLzuZrZSOojssQ=="],
|
||||
"@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.0.0-20251001-d57654da", "", { "os": "win32", "cpu": "arm64" }, "sha512-F3ySKR284VLS1UUDAtcya7RJRuknghlANwlrYxiJkVOjOa7swAaxGZNYdMXmRRvOmMraeOgHWHVK3y0qdPFV9A=="],
|
||||
|
||||
"@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.0.0-20251001-886e38c1", "", { "os": "win32", "cpu": "x64" }, "sha512-WeoojsODqLH5nX9P9UF7QjFAKDq9Z0SLBDzvcRo7NyU3Wd9PhcQf1v9Cjc42lYgF/EOX24UGv2pDLqT0mhIANA=="],
|
||||
"@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.0.0-20251001-d57654da", "", { "os": "win32", "cpu": "x64" }, "sha512-aVpSsEqke8ryVh2oChQrwcz4+zYPh77radM+lks5A2bo926r3dcFWNuIBFHwGTJ0tll5iAXw2MdfHo+2r8srxQ=="],
|
||||
|
||||
"@opentui/solid": ["@opentui/solid@0.0.0-20251001-886e38c1", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.0.0-20251001-886e38c1", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-mEydaU1JrFL7sSz0lAVIS80IprmhTpqUFabOyLJSReSQ3SSA3tLssdJCWNdqbLXAMaP5NgpmQu6iOwvVxZdJFA=="],
|
||||
"@opentui/solid": ["@opentui/solid@0.0.0-20251001-d57654da", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.0.0-20251001-d57654da", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-8rJDFe8b2icFs7kTNT4ypDCIKU0RTgE2bION197RtYh9Mu6ViIagqrfGZloRdIRLcRYroYqXdl21IVh5ji2BsQ=="],
|
||||
|
||||
"@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="],
|
||||
|
||||
|
|
@ -3107,7 +3107,7 @@
|
|||
|
||||
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
|
||||
|
||||
"web-tree-sitter": ["web-tree-sitter@0.22.6", "", {}, "sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q=="],
|
||||
"web-tree-sitter": ["web-tree-sitter@0.26.0", "", {}, "sha512-wGGAMnJEMF8wy33iEGxSvnyEOfVLzSaa3x6g66aEHsL/hsgFb6IVPrpacIordAMz198pE9qReCEqFUuM0pnfwg=="],
|
||||
|
||||
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
||||
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@
|
|||
"@openauthjs/openauth": "catalog:",
|
||||
"@opencode-ai/plugin": "workspace:*",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@opentui/core": "0.0.0-20251001-886e38c1",
|
||||
"@opentui/solid": "0.0.0-20251001-886e38c1",
|
||||
"@opentui/core": "0.0.0-20251001-d57654da",
|
||||
"@opentui/solid": "0.0.0-20251001-d57654da",
|
||||
"@standard-schema/spec": "1.0.0",
|
||||
"@zip.js/zip.js": "2.7.62",
|
||||
"ai": "catalog:",
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
"turndown": "7.2.0",
|
||||
"ulid": "catalog:",
|
||||
"vscode-jsonrpc": "8.2.1",
|
||||
"web-tree-sitter": "0.22.6",
|
||||
"web-tree-sitter": "0.26.0",
|
||||
"xdg-basedir": "5.1.0",
|
||||
"yargs": "18.0.0",
|
||||
"zod": "catalog:"
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ for (const [os, arch] of targets) {
|
|||
await $`mkdir -p ../../node_modules/${opentui}`
|
||||
await $`npm pack npm pack ${opentui}`.cwd(path.join(dir, "../../node_modules")).quiet()
|
||||
await $`tar -xf ../../node_modules/${opentui.replace("@opentui/", "opentui-")}-*.tgz -C ../../node_modules/${opentui} --strip-components=1`
|
||||
|
||||
await Bun.build({
|
||||
conditions: ["browser"],
|
||||
tsconfig: "./tsconfig.json",
|
||||
|
|
@ -50,12 +51,14 @@ for (const [os, arch] of targets) {
|
|||
execArgv: [`--user-agent=opencode/${version}`, `--env-file=""`, `--`],
|
||||
windows: {},
|
||||
},
|
||||
entrypoints: ["./src/index.ts", "./src/cli/cmd/tui/worker.ts"],
|
||||
entrypoints: ["./src/index.ts", path.resolve(dir, "../../node_modules/@opentui/core/parser.worker.js")],
|
||||
define: {
|
||||
OPENCODE_VERSION: `'${version}'`,
|
||||
OPENCODE_TUI_PATH: `'../../../dist/${name}/bin/tui'`,
|
||||
OTUI_TREE_SITTER_WORKER_PATH: "/$bunfs/root/../../node_modules/@opentui/core/parser.worker.js",
|
||||
},
|
||||
})
|
||||
|
||||
await $`rm -rf ./dist/${name}/bin/tui`
|
||||
await Bun.file(`dist/${name}/package.json`).write(
|
||||
JSON.stringify(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { SyntaxStyle } from "@opentui/core"
|
||||
|
||||
const OPENCODE_THEME = {
|
||||
primary: {
|
||||
dark: "#fab283",
|
||||
|
|
@ -243,18 +245,191 @@ type Theme = {
|
|||
markdownImage: string
|
||||
markdownImageText: string
|
||||
markdownCodeBlock: string
|
||||
syntaxComment: string
|
||||
syntaxKeyword: string
|
||||
syntaxFunction: string
|
||||
syntaxVariable: string
|
||||
syntaxString: string
|
||||
syntaxNumber: string
|
||||
syntaxType: string
|
||||
syntaxOperator: string
|
||||
syntaxPunctuation: string
|
||||
}
|
||||
|
||||
export const Theme = Object.entries(OPENCODE_THEME).reduce((acc, [key, value]) => {
|
||||
acc[key as keyof Theme] = value.dark
|
||||
return acc
|
||||
}, {} as Theme)
|
||||
}, {} as Theme)
|
||||
|
||||
const syntaxThemeDark = [
|
||||
{
|
||||
scope: ["prompt"],
|
||||
style: {
|
||||
foreground: "#56b6c2",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["comment"],
|
||||
style: {
|
||||
foreground: "#808080",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["comment.documentation"],
|
||||
style: {
|
||||
foreground: "#808080",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["string", "symbol"],
|
||||
style: {
|
||||
foreground: "#7fd88f",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["number", "boolean"],
|
||||
style: {
|
||||
foreground: "#f5a742",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["character.special"],
|
||||
style: {
|
||||
foreground: "#7fd88f",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.return", "keyword.conditional", "keyword.repeat", "keyword.coroutine"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.type"],
|
||||
style: {
|
||||
foreground: "#e5c07b",
|
||||
bold: true,
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.function", "function.method"],
|
||||
style: {
|
||||
foreground: "#fab283",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.import"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["operator", "keyword.operator", "punctuation.delimiter"],
|
||||
style: {
|
||||
foreground: "#56b6c2",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.conditional.ternary"],
|
||||
style: {
|
||||
foreground: "#56b6c2",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["variable", "variable.parameter", "function.method.call", "function.call"],
|
||||
style: {
|
||||
foreground: "#e06c75",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["variable.member", "function", "constructor"],
|
||||
style: {
|
||||
foreground: "#fab283",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["type", "module"],
|
||||
style: {
|
||||
foreground: "#e5c07b",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["constant"],
|
||||
style: {
|
||||
foreground: "#e06c75",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["property"],
|
||||
style: {
|
||||
foreground: "#e06c75",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["class"],
|
||||
style: {
|
||||
foreground: "#e5c07b",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["parameter"],
|
||||
style: {
|
||||
foreground: "#eeeeee",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["punctuation", "punctuation.bracket"],
|
||||
style: {
|
||||
foreground: "#eeeeee",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["variable.builtin", "type.builtin", "function.builtin", "module.builtin", "constant.builtin"],
|
||||
style: {
|
||||
foreground: "#7fd88f",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["variable.super"],
|
||||
style: {
|
||||
foreground: "#e06c75",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["string.escape", "string.regexp"],
|
||||
style: {
|
||||
foreground: "#7fd88f",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.directive"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["punctuation.special"],
|
||||
style: {
|
||||
foreground: "#56b6c2",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.modifier"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ["keyword.exception"],
|
||||
style: {
|
||||
foreground: "#9d7cd8",
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export const syntaxTheme = SyntaxStyle.fromTheme(syntaxThemeDark)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import path from "path"
|
|||
import { useRouteData } from "@tui/context/route"
|
||||
import { useSync } from "@tui/context/sync"
|
||||
import { SplitBorder } from "@tui/component/border"
|
||||
import { Theme } from "@tui/context/theme"
|
||||
import { BoxRenderable, ScrollBoxRenderable } from "@opentui/core"
|
||||
import { syntaxTheme, Theme } from "@tui/context/theme"
|
||||
import { BoxRenderable, pathToFiletype, ScrollBoxRenderable } from "@opentui/core"
|
||||
import { Prompt, type PromptRef } from "@tui/component/prompt"
|
||||
import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencode-ai/sdk"
|
||||
import { useLocal } from "@tui/context/local"
|
||||
|
|
@ -648,22 +648,6 @@ ToolRegistry.register<typeof BashTool>({
|
|||
},
|
||||
})
|
||||
|
||||
/*
|
||||
const syntax = new SyntaxStyle({
|
||||
keyword: { fg: RGBA.fromHex(Theme.syntaxKeyword), bold: true },
|
||||
string: { fg: RGBA.fromHex(Theme.syntaxString) },
|
||||
comment: { fg: RGBA.fromHex(Theme.syntaxComment), italic: true },
|
||||
number: { fg: RGBA.fromHex(Theme.syntaxNumber) },
|
||||
function: { fg: RGBA.fromHex(Theme.syntaxFunction) },
|
||||
type: { fg: RGBA.fromHex(Theme.syntaxType) },
|
||||
operator: { fg: RGBA.fromHex(Theme.syntaxOperator) },
|
||||
variable: { fg: RGBA.fromHex(Theme.syntaxVariable) },
|
||||
bracket: { fg: RGBA.fromHex(Theme.syntaxPunctuation) },
|
||||
punctuation: { fg: RGBA.fromHex(Theme.syntaxPunctuation) },
|
||||
default: { fg: RGBA.fromHex(Theme.syntaxVariable) },
|
||||
})
|
||||
*/
|
||||
|
||||
ToolRegistry.register<typeof ReadTool>({
|
||||
name: "read",
|
||||
container: "inline",
|
||||
|
|
@ -708,7 +692,7 @@ ToolRegistry.register<typeof WriteTool>({
|
|||
<For each={numbers()}>{(value) => <text style={{ fg: Theme.textMuted }}>{value}</text>}</For>
|
||||
</box>
|
||||
<box paddingLeft={1} flexGrow={1}>
|
||||
<text>{code()}</text>
|
||||
<code filetype={pathToFiletype(props.input.filePath!)} syntaxStyle={syntaxTheme} content={code()} />
|
||||
</box>
|
||||
</box>
|
||||
</>
|
||||
|
|
@ -819,13 +803,21 @@ ToolRegistry.register<typeof EditTool>({
|
|||
</Match>
|
||||
<Match when={code()}>
|
||||
<box paddingLeft={1}>
|
||||
<text>{code()}</text>
|
||||
<code filetype={pathToFiletype(props.input.filePath!)} syntaxStyle={syntaxTheme} content={code()} />
|
||||
</box>
|
||||
</Match>
|
||||
<Match when={props.input.newString && props.input.oldString}>
|
||||
<box paddingLeft={1}>
|
||||
<text>{props.input.oldString}</text>
|
||||
<text>{props.input.newString}</text>
|
||||
<code
|
||||
filetype={pathToFiletype(props.input.filePath!)}
|
||||
syntaxStyle={syntaxTheme}
|
||||
content={props.input.oldString}
|
||||
/>
|
||||
<code
|
||||
filetype={pathToFiletype(props.input.filePath!)}
|
||||
syntaxStyle={syntaxTheme}
|
||||
content={props.input.newString}
|
||||
/>
|
||||
</box>
|
||||
</Match>
|
||||
</Switch>
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ const parser = lazy(async () => {
|
|||
p.setLanguage(Bash.language as any)
|
||||
return p
|
||||
} catch (e) {
|
||||
const { default: Parser } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, { with: { type: "wasm" } })
|
||||
const { Parser, Language } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/web-tree-sitter.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
})
|
||||
await Parser.init({
|
||||
locateFile() {
|
||||
return treeWasm
|
||||
|
|
@ -36,7 +38,7 @@ const parser = lazy(async () => {
|
|||
const { default: bashWasm } = await import("tree-sitter-bash/tree-sitter-bash.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
})
|
||||
const bashLanguage = await Parser.Language.load(bashWasm)
|
||||
const bashLanguage = await Language.load(bashWasm)
|
||||
const p = new Parser()
|
||||
p.setLanguage(bashLanguage)
|
||||
return p
|
||||
|
|
@ -57,6 +59,9 @@ export const BashTool = Tool.define("bash", {
|
|||
async execute(params, ctx) {
|
||||
const timeout = Math.min(params.timeout ?? DEFAULT_TIMEOUT, MAX_TIMEOUT)
|
||||
const tree = await parser().then((p) => p.parse(params.command))
|
||||
if (!tree) {
|
||||
throw new Error("Failed to parse command")
|
||||
}
|
||||
const permissions = await Agent.get(ctx.agent).then((x) => x.permission.bash)
|
||||
|
||||
const askPatterns = new Set<string>()
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ const parser = async () => {
|
|||
p.setLanguage(Bash.language as any)
|
||||
return p
|
||||
} catch (e) {
|
||||
const { default: Parser } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, { with: { type: "wasm" } })
|
||||
const { Parser, Language } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/web-tree-sitter.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
})
|
||||
await Parser.init({
|
||||
locateFile() {
|
||||
return treeWasm
|
||||
|
|
@ -16,7 +18,7 @@ const parser = async () => {
|
|||
const { default: bashWasm } = await import("tree-sitter-bash/tree-sitter-bash.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
})
|
||||
const bashLanguage = await Parser.Language.load(bashWasm)
|
||||
const bashLanguage = await Language.load(bashWasm)
|
||||
const p = new Parser()
|
||||
p.setLanguage(bashLanguage)
|
||||
return p
|
||||
|
|
@ -62,6 +64,9 @@ function extractCommands(node: any): Array<{ command: string; args: string[] }>
|
|||
|
||||
// Extract and display commands
|
||||
console.log("Source code: " + sourceCode)
|
||||
if (!tree) {
|
||||
throw new Error("Failed to parse command")
|
||||
}
|
||||
const commands = extractCommands(tree.rootNode)
|
||||
console.log("Extracted commands:")
|
||||
commands.forEach((cmd, index) => {
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
import { lazy } from "../util/lazy"
|
||||
|
||||
export namespace TreeSitter {
|
||||
const Parser = lazy(async () => {
|
||||
try {
|
||||
return NativeParser()
|
||||
} catch (e) {
|
||||
return WasmParser()
|
||||
}
|
||||
})
|
||||
|
||||
const NativeParser = lazy(async () => {
|
||||
const { default: Parser } = await import("tree-sitter")
|
||||
return Parser
|
||||
})
|
||||
|
||||
const WasmParser = lazy(async () => {
|
||||
const { default: Parser } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
})
|
||||
await Parser.init({
|
||||
locateFile() {
|
||||
return treeWasm
|
||||
},
|
||||
})
|
||||
return Parser
|
||||
})
|
||||
|
||||
export async function parser() {
|
||||
const p = await Parser()
|
||||
const result = new p()
|
||||
return result
|
||||
}
|
||||
|
||||
const Languages: Record<string, { native: () => any; wasm: () => any }> = {
|
||||
bash: {
|
||||
native: () => import("tree-sitter-bash"),
|
||||
wasm: () =>
|
||||
import("tree-sitter-bash/tree-sitter-bash.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
}),
|
||||
},
|
||||
typescript: {
|
||||
native: () => import("tree-sitter-typescript"),
|
||||
wasm: () =>
|
||||
import("tree-sitter-typescript/tree-sitter-typescript.wasm" as string, {
|
||||
with: { type: "wasm" },
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
const Extensions = {
|
||||
".ts": "typescript",
|
||||
".tsx": "typescript",
|
||||
".js": "typescript",
|
||||
".jsx": "typescript",
|
||||
".sh": "bash",
|
||||
}
|
||||
|
||||
export async function language(extension: keyof typeof Extensions) {
|
||||
const language = Extensions[extension]
|
||||
if (!language) return undefined
|
||||
const { native, wasm } = Languages[language]
|
||||
try {
|
||||
const { language } = await native()
|
||||
return language
|
||||
} catch (e) {
|
||||
const { default: mod } = await wasm()
|
||||
const language = await WasmParser().then((p) => p.Language.load(mod))
|
||||
return language
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue