Commit Graph

731 Commits

Author SHA1 Message Date
gavrielc b591d7ce96 refactor: move destinations from JSON file into inbound.db
The per-session destination map was being written as a sidecar JSON file
(/workspace/.nanoclaw-destinations.json) — inconsistent with the rest of
v2, where all host↔container IO goes through inbound.db / outbound.db.

Move it into a `destinations` table in INBOUND_SCHEMA. The host writes
it before every container wake AND on demand (e.g. after create_agent)
so the creator sees the new child destination mid-session without a
restart. The container queries the table live on every lookup — no
cache, no staleness window.

- src/db/schema.ts: add `destinations` table to INBOUND_SCHEMA.
- src/session-manager.ts: writeDestinationsFile → writeDestinations,
  writes via DELETE + INSERT inside a transaction.
- src/delivery.ts: create_agent handler calls writeDestinations on the
  creator's session after inserting the new destination rows.
- container/agent-runner/src/destinations.ts: queries inbound.db
  directly in every findByName/getAllDestinations/findByRouting call.
  No more cache. No setDestinationsForTest (obsolete). No fs import.
- container/agent-runner/src/index.ts and mcp-tools/index.ts: remove
  loadDestinations() calls — no longer needed.
- Test helper initTestSessionDb creates the destinations table.
  Integration test inserts a row directly instead of mocking the cache.

No backwards compatibility: sessions predating the schema update must
be recreated. This is fine on the v2 branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:45:53 +03:00
gavrielc 09e1861a22 feat: single-destination shortcut — no wrapping needed when there's only one
When an agent has exactly one configured destination, wrapping output in
<message to="..."> blocks is unnecessary. Plain text goes to the sole
destination automatically. This preserves the simple "just reply" flow
for the common case of one user on one channel.

Applies in three places:

- System prompt addendum: single-destination case gets a simplified
  explanation ("your messages are delivered to X, just write directly").
  Multi-destination case keeps the <message to="..."> syntax docs.

- Main output parser: if zero <message> blocks are found and there is
  exactly one destination, the entire cleaned text (with <internal>
  stripped) is sent to that destination.

- send_message / send_file MCP tools: `to` parameter is now optional.
  With one destination, omitted defaults to it. With multiple, omitting
  returns an error listing the options.

Multi-destination behavior is unchanged — explicit <message to="..."> is
still required, and untagged text is still scratchpad.

groups/global/CLAUDE.md updated to describe both cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:36:09 +03:00
gavrielc 67f081671d style: prettier formatting fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:31:45 +03:00
gavrielc e83ffbc103 feat: named destinations + permission enforcement + fire-and-forget self-mod
Replaces implicit routing context (NANOCLAW_PLATFORM_ID env vars) with
per-agent named destination maps. Agents reference channels and peer
agents by local names; the host re-validates every outbound route against
a new agent_destinations table that is both the routing map and the ACL.

Model changes:
- New migration 004 adds agent_destinations (agent_group_id, local_name,
  target_type, target_id). Backfills from existing messaging_group_agents.
- Host writes /workspace/.nanoclaw-destinations.json before every container
  wake so admin changes take effect on next start.
- Container loads map at startup, appends system-prompt addendum listing
  available destinations and the <message to="name">…</message> syntax.
- Agent main output is parsed for <message to="..."> blocks; each block
  becomes a messages_out row with routing resolved via the local map.
  Untagged text and <internal>…</internal> are scratchpad (logged only).
- send_message MCP tool now takes `to` (destination name) instead of raw
  routing fields. send_to_agent deleted (redundant — agents are just
  destinations). send_file/edit_message/add_reaction route via map too.
- Inbound formatter adds from="name" attribute via reverse-lookup so the
  agent sees a consistent namespace in both directions.

Permission enforcement:
- Host checks hasDestination() before every channel delivery AND every
  agent-to-agent route. Unauthorized messages dropped and logged.
