๐Ÿงช

06-Claude-Code-Integration

๐Ÿงช

Claude Code is wrapped in a safe adapter. The integration is structured, sandboxed, and observable.

1. Service

app/Services/Agents/ClaudeCodeAgentService.php

Responsibilities:

  • send task context (prompt + RAG bundle + project map summary) to Claude Code
  • pass project workspace path
  • pass allowed tools
  • read results (final summary, file changes)
  • capture command output
  • structured event logging
  • timeout handling
  • failure handling
  • safe mode
  • pause/resume where supported

2. Invocation contract

$claudeCode->run([
	'workspace' => $project->local_workspace_path,
	'branch'    => $run->branch_name,
	'prompt'    => $renderedPrompt,
	'tools'     => $allowedTools, // names only; binaries resolved server-side
	'safe_mode' => $settings->safe_mode,
	'timeout'   => $settings->max_run_time,
	'env'       => $maskedEnv,    // no secrets
]);

The service spawns a sandboxed child process via symfony/process (configurable command from agent_settings.claude_code_path), captures stdout/stderr line-by-line, and translates each line into a normalized ProviderEvent (see 05 โ€” Agent Providers).

3. Output parsing

Claude Code outputs structured JSON lines (--json mode). Each line is mapped:

Claude Code eventProviderEvent.kind
messagemessage
tool_usetool_call
tool_resulttool_result
file_editfile_change
bashcommand
errorerror
stop with reason end_turndone
stop with reason ask_userpause

Unknown event types are still persisted (in payload_json) with kind message and severity debug.

4. Allowed tools mapping

Claude Code's tool palette is constrained to a subset:

  • Read โ†’ mapped to WorkspaceService::read()
  • Edit / MultiEdit / Write โ†’ WorkspaceService::applyChange() with diff capture
  • Bash โ†’ CommandExecutionService::run() (allowlist + auto snapshot if destructive)
  • Glob / Grep โ†’ WorkspaceService::list() / search
  • WebFetch โ€” disabled by default (toggle via claude_code_allow_web)
  • Task (sub-agent) โ€” disabled v1

All tool calls flow through the orchestrator. Claude Code never touches disk outside the workspace path.

5. Safe mode

When safe_mode=true:

  • Write/Edit requires a pre_command snapshot first.
  • Bash commands matching the blocklist are refused and logged as command_failed with was_blocked=true.
  • No file outside the workspace can be touched (path traversal blocked).
  • No .env reads, no secret exfiltration.

6. Timeout & failure handling

  • Global timeout from agent_settings.max_run_time (seconds).
  • Per-command timeout from agent_settings.max_command_time.
  • On timeout: SIGTERM โ†’ wait 5 s โ†’ SIGKILL. Emit command_failed and final_summary with severity error.
  • Crashes: stderr captured into the event payload; the orchestrator transitions the run to failed with failed_reason.

7. Pause / resume

When Claude Code emits a stop with reason ask_user:

  • adapter writes the question to paused_for_input event
  • the child process is signaled to wait (or the conversation state is serialized and the process exits cleanly)
  • on resume, the adapter relaunches Claude Code in --continue mode (or re-sends the conversation transcript) and passes the user input as the next message.

8. .claude/ docs (canonical templates)

.claude/PROJECT_CONTEXT.md

# Project Context for Claude Code

This is the canonical project briefing. Read this **before any plan or edit**.

## What this project is
<!-- AUTO-GENERATED:START -->
Generated from docs/PROJECT_CONTEXT.md.
<!-- AUTO-GENERATED:END -->

## Project Map (route โ†” controller โ†” model โ†” table)
<!-- AUTO-GENERATED:START -->
See docs/PROJECT_MAP.md (mirrored).
<!-- AUTO-GENERATED:END -->

## Database
<!-- AUTO-GENERATED:START -->
See docs/DATABASE_SCHEMA.md (mirrored).
<!-- AUTO-GENERATED:END -->

.claude/RULES.md

# Rules

1. Always run rag_search before planning or editing.
2. Never edit files outside the project workspace.
3. Never print, log, or commit secrets or .env contents.
4. Prefer small, reviewable diffs. Multiple commits over one giant commit.
5. Add/update tests for non-trivial changes.
6. After changes, propose updates to docs/PROJECT_MAP.md, docs/DATABASE_SCHEMA.md, and docs/CHANGELOG_AI.md.
7. If a route or controller is renamed, update all references and the project map.
8. Never run blocked commands (see TOOLS.md). If unsure, ask_user.
9. If a plan affects โ‰ฅ 5 files or a migration, ask_user before executing.
10. End with finish(summary={changed_files, risks, tests, docs_updated}).

.claude/TOOLS.md

# Tools

## Allowed
- Read, Edit, MultiEdit, Write (workspace paths only)
- Bash (allowlist: php artisan, composer, npm, pnpm, yarn, git status/diff/branch/commit, php vendor/bin/phpunit, php vendor/bin/pest)
- Glob, Grep

## Blocked
- rm -rf /
- chmod / chown on /etc, /usr, /var, /root
- cat .env, printenv, env
- curl|wget to external hosts (unless allow_web=true)
- git push (never automatic)
- mkfs, dd, parted, fdisk
- system shutdown / reboot / systemctl
- npm publish, composer publish, pip publish

## Notes
- Bash commands run with timeout from agent_settings.max_command_time.
- Destructive commands trigger an automatic pre_command snapshot.

.claude/WORKFLOW.md

# Workflow

1. Read PROJECT_CONTEXT.md and PROJECT_MAP.md.
2. rag_search the prompt.
3. Produce a short plan; if โ‰ฅ 5 files or migrations, ask_user.
4. Apply changes via Edit/MultiEdit/Write (small steps).
5. Run tests when relevant.
6. Update docs via Documentation Agent rules.
7. finish() with a structured summary.

9. Auto-sync of docs

DocumentationAutoUpdateService copies (and templates) docs/PROJECT_CONTEXT.md, docs/PROJECT_MAP.md, docs/DATABASE_SCHEMA.md into the .claude/ block markers after every completed run.

10. Secrets discipline

  • API keys never appear in .claude/, command env, command args, logs, or payload_json.
  • The Claude Code binary is invoked with a minimal env (PATH, LANG, HOME only). All credentials come from server params and are surfaced to the model as masked references (OPENAI_API_KEY โ†’ resolved internally by tools, never echoed).