tomo-ai 0.5.3 → 0.5.5

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -1
  3. package/defaults/AGENT.md +4 -0
  4. package/defaults/skills/browse/SKILL.md +22 -141
  5. package/defaults/skills/lcm/DAILY.md +1 -1
  6. package/defaults/skills/system/CONFIG.md +4 -2
  7. package/defaults/skills/system/SKILL.md +18 -9
  8. package/dist/agent/live-session.d.ts +57 -0
  9. package/dist/agent/live-session.d.ts.map +1 -0
  10. package/dist/agent/live-session.js +256 -0
  11. package/dist/agent/live-session.js.map +1 -0
  12. package/dist/agent/sdk-options.d.ts +51 -0
  13. package/dist/agent/sdk-options.d.ts.map +1 -0
  14. package/dist/agent/sdk-options.js +107 -0
  15. package/dist/agent/sdk-options.js.map +1 -0
  16. package/dist/agent/text-utils.d.ts +14 -0
  17. package/dist/agent/text-utils.d.ts.map +1 -0
  18. package/dist/agent/text-utils.js +28 -0
  19. package/dist/agent/text-utils.js.map +1 -0
  20. package/dist/agent.d.ts +45 -1
  21. package/dist/agent.d.ts.map +1 -1
  22. package/dist/agent.js +200 -460
  23. package/dist/agent.js.map +1 -1
  24. package/dist/channels/imageStore.d.ts +8 -0
  25. package/dist/channels/imageStore.d.ts.map +1 -1
  26. package/dist/channels/imageStore.js +15 -0
  27. package/dist/channels/imageStore.js.map +1 -1
  28. package/dist/channels/imessage.d.ts +4 -2
  29. package/dist/channels/imessage.d.ts.map +1 -1
  30. package/dist/channels/imessage.js +116 -28
  31. package/dist/channels/imessage.js.map +1 -1
  32. package/dist/channels/telegram.d.ts +4 -1
  33. package/dist/channels/telegram.d.ts.map +1 -1
  34. package/dist/channels/telegram.js +108 -12
  35. package/dist/channels/telegram.js.map +1 -1
  36. package/dist/channels/types.d.ts +19 -1
  37. package/dist/channels/types.d.ts.map +1 -1
  38. package/dist/cli/config/autostart.d.ts +2 -0
  39. package/dist/cli/config/autostart.d.ts.map +1 -0
  40. package/dist/cli/config/autostart.js +33 -0
  41. package/dist/cli/config/autostart.js.map +1 -0
  42. package/dist/cli/config/channels.d.ts +2 -0
  43. package/dist/cli/config/channels.d.ts.map +1 -0
  44. package/dist/cli/config/channels.js +156 -0
  45. package/dist/cli/config/channels.js.map +1 -0
  46. package/dist/cli/config/costs.d.ts +2 -0
  47. package/dist/cli/config/costs.d.ts.map +1 -0
  48. package/dist/cli/config/costs.js +141 -0
  49. package/dist/cli/config/costs.js.map +1 -0
  50. package/dist/cli/config/groups.d.ts +2 -0
  51. package/dist/cli/config/groups.d.ts.map +1 -0
  52. package/dist/cli/config/groups.js +57 -0
  53. package/dist/cli/config/groups.js.map +1 -0
  54. package/dist/cli/config/identities.d.ts +2 -0
  55. package/dist/cli/config/identities.d.ts.map +1 -0
  56. package/dist/cli/config/identities.js +313 -0
  57. package/dist/cli/config/identities.js.map +1 -0
  58. package/dist/cli/{config.d.ts → config/index.d.ts} +1 -1
  59. package/dist/cli/config/index.d.ts.map +1 -0
  60. package/dist/cli/config/index.js +64 -0
  61. package/dist/cli/config/index.js.map +1 -0
  62. package/dist/cli/config/model.d.ts +2 -0
  63. package/dist/cli/config/model.d.ts.map +1 -0
  64. package/dist/cli/config/model.js +21 -0
  65. package/dist/cli/config/model.js.map +1 -0
  66. package/dist/cli/config/sessions.d.ts +2 -0
  67. package/dist/cli/config/sessions.d.ts.map +1 -0
  68. package/dist/cli/config/sessions.js +83 -0
  69. package/dist/cli/config/sessions.js.map +1 -0
  70. package/dist/cli/config/shared.d.ts +9 -0
  71. package/dist/cli/config/shared.d.ts.map +1 -0
  72. package/dist/cli/config/shared.js +38 -0
  73. package/dist/cli/config/shared.js.map +1 -0
  74. package/dist/cli/start.js +15 -0
  75. package/dist/cli/start.js.map +1 -1
  76. package/dist/cli.js +1 -1
  77. package/dist/cli.js.map +1 -1
  78. package/dist/config.d.ts +6 -2
  79. package/dist/config.d.ts.map +1 -1
  80. package/dist/config.js +4 -1
  81. package/dist/config.js.map +1 -1
  82. package/dist/lcm/blocks.d.ts +4 -3
  83. package/dist/lcm/blocks.d.ts.map +1 -1
  84. package/dist/lcm/blocks.js +15 -9
  85. package/dist/lcm/blocks.js.map +1 -1
  86. package/dist/lcm/compact.d.ts +56 -0
  87. package/dist/lcm/compact.d.ts.map +1 -1
  88. package/dist/lcm/compact.js +203 -9
  89. package/dist/lcm/compact.js.map +1 -1
  90. package/dist/lcm/runner.d.ts.map +1 -1
  91. package/dist/lcm/runner.js +11 -4
  92. package/dist/lcm/runner.js.map +1 -1
  93. package/dist/mcp/internal-server.d.ts.map +1 -1
  94. package/dist/mcp/internal-server.js +51 -0
  95. package/dist/mcp/internal-server.js.map +1 -1
  96. package/dist/workspace/index.d.ts.map +1 -1
  97. package/dist/workspace/index.js +8 -0
  98. package/dist/workspace/index.js.map +1 -1
  99. package/package.json +1 -1
  100. package/defaults/skills/cron/SKILL.md +0 -78
  101. package/dist/cli/config.d.ts.map +0 -1
  102. package/dist/cli/config.js +0 -884
  103. package/dist/cli/config.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.5 (2026-05-01)
