@sneub/pair 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/LICENSE +21 -0
- package/README.md +169 -0
- package/config.example.json +22 -0
- package/dist/cli.js +30347 -0
- package/package.json +47 -0
- package/tools/examples/hello +7 -0
- package/tools/todoist/todoist-add +76 -0
- package/tools/todoist/todoist-complete +29 -0
- package/tools/todoist/todoist-delete +29 -0
- package/tools/todoist/todoist-list +51 -0
- package/tools/todoist/todoist-reopen +29 -0
- package/tools/todoist/todoist-update +86 -0
- package/workspace-init/MEMORY.md +4 -0
- package/workspace-init/SYSTEM.md +44 -0
- package/workspace-init/USER.md +13 -0
- package/workspace-init/tasks.md +7 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shane
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# pair
|
|
2
|
+
|
|
3
|
+
A personal AI assistant powered by Claude. Connects Telegram and Slack to
|
|
4
|
+
Claude with persistent memory, a workspace of notes, and custom tools — all
|
|
5
|
+
running as a long-lived daemon on your own machine.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Pair is a Bun CLI. Install it globally:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun install -g @sneub/pair
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
mkdir my-agent && cd my-agent
|
|
19
|
+
pair init # scaffolds config.json, workspace/, .env, .gitignore
|
|
20
|
+
# edit .env with your API keys / bot tokens
|
|
21
|
+
pair run # foreground
|
|
22
|
+
pair run -d # background daemon
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`pair init` is non-interactive and creates everything in the current directory.
|
|
26
|
+
After editing `.env`, point it at Telegram or Slack and start chatting.
|
|
27
|
+
|
|
28
|
+
For an interactive setup that writes to `~/.pair/` instead, use `pair setup`.
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
| Command | Description |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `pair init` | Bootstrap a new agent directory in the current working dir (non-interactive) |
|
|
35
|
+
| `pair setup` | Interactive setup wizard — creates config, workspace, prompts for keys |
|
|
36
|
+
| `pair doctor` | Run diagnostic checks on your configuration |
|
|
37
|
+
| `pair tool list` | Show packaged and user tools, and which are enabled |
|
|
38
|
+
| `pair tool enable <name>` | Enable a packaged tool by adding it to `config.tools.enabled` |
|
|
39
|
+
| `pair tool disable <name>` | Disable a packaged tool |
|
|
40
|
+
| `pair run` | Start Pair in the foreground (alias: `pair start`) |
|
|
41
|
+
| `pair run -d` | Start Pair as a background daemon |
|
|
42
|
+
| `pair stop` | Stop the running daemon (SIGTERM, then SIGKILL after 10s) |
|
|
43
|
+
| `pair status` | Show running state, workspace stats, and config summary |
|
|
44
|
+
|
|
45
|
+
## Configuration
|
|
46
|
+
|
|
47
|
+
Pair stores its configuration under its resolved home directory:
|
|
48
|
+
|
|
49
|
+
1. `$PAIR_HOME` — explicit override (used by Docker and multi-instance setups)
|
|
50
|
+
2. `./config.json` in the current working directory → **local mode**
|
|
51
|
+
3. `~/.pair/` → **global mode** (default)
|
|
52
|
+
|
|
53
|
+
Within that home directory, Pair reads `config.json` (non-secret settings)
|
|
54
|
+
and `.env` (secrets). Environment variables always override values from
|
|
55
|
+
`config.json`, so you can keep non-secret settings in JSON and inject
|
|
56
|
+
secrets at deploy time.
|
|
57
|
+
|
|
58
|
+
### config.json
|
|
59
|
+
|
|
60
|
+
| Field | Type | Default | Description |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| `pair.sessionTimeoutMinutes` | number | `30` | Idle time before a session expires |
|
|
63
|
+
| `pair.logLevel` | string | `"info"` | `debug`, `info`, `warn`, `error` |
|
|
64
|
+
| `pair.model` | string | `"claude-sonnet-4-6"` | Claude model to use |
|
|
65
|
+
| `pair.workspaceDir` | string | `"~/.pair/workspace"` | Path to workspace directory |
|
|
66
|
+
| `pair.healthCheckPort` | number | _(unset)_ | Port for HTTP health check endpoint |
|
|
67
|
+
| `pair.authMode` | string | `"api-key"` | `"api-key"` or `"oauth"` (Claude Max/Pro) |
|
|
68
|
+
| `telegram.allowedUsers` | number[] | `[]` | Telegram user IDs allowed to interact |
|
|
69
|
+
| `slack.allowedUsers` | string[] | `[]` | Slack user IDs allowed to interact |
|
|
70
|
+
| `mcp.servers` | object | `{}` | MCP server configurations |
|
|
71
|
+
| `tools.enabled` | string[] | `["examples"]` | Packaged tool names to enable |
|
|
72
|
+
|
|
73
|
+
### Environment variables
|
|
74
|
+
|
|
75
|
+
| Variable | Required | Description |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `ANTHROPIC_API_KEY` | api-key mode only | Anthropic API key for Claude |
|
|
78
|
+
| `PAIR_AUTH_MODE` | No | `api-key` (default) or `oauth` (Claude Max/Pro) |
|
|
79
|
+
| `PAIR_API_KEY_HELPER` | No | Path to a script that outputs fresh credentials |
|
|
80
|
+
| `TELEGRAM_BOT_TOKEN` | No | Telegram Bot API token |
|
|
81
|
+
| `TELEGRAM_ALLOWED_USERS` | No | Comma-separated Telegram user IDs |
|
|
82
|
+
| `SLACK_BOT_TOKEN` | No | Slack bot OAuth token (`xoxb-...`) |
|
|
83
|
+
| `SLACK_APP_TOKEN` | No | Slack app-level token (`xapp-...`) |
|
|
84
|
+
| `SLACK_SIGNING_SECRET` | No | Slack signing secret |
|
|
85
|
+
| `PAIR_MODEL` | No | Override the Claude model |
|
|
86
|
+
| `PAIR_LOG_LEVEL` | No | Override the log level |
|
|
87
|
+
| `PAIR_WORKSPACE_DIR` | No | Override the workspace directory |
|
|
88
|
+
| `PAIR_HEALTH_PORT` | No | Override the health check port |
|
|
89
|
+
| `PAIR_HOME` | No | Override the Pair home directory |
|
|
90
|
+
|
|
91
|
+
## Workspace
|
|
92
|
+
|
|
93
|
+
After `pair init`, your workspace lives at `./workspace/` (or
|
|
94
|
+
`~/.pair/workspace/` in global mode) and contains files Claude reads on every
|
|
95
|
+
turn:
|
|
96
|
+
|
|
97
|
+
- `SYSTEM.md` — base system prompt and personality
|
|
98
|
+
- `USER.md` — information about you
|
|
99
|
+
- `MEMORY.md` — persistent memory (Claude can update this)
|
|
100
|
+
- `tasks.md` — your current task list
|
|
101
|
+
|
|
102
|
+
Edit them freely — they're how you customize Pair's behavior.
|
|
103
|
+
|
|
104
|
+
## Tools
|
|
105
|
+
|
|
106
|
+
Tools are the quickest way to add custom capabilities. You have two options:
|
|
107
|
+
enable one of the packaged tools that ship with Pair, or drop your own
|
|
108
|
+
executable into `<pair home>/tools/`.
|
|
109
|
+
|
|
110
|
+
**Enable a packaged tool:**
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pair tool list # see what's available
|
|
114
|
+
pair tool enable todoist # adds "todoist" to config.tools.enabled
|
|
115
|
+
echo "TODOIST_API_TOKEN=..." >> .env
|
|
116
|
+
pair stop && pair run -d
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Write a custom tool** by dropping a file into `./tools/`:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
#!/usr/bin/env bash
|
|
123
|
+
# name: uk-holiday
|
|
124
|
+
# description: Return whether today is a UK bank holiday.
|
|
125
|
+
# usage: uk-holiday
|
|
126
|
+
|
|
127
|
+
curl -s https://www.gov.uk/bank-holidays.json | jq -r \
|
|
128
|
+
--arg today "$(date +%Y-%m-%d)" '
|
|
129
|
+
.["england-and-wales"].events
|
|
130
|
+
| map(select(.date == $today))
|
|
131
|
+
| if length > 0 then "yes — \(.[0].title)" else "no" end
|
|
132
|
+
'
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
chmod +x ./tools/uk-holiday
|
|
137
|
+
pair stop && pair run -d
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Now DM Pair _"is today a UK bank holiday?"_ and it'll run the tool. Any
|
|
141
|
+
language works (bash, Bun, Node, Python, Ruby). Pair parses a short header
|
|
142
|
+
comment at the top of each file for the description it shows to Claude.
|
|
143
|
+
|
|
144
|
+
## MCP servers
|
|
145
|
+
|
|
146
|
+
Pair supports [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
147
|
+
servers for extending Claude's capabilities. Configure them in `config.json`:
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"mcp": {
|
|
152
|
+
"servers": {
|
|
153
|
+
"filesystem": {
|
|
154
|
+
"command": "npx",
|
|
155
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Requirements
|
|
163
|
+
|
|
164
|
+
- [Bun](https://bun.sh) ≥ 1.1.0
|
|
165
|
+
- An Anthropic API key (or a Claude Max/Pro account for OAuth mode)
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pair": {
|
|
3
|
+
"sessionTimeoutMinutes": 30,
|
|
4
|
+
"logLevel": "info",
|
|
5
|
+
"model": "claude-sonnet-4-6"
|
|
6
|
+
},
|
|
7
|
+
"telegram": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"allowedUsers": []
|
|
10
|
+
},
|
|
11
|
+
"slack": {
|
|
12
|
+
"enabled": false,
|
|
13
|
+
"allowedUsers": [],
|
|
14
|
+
"channels": []
|
|
15
|
+
},
|
|
16
|
+
"mcp": {
|
|
17
|
+
"servers": {}
|
|
18
|
+
},
|
|
19
|
+
"tools": {
|
|
20
|
+
"enabled": ["examples"]
|
|
21
|
+
}
|
|
22
|
+
}
|