@hasna/bridge 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,16 +12,42 @@ bun install -g @hasna/bridge
12
12
 
13
13
  ## Commands
14
14
 
15
+ The `0.2.x` direction is session-first. A channel conversation attaches to a
16
+ bridge session, and normal messages go to that session. Agent adapters that do
17
+ not yet expose a stable create/send/resume API are marked `compatibility` in
18
+ session state.
19
+
20
+ Session surface:
21
+
22
+ ```sh
23
+ bridge sessions list
24
+ bridge sessions create --agent codewith --cwd /repo
25
+ bridge sessions attach SESSION_ID --channel telegram-main --conversation 123456789
26
+ bridge sessions use SESSION_ID --channel telegram-main --conversation 123456789
27
+ bridge sessions detach --channel telegram-main --conversation 123456789
28
+ bridge sessions pause SESSION_ID
29
+ bridge sessions resume SESSION_ID
30
+ bridge sessions close SESSION_ID
31
+ bridge sessions send SESSION_ID "status"
32
+ ```
33
+
34
+ Route compatibility surface:
35
+
15
36
  ```sh
16
37
  bridge init
17
38
  bridge doctor
18
39
  bridge channels add-telegram telegram-main --token-env TELEGRAM_BOT_TOKEN --allowed-chat-ids 123456789
40
+ bridge channels add-imessage imessage-main --allowed-handles +15555550100 --default-handle +15555550100
19
41
  bridge profiles add codewith-main --agent-kind codewith --auth-profile account001 --cwd /Users/hasna
20
42
  bridge agents add codewith --kind codewith --profile codewith-main
21
43
  bridge routes add telegram-codewith --from telegram-main --to codewith --chat-ids 123456789
22
44
  bridge serve
45
+ bridge daemon start
23
46
  ```
24
47
 
48
+ The session-backed multi-channel plan for the `0.2.x` release is tracked in
49
+ [`docs/session-bridge-plan.md`](docs/session-bridge-plan.md).
50
+
25
51
  Useful inspection commands:
26
52
 
27
53
  ```sh
@@ -37,8 +63,52 @@ Direct operations:
37
63
 
38
64
  ```sh
39
65
  bridge send telegram-main 123456789 "hello"
66
+ bridge send imessage-main +15555550100 "hello"
40
67
  bridge ask codewith "summarize this repo"
41
68
  bridge route-message --channel telegram-main --chat-id 123456789 --text "status" --json
