Commit Graph

86 Commits

Author SHA1 Message Date
Gabi Simons
c303b6eb14 feat(v2): add native WhatsApp adapter using Baileys v6
Direct ChannelAdapter implementation — no Chat SDK bridge.
Ports v1 infrastructure: getMessage fallback, outgoing queue,
group metadata cache, LID-to-phone mapping, auto-reconnect.
Auth via pairing code (WHATSAPP_PHONE_NUMBER) or QR code.

Text messaging only (MVP). Not yet implemented:
- File/image attachments (send and receive)
- Edit message, delete message
- Reactions
- Bot echo filtering (own messages loop back as inbound)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 15:04:24 +00:00
gavrielc
e92b245399 feat(v2): OneCLI 0.3.1 — approvals, credential collection, threaded routing
Three features built on top of @onecli-sh/sdk 0.3.1, landed together because
they share wiring surfaces (session DB schema, delivery dispatcher, Chat SDK
bridge, channel adapter contract).

## OneCLI manual-approval handler

* `src/onecli-approvals.ts` — long-polls OneCLI via the SDK's
  `configureManualApproval`; on each request, delivers an `ask_question` card
  to the admin agent group's first messaging group, persists a
  `pending_approvals` row, and waits on an in-memory Promise resolved by the
  admin's button click or an expiry timer. Expired cards are edited to
  "Expired (...)" and a startup sweep flushes any rows left over from a
  previous process.
* Short 11-byte approval id (`oa-<8 base36>`) instead of the SDK's UUID so the
  Telegram 64-byte `callback_data` limit is respected; the OneCLI UUID stays
  in the persisted payload for audit.
* Migration 003 consolidated: `pending_approvals` now has the OneCLI-aware
  columns from the start (`agent_group_id`, `channel_type`, `platform_id`,
  `platform_message_id`, `expires_at`, `status`), `session_id` relaxed to
  nullable so cross-session approvals fit.
* `handleQuestionResponse` in `src/index.ts` now routes OneCLI approvals
  through `resolveOneCLIApproval` before falling back to the
  session-bound approval path.

## Credential collection from chat

New `trigger_credential_collection` MCP tool — the agent researches a
third-party API, calls the tool with `{name, hostPattern, headerName,
valueFormat, description}`, and blocks until the host reports saved, rejected,
or failed. The credential value never enters the agent's context: the user
submits it into a Chat SDK Modal on the host side, the host writes it to
OneCLI via a thin facade (`src/onecli-secrets.ts` — shells out to
`onecli secrets create`, shape mirrors the SDK we expect upstream), and only
the status string flows back to the container via a system message.

* `src/credentials.ts` — host-side handler: delivers the card to the
  conversation's own channel (not the admin channel — credential collection
  is a user-facing flow, distinct from admin approval), persists a
  `pending_credentials` row, drives the submit → `createSecret` → notify
  pipeline. Falls back gracefully when the channel doesn't support modals.
* `src/db/credentials.ts` + migration 005: `pending_credentials` table.
* `src/channels/chat-sdk-bridge.ts`: renders a `credential_request` card,
  handles the `nccr:` action prefix by opening a Modal with a TextInput,
  registers an `onModalSubmit` handler for the `nccm:` callback prefix.
* `container/agent-runner/src/mcp-tools/credentials.ts`: the blocking MCP
  tool, mirroring the `ask_user_question` polling pattern.
* `container/agent-runner/src/db/messages-in.ts`: `findCredentialResponse`
  helper to pick up the system message the host writes back.

## Threaded adapter routing

The destination layer previously didn't carry thread context, so agent replies
to Discord always landed in the root channel regardless of which thread the
inbound came from.

* `ChannelAdapter.supportsThreads: boolean` — declared by every channel skill
  at `createChatSdkBridge`. Threaded: Discord, Slack, Teams, Google Chat,
  Linear, GitHub, Webex. Non-threaded: Telegram, WhatsApp Cloud, Matrix,
  Resend, iMessage.
