@datarails-ai/dr-cli 0.0.1-locked → 1.6.71
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 +608 -0
- package/dist/chunk-DWMCBGQH.js +242 -0
- package/dist/cli.js +64468 -0
- package/dist/kb-6UWI7Q32.js +21 -0
- package/dist/scopes-map.json +4412 -0
- package/dist/skills/connector-sandbox/SKILL.md +95 -0
- package/dist/skills/datarails-connect-workato/SKILL.md +140 -0
- package/dist/skills/datarails-connectors-onboard-connector/SKILL.md +813 -0
- package/dist/skills/dr-cli/SKILL.md +659 -0
- package/dist/skills/dr-cli/reference/admin.md +796 -0
- package/dist/skills/dr-cli/reference/budget-builder.md +151 -0
- package/dist/skills/dr-cli/reference/calc-vals.md +73 -0
- package/dist/skills/dr-cli/reference/calcmodels.md +76 -0
- package/dist/skills/dr-cli/reference/cash.md +61 -0
- package/dist/skills/dr-cli/reference/dashboards-widgets.md +85 -0
- package/dist/skills/dr-cli/reference/datamappers.md +150 -0
- package/dist/skills/dr-cli/reference/desk.md +472 -0
- package/dist/skills/dr-cli/reference/filebox-documents.md +373 -0
- package/dist/skills/dr-cli/reference/forecast.md +51 -0
- package/dist/skills/dr-cli/reference/integrations.md +57 -0
- package/dist/skills/dr-cli/reference/lookups.md +168 -0
- package/dist/skills/dr-cli/reference/metrics.md +512 -0
- package/dist/skills/dr-cli/reference/multi-product.md +180 -0
- package/dist/skills/dr-cli/reference/reconciliation-mec.md +76 -0
- package/dist/skills/dr-cli/reference/rh-config.md +84 -0
- package/dist/skills/dr-cli/reference/safety.md +143 -0
- package/dist/skills/dr-cli/reference/spend-control.md +206 -0
- package/dist/skills/dr-cli/reference/templates.md +163 -0
- package/dist/skills/dr-cli/reference/workflows.md +137 -0
- package/dist/skills/dr-error-enrichment/SKILL.md +80 -0
- package/dist/skills/dr-error-enrichment/reference/core.md +257 -0
- package/dist/skills/dr-error-enrichment/reference/groundcover.md +84 -0
- package/dist/skills/dr-error-enrichment/reference/jira-bugs.md +219 -0
- package/dist/skills/dr-error-enrichment/reference/safety-backup.md +122 -0
- package/dist/skills/dr-error-enrichment-author/SKILL.md +219 -0
- package/dist/skills/dr-error-enrichment-improve/SKILL.md +218 -0
- package/dist/skills/dr-error-enrichment-maintain/SKILL.md +237 -0
- package/dist/skills/dr-error-enrichment-reconcile/SKILL.md +167 -0
- package/dist/skills/dr-filebox-api-setup/SKILL.md +170 -0
- package/dist/skills/dr-switch-user/SKILL.md +395 -0
- package/dist/skills/dr-validate/SKILL.md +392 -0
- package/dist/skills/dr-validate/report-template.html +950 -0
- package/dist/skills/fx-conversion-matrix/SKILL.md +763 -0
- package/dist/skills/fx-conversion-matrix/scripts/_args.mjs +52 -0
- package/dist/skills/fx-conversion-matrix/scripts/_xlsx.mjs +241 -0
- package/dist/skills/fx-conversion-matrix/scripts/build-matrix.mjs +366 -0
- package/dist/skills/fx-conversion-matrix/scripts/gen-mappers.mjs +171 -0
- package/dist/skills/fx-conversion-matrix/scripts/rates-to-xlsx.mjs +172 -0
- package/dist/skills/fx-onboard/SKILL.md +325 -0
- package/dist/skills/mec-table-validation/SKILL.md +383 -0
- package/dist/skills/plugins.json +24 -0
- package/dist/skills/validate-workato-migration/SKILL.md +167 -0
- package/dist/skills/validate-workato-migration/reference/gotchas.md +16 -0
- package/dist/skills/validate-workato-migration/reference/staging-orgs.md +26 -0
- package/dist/skills/validate-workato-migration/scripts/compare_files.py +255 -0
- package/dist/zendeskKb-JPSHVOPH.js +243 -0
- package/package.json +56 -9
- package/scripts/postinstall.mjs +91 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dr-switch-user
|
|
3
|
+
description: Set an in-conversation default --account for dr-cli (Datarails CLI), and impersonate a customer via `dr login-as` when needed. Use when the user wants to switch identity, log in as someone else, impersonate a customer, or list saved identities. Triggers - "switch to <email>", "switch user to <email>", "use <email>", "use <email> from now on", "login as <email>", "log me in as <email>", "impersonate <email>", "show me available identities", "show stored identities", "list saved users", "who am I logged in as", "which dr accounts are saved", "/switch-user", "/switch-user <email>". The session default itself is not written to any file - it's a rule Claude follows for the rest of this conversation; credential storage is handled by dr login / dr login-as. Install, update, or log in to the CLI → /dr-cli:install; a CLI that is installed but misbehaving → /dr-cli:doctor.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dr-switch-user — set the session default --account for dr-cli
|
|
7
|
+
|
|
8
|
+
## Why this skill exists
|
|
9
|
+
|
|
10
|
+
`dr-cli` is **stateless with respect to identity** — every command takes
|
|
11
|
+
`--account <email>` separately. There is no "active user" in the CLI. So
|
|
12
|
+
"switching user" really means: tell Claude which email to pass as
|
|
13
|
+
`--account` for the rest of *this conversation only*.
|
|
14
|
+
|
|
15
|
+
This skill does three things:
|
|
16
|
+
|
|
17
|
+
1. **Verify** the chosen email has working credentials on at least one
|
|
18
|
+
server, by probing each server's local JWT via `dr whoami`.
|
|
19
|
+
2. **Add the identity** if credentials are missing — either by
|
|
20
|
+
impersonating a customer with `dr login-as <email>` (JWT only, no
|
|
21
|
+
browser; needs an operator login first), or by a browser `dr login`
|
|
22
|
+
for the operator's own identity. See Section 3.
|
|
23
|
+
3. **Record an in-conversation session default** — a directive Claude
|
|
24
|
+
obeys for the rest of this chat.
|
|
25
|
+
|
|
26
|
+
> **Impersonation is now a real CLI command.** `dr login-as <email>
|
|
27
|
+
> --server <X>` mints an impersonation JWT from an existing operator login
|
|
28
|
+
> and stores it as a switchable `(server, email)` identity — no browser
|
|
29
|
+
> round-trip. This is the correct path for "log me in as <customer>";
|
|
30
|
+
> browser `dr login` can only sign you in as whoever the browser is.
|
|
31
|
+
|
|
32
|
+
## Hard rules
|
|
33
|
+
|
|
34
|
+
- **Never persist.** Do not write to `MEMORY.md`, `CLAUDE.md`,
|
|
35
|
+
`settings.json`, or any other file. The default lives only in
|
|
36
|
+
Claude's context for this conversation. Opening a new Claude Code
|
|
37
|
+
session = no default carries over.
|
|
38
|
+
- **Never assume which identity to use.** This skill is the cure for
|
|
39
|
+
exactly that mistake. If the user's intent is ambiguous (no email
|
|
40
|
+
given, multiple matches, mismatch after login), **ask**.
|
|
41
|
+
- **Server is always passed per-command.** The default scopes only
|
|
42
|
+
`--account`. `--server` stays explicit on every dr invocation.
|
|
43
|
+
|
|
44
|
+
## Inputs
|
|
45
|
+
|
|
46
|
+
The skill is invoked in one of these forms:
|
|
47
|
+
|
|
48
|
+
| Form | Meaning |
|
|
49
|
+
| ------------------------------------------ | ---------------------------------------------------- |
|
|
50
|
+
| `/switch-user <email>` or "switch to <email>" | Set default to `<email>` (Sections 2 + 3 below) |
|
|
51
|
+
| `/switch-user` (no arg) or "show identities" | List all stored identities + offer picker (Section 4) |
|
|
52
|
+
| "stop defaulting" / "clear default user" | Remove any active session default |
|
|
53
|
+
|
|
54
|
+
## Server keys (the universe to probe)
|
|
55
|
+
|
|
56
|
+
`US`, `US2`, `UK`, `CA`, `EU`, `DEV`, `DEV-1`, `TEST`, `TEST-1`, `TEST-2`, `TEST-3`, `TEST-4`, `TEST-5`, `TEST-6`, `TEST-7`, `DEMO` — case-insensitive.
|
|
57
|
+
These are the only valid `--server` values dr-cli accepts.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Section 1 — Validate the email
|
|
62
|
+
|
|
63
|
+
Before probing, sanity-check the input:
|
|
64
|
+
|
|
65
|
+
- Must contain a single `@`.
|
|
66
|
+
- Must have at least one character before and after `@`.
|
|
67
|
+
- Must contain at least one `.` after the `@`.
|
|
68
|
+
|
|
69
|
+
If invalid: print `<input> doesn't look like an email — usage:
|
|
70
|
+
/switch-user <user>@<domain>` and stop. Do not probe.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Section 2 — Probe one server for the email (happy path)
|
|
75
|
+
|
|
76
|
+
**Do NOT probe all 16 servers.** When the user invokes the skill with an
|
|
77
|
+
email, they have a specific server in mind. Asking is cheap; guessing
|
|
78
|
+
across all servers wastes turns and can scope the default wrongly.
|
|
79
|
+
|
|
80
|
+
### 2.1. Ask which server
|
|
81
|
+
|
|
82
|
+
Print verbatim, then wait for the user's reply. Do not guess from
|
|
83
|
+
context, prior turns, or `userEmail`:
|
|
84
|
+
|
|
85
|
+
> Which server should I switch to `<email>` on? (`US`, `US2`, `UK`, `CA`, `EU`, `DEV`, `DEV-1`, `TEST`, `TEST-1`, `TEST-2`, `TEST-3`, `TEST-4`, `TEST-5`, `TEST-6`, `TEST-7`, `DEMO`)
|
|
86
|
+
|
|
87
|
+
### 2.2. Probe that one server
|
|
88
|
+
|
|
89
|
+
Run a single Bash call:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
dr whoami --server <X> --account <email> 2>&1 || true
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`whoami` is purely offline (decodes the locally-stored JWT, no network).
|
|
96
|
+
Classify the output:
|
|
97
|
+
|
|
98
|
+
| Result | Meaning |
|
|
99
|
+
| ------------------------------------------------------ | ---------------------------------------- |
|
|
100
|
+
| Exit 0, prints matching email + JWT exp | Stored on this server → Section 5 (if it shows `Impersonated by:`, it's a login-as identity — still stored, still fine) |
|
|
101
|
+
| `not logged in to <SERVER>` | Not stored → Section 3 (add it — login-as or browser login) |
|
|
102
|
+
| `no JWT stored for <server>` | Creds malformed → Section 3 (add it — login-as or browser login) |
|
|
103
|
+
| `multiple accounts stored for <SERVER>: ...` with the requested email in the list | Stored on this server (defensive case — passing --account should normally avoid this) → Section 5 |
|
|
104
|
+
| Anything else | Surface verbatim, do not record a default |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Section 3 — Add the identity (email not stored on the chosen server)
|
|
109
|
+
|
|
110
|
+
The server was already chosen in Section 2.1. There are **two ways** to add
|
|
111
|
+
`<email>`, and which is correct depends on *whose* identity it is:
|
|
112
|
+
|
|
113
|
+
- **3A — Impersonate a customer with `dr login-as` (JWT, no browser).**
|
|
114
|
+
Use when `<email>` is a **customer / another user** you want to act as,
|
|
115
|
+
and you (an operator/support user) are already logged in on this server.
|
|
116
|
+
This is the normal path for "log me in as <customer>".
|
|
117
|
+
- **3B — Browser `dr login` (your own / the operator identity).**
|
|
118
|
+
Use when `<email>` is **you** (the operator) and you just haven't logged
|
|
119
|
+
in on this server yet — or when there's *no* operator login on the server
|
|
120
|
+
at all, so nobody can authorize an impersonation.
|
|
121
|
+
|
|
122
|
+
Decide with one offline probe (no network) — list what's stored on <X>:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
dr whoami --server <X> 2>&1 || true
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- **An operator (non-impersonated) login already exists on <X>** and
|
|
129
|
+
`<email>` is *not* that operator → **3A** (login-as).
|
|
130
|
+
- **Nothing is stored on <X>**, or the only way to reach `<email>` is to
|
|
131
|
+
sign in as yourself → **3B** (browser login).
|
|
132
|
+
|
|
133
|
+
If it's genuinely ambiguous whether `<email>` is a customer to impersonate
|
|
134
|
+
or an operator to sign in as, **ask** — don't guess.
|
|
135
|
+
|
|
136
|
+
### 3A. Impersonate via `dr login-as`
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
dr login-as <email> --server <X>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Resolves `<email>` to a user id via `can_login_as`, mints an impersonation
|
|
143
|
+
JWT from the monolith authorized by the operator, and stores it as a
|
|
144
|
+
switchable `(server, email)` identity — no browser, no TTY prompt.
|
|
145
|
+
|
|
146
|
+
- **Multiple operators stored on <X>** → the CLI refuses and lists them.
|
|
147
|
+
Re-run with `--as <operator-email>` to pick who authorizes the mint.
|
|
148
|
+
- **Email doesn't resolve** → the CLI suggests near matches; if you already
|
|
149
|
+
know the id, re-run with `--user-id <n>`.
|
|
150
|
+
- **No operator login on <X>** → the CLI says to run `dr login` first. Fall
|
|
151
|
+
back to **3B** to establish the operator, then re-run login-as.
|
|
152
|
+
- **Denials** surface as clear messages — *not permitted to impersonate*,
|
|
153
|
+
*inactive*, *impersonation service unavailable*. Surface verbatim; do not
|
|
154
|
+
retry; do not record a default.
|
|
155
|
+
- **`login-as` needs dr ≥ 1.3.24.** Older installs answer `unknown command
|
|
156
|
+
'login-as'`. If the browser Login-As works but the CLI "can't", check
|
|
157
|
+
`dr --version` / `dr update` first — that's the common cause, not permissions.
|
|
158
|
+
- **The product `SUPER_ADMIN` role ≠ Django `is_superuser`.** `login-as` runs
|
|
159
|
+
the *same* gate as the browser Login-As (`it_loginas`) and only blocks
|
|
160
|
+
genuine Django `is_superuser` / sync-service / application targets — a
|
|
161
|
+
customer whose product role is `SUPER_ADMIN` is still impersonable (verified
|
|
162
|
+
on DEMO). There is **no** equal-or-higher-privilege rule, so a `can-login-as`
|
|
163
|
+
hit is generally reliable. `not permitted` means a true superuser/sync/
|
|
164
|
+
application target, or you the operator lack scope (superuser operator → any
|
|
165
|
+
non-superuser; supporting-manager → only users in your supported orgs). If it
|
|
166
|
+
fires, surface the message — don't fall back to browser login as that email.
|
|
167
|
+
- **Success** prints
|
|
168
|
+
`Logged into <X> as <email> (impersonated by <operator>). JWT expires in …`
|
|
169
|
+
→ go to Section 5 (record the default, scoped to this server). No
|
|
170
|
+
post-login identity check needed — login-as targets `<email>` directly,
|
|
171
|
+
so there's no browser-mismatch risk.
|
|
172
|
+
|
|
173
|
+
### 3B. Browser login via `dr login`
|
|
174
|
+
|
|
175
|
+
Do **not** prompt the user before running login. Just run it. The
|
|
176
|
+
post-login identity check (3B.2) is the safety net for the
|
|
177
|
+
browser-signed-in-as-the-wrong-account case — we catch the mismatch after
|
|
178
|
+
and let the user decide.
|
|
179
|
+
|
|
180
|
+
Optionally print a single short status line like *"Running `dr login
|
|
181
|
+
--server <X>` — if your browser is signed in as a different account, the
|
|
182
|
+
OAuth flow will pick that one and I'll flag the mismatch after. To
|
|
183
|
+
impersonate a customer instead, I can use `dr login-as` once there's an
|
|
184
|
+
operator login here."* **Do not wait for a reply.**
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
dr login --server <X>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
(No `--account` flag — `dr login` doesn't accept one; the browser flow
|
|
191
|
+
determines identity.)
|
|
192
|
+
|
|
193
|
+
#### 3B.2. Verify post-login identity
|
|
194
|
+
|
|
195
|
+
Capture the email from the success line:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
Logged into <X> as <whoever>@datarails.com. JWT expires in ...
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Compare `<whoever>@datarails.com` to the requested `<email>`:
|
|
202
|
+
|
|
203
|
+
- **Match** → loop back to Section 5 (announce + record default,
|
|
204
|
+
scoped to this server).
|
|
205
|
+
- **Mismatch** → print and stop:
|
|
206
|
+
|
|
207
|
+
> Browser logged you in as `<whoever>@datarails.com`, not `<email>`. Three options: (1) if `<email>` is a customer, keep `<whoever>` as the operator and re-run `/switch-user <email>` — I'll impersonate via `dr login-as`; (2) sign out of the browser and re-run `/switch-user <email>`; or (3) accept `<whoever>` as the new session default instead. Which?
|
|
208
|
+
|
|
209
|
+
Do **not** auto-pick. Do **not** silently accept the wrong identity.
|
|
210
|
+
|
|
211
|
+
#### 3B.3. Login failures
|
|
212
|
+
|
|
213
|
+
Browser closed, timeout, network error: surface dr-cli's stderr
|
|
214
|
+
verbatim. Do not retry. Do not record any default.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Section 4 — No-arg flow: list saved identities + picker
|
|
219
|
+
|
|
220
|
+
User invokes `/switch-user` with no email, or asks "show identities" /
|
|
221
|
+
"who's logged in" / "which accounts are saved".
|
|
222
|
+
|
|
223
|
+
### 4.1. Probe every server (no --account)
|
|
224
|
+
|
|
225
|
+
Use the **single-loop pattern** (same reason as Section 2 — parallel
|
|
226
|
+
tool calls cancel each other on the first non-zero exit):
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
for srv in US US2 UK CA EU DEV DEV-1 TEST TEST-1 TEST-2 TEST-3 TEST-4 TEST-5 TEST-6 TEST-7 DEMO; do
|
|
230
|
+
echo "=== $srv ==="
|
|
231
|
+
dr whoami --server "$srv" 2>&1 || true
|
|
232
|
+
done
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Possible outcomes per server (parse each `=== <srv> ===` block):
|
|
236
|
+
|
|
237
|
+
- **Exit 0** → one identity is stored; capture the email from output.
|
|
238
|
+
- **Exit 1 with `multiple accounts stored for <SERVER>:`** → parse
|
|
239
|
+
the email list from stderr. Each row shape: ` - <email> (last used <date>)`.
|
|
240
|
+
- **`not logged in`** or **`no JWT stored`** → skip this server.
|
|
241
|
+
|
|
242
|
+
### 4.2. Render a picker
|
|
243
|
+
|
|
244
|
+
Print a numbered, flat list of every `(server, email, last-used)` pair
|
|
245
|
+
found:
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
Stored identities:
|
|
249
|
+
1. US alice@datarails.com (last used 2026-05-14)
|
|
250
|
+
2. US bob@datarails.com (last used 2026-05-15)
|
|
251
|
+
3. DEV alice@datarails.com (last used 2026-05-10)
|
|
252
|
+
4. DEMO carol@datarails.com (last used 2026-04-02)
|
|
253
|
+
|
|
254
|
+
Reply with a number to set as session default, or an email to set that
|
|
255
|
+
email across every server it appears on. Reply 'login' to add a new
|
|
256
|
+
identity (browser login for yourself, or `dr login-as` to impersonate a
|
|
257
|
+
customer).
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Wait for the user's pick.
|
|
261
|
+
|
|
262
|
+
### 4.3. Resolve the pick
|
|
263
|
+
|
|
264
|
+
- **Number** → default is scoped to that one specific `(server, email)`
|
|
265
|
+
pair. Jump straight to Section 5.
|
|
266
|
+
- **Email** → ambiguous when the email shows up on multiple rows. Ask:
|
|
267
|
+
*"On which server should I switch to `<email>`? (servers shown above
|
|
268
|
+
where it's stored: <list>)"* — then jump to Section 5 with the
|
|
269
|
+
chosen `(email, server)`. Do not guess.
|
|
270
|
+
- **`login`** → ask which server to log in to (Section 2.1 prompt),
|
|
271
|
+
then enter Section 3.
|
|
272
|
+
|
|
273
|
+
### 4.4. Empty case
|
|
274
|
+
|
|
275
|
+
If no identities are stored anywhere across all 16 servers → skip the
|
|
276
|
+
picker entirely, print "No identities are currently stored." and ask
|
|
277
|
+
the user if they want to log in (then enter Section 3).
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Section 5 — Announce + record the session default
|
|
282
|
+
|
|
283
|
+
After Section 2 or 3 or 4 successfully resolves an `(email, server)`
|
|
284
|
+
pair, print **two things** to the user.
|
|
285
|
+
|
|
286
|
+
### 5.1. Human-readable announcement
|
|
287
|
+
|
|
288
|
+
> `<email>` is logged in on **<server>**. For the rest of this session I'll pass `--account <email>` on dr commands targeting that server. For any other server I'll ask before running.
|
|
289
|
+
|
|
290
|
+
If the identity is an impersonation (it was created by `dr login-as`, or
|
|
291
|
+
`whoami` shows `Impersonated by: <operator>`), add:
|
|
292
|
+
|
|
293
|
+
> This is an impersonated identity (operator: `<operator>`). Its token refreshes silently and auto-remints from the operator, so you won't be re-prompted until the operator's own login expires.
|
|
294
|
+
|
|
295
|
+
### 5.2. Directive block (delimited, durable across compaction)
|
|
296
|
+
|
|
297
|
+
This is the actual mechanism. Print exactly this shape — fenced as
|
|
298
|
+
code, with the visible separators — so Claude treats it as a binding
|
|
299
|
+
rule, not chat prose:
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
======== dr-cli session default (this conversation only) ========
|
|
303
|
+
Default --account: <email>
|
|
304
|
+
Scoped to server: <X>
|
|
305
|
+
|
|
306
|
+
Rule for every subsequent dr-cli invocation in this session:
|
|
307
|
+
- If --server is <X>: pass --account <email> automatically.
|
|
308
|
+
Do not ask the user.
|
|
309
|
+
- If --server is any other key: ASK the user which account before
|
|
310
|
+
running. Do not guess.
|
|
311
|
+
- If the user later says "switch to <other email>", "use <other>",
|
|
312
|
+
"stop defaulting", "clear default user", or invokes /switch-user
|
|
313
|
+
again: that supersedes this rule.
|
|
314
|
+
|
|
315
|
+
Do not persist this to memory, MEMORY.md, CLAUDE.md, settings.json,
|
|
316
|
+
or any file. It dies with this conversation.
|
|
317
|
+
=================================================================
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
After printing the directive, **honor it for the rest of the
|
|
321
|
+
conversation**: on every `dr <subcommand>` invocation thereafter, if
|
|
322
|
+
`--server` matches the scoped server, automatically include
|
|
323
|
+
`--account <email>`. If `--server` is any other key, pause and ask
|
|
324
|
+
before running.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Section 6 — Clearing the default
|
|
329
|
+
|
|
330
|
+
If the user says "stop defaulting", "clear default user", "no default",
|
|
331
|
+
or `/switch-user --clear`:
|
|
332
|
+
|
|
333
|
+
1. Print: `Cleared. From now on I'll ask which account to use on each dr command.`
|
|
334
|
+
2. Mentally retire the directive block from Section 5. On subsequent
|
|
335
|
+
`dr` calls, ask the user for `--account` before running, exactly as
|
|
336
|
+
if the skill had never been invoked.
|
|
337
|
+
|
|
338
|
+
Do **not** rewrite or delete files. Do **not** run any dr commands.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Section 7 — Override semantics
|
|
343
|
+
|
|
344
|
+
If the user re-invokes `/switch-user <other email>` while a default is
|
|
345
|
+
already active:
|
|
346
|
+
|
|
347
|
+
- Run Sections 1–5 against the new email from scratch.
|
|
348
|
+
- The new directive block fully replaces the old one. No merging, no
|
|
349
|
+
per-server overrides.
|
|
350
|
+
|
|
351
|
+
If the user reinvokes `/switch-user` (no arg):
|
|
352
|
+
|
|
353
|
+
- Run Section 4 from scratch.
|
|
354
|
+
- The picker shows the current state of the keychain, including any
|
|
355
|
+
identity that was just added by an earlier `/switch-user` call.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Edge cases
|
|
360
|
+
|
|
361
|
+
| Case | Behavior |
|
|
362
|
+
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
363
|
+
| Email has a typo / wrong format | Reject up-front (Section 1). Do not probe. |
|
|
364
|
+
| `dr` binary not on PATH | First probe fails with `command not found`. Surface verbatim plus hint: `Run node scripts/install.mjs from the dr-cli repo to install the dr binary.` |
|
|
365
|
+
| JWT expired but refresh token alive | `whoami` decodes locally and still prints the email — treat as stored. dr-cli auto-refreshes on the next real network call. |
|
|
366
|
+
| Refresh token dead | Not visible at switch-time (whoami is offline). User will hit `session expired` on their next real `dr` command — at that point they should re-invoke `/switch-user <email>` to re-login. |
|
|
367
|
+
| Impersonated identity, its refresh dies | dr-cli auto-remints a fresh impersonation JWT from the operator on the next real command — no re-invoke needed, unless the **operator's own** login has also expired (then re-login the operator, then re-run `dr login-as`). |
|
|
368
|
+
| Target email you can't impersonate (`not permitted` / `inactive`) | `dr login-as` fails with that message. Surface verbatim. Do not fall back to browser login as that email. Do not record a default. |
|
|
369
|
+
| User cancels mid-login (closes browser, Ctrl-C, timeout) | dr exits non-zero with a cancel/timeout message. Surface verbatim. Do not record any default. Do not retry automatically. |
|
|
370
|
+
| Same email logged in on multiple servers, user picks the email (not a numbered row from the picker) | Ask the user which of the matching servers to scope to. Do not guess. |
|
|
371
|
+
| Login succeeds, post-login email matches requested email | Section 5 with the just-logged-in server in scope. |
|
|
372
|
+
| Login succeeds, post-login email does NOT match | Section 3B.2 mismatch prompt. Do not record any default until the user decides. |
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## What this skill does NOT do
|
|
377
|
+
|
|
378
|
+
- It does **not** write the session default to any file. But it *does*
|
|
379
|
+
trigger `dr login` / `dr login-as` when an identity is missing, and those
|
|
380
|
+
commands write credentials to the keychain (the skill never touches the
|
|
381
|
+
keychain directly). Refresh and impersonation auto-remint are handled by
|
|
382
|
+
dr-cli itself.
|
|
383
|
+
- It does **not** write to `MEMORY.md`, `CLAUDE.md`,
|
|
384
|
+
`settings.json`, or anywhere else on disk. The default is purely
|
|
385
|
+
conversational.
|
|
386
|
+
- It does **not** survive context compaction guaranteed. If a long
|
|
387
|
+
conversation compresses the directive block away, the default
|
|
388
|
+
silently dies — re-invoke if you notice Claude stopped honoring it.
|
|
389
|
+
- It does **not** validate refresh-token health (would require network
|
|
390
|
+
round-trips). If the refresh token is dead, the user will discover
|
|
391
|
+
it on their next real `dr` command, not at switch-time.
|
|
392
|
+
- It does **not** override the dr-cli skill's own Guard Rail #5
|
|
393
|
+
("never assume which identity to send as --account") for ambiguous
|
|
394
|
+
cases — that rule still applies. This skill is the *resolution
|
|
395
|
+
mechanism* for that ambiguity, not a way around it.
|