Commit Graph

351 Commits

Author SHA1 Message Date
Eyejoker
29b78fc286 Refine Codex progress message tracking 2026-03-19 03:22:31 +09:00
Eyejoker
779d57c392 Stabilize paired-room orchestration and Codex app-server flow 2026-03-19 02:57:14 +09:00
Eyejoker
b710d4a33d chore: update claude-agent-sdk to 0.2.76, read dashboard config from .env
- Bump @anthropic-ai/claude-agent-sdk 0.2.68 → 0.2.76
- Read STATUS_CHANNEL_ID and USAGE_DASHBOARD from .env file
2026-03-16 05:54:17 +09:00
Eyejoker
385f3a0349 feat: block follow-up IPC after closeStdin with closingStdin flag
Prevent piping new messages to an agent that is shutting down.
Reset flag on new process start and cleanup.
2026-03-16 05:39:35 +09:00
Eyejoker
ea03956d0a feat: show session ID in dashboard status display
Add session label (last 8 chars) next to each group status.
Export buildStatusContent and DashboardOptions for testing.
2026-03-16 05:36:30 +09:00
Eyejoker
6f38f1cd63 feat: add SESSION_COMMAND_USER_IDS for admin session command access
Allow configured user IDs to execute session commands (/clear etc.)
in non-main groups. Adds isAdminSender check alongside isFromMe.
2026-03-16 05:14:38 +09:00
Eyejoker
7e77f37948 refactor: extract dashboard and message-runtime from index.ts
- Extract dashboard code into src/dashboard.ts
- Extract message runtime into src/message-runtime.ts
- Improve group-queue with better concurrency handling
- Update agent-runner with enhanced env/config passing
- Simplify DB operations and cleanup unused code
- Update README for Codex SDK architecture
2026-03-16 05:08:19 +09:00
Eyejoker
e23315ed48 feat: usage/server dashboard with progress bars and aligned labels 2026-03-15 22:37:40 +09:00
Eyejoker
9a6d9f4c4b revert: roll back DB merge, keep useful improvements
Fully revert DB merge patch (WAL, composite PK, SERVICE_ID in IPC/
router_state/sessions). Return to proven split-DB architecture.

Keep:
- Docker/Apple Container cleanup
- Usage dashboard CLAUDE_CODE_OAUTH_TOKEN fallback
- Codex runner heartbeat
- Agent-runner stderr timeout reset
2026-03-15 22:35:53 +09:00
Eyejoker
e2d6476cdf 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.
2026-03-15 19:29:23 +09:00
Eyejoker
6f4b6f8df7 feat: prepare DB for shared access (WAL, service partitioning)
Phase 0-2 of data unification:
- Enable WAL mode + busy_timeout for safe concurrent access
- router_state: keys prefixed with SERVICE_ID (lazy migration)
- sessions: composite PK (group_folder, agent_type)
- registered_groups: filtered by SERVICE_AGENT_TYPE on load
- Logger: service name tag for unified log streams

All changes are backward-compatible with the current split setup.
Actual directory merge (Phase 3-4) is a separate step.
2026-03-15 19:26:34 +09:00
Eyejoker
26783e520e refactor: switch codex runner from app-server to SDK
Replace raw JSON-RPC app-server protocol with @openai/codex-sdk.
The SDK wraps `codex exec` which ensures complete task execution per
turn, fixing the issue where app-server mode ended turns prematurely
(agent saying "하겠습니다" without doing the work).

