Add QR pairing (terminal QR, in-app scanner, iris://pair deep link)
CI / Kotlin tests (android host + desktop) (push) Successful in 8m5s
CI / Gateway plugin tests (push) Successful in 9m47s

This commit is contained in:
ARIA committed 2026-08-22 22:43:13 +02:00
1 parent 27dc7917f2
commit 7a6d922d12
63 files changed
+2073 -630

No files matched your search

+11 -11
View File
@@ -9,10 +9,10 @@ gateway identity concepts**.
| App concept | hermes primitive | Example |
| --- | --- | --- |
| Default chat | home channel `chat_id` | `android:default` |
| A thread (inside default chat) | `thread_id` under the default `chat_id` | `chat_id=android:default, thread_id=t_12` |
| A user-created channel | a new `chat_id` | `android:chan_7` |
| A thread inside a channel | `thread_id` under that `chat_id` | `chat_id=android:chan_7, thread_id=t_31` |
| Default chat | home channel `chat_id` | `default` |
| A thread (inside default chat) | `thread_id` under the default `chat_id` | `chat_id=default, thread_id=t_12` |
| A user-created channel | a new `chat_id` | `chan_7` |
| A thread inside a channel | `thread_id` under that `chat_id` | `chat_id=chan_7, thread_id=t_31` |
- **`chat_id`** = the conversation lane (a channel or the default chat).
- **`thread_id`** = an optional sub-lane within a `chat_id` (topic-like).
@@ -23,7 +23,7 @@ gateway identity concepts**.
## 6.2 Default chat
- On first connect, the plugin ensures a **default channel** exists:
`chat_id = ANDROID_HOME_CHANNEL` (default `android:default`), `kind=default`,
`chat_id = ANDROID_HOME_CHANNEL` (default `default`), `kind=default`,
`is_default=true`, name "Default".
- It is also the **cron home channel** (`cron_deliver_env_var=
ANDROID_HOME_CHANNEL`), so `deliver=android` (bare) routes here.
@@ -37,7 +37,7 @@ gateway identity concepts**.
- **Threads OFF** — flat conversation; all messages use `thread_id=null`.
- **Threads ON** — the app groups the conversation into topic-like lanes.
Each new "topic" mints a `thread_id` (via `channel.create {kind:thread,
parent_chat_id:android:default}` or an implicit thread). The UI shows a
parent_chat_id:default}` or an implicit thread). The UI shows a
topic switcher (like Telegram topics) above the message list.
- Threads are **app-organized** but **gateway-real**: each `thread_id` is a
distinct hermes session lane, so context is isolated per thread and cron can
@@ -82,7 +82,7 @@ lane (nothing to title / session-scoped, not conversation starters).
- **Requirement:** the user creates new channels so **cron job outputs can be
delegated to them** instead of the default chat.
- **`channel.create {name, kind:"channel"}`** → plugin mints
`chat_id = android:chan_<n>`, stores in directory, broadcasts
`chat_id = chan_<n>`, stores in directory, broadcasts
`channel.created` to all devices. The new channel appears in the channel list.
- **`channel.rename` / `channel.set_default` / `channel.delete`** manage the
directory (rename broadcasts `channel.renamed`; delete is a **hard delete**
@@ -104,9 +104,9 @@ lane (nothing to title / session-scoped, not conversation starters).
- **Cron targeting** (the key payoff): because the plugin registers
`parse_target_ref_fn` and `cron_deliver_env_var`, cron jobs and the
`send_message` tool can target any channel/thread:
- `deliver="android"` → home (default) channel.
- `deliver="android:android:chan_7"` → that channel.
- `deliver="android:android:chan_7:t_31"` → that channel's thread.
- `deliver="iris"` → home (default) channel.
- `deliver="iris:chan_7"` → that channel.
- `deliver="iris:chan_7:t_31"` → that channel's thread.
- In-chat: the agent's `cronjob` tool can be told "deliver to the *Cron
Reports* channel"; the gateway resolves the name via the channel directory.
- **In-app affordance:** each channel's menu has "Set as cron target" / shows a
@@ -118,7 +118,7 @@ lane (nothing to title / session-scoped, not conversation starters).
- Cron resolves delivery targets in `cron/scheduler.py:2148`
(`_resolve_single_delivery_target`). For `platform:chat_id[:thread_id]` it
calls `tools.send_message_tool.resolve_send_target`, which uses our
`parse_target_ref_fn` to parse `android:<chat>[:<thread>]`.
`parse_target_ref_fn` to parse `iris:<chat>[:<thread>]`.
- Delivery then calls the **live adapter's `send(chat_id, text, …)`** (gateway
running) → our WS `message` frame (or outbox+push if the app is offline).
- Cron deliveries are framed with a `[Cron delivery: <name>]` header by hermes;