Skip to content

Commit 6b7ff49

Browse files
shivamstaqclaude
andcommitted
Fix sidecar launch failure: resolve script path to absolute at startup
Root cause: sidecar command used relative path "sidecar/claude/src/index.ts" but subprocess CWD was the workspace directory, not the Symphony project dir. tsx couldn't find the file and exited silently (stderr at debug level). Fixes: 1. Resolve sidecar script path to absolute using os.Getwd() at startup. Store in closure variable captured by adapter factory. 2. Call tsx directly instead of wrapping in bash -lc. 3. Validate sidecar script exists at startup with clear error message. 4. Add sidecar path check to --doctor output. 5. Log subprocess stderr at WARN (was DEBUG) so crash reasons are visible. 6. Remove empty default for SidecarCommand — resolved dynamically in main. End-to-end verified: sidecar now initializes, creates sessions, completes prompt turns with stop_reason=completed against real GitHub project items. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4fe9183 commit 6b7ff49

3 files changed

Lines changed: 36 additions & 17 deletions

File tree

cmd/symphony/main.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ func main() {
173173
},
174174
})
175175

176+
// Resolve sidecar script path to absolute (relative to where symphony was invoked)
177+
symphonyDir, _ := os.Getwd()
178+
var sidecarScript string
179+
if cfg.Agent.Kind == "claude_code" {
180+
sidecarScript = cfg.Claude.SidecarCommand
181+
if sidecarScript == "" {
182+
sidecarScript = filepath.Join(symphonyDir, "sidecar", "claude", "src", "index.ts")
183+
} else if !filepath.IsAbs(sidecarScript) {
184+
sidecarScript = filepath.Join(symphonyDir, sidecarScript)
185+
}
186+
// Validate sidecar script exists
187+
if _, err := os.Stat(sidecarScript); err != nil {
188+
logger.Error("sidecar script not found", "path", sidecarScript, "error", err)
189+
os.Exit(1)
190+
}
191+
logger.Info("sidecar script resolved", "path", sidecarScript)
192+
}
193+
176194
// Create worker runner
177195
runner := orchestrator.NewRunner(orchestrator.WorkerDeps{
178196
WorkspaceManager: wsMgr,
@@ -181,15 +199,10 @@ func main() {
181199
Kind: cfg.Agent.Kind,
182200
Cwd: cwd,
183201
}
184-
// Set command based on agent kind
185202
switch cfg.Agent.Kind {
186203
case "claude_code":
187-
acfg.Command = "bash"
188-
cmd := cfg.Claude.SidecarCommand
189-
if cmd == "" {
190-
cmd = "tsx sidecar/claude/src/index.ts"
191-
}
192-
acfg.Args = []string{"-lc", cmd}
204+
acfg.Command = "tsx"
205+
acfg.Args = []string{sidecarScript}
193206
case "opencode":
194207
acfg.Command = "opencode"
195208
acfg.Args = []string{"acp"}
@@ -392,6 +405,17 @@ func runDoctor(cfg *config.ServiceConfig, wsRoot, stateDir string) {
392405
os.Exit(1)
393406
}
394407
fmt.Println("PASS: tsx found on PATH")
408+
// Check sidecar script
409+
sidecar := cfg.Claude.SidecarCommand
410+
if sidecar == "" {
411+
cwd, _ := os.Getwd()
412+
sidecar = filepath.Join(cwd, "sidecar", "claude", "src", "index.ts")
413+
}
414+
if _, err := os.Stat(sidecar); err != nil {
415+
fmt.Printf("FAIL: sidecar script not found: %s\n", sidecar)
416+
os.Exit(1)
417+
}
418+
fmt.Printf("PASS: sidecar script found: %s\n", sidecar)
395419
case "opencode":
396420
if err := checkBinaryExists("opencode"); err != nil {
397421
fmt.Printf("FAIL: opencode not found on PATH: %v\n", err)

internal/adapter/subprocess.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,9 @@ func (a *SubprocessAdapter) handleCallbackRequest(msg *Message) {
214214
}
215215

216216
func (a *SubprocessAdapter) drainStderr() {
217-
buf := make([]byte, 4096)
218-
for {
219-
n, err := a.stderr.Read(buf)
220-
if n > 0 {
221-
slog.Debug("adapter stderr", "output", string(buf[:n]))
222-
}
223-
if err != nil {
224-
return
225-
}
217+
data, err := io.ReadAll(a.stderr)
218+
if len(data) > 0 {
219+
slog.Warn("adapter stderr", "output", string(data))
226220
}
221+
_ = err
227222
}

internal/config/service_config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func (c *ServiceConfig) applyDefaults() {
261261
c.Claude = ClaudeConfig{
262262
AdapterMode: "sdk_sidecar",
263263
SDKLanguage: "typescript",
264-
SidecarCommand: "tsx sidecar/claude/src/index.ts",
264+
SidecarCommand: "", // resolved to absolute path at startup in main.go
265265
ContinueOnPause: true,
266266
}
267267
c.OpenCode = OpenCodeConfig{

0 commit comments

Comments
 (0)