* `src/router.ts`: non-threaded adapters strip `threadId` at ingest (threads
  collapse to channel-level sessions). Threaded adapters override the
  wiring's `session_mode` to `'per-thread'` so each thread = a session
  (except `agent-shared`, which is preserved as a cross-channel intent the
  adapter can't know about).
* `session_routing` table in `inbound.db` — single-row default reply routing
  written by the host on every container wake from
  `session.messaging_group_id` + `session.thread_id`. Forward-compat
  `CREATE TABLE IF NOT EXISTS` handles older session DBs lazily.
* `container/agent-runner/src/db/session-routing.ts` — container-side reader.
* `send_message` / `send_file` / `ask_user_question` / `send_card` /
  scheduling tools all default their routing (channel, platform, **and**
  thread) from the session when no explicit `to` is given. Explicit `to`
  uses the destination's channel with `thread_id = null` (cross-destination
  sends start a new conversation elsewhere).
* `poll-loop.ts::sendToDestination` (the final-text single-destination
  shortcut) now inherits `thread_id` from `RoutingContext` too — this was
  the root cause of Discord replies landing in the root channel even after
  `send_message` was wired correctly.

## Related cleanups

* `src/container-runner.ts`: OneCLI agent identifier switched from the lossy
  folder-derived string to `agent_group.id`, making `getAgentGroup(externalId)`
  a trivial reverse lookup for per-agent scoping.
* `wakeContainer` race fix via an in-flight promise map — concurrent wakes
  during the async buildContainerArgs / OneCLI `applyContainerConfig` window
  no longer double-spawn containers against the same session directory.
* `src/db/db-v2.test.ts`: dropped the brittle `expect(row.v).toBe(N)` schema
  version assertion — it had to be bumped on every migration addition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:18:21 +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
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
934f063aff update deps 2026-04-07 08:35:25 +03:00
github-actions[bot]
b8cf30830b chore: bump version to 1.2.52 2026-04-05 19:33:34 +00:00
github-actions[bot]
653390d9aa chore: bump version to 1.2.51 2026-04-05 19:29:01 +00:00
github-actions[bot]
75c2e1868f chore: bump version to 1.2.50 2026-04-05 13:16:10 +00:00
github-actions[bot]
b752e5cd34 chore: bump version to 1.2.49 2026-04-04 21:11:00 +00:00
github-actions[bot]
8a02170b21 chore: bump version to 1.2.48 2026-04-04 20:47:36 +00:00
github-actions[bot]
8f28cde41d chore: bump version to 1.2.47 2026-04-03 13:18:15 +00:00
github-actions[bot]
6e0653f537 chore: bump version to 1.2.46 2026-04-02 17:05:44 +00:00
github-actions[bot]
4c7bc80299 chore: bump version to 1.2.45 2026-04-01 18:53:21 +00:00
github-actions[bot]
7b0d79a6f3 chore: bump version to 1.2.44 2026-04-01 18:51:18 +00:00
github-actions[bot]
78bfb8df85 chore: bump version to 1.2.43 2026-03-30 22:27:59 +00:00
huahang
d675859c24 fix: Fix npm audit errors
````
4 vulnerabilities (2 moderate, 2 high)

To address all issues, run:
  npm audit fix
````

