refactor: rename container/ to runners/

No longer using Docker containers — agents run as direct host
processes. The directory name now reflects the actual purpose.

Updated all references across source code, docs, and skills.
This commit is contained in:
Eyejoker
2026-03-15 19:29:23 +09:00
parent 6f4b6f8df7
commit e2d6476cdf
28 changed files with 75 additions and 75 deletions

View File

@@ -34,7 +34,7 @@ This adds:
- `src/session-commands.ts` (extract and authorize session commands)
- `src/session-commands.test.ts` (unit tests for command parsing and auth)
- Session command interception in `src/index.ts` (both `processGroupMessages` and `startMessageLoop`)
- Slash command handling in `container/agent-runner/src/index.ts`
- Slash command handling in `runners/agent-runner/src/index.ts`
### Validate
@@ -46,7 +46,7 @@ npm run build
### Rebuild container
```bash
./container/build.sh
./runners/build.sh
```
### Restart service
@@ -106,7 +106,7 @@ cd /tmp/nanoclaw-test
claude # then run /add-compact
npm run build
npm test
./container/build.sh
./runners/build.sh
# Manual: send /compact from main group, verify compaction + continuation
# Manual: send @<assistant> /compact from non-main as non-admin, verify denial
# Manual: send @<assistant> /compact from non-main as admin, verify allowed

View File

