@corenel/tools-node 0.7.1 → 0.8.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/dist/auth.d.ts CHANGED
@@ -39,7 +39,7 @@ export interface StoredCredential {
39
39
  accessToken: string;
40
40
  /** Never written or read any more (nothing refreshed with it). Kept in the
41
41
  * type only so a copy left by an older sign-in is stripped on the next save
42
- * (@corenel/config STORED_CREDENTIAL_KEYS). */
42
+ * (SIGN_IN_KEYS). */
43
43
  refreshToken?: string;
44
44
  /** Epoch ms. Absent means the issuer did not say. */
45
45
  expiresAt?: number;
@@ -71,7 +71,76 @@ export interface StoredCredential {
71
71
  */
72
72
  apiBase?: string;
73
73
  }
74
+ /**
75
+ * Write one 0600 file so that no reader ever sees a half-written one.
76
+ *
77
+ * A credential is read by OTHER processes while it is being written -- a
78
+ * running daemon re-reads it, the gateway client reads it per request -- and
79
+ * `writeFile` truncates before it fills. A reader landing mid-write gets an
80
+ * empty token file (read as signed out) or a JSON parse failure on auth.json
81
+ * (read as no credential at all). A rename over the top is atomic on POSIX and
82
+ * on NTFS, so a reader sees the old file or the new one.
83
+ *
84
+ * The temp file is created 0600 and chmod'ed before the rename, never after:
85
+ * the point is that the file is never readable at a weaker mode, not that it
86
+ * ends up at the right one.
87
+ */
88
+ export declare function writeFilePrivateAtomic(path: string, contents: string): Promise<void>;
74
89
  export declare function writeAuthToken(token: string, stateDir?: string): Promise<void>;
90
+ /**
91
+ * The top-level keys of auth.json that belong to the SIGN-IN record. Every
92
+ * other key is someone else's section and survives a sign-in and a sign-out.
93
+ * `refreshToken` and `expiresAt` are listed although nothing writes them any
94
+ * more, so a copy left by an older sign-in goes with the record it belonged to.
95
+ * The one list of them: nothing else in the workspace keeps its own copy.
96
+ */
97
+ export declare const SIGN_IN_KEYS: readonly (keyof StoredCredential)[];
98
+ /** Where a sign-in or sign-out reports something the user should know but
99
+ * that is not a failure. Defaults to stderr, the login commands' diagnostic
100
+ * channel. */
101
+ export type CredentialNotice = (line: string) => void;
102
+ /** What a strict read of auth.json found. */
103
+ export type AuthDocRead = {
104
+ kind: 'missing';
105
+ } | {
106
+ kind: 'doc';
107
+ doc: Record<string, unknown>;
108
+ } | {
109
+ kind: 'corrupt';
110
+ bytes: Buffer;
111
+ };
112
+ /** Who is about to replace auth.json, for the message when it cannot be read. */
113
+ export type AuthDocWriter = 'sign-in' | 'save';
114
+ /** Run `fn` with this process's lock on the auth.json at `path` held: each
115
+ * caller waits for the one before it, whatever that one's outcome. NOT
116
+ * re-entrant: `fn` must not take the same lock again. */
117
+ export declare function withAuthDocLock<T>(path: string, fn: () => Promise<T>): Promise<T>;
118
+ /**
119
+ * Read auth.json for a READ-MODIFY-WRITE: the one read every writer of this
120
+ * shared file goes through (sign-in here, the MCP and agent sections in
121
+ * @corenel/mcp's config.ts).
122
+ *
123
+ * - Missing: `missing`.
124
+ * - Present but unreadable (EBUSY, EPERM, EACCES, EMFILE, EISDIR...): THROWS,
125
+ * with the fs code on the error. A locked file is not an empty one, and a
126
+ * writer that took it as empty would write back a document missing every
127
+ * other section. Nothing has been written when this throws.
128
+ * - Not JSON, or not a JSON object: `corrupt`, with the raw bytes, for
129
+ * backupCorruptAuthDoc.
130
+ *
131
+ * Read-ONLY callers do not use this: they stay tolerant (absent on any failure)
132
+ * because a lookup that answers "no credential" loses nothing.
133
+ */
134
+ export declare function readAuthDocForWrite(path: string, writer: AuthDocWriter): Promise<AuthDocRead>;
135
+ /**
136
+ * Keep a corrupt auth.json before a writer replaces it: copied byte for byte,
137
+ * 0600, to `auth.json.bad-<epoch ms>` beside it (never over an existing file),
138
+ * and named on `notify`. A corrupt file must not block a write, and every
139
+ * reader already treats one as empty, but what was in it is kept for a person
140
+ * to recover by hand. Throws if the copy cannot be made, so the caller stops
141
+ * rather than replace the only copy.
142
+ */
143
+ export declare function backupCorruptAuthDoc(path: string, bytes: Buffer, notify?: CredentialNotice): Promise<string>;
75
144
  /**
76
145
  * Record a completed sign-in in BOTH stores, including WHERE it was minted.
77
146
  *
@@ -81,9 +150,15 @@ export declare function writeAuthToken(token: string, stateDir?: string): Promis
81
150
  * cause. The base goes in auth.json because the token file is one line by
82
151
  * contract and every existing reader of it splits on nothing.
83
152
  *
84
- * The credential record is REPLACED, not merged: a new sign-in may be a
153
+ * The SIGN-IN FIELDS are replaced, not merged: a new sign-in may be a
85
154
  * different account at a different host, and carrying the previous one's
86
- * account or base onto it would report something nobody established.
155
+ * account or base onto it would report something nobody established. Every
156
+ * OTHER top-level key of auth.json is kept: the file is shared with the
157
+ * daemon's MCP credentials (`mcp`), its OAuth client registrations
158
+ * (`mcpClients`) and team agents' MCP credentials (`agents`), all written by
159
+ * @corenel/mcp's config.ts, and a sign-in has no business erasing them. An
160
+ * auth.json that exists but cannot be read stops the sign-in with nothing
161
+ * written; a corrupt one is backed up first (readForeignAuthSections).
87
162
  *
88
163
  * TWO FILES, AND A READER BETWEEN THEM. `resolveNodeCredential` borrows the
89
164
  * account from auth.json only when auth.json describes the SAME token the
@@ -112,6 +187,7 @@ export declare function writeLoginCredential(token: string, opts?: {
112
187
  apiBase?: string;
113
188
  stateDir?: string;
114
189
  account?: string;
190
+ notify?: CredentialNotice;
115
191
  }): Promise<void>;
116
192
  /**
117
193
  * A store read that says WHICH kind of nothing it found.
@@ -159,8 +235,19 @@ export declare function readCredentialFileRead(stateDir?: string): Promise<Crede
159
235
  * pointing the other way, and worse: the operator believes they signed out
160
236
  * while the gateway keeps sending a credential. Every sign-out path must land
161
237
  * here rather than removing a single file.
238
+ *
239
+ * Only the SIGN-IN is removed from auth.json. The file also holds the daemon's
240
+ * MCP credentials and team agents' MCP credentials (see writeLoginCredential),
241
+ * which are not the user's sign-in and outlive it; the file is deleted only
242
+ * when nothing else is left in it.
243
+ *
244
+ * THROWS when a sign-in is still on disk afterwards (the token file or
245
+ * auth.json could not be cleared), so no caller can report a sign-out that did
246
+ * not happen. Both stores are attempted before it throws.
162
247
  */
163
- export declare function clearAllCredentials(stateDir?: string): Promise<void>;
248
+ export declare function clearAllCredentials(stateDir?: string, opts?: {
249
+ notify?: CredentialNotice;
250
+ }): Promise<void>;
164
251
  /** Which store answered. */
165
252
  export type CredentialSource = 'env' | 'token-file' | 'credential-file' | 'none';
166
253
  export interface ResolvedCredential {
@@ -221,6 +308,10 @@ export interface ResolveApiBaseOptions {
221
308
  explicit?: string;
222
309
  env?: NodeJS.ProcessEnv;
223
310
  stateDir?: string;
311
+ /** Skip the stored credential's recorded base. For a SIGN-IN, which replaces
312
+ * that credential: following it, one sign-in against a local API sent every
313
+ * later login (the installed production CLI included) to localhost. */
314
+ ignoreCredential?: boolean;
224
315
  }
225
316
  /**
226
317
  * Which API to talk to.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAW5D;2DAC2D;AAC3D,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE3D;AAED;iFACiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE3D;AAED;0EAC0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE9D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,mEAAmE;AACnE,eAAO,MAAM,SAAS,kBAAkB,CAAC;AAEzC;+EAC+E;AAC/E,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C;gDACgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB;;oDAEgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA8BD,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACnE,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;CACrB;AAOD,wBAAsB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE7E;AAED,kEAAkE;AAClE,wBAAsB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAS1F;AAED;sDACsD;AACtD,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;AAED;;iDAEiD;AACjD,wBAAsB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAE5F;AAED;qDACqD;AACrD,wBAAsB,sBAAsB,CAC1C,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CA4B3C;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED,4BAA4B;AAC5B,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,YAAY,GAAG,iBAAiB,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;yEACqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;yBAEqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,GAAE,wBAA6B,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAwC7B;AAkBD;kDACkD;AAClD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,SAAS,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC;qEACiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,cAAc,CAAC,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,eAAe,CAAC,CAW/F;AAED;;8DAE8D;AAC9D,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAStE;AAED;;kCAEkC;AAClC,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAEnE"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"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"}
package/dist/auth.js CHANGED
@@ -33,7 +33,7 @@
33
33
  * the gateway client and @corenel/cli have always read it, and real installs
34
34
  * are signed in through it right now. Making the newer store win would change
35
35
  * which token a working machine sends. The two only ever diverge on a machine
36
- * that signed in both ways, because saveCredential writes BOTH and
36
+ * that signed in both ways, because writeLoginCredential writes BOTH and
37
37
  * clearAllCredentials removes BOTH — so login and logout leave the two readers
38
38
  * agreeing rather than leaning on the precedence at all. When the credential
39
39
  * file describes the SAME token, its account/expiry metadata is carried over,
@@ -46,7 +46,7 @@
46
46
  */
47
47
  import { promises as fs } from 'node:fs';
48
48
  import { homedir } from 'node:os';
49
- import { join } from 'node:path';
49
+ import { join, resolve } from 'node:path';
50
50
  import { stateDirName, DEFAULT_API_BASE } from '@corenel/protocol';
51
51
  /* Every path helper takes an explicit base, defaulting to the real home.
52
52
  *
@@ -115,7 +115,7 @@ export const API_BASE_ENV = 'CORENEL_API_BASE';
115
115
  * the point is that the file is never readable at a weaker mode, not that it
116
116
  * ends up at the right one.
117
117
  */
118
- async function writeFilePrivateAtomic(path, contents) {
118
+ export async function writeFilePrivateAtomic(path, contents) {
119
119
  const tmp = `${path}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
120
120
  await fs.writeFile(tmp, contents, { mode: 0o600 });
121
121
  // Best-effort: non-POSIX filesystems reject it, and a failure must not lose
@@ -153,6 +153,150 @@ export async function writeAuthToken(token, stateDir) {
153
153
  }
154
154
  catch { /* non-POSIX */ }
155
155
  }
156
+ /**
157
+ * The top-level keys of auth.json that belong to the SIGN-IN record. Every
158
+ * other key is someone else's section and survives a sign-in and a sign-out.
159
+ * `refreshToken` and `expiresAt` are listed although nothing writes them any
160
+ * more, so a copy left by an older sign-in goes with the record it belonged to.
161
+ * The one list of them: nothing else in the workspace keeps its own copy.
162
+ */
163
+ export const SIGN_IN_KEYS = ['accessToken', 'refreshToken', 'expiresAt', 'account', 'apiBase'];
164
+ const toStderr = (line) => { console.error(line); };
165
+ /** auth.json's text as a plain JSON object, or null when it is not one. */
166
+ function authObjectOf(raw) {
167
+ let parsed;
168
+ try {
169
+ parsed = JSON.parse(raw);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
175
+ return null;
176
+ return parsed;
177
+ }
178
+ /** `doc` minus the sign-in keys. */
179
+ function withoutSignIn(doc) {
180
+ const rest = { ...doc };
181
+ for (const k of SIGN_IN_KEYS)
182
+ delete rest[k];
183
+ return rest;
184
+ }
185
+ /** An fs error's code, for a message a person reads. */
186
+ function codeOf(err) {
187
+ const code = typeof err === 'object' && err !== null ? err.code : undefined;
188
+ return typeof code === 'string' && code ? code : 'unknown error';
189
+ }
190
+ /* ONE IN-PROCESS QUEUE PER auth.json.
191
+ *
192
+ * Every writer of auth.json reads the whole document, changes its own part and
193
+ * renames a new file over it. Two of those interleaved in one process read the
194
+ * same document, and the second rename drops the first writer's change: two
195
+ * agents' token refreshes lose one, and a clear racing another agent's write
196
+ * brings the cleared credential back. So every read-modify-write (the MCP
197
+ * writers in @corenel/mcp's config.ts, a sign-in, a sign-out) runs under this
198
+ * lock, keyed by the file's path. In-process only: another process writing
199
+ * the same file is not serialized (a cross-process lock is out of scope).
200
+ *
201
+ * The map lives on globalThis under a registered symbol, so a second copy of
202
+ * this module (a bundle that inlined it twice) still shares one queue. */
203
+ const AUTH_DOC_LOCKS = Symbol.for('corenel.tools-node.authDocLocks');
204
+ function authDocLocks() {
205
+ const host = globalThis;
206
+ let m = host[AUTH_DOC_LOCKS];
207
+ if (!m) {
208
+ m = new Map();
209
+ host[AUTH_DOC_LOCKS] = m;
210
+ }
211
+ return m;
212
+ }
213
+ /** Run `fn` with this process's lock on the auth.json at `path` held: each
214
+ * caller waits for the one before it, whatever that one's outcome. NOT
215
+ * re-entrant: `fn` must not take the same lock again. */
216
+ export async function withAuthDocLock(path, fn) {
217
+ const abs = resolve(path);
218
+ const key = process.platform === 'win32' ? abs.toLowerCase() : abs;
219
+ const locks = authDocLocks();
220
+ const prev = locks.get(key) ?? Promise.resolve();
221
+ let release = () => { };
222
+ const mine = new Promise((r) => { release = r; });
223
+ const tail = prev.then(() => mine);
224
+ locks.set(key, tail);
225
+ await prev;
226
+ try {
227
+ return await fn();
228
+ }
229
+ finally {
230
+ release();
231
+ if (locks.get(key) === tail)
232
+ locks.delete(key);
233
+ }
234
+ }
235
+ /**
236
+ * Read auth.json for a READ-MODIFY-WRITE: the one read every writer of this
237
+ * shared file goes through (sign-in here, the MCP and agent sections in
238
+ * @corenel/mcp's config.ts).
239
+ *
240
+ * - Missing: `missing`.
241
+ * - Present but unreadable (EBUSY, EPERM, EACCES, EMFILE, EISDIR...): THROWS,
242
+ * with the fs code on the error. A locked file is not an empty one, and a
243
+ * writer that took it as empty would write back a document missing every
244
+ * other section. Nothing has been written when this throws.
245
+ * - Not JSON, or not a JSON object: `corrupt`, with the raw bytes, for
246
+ * backupCorruptAuthDoc.
247
+ *
248
+ * Read-ONLY callers do not use this: they stay tolerant (absent on any failure)
249
+ * because a lookup that answers "no credential" loses nothing.
250
+ */
251
+ export async function readAuthDocForWrite(path, writer) {
252
+ let bytes;
253
+ try {
254
+ bytes = await fs.readFile(path);
255
+ }
256
+ catch (err) {
257
+ if (isMissing(err))
258
+ return { kind: 'missing' };
259
+ const code = codeOf(err);
260
+ const what = writer === 'sign-in'
261
+ ? 'sign-in aborted so the MCP and agent credentials in it are not lost'
262
+ : 'not saved so the credentials in it are not lost';
263
+ throw Object.assign(new Error(`Could not read ${path} (${code}); ${what}. Close whatever holds it and retry.`), { code });
264
+ }
265
+ const doc = authObjectOf(bytes.toString('utf8'));
266
+ return doc ? { kind: 'doc', doc } : { kind: 'corrupt', bytes };
267
+ }
268
+ /**
269
+ * Keep a corrupt auth.json before a writer replaces it: copied byte for byte,
270
+ * 0600, to `auth.json.bad-<epoch ms>` beside it (never over an existing file),
271
+ * and named on `notify`. A corrupt file must not block a write, and every
272
+ * reader already treats one as empty, but what was in it is kept for a person
273
+ * to recover by hand. Throws if the copy cannot be made, so the caller stops
274
+ * rather than replace the only copy.
275
+ */
276
+ export async function backupCorruptAuthDoc(path, bytes, notify = toStderr) {
277
+ const backup = `${path}.bad-${Date.now()}`;
278
+ await fs.writeFile(backup, bytes, { mode: 0o600, flag: 'wx' });
279
+ try {
280
+ await fs.chmod(backup, 0o600);
281
+ }
282
+ catch { /* non-POSIX */ }
283
+ notify(`${path} was not valid JSON; a copy was kept at ${backup} and it was replaced.`);
284
+ return backup;
285
+ }
286
+ /**
287
+ * Every top-level key of auth.json that is NOT the sign-in record's, for a
288
+ * sign-in to carry over. Missing reads as `{}`, an unreadable file stops the
289
+ * sign-in before anything is staged, and a corrupt one is backed up and then
290
+ * reads as `{}` (readAuthDocForWrite, backupCorruptAuthDoc).
291
+ */
292
+ async function readForeignAuthSections(path, notify) {
293
+ const read = await readAuthDocForWrite(path, 'sign-in');
294
+ if (read.kind === 'doc')
295
+ return withoutSignIn(read.doc);
296
+ if (read.kind === 'corrupt')
297
+ await backupCorruptAuthDoc(path, read.bytes, notify);
298
+ return {};
299
+ }
156
300
  /**
157
301
  * Record a completed sign-in in BOTH stores, including WHERE it was minted.
158
302
  *
@@ -162,9 +306,15 @@ export async function writeAuthToken(token, stateDir) {
162
306
  * cause. The base goes in auth.json because the token file is one line by
163
307
  * contract and every existing reader of it splits on nothing.
164
308
  *
165
- * The credential record is REPLACED, not merged: a new sign-in may be a
309
+ * The SIGN-IN FIELDS are replaced, not merged: a new sign-in may be a
166
310
  * different account at a different host, and carrying the previous one's
167
- * account or base onto it would report something nobody established.
311
+ * account or base onto it would report something nobody established. Every
312
+ * OTHER top-level key of auth.json is kept: the file is shared with the
313
+ * daemon's MCP credentials (`mcp`), its OAuth client registrations
314
+ * (`mcpClients`) and team agents' MCP credentials (`agents`), all written by
315
+ * @corenel/mcp's config.ts, and a sign-in has no business erasing them. An
316
+ * auth.json that exists but cannot be read stops the sign-in with nothing
317
+ * written; a corrupt one is backed up first (readForeignAuthSections).
168
318
  *
169
319
  * TWO FILES, AND A READER BETWEEN THEM. `resolveNodeCredential` borrows the
170
320
  * account from auth.json only when auth.json describes the SAME token the
@@ -199,11 +349,23 @@ export async function writeLoginCredential(token, opts = {}) {
199
349
  const credPath = credentialFilePath(opts.stateDir);
200
350
  const tokPath = tokenFilePath(opts.stateDir);
201
351
  await fs.mkdir(dir, { recursive: true, mode: 0o700 });
352
+ // The read, the staging and the publish, under the auth.json lock: an MCP
353
+ // writer in this process must not read between them (withAuthDocLock).
354
+ await withAuthDocLock(credPath, () => publishSignIn(credPath, tokPath, cred, opts.notify ?? toStderr));
355
+ try {
356
+ await fs.chmod(dir, 0o700);
357
+ }
358
+ catch { /* non-POSIX */ }
359
+ }
360
+ async function publishSignIn(credPath, tokPath, cred, notify) {
361
+ // Read before anything is staged, so the publish below stays two adjacent
362
+ // renames. Foreign sections first, the new sign-in on top.
363
+ const record = { ...(await readForeignAuthSections(credPath, notify)), ...cred };
202
364
  // Staged before either is published, so the publish is two renames and
203
365
  // nothing else.
204
366
  const credTmp = `${credPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
205
367
  const tokTmp = `${tokPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
206
- await fs.writeFile(credTmp, `${JSON.stringify(cred, null, 2)}\n`, { mode: 0o600 });
368
+ await fs.writeFile(credTmp, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
207
369
  await fs.writeFile(tokTmp, `${cred.accessToken}\n`, { mode: 0o600 });
208
370
  try {
209
371
  await fs.chmod(credTmp, 0o600);
@@ -228,10 +390,6 @@ export async function writeLoginCredential(token, opts = {}) {
228
390
  catch { /* nothing to clean */ }
229
391
  throw e;
230
392
  }
231
- try {
232
- await fs.chmod(dir, 0o700);
233
- }
234
- catch { /* non-POSIX */ }
235
393
  }
236
394
  /** ENOENT -- the store simply is not there -- as opposed to any other failure. */
237
395
  function isMissing(err) {
@@ -308,13 +466,75 @@ export async function readCredentialFileRead(stateDir) {
308
466
  * pointing the other way, and worse: the operator believes they signed out
309
467
  * while the gateway keeps sending a credential. Every sign-out path must land
310
468
  * here rather than removing a single file.
469
+ *
470
+ * Only the SIGN-IN is removed from auth.json. The file also holds the daemon's
471
+ * MCP credentials and team agents' MCP credentials (see writeLoginCredential),
472
+ * which are not the user's sign-in and outlive it; the file is deleted only
473
+ * when nothing else is left in it.
474
+ *
475
+ * THROWS when a sign-in is still on disk afterwards (the token file or
476
+ * auth.json could not be cleared), so no caller can report a sign-out that did
477
+ * not happen. Both stores are attempted before it throws.
311
478
  */
312
- export async function clearAllCredentials(stateDir) {
313
- await clearAuthToken(stateDir);
479
+ export async function clearAllCredentials(stateDir, opts = {}) {
480
+ const failures = [];
481
+ const tokPath = tokenFilePath(stateDir);
314
482
  try {
315
- await fs.rm(credentialFilePath(stateDir), { force: true });
483
+ await fs.rm(tokPath, { force: true });
316
484
  }
317
- catch { /* already gone */ }
485
+ catch (err) {
486
+ failures.push(`${tokPath} (${codeOf(err)})`);
487
+ }
488
+ const credPath = credentialFilePath(stateDir);
489
+ try {
490
+ await withAuthDocLock(credPath, () => clearSignInRecord(credPath, opts.notify ?? toStderr));
491
+ }
492
+ catch (err) {
493
+ failures.push(`${credPath} (${codeOf(err)})`);
494
+ }
495
+ if (failures.length) {
496
+ throw new Error(`Could not remove the sign-in from ${failures.join(' and ')}; it is still on disk.`);
497
+ }
498
+ }
499
+ /**
500
+ * Remove the sign-in fields from auth.json, keeping every other section.
501
+ *
502
+ * Signing out wins whenever it conflicts with keeping a section, because a
503
+ * sign-out that leaves a working token behind is the worse failure:
504
+ * - a file that exists but cannot be read is removed outright, since what
505
+ * else is in it cannot be told, and `notify` says the sections went too;
506
+ * - a corrupt file holds nothing any reader can use, so it is removed. It is
507
+ * NOT backed up: it may hold a fragment of the token being signed out;
508
+ * - if rewriting the file without the sign-in fails, the file is removed,
509
+ * and `notify` says so.
510
+ * Throws the removal's error when the file could not be removed either.
511
+ */
512
+ async function clearSignInRecord(path, notify) {
513
+ let raw;
514
+ try {
515
+ raw = await fs.readFile(path, 'utf8');
516
+ }
517
+ catch (err) {
518
+ if (isMissing(err))
519
+ return;
520
+ await fs.rm(path, { force: true });
521
+ notify('auth.json could not be read and was removed; MCP and agent credentials in it are gone');
522
+ return;
523
+ }
524
+ const doc = authObjectOf(raw);
525
+ const rest = doc ? withoutSignIn(doc) : {};
526
+ if (Object.keys(rest).length > 0) {
527
+ try {
528
+ await writeFilePrivateAtomic(path, `${JSON.stringify(rest, null, 2)}\n`);
529
+ return;
530
+ }
531
+ catch {
532
+ await fs.rm(path, { force: true });
533
+ notify('auth.json could not be rewritten and was removed; MCP and agent credentials in it are gone');
534
+ return;
535
+ }
536
+ }
537
+ await fs.rm(path, { force: true });
318
538
  }
319
539
  /**
320
540
  * Resolve the credential this machine authenticates with, per the precedence
@@ -404,6 +624,8 @@ export async function resolveApiBase(opts = {}) {
404
624
  const fromEnv = (opts.env ?? process.env)[API_BASE_ENV]?.trim();
405
625
  if (fromEnv)
406
626
  return { base: fromEnv, source: 'env' };
627
+ if (opts.ignoreCredential)
628
+ return { base: DEFAULT_API_BASE, source: 'default' };
407
629
  const cred = await resolveNodeCredential({
408
630
  env: {},
409
631
  ...(opts.stateDir ? { stateDir: opts.stateDir } : {}),
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export interface DeviceLoginOpts {
2
+ /** Gateway/auth base (e.g. https://api.corenel.ai). */
3
+ base: string;
4
+ /**
5
+ * Persist the completed sign-in (tools-node writeLoginCredential).
6
+ *
7
+ * `account` is WHO this token belongs to, when the server would say. It is
8
+ * not decoration: a daemon files a same-machine browser claiming this same
9
+ * account under one synced directory instead of one per browser origin
10
+ * (@corenel/sidecar's hostIdentity.ts), and without it stored there is
11
+ * nothing for that rule to match against, so it never fires.
12
+ *
13
+ * Absent when the API did not answer -- an older deployment, an offline
14
+ * moment, a revoked token. The sign-in still succeeded; only the
15
+ * one-directory-per-person behaviour is unavailable, which is exactly the
16
+ * behaviour every install has today.
17
+ */
18
+ store: (token: string, account?: string) => Promise<void>;
19
+ /** Tell the user where/what to enter. Defaults to stdout. */
20
+ open?: (verificationUri: string, userCode: string) => void;
21
+ /** Poll interval override in ms (tests); else the server's `interval` seconds. */
22
+ pollMs?: number;
23
+ /** Account-lookup deadline override in ms (tests); else ACCOUNT_LOOKUP_MS. */
24
+ accountLookupMs?: number;
25
+ /** Injectable fetch (tests); defaults to the node global. */
26
+ fetchImpl?: typeof fetch;
27
+ signal?: AbortSignal;
28
+ }
29
+ /**
30
+ * WHO the freshly-minted token belongs to, or undefined.
31
+ *
32
+ * WHY AN API CALL RATHER THAN THE GRANT. The device-grant token response is the
33
+ * other place this could come from, and it would be one fewer request -- but it
34
+ * is a field the deployed `/oauth/token` does not send, so taking it from there
35
+ * means changing the API before anything works at all. `GET <base>/auth/me`
36
+ * already exists, is already mounted at every base this CLI logs in to, and its
37
+ * `clerkAuth` already accepts the `cnl_cli_` token that was just minted. So
38
+ * this needs no backend surface, new or changed, and it answers today.
39
+ *
40
+ * WHY THE EMAIL AND NOT THE ID. The value has to be one a BROWSER could also
41
+ * present, because the daemon rule compares the two: a browser claims the Clerk
42
+ * user id and the primary email address (src/auth/clerk.tsx). `/auth/me`
43
+ * returns the email and an internal record id -- the id is this API's own,
44
+ * which no browser has ever seen and which therefore could never match. The
45
+ * email can, and the comparison lowercases and trims both sides, so the two
46
+ * need not agree on spelling.
47
+ *
48
+ * BEST-EFFORT BY CONSTRUCTION, AND BOUNDED. Every failure -- a 404 from an
49
+ * older deployment, a network error, the deadline, the caller's own abort, a
50
+ * body that is not what we expect -- answers undefined, because a login that
51
+ * worked must not fail, or hang, over a detail that only enables an
52
+ * optimisation. Swallowing the abort is deliberate: the token is stored by the
53
+ * caller immediately after this returns, so an abort here still lands the
54
+ * credential rather than throwing it away. And nothing here is logged: the
55
+ * value is an email address.
56
+ */
57
+ export declare function whoIsThis(base: string, token: string, f: typeof fetch, outer?: AbortSignal, deadlineMs?: number): Promise<string | undefined>;
58
+ export declare function deviceLogin(opts: DeviceLoginOpts): Promise<string>;
59
+ //# sourceMappingURL=deviceLogin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceLogin.d.ts","sourceRoot":"","sources":["../deviceLogin.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;;OAaG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,6DAA6D;IAC7D,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,OAAO,KAAK,EACf,KAAK,CAAC,EAAE,WAAW,EACnB,UAAU,GAAE,MAA0B,GACrC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB7B;AAMD,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyFxE"}
@@ -0,0 +1,204 @@
1
+ /* OAuth 2.0 Device Authorization Grant (RFC 8628): THE sign-in for both
2
+ * `corenel login` and `corenel-sidecar login`. It lived in the CLI while the
3
+ * sidecar carried a separate PKCE flow that nothing could configure (it asked
4
+ * for CORENEL_OAUTH_ISSUER/CLIENT_ID, which no build set) -- yet the daemon told
5
+ * users to run it. One flow, here, beside the credential store it writes to.
6
+ *
7
+ * Requests a
8
+ * device code, shows the user the verification URL + code, polls until they
9
+ * authorize, then hands the access token to `store` (writeAuthToken -> ~/.corenel/
10
+ * token). Transport (fetch) + endpoints are injectable for a headless test. */
11
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
12
+ /** Floor for a SERVER-supplied poll interval. RFC 8628's own default is 5s; this
13
+ * only has to stop a zero or a negative from becoming a hot loop. */
14
+ const MIN_POLL_MS = 1000;
15
+ /** Used when the server omits `expires_in`. RFC 8628 does not mandate a value;
16
+ * 15 minutes is long enough for a real person to find the browser tab and short
17
+ * enough that an unattended `corenel login` eventually gives up. */
18
+ const DEFAULT_LIFETIME_S = 900;
19
+ /**
20
+ * How long the account lookup may take before the sign-in gives up on it.
21
+ *
22
+ * IT IS BOUNDED BECAUSE OF WHAT IS ALREADY SPENT BY THEN. The device code has
23
+ * been redeemed and the token exists server-side; a single-use code cannot be
24
+ * exchanged twice. So every second spent here is a second in which Ctrl-C
25
+ * destroys a credential that already exists and cannot be re-minted -- the user
26
+ * has to run `corenel login` again and approve a fresh code. Undici's default
27
+ * is around five MINUTES, which turns a hung or black-holed API into exactly
28
+ * that. Five seconds against a route that does one indexed lookup is generous,
29
+ * and the cost of being wrong is the account going unrecorded, which is only
30
+ * today's behaviour.
31
+ */
32
+ const ACCOUNT_LOOKUP_MS = 5000;
33
+ /**
34
+ * A signal that fires on the deadline OR on the caller's own abort, on Node 18.
35
+ *
36
+ * `AbortSignal.any` is the one-liner for this and lands in Node 20.3; this
37
+ * package declares `>=18`. Composing it by hand costs six lines and removes the
38
+ * chance of a runtime that silently lacks it. `dispose` is not optional
39
+ * bookkeeping: an uncleared timer keeps a CLI process alive past the work it
40
+ * was timing.
41
+ */
42
+ function deadlineSignal(ms, outer) {
43
+ const ac = new AbortController();
44
+ const onOuter = () => ac.abort();
45
+ const timer = setTimeout(() => ac.abort(), ms);
46
+ if (outer) {
47
+ if (outer.aborted)
48
+ ac.abort();
49
+ else
50
+ outer.addEventListener('abort', onOuter, { once: true });
51
+ }
52
+ return {
53
+ signal: ac.signal,
54
+ dispose: () => { clearTimeout(timer); outer?.removeEventListener('abort', onOuter); },
55
+ };
56
+ }
57
+ /**
58
+ * WHO the freshly-minted token belongs to, or undefined.
59
+ *
60
+ * WHY AN API CALL RATHER THAN THE GRANT. The device-grant token response is the
61
+ * other place this could come from, and it would be one fewer request -- but it
62
+ * is a field the deployed `/oauth/token` does not send, so taking it from there
63
+ * means changing the API before anything works at all. `GET <base>/auth/me`
64
+ * already exists, is already mounted at every base this CLI logs in to, and its
65
+ * `clerkAuth` already accepts the `cnl_cli_` token that was just minted. So
66
+ * this needs no backend surface, new or changed, and it answers today.
67
+ *
68
+ * WHY THE EMAIL AND NOT THE ID. The value has to be one a BROWSER could also
69
+ * present, because the daemon rule compares the two: a browser claims the Clerk
70
+ * user id and the primary email address (src/auth/clerk.tsx). `/auth/me`
71
+ * returns the email and an internal record id -- the id is this API's own,
72
+ * which no browser has ever seen and which therefore could never match. The
73
+ * email can, and the comparison lowercases and trims both sides, so the two
74
+ * need not agree on spelling.
75
+ *
76
+ * BEST-EFFORT BY CONSTRUCTION, AND BOUNDED. Every failure -- a 404 from an
77
+ * older deployment, a network error, the deadline, the caller's own abort, a
78
+ * body that is not what we expect -- answers undefined, because a login that
79
+ * worked must not fail, or hang, over a detail that only enables an
80
+ * optimisation. Swallowing the abort is deliberate: the token is stored by the
81
+ * caller immediately after this returns, so an abort here still lands the
82
+ * credential rather than throwing it away. And nothing here is logged: the
83
+ * value is an email address.
84
+ */
85
+ export async function whoIsThis(base, token, f, outer, deadlineMs = ACCOUNT_LOOKUP_MS) {
86
+ const { signal, dispose } = deadlineSignal(deadlineMs, outer);
87
+ try {
88
+ const res = await f(`${base}/auth/me`, {
89
+ headers: { Authorization: `Bearer ${token}` },
90
+ signal,
91
+ });
92
+ if (!res.ok)
93
+ return undefined;
94
+ const body = JSON.parse(await res.text());
95
+ const email = body?.user?.email;
96
+ if (typeof email !== 'string')
97
+ return undefined;
98
+ const trimmed = email.trim();
99
+ return trimmed ? trimmed : undefined;
100
+ }
101
+ catch {
102
+ return undefined;
103
+ }
104
+ finally {
105
+ dispose();
106
+ }
107
+ }
108
+ function defaultOpen(uri, code) {
109
+ process.stdout.write(`\n To authorize, open: ${uri}\n and enter the code: ${code}\n\n Waiting for authorization…\n`);
110
+ }
111
+ export async function deviceLogin(opts) {
112
+ const f = opts.fetchImpl ?? fetch;
113
+ const base = opts.base.replace(/\/$/, '');
114
+ /**
115
+ * POST and parse — but say something useful when the answer is not JSON.
116
+ *
117
+ * `res.json()` on an HTML error page throws `Unexpected token '<'`, which sends
118
+ * the reader looking at their JSON and not at the URL. And it is the LIKELIEST
119
+ * failure here by some distance: point `--base` at the web app, or at the API
120
+ * without its `/api` prefix, and Express answers 404 with an HTML page. A
121
+ * stale CLI whose baked-in default predates a path change fails exactly this
122
+ * way, on a machine where nothing is obviously wrong.
123
+ *
124
+ * So a non-JSON body is reported as what it is — the status, the URL, and the
125
+ * one thing worth checking.
126
+ */
127
+ const post = async (path, body) => {
128
+ const url = `${base}${path}`;
129
+ const res = await f(url, {
130
+ method: 'POST',
131
+ headers: { 'Content-Type': 'application/json' },
132
+ body: JSON.stringify(body),
133
+ signal: opts.signal,
134
+ });
135
+ const text = await res.text();
136
+ try {
137
+ return JSON.parse(text);
138
+ }
139
+ catch {
140
+ const looksLikeHtml = /^\s*</.test(text);
141
+ throw new Error(`${url} answered ${res.status} with ${looksLikeHtml ? 'an HTML page' : 'a non-JSON body'}, not JSON.`
142
+ + (res.status === 404
143
+ ? `
144
+ That usually means --base is wrong. The device endpoints live under /api — try --base ${base.replace(/\/api$/, '')}/api`
145
+ : ''));
146
+ }
147
+ };
148
+ /* `pair` asks to let this CLI connect to the user's sidecars. The API grants
149
+ * it only if the person approving ticks that box; without it the CLI can
150
+ * still do everything else, and pairing says to log in again. */
151
+ const dc = await post('/oauth/device/code', { client_id: 'corenel-cli', scope: 'agent pair' });
152
+ if (!dc.device_code)
153
+ throw new Error('device authorization failed');
154
+ (opts.open ?? defaultOpen)(dc.verification_uri, dc.user_code);
155
+ /* The server names the poll interval, but it does NOT get to name zero.
156
+ * `(dc.interval ?? 5)` looks like it defaults to 5, and does for a MISSING
157
+ * field -- but `0 ?? 5` is `0`, so a server answering `interval: 0` produced
158
+ * `sleep(0)` and turned this into a tight unbounded-rate loop against its own
159
+ * token endpoint. Floor the server's value; an explicit `opts.pollMs` (the
160
+ * test/`verify` injection) deliberately bypasses the floor, which is why the
161
+ * headless proof still runs in milliseconds. */
162
+ let interval = opts.pollMs ?? Math.max(MIN_POLL_MS, (dc.interval ?? 5) * 1000);
163
+ /* RFC 8628 gives the device code a lifetime, and without honoring it `login`
164
+ * waits forever when the user simply never authorizes -- no error, no exit,
165
+ * a hung terminal. Bound the loop by the server's `expires_in` (its own
166
+ * stated lifetime), falling back to a sane default when it omits one. */
167
+ const lifetimeMs = (typeof dc.expires_in === 'number' && dc.expires_in > 0 ? dc.expires_in : DEFAULT_LIFETIME_S) * 1000;
168
+ const deadline = Date.now() + lifetimeMs;
169
+ for (;;) {
170
+ if (opts.signal?.aborted)
171
+ throw new Error('login cancelled');
172
+ if (Date.now() >= deadline) {
173
+ throw new Error(`the code ${dc.user_code} expired before it was authorized -- run \`corenel login\` again`);
174
+ }
175
+ await sleep(interval);
176
+ const tok = await post('/oauth/token', {
177
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
178
+ device_code: dc.device_code,
179
+ client_id: 'corenel-cli',
180
+ });
181
+ if (tok.access_token) {
182
+ /* Approved. Find out who this is BEFORE storing, so the credential is
183
+ * written once and complete -- a second write to enrich it is a window
184
+ * in which a daemon reads a credential that names nobody. The grant's
185
+ * own answer wins when it gives one; otherwise ask, BOUNDED: the device
186
+ * code is spent by now and the token cannot be re-minted, so this must
187
+ * never be able to keep a user waiting long enough that they abandon a
188
+ * credential that already exists. See ACCOUNT_LOOKUP_MS. */
189
+ const claimed = typeof tok.account === 'string' ? tok.account.trim() : '';
190
+ const account = claimed
191
+ || await whoIsThis(base, tok.access_token, f, opts.signal, opts.accountLookupMs);
192
+ await opts.store(tok.access_token, account || undefined);
193
+ return tok.access_token;
194
+ }
195
+ if (tok.error === 'authorization_pending')
196
+ continue;
197
+ if (tok.error === 'slow_down') {
198
+ interval += 5000;
199
+ continue;
200
+ }
201
+ throw new Error(tok.error_description || tok.error || 'login failed');
202
+ }
203
+ }
204
+ //# sourceMappingURL=deviceLogin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceLogin.js","sourceRoot":"","sources":["../deviceLogin.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export { NodeFileService } from './fileService';
2
- export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, type StoredCredential, type CredentialSource, type ResolvedCredential, type ResolveCredentialOptions, type CredentialRead, type ApiBaseSource, type ResolvedApiBase, type ResolveApiBaseOptions, } from './auth';
2
+ export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, writeFilePrivateAtomic, SIGN_IN_KEYS, type CredentialNotice, readAuthDocForWrite, backupCorruptAuthDoc, withAuthDocLock, type AuthDocRead, type AuthDocWriter, type StoredCredential, type CredentialSource, type ResolvedCredential, type ResolveCredentialOptions, type CredentialRead, type ApiBaseSource, type ResolvedApiBase, type ResolveApiBaseOptions, } from './auth';
3
3
  export { nodePromptHost } from './promptHost';