4
+
5
+ ### Features
6
+
7
+ - **Inbound image marker is now always emitted, with the saved disk path when local storage is on.** Previously, a `[Sent an image]` fallback only appeared when the user sent an image with no caption — captions replaced the marker outright, and the model couldn't see the on-disk file path even when `saveInboundImages` was on. Now both Telegram and iMessage prepend `[Sent an image]` (or `[Sent N images]` for iMessage's multi-attachment messages) to the user's caption, and append `saved to: /abs/path[, /abs/path…]` when storage is enabled. The agent can now reliably know an image was attached and `Read` it from disk for tool work that goes beyond what the inline content blocks support. New `formatImageMarker(intendedCount, savedPaths)` helper in `channels/imageStore.ts`; both channels thread `savedPath` through `ImageAttachment`. Marker reflects intended-image count, so a download failure for one attachment doesn't hide the fact that an image was sent.
8
+
9
+ ### UX
10
+
11
+ - **Group sessions default to hierarchical LCM compaction.** `config.lcm.groupCompactStyle` now defaults to `"lcm"` instead of `"sdk"`. Group sessions get the same daily/weekly/monthly/yearly rollup nudges, %-based compact prompts, and `tomo-lcm-stats` MCP tool that DMs already had. Set to `"sdk"` to opt back into SDK auto-compact for groups. Existing installs with the field unset flip on next `tomo start`. Rollup nudges for group sessions splice in a "Group scope" line so summaries stay focused on that group's conversation rather than mixing in personal/DM context.
12
+ - **`tomo-cron` skill removed; the `schedule_*` MCP tools are now the everyday interface.** The standalone `tomo-cron` skill was redundant once `schedule_create` / `schedule_list` / `schedule_remove` landed on the `tomo-internal` MCP server in 0.5.3. The `tomo-system` skill now briefly mentions the three MCP tools and notes that the `tomo cron …` CLI remains for human debugging (auditing the job store, fixing a stuck job after a restart). Built-in skills list trimmed accordingly.
13
+ - **`tomo-browse` skill switched from `playwright-cli` to `agent-browser`.** New skill content is a thin discovery stub pointing at `agent-browser skills get core`, so workflow guidance always tracks the installed CLI version instead of going stale in this repo. Frontmatter description broadens trigger coverage to web automation, exploratory testing, Electron app automation (VS Code, Slack, Discord, Figma), Slack workspace tasks, Vercel Sandbox, and AWS Bedrock AgentCore.
14
+
15
+ ### Bug fixes
16
+
17
+ - **`lcm compact`: fix write race that could clobber events the SDK appended while `compactSession` was running.** Symptom: when an agent invokes a long-running `tomo lcm daily/weekly/...` via Bash tool, the SDK's `thinking` + `tool_use` events for that very turn could land on disk between compactSession's initial read and its truncate-rewrite, then get wiped by the rewrite. The subsequent `tool_result` then had a `parentUuid` pointing at a vanished tool_use, breaking the chain.
18
+ - Fix: capture the file size at read time, re-read the tail at write time, splice any late-arriving events into the new content, and write atomically via `<path>.compacting.tmp` + `rename`.
19
+ - **iMessage typing indicator: stop the flicker.** BlueBubbles' typing decays server-side faster than Telegram's, so the previous 6-second refresh cadence raced the decay and left the indicator visibly turning on/off between ticks during long SDK turns. Three changes: (1) refresh interval dropped from 6 s to **3 s**; (2) added a `tickInFlight` guard so a slow BlueBubbles HTTP server doesn't queue overlapping POSTs; (3) added Tomo-Telegram-style consecutive-error suspension — after 10 consecutive failed POSTs (e.g. Private API helper missing), typing self-suspends with a single `log.warn` and explicitly DELETEs the indicator instead of hammering the endpoint forever. Cross-checked the design against the openclaw bluebubbles extension's typing controller (`openclaw/src/channels/typing.ts`), which uses the same 3 s default and `tickInFlight` pattern.
20
+
21
+ ### Internal
22
+
23
+ - **Built-in skill prune on startup.** `cli/start.ts` now removes `~/.tomo/workspace/.claude/skills/tomo-*` directories that no longer have a counterpart in bundled `defaults/skills/`. Custom skills (anything not prefixed `tomo-`) are never touched. Without this, retired built-ins like `tomo-cron` would persist forever on existing installs.
24
+
25
+ ## 0.5.4 (2026-04-29)
26
+
27
+ ### Features
28
+
29
+ - **Group chat rename MCP tool**: `tomo-internal` now exposes `rename_group_chat(target, title)` for explicit user-requested group title changes. Telegram uses Bot API `setChatTitle`; iMessage uses BlueBubbles Private API `PUT /chat/:guid` with `displayName`. Successful renames update Tomo's persisted `chatTitle` immediately so `list_sessions` reflects the new name.
30
+ - **Latest-message reaction MCP tool**: `react_to_latest_message(target, reaction, remove?)` reacts/tapbacks to the latest inbound message Tomo has seen in a session since startup. Telegram uses `setMessageReaction`; iMessage uses BlueBubbles Private API `POST /message/react`. Supported cross-channel reactions are `love`, `like`, `dislike`, `laugh`, `emphasize`, and `question`.
31
+ - **Telegram sticker sending**: responses can now include `STICKER:<telegram_file_id>` to send a Telegram sticker via `sendSticker`, mirroring the existing `MEDIA:` attachment tag flow.
32
+ - **Telegram sticker ingress**: inbound Telegram stickers now arrive as text metadata including `file_id`, optional emoji/set/type flags, and a ready-to-use `STICKER:<file_id>` resend hint.
33
+
3
34
  ## 0.5.3 (2026-04-28)
