@lifeaitools/clauth 1.16.9 → 1.18.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.
@@ -9,49 +9,49 @@ Hardware-bound credential vault for the LIFEAI stack. Your machine is the second
9
9
 
10
10
  ---
11
11
 
12
- ## How Claude Interfaces with clauth
13
-
14
- > **CRITICAL:** Agents should use the local daemon for credential discovery and
15
- > exact secret retrieval. Do not ask the user for the vault password just to get
16
- > a key, do not use interactive prompts, and do not walk every service.
17
-
18
- ### Method 1 — Local daemon (preferred for agents)
19
-
20
- Discover services without reading secrets:
21
-
22
- ```bash
23
- curl -s http://127.0.0.1:52437/ping
24
- curl -s http://127.0.0.1:52437/knowledge
25
- curl -s http://127.0.0.1:52437/list-services
26
- ```
27
-
28
- Retrieve exactly one credential only when the next command needs it:
29
-
30
- ```bash
31
- curl -s http://127.0.0.1:52437/v/<service>
32
- ```
33
-
34
- `/knowledge` is safe to cache for a session: it returns service metadata and
35
- `has_key`, but no raw secrets and no Vault secret names. `/status` uses the same
36
- short metadata cache and can be forced with `?refresh=1`.
37
-
38
- ### Method 2 — CLI with `--pw` flag (admin/setup only)
39
-
40
- All clauth commands accept `-p` / `--pw <password>` to skip the interactive
41
- password prompt. Use this for local admin/setup tasks, not routine agent secret
42
- retrieval:
43
-
44
- ```bash
45
- clauth status -p "YourPassword"
46
- clauth test -p "YourPassword"
47
- clauth enable github -p "YourPassword"
48
- clauth write key github -p "YourPassword" # still prompts for the key value
49
- ```
50
-
51
- ### Method 3 — Direct API calls (implementation/debugging only)
52
-
53
- Call the auth-vault Edge Function directly only when debugging clauth internals.
54
- Normal agents should not bypass the daemon metadata cache.
12
+ ## How Claude Interfaces with clauth
13
+
14
+ > **CRITICAL:** Agents should use the local daemon for credential discovery and
15
+ > exact secret retrieval. Do not ask the user for the vault password just to get
16
+ > a key, do not use interactive prompts, and do not walk every service.
17
+
18
+ ### Method 1 — Local daemon (preferred for agents)
19
+
20
+ Discover services without reading secrets:
21
+
22
+ ```bash
23
+ curl -s http://127.0.0.1:52437/ping
24
+ curl -s http://127.0.0.1:52437/knowledge
25
+ curl -s http://127.0.0.1:52437/list-services
26
+ ```
27
+
28
+ Retrieve exactly one credential only when the next command needs it:
29
+
30
+ ```bash
31
+ curl -s http://127.0.0.1:52437/v/<service>
32
+ ```
33
+
34
+ `/knowledge` is safe to cache for a session: it returns service metadata and
35
+ `has_key`, but no raw secrets and no Vault secret names. `/status` uses the same
36
+ short metadata cache and can be forced with `?refresh=1`.
37
+
38
+ ### Method 2 — CLI with `--pw` flag (admin/setup only)
39
+
40
+ All clauth commands accept `-p` / `--pw <password>` to skip the interactive
41
+ password prompt. Use this for local admin/setup tasks, not routine agent secret
42
+ retrieval:
43
+
44
+ ```bash
45
+ clauth status -p "YourPassword"
46
+ clauth test -p "YourPassword"
47
+ clauth enable github -p "YourPassword"
48
+ clauth write key github -p "YourPassword" # still prompts for the key value
49
+ ```
50
+
51
+ ### Method 3 — Direct API calls (implementation/debugging only)
52
+
53
+ Call the auth-vault Edge Function directly only when debugging clauth internals.
54
+ Normal agents should not bypass the daemon metadata cache.
55
55
 
56
56
  **Base URL:** `https://<project-ref>.supabase.co/functions/v1/auth-vault`
57
57
  **Auth header:** `Authorization: Bearer <supabase-anon-key>`