4
4
  export { migrateHomeLayout, type MigrationReport } from './migrateHome';
5
5
  export { openBrowser } from './openBrowser';
6
6
  export { approvalsHomeDir, ensurePrivateDir, fileTextStore, insideAnyRoot, workspaceApprovalsId } from './approvalsStore';
7
+ export { deviceLogin, whoIsThis, type DeviceLoginOpts } from './deviceLogin';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAClD,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EACpG,KAAK,cAAc,EACnB,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,GACrE,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAClD,sBAAsB,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAC3D,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAChG,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EACpG,KAAK,cAAc,EACnB,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,GACrE,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1H,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  /* @corenel/tools-node — node capabilities (the tools-web twin). */
2
2
  export { NodeFileService } from './fileService';
3
- export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, } from './auth';
3
+ export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, writeFilePrivateAtomic, SIGN_IN_KEYS, readAuthDocForWrite, backupCorruptAuthDoc, withAuthDocLock, } from './auth';
4
4
  export { nodePromptHost } from './promptHost';
5
5
  export { migrateHomeLayout } from './migrateHome';
6
6
  export { openBrowser } from './openBrowser';
7
7
  export { approvalsHomeDir, ensurePrivateDir, fileTextStore, insideAnyRoot, workspaceApprovalsId } from './approvalsStore';