@@ -48,7 +48,7 @@ This merges in:
- `src/channels/gmail.test.ts` (unit tests)
- `import './gmail.js'` appended to the channel barrel file `src/channels/index.ts`
- Gmail credentials mount (`~/.gmail-mcp`) in `src/container-runner.ts`
- Gmail MCP server (`@gongrzhe/server-gmail-autoauth-mcp`) and `mcp__gmail__*` allowed tool in `container/agent-runner/src/index.ts`
- Gmail MCP server (`@gongrzhe/server-gmail-autoauth-mcp`) and `mcp__gmail__*` allowed tool in `runners/agent-runner/src/index.ts`
- `googleapis` npm dependency in `package.json`
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
@@ -199,7 +199,7 @@ npx -y @gongrzhe/server-gmail-autoauth-mcp
### Tool-only mode
1. Remove `~/.gmail-mcp` mount from `src/container-runner.ts`
2. Remove `gmail` MCP server and `mcp__gmail__*` from `container/agent-runner/src/index.ts`
2. Remove `gmail` MCP server and `mcp__gmail__*` from `runners/agent-runner/src/index.ts`
3. Rebuild and restart
4. Clear stale agent-runner copies: `rm -r data/sessions/*/agent-runner-src 2>/dev/null || true`
5. Rebuild: `cd container && ./build.sh && cd .. && npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux)
@@ -209,7 +209,7 @@ npx -y @gongrzhe/server-gmail-autoauth-mcp
1. Delete `src/channels/gmail.ts` and `src/channels/gmail.test.ts`
2. Remove `import './gmail.js'` from `src/channels/index.ts`
3. Remove `~/.gmail-mcp` mount from `src/container-runner.ts`
4. Remove `gmail` MCP server and `mcp__gmail__*` from `container/agent-runner/src/index.ts`
4. Remove `gmail` MCP server and `mcp__gmail__*` from `runners/agent-runner/src/index.ts`
5. Uninstall: `npm uninstall googleapis`
6. Rebuild and restart
7. Clear stale agent-runner copies: `rm -r data/sessions/*/agent-runner-src 2>/dev/null || true`

View File

@@ -40,7 +40,7 @@ This merges in:
- `src/image.test.ts` (8 unit tests)
- Image attachment handling in `src/channels/whatsapp.ts`
- Image passing to agent in `src/index.ts` and `src/container-runner.ts`
- Image content block support in `container/agent-runner/src/index.ts`
- Image content block support in `runners/agent-runner/src/index.ts`
- `sharp` npm dependency in `package.json`
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
@@ -59,13 +59,13 @@ All tests must pass and build must be clean before proceeding.
1. Rebuild the container (agent-runner changes need a rebuild):
```bash
./container/build.sh
./runners/build.sh
```
2. Sync agent-runner source to group caches:
```bash
for dir in data/sessions/*/agent-runner-src/; do
cp container/agent-runner/src/*.ts "$dir"
cp runners/agent-runner/src/*.ts "$dir"
done
```

View File

@@ -15,7 +15,7 @@ Tools added:
### Check if already applied
Check if `container/agent-runner/src/ollama-mcp-stdio.ts` exists. If it does, skip to Phase 3 (Configure).
Check if `runners/agent-runner/src/ollama-mcp-stdio.ts` exists. If it does, skip to Phase 3 (Configure).
### Check prerequisites
@@ -59,9 +59,9 @@ git merge upstream/skill/ollama-tool
```
This merges in:
- `container/agent-runner/src/ollama-mcp-stdio.ts` (Ollama MCP server)
- `runners/agent-runner/src/ollama-mcp-stdio.ts` (Ollama MCP server)
- `scripts/ollama-watch.sh` (macOS notification watcher)
- Ollama MCP config in `container/agent-runner/src/index.ts` (allowedTools + mcpServers)
- Ollama MCP config in `runners/agent-runner/src/index.ts` (allowedTools + mcpServers)
- `[OLLAMA]` log surfacing in `src/container-runner.ts`
- `OLLAMA_HOST` in `.env.example`
@@ -73,8 +73,8 @@ Existing groups have a cached copy of the agent-runner source. Copy the new file
```bash
for dir in data/sessions/*/agent-runner-src; do
cp container/agent-runner/src/ollama-mcp-stdio.ts "$dir/"
cp container/agent-runner/src/index.ts "$dir/"
cp runners/agent-runner/src/ollama-mcp-stdio.ts "$dir/"
cp runners/agent-runner/src/index.ts "$dir/"
done
```
@@ -82,7 +82,7 @@ done
```bash
npm run build
./container/build.sh
./runners/build.sh
```
Build must be clean before proceeding.
@@ -138,9 +138,9 @@ Look for:
### Agent says "Ollama is not installed"
The agent is trying to run `ollama` CLI inside the container instead of using the MCP tools. This means:
1. The MCP server wasn't registered — check `container/agent-runner/src/index.ts` has the `ollama` entry in `mcpServers`
1. The MCP server wasn't registered — check `runners/agent-runner/src/index.ts` has the `ollama` entry in `mcpServers`
2. The per-group source wasn't updated — re-copy files (see Phase 2)
3. The container wasn't rebuilt — run `./container/build.sh`
3. The container wasn't rebuilt — run `./runners/build.sh`
### "Failed to connect to Ollama"

View File

@@ -78,7 +78,7 @@ const allowedVars = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'PARALLEL_A
### 4. Configure MCP Servers in Agent Runner
Update `container/agent-runner/src/index.ts`:
Update `runners/agent-runner/src/index.ts`:
Find the section where `mcpServers` is configured (around line 237-252):
```typescript
@@ -219,7 +219,7 @@ AskUserQuestion: I can do deep research on [topic] using Parallel's Task API. Th
Build the container with updated agent runner:
```bash
./container/build.sh
./runners/build.sh
```
Verify the build:
@@ -286,5 +286,5 @@ To remove Parallel AI integration:
1. Remove from .env: `sed -i.bak '/PARALLEL_API_KEY/d' .env`
2. Revert changes to container-runner.ts and agent-runner/src/index.ts
3. Remove Web Research Tools section from groups/main/CLAUDE.md
4. Rebuild: `./container/build.sh && npm run build`
4. Rebuild: `./runners/build.sh && npm run build`
5. Restart: `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux)

View File

@@ -9,7 +9,7 @@ Adds PDF reading capability to all container agents using poppler-utils (pdftote
## Phase 1: Pre-flight
1. Check if `container/skills/pdf-reader/pdf-reader` exists — skip to Phase 3 if already applied
1. Check if `runners/skills/pdf-reader/pdf-reader` exists — skip to Phase 3 if already applied
2. Confirm WhatsApp is installed first (`skill/whatsapp` merged). This skill modifies WhatsApp channel files.
## Phase 2: Apply Code Changes
@@ -34,9 +34,9 @@ git merge whatsapp/skill/pdf-reader
```
This merges in:
- `container/skills/pdf-reader/SKILL.md` (agent-facing documentation)
- `container/skills/pdf-reader/pdf-reader` (CLI script)
- `poppler-utils` in `container/Dockerfile`
- `runners/skills/pdf-reader/SKILL.md` (agent-facing documentation)
- `runners/skills/pdf-reader/pdf-reader` (CLI script)
- `poppler-utils` in `runners/Dockerfile`
- PDF attachment download in `src/channels/whatsapp.ts`
- PDF tests in `src/channels/whatsapp.test.ts`
@@ -52,7 +52,7 @@ npx vitest run src/channels/whatsapp.test.ts
### Rebuild container
```bash
./container/build.sh
./runners/build.sh
```
### Restart service
@@ -89,7 +89,7 @@ Look for:
### Agent says pdf-reader command not found
Container needs rebuilding. Run `./container/build.sh` and restart the service.
Container needs rebuilding. Run `./runners/build.sh` and restart the service.
### PDF text extraction is empty