4
35
 
5
36
  ### Features
package/README.md CHANGED
@@ -183,7 +183,7 @@ Run `tomo config` for interactive setup, or edit `~/.tomo/config.json` directly:
183
183
  "lcm": {
184
184
  "nudgeAtPct": 70,
185
185
  "nudgeResetPct": 60,
186
- "groupCompactStyle": "sdk"
186
+ "groupCompactStyle": "lcm"
187
187
  }
188
188
  }
189
189
  ```
package/defaults/AGENT.md CHANGED
@@ -20,3 +20,7 @@ You have `list_sessions` and `send_message` tools for proactively posting to ano
20
20
  - **`direct`**: send verbatim text. Use for factual broadcasts ("meeting moved to 3pm"), pasted content, or self-targeted mid-loop progress updates.
21
21
 
22
22
  Call `list_sessions` first if you're unsure which group to address. For normal in-conversation responses, just reply with text — don't reach for these tools.
23
+
24
+ You also have `rename_group_chat` for changing the real title of a Telegram or iMessage group. Only use it when the user explicitly asks to rename a group, and pass a group session key from `list_sessions`.
25
+
26
+ You also have `react_to_latest_message` for reacting/tapbacking to the latest inbound message Tomo has seen in a session. Latest-message state is in-memory since startup; if the tool says none is known, wait for a new inbound message. Usually pass the current Session key.
@@ -1,159 +1,40 @@
1
1
  ---
2
2
  name: tomo-browse
3
- description: Browse the web with a real browser using playwright-cli. Navigate pages, click elements, fill forms, take screenshots. Use when WebFetch isn't enough pages need JavaScript, interaction, or visual capture.
3
+ description: Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
4
4
  ---
5
5
 
6
- # Browser Automation with playwright-cli
6
+ # agent-browser
7
7
 
8
- ## Installation
8
+ Fast browser automation CLI for AI agents. Chrome/Chromium via CDP with
9
+ accessibility-tree snapshots and compact `@eN` element refs.
9
10
 
10
- Before using any playwright-cli command, check if it's installed. If not, install it automatically — don't ask the user:
11
+ Install: `npm i -g agent-browser && agent-browser install`
11
12
 
12
- ```bash
13
- which playwright-cli || npm install -g @playwright/cli@latest
14
- ```
13
+ ## Start here
15
14
 
16
- ## Quick start
15
+ This file is a discovery stub, not the usage guide. Before running any
16
+ `agent-browser` command, load the actual workflow content from the CLI:
17
17
 
18
18
  ```bash