Signed-off-by: huahang <huahang.liu@gmail.com>
2026-03-30 23:12:49 +08:00
github-actions[bot]
37aee02b46 chore: bump version to 1.2.42 2026-03-28 11:23:18 +00:00
github-actions[bot]
c3e9a892c2 chore: bump version to 1.2.41 2026-03-27 20:19:23 +00:00
github-actions[bot]
e6e0c6fa9e chore: bump version to 1.2.40 2026-03-27 18:42:36 +00:00
github-actions[bot]
842ec5fd30 chore: bump version to 1.2.39 2026-03-27 14:15:52 +00:00
github-actions[bot]
6e602a1f5b chore: bump version to 1.2.38 2026-03-27 14:10:36 +00:00
github-actions[bot]
877650541a chore: bump version to 1.2.37 2026-03-27 14:10:01 +00:00
github-actions[bot]
62fc8c7708 chore: bump version to 1.2.36 2026-03-27 12:13:53 +00:00
gavrielc
7b22e23761 chore: replace pino/pino-pretty with built-in logger
Drop 23 transitive dependencies by replacing pino + pino-pretty with a
~70-line logger that matches the same output format and API. All 80+
call sites work unchanged. Production deps now: @onecli-sh/sdk,
better-sqlite3, cron-parser.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:13:34 +03:00
gavrielc
8f01a9a05e chore: remove unused dependencies (yaml, zod, @vitest/coverage-v8)
None of these are imported or referenced by the main codebase.
yaml had zero imports; zod is only used in container/agent-runner
(which has its own package.json); coverage-v8 was never configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:24:41 +03:00
github-actions[bot]
4383e3e61a chore: bump version to 1.2.35 2026-03-26 15:39:34 +00:00
github-actions[bot]
125757bc7d chore: bump version to 1.2.34 2026-03-25 21:29:02 +00:00
github-actions[bot]
7bfd060536 chore: bump version to 1.2.33 2026-03-25 20:47:41 +00:00
github-actions[bot]
3a26f69c7f chore: bump version to 1.2.32 2026-03-25 20:39:06 +00:00
github-actions[bot]
6d4f972ad0 chore: bump version to 1.2.31 2026-03-25 15:37:53 +00:00
github-actions[bot]
fd444681ef chore: bump version to 1.2.30 2026-03-25 15:36:23 +00:00
github-actions[bot]
bb736f37f2 chore: bump version to 1.2.29 2026-03-25 15:28:25 +00:00
github-actions[bot]
31c03cf924 chore: bump version to 1.2.28 2026-03-25 15:27:45 +00:00
github-actions[bot]
093530a418 chore: bump version to 1.2.27 2026-03-25 11:26:17 +00:00
gavrielc
e60eb6dea2 Merge remote-tracking branch 'telegram/main' 2026-03-25 13:22:40 +02:00
gavrielc
63f680d0be chore: remove grammy and pin better-sqlite3/cron-parser versions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:22:36 +02:00
github-actions[bot]
5d5b90448c chore: bump version to 1.2.26 2026-03-24 23:05:58 +00:00
github-actions[bot]
6d4e251534 chore: bump version to 1.2.25 2026-03-24 23:05:15 +00:00
gavrielc
11847a1af0 fix: validate timezone to prevent crash on POSIX-style TZ values
POSIX-style TZ strings like IST-2 cause a hard RangeError crash in
formatMessages because Intl.DateTimeFormat only accepts IANA identifiers.

- Add isValidTimezone/resolveTimezone helpers to src/timezone.ts
- Make formatLocalTime fall back to UTC on invalid timezone
- Validate TZ candidates in config.ts before accepting
- Add timezone setup step to detect and prompt when autodetection fails
- Use node:22-slim in Dockerfile (node:24-slim Trixie package renames)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:04:59 +02:00
github-actions[bot]
e26e1b3e68 chore: bump version to 1.2.24 2026-03-24 22:39:38 +00:00
github-actions[bot]
7d640cb9f6 chore: bump version to 1.2.23 2026-03-24 15:45:50 +00:00
github-actions[bot]
81f6703102 chore: bump version to 1.2.22 2026-03-24 12:55:54 +00:00
Guy Ben Aharon
2583af7ead fix: ensure OneCLI agents exist for all groups on startup 2026-03-23 14:45:58 +02:00
Guy Ben Aharon
e9369617fb feat: replace credential proxy with OneCLI gateway for secret injection 2026-03-23 14:45:58 +02:00
github-actions[bot]
c3b19876eb chore: bump version to 1.2.21 2026-03-21 09:57:39 +00:00
Claude
30ebcaa61e feat: add ESLint with error-handling rules
Add ESLint v9.35+ with typescript-eslint recommended config and
error-handling rules: preserve-caught-error (enforces { cause } when
re-throwing), no-unused-vars with caughtErrors:all, and
eslint-plugin-no-catch-all (warns on catch blocks that don't rethrow).

Fix existing violations: add error cause to container-runtime rethrow,
prefix unused vars with underscore, remove unused imports.

https://claude.ai/code/session_01JPjzhBp9PR5LtfLWVDrYrH
2026-03-21 11:57:22 +02:00
github-actions[bot]
b7420c6562 chore: bump version to 1.2.20 2026-03-21 09:54:51 +00:00
github-actions[bot]
91f17a11b2 chore: bump version to 1.2.19 2026-03-19 19:05:42 +00:00
github-actions[bot]
c78042e90e chore: bump version to 1.2.18 2026-03-19 19:03:27 +00:00
github-actions[bot]
c71c7b7e83 chore: bump version to 1.2.17 2026-03-18 10:10:45 +00:00