View File

@@ -44,8 +44,8 @@ This adds:
- `scripts/migrate-reactions.ts` (database migration for `reactions` table with composite PK and indexes)
- `src/status-tracker.ts` (forward-only emoji state machine for message lifecycle signaling, with persistence and retry)
- `src/status-tracker.test.ts` (unit tests for StatusTracker)
- `container/skills/reactions/SKILL.md` (agent-facing documentation for the `react_to_message` MCP tool)
- Reaction support in `src/db.ts`, `src/channels/whatsapp.ts`, `src/types.ts`, `src/ipc.ts`, `src/index.ts`, `src/group-queue.ts`, and `container/agent-runner/src/ipc-mcp-stdio.ts`
- `runners/skills/reactions/SKILL.md` (agent-facing documentation for the `react_to_message` MCP tool)
- Reaction support in `src/db.ts`, `src/channels/whatsapp.ts`, `src/types.ts`, `src/ipc.ts`, `src/index.ts`, `src/group-queue.ts`, and `runners/agent-runner/src/ipc-mcp-stdio.ts`
### Run database migration

View File

@@ -168,7 +168,7 @@ export async function sendPoolMessage(
### Step 3: Add sender Parameter to MCP Tool
Read `container/agent-runner/src/ipc-mcp-stdio.ts` and update the `send_message` tool to accept an optional `sender` parameter:
Read `runners/agent-runner/src/ipc-mcp-stdio.ts` and update the `send_message` tool to accept an optional `sender` parameter:
Change the tool's schema from:
```typescript
@@ -320,7 +320,7 @@ Also add `TELEGRAM_BOT_POOL` to the launchd plist (`~/Library/LaunchAgents/com.n
```bash
npm run build
./container/build.sh # Required — MCP tool changed
./runners/build.sh # Required — MCP tool changed
# macOS:
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
@@ -378,7 +378,7 @@ To remove Agent Swarm support while keeping basic Telegram:
2. Remove pool code from `src/telegram.ts` (`poolApis`, `senderBotMap`, `initBotPool`, `sendPoolMessage`)
3. Remove pool routing from IPC handler in `src/index.ts` (revert to plain `sendMessage`)
4. Remove `initBotPool` call from `main()`
5. Remove `sender` param from MCP tool in `container/agent-runner/src/ipc-mcp-stdio.ts`
5. Remove `sender` param from MCP tool in `runners/agent-runner/src/ipc-mcp-stdio.ts`
6. Remove Agent Teams section from group CLAUDE.md files
7. Remove `TELEGRAM_BOT_POOL` from `.env`, `data/env/env`, and launchd plist/systemd unit
8. Rebuild: `npm run build && ./container/build.sh && launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist && launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist` (macOS) or `npm run build && ./container/build.sh && systemctl --user restart nanoclaw` (Linux)
8. Rebuild: `npm run build && ./runners/build.sh && launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist && launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist` (macOS) or `npm run build && ./runners/build.sh && systemctl --user restart nanoclaw` (Linux)

View File

@@ -72,8 +72,8 @@ This merges in:
- `src/container-runtime.ts` — Apple Container implementation (replaces Docker)
- `src/container-runtime.test.ts` — Apple Container-specific tests
- `src/container-runner.ts` — .env shadow mount fix and privilege dropping
- `container/Dockerfile` — entrypoint that shadows .env via `mount --bind`
- `container/build.sh` — default runtime set to `container`
- `runners/Dockerfile` — entrypoint that shadows .env via `mount --bind`
- `runners/build.sh` — default runtime set to `container`
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
@@ -97,7 +97,7 @@ container system status || container system start
### Build the container image
```bash
./container/build.sh
./runners/build.sh
```
### Test basic execution
@@ -158,7 +158,7 @@ container system status
```bash
# Clean rebuild — Apple Container caches aggressively
container builder stop && container builder rm && container builder start
./container/build.sh
./runners/build.sh
```
**Container can't write to mounted directories:**
@@ -171,5 +171,5 @@ Check directory permissions on the host. The container runs as uid 1000.
| `src/container-runtime.ts` | Full replacement — Docker → Apple Container API |
| `src/container-runtime.test.ts` | Full replacement — tests for Apple Container behavior |
| `src/container-runner.ts` | .env shadow mount removed, main containers start as root with privilege drop |
| `container/Dockerfile` | Entrypoint: `mount --bind` for .env shadowing, `setpriv` privilege drop |
| `container/build.sh` | Default runtime: `docker``container` |
| `runners/Dockerfile` | Entrypoint: `mount --bind` for .env shadowing, `setpriv` privilege drop |
| `runners/build.sh` | Default runtime: `docker``container` |

View File

@@ -12,7 +12,7 @@ This guide covers debugging the containerized agent execution system.
```
Host (macOS) Container (Linux VM)
─────────────────────────────────────────────────────────────
src/container-runner.ts container/agent-runner/
src/container-runner.ts runners/agent-runner/
│ │
│ spawns container │ runs Claude Agent SDK
│ with volume mounts │ with MCP servers
@@ -234,11 +234,11 @@ query({
npm run build
# Rebuild container (use --no-cache for clean rebuild)
./container/build.sh
./runners/build.sh
# Or force full rebuild
docker builder prune -af
./container/build.sh
./runners/build.sh
```
## Checking Container Image
@@ -332,7 +332,7 @@ echo -e "\n3. Container runtime running?"
docker info &>/dev/null && echo "OK" || echo "NOT RUNNING - start Docker Desktop (macOS) or sudo systemctl start docker (Linux)"
echo -e "\n4. Container image exists?"
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "OK" 2>/dev/null || echo "MISSING - run ./container/build.sh"
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "OK" 2>/dev/null || echo "MISSING - run ./runners/build.sh"
echo -e "\n5. Session mount path correct?"
grep -q "/home/node/.claude" src/container-runner.ts 2>/dev/null && echo "OK" || echo "WRONG - should mount to /home/node/.claude/, not /root/.claude/"

View File

@@ -11,7 +11,7 @@ Run setup steps automatically. Only pause when user action is required (channel
**UX Note:** Use `AskUserQuestion` for all user-facing questions.
**Architecture:** NanoClaw runs agents as direct host processes (no Docker/containers). Each agent type (Claude Code, Codex) has its own runner in `container/agent-runner/` and `container/codex-runner/`.
**Architecture:** NanoClaw runs agents as direct host processes (no Docker/containers). Each agent type (Claude Code, Codex) has its own runner in `runners/agent-runner/` and `runners/codex-runner/`.
## 0. Git & Fork Setup
@@ -76,12 +76,12 @@ Run `npx tsx setup/index.ts --step environment` and parse the status block.
Run `npx tsx setup/index.ts --step runners` and parse the status block.
This builds the agent runners that execute as host processes:
- `container/agent-runner/` — Claude Code agent (via Claude Agent SDK)
- `container/codex-runner/` — Codex agent (via Codex CLI)
- `runners/agent-runner/` — Claude Code agent (via Claude Agent SDK)
- `runners/codex-runner/` — Codex agent (via Codex CLI)
**If BUILD_OK=false:** Read `logs/setup.log` for the error. Common fix: `cd container/agent-runner && npm install && npm run build`.
**If BUILD_OK=false:** Read `logs/setup.log` for the error. Common fix: `cd runners/agent-runner && npm install && npm run build`.
**If CODEX_RUNNER=false but AGENT_RUNNER=true:** Codex runner failed to build. Not critical if you only use Claude Code. Fix: `cd container/codex-runner && npm install && npm run build`.
**If CODEX_RUNNER=false but AGENT_RUNNER=true:** Codex runner failed to build. Not critical if you only use Claude Code. Fix: `cd runners/codex-runner && npm install && npm run build`.
## 4. Claude Authentication (No Script)

View File

@@ -18,7 +18,7 @@ Run `/update-nanoclaw` in Claude Code.
**Preview**: runs `git log` and `git diff` against the merge base to show upstream changes since your last sync. Groups changed files into categories:
- **Skills** (`.claude/skills/`): unlikely to conflict unless you edited an upstream skill
- **Source** (`src/`): may conflict if you modified the same files
- **Build/config** (`package.json`, `tsconfig*.json`, `container/`): review needed
- **Build/config** (`package.json`, `tsconfig*.json`, `runners/`): review needed
**Update paths** (you pick one):
- `merge` (default): `git merge upstream/<branch>`. Resolves all conflicts in one pass.
@@ -109,7 +109,7 @@ Show file-level impact from upstream:
Bucket the upstream changed files:
- **Skills** (`.claude/skills/`): unlikely to conflict unless the user edited an upstream skill
- **Source** (`src/`): may conflict if user modified the same files
- **Build/config** (`package.json`, `package-lock.json`, `tsconfig*.json`, `container/`, `launchd/`): review needed
- **Build/config** (`package.json`, `package-lock.json`, `tsconfig*.json`, `runners/`, `launchd/`): review needed
- **Other**: docs, tests, misc
Present these buckets to the user and ask them to choose one path using AskUserQuestion:

View File

@@ -44,7 +44,7 @@ npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts
# Verify: data/x-auth.json should exist after successful login
# 2. Rebuild container to include skill
./container/build.sh
./runners/build.sh
# Verify: Output shows "COPY .claude/skills/x-integration/agent.ts"
# 3. Rebuild host and restart service
@@ -181,7 +181,7 @@ if (!handled) {
---
**2. Container side: `container/agent-runner/src/ipc-mcp.ts`**
**2. Container side: `runners/agent-runner/src/ipc-mcp.ts`**
Add import after `cron-parser` import:
```typescript
@@ -196,21 +196,21 @@ Add to the end of tools array (before the closing `]`):
---
**3. Build script: `container/build.sh`**
**3. Build script: `runners/build.sh`**
Change build context from `container/` to project root (required to access `.claude/skills/`):
Change build context from `runners/` to project root (required to access `.claude/skills/`):
```bash
# Find:
docker build -t "${IMAGE_NAME}:${TAG}" .
# Replace with:
cd "$SCRIPT_DIR/.."
docker build -t "${IMAGE_NAME}:${TAG}" -f container/Dockerfile .
docker build -t "${IMAGE_NAME}:${TAG}" -f runners/Dockerfile .
```
---
**4. Dockerfile: `container/Dockerfile`**
**4. Dockerfile: `runners/Dockerfile`**
First, update the build context paths (required to access `.claude/skills/` from project root):
```dockerfile
@@ -220,12 +220,12 @@ COPY agent-runner/package*.json ./
COPY agent-runner/ ./
# Replace with:
COPY container/agent-runner/package*.json ./
COPY runners/agent-runner/package*.json ./
...
COPY container/agent-runner/ ./
COPY runners/agent-runner/ ./
```
Then add COPY line after `COPY container/agent-runner/ ./` and before `RUN npm run build`:
Then add COPY line after `COPY runners/agent-runner/ ./` and before `RUN npm run build`:
```dockerfile
# Copy skill MCP tools
COPY .claude/skills/x-integration/agent.ts ./src/skills/x-integration/
@@ -260,12 +260,12 @@ cat data/x-auth.json # Should show {"authenticated": true, ...}
### 3. Rebuild Container
```bash
./container/build.sh
./runners/build.sh
```
**Verify success:**
```bash
./container/build.sh 2>&1 | grep -i "agent.ts" # Should show COPY line
./runners/build.sh 2>&1 | grep -i "agent.ts" # Should show COPY line
```
### 4. Restart Service
@@ -403,7 +403,7 @@ If MCP tools not found in container:
```bash
# Verify build copies skill
./container/build.sh 2>&1 | grep -i skill
./runners/build.sh 2>&1 | grep -i skill
# Check container has the file
docker run nanoclaw-agent ls -la /app/src/skills/

View File

@@ -18,8 +18,8 @@ Two systemd services (`nanoclaw`, `nanoclaw-codex`) share the same codebase but
| `src/config.ts` | Trigger pattern, paths, intervals |
| `src/task-scheduler.ts` | Runs scheduled tasks |
| `src/db.ts` | SQLite operations |
| `container/agent-runner/` | Claude Code runner (Agent SDK) |
| `container/codex-runner/` | Codex runner (SDK, `codex exec` wrapper) |
| `runners/agent-runner/` | Claude Code runner (Agent SDK) |
| `runners/codex-runner/` | Codex runner (SDK, `codex exec` wrapper) |
| `groups/{name}/CLAUDE.md` | Per-group memory (isolated) |
## Skills

View File

@@ -60,7 +60,7 @@ nanoclaw/
│ └── channels/
│ ├── registry.ts # Channel self-registration system
│ └── discord.ts # Discord: mentions, images, typing, file attachments
├── container/
├── runners/
│ ├── agent-runner/ # Claude Code runner (Agent SDK, multimodal input)
│ ├── codex-runner/ # Codex runner (app-server JSON-RPC, auto-continue)
│ └── skills/ # Shared agent skills (browser, etc.)
@@ -77,7 +77,7 @@ nanoclaw/
### Codex App-Server Integration
The Codex runner (`container/codex-runner/`) communicates with `codex app-server` via JSON-RPC over stdio:
The Codex runner (`runners/codex-runner/`) communicates with `codex app-server` via JSON-RPC over stdio:
- **Session persistence**: Thread IDs stored in DB, sessions saved as JSONL on disk
- **Streaming**: `item/agentMessage/delta` notifications for real-time text
@@ -98,7 +98,7 @@ Bidirectional image support through Discord:
Skills are managed from a single source of truth (`~/.claude/skills/` on the server) and automatically synced to all agent session directories at process start:
- Claude Code sessions: `~/.claude/skills/` + project `container/skills/`
- Claude Code sessions: `~/.claude/skills/` + project `runners/skills/`
- Codex sessions: Same sources, synced to per-group `.codex/` directories
- Skills auto-register as slash commands (`/name`) in Claude Code and `$name` in Codex

View File

@@ -268,7 +268,7 @@ nanoclaw/
│ ├── task-scheduler.ts # Runs scheduled tasks when due
│ └── container-runner.ts # Spawns agents in containers
├── container/
├── runners/
│ ├── Dockerfile # Container image (runs as 'node' user, includes Claude Code CLI)
│ ├── build.sh # Build script for container image
│ ├── agent-runner/ # Code that runs inside the container

View File

@@ -6,7 +6,7 @@
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"build:runners": "cd container/agent-runner && npm install && npm run build && cd ../codex-runner && npm install && npm run build",
"build:runners": "cd runners/agent-runner && npm install && npm run build && cd ../codex-runner && npm install && npm run build",
"start": "node dist/index.js",
"dev": "tsx src/index.ts",
"typecheck": "tsc --noEmit",

View File

@@ -82,14 +82,14 @@ function prepareGroupEnvironment(
}
// Sync skills into each group's .claude/ session dir
// Sources: 1) user's global ~/.claude/skills 2) project workDir/.claude/skills 3) container/skills/
// Sources: 1) user's global ~/.claude/skills 2) project workDir/.claude/skills 3) runners/skills/
const workDirClaude = group.workDir
? path.join(group.workDir, '.claude')
: null;
const skillSources = [
path.join(os.homedir(), '.claude', 'skills'),
...(workDirClaude ? [path.join(workDirClaude, 'skills')] : []),
path.join(projectRoot, 'container', 'skills'),
path.join(projectRoot, 'runners', 'skills'),
];
const skillsDst = path.join(groupSessionsDir, 'skills');
for (const src of skillSources) {
@@ -128,7 +128,7 @@ function prepareGroupEnvironment(
// Determine runner directory
const agentType = group.agentType || 'claude-code';
const runnerDirName = agentType === 'codex' ? 'codex-runner' : 'agent-runner';
const runnerDir = path.join(projectRoot, 'container', runnerDirName);
const runnerDir = path.join(projectRoot, 'runners', runnerDirName);
// Build environment variables for the runner process
const envVars = readEnvFile([
@@ -222,10 +222,10 @@ function prepareGroupEnvironment(
}
}
// Sync skills into Codex session dir
// SSOT: ~/.claude/skills/ (shared with Claude Code) + container/skills/
// SSOT: ~/.claude/skills/ (shared with Claude Code) + runners/skills/
const codexSkillSources = [
path.join(os.homedir(), '.claude', 'skills'),
path.join(projectRoot, 'container', 'skills'),
path.join(projectRoot, 'runners', 'skills'),
];
const codexSkillsDst = path.join(sessionCodexDir, 'skills');
for (const src of codexSkillSources) {
@@ -245,7 +245,7 @@ function prepareGroupEnvironment(
// Inject nanoclaw MCP server into Codex config.toml
const mcpServerPath = path.join(
projectRoot,
'container',
'runners',
'agent-runner',
'dist',
'ipc-mcp-stdio.js',
@@ -333,7 +333,7 @@ export async function runAgentProcess(
if (!fs.existsSync(distEntry)) {
logger.error(
{ runnerDir },
'Runner not built. Run: cd container/agent-runner && npm install && npm run build',
'Runner not built. Run: cd runners/agent-runner && npm install && npm run build',
);
return {
status: 'error',