- routeAgentMessage simplified: ~15 lines, no JSON parse, content copied
  verbatim (target formatter resolves the sender via its own local map).
- create_agent is admin-only, checked at both the container (tool not
  registered for non-admins) and the host (re-check on receive). Inserts
  bidirectional destination rows so parent↔child comms work immediately.
  Includes path-traversal guard on folder name.

Self-modification cleanup:
- add_mcp_server now requires admin approval (previously had none).
- install_packages validates package names on BOTH sides (container tool
  + host receiver) with strict regex. Max 20 packages per request.
- All three self-mod tools are fire-and-forget: write request, return
  immediately with "submitted" message. Admin approval triggers a chat
  notification to the requesting agent — no tool-call polling, no 5-min
  holds. On rebuild/mcp_server approval, the container is killed so the
  next wake picks up new config/image.
- Approval delivery extracted into requestApproval() helper (the one
  place where three call sites were literally identical).

Also folded in the phase-1 dynamic import cleanup (create_agent no longer
does `await import('./db/agent-groups.js')`) and removes NANOCLAW_PLATFORM_ID
/ CHANNEL_TYPE / THREAD_ID env-var routing entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:31:37 +03:00
gavrielc 4004a6b284 docs: add self-customize skill and refine communication guidance
Self-customize skill lives in container/skills/ so it's loaded into the
agent container at runtime. Documents the builder-agent pattern with
diff size limits for safer self-modification.

CLAUDE.md communication section now has three tiers (short / longer /
long-running) instead of a single blanket rule — agents should
acknowledge upfront on longer work and update before slow operations,
but stay silent on quick tasks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:02:32 +03:00
gavrielc 6eb81b5737 style: prettier formatting fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 01:11:06 +03:00
gavrielc d8fbd3b239 feat: agent-to-agent communication, dynamic agent creation, self-modification tools
Agent-to-agent: host routes messages with channel_type='agent' to target
agent's inbound.db, enriches with sender info, wakes target container.
Bidirectional routing works via inherited routing context.

Dynamic agents: create_agent MCP tool + system action handler creates
agent groups, folders, and optional CLAUDE.md on the fly.

Self-modification: install_packages (apt/npm, requires admin approval),
add_mcp_server (no approval), request_rebuild (builds per-agent-group
Docker image with approved packages). Approval flow reuses interactive
card infrastructure with pending_approvals table.

Also includes fixes from prior session: attachment download, reply context
extraction, message editing (platform message ID tracking), delivery retry
limits, and card update on button click.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 01:11:06 +03:00
Gabi Simons 9af9bc947a fix(discord-v2): document required DISCORD_PUBLIC_KEY and APPLICATION_ID
The Discord adapter fails to start without all three env vars. Also
fix platform ID format docs to show discord:{guildId}:{channelId}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:57:28 +00:00
gavrielc 69939b7774 docs: fix v2 checklist accuracy — pre-agent scripts, typing, stubs
- Pre-agent scripts: [~] → [ ] (formatter references scriptOutput but
  no execution logic exists)
- Add typing indicator as completed (triggerTyping in router)
- Remove "stub exists" from register_group/reset_session (no stubs found)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:54:54 +03:00
gavrielc e2dbc35a15 docs: add auto-onboarding to v2 checklist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:52:35 +03:00
gavrielc 5a309a0e25 fix: only send onboarding message on first wiring, not re-registration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:49:58 +03:00
gavrielc 4a999ec973 feat: auto-onboarding when a channel is registered
After wiring a channel to an agent group, register.ts writes a task
message to the session that triggers the /welcome container skill.
The agent introduces itself immediately — the user sees typing and
then a greeting without having to send a message first.