@@ -97,12 +97,12 @@ const timestamp = window * windowMs;
97
97
 
98
98
  All auth routes require: `machine_hash`, `token`, `timestamp`, `password`.
99
99
 
100
- ### Password Handling
101
-
102
- - Do not ask the user for their clauth password for routine credential lookup
103
- - Use the unlocked local daemon whenever possible
104
- - Never log or echo the password
105
- - If the daemon is locked, ask the user to unlock `http://127.0.0.1:52437`
100
+ ### Password Handling
101
+
102
+ - Do not ask the user for their clauth password for routine credential lookup
103
+ - Use the unlocked local daemon whenever possible
104
+ - Never log or echo the password
105
+ - If the daemon is locked, ask the user to unlock `http://127.0.0.1:52437`
106
106
 
107
107
  ---
108
108
 
@@ -165,14 +165,14 @@ See `references/keys-guide.md` for where to find every credential.
165
165
  ```
166
166
  clauth install [--ref R] [--pat P] First-time: provision Supabase + install skill
167
167
  clauth setup [--admin-token T] [-p P] Register this machine
168
- clauth status [-p P] All services + state
169
- clauth test [-p P] Verify HMAC connection
170
- clauth list [-p P] Service names
171
- clauth search <query> [-p P] Search names and metadata
172
- clauth search <query> --addresses [-p P]
173
- Also search redacted address hints (may read multiple secrets)
174
-
175
- clauth write key <service> [-p P] Store a credential
168
+ clauth status [-p P] All services + state
169
+ clauth test [-p P] Verify HMAC connection
170
+ clauth list [-p P] Service names
171
+ clauth search <query> [-p P] Search names and metadata
172
+ clauth search <query> --addresses [-p P]
173
+ Also search redacted address hints (may read multiple secrets)
174
+
175
+ clauth write key <service> [-p P] Store a credential
176
176
  clauth write pw [-p P] Change password
177
177
  clauth enable <svc|all> [-p P] Activate service
178
178
  clauth disable <svc|all> [-p P] Suspend service
@@ -201,65 +201,65 @@ Service type `fileserver` — mount configuration for fs tools (UI-only config).
201
201
 
202
202
  ---
203
203
 
204
- ## Daemon Metadata Cache
205
-
206
- When discovering service names, do not retrieve secrets. Use the daemon metadata
207
- cache:
208
-
209
- ```bash
210
- curl -s http://127.0.0.1:52437/knowledge
211
- curl -s http://127.0.0.1:52437/list-services
212
- ```
213
-
214
- `/knowledge` is agent-safe: it returns service metadata and `has_key`, but no
215
- raw secrets and no Vault secret names. Fetch `GET /v/<service>` only for the one
216
- exact credential needed by the next command. Never walk every service and never
217
- bulk-fetch all secrets.
218
-
219
- ## MCP Server (v1.16.9+)
220
-
221
- clauth runs as an MCP server with five namespaced paths and safe
222
- credential-discovery tools:
223
-
224
- | Path | Namespace | Tools |
225
- |------|-----------|-------|
226
- | `/clauth` | `clauth_*` + runtime helpers | 23 default live tools, including `clauth_knowledge` |
227
- | `/gws` | `gws_*` | 6 Google Workspace tools |
228
- | `/fs` | `fs_*` | 20 filesystem and git-safe file tools |
229
- | `/chitchat` | `chitchat_*` | 7 collaboration relay tools |
230
- | `/codevelop` | `codevelop_*` | 7 peer development tools |
231
- | `/mcp` | all | 63 tools combined |
232
-
233
- The default live `/clauth` surface includes credential tools plus
234
- `call_agent`, `monkey_dispatch`, `handoff_start`, `terminal_*`, and `channel_*`.
235
- Admin write tools are gated by write-mode.
204
+ ## Daemon Metadata Cache
205
+
206
+ When discovering service names, do not retrieve secrets. Use the daemon metadata
207
+ cache:
208
+
209
+ ```bash
210
+ curl -s http://127.0.0.1:52437/knowledge
211
+ curl -s http://127.0.0.1:52437/list-services
212
+ ```
213
+
214
+ `/knowledge` is agent-safe: it returns service metadata and `has_key`, but no
215
+ raw secrets and no Vault secret names. Fetch `GET /v/<service>` only for the one
216
+ exact credential needed by the next command. Never walk every service and never
217
+ bulk-fetch all secrets.
218
+
219
+ ## MCP Server (v1.16.9+)
220
+
221
+ clauth runs as an MCP server with five namespaced paths and safe
222
+ credential-discovery tools:
223
+
224
+ | Path | Namespace | Tools |
225
+ |------|-----------|-------|
226
+ | `/clauth` | `clauth_*` + runtime helpers | 23 default live tools, including `clauth_knowledge` |
227
+ | `/gws` | `gws_*` | 6 Google Workspace tools |
228
+ | `/fs` | `fs_*` | 20 filesystem and git-safe file tools |
229
+ | `/chitchat` | `chitchat_*` | 7 collaboration relay tools |
230
+ | `/codevelop` | `codevelop_*` | 7 peer development tools |
231
+ | `/mcp` | all | 63 tools combined |
232
+
233
+ The default live `/clauth` surface includes credential tools plus
234
+ `call_agent`, `monkey_dispatch`, `handoff_start`, `terminal_*`, and `channel_*`.
235
+ Admin write tools are gated by write-mode.
236
236
 
237
237
  ### claude.ai Connector URLs (noauth mode)
238
- - `https://clauth.regendevcorp.com/clauth` — credential tools
239
- - `https://clauth.regendevcorp.com/gws` — Google Workspace
240
- - `https://clauth.regendevcorp.com/chitchat` — collaboration relay tools
241
- - `https://clauth.regendevcorp.com/codevelop` — peer development tools
242
- - `https://fs.regendevcorp.com/fs` — filesystem tools
243
-
244
- Noauth mode: fresh domains that return 404 on OAuth endpoints. claude.ai connects directly (Anthropic OAuth proxy bug workaround).
245
-
246
- Use `clauth_knowledge` or `clauth_status` for discovery. Use `clauth_get` only
247
- for one exact secret. `clauth_search` is metadata-only by default; pass
248
- `addresses: true` only when redacted address hints are intentionally needed.
249
- `clauth_inject` is guarded against accidental bulk vault sweeps.
250
-
251
- ### FS Tools
252
- `fs_read` `fs_write` `fs_stat` `fs_append` `fs_write_chunk` `fs_ingest_url`
253
- `fs_import_git_files` `fs_list` `fs_grep` `fs_glob` `fs_delete` `fs_mkdir`
254
- `fs_edit` `fs_move` `fs_copy` `fs_mounts` `fs_repo_status` `fs_use_branch`
255
- `fs_commit` `fs_diff`
238
+ - `https://clauth.regendevcorp.com/clauth` — credential tools
239
+ - `https://clauth.regendevcorp.com/gws` — Google Workspace
240
+ - `https://clauth.regendevcorp.com/chitchat` — collaboration relay tools
241
+ - `https://clauth.regendevcorp.com/codevelop` — peer development tools
242
+ - `https://fs.regendevcorp.com/fs` — filesystem tools
243
+
244
+ Noauth mode: fresh domains that return 404 on OAuth endpoints. claude.ai connects directly (Anthropic OAuth proxy bug workaround).
245
+
246
+ Use `clauth_knowledge` or `clauth_status` for discovery. Use `clauth_get` only
247
+ for one exact secret. `clauth_search` is metadata-only by default; pass
248
+ `addresses: true` only when redacted address hints are intentionally needed.
249
+ `clauth_inject` is guarded against accidental bulk vault sweeps.
250
+
251
+ ### FS Tools
252
+ `fs_read` `fs_write` `fs_stat` `fs_append` `fs_write_chunk` `fs_ingest_url`
253
+ `fs_import_git_files` `fs_list` `fs_grep` `fs_glob` `fs_delete` `fs_mkdir`
254
+ `fs_edit` `fs_move` `fs_copy` `fs_mounts` `fs_repo_status` `fs_use_branch`
255
+ `fs_commit` `fs_diff`
256
256
 
