feat(v0.5): launch agent inside project subdirectory via launch_dir
LaunchOpts gains LaunchDir. session.Run resolves it via workspace.ResolveLaunch, prints any fallback warning, and passes the absolute path as the child process's working directory. Security violations (absolute paths, .. escape) abort the session. The banner gains a 'project dir: <name>/' line when launch_dir is set. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,11 +37,16 @@ func PromptPrefix(slug, mode string) string {
|
||||
}
|
||||
|
||||
// BannerLines returns the launch banner lines for agent mode.
|
||||
func BannerLines(mode, slug, wsPath string) []string {
|
||||
return []string{
|
||||
// Adds a "project dir:" line when launchDir is non-empty.
|
||||
func BannerLines(mode, slug, wsPath, launchDir string) []string {
|
||||
lines := []string{
|
||||
fmt.Sprintf("[ctask] %s :: %s", mode, slug),
|
||||
fmt.Sprintf("[ctask] %s", wsPath),
|
||||
}
|
||||
if launchDir != "" {
|
||||
lines = append(lines, fmt.Sprintf("[ctask] project dir: %s/", launchDir))
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
// ContainerNotice returns the v0.1 deferred container mode message.
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -44,7 +45,7 @@ func TestPromptPrefix(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBannerLines(t *testing.T) {
|
||||
lines := BannerLines("local", "my-task", "/home/user/ws/general/2026-04-05_my-task")
|
||||
lines := BannerLines("local", "my-task", "/home/user/ws/general/2026-04-05_my-task", "")
|
||||
if len(lines) != 2 {
|
||||
t.Fatalf("expected 2 banner lines, got %d", len(lines))
|
||||
}
|
||||
@@ -56,6 +57,26 @@ func TestBannerLines(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBannerLinesIncludesLaunchDirWhenSet(t *testing.T) {
|
||||
lines := BannerLines("local", "demo", "/ws/2026-04-22_demo", "demo")
|
||||
if len(lines) < 3 {
|
||||
t.Fatalf("expected at least 3 lines when launch dir set, got %d: %v", len(lines), lines)
|
||||
}
|
||||
if !strings.Contains(lines[2], "project dir") {
|
||||
t.Errorf("third line should mention 'project dir', got %q", lines[2])
|
||||
}
|
||||
if !strings.Contains(lines[2], "demo/") {
|
||||
t.Errorf("third line should include 'demo/', got %q", lines[2])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBannerLinesOmitsLaunchDirWhenEmpty(t *testing.T) {
|
||||
lines := BannerLines("local", "demo", "/ws/2026-04-22_demo", "")
|
||||
if len(lines) != 2 {
|
||||
t.Errorf("expected 2 lines when launch dir empty, got %d: %v", len(lines), lines)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerNotice(t *testing.T) {
|
||||
msg := ContainerNotice()
|
||||
expected := "[ctask] container mode is not available in v0.1. Use local mode or see docs for manual container setup."
|
||||
|
||||
Reference in New Issue
Block a user