diff --git a/packages/opencode/src/session/todo.ts b/packages/opencode/src/session/todo.ts new file mode 100644 index 00000000..4f426854 --- /dev/null +++ b/packages/opencode/src/session/todo.ts @@ -0,0 +1,34 @@ +import z from "zod/v4" +import { Bus } from "../bus" +import { Storage } from "../storage/storage" + +export namespace Todo { + export const Info = z + .object({ + content: z.string().describe("Brief description of the task"), + status: z.string().describe("Current status of the task: pending, in_progress, completed, cancelled"), + priority: z.string().describe("Priority level of the task: high, medium, low"), + id: z.string().describe("Unique identifier for the todo item"), + }) + .meta({ ref: "Todo" }) + export type Info = z.infer + + export const Event = { + Updated: Bus.event( + "todo.updated", + z.object({ + sessionID: z.string(), + todos: z.array(Info), + }), + ), + } + + export async function update(input: { sessionID: string; todos: Info[] }) { + await Storage.write(["todo", input.sessionID], input.todos) + Bus.publish(Event.Updated, input) + } + + export async function get(sessionID: string) { + return Storage.read(["todo", sessionID]) ?? [] + } +} diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts index 0e1d37ec..1946ada1 100644 --- a/packages/opencode/src/tool/bash.ts +++ b/packages/opencode/src/tool/bash.ts @@ -3,22 +3,17 @@ import { exec } from "child_process" import { Tool } from "./tool" import DESCRIPTION from "./bash.txt" -import { Permission } from "../permission" -import { Filesystem } from "../util/filesystem" import { lazy } from "../util/lazy" import { Log } from "../util/log" -import { Wildcard } from "../util/wildcard" -import { $ } from "bun" import { Instance } from "../project/instance" -import { Agent } from "../agent/agent" const MAX_OUTPUT_LENGTH = 30_000 const DEFAULT_TIMEOUT = 1 * 60 * 1000 const MAX_TIMEOUT = 10 * 60 * 1000 -const log = Log.create({ service: "bash-tool" }) +export const log = Log.create({ service: "bash-tool" }) -const parser = lazy(async () => { +export const parser = lazy(async () => { try { const { default: Parser } = await import("tree-sitter") const Bash = await import("tree-sitter-bash") @@ -26,8 +21,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 +33,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 @@ -56,7 +53,11 @@ 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() @@ -145,6 +146,7 @@ export const BashTool = Tool.define("bash", { }, }) } + */ const process = exec(params.command, { cwd: Instance.directory, diff --git a/packages/opencode/src/tool/test.ts b/packages/opencode/src/tool/test.ts index 138d92fb..14427c73 100644 --- a/packages/opencode/src/tool/test.ts +++ b/packages/opencode/src/tool/test.ts @@ -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) => { diff --git a/packages/opencode/src/util/fn.ts b/packages/opencode/src/util/fn.ts new file mode 100644 index 00000000..9efe4622 --- /dev/null +++ b/packages/opencode/src/util/fn.ts @@ -0,0 +1,11 @@ +import { z } from "zod" + +export function fn(schema: T, cb: (input: z.infer) => Result) { + const result = (input: z.infer) => { + const parsed = schema.parse(input) + return cb(parsed) + } + result.force = (input: z.infer) => cb(input) + result.schema = schema + return result +} diff --git a/packages/opencode/tsconfig.json b/packages/opencode/tsconfig.json index 8e4f68a0..167d7936 100644 --- a/packages/opencode/tsconfig.json +++ b/packages/opencode/tsconfig.json @@ -2,6 +2,14 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@tsconfig/bun/tsconfig.json", "compilerOptions": { - "lib": ["ESNext", "DOM", "DOM.Iterable"] + "jsx": "preserve", + "jsxImportSource": "@opentui/solid", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "customConditions": ["browser"], + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "@tui/*": ["./src/cli/cmd/tui/*"] + } } }