Skip to content

Commit e09aba1

Browse files
authored
docs: tailor imsg skill for OpenClaw agents (#100105)
* docs: tailor imsg skill for OpenClaw agents * docs(imsg-skill): document that poll send echoes --question as a visible comment * docs(imsg-skill): note inbound native poll question is backfilled from its caption * docs(imsg-skill): document only shipped poll behavior Drop the poll caption echo, --comment override, and inbound question backfill from the imsg skill: those live in imsg PR openclaw/imsg#155, not shipped imsg 0.12.2 (poll --help exposes only --question/--option). Also removes the inaccurate 'reply comment whose reply_to is the poll guid' framing — #155 sends the caption as a plain message, not a reply. Keeps shipped poll send/vote usage. Re-add once a release ships #155. --------- Co-authored-by: Omar Shahine <[email protected]>
1 parent 85c1e09 commit e09aba1

1 file changed

Lines changed: 184 additions & 57 deletions

File tree

skills/imsg/SKILL.md

Lines changed: 184 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: imsg
3-
description: "iMessage/SMS CLI for listing chats, history, and sending messages via Messages.app."
3+
description: "Use the imsg CLI from OpenClaw agents for iMessage/SMS DMs, groups, replies, reactions, polls, watching, and private-API actions."
44
homepage: https://imsg.to
55
metadata:
66
{
@@ -25,98 +25,225 @@ metadata:
2525

2626
# imsg
2727

28-
Use `imsg` to read and send iMessage/SMS via macOS Messages.app.
28+
Use `imsg` when an OpenClaw agent must act through the user's local macOS Messages.app account: inspect iMessage/SMS history, choose the correct DM or group, send messages/files, reply, react, vote in polls, or use private-API iMessage features.
2929

30-
## When to Use
30+
Do not use this skill for Telegram, Signal, WhatsApp, Discord, Slack, or for replying inside the current OpenClaw conversation when the configured channel already routes the reply.
3131

32-
Use when:
32+
## Agent Flow
3333

34-
- User explicitly asks to send iMessage or SMS
35-
- Reading iMessage conversation history
36-
- Checking recent Messages.app chats
37-
- Sending to phone numbers or Apple IDs
34+
1. Resolve the conversation first.
35+
2. Choose DM, existing group, or new group.
36+
3. Pick the lowest-capability command that can do the requested action.
37+
4. Confirm any send or visible state change unless the user already gave exact recipient, content, and action.
38+
5. Execute with stable identifiers: prefer `--chat-id` for normal sends/watch/history and `--chat` chat GUID for bridge actions.
3839

39-
## When NOT to Use
40+
Never infer a recipient from a casual name alone when several chats or handles could match. Show the matched display name, handle(s), group participants, and message text/action before sending.
4041

41-
Do not use when:
42+
## Host Requirements
4243

43-
- Telegram messages -> use `message` tool with `channel:telegram`
44-
- Signal messages -> use Signal channel if configured
45-
- WhatsApp messages -> use WhatsApp channel if configured
46-
- Discord messages -> use `message` tool with `channel:discord`
47-
- Slack messages -> use `slack` skill
48-
- Group chat management (adding/removing members) -> not supported
49-
- Bulk/mass messaging -> always confirm with user first
50-
- Replying in current conversation -> just reply normally (OpenClaw routes automatically)
44+
- macOS 14+ with Messages.app signed in for send/react/bridge actions.
45+
- Full Disk Access for the process context that runs `imsg` or OpenClaw; reads fail without Messages DB access.
46+
- Automation permission for Messages.app when using public `send`.
47+
- Accessibility permission for the process context that runs public `imsg react`; it uses System Events UI automation. Bridge `tapback` uses private API instead.
48+
- Optional Contacts permission for contact-name resolution.
49+
- SMS sends require Text Message Forwarding from the user's iPhone to this Mac.
50+
- Linux reads a copied `chat.db` only; it cannot send, react, launch Messages.app, mark read, or type.
5151

52-
## Requirements
52+
## Resolve Targets
5353

54-
- macOS with Messages.app signed in
55-
- Full Disk Access for terminal
56-
- Automation permission for Messages.app (for sending)
54+
Use `--json` reads. Output is newline-delimited JSON; use `jq -s` when `jq` is available, or consume one object per line directly.
5755

58-
## Common Commands
56+
```bash
57+
imsg chats --limit 25 --json | jq -s
58+
imsg search --query "dinner" --match contains --json | jq -s
59+
imsg history --chat-id 42 --limit 20 --attachments --json | jq -s
60+
imsg group --chat-id 42 --json
61+
```
62+
63+
Target rules:
64+
65+
- DM to a phone/email: use `imsg send --to` when the user gave an exact handle, or after a single unambiguous chat match.
66+
- Existing DM thread: `imsg send --chat-id <id>` is safer than re-resolving a name.
67+
- Existing group: inspect with `imsg group --chat-id <id> --json`; send with `--chat-id`, bridge with the chat GUID from `group`.
68+
- New group: use `chat-create` only when the user explicitly asked to create a group or no existing group matches.
69+
- Ambiguous group names: confirm participants, not just display name.
70+
- SMS: use `--service sms` only when requested or when iMessage fallback is not desired. SMS relay requires Text Message Forwarding.
71+
72+
Do not make `jq` a hard prerequisite for the skill; it is only a convenient formatter for examples.
73+
74+
## Capability Choice
75+
76+
Use public Messages automation when enough:
77+
78+
- Read/list/search/watch: `chats`, `group`, `history`, `search`, `watch`
79+
- Basic text/file send: `send`
80+
- Standard tapback to most recent incoming message in a chat: `react`
5981

60-
### List Chats
82+
Use the private API bridge only for features public automation cannot do:
83+
84+
- Rich replies, text formatting, effects, subjects, multipart sends
85+
- Native Apple Messages polls and poll votes
86+
- Tapback by message GUID or tapback removal
87+
- Edit, unsend, delete, notify anyways
88+
- Read receipts, typing indicators, bridge event watch
89+
- Group create/name/photo/member/leave/delete/mark actions
90+
- Account, whois, nickname checks
91+
92+
Before bridge actions, check:
6193

6294
```bash
63-
imsg chats --limit 10 --json
95+
imsg status --json
6496
```
6597

66-
### View History
98+
If the host supports bridge actions but Messages is not injected yet, ask before running `imsg launch`. It kills and relaunches Messages.app to inject the bridge, so treat it as a visible state change:
6799

68100
```bash
69-
# By chat ID
70-
imsg history --chat-id 1 --limit 20 --json
101+
imsg launch
102+
imsg status --json
103+
```
104+
105+
If SIP, library validation, private entitlement checks, or missing selectors still block the capability, do not ask the user to disable SIP casually. Explain that the requested private-API action is unavailable on this host and offer the closest non-bridge action, if one exists.
71106

72-
# With attachments info
73-
imsg history --chat-id 1 --limit 20 --attachments --json
107+
## DM Scenarios
108+
109+
Exact handle, basic send:
110+
111+
```bash
112+
imsg send --to "+14155551212" --text "On my way" --service auto
74113
```
75114

76-
### Watch for New Messages
115+
Known DM thread:
77116

78117
```bash
79-
imsg watch --chat-id 1 --attachments
118+
imsg send --chat-id 42 --text "On my way"
119+
imsg send --chat-id 42 --file /path/to/photo.jpg
80120
```
81121

82-
### Send Messages
122+
Force channel only when the user asks:
83123

84124
```bash
85-
# Text only
86-
imsg send --to "+14155551212" --text "Hello!"
125+
imsg send --to "+14155551212" --text "green bubble" --service sms
126+
imsg send --to "+14155551212" --text "iMessage only" --service imessage --no-sms-fallback
127+
```
87128

88-
# With attachment
89-
imsg send --to "+14155551212" --text "Check this out" --file /path/to/image.jpg
129+
Threaded reply, formatting, effects, or attachment reply:
90130

91-
# Specify service
92-
imsg send --to "+14155551212" --text "Hi" --service imessage
93-
imsg send --to "+14155551212" --text "Hi" --service sms
131+
```bash
132+
imsg send-rich --chat 'iMessage;-;+15551234567' \
133+
--reply-to <message-guid> --text "reply text"
134+
imsg send-rich --chat 'iMessage;-;+15551234567' --text 'hello world' \
135+
--format '[{"start":0,"length":5,"styles":["bold"]}]'
136+
imsg send-rich --chat 'iMessage;-;+15551234567' --text "boom" --effect impact
137+
imsg send-attachment --chat 'iMessage;-;+15551234567' \
138+
--reply-to <message-guid> --file /path/to/file.jpg
94139
```
95140

96-
## Service Options
141+
Formatting ranges are UTF-16 positions. Supported styles include `bold`, `italic`, `underline`, and `strikethrough`; use `--format-file` for generated JSON.
97142

98-
- `--service imessage` - Force iMessage (requires recipient has iMessage)
99-
- `--service sms` - Force SMS (green bubble)
100-
- `--service auto` - Let Messages.app decide (default)
143+
## Group Scenarios
101144

102-
## Safety Rules
145+
Inspect before acting:
103146

104-
1. **Always confirm recipient and message content** before sending
105-
2. **Never send to unknown numbers** without explicit user approval
106-
3. **Be careful with attachments** - confirm file path exists
107-
4. **Rate limit yourself** - don't spam
147+
```bash
148+
imsg group --chat-id 42 --json
149+
imsg history --chat-id 42 --limit 20 --json | jq -s
150+
```
151+
152+
Send to an existing group:
108153

109-
## Example Workflow
154+
```bash
155+
imsg send --chat-id 42 --text "Works for me"
156+
```
110157

111-
User: "Text mom that I'll be late"
158+
Bridge reply or poll in an existing group:
112159

113160
```bash
114-
# 1. Find mom's chat
115-
imsg chats --limit 20 --json | jq '.[] | select(.displayName | contains("Mom"))'
161+
imsg send-rich --chat 'iMessage;+;chat0000' \
162+
--reply-to <message-guid> --text "replying in thread"
163+
imsg poll send --chat 'iMessage;+;chat0000' \
164+
--question "Dinner?" --option "Pizza" --option "Sushi"
165+
```
116166

117-
# 2. Confirm with user
118-
# "Found Mom at +1555123456. Send 'I'll be late' via iMessage?"
167+
Create or mutate groups only on explicit request:
119168

120-
# 3. Send after confirmation
121-
imsg send --to "+1555123456" --text "I'll be late"
169+
```bash
170+
imsg chat-create --addresses '+15551111111,+15552222222' --name 'Crew' --text 'gm'
171+
imsg chat-name --chat 'iMessage;+;chat0000' --name 'Renamed'
172+
imsg chat-photo --chat 'iMessage;+;chat0000' --file /path/to/group.jpg
173+
imsg chat-add-member --chat 'iMessage;+;chat0000' --address +15553333333
174+
imsg chat-remove-member --chat 'iMessage;+;chat0000' --address +15553333333
175+
imsg chat-leave --chat 'iMessage;+;chat0000'
176+
imsg chat-delete --chat 'iMessage;+;chat0000'
177+
imsg chat-mark --chat 'iMessage;+;chat0000' --read
122178
```
179+
180+
Group mutations are highly visible. Confirm the exact group and participant list before changing membership, name, photo, read state, leaving, or deleting.
181+
182+
## Reactions and Replies
183+
184+
Public `react` is limited: it reacts to the most recent incoming message in the chat.
185+
186+
```bash
187+
imsg react --chat-id 42 --reaction like
188+
imsg react --chat-id 42 --reaction love
189+
imsg react --chat-id 42 --reaction dislike
190+
imsg react --chat-id 42 --reaction laugh
191+
imsg react --chat-id 42 --reaction emphasis
192+
imsg react --chat-id 42 --reaction question
193+
```
194+
195+
For a specific message GUID or removal, use bridge `tapback`:
196+
197+
```bash
198+
imsg tapback --chat 'iMessage;-;+15551234567' --message <message-guid> --kind love
199+
imsg tapback --chat 'iMessage;-;+15551234567' --message <message-guid> --kind love --remove
200+
```
201+
202+
Use `send-rich --reply-to <message-guid>` for threaded replies. Confirm the referenced message if the user says "that" or "the previous one".
203+
204+
## Polls
205+
206+
Native Apple Messages polls require the bridge. Creation needs at least two `--option` values. Voting requires one of `--option-id`, `--option-index`, or `--option`.
207+
208+
Messages renders only the options on a poll balloon; the `--question` title is not shown to recipients. Set `--question` (required) plus at least two `--option` values.
209+
210+
```bash
211+
imsg poll send --chat 'iMessage;-;+15551234567' \
212+
--question "Dinner?" --option "Pizza" --option "Sushi"
213+
imsg poll send --chat 'iMessage;+;chat0000' --reply-to <message-guid> \
214+
--question "Approve?" --option "Yes" --option "No"
215+
imsg poll vote --chat 'iMessage;+;chat0000' \
216+
--poll <poll-message-guid> --option-id <option-id>
217+
```
218+
219+
Find poll IDs and options with:
220+
221+
```bash
222+
imsg history --chat-id 42 --limit 20 --json | jq -s '.[] | select(.poll != null) | {guid, poll}'
223+
```
224+
225+
Poll vote rows are `poll` events, not tapbacks; `watch --reactions` is not required to see them.
226+
227+
## Watch and Long-Running Agents
228+
229+
For a short one-off wait, use `watch`:
230+
231+
```bash
232+
imsg watch --chat-id 42 --since-rowid 9000 --json
233+
imsg watch --chat-id 42 --attachments --convert-attachments --json
234+
imsg watch --chat-id 42 --reactions --json
235+
imsg watch --chat-id 42 --bb-events --json
236+
```
237+
238+
`--since-rowid` is exclusive. Without it, `watch` starts at the newest row. `watch` uses filesystem events plus a low-frequency polling fallback, so it can catch up after missed SQLite sidecar events. Poll objects appear without `--reactions`.
239+
240+
For a daemon or multi-chat integration, use `imsg rpc`. It speaks JSON-RPC 2.0 over stdin/stdout. Inspect `imsg status --json` for `rpc_methods` before using newer bridge or poll methods.
241+
242+
## Safety Rules
243+
244+
- Confirm recipient, chat, and content before every send unless the user's request already contains exact values.
245+
- Confirm visible state changes: read receipts, typing indicators, edits, unsends, deletes, poll votes, tapbacks, group membership, group name/photo, leaving/deleting chats.
246+
- Never send to unknown numbers or ambiguous contact-name matches without approval.
247+
- Confirm attachments exist and are the intended files.
248+
- Prefer E.164 phone numbers; use `--region US` or another region only when needed for local formats.
249+
- Do not use bridge actions just because they are available; use them only when the requested behavior needs them.

0 commit comments

Comments
 (0)