19
- playwright-cli open -s=tomo --browser=chrome --persistent --headed
20
- playwright-cli goto https://example.com
21
- playwright-cli snapshot
22
- playwright-cli click e15
23
- playwright-cli type "search query"
24
- playwright-cli screenshot
25
- playwright-cli -s=tomo close
19
+ agent-browser skills get core # start here — workflows, common patterns, troubleshooting
20
+ agent-browser skills get core --full # include full command reference and templates
26
21
  ```
27
22
 
28
- **Always use `-s=tomo --browser=chrome --persistent --headed`** when opening a browser. This uses real Chrome with a persistent profile (cookies/logins survive), and the user can see the browser window.
23
+ The CLI serves skill content that always matches the installed version,
24
+ so instructions never go stale. The content in this stub cannot change
25
+ between releases, which is why it just points at `skills get core`.
29
26
 
30
- The agent profile is separate from the user's personal Chrome. The user can interact with the visible browser (e.g., to log in) while the agent operates it.
27
+ ## Specialized skills
31
28
 
32
- **Important:** After opening, all subsequent commands must include `-s=tomo` to target the named session:
33
- ```bash
34
- playwright-cli -s=tomo goto https://example.com
35
- playwright-cli -s=tomo snapshot
36
- playwright-cli -s=tomo click e15
37
- playwright-cli -s=tomo close
38
- ```
39
-
40
- ## Commands
41
-
42
- ### Core
29
+ Load a specialized skill when the task falls outside browser web pages:
43
30
 
44
31
  ```bash
