Add sanitizeForDiscord() in src/runtime/sanitize.ts.
Router applies sanitizer to all channel.send() calls.
Prevents path/token leaks into Discord channels.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all CREATE TABLE/INDEX DDL from database.ts to schema.sql.
database.ts loads and executes schema.sql via db.exec().
Add integration test verifying idempotent schema init.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add DisclawConfigSchema and AgentYamlSchema with Zod validation.
loader.ts and identity.ts validate external data at parse time.
Clear error messages with field name and expected type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all console.* calls in src/ with pino child-loggers.
Add rootLogger + childLogger(component) in src/runtime/logger.ts.
pino-pretty used as dev transport only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Semaphore class in src/runtime/concurrency.ts.
Runner acquires/releases slot around claude spawn.
Default cap: 4, configurable via disclaw.yaml max_concurrent_agents.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--bare disables OAuth/keychain auth and requires ANTHROPIC_API_KEY,
breaking Claude Pro/Max subscriptions. CLAUDE.md isolation is now
achieved structurally: workspaces live under ~/.disclaw/workspaces/
(outside the repo) so walk-up never reaches DisClaw's CLAUDE.md.
Update integration test to assert --bare is absent and verify correct
args (-p, --output-format json). Fix sanitize-env tests to reflect
CI=true removal (was breaking OAuth headless-mode detection).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements acquireLock() in src/runtime/lockfile.ts that writes a PID-stamped
lock file under workspaces_root, detects live vs stale locks via process.kill(pid, 0),
and returns a release function. src/index.ts acquires the lock before DB init and
releases it in the graceful-shutdown handler. Four unit tests cover acquire, duplicate-
acquire rejection, stale-lock recovery, and release.
Prevents CLAUDE.md walk-up through parent directories by passing --bare
to every Claude CLI invocation, and explicitly injects the workspace
CLAUDE.md via --append-system-prompt-file so agent identity is isolated.
Adds fake-claude fixture and integration test to verify flags are present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces src/runtime/env.ts with a pure sanitizedEnv() function that
strips DISCORD_BOT_TOKEN, DISCORD_CLIENT_SECRET, DISCORD_PUBLIC_KEY, and
all keys matching /^(DISCLAW_SECRET_|SECRET_|TOKEN_|API_KEY_?)/i before
passing the environment to spawned Claude Code child processes. Adds
optional env_blocklist field to DisclawConfig. Runner now passes
DISCLAW_AGENT_NAME and respects the blocklist.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>