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 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
+ [![npm](https://img.shields.io/npm/v/claude-nonstop)](https://www.npmjs.com/package/claude-nonstop)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-22%2B-green.svg)](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
+ ![claude-nonstop: Slack remote access and multi-account switching](assets/screenshot.png)
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)
Binary file
Binary file