69
+ bridge sessions route-message --channel telegram-main --chat-id 123456789 --text "status" --json
70
+ ```
71
+
72
+ Daemon operations:
73
+
74
+ ```sh
75
+ bridge daemon start
76
+ bridge daemon status
77
+ bridge daemon logs --lines 100
78
+ bridge daemon restart
79
+ bridge daemon stop
80
+ ```
81
+
82
+ `bridge daemon start` uses the process supervisor by default. It starts
83
+ `bridge serve` in the background, inherits the current environment, and writes
84
+ private metadata and logs under `~/.hasna/bridge/daemon`.
85
+
86
+ For login-started services:
87
+
88
+ ```sh
89
+ bridge daemon install --supervisor auto
90
+ bridge daemon start --supervisor auto
91
+ bridge daemon stop --supervisor auto
92
+ bridge daemon uninstall --supervisor auto
93
+ ```
94
+
95
+ `install` writes a user `launchd` file on macOS or a user `systemd` file on
96
+ Linux. Telegram token values are not written to those files. Make token
97
+ environment variables available to the user service manager before starting an
98
+ installed daemon.
99
+
100
+ macOS:
101
+
102
+ ```sh
103
+ launchctl setenv TELEGRAM_BOT_TOKEN "$TELEGRAM_BOT_TOKEN"
104
+ bridge daemon start --supervisor launchd
105
+ ```
106
+
107
+ Linux:
108
+
109
+ ```sh
110
+ systemctl --user import-environment TELEGRAM_BOT_TOKEN
111
+ bridge daemon start --supervisor systemd
42
112
  ```
43
113
 
44
114
  ## Profiles
@@ -91,5 +161,92 @@ var name, not the token value. Telegram channels fail closed unless
91
161
  `allowedChatIds` are set or `allowAllChats` is explicitly enabled.
92
162
  Disabled channels do not match or deliver routes. Channel-level `allowedChatIds`
93
163
  are enforced before route matching, and long-poll offsets are persisted in
94
- `~/.hasna/bridge/state.json` so restarts do not replay already-seen updates.
164
+ `~/.hasna/bridge/state.json` so restarts do not replay already-seen terminal
165
+ updates.
95
166
  MCP config inspection redacts profile and agent environment values.
167
+
168
+ Session state also lives in `~/.hasna/bridge/state.json`: `sessions`,
169
+ `bindings`, `messageLedger`, and `cursors`. The daemon records inbound messages
170
+ in the ledger and advances Telegram offsets only after a terminal state:
171
+ delivered, skipped, or unauthorized. Failed messages remain retryable and do
172
+ not advance the Telegram offset. If an agent succeeds but outbound delivery
173
+ fails, the response is stored as `agent_completed` so retry delivery does not
174
+ re-run the agent.
175
+
176
+ Daemon metadata and logs are private as well. Logs can contain prompts and agent
177
+ responses, so treat them as sensitive.
178
+
179
+ ## Telegram Smoke Test
180
+
181
+ Create a bot with BotFather and set the token only in your shell:
182
+
183
+ ```sh
184
+ export TELEGRAM_BOT_TOKEN='123456:...'
185
+ ```
186
+
187
+ Send any message to the bot from the Telegram account or group you want to use,
188
+ then find the chat id:
189
+
190
+ ```sh
191
+ curl "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates"
192
+ ```
193
+
194
+ Configure one allowed chat and a test shell agent:
195
+
196
+ ```sh
197
+ bridge init
198
+ bridge channels add-telegram telegram-main --token-env TELEGRAM_BOT_TOKEN --allowed-chat-ids CHAT_ID --default-chat-id CHAT_ID
199
+ bridge profiles add shell-echo --agent-kind shell --command printf --arg 'bridge ok: {prompt}'
200
+ bridge agents add echo --kind shell --profile shell-echo
201
+ bridge sessions create --id test-session --agent echo
202
+ bridge sessions attach test-session --channel telegram-main --conversation CHAT_ID
203
+ bridge doctor
204
+ bridge daemon start
205
+ bridge daemon status
206
+ ```
207
+
208
+ Send a plain Telegram message to the bot. It should reply with `bridge ok: ...`
209
+ without any prefix.
210
+ Inspect logs with `bridge daemon logs`, then stop it with `bridge daemon stop`.
211
+
212
+ For Telegram forum topics, use `CHAT_ID:THREAD_ID` as the conversation value.
213
+
214
+ For the first live test, use the default process supervisor above because it
215
+ inherits `TELEGRAM_BOT_TOKEN` from your shell. Move to launchd/systemd after that
216
+ works.
217
+
218
+ ## iMessage
219
+
220
+ iMessage is a local macOS channel. Sending uses the Messages app through
221
+ `osascript`, so macOS may ask for Automation permission for the terminal or
222
+ daemon host process.
223
+
224
+ Configure a send-only channel:
225
+
226
+ ```sh
227
+ bridge channels add-imessage imessage-main --allowed-handles +15555550100 --default-handle +15555550100
228
+ bridge send imessage-main "hello"
229
+ ```
230
+
231
+ If your Mac has more than one Messages account, add the account selector:
232
+
233
+ ```sh
234
+ bridge channels add-imessage imessage-main --allowed-handles +15555550100 --account you@example.com
235
+ ```
236
+
237
+ Enable local receive polling only when you are comfortable granting the daemon
238
+ host access to Messages data:
239
+
240
+ ```sh
241
+ bridge channels add-imessage imessage-main --allowed-handles +15555550100 --receive
242
+ bridge sessions attach SESSION_ID --channel imessage-main --conversation +15555550100
243
+ bridge daemon restart
244
+ ```
245
+
246
+ Receive mode reads `~/Library/Messages/chat.db`. If `bridge doctor` reports a
247
+ chat database permission failure, grant Full Disk Access to the terminal or
248
+ service host, or recreate the channel without `--receive`.
249
+
250
+ Inbound direct chats bind by handle. Group chats bind by local Messages chat id,
251
+ shown internally as `chat:<guid>`, and replies go back to that chat after the
252
+ sender handle passes the channel allowlist.