Uses kind 'task' (not 'system') so the poll loop picks it up normally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:48:56 +03:00
gavrielc a2badbd525 fix: normalize platform ID at registration, not router lookup
Channel adapters prefix platform IDs with their channel type
(e.g. "telegram:123"). Normalize in register.ts so the DB always
stores the canonical format. Removes fallback lookup from router.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:41:07 +03:00
gavrielc 9f5c37fc4c fix: handle platform ID prefix mismatch in router, not register
Move prefix handling from register.ts to router.ts. Users register with
raw platform IDs (what they naturally have), adapters send prefixed IDs
(their internal format). Router now tries stripping the channel type
prefix when the exact lookup fails, matching either format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:39:40 +03:00
gavrielc 6941e37366 fix: auto-prefix platform IDs in register.ts to match Chat SDK format
Chat SDK adapters use prefixed platform IDs (e.g. "telegram:6037840640",
"discord:guildId:channelId") but users provide raw IDs during setup.
Without the prefix, the router can't match the registered messaging group
to incoming messages and silently drops them.

register.ts now auto-prefixes with the channel type if not already present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:38:23 +03:00
gavrielc d656b5ccc1 fix: Chat SDK bridge delivery and typing for non-Discord adapters
- Use platformId directly as thread ID in deliver() and setTyping()
  instead of calling encodeThreadId with Discord-shaped args — platformId
  is already in the adapter's encoded format (e.g. "telegram:6037840640")
- Add triggerTyping() in delivery.ts, call from router on message route
- Enable Telegram channel in barrel
- Verified E2E: Telegram message in → agent → typing indicator → response

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:36:45 +03:00
gavrielc 57a6491c7e v2: channel isolation model, manage-channels skill, refactored channel skills
- Add three-level isolation model (shared session, same agent, separate agent)
  with agent-shared session mode for cross-channel shared sessions
- Create /manage-channels skill for wiring channels to agent groups
- Refactor all 12 v2 channel skills: lean SKILL.md + VERIFY.md + REMOVE.md
  with structured Channel Info section for platform-specific metadata
- Create /add-discord-v2 skill (was missing)
- Add step 5a to setup SKILL.md invoking /manage-channels after channel install
- Update setup/verify.ts to check all 12 channel token types
- Add docs/v2-isolation-model.md explaining the isolation model
- Update v2-checklist.md and v2-setup-wiring.md to reflect completed work

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:19:19 +03:00
gavrielc ed76d51e0b docs: add v2 setup wiring status and remaining work
Detailed status document for next session: what's done (two-DB split,
OneCLI, barrel, register.ts), what's not (channel skills don't call
register, no group creation step in setup, v1 add-discord incompatible).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:28:46 +03:00
gavrielc 1dc5750ca3 fix: uncomment Discord import in channel barrel
Discord was directly imported in src/index.ts before the barrel wiring.
Moving to the barrel without uncommenting it broke Discord.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:24:06 +03:00
gavrielc e7514edd35 fix: wire v2 setup flow — barrel import, registration, verification
- Import channel barrel from src/index.ts so channel skills that
  uncomment lines in src/channels/index.ts actually execute
- Rewrite setup/register.ts to create v2 entities (agent_groups,
  messaging_groups, messaging_group_agents) in data/v2.db instead
  of v1's store/messages.db
- Fix setup/verify.ts to check v2 central DB for registered groups
- Add prominent "MESSAGE DROPPED" warnings in router when no agent
  groups are wired, with actionable guidance

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:23:23 +03:00
gavrielc b76fd425c8 style: prettier formatting fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:18:31 +03:00
gavrielc 82cb363f84 v2: split session DB into inbound/outbound for write isolation
Eliminates SQLite write contention across the host-container mount
boundary by splitting the single session.db into two files, each with
exactly one writer:

  inbound.db  — host writes (messages_in, delivered tracking)
  outbound.db — container writes (messages_out, processing_ack)

Key changes:
- Host uses even seq numbers, container uses odd (collision-free)
- Container heartbeat via file touch instead of DB UPDATE
- Scheduling MCP tools now emit system actions via messages_out
  (host applies them to inbound.db during delivery)
