Skip to content

fix: system prompt 引导 agent 优先用 repo_url 创建工作区 - #23

Merged
lishuceo merged 3 commits into
mainfrom
fix/workspace-prompt-prefer-repo-url
Feb 18, 2026
Merged

fix: system prompt 引导 agent 优先用 repo_url 创建工作区#23
lishuceo merged 3 commits into
mainfrom
fix/workspace-prompt-prefer-repo-url

Conversation

@lishuceo

Copy link
Copy Markdown
Owner

Summary

  • Agent 在本地找到仓库后误用 local_path 调用 setup_workspace,路径不在 DEFAULT_WORK_DIR 范围内被安全校验拒绝,导致工作区创建失败
  • 修改 system prompt:明确优先使用 repo_url(走缓存+隔离工作区流程),local_path 仅限项目目录范围内
  • 补充说明:修改代码应创建隔离工作区,不要直接在原始仓库上改

Test plan

  • 验证 setup_workspacerepo_url 方式能正确 clone 到 .workspaces/ 目录
  • 飞书实测:agent 收到仓库 URL 后使用 repo_url 参数而非 local_path

🤖 Generated with Claude Code

agent 在本地找到仓库后误用 local_path 调用 setup_workspace,
但路径不在 DEFAULT_WORK_DIR 范围内被安全校验拒绝。
修改 prompt 明确:优先用 repo_url 走缓存+隔离工作区流程,
local_path 仅限项目目录范围内,修改代码应创建隔离工作区。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Feb 18, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 1m 46s —— View job


PR Review: fix/workspace-prompt-prefer-repo-url

  • Check for previous review comments
  • Read full source file and diff
  • Trace changes across module boundaries
  • Post review summary

✅ Approved

Verdict: Clean, minimal, and correctly targeted change. No bugs, no security issues.

What this PR does:

The system prompt in buildWorkspaceSystemPrompt() (src/claude/executor.ts:73-82) is updated to guide the agent to prefer repo_url over local_path when calling setup_workspace. This fixes a real problem where the agent would find a repo on the host filesystem (e.g. under /repos/cache/), then pass that path as local_path — which fails security validation because it's outside DEFAULT_WORK_DIR (/home/ubuntu/projects).

Analysis of the three changed lines:

  1. Line 74: repo_url is now marked as the preferred parameter with a clear rationale (caching + isolation). This correctly steers the agent toward the path that goes through ensureBareCache() in src/workspace/manager.ts:101-103.

  2. Line 75: local_path is now scoped to repos already within ${projectsDir}. This matches the actual security validation at src/workspace/manager.ts:85-90 which rejects any path outside config.claude.defaultWorkDir.

  3. Line 82: New guidance that code modifications should use repo_url to create an isolated workspace rather than modifying in-place. This aligns with the writable mode design (mode="writable" creates a feature branch in an isolated worktree).

Why this is the right fix: The root cause is an LLM behavioral issue — the agent finds a cached bare clone at /repos/cache/... and tries to use it as local_path, which correctly gets rejected by the path whitelist. The fix addresses this at the prompt layer, which is the appropriate place since the security validation itself is working as designed.

No issues found at confidence ≥ 75.

飞书会将 github.com: 解析为超链接,agent 拿到的 URL 可能
缺少 git@ 前缀。新增 normalizeRepoUrl 自动补全 SSH 简写格式。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Feb 18, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 1m 51s —— View job


PR Review: fix/workspace-prompt-prefer-repo-url

  • Check for previous review comments
  • Read full diff and changed files
  • Trace changes across module boundaries
  • Post review summary

✅ Approved

Verdict: Clean, well-targeted fix. No bugs or security issues found.

What changed:

  1. src/claude/executor.ts:74-82 — System prompt updated to steer the agent toward repo_url over local_path, and added guidance that code modifications should use isolated workspaces. This correctly addresses the root cause: the agent was finding bare clones in the cache directory and passing them as local_path, which gets rejected by the path whitelist at src/workspace/manager.ts:100-106.

  2. src/workspace/manager.ts:45-58 — New normalizeRepoUrl() function prepends git@ to SSH shorthand URLs (e.g. github.com:user/repogit@github.com:user/repo). Applied at line 84 before any validation or downstream use.

