claude-nonstop 0.3.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/.env.example +33 -0
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/assets/icon.jpeg +0 -0
- package/assets/screenshot.png +0 -0
- package/bin/claude-nonstop.js +1679 -0
- package/lib/config.js +163 -0
- package/lib/keychain.js +397 -0
- package/lib/platform.js +9 -0
- package/lib/reauth.js +147 -0
- package/lib/runner.js +566 -0
- package/lib/scorer.js +100 -0
- package/lib/service.js +196 -0
- package/lib/session.js +294 -0
- package/lib/tmux.js +95 -0
- package/lib/usage.js +146 -0
- package/package.json +56 -0
- package/remote/channel-manager.cjs +548 -0
- package/remote/hook-notify.cjs +504 -0
- package/remote/load-env.cjs +32 -0
- package/remote/paths.cjs +17 -0
- package/remote/start-webhook.cjs +97 -0
- package/remote/webhook.cjs +228 -0
- package/scripts/postinstall.js +40 -0
- package/slack-manifest.yaml +32 -0
package/.env.example
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# claude-nonstop Slack Remote Access Configuration
|
|
2
|
+
#
|
|
3
|
+
# Recommended: run "claude-nonstop setup" which writes ~/.claude-nonstop/.env for you.
|
|
4
|
+
# Or copy this file manually:
|
|
5
|
+
# mkdir -p ~/.claude-nonstop && cp .env.example ~/.claude-nonstop/.env
|
|
6
|
+
#
|
|
7
|
+
# CLI flags (--bot-token, --app-token, etc.) override these values.
|
|
8
|
+
# Environment variables (SLACK_BOT_TOKEN, etc.) override .env file values.
|
|
9
|
+
|
|
10
|
+
# ─── Required ─────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
# Bot Token — from Slack App > OAuth & Permissions (starts with xoxb-)
|
|
13
|
+
# Created automatically when you install the app to your workspace.
|
|
14
|
+
SLACK_BOT_TOKEN=xoxb-your-bot-token
|
|
15
|
+
|
|
16
|
+
# App Token — from Slack App > Basic Information > App-Level Tokens (starts with xapp-)
|
|
17
|
+
# Must be generated manually with the "connections:write" scope.
|
|
18
|
+
SLACK_APP_TOKEN=xapp-your-app-token
|
|
19
|
+
|
|
20
|
+
# Slack user ID to auto-invite when creating per-session channels.
|
|
21
|
+
# Without this, channels are created but won't appear in your Slack sidebar.
|
|
22
|
+
# Find your user ID: click your profile picture > Profile > "..." > Copy member ID.
|
|
23
|
+
SLACK_INVITE_USER_ID=
|
|
24
|
+
|
|
25
|
+
# ─── Optional ─────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
# Comma-separated Slack user IDs allowed to send commands via session channels.
|
|
28
|
+
# Empty = allow all workspace members.
|
|
29
|
+
SLACK_ALLOWED_USERS=
|
|
30
|
+
|
|
31
|
+
# Prefix for per-session channel names (default: cn).
|
|
32
|
+
# Channels are named: <prefix>-<project>-<session-id>
|
|
33
|
+
SLACK_CHANNEL_PREFIX=cn
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rahul Chandrasekaran
|
|
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,262 @@
|
|
|
1
|
+
# claude-nonstop
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/claude-nonstop)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
|
|
7
|
+
Multi-account switching + Slack remote access for Claude Code.
|
|
8
|
+
|
|
9
|
+
**Multi-account switching:** When you hit a rate limit mid-session, claude-nonstop kills the idle process, migrates your session to a different account, and resumes — fully automated, zero downtime.
|
|
10
|
+
|
|
11
|
+
**Slack remote access:** Each Claude Code session gets a dedicated Slack channel. Send messages in the channel to control Claude remotely. Claude's responses are posted back to the channel.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
> **Platform:** Tested on macOS only. Linux may work but is untested.
|
|
16
|
+
|
|
17
|
+
[Contributing](CONTRIBUTING.md) | [Security Policy](SECURITY.md) | [Architecture](DESIGN.md)
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
claude-nonstop # Run Claude (best account, auto-switching)
|
|
23
|
+
claude-nonstop -p "fix the bug" # One-shot prompt
|
|
24
|
+
claude-nonstop status # Show usage across all accounts
|
|
25
|
+
claude-nonstop --remote-access # Run with tmux + Slack channels
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Sample `status` output:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
default (alice@gmail.com)
|
|
32
|
+
5-hour: ███░░░░░░░░░░░░░░░░░ 14%
|
|
33
|
+
7-day: ██████░░░░░░░░░░░░░░ 29%
|
|
34
|
+
|
|
35
|
+
work (alice@company.com) <-- best
|
|
36
|
+
5-hour: █░░░░░░░░░░░░░░░░░░░ 3%
|
|
37
|
+
7-day: ██░░░░░░░░░░░░░░░░░░ 8%
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
On launch, claude-nonstop checks usage across all accounts and picks the one with the most headroom. If you hit a rate limit mid-session, it automatically switches to the next best account and resumes your conversation.
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
|
|
44
|
+
**Core:**
|
|
45
|
+
|
|
46
|
+
| Command | Description |
|
|
47
|
+
|---------|-------------|
|
|
48
|
+
| `status` | Show usage with progress bars and reset times |
|
|
49
|
+
| `add <name>` | Add a new Claude account (opens browser for OAuth) |
|
|
50
|
+
| `remove <name>` | Remove an account |
|
|
51
|
+
| `list` | List accounts with auth status |
|
|
52
|
+
| `reauth` | Re-authenticate expired accounts |
|
|
53
|
+
| `resume [id]` | Resume most recent session, or a specific one by ID |
|
|
54
|
+
|
|
55
|
+
**Slack remote access:**
|
|
56
|
+
|
|
57
|
+
| Command | Description |
|
|
58
|
+
|---------|-------------|
|
|
59
|
+
| `setup` | Configure Slack tokens + install hooks (run `setup --help` for flags) |
|
|
60
|
+
| `webhook status` | Show webhook service status |
|
|
61
|
+
| `webhook install` | Install webhook as launchd service (macOS) |
|
|
62
|
+
| `webhook logs` | Tail the webhook log |
|
|
63
|
+
| `hooks install` | Install hooks into all profiles |
|
|
64
|
+
| `hooks status` | Show hook installation status |
|
|
65
|
+
|
|
66
|
+
**Maintenance:**
|
|
67
|
+
|
|
68
|
+
| Command | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| `update` | Update to latest version |
|
|
71
|
+
| `uninstall` | Remove claude-nonstop completely |
|
|
72
|
+
|
|
73
|
+
Any unrecognized arguments are passed through to `claude` directly. Use `-a <name>` to select a specific account.
|
|
74
|
+
|
|
75
|
+
## Install
|
|
76
|
+
|
|
77
|
+
The easiest way to install is to ask Claude Code:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
You: set up claude-nonstop for me
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Claude Code will follow the [setup instructions in CLAUDE.md](CLAUDE.md#setting-up-claude-nonstop-for-a-user) to install, configure accounts, and set up Slack remote access interactively. That file also serves as a reference for AI agents automating the setup.
|
|
84
|
+
|
|
85
|
+
### Manual install
|
|
86
|
+
|
|
87
|
+
**Prerequisites:** Node.js 22+ ([download](https://nodejs.org/)), C/C++ build tools (`xcode-select --install` on macOS), Claude Code CLI ([install](https://docs.anthropic.com/en/docs/claude-code/overview)), and tmux for remote access.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install -g claude-nonstop
|
|
91
|
+
claude-nonstop help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If `npm install -g` fails with compilation errors, you're missing C/C++ build tools.
|
|
95
|
+
|
|
96
|
+
<details>
|
|
97
|
+
<summary>Install from source (for development)</summary>
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://github.com/rchaz/claude-nonstop.git
|
|
101
|
+
cd claude-nonstop
|
|
102
|
+
npm install -g "$(npm pack)"
|
|
103
|
+
```
|
|
104
|
+
</details>
|
|
105
|
+
|
|
106
|
+
## Multi-Account Setup
|
|
107
|
+
|
|
108
|
+
Your existing `~/.claude` account is auto-detected as "default". Verify with `claude-nonstop list`.
|
|
109
|
+
|
|
110
|
+
Add additional accounts (each must be a different Claude organization). Two accounts can share the same email if they belong to different orgs. Names can contain letters, numbers, hyphens, and underscores:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
claude-nonstop add work
|
|
114
|
+
claude-nonstop add personal
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Each `add` opens your browser for OAuth. After login, claude-nonstop checks for duplicate accounts (same organization) and removes them automatically.
|
|
118
|
+
|
|
119
|
+
Verify all accounts are working:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
claude-nonstop status
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then just run `claude-nonstop` — rate limit switching is automatic.
|
|
126
|
+
|
|
127
|
+
**Troubleshooting:**
|
|
128
|
+
- OAuth didn't complete? Run `claude-nonstop reauth`
|
|
129
|
+
- Status shows `error (HTTP 401)`? Run `claude-nonstop reauth`
|
|
130
|
+
- "No credentials found"? Run `CLAUDE_CONFIG_DIR="$HOME/.claude-nonstop/profiles/<name>" claude auth login`
|
|
131
|
+
|
|
132
|
+
**Optional aliases** (`~/.zshrc` or `~/.bashrc`):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
alias claude='claude-nonstop'
|
|
136
|
+
alias cn='claude-nonstop --dangerously-skip-permissions'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Slack Remote Access
|
|
140
|
+
|
|
141
|
+
### 1. Create a Slack App
|
|
142
|
+
|
|
143
|
+
Go to [api.slack.com/apps](https://api.slack.com/apps) > **Create New App** > **From a manifest**. Paste [`slack-manifest.yaml`](slack-manifest.yaml), click **Create**, then **Install to Workspace**.
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary>Manual setup (without manifest)</summary>
|
|
147
|
+
|
|
148
|
+
Create a new app at [api.slack.com/apps](https://api.slack.com/apps). Enable Socket Mode (Settings > Socket Mode). Add bot token scopes: `chat:write`, `channels:manage`, `channels:history`, `channels:read`, `reactions:read`, `reactions:write`, `app_mentions:read`, `im:history`, `im:read`, `im:write`. Subscribe to bot events: `message.channels`, `message.im`, `app_mention`. Install to workspace.
|
|
149
|
+
</details>
|
|
150
|
+
|
|
151
|
+
**Collect two tokens:**
|
|
152
|
+
|
|
153
|
+
1. **Bot Token** (`xoxb-...`) — OAuth & Permissions page (created on install)
|
|
154
|
+
2. **App Token** (`xapp-...`) — Basic Information > App-Level Tokens > **Generate Token and Scopes** > add `connections:write` scope > Generate
|
|
155
|
+
|
|
156
|
+
### 2. Run setup
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
claude-nonstop setup --bot-token xoxb-... --app-token xapp-... --invite-user-id U12345ABCDE
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This writes `~/.claude-nonstop/.env`, installs hooks, and starts the webhook service (macOS). Run `setup --help` for all flags. For interactive setup, just run `claude-nonstop setup`.
|
|
163
|
+
|
|
164
|
+
Find your Slack User ID: click your profile picture > Profile > three-dot menu > Copy member ID.
|
|
165
|
+
|
|
166
|
+
### 3. Verify
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
claude-nonstop webhook status # Should show "running" with a PID
|
|
170
|
+
claude-nonstop hooks status # All should show "installed"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 4. Run with remote access
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
claude-nonstop --remote-access
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This creates a tmux session named after the current directory, enables `--dangerously-skip-permissions` for unattended operation, and sets `CLAUDE_REMOTE_ACCESS=true` so each session gets a dedicated Slack channel (e.g., `#cn-myproject-abc12345`). Reply in the channel to send messages to Claude.
|
|
180
|
+
|
|
181
|
+
**Control commands** in session channels:
|
|
182
|
+
|
|
183
|
+
| Command | Action |
|
|
184
|
+
|---------|--------|
|
|
185
|
+
| `!stop` | Interrupt Claude (Ctrl+C) |
|
|
186
|
+
| `!status` | Show current terminal output |
|
|
187
|
+
| `!cmd <text>` | Relay text verbatim (e.g. `!cmd /clear`) |
|
|
188
|
+
| `!help` | List available commands |
|
|
189
|
+
| `!archive` | Archive the channel |
|
|
190
|
+
|
|
191
|
+
**Note:** Slack message relay sends keystrokes to tmux. Claude must be waiting for input to receive messages. If Claude is mid-processing, keystrokes queue and are delivered when Claude next waits.
|
|
192
|
+
|
|
193
|
+
**Security:** `--remote-access` implies `--dangerously-skip-permissions`, giving Claude full system access. Use `SLACK_ALLOWED_USERS` to restrict who can send commands via Slack.
|
|
194
|
+
|
|
195
|
+
**Troubleshooting:**
|
|
196
|
+
- Channel not created? Run `claude-nonstop hooks install` then `hooks status`
|
|
197
|
+
- Webhook not receiving? Run `claude-nonstop webhook status` then `webhook logs`
|
|
198
|
+
- Messages not reaching Claude? Check `tmux ls` and that Claude is waiting for input
|
|
199
|
+
|
|
200
|
+
## How It Works
|
|
201
|
+
|
|
202
|
+
**Multi-account switching** queries the Anthropic usage API for all accounts (~200ms), picks the one with the most headroom, then monitors Claude's output for rate limit messages in real-time. On detection: kill, migrate session files to the next account, resume with `claude --resume`.
|
|
203
|
+
|
|
204
|
+
**Slack remote access** uses Claude Code [hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) — `SessionStart` creates a Slack channel, `Stop` posts a completion summary. A separate webhook process connects via Slack Socket Mode and relays channel messages to tmux. The runner scrapes PTY output for tool activity and posts progress updates to Slack every ~10 seconds.
|
|
205
|
+
|
|
206
|
+
## Architecture
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
claude-nonstop/
|
|
210
|
+
├── bin/claude-nonstop.js CLI entry point and command routing
|
|
211
|
+
├── lib/ Core logic (ESM)
|
|
212
|
+
│ ├── config.js Account registry
|
|
213
|
+
│ ├── keychain.js OS credential store reading
|
|
214
|
+
│ ├── usage.js Anthropic usage API client
|
|
215
|
+
│ ├── scorer.js Best-account selection
|
|
216
|
+
│ ├── session.js Session file migration
|
|
217
|
+
│ ├── runner.js Process wrapper + rate limit detection
|
|
218
|
+
│ ├── service.js launchd service management (macOS)
|
|
219
|
+
│ ├── tmux.js tmux session management
|
|
220
|
+
│ ├── reauth.js Re-authentication flow
|
|
221
|
+
│ └── platform.js OS detection
|
|
222
|
+
├── remote/ Slack remote access subsystem (CJS)
|
|
223
|
+
│ ├── hook-notify.cjs Hook entry point
|
|
224
|
+
│ ├── channel-manager.cjs Slack channel lifecycle
|
|
225
|
+
│ ├── webhook.cjs Socket Mode handler (Slack -> tmux)
|
|
226
|
+
│ ├── start-webhook.cjs Webhook process entry point
|
|
227
|
+
│ ├── load-env.cjs Environment file loader
|
|
228
|
+
│ └── paths.cjs Shared path constants
|
|
229
|
+
└── scripts/postinstall.js Restart webhook on npm install
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
User data lives under `~/.claude-nonstop/` (config, `.env`, profiles, logs). See [DESIGN.md](DESIGN.md) for details.
|
|
233
|
+
|
|
234
|
+
## Troubleshooting
|
|
235
|
+
|
|
236
|
+
### `npm install` fails with compilation errors
|
|
237
|
+
|
|
238
|
+
`node-pty` requires C/C++ build tools: `xcode-select --install` (macOS), then re-run `npm install`.
|
|
239
|
+
|
|
240
|
+
### Usage shows "error (HTTP 401)"
|
|
241
|
+
|
|
242
|
+
OAuth token expired. Run `claude-nonstop reauth` to refresh all expired accounts.
|
|
243
|
+
|
|
244
|
+
### Webhook not receiving messages
|
|
245
|
+
|
|
246
|
+
Check `claude-nonstop webhook status` and `webhook logs`. Verify Socket Mode is enabled and bot events (`message.channels`, `message.im`) are subscribed in your Slack app settings.
|
|
247
|
+
|
|
248
|
+
### Messages not reaching Claude
|
|
249
|
+
|
|
250
|
+
Claude must be waiting for input. Check `tmux ls` and `~/.claude-nonstop/data/channel-map.json`.
|
|
251
|
+
|
|
252
|
+
## Platform Support
|
|
253
|
+
|
|
254
|
+
| Platform | Credential Store | Service Management | Status |
|
|
255
|
+
|----------|-----------------|-------------------|--------|
|
|
256
|
+
| macOS | Keychain (`security`) | launchd | Tested |
|
|
257
|
+
| Linux | Secret Service (`secret-tool`) | Manual (systemd) | Untested |
|
|
258
|
+
| Windows | — | — | Not supported |
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
[MIT](LICENSE)
|
package/assets/icon.jpeg
ADDED
|
Binary file
|
|
Binary file
|