@agentteams/cli 0.1.95 → 0.1.97

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.
Files changed (59) hide show
  1. package/.eslintcache +1 -1
  2. package/README.md +103 -1
  3. package/dist/auth/credentialStore.d.ts +70 -10
  4. package/dist/auth/credentialStore.d.ts.map +1 -1
  5. package/dist/auth/credentialStore.js +207 -20
  6. package/dist/auth/credentialStore.js.map +1 -1
  7. package/dist/auth/deviceAuthClient.d.ts +63 -0
  8. package/dist/auth/deviceAuthClient.d.ts.map +1 -0
  9. package/dist/auth/deviceAuthClient.js +131 -0
  10. package/dist/auth/deviceAuthClient.js.map +1 -0
  11. package/dist/auth/fileCredentialStore.d.ts +172 -0
  12. package/dist/auth/fileCredentialStore.d.ts.map +1 -0
  13. package/dist/auth/fileCredentialStore.js +445 -0
  14. package/dist/auth/fileCredentialStore.js.map +1 -0
  15. package/dist/auth/personalTokenClient.d.ts +51 -1
  16. package/dist/auth/personalTokenClient.d.ts.map +1 -1
  17. package/dist/auth/personalTokenClient.js +135 -4
  18. package/dist/auth/personalTokenClient.js.map +1 -1
  19. package/dist/auth/personalTokenStore.d.ts +1 -1
  20. package/dist/auth/personalTokenStore.d.ts.map +1 -1
  21. package/dist/auth/personalTokenStore.js +7 -2
  22. package/dist/auth/personalTokenStore.js.map +1 -1
  23. package/dist/auth/refreshLock.d.ts +5 -2
  24. package/dist/auth/refreshLock.d.ts.map +1 -1
  25. package/dist/auth/refreshLock.js +8 -4
  26. package/dist/auth/refreshLock.js.map +1 -1
  27. package/dist/auth/slotHash.d.ts +15 -0
  28. package/dist/auth/slotHash.d.ts.map +1 -0
  29. package/dist/auth/slotHash.js +18 -0
  30. package/dist/auth/slotHash.js.map +1 -0
  31. package/dist/commands/auth.d.ts +75 -2
  32. package/dist/commands/auth.d.ts.map +1 -1
  33. package/dist/commands/auth.js +150 -4
  34. package/dist/commands/auth.js.map +1 -1
  35. package/dist/commands/doctor.js +1 -1
  36. package/dist/commands/doctor.js.map +1 -1
  37. package/dist/commands/init.d.ts +10 -0
  38. package/dist/commands/init.d.ts.map +1 -1
  39. package/dist/commands/init.js +82 -2
  40. package/dist/commands/init.js.map +1 -1
  41. package/dist/index.js +26 -2
  42. package/dist/index.js.map +1 -1
  43. package/dist/mcp/context.d.ts +1 -1
  44. package/dist/mcp-registration/index.js +3 -3
  45. package/dist/mcp-registration/index.js.map +1 -1
  46. package/dist/mcp-registration/serverSpec.d.ts +1 -1
  47. package/dist/types/index.d.ts +3 -1
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/utils/authFormat.d.ts.map +1 -1
  50. package/dist/utils/authFormat.js +47 -11
  51. package/dist/utils/authFormat.js.map +1 -1
  52. package/dist/utils/config.d.ts +19 -1
  53. package/dist/utils/config.d.ts.map +1 -1
  54. package/dist/utils/config.js +57 -1
  55. package/dist/utils/config.js.map +1 -1
  56. package/dist/utils/initOutput.d.ts.map +1 -1
  57. package/dist/utils/initOutput.js +14 -3
  58. package/dist/utils/initOutput.js.map +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,445 @@