45
- playwright-cli open -s=tomo --browser=chrome --persistent --headed
46
- playwright-cli open -s=tomo --browser=chrome --persistent --headed https://example.com/
47
- playwright-cli goto https://playwright.dev
48
- playwright-cli type "search query"
49
- playwright-cli click e3
50
- playwright-cli dblclick e7
51
- playwright-cli fill e5 "user@example.com" --submit
52
- playwright-cli drag e2 e8
53
- playwright-cli hover e4
54
- playwright-cli select e9 "option-value"
55
- playwright-cli upload ./document.pdf
56
- playwright-cli check e12
57
- playwright-cli uncheck e12
58
- playwright-cli snapshot
59
- playwright-cli eval "document.title"
60
- playwright-cli dialog-accept
61
- playwright-cli dialog-dismiss
62
- playwright-cli -s=tomo close
32
+ agent-browser skills get electron # Electron desktop apps (VS Code, Slack, Discord, Figma, ...)
33
+ agent-browser skills get slack # Slack workspace automation
34
+ agent-browser skills get dogfood # Exploratory testing / QA / bug hunts
35
+ agent-browser skills get vercel-sandbox # agent-browser inside Vercel Sandbox microVMs
36
+ agent-browser skills get agentcore # AWS Bedrock AgentCore cloud browsers
63
37
  ```
64
38
 
65
- ### Navigation
66
-
67
- ```bash
68
- playwright-cli go-back
69
- playwright-cli go-forward
70
- playwright-cli reload
71
- ```
72
-
73
- ### Keyboard
74
-
75
- ```bash
76
- playwright-cli press Enter
77
- playwright-cli press ArrowDown
78
- playwright-cli keydown Shift
79
- playwright-cli keyup Shift
80
- ```
81
-
82
- ### Save as
83
-
84
- ```bash
85
- playwright-cli screenshot
86
- playwright-cli screenshot e5
87
- playwright-cli screenshot --filename=page.png
88
- playwright-cli pdf --filename=page.pdf
89
- ```
90
-
91
- ### Tabs
92
-
93
- ```bash
94
- playwright-cli tab-list
95
- playwright-cli tab-new https://example.com/page
96
- playwright-cli tab-close
97
- playwright-cli tab-select 0
98
- ```
99
-
100
- ### Storage
101
-
102
- ```bash
103
- playwright-cli cookie-list
104
- playwright-cli cookie-get session_id
105
- playwright-cli cookie-set session_id abc123
106
- playwright-cli localstorage-get theme
107
- playwright-cli localstorage-set theme dark
108
- ```
109
-
110
- ## Raw output
111
-
112
- Use `--raw` to get clean output for piping:
113
-
114
- ```bash
115
- playwright-cli --raw eval "document.title"
116
- playwright-cli --raw snapshot > page.yml
117
- ```
118
-
119
- ## Snapshots
120
-
121
- After each command, playwright-cli provides a snapshot with element refs (e.g., `e15`, `e3`). Use these refs to interact:
122
-
123
- ```bash
124
- playwright-cli snapshot
125
- playwright-cli click e15
126
- ```
127
-
128
- You can also use CSS selectors or Playwright locators:
129
-
130
- ```bash
131
- playwright-cli click "#main > button.submit"
132
- playwright-cli click "getByRole('button', { name: 'Submit' })"
133
- ```
134
-
135
- ## Targeting elements
136
-
137
- Prefer refs from snapshots. Fall back to CSS selectors or locators when refs are ambiguous.
138
-
139
- ## Example: Form submission
140
-
141
- ```bash
142
- playwright-cli open -s=tomo --browser=chrome --persistent --headed https://example.com/form
143
- playwright-cli snapshot
144
- playwright-cli fill e1 "user@example.com"
145
- playwright-cli fill e2 "password123"
146
- playwright-cli click e3
147
- playwright-cli snapshot
148
- playwright-cli -s=tomo close
149
- ```
150
-
151
- ## Example: Multi-tab workflow
152
-
153
- ```bash
154
- playwright-cli open -s=tomo --browser=chrome --persistent --headed https://example.com
155
- playwright-cli tab-new https://example.com/other
156
- playwright-cli tab-select 0
157
- playwright-cli snapshot
158
- playwright-cli -s=tomo close
159
- ```
39
+ Run `agent-browser skills list` to see everything available on the
40
+ installed version.
@@ -15,7 +15,7 @@ tomo lcm daily --session-id SESSION_ID --summary "<today's summary>"
15
15
  ## When to run
16
16
 
17
17
  - **End of day** (before bed or before a long idle). Cleanest shape.
18
- - **Mid-day** when the harness nudges you that raw tail > 40 events.
18
+ - **Mid-day** when the harness nudges you that the raw tail has grown past the fresh-tail floor (default 32 events; tune via `lcm.dailyFreshTail` in config.json).
19
19
  - **Before a big task** when you want clean context for an involved piece of work.
20
20
  - **After long tool-heavy work** — reduce clutter before the conversation continues.
21
21
 
@@ -40,7 +40,8 @@ Prefer editing via `tomo config` (interactive TUI). This reference is for readin
40
40
  "lcm": {
41
41
  "nudgeAtPct": 70,
42
42
  "nudgeResetPct": 60,
43
- "groupCompactStyle": "sdk"
43
+ "groupCompactStyle": "sdk",
44
+ "dailyFreshTail": 32
44
45
  }
45
46
  }
46
47
  ```