Also fix AGENTS.md copy in agent-runner (was copying instructions.md
which Codex CLI doesn't read).
2026-03-14 22:42:47 +09:00
Eyejoker
66bc3c6ff1 fix: skip discord-codex channel registration on codex service
The codex service uses its own DISCORD_BOT_TOKEN via systemd
EnvironmentFile, so the discord-codex secondary channel is only
relevant for the primary service. Removes spurious credential
missing warning on codex service startup.
2026-03-14 19:13:16 +09:00
Eyejoker
35356dd8a7 refactor: remove token-refresh, use env-based auth only
Delete token-refresh.ts and credentials.json sync. Auth is now
via CLAUDE_CODE_OAUTH_TOKEN in .env (1-year setup-token).
No more auto-refresh loop or credentials.json dependency.
2026-03-14 19:09:40 +09:00
Eyejoker
3546a35354 refactor: skip token auto-refresh when using env-based auth
When CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY is set in .env,
the credentials.json refresh loop is unnecessary. setup-token
generates a 1-year token, making auto-refresh redundant.
2026-03-14 19:01:30 +09:00
Eyejoker
e4eca65c7c feat: suppress Discord link embed previews on bot messages
Add MessageFlags.SuppressEmbeds to all send() calls so URLs in
agent responses don't generate large preview cards.
2026-03-14 03:29:26 +09:00
Eyejoker
f388323987 chore: increase text file inline limit from 8000 to 32000 chars
11k char deployment logs were getting truncated, cutting off the
actual error. 32k is safe for 200k context window.
2026-03-14 02:34:34 +09:00
Eyejoker
ae1b37694e feat: inline text file attachments from Discord
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.
2026-03-14 02:32:14 +09:00
Eyejoker
16ab231df4 docs: update README, CLAUDE.md, and skills for Groq Whisper
- Add GROQ_API_KEY to README env vars and authentication steps
- Add Voice Transcription section to CLAUDE.md
- Update setup skill with Groq voice transcription setup step
- Rewrite add-voice-transcription skill for Groq-first approach
2026-03-14 02:02:37 +09:00
Eyejoker
b8421b659d feat: switch audio transcription from OpenAI Whisper to Groq Whisper
Groq runs the same whisper-large-v3-turbo model at 200x+ real-time speed.
Falls back to OpenAI Whisper if GROQ_API_KEY is not set.
Logs elapsed time per transcription for monitoring.
2026-03-14 01:51:38 +09:00
Eyejoker
b8292e14a1 feat: shared transcription cache to avoid duplicate Whisper API calls
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.
2026-03-14 01:40:35 +09:00
Eyejoker
7a726c335d feat: purge status channel on startup for clean dashboard
- Add purgeChannel() to Channel interface and DiscordChannel
- Uses bulkDelete for recent messages, individual delete for old ones
- Called once at startup before creating fresh dashboard messages
2026-03-14 00:52:41 +09:00
Eyejoker
d06a835163 fix: usage dashboard - remove title, use system uptime, handle null limitName, drop seconds from timestamp
- Remove "📊 Usage 보고" title line
- Use os.uptime() instead of process.uptime() for actual server uptime
- Handle null limitName in Codex rate limits (fallback to limitId or 'Codex')
- Fix Codex usage parsing: extract from rateLimitsByLimitId object
- Fix formatResetKST to handle unix timestamps (number type)
- Remove seconds from update timestamp display
2026-03-14 00:50:29 +09:00
Eyejoker
26d50933de fix: re-throw editMessage errors so dashboard can reset message ID 2026-03-14 00:45:25 +09:00
Eyejoker
9e36d9d8d2 style: prettier formatting for discord test 2026-03-14 00:44:02 +09:00
Eyejoker
e0fcf836f4 feat: gate usage dashboard behind USAGE_DASHBOARD env var
Only one service needs to show system resources + API usage.
Set USAGE_DASHBOARD=true on the primary service only.
2026-03-13 23:51:31 +09:00
Eyejoker
cf75a1b993 feat: API usage in live dashboard + Discord channel names
- Fetch Claude Code usage via OAuth API (five_hour/seven_day)
- Fetch Codex usage via app-server JSON-RPC (rateLimits/read)
- System resources: CPU%, memory, disk in GB with emoji thresholds
- Show actual Discord channel names (#name) instead of DB-stored names
- Guard against overlapping usage updates (async API calls)
2026-03-13 23:48:36 +09:00
Eyejoker
7dcb3fe1e4 feat: status dashboard categories/ordering + live usage dashboard
- 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)
2026-03-13 23:42:45 +09:00
Eyejoker
27d4ea05dc feat: add status dashboard for live agent monitoring
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
2026-03-13 23:05:32 +09:00
Eyejoker
6a65136ff2 style: collapse multiline parseInt in config 2026-03-13 22:44:58 +09:00
Eyejoker
37188bd98e refactor: remove auto-continue from codex runner
Auto-continue was punishing the model for thinking — text-only turns
were treated as failures and re-prompted up to 5 times with aggressive
"execute now" messages. This made Codex overly compliant and suppressed
critical thinking.

Now each turn result is delivered directly. The model decides whether
to think, push back, or execute.
2026-03-13 22:43:06 +09:00
Eyejoker
8bd5f71a95 chore: remove container legacy references
- Delete container/build.sh (Docker build script, no longer used)
- Remove "auth" npm script (whatsapp-auth.ts doesn't exist)
- Remove CONTAINER_* env var fallbacks from config.ts
- Update CLAUDE.md: container-runner → agent-runner, fix descriptions
- Rename MAX_CONCURRENT_CONTAINERS → MAX_CONCURRENT_AGENTS in systemd
2026-03-13 20:22:17 +09:00
Eyejoker
60de59627c docs: complete setup guide with step-by-step instructions
Add clone, install, CLI auth, env files, systemd templates,
channel registration with sqlite examples. Move secrets to
EnvironmentFile instead of inline systemd Environment.
2026-03-13 20:04:46 +09:00
Eyejoker
1897b56760 docs: clean up README, remove upstream comparison table
Present as standalone project. Keep origin attribution in header
and license. Add key features summary.
2026-03-13 19:59:06 +09:00
Eyejoker
d295eb7aaf docs: update README to reflect current codebase
- container-runner.ts → agent-runner.ts
- Add missing files: group-queue, group-folder, router, sender-allowlist,
  session-commands, channels/registry
- Add image handling, skill sync, auto-continue, GroupQueue sections
- Add 'both' agent type, data/attachments directory
- Add npm test to development commands
2026-03-13 19:56:19 +09:00
Eyejoker
d4e2d78585 fix: clean up empty bullet points after stripping image links 2026-03-13 19:32:34 +09:00
Eyejoker
288c3c63c7 feat: convert non-image markdown links to readable filenames in Discord
[BuildPanel.tsx](/long/path#L320) → `BuildPanel.tsx:320`
Keeps Discord output clean since local paths aren't clickable anyway.
2026-03-13 19:28:17 +09:00
Eyejoker
3cff07cc2e refactor: remove SendImage tag, rely on natural markdown link parsing
LLMs naturally produce [name.png](/path) markdown links for images.
Parse only this pattern instead of teaching agents a custom tag.
Remove Image Handling sections from instructions.
2026-03-13 19:24:49 +09:00
Eyejoker
fd5c81401d feat: also parse markdown image links for Discord image sending
Support [name.png](/path) format in addition to [SendImage: /path].
LLMs naturally produce markdown links, so both patterns are recognized.
Only absolute paths with image extensions are matched.
2026-03-13 19:23:49 +09:00
Eyejoker
a1db0e2161 feat: support agent-to-user image sending via Discord
Parse [SendImage: /absolute/path] tags from agent responses and send
them as Discord file attachments alongside the text message.
2026-03-13 19:18:09 +09:00
Eyejoker
8a0e407526 feat: add Discord image receiving for Claude Code and Codex agents
Download Discord image attachments to DATA_DIR/attachments/ and pass
them as multimodal content blocks to both agent types:
- Claude Code: base64 ImageBlockParam via Agent SDK MessageParam
- Codex: localImage input block via app-server turn/start
2026-03-13 19:15:23 +09:00
Eyejoker
a10cf049ca feat: auto-continue turns when Codex responds without tool execution
Track whether tool execution occurred during each turn via approval
request notifications. If a turn completes with only text (no commands
or file changes), automatically start a follow-up turn nudging Codex
to execute rather than just describe plans. Max 5 auto-continues per
user message to prevent infinite loops.

Also strengthen instructions.md with execution-first policy.
2026-03-13 18:04:13 +09:00
Eyejoker
09a089ccaf refactor: unify skill sync, remove commands directory
- Remove commands/ sync from agent-runner (skills/ is SSOT for both agents)
- Remove ~/.codex/skills/ as source (use ~/.claude/skills/ only)
- Codex uses $skill prefix, Claude Code uses /skill — both read from skills/
- Minor formatting fixes in config.ts, group-queue.test.ts, index.ts
2026-03-13 17:03:28 +09:00
Eyejoker
922ec60517 fix: sync Claude Code skills/commands to Codex sessions
Codex sessions now also receive skills and commands from ~/.claude/
in addition to ~/.codex/, so both agents share the same tool set
(patch, linear, sentry, coolify, exa, playwright, sprite, etc.)
2026-03-13 16:45:36 +09:00
Eyejoker
bd7f4408ae refactor: rename container references to agent across codebase
- container-runner.ts → agent-runner.ts
- ContainerInput/Output → AgentInput/Output
- ContainerConfig → AgentConfig
- runContainerAgent → runAgentProcess
- CONTAINER_TIMEOUT → AGENT_TIMEOUT (with env fallback)
- MAX_CONCURRENT_CONTAINERS → MAX_CONCURRENT_AGENTS
- containerName → processName, isTaskContainer → isTaskProcess
- DB column container_config kept as-is (backwards compat)
2026-03-13 16:18:36 +09:00
Eyejoker
35277cea0a feat: codex app-server integration, token sync fix, typing fix
- Rewrite codex-runner to use `codex app-server` JSON-RPC instead of
  `codex exec`. Supports streaming (item/agentMessage/delta), session
  persistence (thread/start, thread/resume), and mid-turn message
  injection (turn/steer with IPC polling during execution).
- Fix token refresh not syncing to per-group session directories,
  causing 401 errors on running agents.
- Fix typing indicator staying on when codex returns null result
  by always clearing typing on any streaming callback.
- Update README and CLAUDE.md to reflect dual-service architecture,
  host process mode, and codex app-server integration.
2026-03-13 16:03:08 +09:00
Eyejoker
0515edc93d feat: OAuth auto-refresh, Codex session resume, MCP injection, and secret sanitization
- Add token-refresh module that auto-renews Claude OAuth tokens 30min before expiry
- Fix Codex session loss on service restart by resuming previous sessions
- Inject nanoclaw MCP server into Codex config.toml for send_message/schedule_task
- Sanitize ANTHROPIC_API_KEY and CLAUDE_CODE_OAUTH_TOKEN from Codex subprocess env
2026-03-12 02:47:24 +09:00
Eyejoker
3fd9ce18b5 feat: sync skills to per-group Codex session dirs 2026-03-11 20:06:38 +09:00
Eyejoker
03c1a67649 fix: sync instructions.md to per-group Codex session dirs 2026-03-11 19:01:09 +09:00
Eyejoker
2cbaa47101 fix: use NANOCLAW_IPC_DIR env var in MCP server instead of hardcoded /workspace/ipc 2026-03-11 18:48:06 +09:00