- Host sweep reads processing_ack + heartbeat file for stale detection
- OneCLI ensureAgent() call added (was missing from v2, caused
  applyContainerConfig to reject unknown agent identifiers)

Verified: tsc clean, 327 tests pass, real e2e through Docker works.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:17:31 +03:00
gavrielc 320176e7e8 fix: remaining -v2 references in scripts, add v1 channels barrel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:44:06 +03:00
gavrielc 2b64fec0e6 fix: clean up iMessage adapter type compatibility
Replace `as never` cast with proper polyfill for channelIdFromThreadId.
Narrow GatewayAdapter cast to only the gateway code path in bridge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:42:49 +03:00
gavrielc 9486d56b01 v2: make v2 the main entry point, move v1 to src/v1/
- Move all v1 files (index, router, container-runner, db, ipc, types,
  logger, channels/registry, and all utilities) to src/v1/ as a
  fully self-contained archive with no shared dependencies
- Rename v2 files to remove -v2 suffix (index-v2.ts → index.ts, etc.)
- Update all imports across v2 source, tests, and setup files
- Migrate shared utilities (config, env, container-runtime, mount-security,
  timezone, group-folder) from pino logger to v2 log module
- Migrate setup/ files from logger to log with argument order swap
- Container agent-runner: move v1 entry to v1/, rename v2 to index.ts
- Update setup skill to offer all 13 v2 channels
- Install all Chat SDK adapter packages
- dist/index.js now runs v2; dist/v1/index.js runs v1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:40:36 +03:00
gavrielc 12af451069 v2: add Chat SDK channel adapters and skills for 11 platforms
Thin wrapper adapters + SKILL.md for Slack, Telegram, GitHub, Linear,
Google Chat, Teams, WhatsApp Cloud API, Resend, Matrix, Webex, iMessage.
All follow the same pattern as discord-v2.ts: readEnvFile → create*Adapter
→ createChatSdkBridge → registerChannelAdapter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:26:33 +03:00
gavrielc 8a06b01646 v2: SQLite state adapter, admin commands, compact feedback
- Replace in-memory Chat SDK state with SqliteStateAdapter — thread
  subscriptions now persist across restarts
- Add migration 002 for chat_sdk_kv, subscriptions, locks, lists tables
- Handle /clear in agent-runner (reset sessionId) — SDK has
  supportsNonInteractive:false for this command
- Pass /compact, /context, /cost, /files through to SDK as admin commands
- Skip admin commands in follow-up poll so they start fresh queries
- Emit compact_boundary events as user-visible feedback messages
- Pass NANOCLAW_ADMIN_USER_ID and NANOCLAW_ASSISTANT_NAME to containers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 03:58:35 +03:00
gavrielc c31bb02c06 v2 phase 5: pending questions with interactive cards
End-to-end ask_user_question flow:
- Agent MCP tool writes question card to messages_out
- Host delivery creates pending_questions row, delivers as Discord Card with buttons
- Local webhook server receives Gateway INTERACTION_CREATE events
- Acknowledges interaction + updates card to show selected answer
- Routes response back to session DB as system message
- MCP tool poll picks up response and returns to agent

Key fixes:
- Poll loop now skips system messages (reserved for MCP tool responses)
- Gateway listener uses webhookUrl forwarding mode for interaction support
- Button custom_id encodes questionId + option text for self-contained routing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 03:26:16 +03:00
gavrielc c348fabf22 v2 phase 5: scheduling fixes, media handling, command processing
- Host sweep: fix DELETE journal mode, busy_timeout, seq in recurrence INSERT
- Outbound files: delivery reads from outbox dir, passes buffers to adapter,
  cleans up after delivery. Chat SDK bridge sends files via postMessage.
- Inbound attachments: formatter includes attachment info in prompts
- Commands: categorize /commands as admin, filtered, or passthrough.
  Admin commands check sender against NANOCLAW_ADMIN_USER_ID.
  Filtered commands silently dropped. Passthrough sent raw to agent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 02:59:33 +03:00