@@ -67,7 +68,8 @@ Prefer editing via `tomo config` (interactive TUI). This reference is for readin
67
68
  | `maxTurns` | number | Max agent turns per single user message (one turn ≈ one tool-use round). Default `50`. Raise if you see "max turns exceeded" on long tool chains. |
68
69
  | `lcm.nudgeAtPct` | number | Context-usage % at which the harness nudges the agent to run `tomo lcm daily`. Default `70`. Lower = compact earlier and more often. |
69
70
  | `lcm.nudgeResetPct` | number | Hysteresis reset threshold — the "already nudged" flag clears once usage drops below this %. Default `60`. Must be less than `nudgeAtPct`; invalid values fall back to defaults. |
70
- | `lcm.groupCompactStyle` | string | `"sdk"` (default) or `"lcm"`. `"sdk"` lets the SDK auto-compact group sessions; `"lcm"` opts groups into the same hierarchical LCM flow as DMs (disables SDK auto-compact and fires the daily/80% nudges). DMs always use LCM regardless. |
71
+ | `lcm.groupCompactStyle` | string | `"sdk"` (default) or `"lcm"`. `"sdk"` lets the SDK auto-compact group sessions; `"lcm"` opts groups into the same hierarchical LCM flow as DMs (disables SDK auto-compact and fires all three harness nudges: 70% daily, 80% safety net, and the periodic rollup runner). DMs always use LCM regardless. |
72
+ | `lcm.dailyFreshTail` | number | Number of most-recent raw user/assistant events kept outside today's daily rollup so mid-day compacts don't wipe warm short-term texture. Default `32`. Counts SDK events (one tool round = multiple events), not user-typed messages. Set to `0` to compact every event into today's block. Past days are always compacted in full regardless of this value. |
71
73
 
72
74
  ## Requirements and overrides
73
75
 
@@ -29,15 +29,19 @@ Session stats show:
29
29
 
30
30
  **Note:** Context stats come from the SDK API and reflect the state at the end of the *previous* query. After compacting or other changes, you need to wait for a new query to complete before the numbers update.
31
31
 
32
- When context crosses the nudge threshold (default 70%, set via `lcm.nudgeAtPct` in config.json), the harness sends a system message asking you to run `tomo lcm daily` — see the `tomo-lcm` skill. A second nudge at 80% asks you to use the `lcm compact` skill before the next user message. Group sessions default to SDK auto-compact instead (override with `lcm.groupCompactStyle: "lcm"`).
32
+ When context crosses the nudge threshold (default 70%, set via `lcm.nudgeAtPct` in config.json), the harness sends a system message asking you to run `tomo lcm daily` — see the `tomo-lcm` skill. A second nudge at 80% asks you to use the `lcm compact` skill before the next user message. A periodic rollup runner also nudges you when daily/weekly/monthly/yearly blocks are due. Group sessions default to SDK auto-compact instead (override with `lcm.groupCompactStyle: "lcm"` to enroll groups in all three nudges).
33
33
 
34
34
  ## Cron Jobs
35
35
 
