Skip to content

The Executor

The xianix-executor is a short-lived Docker container that does the actual work. Each container clones (or fetches) a Git repository, installs Claude Code plugins, runs a prompt against the codebase, and returns a structured JSON result via stdout.

The executor image is built on Python 3.12 slim with Node.js 20, and includes git, gh CLI, Azure CLI, and the Claude Code CLI + SDK.

FilePurpose
entrypoint.shGit bare-clone/fetch, worktree creation, plugin install, launches Python
execute_plugin.pyCalls the Claude Code SDK, streams messages, writes JSON result to stdout
requirements.txtPinned Python dependencies
1. Read XIANIX_INPUTS → extract repository-url, platform, branch
2. Configure git credentials (GitHub PAT or Azure DevOps PAT)
3. Bare clone (first run) or git fetch (subsequent runs)
4. Create isolated git worktree: /workspace/exec-<EXECUTION_ID>/
5. Install Claude Code plugins from CLAUDE_CODE_PLUGINS
6. Run execute_plugin.py with the interpolated PROMPT
7. Write JSON result to stdout; progress to stderr
8. Clean up worktree on exit

The executor uses git worktrees to support concurrent executions against the same repo:

/workspace/repo/ ← bare clone (persistent volume, shared)
/workspace/exec-<exec-id>/ ← isolated worktree per execution (ephemeral)

Multiple containers can mount the same volume simultaneously. Each creates its own worktree, runs independently, and cleans up on exit. Orphaned worktrees from crashed containers are pruned on the next run.

VariableRequiredDescription
TENANT_IDYesTenant identifier for logging
EXECUTION_IDYesUnique ID per execution (used as worktree name)
XIANIX_INPUTSYesJSON object — must include repository-url
CLAUDE_CODE_PLUGINSYesJSON array of plugin descriptors
PROMPTYesFully interpolated prompt to execute
ANTHROPIC_API_KEYYesAnthropic API key
GITHUB_TOKENConditionalGitHub PAT (injected when available)
AZURE_DEVOPS_TOKENConditionalAzure DevOps PAT (when platform=azuredevops)

The executor writes a single JSON object to stdout that ProcessingWorkflow parses:

{
"status": "success",
"result": "...",
"cost_usd": 0.042,
"input_tokens": 12500,
"output_tokens": 3200,
"session_id": "sess_abc123"
}

Progress messages go to stderr.

Terminal window
cd Executor/
docker build -t xianix-executor:latest .
Terminal window
docker run --rm \
-e TENANT_ID=local-test \
-e EXECUTION_ID=test-001 \
-e 'XIANIX_INPUTS={"repository-url":"https://github.com/org/repo","platform":"github"}' \
-e CLAUDE_CODE_PLUGINS='[]' \
-e PROMPT="Summarize this repository." \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e GITHUB_TOKEN=ghp_... \
-v xianix-test-vol:/workspace/repo \
xianix-executor:latest

Separate stdout and stderr:

Terminal window
docker run ... xianix-executor:latest 1>result.json 2>progress.log

Ready to make changes? See Extending the Agent.