- Add .forgejo/workflows/ci.yml with matrix (ubuntu/windows), build, test, lint jobs
- Add .eslintrc.cjs with shell:true guard (no-restricted-syntax) and @typescript-eslint rules
- Add lint script to package.json and ESLint v8 devDependencies
- Add CI section to README.md
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>