257
257
  Path-jail security: all paths resolved against mount root. Permission flags (r/w/d) per mount. Uses `@vscode/ripgrep` for grep, `fast-glob` for glob.
258
258
 
259
- ### Testing
260
- ```bash
261
- node test-tools.mjs # MCP tool execution smoke tests
262
- ```
259
+ ### Testing
260
+ ```bash
261
+ node test-tools.mjs # MCP tool execution smoke tests
262
+ ```
263
263
 
264
264
  ---
265
265
 
package/README.md CHANGED
@@ -27,37 +27,37 @@ At the end it prints a **bootstrap token** — save it for the next step.
27
27
 
28
28
  ---
29
29
 
30
- ## After Install — Register Your Machine
31
-
32
- ```bash
33
- clauth setup
34
- ```
30
+ ## After Install — Register Your Machine
31
+
32
+ ```bash
33
+ clauth setup
34
+ ```
35
35
 
36
36
  Prompts for: machine label, password, bootstrap token (from `clauth install`).
37
37
 
38
- Then verify:
39
- ```bash
40
- clauth test # → PASS
41
- clauth status # → 12 services, all NO KEY
42
- ```
43
-
44
- ### Add A New Computer
45
-
46
- On an old computer where clauth is already registered:
47
-
48
- ```bash
49
- clauth enroll --label "Dave-New-Laptop"
50
- ```
51
-
52
- This creates a one-time enrollment code tied to the same `install_id` and writes
53
- a one-time PowerShell setup script. Move that script to the new computer and run
54
- it. The script installs clauth, enrolls the computer, installs startup, then
55
- deletes itself. Setup defaults the machine label to the computer name and only
56
- asks you to set the new computer's local clauth password.
57
-
58
- The enrollment code does not copy repo credentials into the script. It lets the
59
- new hardware-bound `machine_hash` join the shared Supabase Vault once. After the
60
- code is redeemed, it cannot be used again.
38
+ Then verify:
39
+ ```bash
40
+ clauth test # → PASS
41
+ clauth status # → 12 services, all NO KEY
42
+ ```
43
+
44
+ ### Add A New Computer
45
+
46
+ On an old computer where clauth is already registered:
47
+
48
+ ```bash
49
+ clauth enroll --label "Dave-New-Laptop"
50
+ ```
51
+
52
+ This creates a one-time enrollment code tied to the same `install_id` and writes
53
+ a one-time PowerShell setup script. Move that script to the new computer and run
54
+ it. The script installs clauth, enrolls the computer, installs startup, then
55
+ deletes itself. Setup defaults the machine label to the computer name and only
56
+ asks you to set the new computer's local clauth password.
57
+
58
+ The enrollment code does not copy repo credentials into the script. It lets the
59
+ new hardware-bound `machine_hash` join the shared Supabase Vault once. After the
60
+ code is redeemed, it cannot be used again.
61
61
 