1
+ /**
2
+ * Last-resort credential storage: one permission-protected file per slot.
3
+ *
4
+ * The OS credential stores in `credentialStore.ts` are the preferred home for the
5
+ * personal refresh token, but every one of them can be unavailable in exactly the
6
+ * situation a personal login matters most — a remote session:
7
+ *
8
+ * Linux no Secret Service on the bus, so `secret-tool` has nothing to talk to
9
+ * macOS the login keychain of an SSH session is locked, so writes are refused
10
+ * Windows PasswordVault rejects the write for a session with no interactive logon
11
+ *
12
+ * Before this backend existed all three ended the same way: the user walked to
13
+ * another device, approved the request, and was then told the login could not be
14
+ * saved — after which it was revoked. A protected file is a weaker secret than a
15
+ * keyring, and this module never pretends otherwise; it is a deliberate trade
16
+ * against losing the login entirely.
17
+ *
18
+ * What it does not trade away is the protection it *can* enforce, which is where
19
+ * the two platform paths come from:
20
+ *
21
+ * POSIX 0700 directory, 0600 file, plus an ownership / symlink / node-type
22
+ * check before every read and write.
23
+ * Windows `fs.chmod` only moves the read-only bit there, so `0600` would be a
24
+ * lie. `icacls` strips inheritance and grants the current user alone,
25
+ * and an ACL that cannot be set or verified disables the backend
26
+ * rather than downgrading it to an unprotected file.
27
+ *
28
+ * Every failure here is closed: when the protection cannot be proven, no token is
29
+ * read and none is written. The caller then behaves exactly as it did before this
30
+ * module existed.
31
+ */
32
+ import { randomUUID } from 'node:crypto';
33
+ import { chmodSync, lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
34
+ import { homedir } from 'node:os';
35
+ import { join } from 'node:path';
36
+ import { credentialSlotHash } from './slotHash.js';
37
+ /** Shown to the user wherever a backend name is reported. */
38
+ export const FILE_CREDENTIAL_BACKEND = 'protected-file';
39
+ /** Same `.agentteams` directory the rotation locks live in, one level down. */
40
+ export const CREDENTIAL_DIR = ['.agentteams', 'credentials'];
41
+ /**
42
+ * Opt-out for organisations that forbid a plaintext secret on disk at any
43
+ * protection level. Setting it restores the pre-fallback behaviour for every new
44
+ * login, including the refusal to start device authorization.
45
+ *
46
+ * It gates **writing**, not seeing. A file this CLI wrote before the opt-out was
47
+ * set stays readable and removable, so `auth logout` can still revoke that token
48
+ * and delete it; blinding the store instead would strand a live refresh token on
49
+ * disk with no CLI path left to reach it.
50
+ */
51
+ export const FILE_CREDENTIALS_DISABLED_ENV = 'AGENTTEAMS_DISABLE_FILE_CREDENTIALS';
52
+ const DIRECTORY_MODE = 0o700;
53
+ const FILE_MODE = 0o600;
54
+ /** Bits that must be clear: anything reachable by group or other. */
55
+ const SHARED_ACCESS_MASK = 0o077;
56
+ /** Bumped only if the on-disk shape changes; an unknown version is refused. */
57
+ const FILE_FORMAT_VERSION = 1;
58
+ export function isFileCredentialFallbackDisabled(env = process.env) {
59
+ const value = env[FILE_CREDENTIALS_DISABLED_ENV];
60
+ return value !== undefined && value !== '' && value !== '0' && value.toLowerCase() !== 'false';
61
+ }
62
+ /** `personal-token-<hash>.cred` — the rotation lock's name with a different suffix. */
63
+ export function credentialFileName(account) {
64
+ return `personal-token-${credentialSlotHash(account)}.cred`;
65
+ }
66
+ /**
67
+ * Whether a POSIX path is safe to hold, or hand back, a token.
68
+ *
69
+ * Split out from the filesystem so the ownership case is testable: a file owned
70
+ * by another user is the one condition that cannot be staged in a temp directory
71
+ * without root.
72
+ */
73
+ export function checkPosixProtection(facts, expected, options = {}) {
74
+ if (facts.isSymbolicLink) {
75
+ return { ok: false, detail: 'it is a symbolic link, which could point anywhere' };
76
+ }
77
+ if (expected.kind === 'file' && !facts.isFile) {
78
+ return { ok: false, detail: 'it is not a regular file' };
79
+ }
80
+ if (expected.kind === 'directory' && !facts.isDirectory) {
81
+ return { ok: false, detail: 'it is not a directory' };
82
+ }
83
+ if (facts.uid !== expected.uid) {
84
+ return { ok: false, detail: 'it is owned by a different user' };
85
+ }
86
+ if (!options.ignoreSharedAccess && (facts.mode & SHARED_ACCESS_MASK) !== 0) {
87
+ return { ok: false, detail: 'it is readable or writable by other users' };
88
+ }
89
+ return { ok: true };
90
+ }
91
+ /** Every `[path ]principal:(perm)(perm)` entry `icacls` printed, in order. */
92
+ export function parseAclEntries(output) {
93
+ const entries = [];
94
+ for (const line of output.split(/\r?\n/)) {
95
+ // The permission groups are the anchor: they run to the end of the line, so
96
+ // the last colon in front of them is the one that separates the subject.
97
+ const match = /^(.*):((?:\([^()]*\))+)\s*$/.exec(line);
98
+ if (!match)
99
+ continue;
100
+ const permissions = [...(match[2] ?? '').matchAll(/\(([^()]*)\)/g)].map((group) => group[1] ?? '');
101
+ entries.push({ subject: (match[1] ?? '').trim(), permissions });
102
+ }
103
+ return entries;
104
+ }
105
+ /**
106
+ * Whether an entry grants the expected account and nobody else.
107
+ *
108
+ * `icacls` echoes the path it was given in front of the first ACE, and both the
109
+ * path and the account name may contain spaces — `C:\Users\John Smith\...` and
110
+ * `DOMAIN\John Smith` are both ordinary, and nothing in the line says where one
111
+ * ends and the other begins. Removing exactly the path this call passed is what
112
+ * makes the comparison precise; the suffix form is the fallback for a listing
113
+ * that echoed the path in some other shape, and its leading space is what keeps
114
+ * `DESK\dev` from matching an entry for `OTHERDESK\dev`.
115
+ */
116
+ function grantsOnly(subject, principal, path) {
117
+ const found = subject.toLowerCase();
118
+ const expected = principal.toLowerCase();
119
+ if (path !== null) {
120
+ const prefix = `${path.toLowerCase()} `;
121
+ // The echo removed exactly: what remains is the account and nothing else.
122
+ if (found.startsWith(prefix))
123
+ return found.slice(prefix.length) === expected;
124
+ // No prefix to remove — a listing that echoed the path in some other shape.
125
+ // Tolerated, but only here, and only with the separating space.
126
+ return found === expected || found.endsWith(` ${expected}`);
127
+ }
128
+ return found === expected;
129
+ }
130
+ /**
131
+ * Whether an `icacls` listing shows exactly "this user, explicitly, and nobody
132
+ * else". Anything unreadable, inherited, or shared fails.
133
+ *
134
+ * @param path - The path `icacls` was asked about, so its echo can be told apart
135
+ * from the account name that follows it.
136
+ */
137
+ export function verifyAclOutput(output, principal, path) {
138
+ const entries = parseAclEntries(output);
139
+ if (entries.length === 0) {
140
+ return { ok: false, detail: 'its access control list could not be read' };
141
+ }
142
+ for (const [index, entry] of entries.entries()) {
143
+ // `(I)` marks an inherited ACE. `(OI)` / `(CI)` are propagation flags on an
144
+ // explicit one, which is what a directory grant is supposed to look like.
145
+ if (entry.permissions.includes('I')) {
146
+ return { ok: false, detail: 'it still inherits permissions from its parent directory' };
147
+ }
148
+ // Only the first entry carries the path; every later line is an account on
149
+ // its own and is compared as one, so `NT AUTHORITY\SYSTEM` can never pass as
150
+ // a principal that happens to end the same way.
151
+ if (!grantsOnly(entry.subject, principal, index === 0 ? path : null)) {
152
+ return { ok: false, detail: 'its access control list grants another account' };
153
+ }
154
+ }
155
+ return { ok: true };
156
+ }
157
+ export function buildAclHardenCommand(path, principal, kind) {
158
+ // `/inheritance:r` converts inherited entries away and then removes them;
159
+ // `/grant:r` replaces any existing grant for the principal rather than adding
160
+ // to it, so re-running this is idempotent.
161
+ const grant = kind === 'directory' ? `${principal}:(OI)(CI)(F)` : `${principal}:(F)`;
162
+ return { command: 'icacls', args: [path, '/inheritance:r', '/grant:r', grant, '/Q', '/C'] };
163
+ }
164
+ export function buildAclInspectCommand(path) {
165
+ return { command: 'icacls', args: [path] };
166
+ }
167
+ /** `DOMAIN\user`, the form `icacls` prints. */
168
+ function resolveWindowsPrincipal(env) {
169
+ const user = env.USERNAME?.trim();
170
+ if (!user)
171
+ return null;
172
+ const domain = env.USERDOMAIN?.trim();
173
+ return domain ? `${domain}\\${user}` : user;
174
+ }
175
+ function fileSystemDetail(error) {
176
+ // `code` is stable across locales; `message` embeds the path, which is not a
177
+ // secret but is noise in a user-facing line.
178
+ const code = error?.code;
179
+ return code ? `the filesystem refused the operation (${code})` : 'the filesystem refused the operation';
180
+ }
181
+ export function createFileCredentialStore(options = {}) {
182
+ const platform = options.platform ?? process.platform;
183
+ const env = options.env ?? process.env;
184
+ const runner = options.runner;
185
+ const hardenDirectoryMode = options.hardenDirectory ?? true;
186
+ const directory = options.directory ?? join(options.homeDir ?? homedir(), ...CREDENTIAL_DIR);
187
+ const isWindows = platform === 'win32';
188
+ const windowsPrincipal = isWindows ? resolveWindowsPrincipal(env) : null;
189
+ const pathFor = (account) => join(directory, credentialFileName(account));
190
+ const runIcacls = (command) => {
191
+ if (!runner)
192
+ return { ok: false, stdout: '' };
193
+ const result = runner(command);
194
+ return { ok: result.status === 0, stdout: result.stdout };
195
+ };
196
+ /** Set, then prove, the protection on a path that already exists. */
197
+ const protectPath = (path, kind) => {
198
+ if (isWindows) {
199
+ if (!windowsPrincipal) {
200
+ return { ok: false, detail: 'Windows did not report which account is running this command' };
201
+ }
202
+ if (!runIcacls(buildAclHardenCommand(path, windowsPrincipal, kind)).ok) {
203
+ return { ok: false, detail: 'its access control list could not be set with icacls' };
204
+ }
205
+ const inspected = runIcacls(buildAclInspectCommand(path));
206
+ if (!inspected.ok) {
207
+ return { ok: false, detail: 'its access control list could not be read with icacls' };
208
+ }
209
+ return verifyAclOutput(inspected.stdout, windowsPrincipal, path);
210
+ }
211
+ let facts;
212
+ try {
213
+ facts = lstatSync(path);
214
+ }
215
+ catch (error) {
216
+ return { ok: false, detail: fileSystemDetail(error) };
217
+ }
218
+ // Never chmod through a link: that would apply the mode to whatever it points
219
+ // at. The check below rejects the link itself.
220
+ if (!facts.isSymbolicLink() && ((kind === 'directory' && hardenDirectoryMode) || kind === 'file')) {
221
+ try {
222
+ chmodSync(path, kind === 'directory' ? DIRECTORY_MODE : FILE_MODE);
223
+ }
224
+ catch {
225
+ // Not ours to tighten. The verification below is what decides.
226
+ }
227
+ try {
228
+ facts = lstatSync(path);
229
+ }
230
+ catch (error) {
231
+ return { ok: false, detail: fileSystemDetail(error) };
232
+ }
233
+ }
234
+ return checkPosixProtection({
235
+ isSymbolicLink: facts.isSymbolicLink(),
236
+ isDirectory: facts.isDirectory(),
237
+ isFile: facts.isFile(),
238
+ mode: facts.mode,
239
+ uid: facts.uid,
240
+ }, { kind, uid: process.getuid?.() ?? facts.uid });
241
+ };
242
+ /**
243
+ * Inspect an existing path without touching it.
244
+ *
245
+ * Used before a read and before a write: a path that is already wrong must be
246
+ * reported, not silently repaired, because a credential file this CLI did not
247
+ * write is evidence of tampering rather than of a stale umask.
248
+ */
249
+ const inspectExistingFile = (path) => {
250
+ if (isWindows) {
251
+ try {
252
+ lstatSync(path);
253
+ }
254
+ catch (error) {
255
+ if (error?.code === 'ENOENT')
256
+ return { kind: 'missing' };
257
+ return { ok: false, detail: fileSystemDetail(error) };
258
+ }
259
+ if (!windowsPrincipal) {
260
+ return { ok: false, detail: 'Windows did not report which account is running this command' };
261
+ }
262
+ const inspected = runIcacls(buildAclInspectCommand(path));
263
+ if (!inspected.ok)
264
+ return { ok: false, detail: 'its access control list could not be read with icacls' };
265
+ return verifyAclOutput(inspected.stdout, windowsPrincipal, path);
266
+ }
267
+ let facts;
268
+ try {
269
+ facts = lstatSync(path);
270
+ }
271
+ catch (error) {
272
+ if (error?.code === 'ENOENT')
273
+ return { kind: 'missing' };
274
+ return { ok: false, detail: fileSystemDetail(error) };
275
+ }
276
+ return checkPosixProtection({
277
+ isSymbolicLink: facts.isSymbolicLink(),
278
+ isDirectory: facts.isDirectory(),
279
+ isFile: facts.isFile(),
280
+ mode: facts.mode,
281
+ uid: facts.uid,
282
+ }, { kind: 'file', uid: process.getuid?.() ?? facts.uid });
283
+ };
284
+ let usable = null;
285
+ const ensureDirectory = () => {
286
+ if (usable !== null)
287
+ return usable;
288
+ try {
289
+ mkdirSync(directory, { recursive: true, mode: DIRECTORY_MODE });
290
+ }
291
+ catch (error) {
292
+ if (error?.code !== 'EEXIST') {
293
+ usable = { ok: false, detail: fileSystemDetail(error) };
294
+ return usable;
295
+ }
296
+ }
297
+ usable = protectPath(directory, 'directory');
298
+ return usable;
299
+ };
300
+ /**
301
+ * What the existing directory already rules out, without creating or changing
302
+ * anything.
303
+ *
304
+ * `auth status` is a read-only question and must not leave a credential
305
+ * directory on a machine that has never stored a login. An absent directory is
306
+ * therefore not a failure — `save()` creates it — and neither are the
307
+ * conditions `save()` repairs on the way (loose POSIX bits, an ACL that has
308
+ * not been applied yet). Only what no harden could fix is reported.
309
+ */
310
+ const inspectDirectory = () => {
311
+ // A real attempt already happened; its answer is the authoritative one.
312
+ if (usable !== null)
313
+ return usable;
314
+ if (isWindows && !windowsPrincipal) {
315
+ return { ok: false, detail: 'Windows did not report which account is running this command' };
316
+ }
317
+ let facts;
318
+ try {
319
+ facts = lstatSync(directory);
320
+ }
321
+ catch (error) {
322
+ if (error?.code === 'ENOENT')
323
+ return { ok: true };
324
+ return { ok: false, detail: fileSystemDetail(error) };
325
+ }
326
+ // The Windows ACL is applied by `save()`, and inspecting it here would say
327
+ // nothing about a directory that has never been hardened.
328
+ if (isWindows)
329
+ return { ok: true };
330
+ return checkPosixProtection({
331
+ isSymbolicLink: facts.isSymbolicLink(),
332
+ isDirectory: facts.isDirectory(),
333
+ isFile: facts.isFile(),
334
+ mode: facts.mode,
335
+ uid: facts.uid,
336
+ }, { kind: 'directory', uid: process.getuid?.() ?? facts.uid }, { ignoreSharedAccess: true });
337
+ };
338
+ const removeQuietly = (path) => {
339
+ try {
340
+ unlinkSync(path);
341
+ }
342
+ catch {
343
+ // Already gone, or never created. Either way there is nothing to clean up.
344
+ }
345
+ };
346
+ return {
347
+ backend: FILE_CREDENTIAL_BACKEND,
348
+ directory,
349
+ check(options) {
350
+ return options?.create === false ? inspectDirectory() : ensureDirectory();
351
+ },
352
+ isUsable() {
353
+ return ensureDirectory().ok;
354
+ },
355
+ has(account) {
356
+ try {
357
+ lstatSync(pathFor(account));
358
+ return true;
359
+ }
360
+ catch {
361
+ return false;
362
+ }
363
+ },
364
+ read(account) {
365
+ const path = pathFor(account);
366
+ const inspected = inspectExistingFile(path);
367
+ if ('kind' in inspected)
368
+ return { kind: 'missing' };
369
+ if (!inspected.ok) {
370
+ return { kind: 'error', detail: `the stored login could not be trusted: ${inspected.detail}` };
371
+ }
372
+ let body;
373
+ try {
374
+ body = readFileSync(path, 'utf-8');
375
+ }
376
+ catch (error) {
377
+ return { kind: 'error', detail: fileSystemDetail(error) };
378
+ }
379
+ try {
380
+ const parsed = JSON.parse(body);
381
+ // The parse error and the parsed content are both withheld on purpose:
382
+ // whatever is in this file is either the token or something pretending to
383
+ // be it, and neither belongs in a message.
384
+ if (parsed.version !== FILE_FORMAT_VERSION) {
385
+ return { kind: 'error', detail: 'the stored login is in a format this version does not understand' };
386
+ }
387
+ if (typeof parsed.secret !== 'string' || parsed.secret.length === 0) {
388
+ return { kind: 'error', detail: 'the stored login file is incomplete' };
389
+ }
390
+ return { kind: 'found', secret: parsed.secret };
391
+ }
392
+ catch {
393
+ return { kind: 'error', detail: 'the stored login file is unreadable' };
394
+ }
395
+ },
396
+ save(account, secret) {
397
+ const directoryReady = ensureDirectory();
398
+ if (!directoryReady.ok) {
399
+ return { ok: false, detail: `a protected credential directory could not be created: ${directoryReady.detail}` };
400
+ }
401
+ const path = pathFor(account);
402
+ const existing = inspectExistingFile(path);
403
+ if (!('kind' in existing) && !existing.ok) {
404
+ // Replacing it would destroy evidence of whatever put it there, and
405
+ // renaming over a link or a directory has its own surprises.
406
+ return { ok: false, detail: `an existing credential file could not be trusted: ${existing.detail}` };
407
+ }
408
+ // Same directory as the target, so `rename` stays within one filesystem and
409
+ // is therefore atomic. `wx` guarantees the staging path is ours alone.
410
+ const staging = join(directory, `.${process.pid}-${randomUUID()}.tmp`);
411
+ const body = `${JSON.stringify({ version: FILE_FORMAT_VERSION, secret })}\n`;
412
+ try {
413
+ writeFileSync(staging, body, { encoding: 'utf-8', flag: 'wx', mode: FILE_MODE });
414
+ // `mode` on open is masked by umask, so the protection is restated — and
415
+ // on Windows this is where the ACL is applied, before any token is
416
+ // reachable under the final name.
417
+ const staged = protectPath(staging, 'file');
418
+ if (!staged.ok) {
419
+ removeQuietly(staging);
420
+ return { ok: false, detail: `the credential file could not be protected: ${staged.detail}` };
421
+ }
422
+ renameSync(staging, path);
423
+ }
424
+ catch (error) {
425
+ removeQuietly(staging);
426
+ return { ok: false, detail: fileSystemDetail(error) };
427
+ }
428
+ // A rename preserves POSIX modes and NTFS ACLs, but the whole point of this
429
+ // backend is that the protection is proven rather than assumed.
430
+ const published = protectPath(path, 'file');
431
+ if (!published.ok) {
432
+ removeQuietly(path);
433
+ return { ok: false, detail: `the credential file could not be protected: ${published.detail}` };
434
+ }
435
+ return { ok: true };
436
+ },
437
+ remove(account) {
438
+ // Deliberately does not create the directory: `remove` runs on every
439
+ // successful OS-backend write, and a logout on a healthy machine must not
440
+ // leave a credential directory behind.
441
+ removeQuietly(pathFor(account));
442
+ },
443
+ };
444
+ }
445
+ //# sourceMappingURL=fileCredentialStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileCredentialStore.js","sourceRoot":"","sources":["../../src/auth/fileCredentialStore.ts"],"names":[],"mappings":"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"}
@@ -65,9 +65,15 @@ export interface PersonalTokenState {
65
65
  connected: boolean;
66
66
  /** false → the refresh token is session-memory only and disappears with this process. */
67
67
  persisted: boolean;
68
- /** Which OS store is in play, regardless of whether it currently works. */
68
+ /** Which store holds this slot, regardless of whether it currently works. */
69
69
  storeBackend: CredentialBackendId;
70
70
  storeReason: CredentialStoreReason;
71
+ /**
72
+ * Why that backend, when the store had something to say — a rejected write, or
73
+ * the reason the OS store was skipped in favour of the file fallback. Absent
74
+ * on the ordinary path, where the backend name is the whole story.
75
+ */
76
+ storeDetail?: string;
71
77
  identity: PersonalTokenIdentity | null;
72
78
  expiresAt: number | null;
73
79
  /** The server rejected the refresh token; only a fresh login recovers. */
@@ -115,6 +121,40 @@ type ParsedTokenResponse = {
115
121
  * a truncated body). Only the first justifies destroying local credentials.
116
122
  */
117
123
  export declare function parseTokenResponse(response: Response): Promise<ParsedTokenResponse>;
124
+ /** `flow: 'setup'` result the approval screen chose; `init` writes these into the project config. */
125
+ export interface DeviceSetupResult {
126
+ teamId: string;
127
+ projectId: string;
128
+ agentConfigId: string;
129
+ agentName: string;
130
+ seedPlanId: string | null;
131
+ }
132
+ /**
133
+ * One poll's outcome, in the server's own vocabulary (RFC 8628 error codes).
134
+ *
135
+ * `transient` is deliberately separate from `denied`/`expired`: only the latter
136
+ * two are decisions, and treating a dropped connection as a decision would end a
137
+ * login the user is still completing.
138
+ */
139
+ export type DevicePollOutcome = {
140
+ kind: 'approved';
141
+ session: PersonalTokenSession;
142
+ setup: DeviceSetupResult | null;
143
+ } | {
144
+ kind: 'pending';
145
+ } | {
146
+ kind: 'slowDown';
147
+ intervalSeconds: number | null;
148
+ } | {
149
+ kind: 'denied';
150
+ } | {
151
+ kind: 'expired';
152
+ } | {
153
+ kind: 'invalid';
154
+ } | {
155
+ kind: 'transient';
156
+ detail: string;
157
+ };
118
158
  export declare class PersonalTokenClient {
119
159
  private readonly deps;
120
160
  private accessToken;
@@ -126,6 +166,16 @@ export declare class PersonalTokenClient {
126
166
  constructor(deps: PersonalTokenClientDeps);
127
167
  state(): PersonalTokenState;
128
168
  hasCredential(): boolean;
169
+ /**
170
+ * One poll of the RFC 8628 device token endpoint.
171
+ *
172
+ * Lives here rather than in the polling loop because the *storage* invariants
173
+ * are the same as a PKCE exchange: a credential the next process cannot find
174
+ * is not a login, so an unstorable token pair is revoked instead of orphaned.
175
+ * The loop only decides *when* to call this; the outcome vocabulary below is
176
+ * the server's error contract verbatim.
177
+ */
178
+ pollDeviceToken(deviceCode: string): Promise<DevicePollOutcome>;
129
179
  /**
130
180
  * Trade a PKCE authorization code for the first token pair.
131
181
  *
@@ -1 +1 @@
1
- {"version":3,"file":"personalTokenClient.d.ts","sourceRoot":"","sources":["../../src/auth/personalTokenClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"personalTokenClient.d.ts","sourceRoot":"","sources":["../../src/auth/personalTokenClient.ts"],"names":[],"mappings":"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"}