Add RunResult type in src/agent/types.ts (success|timeout|cli-error|parse-error).
Runner resolves instead of rejects for all error cases.
Router handles all four status variants explicitly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve conflict in src/router.ts: keep both splitForDiscord (DIS-105)
and sanitizeForDiscord (DIS-102). Apply splitForDiscord to the already
sanitized response text.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The root cause was twofold:
1. Raw (unsanitized) agent responses were stored in the conversation
history DB. On subsequent calls, these paths were fed back to the
agent as context, causing it to reproduce full paths regardless of
Discord-side sanitization.
2. repoRoot (workspace_path) was not passed to sanitizeForDiscord,
so workspace-specific paths were only partially masked via the
home directory fallback.
Fix: sanitize the full response once before both sending to Discord
and storing in the DB. Pass workspace_path as repoRoot for precise
path replacement. Add Windows path tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Add splitForDiscord() in src/discord/split.ts.
Fences are properly closed and reopened across chunk boundaries.
Router uses splitForDiscord instead of internal splitMessage().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>