paperclip-plugin-claude-accounts 0.3.0 → 0.5.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/README.md CHANGED
@@ -1,94 +1,105 @@
1
- # Claude Accounts (Paperclip plugin)
2
-
3
- Every team member connects **their own** Claude Pro/Max account from the browser, picks which agents use it,
4
- and it **stays signed in** across restarts, redeploys and reconnects. No `docker exec … /bin/sh`, no `claude login`
5
- every few hours.
6
-
7
- ## Why you kept having to re-auth
8
-
9
- With the "local" Claude sign-in, Paperclip saves only `claudeAiOauth.accessToken`, which is short-lived. It drops the
10
- refresh token (`server/src/services/local-ai-credentials.ts`) and never writes a renewed token back for Anthropic.
11
- So the saved login dies and you're sent back to a shell. The UI setup-token flow only works in sandbox
12
- environments, not local/SSH (Docker).
13
-
14
- This plugin keeps the **full** login, including the refresh token, in a per-user folder. The Claude CLI renews it there on its own,
15
- and the plugin backs it up so nothing is lost when the container restarts.
16
-
17
- ## Paperclip's own "Connect Claude", without the terminal
18
-
19
- Paperclip normally tells you to run this in a shell:
20
-
21
- ```
22
- (export CLAUDE_CONFIG_DIR='/paperclip/instances/default/ai-local-logins/<id>' && mkdir -p "$CLAUDE_CONFIG_DIR" && claude auth login)
23
- ```
24
-
25
- The plugin does the same thing for you:
26
-
27
- - **One click:** on **Claude accounts**, click **Connect to Paperclip**. The plugin:
28
- 1. starts Paperclip's sign-in attempt
29
- 2. writes your Claude login into that `ai-local-logins/<id>` folder
30
- 3. completes it with Paperclip's own API
31
-
32
- You get a normal **personal Paperclip AI connection**, the default for agents set to "responsible user".
33
- - **Or paste the command** Paperclip showed you into **Paperclip showed me a terminal command → Do it for me**,
34
- then click **Connect** in Paperclip's dialog.
35
- - **Stays connected:** Paperclip keeps only the short-lived access token. The plugin keeps the refresh token in your
36
- account folder, and while you have Paperclip open in a browser tab, the sidebar checks every 2 minutes. Shortly before
37
- the token expires, it renews it with one tiny `claude -p` call (Haiku) and **reconnects the same connection**,
38
- which rotates its secret in place. No shell, ever.
39
-
40
- Only the owner can reconnect a personal connection, so this runs in your own browser. If you don't open Paperclip for longer than the token lives, the connection can expire. The next time you open
41
- Paperclip it reconnects by itself within ~2 minutes. For agents that must keep running unattended, use
42
- **Advanced → Use my Claude**, which renews entirely on the server.
43
-
44
- ## For each user (≈30 seconds)
45
-
46
- 1. Open **Claude accounts** in the sidebar.
47
- 2. Click **Sign in with Claude**. A Claude page opens. Approve it and copy the code it shows.
48
- 3. Paste the code and click **Connect**. ✅
49
- 4. Under **Agents**, click **Use my Claude** on the agents that should run on your account.
50
- You can also do this from the agent's **Claude login** tab.
51
-
52
- Alternative: click **Paste a token instead** and paste the output of `claude setup-token` (run on your own computer),
53
- or your `~/.claude/.credentials.json`.
54
-
55
- ## How it works
56
-
57
- - Each user gets `$PAPERCLIP_HOME/claude-accounts/<userId>/`, used as that user's `CLAUDE_CONFIG_DIR`.
58
- - **Use my Claude** sets `CLAUDE_CONFIG_DIR` in the agent's adapter env. The browser does this through Paperclip's own API, as
59
- the signed-in user, so normal permissions apply.
60
- - **Sign in with Claude** runs `claude auth login` in a pseudo-terminal on the server (`script` from util-linux) and
61
- relays the link and code through the UI.
62
- - A keeper process watches every account. It runs on startup, every 5 min, on file changes and on agent events, plus right away
63
- after a run fails with an auth error. For each account it:
64
- - restores a missing, corrupt or older `.credentials.json` from the backup in Paperclip's database
65
- - updates the backup when the CLI rotates the token (refresh tokens rotate)
66
- - makes sure a `.claude.json` with onboarding marked done exists
67
- - Users can only manage **their own** account. Every action is checked against the authenticated Paperclip user, and agents
68
- and the system are rejected.
69
- - The server's shared login (`$HOME/.claude`) is also kept alive for agents that don't use a personal account. You can turn this off.
70
-
71
- ## Install
72
-
73
- ```bash
74
- npm install && npm run build
75
- npx paperclipai plugin install ./paperclip-plugin-claude-autoauth
76
- ```
77
-
78
- Then in the plugin settings, set a **Backup encryption key** secret (any long random string).
79
-
80
- ## Limits
81
-
82
- - An agent that has a Paperclip **AI connection** selected (`runtimeConfig.aiConnection`) ignores `CLAUDE_CONFIG_DIR`.
83
- Paperclip blanks it, and its PATCH API won't let a plugin remove the binding. The UI warns you. Switch that agent
84
- to the local login in its settings.
85
- - Agents with `filesystemScope` sandboxing use the server login dir instead of the per-user one.
86
- - The browser sign-in needs `script` (util-linux; included in Debian/Ubuntu images) and `claude` on the server's PATH.
87
- If either is missing, use **Paste a token instead**.
88
- - A `setup-token` token can't renew itself. It is valid for about 1 year. Browser sign-in can renew forever.
89
- - `accountsDir` must be on a persistent volume if you want sessions and settings kept. The credentials are restored either way.
90
-
91
- ## Security
92
-
93
- The backup holds live OAuth refresh tokens. Set the encryption key, and treat Paperclip DB backups as secrets.
94
- Folders are created `0700` and files `0600`.
1
+ # Claude (Paperclip plugin)
2
+
3
+ Adds a **Claude** item to Paperclip's sidebar with four tabs:
4
+
5
+ | Tab | What it does |
6
+ |---|---|
7
+ | **Account** | Each user connects their own Claude subscription from the browser (no shell) and stays signed in. |
8
+ | **Models** | Current Claude model catalog, what Paperclip's built-in picker is missing, and switching agents to newer models (one at a time or "Upgrade all"). Effort settings are adjusted to what the new model supports, and models that need a newer Claude Code are blocked until you update it. |
9
+ | **Claude Code** | Installed vs latest Claude Code, one-click **Update** (company owners/admins). If the server install isn't writable (Paperclip's Docker image), it installs to `$PAPERCLIP_HOME/tools/claude-code` and lets you point agents at it. |
10
+ | **Plugin** | Installed vs latest plugin version and an **Update** button (instance admins), using Paperclip's own upgrade API. |
11
+
12
+ The model catalog ships with the plugin, so updating the plugin from the Plugin tab is how you get new models.
13
+
14
+ Every team member connects **their own** Claude Pro/Max account from the browser, picks which agents use it,
15
+ and it **stays signed in** across restarts, redeploys and reconnects. No `docker exec … /bin/sh`, no `claude login`
16
+ every few hours.
17
+
18
+ ## Why you kept having to re-auth
19
+
20
+ With the "local" Claude sign-in, Paperclip saves only `claudeAiOauth.accessToken`, which is short-lived. It drops the
21
+ refresh token (`server/src/services/local-ai-credentials.ts`) and never writes a renewed token back for Anthropic.
22
+ So the saved login dies and you're sent back to a shell. The UI setup-token flow only works in sandbox
23
+ environments, not local/SSH (Docker).
24
+
25
+ This plugin keeps the **full** login, including the refresh token, in a per-user folder. The Claude CLI renews it there on its own,
26
+ and the plugin backs it up so nothing is lost when the container restarts.
27
+
28
+ ## Paperclip's own "Connect Claude", without the terminal
29
+
30
+ Paperclip normally tells you to run this in a shell:
31
+
32
+ ```
33
+ (export CLAUDE_CONFIG_DIR='/paperclip/instances/default/ai-local-logins/<id>' && mkdir -p "$CLAUDE_CONFIG_DIR" && claude auth login)
34
+ ```
35
+
36
+ The plugin does the same thing for you:
37
+
38
+ - **One click:** on **Claude accounts**, click **Connect to Paperclip**. The plugin:
39
+ 1. starts Paperclip's sign-in attempt
40
+ 2. writes your Claude login into that `ai-local-logins/<id>` folder
41
+ 3. completes it with Paperclip's own API
42
+
43
+ You get a normal **personal Paperclip AI connection**, the default for agents set to "responsible user".
44
+ - **Or paste the command** Paperclip showed you into **Paperclip showed me a terminal command → Do it for me**,
45
+ then click **Connect** in Paperclip's dialog.
46
+ - **Stays connected:** Paperclip keeps only the short-lived access token. The plugin keeps the refresh token in your
47
+ account folder, and while you have Paperclip open in a browser tab, the sidebar checks every 2 minutes. Shortly before
48
+ the token expires, it renews it with one tiny `claude -p` call (Haiku) and **reconnects the same connection**,
49
+ which rotates its secret in place. No shell, ever.
50
+
51
+ Only the owner can reconnect a personal connection, so this runs in your own browser. If you don't open Paperclip for longer than the token lives, the connection can expire. The next time you open
52
+ Paperclip it reconnects by itself within ~2 minutes. For agents that must keep running unattended, use
53
+ **Advanced → Use my Claude**, which renews entirely on the server.
54
+
55
+ ## For each user (≈30 seconds)
56
+
57
+ 1. Open **Claude accounts** in the sidebar.
58
+ 2. Click **Sign in with Claude**. A Claude page opens. Approve it and copy the code it shows.
59
+ 3. Paste the code and click **Connect**. ✅
60
+ 4. Under **Agents**, click **Use my Claude** on the agents that should run on your account.
61
+ You can also do this from the agent's **Claude login** tab.
62
+
63
+ Alternative: click **Paste a token instead** and paste the output of `claude setup-token` (run on your own computer),
64
+ or your `~/.claude/.credentials.json`.
65
+
66
+ ## How it works
67
+
68
+ - Each user gets `$PAPERCLIP_HOME/claude-accounts/<userId>/`, used as that user's `CLAUDE_CONFIG_DIR`.
69
+ - **Use my Claude** sets `CLAUDE_CONFIG_DIR` in the agent's adapter env. The browser does this through Paperclip's own API, as
70
+ the signed-in user, so normal permissions apply.
71
+ - **Sign in with Claude** runs `claude auth login` in a pseudo-terminal on the server (`script` from util-linux) and
72
+ relays the link and code through the UI.
73
+ - A keeper process watches every account. It runs on startup, every 5 min, on file changes and on agent events, plus right away
74
+ after a run fails with an auth error. For each account it:
75
+ - restores a missing, corrupt or older `.credentials.json` from the backup in Paperclip's database
76
+ - updates the backup when the CLI rotates the token (refresh tokens rotate)
77
+ - makes sure a `.claude.json` with onboarding marked done exists
78
+ - Users can only manage **their own** account. Every action is checked against the authenticated Paperclip user, and agents
79
+ and the system are rejected.
80
+ - The server's shared login (`$HOME/.claude`) is also kept alive for agents that don't use a personal account. You can turn this off.
81
+
82
+ ## Install
83
+
84
+ ```bash
85
+ npm install && npm run build
86
+ npx paperclipai plugin install ./paperclip-plugin-claude-autoauth
87
+ ```
88
+
89
+ Then in the plugin settings, set a **Backup encryption key** secret (any long random string).
90
+
91
+ ## Limits
92
+
93
+ - An agent that has a Paperclip **AI connection** selected (`runtimeConfig.aiConnection`) ignores `CLAUDE_CONFIG_DIR`.
94
+ Paperclip blanks it, and its PATCH API won't let a plugin remove the binding. The UI warns you. Switch that agent
95
+ to the local login in its settings.
96
+ - Agents with `filesystemScope` sandboxing use the server login dir instead of the per-user one.
97
+ - The browser sign-in needs `script` (util-linux; included in Debian/Ubuntu images) and `claude` on the server's PATH.
98
+ If either is missing, use **Paste a token instead**.
99
+ - A `setup-token` token can't renew itself. It is valid for about 1 year. Browser sign-in can renew forever.
100
+ - `accountsDir` must be on a persistent volume if you want sessions and settings kept. The credentials are restored either way.
101
+
102
+ ## Security
103
+
104
+ The backup holds live OAuth refresh tokens. Set the encryption key, and treat Paperclip DB backups as secrets.
105
+ Folders are created `0700` and files `0600`.
package/dist/manifest.js CHANGED
@@ -2,9 +2,9 @@
2
2
  var manifest = {
3
3
  id: "neotalk.claude-autoauth",
4
4
  apiVersion: 1,
5
- version: "0.3.0",
6
- displayName: "Claude Accounts",
7
- description: "Each team member connects their own Claude account from the browser (no shell), picks which agents use it, and it stays signed in across restarts.",
5
+ version: "0.5.0",
6
+ displayName: "Claude",
7
+ description: "Claude for Paperclip: everyone connects their own Claude account from the browser and it stays signed in. Also keeps the Claude model catalog and Claude Code up to date.",
8
8
  author: "Victor <victor@neotalk.com.br>",
9
9
  categories: ["automation"],
10
10
  capabilities: [
@@ -14,6 +14,7 @@ var manifest = {
14
14
  "plugin.state.write",
15
15
  "secrets.read-ref",
16
16
  "agents.read",
17
+ "access.members.read",
17
18
  "ui.page.register",
18
19
  "ui.sidebar.register",
19
20
  "ui.detailTab.register"
@@ -24,8 +25,8 @@ var manifest = {
24
25
  },
25
26
  ui: {
26
27
  slots: [
27
- { type: "page", id: "claude-accounts", displayName: "Claude accounts", exportName: "ClaudeAccountsPage", routePath: "claude-accounts" },
28
- { type: "sidebar", id: "claude-accounts-link", displayName: "Claude accounts", exportName: "ClaudeAccountsSidebar" },
28
+ { type: "page", id: "claude-accounts", displayName: "Claude", exportName: "ClaudeAccountsPage", routePath: "claude" },
29
+ { type: "sidebar", id: "claude-accounts-link", displayName: "Claude", exportName: "ClaudeAccountsSidebar" },
29
30
  { type: "detailTab", id: "agent-claude", displayName: "Claude login", exportName: "AgentClaudeTab", entityTypes: ["agent"] }
30
31
  ]
31
32
  },