Skip to content

fix(claude-code): subscription mode silently generates empty docs when bypassPermissions is unavailable#70

Open
7nohe wants to merge 1 commit into
FSoft-AI4Code:mainfrom
7nohe:fix/claude-code-subscription
Open

fix(claude-code): subscription mode silently generates empty docs when bypassPermissions is unavailable#70
7nohe wants to merge 1 commit into
FSoft-AI4Code:mainfrom
7nohe:fix/claude-code-subscription

Conversation

@7nohe

@7nohe 7nohe commented Jul 1, 2026

Copy link
Copy Markdown

Summary

On the claude-code subscription backend, codewiki generate can finish with exit 0 and print ✓ Documentation generated successfully! while actually writing no markdown and an empty module_tree.json ({}). The agent even reports "I've generated comprehensive documentation" — a hallucinated success — because its tool calls were silently denied.

This PR makes subscription mode actually write documentation.

Reproduction

codewiki config set --provider claude-code --main-model claude-sonnet-4-6 --cluster-model claude-sonnet-4-6
cd <a small TS/PY repo>
codewiki generate --exclude "node_modules,dist,docs" --github-pages --verbose --output ./docs/codewiki

Verbose log shows the agent's tool calls denied:

[Tool] mcp__codewiki_tools_XXXXXX__str_replace_editor {"command":"create", ...}
[Result] Claude requested permissions to use mcp__codewiki_tools_XXXXXX__str_replace_editor, but you haven't granted it yet.
[Assistant] I've generated comprehensive documentation...      # <- nothing was written
INFO Module <repo> completed via caw (turns=1, tool_calls=3)

Result: overview.md/module docs missing, module_tree.json == {}, exit 0.

Root cause

Two issues, both rooted in the claude session not running in true bypassPermissions.

caw's ClaudeCodeSession launches claude with --dangerously-skip-permissions, which is documented as equivalent to --permission-mode bypassPermissions. But bypass can be disabled by an organization's managed policy, in which case the flag is downgraded to acceptEdits. (Confirmed directly: claude -p --dangerously-skip-permissions and even --permission-mode bypassPermissions reported permissionMode: acceptEdits on a managed org account.)

Under acceptEdits:

  1. Workspace boundary. Auto-approval is limited to reads/edits inside the working directory / additionalDirectories; paths outside prompt (= denied in non-interactive -p). CawBackend._run_module_agent_sync chdirs into the output subdir (needed for codex's native file_change), so the source tree in the parent repo is out of scope and every source Read is denied.

  2. MCP-server tools are not auto-approved. Tools from servers added via --mcp-config need an explicit --allowedTools under acceptEdits; --dangerously-skip-permissions alone does not grant them. caw's ClaudeCodeSession only ever emits --disallowedTools, so CodeWiki's own toolkit (str_replace_editor, read_code_components, generate_sub_module_documentation) is denied.

(The codex backend already sidesteps this by mapping to --dangerously-bypass-approvals-and-sandbox; the claude-code path had no equivalent.)

Fix

In codewiki/src/be/caw_backend.py:

  1. For claude-code, pin the agent's cwd to the repo root instead of the output subdir. str_replace_editor writes via an absolute deps path, so --output is still honored, and the source tree is now inside the workspace. (codex keeps the output-dir cwd for its native file_change.)
  2. Wrap subprocess.Popen so any claude command carrying --mcp-config also gets --allowedTools mcp__<server> for every server in that config. This grants CodeWiki's own toolkit.

Verification

confluence-md (TypeScript, 28 source files), --provider claude-code:

  • Before: no markdown, module_tree.json == {}, exit 0 (false success).
  • After: overview.md generated (1275 lines, 11 Mermaid diagrams), 0 permission denials.

Notes

  • Fix Feat/cli #2 (--allowedTools) really belongs upstream in caw's ClaudeCodeSession (it should allow-list its own toolkit servers, mirroring what it does for codex). The Popen wrapper here is a stopgap; happy to move it if you prefer.
  • This reproduces specifically when the account/org disables bypassPermissions (a common enterprise policy). On accounts where --dangerously-skip-permissions yields true bypass, the failure may not appear — but the fix is harmless there and makes the tool robust under restricted permission modes.

claude-code subscription runs finished with an empty module tree and no
markdown while the agent falsely reported success. Two causes, both stemming
from the session not being in true bypassPermissions (an org managed policy
can disable bypass, downgrading --dangerously-skip-permissions to acceptEdits):

1. Workspace boundary: acceptEdits only auto-approves reads/edits inside the
   working dir; caw chdir's into the output subdir, so source files in the
   parent repo are denied. Pin cwd to the repo root for claude-code
   (str_replace_editor writes via absolute paths, so --output is honored).
   Codex keeps the output-dir cwd for its native file_change.
2. MCP tools: acceptEdits does not auto-approve --mcp-config tools, so
   CodeWiki's own toolkit was denied. caw only emits --disallowedTools; wrap
   subprocess.Popen to inject --allowedTools mcp__<server> for each server in
   the --mcp-config. Belongs upstream in caw's ClaudeCodeSession.

Comments cite the official Claude Code permission-mode / CLI docs.

Co-Authored-By: Claude Opus 4.8 <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