@bookedsolid/reagent 0.14.3 → 0.15.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 +61 -9
- package/dist/cli/commands/account.d.ts +2 -0
- package/dist/cli/commands/account.d.ts.map +1 -0
- package/dist/cli/commands/account.js +455 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/init/index.d.ts.map +1 -1
- package/dist/cli/commands/init/index.js +3 -0
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/package-dep.d.ts +13 -0
- package/dist/cli/commands/init/package-dep.d.ts.map +1 -0
- package/dist/cli/commands/init/package-dep.js +112 -0
- package/dist/cli/commands/init/package-dep.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -1
- package/dist/cli/commands/upgrade.js +6 -3
- package/dist/cli/commands/upgrade.js.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/accounts.d.ts +26 -0
- package/dist/config/accounts.d.ts.map +1 -0
- package/dist/config/accounts.js +104 -0
- package/dist/config/accounts.js.map +1 -0
- package/dist/gateway/client-manager.d.ts.map +1 -1
- package/dist/gateway/client-manager.js +3 -1
- package/dist/gateway/client-manager.js.map +1 -1
- package/dist/platform/keychain.d.ts +26 -0
- package/dist/platform/keychain.d.ts.map +1 -0
- package/dist/platform/keychain.js +92 -0
- package/dist/platform/keychain.js.map +1 -0
- package/dist/types/accounts.d.ts +22 -0
- package/dist/types/accounts.d.ts.map +1 -0
- package/dist/types/accounts.js +2 -0
- package/dist/types/accounts.js.map +1 -0
- package/dist/types/audit.d.ts +1 -0
- package/dist/types/audit.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Governance layer for Claude Code — policy enforcement, hook-based safety gates, and audit logging for AI-assisted projects.
|
|
4
4
|
|
|
5
|
-
reagent enforces policy, prevents dangerous operations, and audits AI agent activity in Claude Code projects. One command (`reagent init`) installs
|
|
5
|
+
reagent enforces policy, prevents dangerous operations, and audits AI agent activity in Claude Code projects. One command (`reagent init`) installs 26 safety hooks and a full engineering team of AI specialists into your project. Every tool call — from every AI agent — is governed by your `policy.yaml`. It's Claude Code + accountability.
|
|
6
6
|
|
|
7
7
|
## What it is
|
|
8
8
|
|
|
@@ -35,20 +35,25 @@ cd your-project
|
|
|
35
35
|
reagent init
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
That's it. `reagent init`
|
|
38
|
+
That's it. `reagent init` installs reagent as a devDependency (detecting your package manager
|
|
39
|
+
automatically) and writes `.mcp.json` to your project root:
|
|
39
40
|
|
|
40
41
|
```json
|
|
41
42
|
{
|
|
42
43
|
"mcpServers": {
|
|
43
44
|
"reagent": {
|
|
44
45
|
"type": "stdio",
|
|
45
|
-
"command": "
|
|
46
|
-
"args": ["reagent", "serve"]
|
|
46
|
+
"command": "node",
|
|
47
|
+
"args": ["node_modules/@bookedsolid/reagent/dist/cli/index.js", "serve"]
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
The direct `node` path works across npm, yarn, pnpm, and bun. If reagent is not yet installed
|
|
54
|
+
locally, init falls back to `npx @bookedsolid/reagent serve`; run `reagent upgrade` after
|
|
55
|
+
installing the package to migrate.
|
|
56
|
+
|
|
52
57
|
Restart Claude Code. It will pick up `.mcp.json` and spawn `reagent serve` automatically.
|
|
53
58
|
reagent loads your `.reagent/policy.yaml` and `.reagent/gateway.yaml`, connects to any
|
|
54
59
|
downstream servers, and starts listening on stdio.
|
|
@@ -162,6 +167,17 @@ notification_channel: ''
|
|
|
162
167
|
|
|
163
168
|
quality_gates:
|
|
164
169
|
push_review: false
|
|
170
|
+
|
|
171
|
+
# Prompt injection detection for proxied tool results
|
|
172
|
+
injection_detection: block # 'block' (default) or 'warn'
|
|
173
|
+
|
|
174
|
+
# Context protection — delegate expensive commands to subagents
|
|
175
|
+
context_protection:
|
|
176
|
+
delegate_to_subagent:
|
|
177
|
+
- 'pnpm run preflight'
|
|
178
|
+
- 'pnpm run test'
|
|
179
|
+
- 'pnpm run build'
|
|
180
|
+
max_bash_output_lines: 100
|
|
165
181
|
```
|
|
166
182
|
|
|
167
183
|
The `autonomy_level` controls what tier of tools an agent can call. Raise it to give
|
|
@@ -284,7 +300,7 @@ The `client-engagement` profile installs:
|
|
|
284
300
|
|
|
285
301
|
## Hooks
|
|
286
302
|
|
|
287
|
-
reagent installs
|
|
303
|
+
reagent installs 26 Claude Code hooks into `.claude/hooks/`. Every hook checks for
|
|
288
304
|
`.reagent/HALT` at the top — if it exists, the hook returns exit code 2 (hard block)
|
|
289
305
|
immediately.
|
|
290
306
|
|
|
@@ -326,6 +342,17 @@ immediately.
|
|
|
326
342
|
- `architecture-review-gate` — After significant file edits, checks the change against
|
|
327
343
|
the project's architecture plan and flags deviations.
|
|
328
344
|
|
|
345
|
+
**Integration hooks:**
|
|
346
|
+
|
|
347
|
+
- `reagent-notify` — Sends Discord notifications on significant events (commits, PR
|
|
348
|
+
creation, pushes). Requires `discord_ops` in `gateway.yaml`.
|
|
349
|
+
- `reagent-obsidian-journal` — Fires on session end. Appends a session summary to the
|
|
350
|
+
daily note in your Obsidian vault.
|
|
351
|
+
- `reagent-obsidian-precompact` — Fires before context compaction. Creates a knowledge
|
|
352
|
+
extraction note in the vault's sessions directory.
|
|
353
|
+
- `reagent-obsidian-tasks` — Fires after `task_create`/`task_update`. Materializes tasks
|
|
354
|
+
as individual Obsidian notes with typed frontmatter.
|
|
355
|
+
|
|
329
356
|
**Additional hooks installed by tech stack profiles:**
|
|
330
357
|
|
|
331
358
|
- `commit-msg` (husky) — Enforces commit message format and rejects AI attribution
|
|
@@ -363,8 +390,17 @@ are stored as append-only JSONL in `.reagent/tasks.jsonl`. Each line is a JSON e
|
|
|
363
390
|
All native tools go through the same middleware chain as proxied tools — the kill switch,
|
|
364
391
|
policy, blocked paths, redaction, and audit all apply.
|
|
365
392
|
|
|
366
|
-
|
|
367
|
-
|
|
393
|
+
Slash commands provide quick access to the task board and team orchestration from within
|
|
394
|
+
Claude Code conversations:
|
|
395
|
+
|
|
396
|
+
| Command | Description |
|
|
397
|
+
| ------------ | ----------------------------------------------------------------------------- |
|
|
398
|
+
| `/tasks` | Render a markdown table of current tasks from tasks.jsonl |
|
|
399
|
+
| `/plan-work` | Invoke the product-owner agent to propose and create tasks for a goal |
|
|
400
|
+
| `/restart` | Session handoff — save state on spin-down, orient from saved state on spin-up |
|
|
401
|
+
| `/rea` | Invoke the REA (Reactive Execution Agent) for autonomous team orchestration |
|
|
402
|
+
| `/pm-status` | Scan open PRs, report pipeline state, merge ready work, staging promotion |
|
|
403
|
+
| `/review-pr` | Fetch a PR diff, run code-reviewer analysis, post findings in owner voice |
|
|
368
404
|
|
|
369
405
|
**Example `tasks.jsonl` entries:**
|
|
370
406
|
|
|
@@ -548,12 +584,28 @@ reagent catalyze [targetDir]
|
|
|
548
584
|
--dry-run Print analysis without writing files
|
|
549
585
|
|
|
550
586
|
reagent upgrade [--dry-run] [--clean-blocked-paths]
|
|
551
|
-
Re-syncs
|
|
552
|
-
|
|
587
|
+
Re-syncs husky hooks, merges new policy fields into policy.yaml, ensures
|
|
588
|
+
reagent is a devDependency, and migrates .mcp.json from the legacy npx
|
|
589
|
+
pattern to the direct node path (for pnpm compatibility).
|
|
553
590
|
--clean-blocked-paths replaces the blanket '.reagent/' blocked path with
|
|
554
591
|
granular entries, allowing agents to write to operational files (tasks,
|
|
555
592
|
review cache) while keeping policy and audit files protected.
|
|
556
593
|
|
|
594
|
+
reagent account <subcommand>
|
|
595
|
+
Multi-credential management. Switch between Claude billing accounts by
|
|
596
|
+
storing OAuth tokens in macOS Keychain and exporting CLAUDE_CODE_OAUTH_TOKEN.
|
|
597
|
+
|
|
598
|
+
Subcommands:
|
|
599
|
+
add <name> Register a new account via OAuth login
|
|
600
|
+
list Show all registered accounts and active status
|
|
601
|
+
env <name> Output shell export commands (for eval/rswitch)
|
|
602
|
+
env --clear Output shell unset commands
|
|
603
|
+
check [--all] Validate token health (expiry, keychain access)
|
|
604
|
+
whoami Show active account details
|
|
605
|
+
rotate <name> Re-authenticate and store new token
|
|
606
|
+
remove <name> Delete keychain entry and remove from config
|
|
607
|
+
setup-shell Print shell function and completions for rswitch
|
|
608
|
+
|
|
557
609
|
reagent cache <set|get|del> <key> [value]
|
|
558
610
|
Manages the review cache used by commit-review-gate and push-review-gate.
|
|
559
611
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/account.ts"],"names":[],"mappings":"AAgBA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsC/C"}
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { parseFlag } from '../utils.js';
|
|
3
|
+
import { loadAccounts, upsertAccount, removeAccount as removeAccountConfig, } from '../../config/accounts.js';
|
|
4
|
+
import { keychainSet, keychainGet, keychainDelete, keychainExists, readClaudeCodeCredential, writeClaudeCodeCredential as writeClaudeCredential, } from '../../platform/keychain.js';
|
|
5
|
+
export function runAccount(args) {
|
|
6
|
+
const [subcommand, ...rest] = args;
|
|
7
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
8
|
+
printAccountHelp();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
switch (subcommand) {
|
|
12
|
+
case 'add':
|
|
13
|
+
accountAdd(rest);
|
|
14
|
+
break;
|
|
15
|
+
case 'list':
|
|
16
|
+
accountList();
|
|
17
|
+
break;
|
|
18
|
+
case 'env':
|
|
19
|
+
accountEnv(rest);
|
|
20
|
+
break;
|
|
21
|
+
case 'check':
|
|
22
|
+
accountCheck(rest);
|
|
23
|
+
break;
|
|
24
|
+
case 'whoami':
|
|
25
|
+
accountWhoami();
|
|
26
|
+
break;
|
|
27
|
+
case 'rotate':
|
|
28
|
+
accountRotate(rest);
|
|
29
|
+
break;
|
|
30
|
+
case 'remove':
|
|
31
|
+
accountRemove(rest);
|
|
32
|
+
break;
|
|
33
|
+
case 'setup-shell':
|
|
34
|
+
accountSetupShell(rest);
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
console.error(`Unknown account subcommand: ${subcommand}`);
|
|
38
|
+
printAccountHelp();
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function printAccountHelp() {
|
|
43
|
+
console.log(`
|
|
44
|
+
reagent account — Multi-credential management
|
|
45
|
+
|
|
46
|
+
Subcommands:
|
|
47
|
+
add <name> Register new account (OAuth login + keychain store)
|
|
48
|
+
list Show all accounts + which is active
|
|
49
|
+
env <name> Output shell export commands (for rswitch/eval)
|
|
50
|
+
env --clear Output shell unset commands
|
|
51
|
+
check [--all] Validate token health (expiry, keychain access)
|
|
52
|
+
whoami Show active account details
|
|
53
|
+
rotate <name> Re-authenticate and store new token
|
|
54
|
+
remove <name> Delete keychain entry + remove from accounts.yaml
|
|
55
|
+
setup-shell Print shell function + completions to add to ~/.zshrc
|
|
56
|
+
|
|
57
|
+
Options for setup-shell:
|
|
58
|
+
--shell <zsh|bash|fish> Target shell (default: zsh)
|
|
59
|
+
|
|
60
|
+
Examples:
|
|
61
|
+
reagent account add clarity-house
|
|
62
|
+
reagent account list
|
|
63
|
+
eval "$(reagent account env clarity-house)"
|
|
64
|
+
eval "$(reagent account env --clear)"
|
|
65
|
+
reagent account whoami
|
|
66
|
+
reagent account check --all
|
|
67
|
+
reagent account rotate personal
|
|
68
|
+
reagent account remove huge-inc
|
|
69
|
+
reagent account setup-shell >> ~/.zshrc
|
|
70
|
+
`);
|
|
71
|
+
}
|
|
72
|
+
// --- add ---
|
|
73
|
+
function accountAdd(args) {
|
|
74
|
+
const name = args.find((a) => !a.startsWith('--'));
|
|
75
|
+
if (!name) {
|
|
76
|
+
console.error('Usage: reagent account add <name>');
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {
|
|
80
|
+
console.error('Account name must be lowercase alphanumeric with hyphens (e.g., clarity-house)');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
const keychainService = `reagent-${name}`;
|
|
84
|
+
const config = loadAccounts();
|
|
85
|
+
if (config.accounts[name]) {
|
|
86
|
+
console.error(`Account "${name}" already exists. Use 'reagent account rotate ${name}' to re-authenticate.`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
console.log(`\nRegistering account: ${name}`);
|
|
90
|
+
console.log('Step 1: Backing up current Claude Code credential...');
|
|
91
|
+
// Back up current Claude Code keychain credential
|
|
92
|
+
let backupRaw = null;
|
|
93
|
+
try {
|
|
94
|
+
backupRaw = execFileSync('security', ['find-generic-password', '-s', 'Claude Code-credentials', '-w'], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf8' }).trim();
|
|
95
|
+
console.log(' Backup saved.');
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
console.log(' No existing Claude Code credential found (first-time setup).');
|
|
99
|
+
}
|
|
100
|
+
console.log('\nStep 2: Opening browser for OAuth login...');
|
|
101
|
+
console.log(` Log in with the account you want to register as "${name}".`);
|
|
102
|
+
console.log(' Press Enter when ready, or Ctrl+C to cancel.');
|
|
103
|
+
// Wait for user confirmation
|
|
104
|
+
const buf = Buffer.alloc(1);
|
|
105
|
+
try {
|
|
106
|
+
const fd = require('node:fs').openSync('/dev/tty', 'r');
|
|
107
|
+
require('node:fs').readSync(fd, buf, 0, 1, null);
|
|
108
|
+
require('node:fs').closeSync(fd);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Non-interactive — proceed anyway
|
|
112
|
+
}
|
|
113
|
+
// Run claude auth login
|
|
114
|
+
const loginResult = spawnSync('claude', ['auth', 'login'], {
|
|
115
|
+
stdio: 'inherit',
|
|
116
|
+
});
|
|
117
|
+
if (loginResult.status !== 0) {
|
|
118
|
+
console.error('\nOAuth login failed or was cancelled.');
|
|
119
|
+
if (backupRaw) {
|
|
120
|
+
console.log('Restoring original credential...');
|
|
121
|
+
writeClaudeCredential(backupRaw);
|
|
122
|
+
}
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
console.log('\nStep 3: Reading new credential from keychain...');
|
|
126
|
+
const newCredential = readClaudeCodeCredential();
|
|
127
|
+
if (!newCredential || !newCredential.accessToken) {
|
|
128
|
+
console.error('Failed to read new credential from Claude Code keychain entry.');
|
|
129
|
+
if (backupRaw) {
|
|
130
|
+
console.log('Restoring original credential...');
|
|
131
|
+
writeClaudeCredential(backupRaw);
|
|
132
|
+
}
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
console.log('Step 4: Storing under reagent keychain entry...');
|
|
136
|
+
keychainSet(keychainService, newCredential);
|
|
137
|
+
console.log('Step 5: Restoring original Claude Code credential...');
|
|
138
|
+
if (backupRaw) {
|
|
139
|
+
writeClaudeCredential(backupRaw);
|
|
140
|
+
console.log(' Original credential restored.');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log(' No original credential to restore.');
|
|
144
|
+
}
|
|
145
|
+
console.log('Step 6: Updating accounts.yaml...');
|
|
146
|
+
upsertAccount(name, {
|
|
147
|
+
credential_store: 'keychain',
|
|
148
|
+
keychain_service: keychainService,
|
|
149
|
+
});
|
|
150
|
+
console.log(`\nAccount "${name}" registered successfully.`);
|
|
151
|
+
console.log(`\nTo switch: eval "$(reagent account env ${name})"`);
|
|
152
|
+
console.log(`Or use: rswitch ${name} (after running 'reagent account setup-shell')\n`);
|
|
153
|
+
}
|
|
154
|
+
// --- list ---
|
|
155
|
+
function accountList() {
|
|
156
|
+
const config = loadAccounts();
|
|
157
|
+
const names = Object.keys(config.accounts);
|
|
158
|
+
const activeAccount = process.env.REAGENT_ACCOUNT;
|
|
159
|
+
if (names.length === 0) {
|
|
160
|
+
console.log('\nNo accounts registered. Run: reagent account add <name>\n');
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
console.log('\nRegistered accounts:\n');
|
|
164
|
+
for (const name of names) {
|
|
165
|
+
const acct = config.accounts[name];
|
|
166
|
+
const isActive = activeAccount === name;
|
|
167
|
+
const marker = isActive ? ' (active)' : '';
|
|
168
|
+
const desc = acct.description ? ` — ${acct.description}` : '';
|
|
169
|
+
const hasToken = keychainExists(acct.keychain_service) ? 'keychain ok' : 'keychain MISSING';
|
|
170
|
+
console.log(` ${isActive ? '*' : ' '} ${name}${marker}${desc}`);
|
|
171
|
+
console.log(` Store: ${hasToken} (${acct.keychain_service})`);
|
|
172
|
+
}
|
|
173
|
+
if (!activeAccount) {
|
|
174
|
+
console.log('\n No account active (using keychain default)');
|
|
175
|
+
}
|
|
176
|
+
console.log('');
|
|
177
|
+
}
|
|
178
|
+
// --- env ---
|
|
179
|
+
function accountEnv(args) {
|
|
180
|
+
const clearFlag = args.includes('--clear');
|
|
181
|
+
if (clearFlag) {
|
|
182
|
+
// Output unset commands
|
|
183
|
+
console.log('unset CLAUDE_CODE_OAUTH_TOKEN');
|
|
184
|
+
console.log('unset CLAUDE_CODE_OAUTH_REFRESH_TOKEN');
|
|
185
|
+
console.log('unset REAGENT_ACCOUNT');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const name = args.find((a) => !a.startsWith('--'));
|
|
189
|
+
if (!name) {
|
|
190
|
+
console.error('Usage: reagent account env <name> | reagent account env --clear');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
const config = loadAccounts();
|
|
194
|
+
const account = config.accounts[name];
|
|
195
|
+
if (!account) {
|
|
196
|
+
console.error(`Account "${name}" not found. Run: reagent account list`);
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
const credential = keychainGet(account.keychain_service);
|
|
200
|
+
if (!credential) {
|
|
201
|
+
console.error(`No credential found in keychain for "${name}" (service: ${account.keychain_service})`);
|
|
202
|
+
console.error(`Run: reagent account rotate ${name}`);
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
// Output shell export commands — safe for eval
|
|
206
|
+
console.log(`export CLAUDE_CODE_OAUTH_TOKEN='${escapeShellSingleQuote(credential.accessToken)}'`);
|
|
207
|
+
if (credential.refreshToken) {
|
|
208
|
+
console.log(`export CLAUDE_CODE_OAUTH_REFRESH_TOKEN='${escapeShellSingleQuote(credential.refreshToken)}'`);
|
|
209
|
+
}
|
|
210
|
+
console.log(`export REAGENT_ACCOUNT='${escapeShellSingleQuote(name)}'`);
|
|
211
|
+
}
|
|
212
|
+
// --- check ---
|
|
213
|
+
function accountCheck(args) {
|
|
214
|
+
const allFlag = args.includes('--all');
|
|
215
|
+
const config = loadAccounts();
|
|
216
|
+
const activeAccount = process.env.REAGENT_ACCOUNT;
|
|
217
|
+
const names = allFlag ? Object.keys(config.accounts) : activeAccount ? [activeAccount] : [];
|
|
218
|
+
if (names.length === 0) {
|
|
219
|
+
if (allFlag) {
|
|
220
|
+
console.log('\nNo accounts registered.\n');
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
console.log('\nNo active account. Use --all to check all accounts.\n');
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
console.log('\nAccount health check:\n');
|
|
228
|
+
for (const name of names) {
|
|
229
|
+
const account = config.accounts[name];
|
|
230
|
+
if (!account) {
|
|
231
|
+
console.log(` ! ${name}: not found in accounts.yaml`);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const credential = keychainGet(account.keychain_service);
|
|
235
|
+
if (!credential) {
|
|
236
|
+
console.log(` ! ${name}: keychain entry MISSING (${account.keychain_service})`);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const hasAccess = !!credential.accessToken;
|
|
240
|
+
const hasRefresh = !!credential.refreshToken;
|
|
241
|
+
const expiry = credential.expiresAt ? new Date(credential.expiresAt) : null;
|
|
242
|
+
const isExpired = expiry ? expiry < new Date() : false;
|
|
243
|
+
const tokenPreview = credential.accessToken
|
|
244
|
+
? `${credential.accessToken.slice(0, 12)}...${credential.accessToken.slice(-4)}`
|
|
245
|
+
: 'none';
|
|
246
|
+
const status = !hasAccess ? 'NO TOKEN' : isExpired ? 'EXPIRED' : 'ok';
|
|
247
|
+
console.log(` ${status === 'ok' ? '+' : '!'} ${name}: ${status}`);
|
|
248
|
+
console.log(` Token: ${tokenPreview}`);
|
|
249
|
+
console.log(` Refresh: ${hasRefresh ? 'present' : 'none'}`);
|
|
250
|
+
if (expiry) {
|
|
251
|
+
console.log(` Expires: ${expiry.toISOString()}${isExpired ? ' (EXPIRED)' : ''}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
console.log('');
|
|
255
|
+
}
|
|
256
|
+
// --- whoami ---
|
|
257
|
+
function accountWhoami() {
|
|
258
|
+
const activeAccount = process.env.REAGENT_ACCOUNT;
|
|
259
|
+
const hasEnvToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
260
|
+
if (!activeAccount && !hasEnvToken) {
|
|
261
|
+
console.log('\nNo reagent account active.');
|
|
262
|
+
console.log('Using Claude Code default (keychain credential).\n');
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
console.log('');
|
|
266
|
+
if (activeAccount) {
|
|
267
|
+
const config = loadAccounts();
|
|
268
|
+
const account = config.accounts[activeAccount];
|
|
269
|
+
const desc = account?.description || '(no description)';
|
|
270
|
+
console.log(`Account: ${activeAccount}`);
|
|
271
|
+
console.log(`Billing: ${desc}`);
|
|
272
|
+
if (hasEnvToken) {
|
|
273
|
+
const token = process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
274
|
+
const preview = `${token.slice(0, 12)}...${token.slice(-4)}`;
|
|
275
|
+
console.log(`Token: ${preview}`);
|
|
276
|
+
}
|
|
277
|
+
console.log(`Status: Active (via CLAUDE_CODE_OAUTH_TOKEN env var)`);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
console.log(`Token: CLAUDE_CODE_OAUTH_TOKEN is set but REAGENT_ACCOUNT is not.`);
|
|
281
|
+
console.log(`Status: Using env var override (unknown account)`);
|
|
282
|
+
}
|
|
283
|
+
console.log('');
|
|
284
|
+
}
|
|
285
|
+
// --- rotate ---
|
|
286
|
+
function accountRotate(args) {
|
|
287
|
+
const name = args.find((a) => !a.startsWith('--'));
|
|
288
|
+
if (!name) {
|
|
289
|
+
console.error('Usage: reagent account rotate <name>');
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
const config = loadAccounts();
|
|
293
|
+
const account = config.accounts[name];
|
|
294
|
+
if (!account) {
|
|
295
|
+
console.error(`Account "${name}" not found. Run: reagent account list`);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
console.log(`\nRotating credential for: ${name}`);
|
|
299
|
+
console.log('Step 1: Backing up current Claude Code credential...');
|
|
300
|
+
let backupRaw = null;
|
|
301
|
+
try {
|
|
302
|
+
backupRaw = execFileSync('security', ['find-generic-password', '-s', 'Claude Code-credentials', '-w'], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf8' }).trim();
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
// No existing credential
|
|
306
|
+
}
|
|
307
|
+
console.log('Step 2: Opening browser for OAuth login...');
|
|
308
|
+
console.log(` Log in with the account for "${name}".`);
|
|
309
|
+
const loginResult = spawnSync('claude', ['auth', 'login'], {
|
|
310
|
+
stdio: 'inherit',
|
|
311
|
+
});
|
|
312
|
+
if (loginResult.status !== 0) {
|
|
313
|
+
console.error('\nOAuth login failed.');
|
|
314
|
+
if (backupRaw)
|
|
315
|
+
writeClaudeCredential(backupRaw);
|
|
316
|
+
process.exit(1);
|
|
317
|
+
}
|
|
318
|
+
const newCredential = readClaudeCodeCredential();
|
|
319
|
+
if (!newCredential || !newCredential.accessToken) {
|
|
320
|
+
console.error('Failed to read new credential.');
|
|
321
|
+
if (backupRaw)
|
|
322
|
+
writeClaudeCredential(backupRaw);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
console.log('Step 3: Updating keychain entry...');
|
|
326
|
+
keychainSet(account.keychain_service, newCredential);
|
|
327
|
+
if (backupRaw) {
|
|
328
|
+
console.log('Step 4: Restoring original credential...');
|
|
329
|
+
writeClaudeCredential(backupRaw);
|
|
330
|
+
}
|
|
331
|
+
console.log(`\nCredential for "${name}" rotated successfully.\n`);
|
|
332
|
+
}
|
|
333
|
+
// --- remove ---
|
|
334
|
+
function accountRemove(args) {
|
|
335
|
+
const name = args.find((a) => !a.startsWith('--'));
|
|
336
|
+
if (!name) {
|
|
337
|
+
console.error('Usage: reagent account remove <name>');
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
const config = loadAccounts();
|
|
341
|
+
const account = config.accounts[name];
|
|
342
|
+
if (!account) {
|
|
343
|
+
console.error(`Account "${name}" not found.`);
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
// Delete keychain entry
|
|
347
|
+
const deleted = keychainDelete(account.keychain_service);
|
|
348
|
+
if (deleted) {
|
|
349
|
+
console.log(`Deleted keychain entry: ${account.keychain_service}`);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
console.log(`No keychain entry found for: ${account.keychain_service}`);
|
|
353
|
+
}
|
|
354
|
+
// Remove from config
|
|
355
|
+
removeAccountConfig(name);
|
|
356
|
+
console.log(`Removed "${name}" from accounts.yaml.`);
|
|
357
|
+
if (process.env.REAGENT_ACCOUNT === name) {
|
|
358
|
+
console.log(`\nNote: "${name}" is currently active in this shell.`);
|
|
359
|
+
console.log(`Run: eval "$(reagent account env --clear)"\n`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// --- setup-shell ---
|
|
363
|
+
function accountSetupShell(args) {
|
|
364
|
+
const shell = parseFlag(args, '--shell') || 'zsh';
|
|
365
|
+
switch (shell) {
|
|
366
|
+
case 'zsh':
|
|
367
|
+
case 'bash':
|
|
368
|
+
printBashZshSetup();
|
|
369
|
+
break;
|
|
370
|
+
case 'fish':
|
|
371
|
+
printFishSetup();
|
|
372
|
+
break;
|
|
373
|
+
default:
|
|
374
|
+
console.error(`Unsupported shell: ${shell}. Use zsh, bash, or fish.`);
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function printBashZshSetup() {
|
|
379
|
+
console.log(`# reagent multi-account switching
|
|
380
|
+
# Add this to your ~/.zshrc or ~/.bashrc
|
|
381
|
+
|
|
382
|
+
rswitch() {
|
|
383
|
+
if [ -z "$1" ]; then
|
|
384
|
+
reagent account list
|
|
385
|
+
return
|
|
386
|
+
fi
|
|
387
|
+
if [ "$1" = "--clear" ]; then
|
|
388
|
+
eval "$(reagent account env --clear)"
|
|
389
|
+
printf 'Cleared reagent account override.\\n' >&2
|
|
390
|
+
return
|
|
391
|
+
fi
|
|
392
|
+
local output
|
|
393
|
+
output="$(reagent account env "$1" 2>/dev/null)"
|
|
394
|
+
if [[ $? -ne 0 || -z "$output" ]]; then
|
|
395
|
+
printf 'rswitch: failed to load account "%s"\\n' "$1" >&2
|
|
396
|
+
return 1
|
|
397
|
+
fi
|
|
398
|
+
eval "$output"
|
|
399
|
+
printf 'Switched to: %s\\n' "$REAGENT_ACCOUNT" >&2
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
# Tab completion
|
|
403
|
+
if [ -n "$ZSH_VERSION" ]; then
|
|
404
|
+
_rswitch() {
|
|
405
|
+
local accounts
|
|
406
|
+
accounts=(\${(f)"$(reagent account list 2>/dev/null | grep '^ ' | sed 's/^[* ] //' | awk '{print $1}')"})
|
|
407
|
+
compadd -- "\${accounts[@]}" --clear
|
|
408
|
+
}
|
|
409
|
+
compdef _rswitch rswitch
|
|
410
|
+
elif [ -n "$BASH_VERSION" ]; then
|
|
411
|
+
_rswitch() {
|
|
412
|
+
local accounts
|
|
413
|
+
accounts=$(reagent account list 2>/dev/null | grep '^ ' | sed 's/^[* ] //' | awk '{print $1}')
|
|
414
|
+
COMPREPLY=( $(compgen -W "$accounts --clear" -- "\${COMP_WORDS[COMP_CWORD]}") )
|
|
415
|
+
}
|
|
416
|
+
complete -F _rswitch rswitch
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
# Optional: show active account in prompt
|
|
420
|
+
# PROMPT='\${REAGENT_ACCOUNT:+[\\$REAGENT_ACCOUNT] }'"$PROMPT"
|
|
421
|
+
`);
|
|
422
|
+
}
|
|
423
|
+
function printFishSetup() {
|
|
424
|
+
console.log(`# reagent multi-account switching for fish
|
|
425
|
+
# Add this to your ~/.config/fish/config.fish
|
|
426
|
+
|
|
427
|
+
function rswitch
|
|
428
|
+
if test (count $argv) -eq 0
|
|
429
|
+
reagent account list
|
|
430
|
+
return
|
|
431
|
+
end
|
|
432
|
+
if test "$argv[1]" = "--clear"
|
|
433
|
+
eval (reagent account env --clear)
|
|
434
|
+
echo "Cleared reagent account override." >&2
|
|
435
|
+
return
|
|
436
|
+
end
|
|
437
|
+
set -l output (reagent account env $argv[1] 2>/dev/null)
|
|
438
|
+
if test $status -ne 0; or test -z "$output"
|
|
439
|
+
echo "rswitch: failed to load account \\"$argv[1]\\"" >&2
|
|
440
|
+
return 1
|
|
441
|
+
end
|
|
442
|
+
eval $output
|
|
443
|
+
echo "Switched to: $REAGENT_ACCOUNT" >&2
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Tab completion
|
|
447
|
+
complete -c rswitch -f -a '(reagent account list 2>/dev/null | grep "^ " | sed "s/^[* ] //" | awk "{print \\$1}")'
|
|
448
|
+
complete -c rswitch -f -a '--clear'
|
|
449
|
+
`);
|
|
450
|
+
}
|
|
451
|
+
// --- helpers ---
|
|
452
|
+
function escapeShellSingleQuote(s) {
|
|
453
|
+
return s.replace(/'/g, "'\\''");
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/cli/commands/account.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/index.ts"],"names":[],"mappings":"AAqBA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmM5C"}
|
|
@@ -12,6 +12,7 @@ import { installMcpJson } from './mcp-config.js';
|
|
|
12
12
|
import { installAgents } from './agents.js';
|
|
13
13
|
import { installClaudeCommands } from './commands.js';
|
|
14
14
|
import { installPm } from './pm.js';
|
|
15
|
+
import { installPackageDep } from './package-dep.js';
|
|
15
16
|
import { installGitHub } from './github.js';
|
|
16
17
|
import { installProfile, listTechProfiles } from './profiles.js';
|
|
17
18
|
import { installDiscord, parseDiscordArgs } from './discord.js';
|
|
@@ -74,6 +75,8 @@ export function runInit(args) {
|
|
|
74
75
|
if (!dryRun) {
|
|
75
76
|
fs.mkdirSync(path.join(targetDir, '.claude'), { recursive: true });
|
|
76
77
|
}
|
|
78
|
+
// Step 0: Install @bookedsolid/reagent as devDependency (before MCP config needs node_modules)
|
|
79
|
+
results.push(...installPackageDep(targetDir, dryRun));
|
|
77
80
|
// Step 1: .gitignore entries
|
|
78
81
|
if (profile.gitignoreEntries?.length) {
|
|
79
82
|
results.push(...installGitignoreEntries(targetDir, profile.gitignoreEntries, dryRun));
|