A final answer over 2000 chars edited straight into the tracked progress
message was rejected by Discord (content[BASE_TYPE_MAX_LENGTH]), leaving a
failed edit + stale progress stub before the send fallback. editMessage
now edits the tracked message with the first 2000-char chunk and sends the
remainder as follow-up messages, so long finals land cleanly in order.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolves the gitea/main <-> deployed-line merge:
- DB migrations: renumber gitea's colliding 019/020 to 021/022
(reviewer_failure_count -> v21, turn_progress_text_compat -> v22) so all
four migrations have distinct versions; update ordered list + bootstrap test.
- paired_tasks INSERT: add the missing VALUES placeholder so both new columns
(reviewer_failure_count + arbiter_intervention_count) bind (26 cols/values).
- index.ts: drop duplicate startUsagePrimer import from the auto-merge.
- discord output: keep the deployed pipeline (attachment rejection notice) and
call sanitizeForOutbound at the channel boundary so prose escaping done in
prepareDiscordOutbound is not double-applied; keep gitea's reviewer
silent-failure cap + router markdown-escape helpers.
- usage-primer/codex-warmup: keep the dawn-hold removal over gitea's primer.
Full test suite: only pre-existing env/bun-path failures remain; no merge regressions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Agent-generated files written to an arbitrary working path (e.g. TTS audio
under /home/claude/jarvis-tts) were rejected by validateOutboundAttachments as
"outside-allowed-dirs". The rejection was only logged; the MEDIA: directive had
already been stripped from the text, so the user got a message claiming a file
was attached with no file and no error.
- Stage attachments outside the room's allowed dirs into a safe per-group dir
(data/attachments/outbound/<group>) at the universal delivery choke point, so
the path delivery uses and revalidates is one the validator accepts. Files
already inside an allowed dir are untouched, preserving isolation checks.
- Surface any still-rejected attachment in the visible Discord body via
appendRejectionNotice, so delivery can never again silently drop a file.
Verified: outbound-attachments 22/22, discord 46/46 (incl. new integration test
asserting the notice lands in the sent body), final-delivery 5/5, tsc clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
One-off script that logs in with each configured Discord bot token and prints
the bot member's effective permission bits per guild, so capability claims can
be verified empirically instead of inferred from intents.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Replace the naive byte-slice chunk loop with a fence-aware chunkForDiscord()
splitter: prefers newline boundaries, re-closes any open ``` fence at the end
of a chunk and reopens it with the same language tag at the start of the next,
and is surrogate-pair safe. Adds 10 unit tests for the seam, multi-fence
documents, surrogate pairs, and single-line overflow.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* feat: refresh dashboard settings UX and Codex feature toggles
Improve settings/tasks mobile layout, model effort validation by agent type, and preset models for GPT 5.5 and Opus 4.7. Store Codex fast mode and goals in config.toml with Claude fastMode session sync and updated docs for Codex 0.133.
Co-authored-by: Cursor <cursoragent@cursor.com>
* style: apply pre-commit formatting after dashboard settings commit
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Major reliability improvements to the message processing pipeline:
- Add messages.seq monotonic cursor replacing timestamp-based cursors,
preventing message loss from timestamp collisions with LIMIT queries
- Add work_items table separating agent production from delivery,
enabling delivery retry without re-running the agent
- Propagate Discord send failures instead of silently swallowing them
- Add Claude 429 → Kimi K2.5 automatic provider fallback with cooldown
- Fix follow-up turn state reset in live index.ts path (not just
message-runtime.ts) to prevent final output from being lost
- Add restart context tracking for graceful restart announcements
- Lazy migration from timestamp cursors to seq cursors for existing data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Download and inline content of .txt and other text-based file
attachments instead of showing just the filename placeholder.
Handles long copy-pastes that Discord auto-converts to .txt files.
Truncates at 8000 chars with a note.
Both services (nanoclaw + nanoclaw-codex) now share cache/transcriptions/
directory. When one service transcribes audio, the other reads from cache
instead of making a second Whisper API call. Uses .pending file to
coordinate concurrent transcription attempts.
- Add getChannelMeta to Discord channel (batch guild fetch)
- Status dashboard groups by Discord category, sorts by position
- Add live usage dashboard (CPU, memory, disk, uptime) with message edit
- Fix 4 failing discord.test.ts tests (sendMessage format, image fetch mock)
Dedicated Discord channel shows per-group agent status with live
elapsed time. Single message is edited every 10s instead of spamming.
- GroupQueue tracks startedAt timestamps and exposes getStatuses()
- Channel interface gets editMessage/sendAndTrack for message editing
- STATUS_CHANNEL_ID env var to configure the dashboard channel
- Shows processing/idle/waiting/inactive per registered group
- Rewrite container-runner.ts to spawn node processes directly instead
of Docker/Apple Container
- Runner paths configurable via env vars (NANOCLAW_GROUP_DIR, etc.)
with container-path defaults for backwards compat
- Pass real credentials directly (no credential proxy needed)
- Remove ensureContainerSystemRunning() and startCredentialProxy()
from startup
- Add build:runners script for building agent-runner and codex-runner
- Fix TS strict mode errors in agent-runner ipc-mcp-stdio.ts
- Add Codex as alternative agent type (agentType: 'codex' per group)
- Codex container runner with session resume and 100-turn limit
- Dual Discord bot support (DISCORD_BOT_TOKEN + DISCORD_CODEX_BOT_TOKEN)
- Each bot handles only its agentType's registered groups
- Discord typing indicator refreshes every 8s (was single-shot, expired after ~10s)
- Agent runner 100-turn limit to prevent infinite bot-to-bot loops
- Apple Container runtime support (convert-to-apple-container skill)
- Session commands (/compact) support
- DB migration for agent_type column