36
- ```bash
37
- tomo cron list # All scheduled jobs with status
38
- tomo cron add --name "X" --schedule "in 20m" --message "Y"
39
- tomo cron remove <id> # Delete a job
40
- ```
36
+ Schedule reminders and recurring tasks via the `tomo-internal` MCP tools:
37
+
38
+ - `schedule_create` create a one-shot or recurring job (`schedule` accepts `in 20m`, `every 6h`, or a 5-field cron expression; `sessionKey` controls where the fired message lands)
39
+ - `schedule_list` list every job with `id`, `nextRunAt`, `lastStatus`, etc.
40
+ - `schedule_remove` — delete by `id`
41
+
42
+ These are the everyday interface — load them via tool search ("schedule reminder cron") when the user asks to schedule something.
43
+
44
+ The `tomo cron list / add / remove` CLI is still here for human debugging (auditing the job store, fixing a stuck job after a restart). Prefer the MCP tools in normal conversation.
41
45
 
42
46
  ## File Paths
43
47
 
@@ -67,6 +71,9 @@ Responses stream to Telegram in real-time — messages update every 1.5s as toke
67
71
  ### MEDIA: tag
68
72
  To send an image/file to the user, include `MEDIA:/path/to/file.png` in your response. The harness strips it from text and sends the file. Text before/after becomes the caption.
69
73
 
74
+ ### STICKER: tag
75
+ To send a Telegram sticker by file_id, include `STICKER:<telegram_file_id>` in your response. The harness strips it from text and sends the sticker on Telegram; other channels ignore sticker sends. Only use file_ids you have seen or been given.
76
+
70
77
  ### NO_REPLY
71
78
  Reply with exactly `NO_REPLY` to suppress delivery to the channel. Use for background tasks that found nothing to report.
72
79
 
@@ -85,12 +92,14 @@ Two listen modes per group:
85
92
  The active mode plus group title and known participants are part of your per-session system prompt under `## Group Chat Context` whenever you're in a group session — survives compaction. Each incoming group message is prefixed with the sender name (`Alice: ...`) so you can attribute it.
86
93
 
87
94
  ### Proactive messaging (MCP tools)
88
- Two in-process MCP tools let you message outside the current conversation:
95
+ In-process MCP tools let you message outside the current conversation:
89
96
 
90
97
  - `mcp__tomo-internal__list_sessions` — discover valid targets. Returns `{identities: [{name}], groups: [{key, title?, participants?}]}`. Group titles and participants populate as messages arrive in the group; an entry without them just hasn't seen activity since the schema landed.
91
98
  - `mcp__tomo-internal__send_message(target, message, mode?)` — send to a target. Two modes:
92
99
  - `delegate` (default): describe the *intent* (e.g. "follow up with Alice about her recent trip"). The recipient session's Claude composes the actual message in its own voice/context. Best for social or contextual relays. Fire-and-forget.
93
100
  - `direct`: send the verbatim text. Recipient is not triggered into a Claude turn. Best for factual broadcasts ("meeting moved to 3pm"), pasted content, or self-targeted mid-loop progress updates.
101
+ - `mcp__tomo-internal__rename_group_chat(target, title)` — rename the real Telegram or iMessage group title. Use only when the user explicitly asks for a rename; `target` must be a group session key from `list_sessions`.
102
+ - `mcp__tomo-internal__react_to_latest_message(target, reaction, remove?)` — react/tapback to the latest inbound message Tomo has seen in that session since startup. This latest-message state is in-memory; after a restart, wait for a new inbound message before using it. Usually pass the current Session key. Reactions: `love`, `like`, `dislike`, `laugh`, `emphasize`, `question`.
94
103
 
95
104
  Pass identity name (`"alice"`) or session key (`"telegram:-1001234567"`) as `target`. Call `list_sessions` first if unsure. Tool result lines (with `is_error` flag) appear in `tomo logs` immediately after the corresponding tool call.
96
105
 
