clawty 0.0.1
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 +157 -0
- package/bin/clawty.ts +2 -0
- package/bin/imessage-claude.ts +2 -0
- package/package.json +44 -0
- package/src/claude/runner.ts +15 -0
- package/src/cli.ts +1959 -0
- package/src/imessage/database.ts +427 -0
- package/src/imessage/sender.ts +196 -0
- package/src/imessage/types.ts +9 -0
- package/src/index.ts +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# imessage-claude-code
|
|
2
|
+
|
|
3
|
+
Bridge iMessage to Claude Code CLI — text Claude from your phone.
|
|
4
|
+
|
|
5
|
+
Send an iMessage from your phone and Claude Code processes it on your Mac, then texts you back the response. Maintains persistent conversation context, streams Claude's thinking and tool calls in a live terminal UI, and supports slash commands for session management.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
| Step | What happens |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| **iPhone** | You send an iMessage |
|
|
12
|
+
| **Mac Messages.app** | Message lands in `chat.db` |
|
|
13
|
+
| **Bridge (polling)** | Reads new messages from SQLite |
|
|
14
|
+
| **Claude Code CLI** | `claude -p` streams thinking, tool calls, and text |
|
|
15
|
+
| **Bridge** | Sends the final response back via JXA/AppleScript |
|
|
16
|
+
| **iPhone** | You receive Claude's reply as an iMessage |
|
|
17
|
+
|
|
18
|
+
You can also type messages directly in the terminal — they're sent to Claude the same way.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- **macOS** (required — iMessage only runs on Apple platforms)
|
|
23
|
+
- **Bun** >= 1.0 (`curl -fsSL https://bun.sh/install | bash`)
|
|
24
|
+
- **Claude Code CLI** installed and authenticated:
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g @anthropic-ai/claude-code
|
|
27
|
+
claude --version # verify
|
|
28
|
+
```
|
|
29
|
+
- **Messages.app** open and signed in to iMessage
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
### 1. Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/nichochar/imessage-claude-code.git
|
|
37
|
+
cd imessage-claude-code
|
|
38
|
+
bun install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Grant macOS Permissions
|
|
42
|
+
|
|
43
|
+
**Full Disk Access** (required to read iMessage database):
|
|
44
|
+
1. Open **System Settings → Privacy & Security → Full Disk Access**
|
|
45
|
+
2. Click **+** and add your terminal app (Terminal.app, iTerm2, Warp, etc.)
|
|
46
|
+
3. **Restart your terminal** after granting
|
|
47
|
+
|
|
48
|
+
**Automation** (required to send iMessages):
|
|
49
|
+
- macOS will prompt you on first run — click **Allow**
|
|
50
|
+
- Or pre-grant in **System Settings → Privacy & Security → Automation** → enable Messages for your terminal
|
|
51
|
+
|
|
52
|
+
### 3. Start the Bridge
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bun run src/cli.ts --contact "+1234567890"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Replace `+1234567890` with your phone number (the one you'll text from). If you omit `--contact`, the bridge will prompt you for it interactively.
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
### CLI Options
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Options:
|
|
66
|
+
--contact, -c <phone|email> Contact to bridge with (prompted if omitted)
|
|
67
|
+
--dir, -d <path> Working directory for Claude Code (default: cwd)
|
|
68
|
+
--model, -m <model> Claude model (e.g. sonnet, opus, haiku)
|
|
69
|
+
--interval, -i <ms> Poll interval in ms (default: 2000)
|
|
70
|
+
--permission-mode <mode> Permission mode (default: bypassPermissions)
|
|
71
|
+
--help, -h Show help
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Also available as `clawty` (alias for `imessage-claude`).
|
|
75
|
+
|
|
76
|
+
### Examples
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Basic — respond to texts from your phone number
|
|
80
|
+
bun run src/cli.ts -c "+1234567890"
|
|
81
|
+
|
|
82
|
+
# With a project directory so Claude has file context
|
|
83
|
+
bun run src/cli.ts -c "+1234567890" -d ~/projects/myapp
|
|
84
|
+
|
|
85
|
+
# Use a specific model
|
|
86
|
+
bun run src/cli.ts -c "+1234567890" -m opus
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Terminal UI
|
|
90
|
+
|
|
91
|
+
The terminal shows a live TUI with:
|
|
92
|
+
|
|
93
|
+
- **Input prompt** (`>`) — always visible at the bottom
|
|
94
|
+
- **Thinking spinner** — animated braille spinner while waiting for Claude
|
|
95
|
+
- **Streaming output** — Claude's response streams in real time, with the prompt pinned below
|
|
96
|
+
- **Tool calls** — shows tool name and first parameter as Claude works
|
|
97
|
+
- **Tool results** — previews output (first 5 lines), errors highlighted in red
|
|
98
|
+
- **Session info** — model, version, MCP servers, tool counts on first response
|
|
99
|
+
- **Cost tracking** — turn count, duration, and cost displayed after each response
|
|
100
|
+
- **Message queuing** — type and send messages at any time; queued messages show a `○ queued` indicator
|
|
101
|
+
- **Multi-line input** — end a line with `\` to continue on the next line
|
|
102
|
+
|
|
103
|
+
### Commands
|
|
104
|
+
|
|
105
|
+
Send these from your phone or type them in the terminal:
|
|
106
|
+
|
|
107
|
+
| Command | Aliases | Description |
|
|
108
|
+
|---------|---------|-------------|
|
|
109
|
+
| `/help` | `/commands` | Show available commands |
|
|
110
|
+
| `/new` | `/reset` | Start a new conversation (fresh session) |
|
|
111
|
+
| `/compact` | — | Summarize context and start a fresh session with the summary |
|
|
112
|
+
| `/status` | — | Show session ID, model, directory, message count, cost, uptime |
|
|
113
|
+
| `/model <name>` | — | Switch model (e.g. `/model opus`) |
|
|
114
|
+
| `/dir <path>` | `/cd` | Change working directory |
|
|
115
|
+
| `/cost` | — | Show cost and API time breakdown |
|
|
116
|
+
| `/resume <id>` | — | Resume a previous session by ID |
|
|
117
|
+
| `/whoami` | — | Show your contact info |
|
|
118
|
+
|
|
119
|
+
## Library API
|
|
120
|
+
|
|
121
|
+
The package exports its core components for programmatic use:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { IMessageDatabase } from "clawty";
|
|
125
|
+
import { sendIMessage, verifySendPermission } from "clawty";
|
|
126
|
+
import { verifyClaudeInstalled } from "clawty";
|
|
127
|
+
import type { IMessage } from "clawty";
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Security
|
|
131
|
+
|
|
132
|
+
- Runs with `--dangerously-skip-permissions` by default — the `--permission-mode` flag can override this
|
|
133
|
+
- Only messages from the **single configured contact** are processed
|
|
134
|
+
- Group chats are filtered out
|
|
135
|
+
- Message content is never embedded in script strings — always written to temp files first
|
|
136
|
+
- SQL queries are parameterized — no string interpolation
|
|
137
|
+
- Echo detection prevents the bridge from responding to its own messages
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
| Problem | Fix |
|
|
142
|
+
|---------|-----|
|
|
143
|
+
| `authorization denied` when starting | Grant Full Disk Access to your terminal, then **restart it** |
|
|
144
|
+
| `Cannot connect to Messages.app` | Open Messages.app, sign in to iMessage, allow Automation permission |
|
|
145
|
+
| `Claude Code CLI not found` | Run `npm i -g @anthropic-ai/claude-code` and verify `claude --version` |
|
|
146
|
+
| Messages not detected | Verify the contact format matches (e.g., `+1` prefix for US numbers) |
|
|
147
|
+
| Response never arrives | Check the terminal for errors — Claude may have timed out or errored |
|
|
148
|
+
|
|
149
|
+
## Disclaimer
|
|
150
|
+
|
|
151
|
+
Clawty is provided "as is", without warranty of any kind, express or implied. The owners, authors, and maintainers of Clawty are not responsible for any damages, data loss, unintended messages, API charges, security vulnerabilities, or any other consequences resulting from the use of this software. You use Clawty entirely at your own risk.
|
|
152
|
+
|
|
153
|
+
This software grants an AI model access to your filesystem and the ability to execute arbitrary commands. It reads your iMessage database and sends messages on your behalf. There may be undiscovered security vulnerabilities. By using Clawty, you accept full responsibility for ensuring appropriate permissions, compliance with applicable laws, and any costs or consequences incurred.
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT
|
package/bin/clawty.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clawty",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"module": "src/index.ts",
|
|
5
|
+
"devDependencies": {
|
|
6
|
+
"@types/bun": "latest"
|
|
7
|
+
},
|
|
8
|
+
"peerDependencies": {
|
|
9
|
+
"typescript": "^5"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"imessage-claude": "./bin/imessage-claude.ts",
|
|
13
|
+
"clawty": "./bin/clawty.ts"
|
|
14
|
+
},
|
|
15
|
+
"description": "Bridge iMessage to Claude Code CLI — text Claude from your phone",
|
|
16
|
+
"engines": {
|
|
17
|
+
"bun": ">=1.0.0"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"src",
|
|
21
|
+
"bin",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"imessage",
|
|
26
|
+
"claude",
|
|
27
|
+
"claude-code",
|
|
28
|
+
"ai",
|
|
29
|
+
"bridge",
|
|
30
|
+
"macos",
|
|
31
|
+
"sms",
|
|
32
|
+
"cli"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"os": [
|
|
36
|
+
"darwin"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"start": "bun run src/cli.ts",
|
|
40
|
+
"dev": "bun run src/cli.ts"
|
|
41
|
+
},
|
|
42
|
+
"type": "module",
|
|
43
|
+
"dependencies": {}
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if Claude Code CLI is available on PATH
|
|
3
|
+
*/
|
|
4
|
+
export async function verifyClaudeInstalled(): Promise<boolean> {
|
|
5
|
+
try {
|
|
6
|
+
const proc = Bun.spawn(["claude", "--version"], {
|
|
7
|
+
stdout: "pipe",
|
|
8
|
+
stderr: "pipe",
|
|
9
|
+
});
|
|
10
|
+
const exitCode = await proc.exited;
|
|
11
|
+
return exitCode === 0;
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|