Cross-module trace verified:

  • After normalization, git@github.com:user/repo passes the GIT_URL_RE validation at line 92 (git@ prefix matches).
  • Downstream ensureBareCache()repoUrlToCachePath() in cache.ts:41 correctly parses the git@host:path format via its own SSH regex.
  • The SSH_SHORTHAND_RE regex (/^[\w.-]+\.\w{2,}:[\w./-]+$/) requires a dotted hostname with 2+ char TLD, which prevents false positives on localhost:port patterns.
  • Path traversal via shorthand (e.g. host.com:../../etc/passwd) is accepted by the regex but is caught downstream by repoUrlToCachePath()'s explicit .. segment check at cache.ts:64-69. Defense-in-depth holds.

No issues found at confidence ≥ 75.

SDK 内部对 PermissionResult 做 Zod 校验时要求 updatedInput
为 Record 类型,省略该字段会导致 undefined 校验失败,
MCP 工具 handler 不会被执行。修复:将 inputObj 原样传回。

同时为 MCP 工具 handler 添加入口日志便于排查。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Feb 18, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 1m 22s —— View job


PR Review: fix/workspace-prompt-prefer-repo-url

  • Check for previous inline review comments
  • Read full diff and changed files
  • Trace changes across module boundaries
  • Post review summary

✅ Approved

Verdict: Clean, well-targeted fix. No bugs or security issues found.

Changes reviewed:

  1. src/claude/executor.ts:74-82 — System prompt updated to steer the agent toward repo_url over local_path. This correctly addresses the root cause: the agent was discovering bare clones in the cache directory and passing them as local_path, which gets rejected by the path whitelist at src/workspace/manager.ts:100-106. Line 82 adds guidance to use isolated workspaces for modifications — aligns with the writable mode design.

  2. src/claude/executor.ts:189canUseTool now returns updatedInput: inputObj alongside behavior: 'allow'. This fixes a Zod validation failure in the SDK when updatedInput was undefined. Correct fix — passing through the original input unchanged.

  3. src/workspace/manager.ts:45-58 — New normalizeRepoUrl() function that prepends git@ to SSH shorthand URLs (github.com:user/repogit@github.com:user/repo). Applied at line 84 before validation. The SSH_SHORTHAND_RE regex requires a dotted hostname with 2+ char TLD, which prevents false positives on localhost:port patterns. Defense-in-depth holds: even if an unusual input like host.com:8080 matches the regex, downstream repoUrlToCachePath() in cache.ts:64-69 validates path segments and the git clone would simply fail.

  4. src/workspace/tool.ts:53 — Added debug logging for setup_workspace invocations. Clean, no sensitive data leakage (only logs repo_url, local_path, mode).

Cross-module verification:

  • After normalization, git@github.com:user/repo passes GIT_URL_RE at manager.ts:92
  • repoUrlToCachePath() in cache.ts:41 correctly parses git@host:path format via its SSH regex ✓
  • Path traversal via shorthand (e.g. host.com:../../etc/passwd) is caught by cache.ts:64-69 segment validation ✓

No issues found at confidence ≥ 75.

@lishuceo
lishuceo merged commit a22b368 into main Feb 18, 2026
1 check passed
@lishuceo
lishuceo deleted the fix/workspace-prompt-prefer-repo-url branch February 18, 2026 16:33
lishuceo added a commit that referenced this pull request Apr 8, 2026
* fix: system prompt 引导 agent 优先用 repo_url 创建工作区

agent 在本地找到仓库后误用 local_path 调用 setup_workspace,
但路径不在 DEFAULT_WORK_DIR 范围内被安全校验拒绝。
修改 prompt 明确:优先用 repo_url 走缓存+隔离工作区流程,
local_path 仅限项目目录范围内,修改代码应创建隔离工作区。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: 归一化 SSH 简写 URL (github.com:user/repo → git@...)

飞书会将 github.com: 解析为超链接,agent 拿到的 URL 可能
缺少 git@ 前缀。新增 normalizeRepoUrl 自动补全 SSH 简写格式。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: canUseTool 必须返回 updatedInput 否则 SDK Zod 校验失败

SDK 内部对 PermissionResult 做 Zod 校验时要求 updatedInput
为 Record 类型,省略该字段会导致 undefined 校验失败,
MCP 工具 handler 不会被执行。修复:将 inputObj 原样传回。

同时为 MCP 工具 handler 添加入口日志便于排查。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant