Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Aiden Cline
cdc8118373 fix(core): restore agent environment markers
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
2026-07-08 15:02:06 +00:00
4 changed files with 28 additions and 1 deletions

View file

@ -158,6 +158,8 @@ const layer = Layer.effectDiscard(
const command = ChildProcess.make(input.command, [], { const command = ChildProcess.make(input.command, [], {
cwd: target.canonical, cwd: target.canonical,
shell, shell,
env: { OPENCODE: "1", AGENT: "1" },
extendEnv: true,
stdin: "ignore", stdin: "ignore",
detached: process.platform !== "win32", detached: process.platform !== "win32",
forceKillAfter: Duration.seconds(3), forceKillAfter: Duration.seconds(3),

View file

@ -28,6 +28,8 @@ const runs: Array<{
readonly command: string readonly command: string
readonly cwd?: string readonly cwd?: string
readonly shell?: string | boolean readonly shell?: string | boolean
readonly env?: Record<string, string | undefined>
readonly extendEnv?: boolean
readonly options?: AppProcess.RunOptions readonly options?: AppProcess.RunOptions
}> = [] }> = []
let denyAction: string | undefined let denyAction: string | undefined
@ -67,7 +69,14 @@ const appProcess = Layer.succeed(
run: (command: ChildProcess.Command, options?: AppProcess.RunOptions) => run: (command: ChildProcess.Command, options?: AppProcess.RunOptions) =>
Effect.suspend(() => { Effect.suspend(() => {
if (command._tag !== "StandardCommand") throw new Error("expected standard command") if (command._tag !== "StandardCommand") throw new Error("expected standard command")
runs.push({ command: command.command, cwd: command.options.cwd, shell: command.options.shell, options }) runs.push({
command: command.command,
cwd: command.options.cwd,
shell: command.options.shell,
env: command.options.env,
extendEnv: command.options.extendEnv,
options,
})
return runFailure ? Effect.fail(runFailure) : Effect.succeed(result) return runFailure ? Effect.fail(runFailure) : Effect.succeed(result)
}), }),
} as unknown as AppProcess.Interface), } as unknown as AppProcess.Interface),
@ -168,6 +177,7 @@ describe("BashTool", () => {
}, },
}) })
expect(runs).toMatchObject([{ command: "pwd", cwd: realpathSync(tmp.path) }]) expect(runs).toMatchObject([{ command: "pwd", cwd: realpathSync(tmp.path) }])
expect(runs[0]).toMatchObject({ env: { OPENCODE: "1", AGENT: "1" }, extendEnv: true })
expect(runs[0]?.options).toMatchObject({ expect(runs[0]?.options).toMatchObject({
combineOutput: true, combineOutput: true,
maxOutputBytes: BashTool.MAX_CAPTURE_BYTES, maxOutputBytes: BashTool.MAX_CAPTURE_BYTES,

View file

@ -422,6 +422,8 @@ export const ShellTool = Tool.define(
return { return {
...process.env, ...process.env,
...extra.env, ...extra.env,
OPENCODE: "1",
AGENT: "1",
} }
}) })

View file

@ -194,6 +194,19 @@ describe("tool.shell", () => {
), ),
) )
each("identifies commands as running under opencode", () =>
runIn(
projectRoot,
Effect.gen(function* () {
const code = "process.stdout.write([process.env.OPENCODE,process.env.AGENT].join(String.fromCharCode(44)))"
const command = `${PS.has(sh()) ? "& " : ""}${bin} -e ${evalarg(code)}`
const result = yield* run({ command })
expect(result.metadata.exit).toBe(0)
expect(result.output).toContain("1,1")
}),
),
)
it.live("falls back from terminal-only configured shell", () => it.live("falls back from terminal-only configured shell", () =>
Effect.gen(function* () { Effect.gen(function* () {
const tmp = yield* tmpdirScoped({ config: { shell: "fish" } }) const tmp = yield* tmpdirScoped({ config: { shell: "fish" } })