8
+ export { deviceLogin, whoIsThis } from './deviceLogin';
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,GAInD,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAwB,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAClD,sBAAsB,EAAE,YAAY,EACpC,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,GAI3D,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAwB,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1H,OAAO,EAAE,WAAW,EAAE,SAAS,EAAwB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,36 @@
1
+ export interface CliIdentityOptions {
2
+ /** The API base, e.g. https://api.corenel.ai/api. */
3
+ base: () => Promise<string>;
4
+ /** The CLI credential, or null when not signed in. */
5
+ token: () => Promise<string | null | undefined>;
6
+ fetchImpl?: typeof fetch;
7
+ timeoutMs?: number;
8
+ /** Who the refusal sentences name: 'this CLI' (default) or 'this daemon'. */
9
+ who?: string;
10
+ /** The command that signs in again: `corenel login` (default) or
11
+ * `corenel-sidecar login` for a daemon. */
12
+ signIn?: string;
13
+ /** Fixed words for a failure to reach the API (DNS, refused, timeout).
14
+ * Given: `problem()` says exactly this and the error text goes only to
15
+ * `detail()`, for a caller whose `problem()` words may leave the machine
16
+ * (a daemon pairing from Settings). Absent: the CLI's terminal is told the
17
+ * reason. */
18
+ unreachable?: string;
19
+ }
20
+ export interface CliIdentity {
21
+ /** Hand to `SidecarHost.onIdentityChallenge`. Never throws. */
22
+ answer: (c: {
23
+ nonce: string;
24
+ sidecarId: string;
25
+ jkt: string;
26
+ orgId?: string;
27
+ }) => Promise<string | null>;
28
+ /** Why the last challenge got no assertion, in words for the terminal;
29
+ * null when it got one (or none was asked). */
30
+ problem: () => string | null;
31
+ /** The full reason for a log: `problem()` plus any error text it left
32
+ * out. Null when `problem()` is. Never for the wire. */
33
+ detail: () => string | null;
34
+ }
35
+ export declare function cliIdentity(o: CliIdentityOptions): CliIdentity;
36
+ //# sourceMappingURL=pairingAssertion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairingAssertion.d.ts","sourceRoot":"","sources":["../pairingAssertion.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;+CAC2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;iBAIa;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzG;mDAC+C;IAC/C,OAAO,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC7B;4DACwD;IACxD,MAAM,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAkE9D"}
@@ -0,0 +1,93 @@
1
+ /* The CLI's answer to a sidecar's identity challenge (spec
2
+ * 2026-09-29-device-enrollment-design, Phase 2).
3
+ *
4
+ * A sidecar REQUIRES a verified identity: in solo mode, its own signed-in
5
+ * account; in team mode, a member of its org. The browser proves it with a
6
+ * Clerk session; the CLI has none, so it asks corenel-api for the pairing
7
+ * assertion with its own CLI credential (`corenel login`, or CORENEL_TOKEN):
8
+ * `POST <base>/v1/pairing-assertions` with `{ aud, nonce, jkt, org? }`. The API
9
+ * resolves the `cnl_cli_` token to the same Clerk user and signs the same
10
+ * assertion a browser would get (azp `corenel-cli`).
11
+ *
12
+ * The daemon's refusal is deliberately uniform (`invalid credentials`), so the
13
+ * CLI remembers WHY it could not produce an assertion (`problem()`) and says
14
+ * that instead: not signed in, or not a member of the org. The token goes to
15
+ * corenel-api and nowhere else; it never crosses the daemon socket.
16
+ *
17
+ * Shared with the sidecar daemon's peer mode (spec 2026-10-01 Part D), which pairs with a team daemon the same way; it lives here because @corenel/sidecar does not depend on @corenel/cli.
18
+ */
19
+ export function cliIdentity(o) {
20
+ const who = o.who ?? 'this CLI';
21
+ const signIn = o.signIn ?? 'corenel login';
22
+ const fetchImpl = o.fetchImpl ?? fetch;
23
+ const timeoutMs = o.timeoutMs ?? 8000;
24
+ let last = null;
25
+ let lastDetail = null;
26
+ return {
27
+ problem: () => last,
28
+ detail: () => lastDetail ?? last,
29
+ answer: async ({ nonce, sidecarId, jkt, orgId }) => {
30
+ last = null;
31
+ lastDetail = null;
32
+ let token;
33
+ try {
34
+ token = await o.token();
35
+ }
36
+ catch {
37
+ token = null;
38
+ }
39
+ if (!token) {
40
+ last = `${who} is not signed in, and the sidecar only admits a verified account. Run \`${signIn}\` (or set CORENEL_TOKEN), then try again.`;
41
+ return null;
42
+ }
43
+ try {
44
+ const base = (await o.base()).replace(/\/+$/, '');
45
+ const res = await fetchImpl(`${base}/v1/pairing-assertions`, {
46
+ method: 'POST',
47
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
48
+ body: JSON.stringify({ aud: sidecarId, nonce, jkt, ...(orgId ? { org_id: orgId } : {}) }),
49
+ signal: AbortSignal.timeout(timeoutMs),
50
+ });
51
+ if (res.status === 403) {
52
+ let code;
53
+ try {
54
+ code = (await res.json())?.code;
55
+ }
56
+ catch {
57
+ code = undefined;
58
+ }
59
+ if (code === 'CLI_SCOPE') {
60
+ last = `${who}'s sign-in is not allowed to connect to sidecars. Run \`${signIn}\` again and allow sidecar access when you approve it.`;
61
+ return null;
62
+ }
63
+ if (orgId) {
64
+ last = `your account is not a member of the organization this sidecar admits (${orgId}).`;
65
+ return null;
66
+ }
67
+ }
68
+ if (res.status === 401) {
69
+ last = `the API refused ${who}'s sign-in. Run \`${signIn}\` again, then try again.`;
70
+ return null;
71
+ }
72
+ if (!res.ok) {
73
+ last = `could not get a pairing assertion from ${base} (HTTP ${res.status}).`;
74
+ return null;
75
+ }
76
+ const body = (await res.json());
77
+ const assertion = body?.assertion;
78
+ if (typeof assertion !== 'string' || !assertion) {
79
+ last = `${base} answered without a pairing assertion.`;
80
+ return null;
81
+ }
82
+ return assertion;
83
+ }
84
+ catch (e) {
85
+ const reason = `could not reach the API for a pairing assertion (${e instanceof Error ? e.message : String(e)}).`;
86
+ last = o.unreachable ?? reason;
87
+ lastDetail = reason;
88
+ return null;
89
+ }
90
+ },
91
+ };
92
+ }
93
+ //# sourceMappingURL=pairingAssertion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairingAssertion.js","sourceRoot":"","sources":["../pairingAssertion.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corenel/tools-node",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "description": "Corenel node capabilities — the tools-web twin. A disk-backed FileService (the harness file tools + node PromptHost workspace) over node:fs, confined to a root. Shell/secrets/~/.corenel to follow.",
@@ -16,8 +16,8 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@prompd/core": "0.5.0-beta.10",
19
- "@corenel/protocol": "0.13.0",
20
- "@corenel/harness": "0.14.0"
19
+ "@corenel/protocol": "0.14.0",
20
+ "@corenel/harness": "0.15.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^24.13.1",