62
62
  ---
63
63
 
@@ -88,13 +88,13 @@ clauth get github
88
88
  ## Command Reference
89
89
 
90
90
  ```
91
- clauth install Provision Supabase + install Claude skill
92
- clauth setup Register this machine with the vault
93
- clauth enroll Create one-time code to add another computer
94
- clauth status All services + state
95
- clauth search <query> Find services by name, project, description, or type
96
- clauth search <query> --addresses
97
- Also search redacted address hints (may read multiple secrets)
91
+ clauth install Provision Supabase + install Claude skill
92
+ clauth setup Register this machine with the vault
93
+ clauth enroll Create one-time code to add another computer
94
+ clauth status All services + state
95
+ clauth search <query> Find services by name, project, description, or type
96
+ clauth search <query> --addresses
97
+ Also search redacted address hints (may read multiple secrets)
98
98
  clauth test Verify connection
99
99
 
100
100
  clauth write key <service> Store a credential
@@ -137,81 +137,81 @@ Nothing stored locally. Password never persisted. Machine hash is one-way only.
137
137
 
138
138
  clauth runs as an HTTP daemon on `http://127.0.0.1:52437`. The daemon provides:
139
139
 
140
- - **Web UI** — unlock vault, manage services, configure mounts
141
- - **REST API** — `GET /knowledge`, `GET /status`, `GET /v/<service>`, `GET /ping`, `POST /restart`, `GET /shutdown`
142
- - **MCP server** — Model Context Protocol for Claude Code and claude.ai
143
- - **Cloudflare Tunnel** — exposes MCP endpoints publicly for claude.ai connectors
144
-
145
- Start: `clauth serve start` (starts locked, auto-opens browser for unlock).
146
-
147
- Full daemon operations reference: see `regen-root/.claude/rules/clauth.md`.
148
-
149
- ### Safe Metadata Cache
150
-
151
- Agents and scripts must discover services through metadata endpoints, not by
152
- walking every secret endpoint. The daemon caches service metadata for 30 seconds:
153
-
154
- ```bash
155
- curl -s http://127.0.0.1:52437/knowledge # sanitized, agent-safe metadata
156
- curl -s http://127.0.0.1:52437/list-services # names only
157
- curl -s http://127.0.0.1:52437/status # full daemon metadata, cached
158
- ```
159
-
160
- `/knowledge` returns service names, labels, key types, enabled state, project,
161
- description, timestamps, and `has_key`. It never returns raw secrets or Vault
162
- secret names. Use `GET /v/<service>` only for the one exact secret needed by the
163
- next command. Do not bulk-fetch every service.
140
+ - **Web UI** — unlock vault, manage services, configure mounts
141
+ - **REST API** — `GET /knowledge`, `GET /status`, `GET /v/<service>`, `GET /ping`, `POST /restart`, `GET /shutdown`
142
+ - **MCP server** — Model Context Protocol for Claude Code and claude.ai
143
+ - **Cloudflare Tunnel** — exposes MCP endpoints publicly for claude.ai connectors
144
+
145
+ Start: `clauth serve start` (starts locked, auto-opens browser for unlock).
146
+
147
+ Full daemon operations reference: see `regen-root/.claude/rules/clauth.md`.
148
+
149
+ ### Safe Metadata Cache
150
+
151
+ Agents and scripts must discover services through metadata endpoints, not by
152
+ walking every secret endpoint. The daemon caches service metadata for 30 seconds:
153
+
154
+ ```bash
155
+ curl -s http://127.0.0.1:52437/knowledge # sanitized, agent-safe metadata
156
+ curl -s http://127.0.0.1:52437/list-services # names only
157
+ curl -s http://127.0.0.1:52437/status # full daemon metadata, cached
158
+ ```
159
+
160
+ `/knowledge` returns service names, labels, key types, enabled state, project,
161
+ description, timestamps, and `has_key`. It never returns raw secrets or Vault
162
+ secret names. Use `GET /v/<service>` only for the one exact secret needed by the
163
+ next command. Do not bulk-fetch every service.
164
164
 
