feat(cursor): add sandbox option to disable restricted tool mode

Cursor Agent CLI defaults to sandbox mode in headless environments,
limiting available tools to read-only operations (ls, etc.). Add a
configurable `sandbox` option ("enabled"/"disabled"/"") that maps to
the `--sandbox` CLI flag, allowing users to unlock full tool access
(shell, edit, write) when running via cc-connect.

Config example:
  [projects.agent.options]
  sandbox = "disabled"

Made-with: Cursor
This commit is contained in:
Claude committed 2026-04-01 09:59:22 +08:00
1 parent 155b204b64
commit 6152854fa0
3 files changed
+31 -4

No files matched your search

+16 -1
View File
@@ -34,6 +34,7 @@ type Agent struct {
model string
mode string
cmd string // CLI binary name, default "agent"
sandbox string // "enabled", "disabled", or "" (let CLI decide)
providers []core.ProviderConfig
activeIdx int
sessionEnv []string
@@ -52,6 +53,7 @@ func New(opts map[string]any) (core.Agent, error) {
if cmd == "" {
cmd = "agent"
}
sandbox := normalizeSandbox(opts["sandbox"])
if _, err := exec.LookPath(cmd); err != nil {
return nil, fmt.Errorf("cursor: %q CLI not found in PATH, install with: npm i -g @anthropic-ai/cursor-agent (or from Cursor IDE settings)", cmd)
@@ -62,6 +64,7 @@ func New(opts map[string]any) (core.Agent, error) {
model: model,
mode: mode,
cmd: cmd,
sandbox: sandbox,
activeIdx: -1,
}, nil
}
@@ -79,6 +82,18 @@ func normalizeMode(raw string) string {
}
}
func normalizeSandbox(v any) string {
s, _ := v.(string)
switch strings.ToLower(strings.TrimSpace(s)) {
case "enabled", "on", "true", "1":
return "enabled"
case "disabled", "off", "false", "0":
return "disabled"
default:
return ""
}
}
func (a *Agent) Name() string { return "cursor" }
func (a *Agent) CLIBinaryName() string { return "agent" }
func (a *Agent) CLIDisplayName() string { return "Cursor Agent" }
@@ -202,7 +217,7 @@ func (a *Agent) StartSession(ctx context.Context, sessionID string) (core.AgentS
}
a.mu.Unlock()
return newCursorSession(ctx, cmd, a.workDir, model, mode, sessionID, extraEnv)
return newCursorSession(ctx, cmd, a.workDir, model, mode, a.sandbox, sessionID, extraEnv)
}
// ListSessions reads sessions from ~/.cursor/chats/<workspace_hash>/.
+7 -1
View File
@@ -26,6 +26,7 @@ type cursorSession struct {
workDir string
model string
mode string
sandbox string // "enabled", "disabled", or ""
extraEnv []string
events chan core.Event
chatID atomic.Value // stores string — Cursor chat/session ID
@@ -37,7 +38,7 @@ type cursorSession struct {
thinkingBuf strings.Builder // accumulate thinking deltas
}
func newCursorSession(ctx context.Context, cmd, workDir, model, mode, resumeID string, extraEnv []string) (*cursorSession, error) {
func newCursorSession(ctx context.Context, cmd, workDir, model, mode, sandbox, resumeID string, extraEnv []string) (*cursorSession, error) {
sessionCtx, cancel := context.WithCancel(ctx)
cs := &cursorSession{
@@ -45,6 +46,7 @@ func newCursorSession(ctx context.Context, cmd, workDir, model, mode, resumeID s
workDir: workDir,
model: model,
mode: mode,
sandbox: sandbox,
extraEnv: extraEnv,
events: make(chan core.Event, 64),
ctx: sessionCtx,
@@ -89,6 +91,10 @@ func (cs *cursorSession) Send(prompt string, images []core.ImageAttachment, file
args = append(args, "--mode", "ask")
}
if cs.sandbox != "" {
args = append(args, "--sandbox", cs.sandbox)
}
if isResume {
args = append(args, "--resume", chatID)
}
+8 -2
View File
@@ -911,8 +911,9 @@ app_secret = "your-feishu-app-secret"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "force" # "default" | "force" (yolo) | "plan" | "ask"
# cmd = "agent" # CLI binary name (default: "agent") / CLI 二进制名称(默认 "agent")
# mode = "force" # "default" | "force" (yolo) | "plan" | "ask"
# cmd = "agent" # CLI binary name (default: "agent") / CLI 二进制名称(默认 "agent")
# sandbox = "disabled" # "enabled" | "disabled" | "" (let CLI decide)
#
# Mode options / 模式说明:
# - "default": Trust workspace, ask before tool use / 信任工作区,工具调用前询问
@@ -920,6 +921,11 @@ app_secret = "your-feishu-app-secret"
# - "plan": Read-only analysis, no edits / 只读分析,不做修改
# - "ask": Q&A style, read-only / 问答风格,只读
#
# Sandbox options / 沙箱模式说明:
# - "disabled": Full tool access (shell, edit, write, etc.) / 完整工具访问(shell、edit、write 等)
# - "enabled": Restricted tools (read-only, ls, etc.) / 受限工具(只读、ls 等)
# - "": Let Cursor CLI decide (may default to sandbox in headless) / 由 CLI 决定(headless 可能默认沙箱)
#
# Optional: specify a model / 可选:指定模型
# model = "claude-sonnet-4-20250514"
#