@@ -99,7 +108,7 @@ Pass identity name (`"alice"`) or session key (`"telegram:-1001234567"`) as `tar
99
108
  ### Built-in skills (`tomo-*`)
100
109
  Skills prefixed with `tomo-` are bundled with Tomo and automatically updated on every `tomo start`. Do not edit these — your changes will be overwritten on next restart.
101
110
 
102
- Current built-in skills: `tomo-system`, `tomo-lcm`, `tomo-browse`, `tomo-cron`.
111
+ Current built-in skills: `tomo-system`, `tomo-lcm`, `tomo-browse`.
103
112
 
104
113
  ### Custom / third-party skills
105
114
  Place skill directories under `~/.tomo/workspace/.claude/skills/`. Each skill needs a `SKILL.md` with YAML frontmatter (`name` and `description`). The harness picks them up automatically — restart Tomo to load new skills.
@@ -143,7 +152,7 @@ tomo restart # Restart
143
152
 
144
153
  ### Session feels stale or confused
145
154
  ```bash
146
- tomo sessions clear # Reset sessions
155
+ tomo sessions clear # Reset sessions (Must ask user to confirm)
147
156
  tomo restart
148
157
  ```
149
158
  Or tell the user to send `/new` in Telegram.
@@ -0,0 +1,57 @@
1
+ import { type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ import type { sdkOptions } from "./sdk-options.js";
3
+ export interface MessageRequest {
4
+ message: SDKUserMessage;
5
+ /** Called for each text-delta as it streams (cumulative running text). */
6
+ onText?: (text: string) => void;
7
+ /**
8
+ * Called once per text block when an `assistant` event arrives, after the
9
+ * block's deltas have all been streamed. Receives the block's full text.
10
+ * Channels can use this to seal the in-flight streamed message and start
11
+ * fresh on the next block, so multi-block turns ship as multiple messages
12
+ * instead of a single edit-in-place that drops earlier blocks.
13
+ */
14
+ onBlockComplete?: (text: string) => void | Promise<void>;
15
+ resolve: (response: string) => void;
16
+ reject: (err: Error) => void;
17
+ }
18
+ export interface QueryResult {
19
+ costUsd: number;
20
+ inputTokens: number;
21
+ outputTokens: number;
22
+ cacheReadTokens: number;
23
+ cacheCreationTokens: number;
24
+ contextUsed: number;
25
+ contextMax: number;
26
+ contextBreakdown?: {
27
+ name: string;
28
+ tokens: number;
29
+ }[];
30
+ }
31
+ export declare class LiveSession {
32
+ private q;
33
+ private pendingMessage;
34
+ private currentRequest;
35
+ private parts;
36
+ private streamingText;
37
+ private sessionId;
38
+ private alive;
39
+ lastResult: QueryResult | null;
40
+ private prevTotalCost;
41
+ private eventLoopDone;
42
+ private sessionKey;
43
+ private pendingToolNames;
44
+ constructor(options: ReturnType<typeof sdkOptions>, sessionKey?: string);
45
+ private messageGenerator;
46
+ private consumeEvents;
47
+ private handleEvent;
48
+ private logContextUsage;
49
+ send(text: string, onText?: (text: string) => void, images?: Array<{
50
+ data: string;
51
+ mediaType: string;
52
+ }>, onBlockComplete?: (text: string) => void | Promise<void>): Promise<string>;
53
+ getSessionId(): string | null;
54
+ isAlive(): boolean;
55
+ close(): void;
56
+ }
57
+ //# sourceMappingURL=live-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-session.d.ts","sourceRoot":"","sources":["../../src/agent/live-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAmB,MAAM,gCAAgC,CAAC;AAEzG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAuCD,qBAAa,WAAW;IACtB,OAAO,CAAC,CAAC,CAAQ;IACjB,OAAO,CAAC,cAAc,CAAgD;IACtE,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAQ;IACrB,UAAU,EAAE,WAAW,GAAG,IAAI,CAAQ;IACtC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAqB;IAGvC,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM;YAMxD,gBAAgB;YAUjB,aAAa;YAeb,WAAW;YA2GX,eAAe;IA6CvB,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC/B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC;IA6ClB,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,OAAO,IAAI,OAAO;IAIlB,KAAK,IAAI,IAAI;CAId"}