165
165
  ---
166
166
 
167
- ## MCP Server — 5 Namespaces, 63 Tools
168
-
169
- clauth is the single MCP interface for all local tools. One process, namespaced paths:
170
-
171
- | Path | Namespace | Tools | Description |
172
- |------|-----------|-------|-------------|
173
- | `/clauth` | `clauth_*` + runtime helpers | 23 | Credential vault operations, safe metadata cache, and agent runtime helpers |
174
- | `/gws` | `gws_*` | 6 | Google Workspace (Gmail, Calendar, Drive) |
175
- | `/fs` | `fs_*` | 20 | Filesystem plus guarded git/local-branch tools |
176
- | `/chitchat` | `chitchat_*` | 7 | Collaboration relay sessions |
177
- | `/codevelop` | `codevelop_*` | 7 | Peer development sessions |
178
- | `/mcp` | all | 63 | All namespaces combined (Claude Code) |
179
-
180
- The default live `/clauth` surface includes 13 credential tools plus
181
- `call_agent`, `monkey_dispatch`, `handoff_start`, `terminal_*`, and `channel_*`
182
- runtime helpers. Admin write tools such as enable/disable/project/token actions
183
- are gated by write-mode.
184
-
185
- ### clauth MCP Usage
186
-
187
- Use `clauth_knowledge` or `clauth_status` for discovery. They use cached
188
- metadata and never retrieve raw secrets. `clauth_search` is metadata-only by
189
- default; pass `addresses: true` only when you intentionally need redacted address
190
- hints from connstrings/fileserver/oauth secrets. `clauth_get` is for one exact
191
- secret. `clauth_inject` refuses more than five services unless `allow_many: true`
192
- is explicitly supplied, to prevent accidental rate-limit lockouts from bulk
193
- secret sweeps.
167
+ ## MCP Server — 5 Namespaces, 63 Tools
168
+
169
+ clauth is the single MCP interface for all local tools. One process, namespaced paths:
170
+
171
+ | Path | Namespace | Tools | Description |
172
+ |------|-----------|-------|-------------|
173
+ | `/clauth` | `clauth_*` + runtime helpers | 23 | Credential vault operations, safe metadata cache, and agent runtime helpers |
174
+ | `/gws` | `gws_*` | 6 | Google Workspace (Gmail, Calendar, Drive) |
175
+ | `/fs` | `fs_*` | 20 | Filesystem plus guarded git/local-branch tools |
176
+ | `/chitchat` | `chitchat_*` | 7 | Collaboration relay sessions |
177
+ | `/codevelop` | `codevelop_*` | 7 | Peer development sessions |
178
+ | `/mcp` | all | 63 | All namespaces combined (Claude Code) |
179
+
180
+ The default live `/clauth` surface includes 13 credential tools plus
181
+ `call_agent`, `monkey_dispatch`, `handoff_start`, `terminal_*`, and `channel_*`
182
+ runtime helpers. Admin write tools such as enable/disable/project/token actions
183
+ are gated by write-mode.
184
+
185
+ ### clauth MCP Usage
186
+
187
+ Use `clauth_knowledge` or `clauth_status` for discovery. They use cached
188
+ metadata and never retrieve raw secrets. `clauth_search` is metadata-only by
189
+ default; pass `addresses: true` only when you intentionally need redacted address
190
+ hints from connstrings/fileserver/oauth secrets. `clauth_get` is for one exact
191
+ secret. `clauth_inject` refuses more than five services unless `allow_many: true`
192
+ is explicitly supplied, to prevent accidental rate-limit lockouts from bulk
193
+ secret sweeps.
194
194
 
