mirror of
https://github.com/cexll/myclaude.git
synced 2026-02-28 09:23:05 +08:00
Merge pull request #147 from AsakiEmura/fix/unset-claudecode-env
fix(executor): unset CLAUDECODE env to prevent nested session rejection
This commit is contained in:
@@ -169,6 +169,12 @@ func (f *execFakeRunner) Process() executor.ProcessHandle {
|
|||||||
return &execFakeProcess{pid: 1}
|
return &execFakeProcess{pid: 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *execFakeRunner) UnsetEnv(keys ...string) {
|
||||||
|
for _, k := range keys {
|
||||||
|
delete(f.env, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestExecutorRunCodexTaskWithContext(t *testing.T) {
|
func TestExecutorRunCodexTaskWithContext(t *testing.T) {
|
||||||
defer resetTestHooks()
|
defer resetTestHooks()
|
||||||
|
|
||||||
|
|||||||
@@ -274,6 +274,10 @@ func (d *drainBlockingCmd) Process() executor.ProcessHandle {
|
|||||||
return d.inner.Process()
|
return d.inner.Process()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *drainBlockingCmd) UnsetEnv(keys ...string) {
|
||||||
|
d.inner.UnsetEnv(keys...)
|
||||||
|
}
|
||||||
|
|
||||||
type bufferWriteCloser struct {
|
type bufferWriteCloser struct {
|
||||||
buf bytes.Buffer
|
buf bytes.Buffer
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -568,6 +572,14 @@ func (f *fakeCmd) Process() executor.ProcessHandle {
|
|||||||
return f.process
|
return f.process
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *fakeCmd) UnsetEnv(keys ...string) {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
for _, k := range keys {
|
||||||
|
delete(f.env, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *fakeCmd) runStdoutScript() {
|
func (f *fakeCmd) runStdoutScript() {
|
||||||
if len(f.stdoutPlan) == 0 {
|
if len(f.stdoutPlan) == 0 {
|
||||||
if !f.keepStdoutOpen {
|
if !f.keepStdoutOpen {
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ func (f *fakeCmd) SetEnv(env map[string]string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (f *fakeCmd) Process() processHandle { return nil }
|
func (f *fakeCmd) Process() processHandle { return nil }
|
||||||
|
func (f *fakeCmd) UnsetEnv(keys ...string) {
|
||||||
|
for _, k := range keys {
|
||||||
|
delete(f.env, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEnvInjection_LogsToStderrAndMasksKey(t *testing.T) {
|
func TestEnvInjection_LogsToStderrAndMasksKey(t *testing.T) {
|
||||||
// Arrange ~/.codeagent/models.json via HOME override.
|
// Arrange ~/.codeagent/models.json via HOME override.
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ type commandRunner interface {
|
|||||||
SetStderr(io.Writer)
|
SetStderr(io.Writer)
|
||||||
SetDir(string)
|
SetDir(string)
|
||||||
SetEnv(env map[string]string)
|
SetEnv(env map[string]string)
|
||||||
|
UnsetEnv(keys ...string)
|
||||||
Process() processHandle
|
Process() processHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +222,33 @@ func (r *realCmd) SetEnv(env map[string]string) {
|
|||||||
r.cmd.Env = out
|
r.cmd.Env = out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *realCmd) UnsetEnv(keys ...string) {
|
||||||
|
if r == nil || r.cmd == nil || len(keys) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// If cmd.Env is nil, Go inherits all parent env vars.
|
||||||
|
// Populate explicitly so we can selectively remove keys.
|
||||||
|
if r.cmd.Env == nil {
|
||||||
|
r.cmd.Env = os.Environ()
|
||||||
|
}
|
||||||
|
drop := make(map[string]struct{}, len(keys))
|
||||||
|
for _, k := range keys {
|
||||||
|
drop[k] = struct{}{}
|
||||||
|
}
|
||||||
|
filtered := make([]string, 0, len(r.cmd.Env))
|
||||||
|
for _, kv := range r.cmd.Env {
|
||||||
|
idx := strings.IndexByte(kv, '=')
|
||||||
|
name := kv
|
||||||
|
if idx >= 0 {
|
||||||
|
name = kv[:idx]
|
||||||
|
}
|
||||||
|
if _, ok := drop[name]; !ok {
|
||||||
|
filtered = append(filtered, kv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.cmd.Env = filtered
|
||||||
|
}
|
||||||
|
|
||||||
func (r *realCmd) Process() processHandle {
|
func (r *realCmd) Process() processHandle {
|
||||||
if r == nil || r.cmd == nil || r.cmd.Process == nil {
|
if r == nil || r.cmd == nil || r.cmd.Process == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -1126,6 +1154,13 @@ func RunCodexTaskWithContext(parentCtx context.Context, taskSpec TaskSpec, backe
|
|||||||
|
|
||||||
injectTempEnv(cmd)
|
injectTempEnv(cmd)
|
||||||
|
|
||||||
|
// Claude Code sets CLAUDECODE=1 in its child processes. If we don't
|
||||||
|
// remove it, the spawned `claude -p` detects the variable and refuses
|
||||||
|
// to start ("cannot be launched inside another Claude Code session").
|
||||||
|
if commandName == "claude" {
|
||||||
|
cmd.UnsetEnv("CLAUDECODE")
|
||||||
|
}
|
||||||
|
|
||||||
// For backends that don't support -C flag (claude, gemini), set working directory via cmd.Dir
|
// For backends that don't support -C flag (claude, gemini), set working directory via cmd.Dir
|
||||||
// Codex passes workdir via -C flag, so we skip setting Dir for it to avoid conflicts
|
// Codex passes workdir via -C flag, so we skip setting Dir for it to avoid conflicts
|
||||||
if cfg.Mode != "resume" && commandName != "codex" && cfg.WorkDir != "" {
|
if cfg.Mode != "resume" && commandName != "codex" && cfg.WorkDir != "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user