gavrielc afbc20a6c4 v2 phase 4+5: Discord via Chat SDK, expanded MCP tools, message seq IDs
- Chat SDK bridge + Discord adapter (gateway listener, message routing)
- MCP tools refactored into modular structure: core (send_message, send_file,
  edit_message, add_reaction), scheduling (schedule/list/cancel/pause/resume
  tasks), interactive (ask_user_question, send_card), agents (send_to_agent)
- Message seq IDs: shared integer sequence across messages_in/out so agents
  see small numeric IDs instead of platform snowflakes
- busy_timeout=5000 for session DB (poll loop + MCP server concurrent access)
- Always copy agent-runner source to fix stale cache when non-index files change
- Seed script for Discord testing, e2e test script

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 02:53:39 +03:00
gavrielc b36f127acc style: prettier formatting fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 01:40:52 +03:00
gavrielc 6f2a7314d0 v2: fix agent-runner lifecycle and session DB reliability
- Use DELETE journal mode for session DBs instead of WAL. WAL doesn't
  sync reliably across Docker volume mounts (VirtioFS), causing dropped
  writes and duplicate deliveries.
- Add 20s idle detection to end the query stream. The concurrent poll
  tracks SDK activity via a new 'activity' provider event. When no SDK
  events arrive for 20s and no messages are pending, the stream ends
  and the poll loop continues.
- Add touchProcessing heartbeat so the host can distinguish active
  agents from idle ones by checking status_changed recency.
- Catch query errors in the poll loop and write error responses to
  messages_out instead of crashing the process.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 01:34:59 +03:00
gavrielc 7201fe5032 v2 phase 4: channel adapter interface, registry, and host wiring
ChannelAdapter interface with setup/deliver/teardown/setTyping lifecycle.
Self-registration pattern via channel-registry. Host wiring in index-v2
bridges inbound messages to routeInbound and outbound delivery to adapters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:10:46 +03:00
gavrielc d35386a46e style: apply prettier formatting to v2 source files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:59:08 +03:00
gavrielc 03c4e3b672 v2: fix container launch for v2 agent-runner
- Override entrypoint to compile and run index-v2.js (no stdin)
- Add better-sqlite3 + @types to agent-runner dependencies
- Exclude test files from agent-runner tsconfig (Docker build)
- Add real e2e test script (host → container → Claude → session DB)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:49:30 +03:00
gavrielc 8535875d0c v2: add host core integration tests
Tests for session manager (folder/DB creation, shared vs per-thread
resolution, message writing), router (end-to-end routing, auto-create
messaging groups), and delivery (undelivered message detection).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:44:26 +03:00
gavrielc d7c68e04b1 v2 phase 3: host core — router, session manager, delivery, sweep
Host orchestrator connecting channel events to session DBs and
delivering responses back through channel adapters.

- session-manager.ts: session folder/DB lifecycle, message writing
- container-runner-v2.ts: Docker spawn with session + agent group
  mounts, OneCLI, idle timeout, agent-runner recompilation
- router-v2.ts: inbound routing (channel → messaging group → agent
  group → session → messages_in → wake container)
- delivery.ts: two-tier polling (1s active, 60s sweep) for
  messages_out, channel adapter delivery
- host-sweep.ts: stale detection with backoff, recurrence, wake
  containers for due messages
- index-v2.ts: thin entry point wiring everything together
- scripts/test-v2-agent.ts: real Claude provider integration test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:43:13 +03:00
gavrielc 18d0b6e53f v2: add agent-runner integration tests
Poll loop end-to-end with mock provider: message pickup, batch
processing, concurrent polling for late arrivals.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:40:00 +03:00
gavrielc 5a0098edc9 v2 phase 2: agent-runner — provider interface, poll loop, formatter
AgentProvider abstraction with Claude and Mock implementations.
Poll loop reads messages_in, formats by kind, queries provider,
writes results to messages_out. Concurrent polling pushes follow-up
messages into active queries.