195
195
  ### FS Tools
196
196
 
197
- 20 filesystem tools with path-jail security:
198
- - `fs_read`, `fs_write`, `fs_stat`, `fs_append`, `fs_write_chunk`, `fs_ingest_url`, `fs_import_git_files`, `fs_list`, `fs_grep`, `fs_glob`, `fs_delete`, `fs_mkdir`, `fs_edit`, `fs_move`, `fs_copy`, `fs_mounts`, `fs_repo_status`, `fs_use_branch`, `fs_commit`, `fs_diff`
197
+ 20 filesystem tools with path-jail security:
198
+ - `fs_read`, `fs_write`, `fs_stat`, `fs_append`, `fs_write_chunk`, `fs_ingest_url`, `fs_import_git_files`, `fs_list`, `fs_grep`, `fs_glob`, `fs_delete`, `fs_mkdir`, `fs_edit`, `fs_move`, `fs_copy`, `fs_mounts`, `fs_repo_status`, `fs_use_branch`, `fs_commit`, `fs_diff`
199
199
  - Uses `node:fs/promises` (async), `@vscode/ripgrep` (shipped binary), `fast-glob`
200
200
  - Permission flags per mount: `r` (read), `w` (write), `d` (delete)
201
201
  - Mount config stored as "fileserver" service type in vault — only configurable through web UI
