summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLuke Parker <[email protected]>2026-04-29 09:10:48 +1000
committerGitHub <[email protected]>2026-04-28 23:10:48 +0000
commitd4bf70be06f5e893cc3b9f39b2c68f8df7481508 (patch)
treed2d687073cf3392f8c7b15d5f2acb46597f1571d
parentae8904c4ffbb369955127ec39965d4c49cb4bab4 (diff)
downloadopencode-d4bf70be06f5e893cc3b9f39b2c68f8df7481508.tar.gz
opencode-d4bf70be06f5e893cc3b9f39b2c68f8df7481508.zip
fix(bash): memory leak - release parsed syntax trees (#24861)
Co-authored-by: jiwenshang <[email protected]>
-rw-r--r--packages/opencode/src/tool/bash.ts17
1 files changed, 12 insertions, 5 deletions
diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts
index 859389949..517512ff4 100644
--- a/packages/opencode/src/tool/bash.ts
+++ b/packages/opencode/src/tool/bash.ts
@@ -252,7 +252,7 @@ function tail(text: string, maxLines: number, maxBytes: number) {
const parse = Effect.fn("BashTool.parse")(function* (command: string, ps: boolean) {
const tree = yield* Effect.promise(() => parser().then((p) => (ps ? p.ps : p.bash).parse(command)))
if (!tree) throw new Error("Failed to parse command")
- return tree.rootNode
+ return tree
})
const ask = Effect.fn("BashTool.ask")(function* (ctx: Tool.Context, scan: Scan) {
@@ -596,10 +596,17 @@ export const BashTool = Tool.define(
}
const timeout = params.timeout ?? DEFAULT_TIMEOUT
const ps = Shell.ps(shell)
- const root = yield* parse(params.command, ps)
- const scan = yield* collect(root, cwd, ps, shell)
- if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
- yield* ask(ctx, scan)
+ yield* Effect.scoped(
+ Effect.gen(function* () {
+ const tree = yield* Effect.acquireRelease(
+ parse(params.command, ps),
+ (tree) => Effect.sync(() => tree.delete()),
+ )
+ const scan = yield* collect(tree.rootNode, cwd, ps, shell)
+ if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
+ yield* ask(ctx, scan)
+ }),
+ )
return yield* run(
{