- providers/types.ts: AgentProvider, AgentQuery, ProviderEvent
- providers/claude.ts: wraps Agent SDK with MessageStream, hooks,
  transcript archiving
- providers/mock.ts: canned responses with push() support
- providers/factory.ts: createProvider()
- formatter.ts: format by kind (chat/task/webhook/system), XML
  escaping, routing extraction
- poll-loop.ts: poll → format → query → write, concurrent polling
- mcp-tools.ts: MCP server with send_message tool
- index-v2.ts: new entry point (config from env, enters poll loop)
- 11 new tests, all 288 tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:36:55 +03:00
gavrielc 3f0451b7b0 v2 phase 1: foundation — types, DB layer, logging
Add the v2 data layer: typed interfaces, central DB with migration
runner, per-entity CRUD, and agent-runner session DB operations.

- src/log.ts: concise message-first logging API
- src/types-v2.ts: AgentGroup, MessagingGroup, Session, MessageIn/Out
- src/db/: connection (WAL), migration runner, 001-initial schema,
  CRUD for agent_groups, messaging_groups, sessions, pending_questions
- container/agent-runner/src/db/: session DB connection, messages_in
  reads + status transitions, messages_out writes
- 31 new tests, all 277 tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:34:09 +03:00
gavrielc 90acff28ad chore: set printWidth to 120 and reformat
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:34:03 +03:00
gavrielc e540df46e6 docs: add code style (120 char lines, concise logging) and config pattern
Skills document env vars in SKILL.md instead of patching config.ts.
Prettier printWidth 120 to keep log calls and signatures on one line.
Thin logging wrapper for one-line structured log calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:24:09 +03:00
gavrielc a03f832dbb docs: add v1 conflict hotspot analysis and isolation strategies
Based on analysis of 33 skill branches. Maps each conflict hotspot
(index.ts, config.ts, container-runner.ts, db.ts) to its v2 solution.
Adds mount registration pattern so channel skills don't edit
container-runner. Config stays in the module that uses it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:19:35 +03:00
gavrielc 820c5067b7 docs: add DB file structure and migration strategy
Split DB by entity (agent-groups.ts, messaging-groups.ts, sessions.ts)
instead of one monolith. Numbered migration files replace inline
ALTER TABLE blocks. Channels use barrel pattern for self-registration.
Session DB split into messages-in.ts and messages-out.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:16:17 +03:00
gavrielc 1b652e1dc0 docs: add code structure principles for skill customization
Channels, MCP tools, and providers use registration patterns so
skill branches can add capabilities without conflicting. Index
stays thin. File map updated with channels/ and mcp-tools/
directories.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:10:15 +03:00
gavrielc b539fddbcb docs: v2 architecture design — session DB, channel adapters, agent provider
Three documents covering the complete v2 architecture:

- v2-architecture-draft.md: Core design (per-session SQLite as sole IO,
  two-level DB, entity model, channel adapters with Chat SDK bridge,
  container lifecycle, message flow, interactive operations, routing,
  flexibility model with PR Factory example)

- v2-api-details.md: Channel adapter interface definitions, Chat SDK
  bridge implementation, native channel example, message content
  format examples, host delivery logic

- v2-agent-runner-details.md: AgentProvider interface (stream-in/out),
  provider implementations (Claude, Codex, OpenCode), poll loop, MCP
  tool definitions, message formatting, media handling, container
  startup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:07:33 +03:00
gavrielc 934f063aff update deps 2026-04-07 08:35:25 +03:00
gavrielc 32a487b96b Merge pull request #1660 from johnnyfish/fix/gmail-onecli-credential-mode
fix(gmail): add OneCLI credential mode detection
2026-04-07 01:12:05 +03:00
johnnyfish 751a9ed2d1 fix(gmail): add OneCLI credential mode detection 2026-04-06 20:34:24 +03:00
gavrielc 22d7856ce0 reduce setup friction 2026-04-06 01:19:22 +03:00