202
- - Large writes should use `fs_write_chunk`; cloud-to-local transfer should use `fs_ingest_url`; guarded appends should pass `expected_sha256` from `fs_stat`
203
- - Durable new files authored by Claude.ai in GitHub should use `fs_import_git_files` so the local dirty monorepo fetches and restores only named paths without `git pull`
204
-
205
- ### Collaboration Tools
206
-
207
- Chitchat tools: `chitchat_start`, `chitchat_list`, `chitchat_send`, `chitchat_recv`, `chitchat_reply`, `chitchat_poll`, `chitchat_stop`
208
-
209
- Codevelop tools: `codevelop_start`, `codevelop_join`, `codevelop_send`, `codevelop_poll`, `codevelop_status`, `codevelop_stream`, `codevelop_stop`
210
-
211
- ### GWS Tools
212
-
213
- 6 Google Workspace tools: `gws_run`, `gws_gmail_list`, `gws_gmail_read`, `gws_gmail_send`, `gws_calendar_list`, `gws_drive_list`
214
- - Calls `gws` CLI via `execSync` with `shell: 'bash'` (fixes Windows cmd.exe JSON quoting)
202
+ - Large writes should use `fs_write_chunk`; cloud-to-local transfer should use `fs_ingest_url`; guarded appends should pass `expected_sha256` from `fs_stat`
203
+ - Durable new files authored by Claude.ai in GitHub should use `fs_import_git_files` so the local dirty monorepo fetches and restores only named paths without `git pull`
204
+
205
+ ### Collaboration Tools
206
+
207
+ Chitchat tools: `chitchat_start`, `chitchat_list`, `chitchat_send`, `chitchat_recv`, `chitchat_reply`, `chitchat_poll`, `chitchat_stop`
208
+
209
+ Codevelop tools: `codevelop_start`, `codevelop_join`, `codevelop_send`, `codevelop_poll`, `codevelop_status`, `codevelop_stream`, `codevelop_stop`
210
+
211
+ ### GWS Tools
212
+
213
+ 6 Google Workspace tools: `gws_run`, `gws_gmail_list`, `gws_gmail_read`, `gws_gmail_send`, `gws_calendar_list`, `gws_drive_list`
214
+ - Calls `gws` CLI via `execSync` with `shell: 'bash'` (fixes Windows cmd.exe JSON quoting)
215
215
 
216
216
  ---
217
217
 
@@ -235,11 +235,11 @@ Full OAuth 2.1 protocol implementation is present for future use when Anthropic
235
235
 
236
236
  | Connector | URL |
237
237
  |-----------|-----|
238
- | clauth | `https://clauth.regendevcorp.com/clauth` |
239
- | gws | `https://clauth.regendevcorp.com/gws` |
240
- | chitchat | `https://clauth.regendevcorp.com/chitchat` |
241
- | codevelop | `https://clauth.regendevcorp.com/codevelop` |
242
- | fs | `https://fs.regendevcorp.com/fs` |
238
+ | clauth | `https://clauth.regendevcorp.com/clauth` |
239
+ | gws | `https://clauth.regendevcorp.com/gws` |
240
+ | chitchat | `https://clauth.regendevcorp.com/chitchat` |
241
+ | codevelop | `https://clauth.regendevcorp.com/codevelop` |
242
+ | fs | `https://fs.regendevcorp.com/fs` |
243
243
 
244
244
  ---
245
245
 
@@ -252,9 +252,9 @@ Full OAuth 2.1 protocol implementation is present for future use when Anthropic
252
252
 
253
253
  ## Testing
254
254
 
255
- ```bash
256
- node test-tools.mjs # MCP tool execution smoke tests
257
- ```
255
+ ```bash
256
+ node test-tools.mjs # MCP tool execution smoke tests
257
+ ```
258
258
 
259
259
  Tests actual MCP tool calls (not just OAuth + listing).
260
260
 
@@ -0,0 +1,75 @@
1
+ // cli/api.classify.test.js
2
+ // Regression tests for backend/external-resource error classification.
3
+ //
4
+ // WHY THIS EXISTS: on 2026-06-19 a saturated Postgres database made every
5
+ // auth-vault verify call time out. clauth counted each timeout as an
6
+ // authentication failure ([AUTH FAIL n/10]), hit the strike ceiling, and
7
+ // hard-locked the vault — turning a transient DB blip into a full lockout that
8
+ // blocked Claude/Codex from starting. A database timeout, a 5xx, a network
9
+ // drop, or a rate-limit is NOT a wrong password and must never take a strike.
10
+ // These tests pin that classification so the regression can't return.
11
+
12
+ import { test } from "node:test";
13
+ import assert from "node:assert/strict";
14
+ import {
15
+ VaultBackendError,
16
+ classifyBackendError,
17
+ classifyServerReason,
18
+ } from "./api.js";
19
+
20
+ test("VaultBackendError marks failures as non-strike + retriable", () => {
21
+ const e = new VaultBackendError("timeout", "no response", { status: 504, detail: "abort" });
22
+ assert.equal(e.kind, "timeout");
23
+ assert.equal(e.isBackend, true);
24
+ assert.equal(e.retriable, true);
25
+ assert.equal(e.status, 504);
26
+ assert.ok(e instanceof Error);
27
+ });
28
+
29
+ test("classifyBackendError: AbortSignal.timeout shapes => 'timeout'", () => {
30
+ // This is the exact error that slipped through the old substring check.
31
+ assert.equal(classifyBackendError({ name: "TimeoutError", message: "The operation was aborted due to timeout" }), "timeout");
32
+ assert.equal(classifyBackendError({ name: "AbortError", message: "This operation was aborted" }), "timeout");
33
+ assert.equal(classifyBackendError(new Error("request timed out")), "timeout");
34
+ });
35
+
36
+ test("classifyBackendError: network/transport shapes => 'network'", () => {
37
+ assert.equal(classifyBackendError(new Error("fetch failed")), "network");
38
+ assert.equal(classifyBackendError(new Error("connect ECONNREFUSED 127.0.0.1:443")), "network");
39
+ assert.equal(classifyBackendError(new Error("getaddrinfo ENOTFOUND db.supabase.co")), "network");
40
+ assert.equal(classifyBackendError(new Error("read ECONNRESET")), "network");
41
+ });
42
+
43
+ test("classifyBackendError: a typed VaultBackendError passes its kind through", () => {
44
+ assert.equal(classifyBackendError(new VaultBackendError("rate_limited", "slow down")), "rate_limited");
45
+ assert.equal(classifyBackendError(new VaultBackendError("db_error", "pool exhausted")), "db_error");
46
+ });
47
+
48
+ test("classifyBackendError: a genuine credential error is NOT a backend error", () => {
49
+ assert.equal(classifyBackendError(new Error("Wrong password")), null);
50
+ assert.equal(classifyBackendError(new Error("invalid_token")), null);
51
+ assert.equal(classifyBackendError(null), null);
52
+ assert.equal(classifyBackendError(undefined), null);
53
+ });
54
+
55
+ test("classifyServerReason: rate-limit reasons => 'rate_limited'", () => {
56
+ assert.equal(classifyServerReason("rate_limited"), "rate_limited");
57
+ assert.equal(classifyServerReason("Rate limit: 38/30 per 60s"), "rate_limited");
58
+ });
59
+
60
+ test("classifyServerReason: database/backend reasons => 'db_error'", () => {
61
+ assert.equal(classifyServerReason("canceling statement due to statement timeout"), "db_error");
62
+ assert.equal(classifyServerReason("database connection pool exhausted"), "db_error");
63
+ assert.equal(classifyServerReason("internal server error"), "db_error");
64
+ assert.equal(classifyServerReason("service unavailable"), "db_error");
65
+ });
66
+
67
+ test("classifyServerReason: genuine auth verdicts are NOT backend errors (they strike)", () => {
68
+ assert.equal(classifyServerReason("invalid_token (3/5)"), null);
69
+ assert.equal(classifyServerReason("machine_locked"), null);
70
+ assert.equal(classifyServerReason("machine_disabled"), null);
71
+ assert.equal(classifyServerReason("machine_not_found"), null);
72
+ assert.equal(classifyServerReason("wrong_password"), null);
73
+ assert.equal(classifyServerReason(null), null);
74
+ assert.equal(classifyServerReason(""), null);
75
+ });