@modelprofile.com/authswitch 6.4.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,343 @@
1
+ import * as plugins from './plugins.js';
2
+ import { commitinfo } from './00_commitinfo_data.js';
3
+ const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
4
+ const isAlive = (child) => child.exitCode === null && child.signalCode === null;
5
+ const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
6
+ /** Same-user process inspection: a unique private --listen socket is the pre-PID crash identity. */
7
+ export const findManagedCodexProcess = async (socketPath) => {
8
+ if (process.platform === 'win32')
9
+ throw new Error('Managed Codex Unix socket process inspection is unavailable on Windows.');
10
+ const output = await new Promise((resolve, reject) => {
11
+ plugins.childProcess.execFile('ps', ['-ww', '-u', String(process.getuid?.()), '-o', 'pid=,lstart=,args='], { timeout: 5_000, maxBuffer: 8 * 1024 * 1024, env: { ...process.env, LC_ALL: 'C' } }, (error, stdout) => error ? reject(new Error('Managed Codex process inspection failed.')) : resolve(stdout));
12
+ });
13
+ const marker = `app-server --listen unix://${socketPath}`;
14
+ const matches = [];
15
+ for (const line of output.split('\n')) {
16
+ const parts = line.trim().split(/\s+/);
17
+ if (parts.length < 8)
18
+ continue;
19
+ const pid = Number(parts[0]);
20
+ const date = Date.parse(parts.slice(1, 6).join(' '));
21
+ const args = parts.slice(6).join(' ');
22
+ if (Number.isSafeInteger(pid) && pid > 0 && Number.isFinite(date) && args.includes(marker)) {
23
+ matches.push({ pid, startedAt: new Date(date).toISOString() });
24
+ }
25
+ }
26
+ if (matches.length > 1)
27
+ throw new Error('Multiple managed Codex processes claim one private socket.');
28
+ return matches[0] ?? null;
29
+ };
30
+ /** Daemon-owned Codex app-server. Only access tokens, never refresh grants, enter Codex. */
31
+ export class AuthSwitchManagedCodex {
32
+ options;
33
+ child;
34
+ childExited;
35
+ client;
36
+ runDirectory;
37
+ homeDirectory;
38
+ socketPath;
39
+ workspaceId;
40
+ grantedGeneration;
41
+ startPromise;
42
+ closePromise;
43
+ closed = false;
44
+ ready = false;
45
+ constructor(options) {
46
+ this.options = options;
47
+ if (!plugins.path.isAbsolute(options.runtimeDirectory) || !plugins.path.isAbsolute(options.workspaceDirectory)
48
+ || !plugins.path.isAbsolute(options.codexHomeDirectory)) {
49
+ throw new Error('Managed Codex requires absolute runtime, home and workspace directories.');
50
+ }
51
+ }
52
+ get isReady() { return this.ready && this.client?.state === 'connected' && !this.closed; }
53
+ environment() {
54
+ const picked = {};
55
+ for (const key of ['PATH', 'HOME', 'USER', 'LOGNAME', 'LANG', 'LC_ALL', 'TERM', 'TMPDIR', 'XDG_RUNTIME_DIR']) {
56
+ if (process.env[key] !== undefined)
57
+ picked[key] = process.env[key];
58
+ }
59
+ picked.CODEX_HOME = this.homeDirectory;
60
+ return picked;
61
+ }
62
+ async requireVersion() {
63
+ const executable = this.options.executable ?? 'codex';
64
+ const output = await new Promise((resolve, reject) => {
65
+ plugins.childProcess.execFile(executable, ['--version'], { timeout: 5_000, maxBuffer: 4096,
66
+ windowsHide: true, env: this.environment() }, (error, stdout) => {
67
+ if (error)
68
+ reject(new Error('Managed Codex version probe failed.'));
69
+ else
70
+ resolve(stdout.trim());
71
+ });
72
+ });
73
+ if (output !== 'codex-cli 0.155.1')
74
+ throw new Error('Managed Codex requires verified codex-cli 0.155.1.');
75
+ }
76
+ start() {
77
+ if (this.closed || this.startPromise)
78
+ throw new Error('Managed Codex can start only once.');
79
+ this.startPromise = this.performStart();
80
+ return this.startPromise;
81
+ }
82
+ async performStart() {
83
+ try {
84
+ const root = this.options.runtimeDirectory;
85
+ await plugins.fs.promises.mkdir(root, { recursive: true, mode: 0o700 });
86
+ const rootStat = await plugins.fs.promises.lstat(root);
87
+ if (!rootStat.isDirectory() || rootStat.isSymbolicLink() || rootStat.uid !== process.getuid?.()) {
88
+ throw new Error('Managed Codex runtime directory is not private.');
89
+ }
90
+ await plugins.fs.promises.chmod(root, 0o700);
91
+ this.runDirectory = await plugins.fs.promises.mkdtemp(plugins.path.join(root, 'codex-'));
92
+ await plugins.fs.promises.chmod(this.runDirectory, 0o700);
93
+ this.homeDirectory = this.options.codexHomeDirectory;
94
+ this.socketPath = plugins.path.join(this.runDirectory, 'app.sock');
95
+ if (Buffer.byteLength(this.socketPath, 'utf8') > 100)
96
+ throw new Error('Managed Codex socket path is too long.');
97
+ const homeStat = await plugins.fs.promises.lstat(this.homeDirectory);
98
+ if (!homeStat.isDirectory() || homeStat.isSymbolicLink() || homeStat.uid !== process.getuid?.()
99
+ || (homeStat.mode & 0o077) !== 0 || await plugins.fs.promises.realpath(this.homeDirectory) !== this.homeDirectory) {
100
+ throw new Error('Managed Codex home is not a private owned directory.');
101
+ }
102
+ try {
103
+ await plugins.fs.promises.lstat(plugins.path.join(this.homeDirectory, 'auth.json'));
104
+ throw new Error('Managed Codex home contains a native credential file.');
105
+ }
106
+ catch (error) {
107
+ if (!isRecord(error) || error.code !== 'ENOENT')
108
+ throw error;
109
+ }
110
+ await this.requireVersion();
111
+ if (this.closed)
112
+ throw new Error('Managed Codex startup was cancelled.');
113
+ const initial = await this.options.broker.resolveAccess(this.options.bindingId, this.options.capability, 60_000);
114
+ if (this.closed)
115
+ throw new Error('Managed Codex startup was cancelled.');
116
+ this.workspaceId = initial.accountId;
117
+ this.grantedGeneration = initial.grantGeneration;
118
+ await this.options.onPreparedRun(this.socketPath);
119
+ if (this.closed)
120
+ throw new Error('Managed Codex startup was cancelled.');
121
+ const child = plugins.childProcess.spawn(this.options.executable ?? 'codex', [
122
+ 'app-server', '--listen', `unix://${this.socketPath}`, '--strict-config',
123
+ '-c', 'cli_auth_credentials_store="ephemeral"',
124
+ ], { cwd: this.options.workspaceDirectory, env: this.environment(), shell: false,
125
+ detached: process.platform !== 'win32', stdio: 'ignore', windowsHide: true });
126
+ this.child = child;
127
+ this.childExited = new Promise(resolve => {
128
+ child.once('error', () => resolve());
129
+ child.once('exit', () => resolve());
130
+ });
131
+ if (!child.pid)
132
+ throw new Error('Managed Codex app-server process has no PID.');
133
+ let observed = null;
134
+ for (let attempt = 0; attempt < 20 && !observed; attempt++) {
135
+ observed = await findManagedCodexProcess(this.socketPath);
136
+ if (!observed)
137
+ await wait(25);
138
+ }
139
+ if (!observed || observed.pid !== child.pid)
140
+ throw new Error('Managed Codex app-server process identity could not be verified.');
141
+ await this.options.onChildSpawned(observed.pid, observed.startedAt);
142
+ const deadline = Date.now() + 10_000;
143
+ while (true) {
144
+ if (this.closed)
145
+ throw new Error('Managed Codex startup was cancelled.');
146
+ if (!isAlive(child))
147
+ throw new Error('Managed Codex app-server exited before accepting connections.');
148
+ try {
149
+ if ((await plugins.fs.promises.lstat(this.socketPath)).isSocket())
150
+ break;
151
+ }
152
+ catch (error) {
153
+ if (!isRecord(error) || error.code !== 'ENOENT')
154
+ throw error;
155
+ }
156
+ if (Date.now() >= deadline)
157
+ throw new Error('Managed Codex app-server socket startup timed out.');
158
+ await wait(25);
159
+ }
160
+ const client = new plugins.crossharness.CodexAppServerClient({
161
+ transport: { type: 'unix', socketPath: this.socketPath },
162
+ clientInfo: { name: 'authswitch', title: 'Authswitch', version: commitinfo.version },
163
+ experimentalApi: true, handshakeTimeoutMs: 5_000, initializeTimeoutMs: 5_000,
164
+ onNotification: notification => this.options.onNotification?.(notification),
165
+ onServerRequest: request => { void this.handleServerRequest(request); },
166
+ onClose: () => {
167
+ const wasReady = this.ready;
168
+ this.ready = false;
169
+ if (wasReady && !this.closed)
170
+ this.options.onUnavailable?.();
171
+ },
172
+ });
173
+ this.client = client;
174
+ await client.connect();
175
+ if (client.serverVersion !== '0.155.1')
176
+ throw new Error('Managed Codex app-server version changed.');
177
+ const login = await client.request('account/login/start', {
178
+ type: 'chatgptAuthTokens', accessToken: initial.accessToken, chatgptAccountId: initial.accountId,
179
+ }, 5_000);
180
+ if (!isRecord(login) || login.type !== 'chatgptAuthTokens') {
181
+ throw new Error('Managed Codex external-token login was not acknowledged.');
182
+ }
183
+ if (this.closed)
184
+ throw new Error('Managed Codex startup was cancelled.');
185
+ this.ready = true;
186
+ }
187
+ catch (error) {
188
+ try {
189
+ await this.close();
190
+ }
191
+ catch (cleanupError) {
192
+ throw new AggregateError([error, cleanupError], 'Managed Codex startup and cleanup failed.');
193
+ }
194
+ throw error;
195
+ }
196
+ }
197
+ async handleServerRequest(request) {
198
+ const client = this.client;
199
+ if (!client || this.closed || !this.ready)
200
+ return;
201
+ if (request.method !== 'account/chatgptAuthTokens/refresh') {
202
+ if (!this.options.onServerRequest) {
203
+ client.rejectRequest(request.id, -32601, 'Managed Codex request requires an owner handler.');
204
+ return;
205
+ }
206
+ try {
207
+ this.options.onServerRequest(request, {
208
+ respond: result => client.respond(request.id, result),
209
+ reject: (code, message) => client.rejectRequest(request.id, code, message),
210
+ });
211
+ }
212
+ catch {
213
+ client.rejectRequest(request.id, -32603, 'Managed Codex owner request failed.');
214
+ }
215
+ return;
216
+ }
217
+ const prior = this.grantedGeneration;
218
+ const workspaceId = this.workspaceId;
219
+ const params = request.params;
220
+ if (params.reason !== 'unauthorized' || !workspaceId || prior === undefined
221
+ || (params.previousAccountId !== undefined && params.previousAccountId !== null
222
+ && params.previousAccountId !== workspaceId)) {
223
+ client.rejectRequest(request.id, -32602, 'Managed Codex account identity is invalid.');
224
+ return;
225
+ }
226
+ try {
227
+ const refreshed = await this.options.broker.resolveAccess(this.options.bindingId, this.options.capability, 60_000, prior);
228
+ if (this.closed || request.signal.aborted)
229
+ return;
230
+ if (refreshed.accountId !== workspaceId || refreshed.grantGeneration <= prior) {
231
+ client.rejectRequest(request.id, -32603, 'Managed Codex account refresh did not advance.');
232
+ return;
233
+ }
234
+ this.grantedGeneration = refreshed.grantGeneration;
235
+ client.respond(request.id, { accessToken: refreshed.accessToken,
236
+ chatgptAccountId: refreshed.accountId, chatgptPlanType: null });
237
+ }
238
+ catch {
239
+ if (!request.signal.aborted)
240
+ client.rejectRequest(request.id, -32603, 'Managed Codex account needs reauthentication.');
241
+ }
242
+ }
243
+ /** The interactive CLI attaches to the owned app-server; the daemon remains its auth control peer. */
244
+ interactiveCommand() {
245
+ if (!this.isReady || !this.socketPath)
246
+ throw new Error('Managed Codex is unavailable.');
247
+ return { executable: this.options.executable ?? 'codex', args: ['--remote', `unix://${this.socketPath}`],
248
+ cwd: this.options.workspaceDirectory, env: this.environment() };
249
+ }
250
+ /** Native app-server thread/turn API for noninteractive consumers; notifications go to onNotification. */
251
+ async startThread(options) {
252
+ if (!this.isReady || !this.client || !options || !['never', 'on-request'].includes(options.approvalPolicy)
253
+ || (options.model !== undefined && (typeof options.model !== 'string' || options.model.length > 128))) {
254
+ throw new Error('Managed Codex thread request is unavailable or invalid.');
255
+ }
256
+ const started = await this.client.request('thread/start', {
257
+ cwd: this.options.workspaceDirectory, approvalPolicy: options.approvalPolicy,
258
+ ...(options.model ? { model: options.model } : {}),
259
+ }, 30_000, options.signal);
260
+ if (!isRecord(started) || !isRecord(started.thread) || typeof started.thread.id !== 'string') {
261
+ throw new Error('Managed Codex returned an invalid thread.');
262
+ }
263
+ return started.thread.id;
264
+ }
265
+ async resumeThread(threadId, options) {
266
+ if (!this.isReady || !this.client || typeof threadId !== 'string' || !threadId || threadId.length > 256
267
+ || !options || !['never', 'on-request'].includes(options.approvalPolicy)
268
+ || (options.model !== undefined && (typeof options.model !== 'string' || options.model.length > 128))) {
269
+ throw new Error('Managed Codex resume request is unavailable or invalid.');
270
+ }
271
+ const resumed = await this.client.request('thread/resume', { threadId,
272
+ cwd: this.options.workspaceDirectory, approvalPolicy: options.approvalPolicy,
273
+ ...(options.model ? { model: options.model } : {}),
274
+ }, 30_000, options.signal);
275
+ if (!isRecord(resumed) || !isRecord(resumed.thread) || resumed.thread.id !== threadId) {
276
+ throw new Error('Managed Codex could not resume the requested thread from its assigned home.');
277
+ }
278
+ }
279
+ async startTextTurn(text, options) {
280
+ if (!this.isReady || !this.client || typeof text !== 'string' || !text.trim() || text.length > 1_000_000
281
+ || !options || !['never', 'on-request'].includes(options.approvalPolicy)
282
+ || (options.model !== undefined && (typeof options.model !== 'string' || options.model.length > 128))
283
+ || (options.threadId !== undefined && (typeof options.threadId !== 'string' || options.threadId.length > 256))) {
284
+ throw new Error('Managed Codex turn request is unavailable or invalid.');
285
+ }
286
+ let threadId = options.threadId;
287
+ if (threadId) {
288
+ await this.resumeThread(threadId, options);
289
+ }
290
+ else {
291
+ threadId = await this.startThread(options);
292
+ }
293
+ const turn = await this.client.request('turn/start', { threadId,
294
+ input: [{ type: 'text', text, text_elements: [] }],
295
+ approvalPolicy: options.approvalPolicy,
296
+ ...(options.model ? { model: options.model } : {}),
297
+ }, 30_000, options.signal);
298
+ if (!isRecord(turn) || !isRecord(turn.turn) || typeof turn.turn.id !== 'string') {
299
+ throw new Error('Managed Codex returned an invalid turn.');
300
+ }
301
+ return { threadId, turnId: turn.turn.id };
302
+ }
303
+ close() {
304
+ if (this.closePromise)
305
+ return this.closePromise;
306
+ const wasReady = this.ready;
307
+ this.closed = true;
308
+ this.ready = false;
309
+ this.closePromise = this.performClose();
310
+ if (wasReady)
311
+ this.options.onUnavailable?.();
312
+ return this.closePromise;
313
+ }
314
+ async performClose() {
315
+ this.client?.close('Managed Codex stopped.');
316
+ const child = this.child;
317
+ if (child && isAlive(child) && child.pid) {
318
+ try {
319
+ process.kill(process.platform === 'win32' ? child.pid : -child.pid, 'SIGTERM');
320
+ }
321
+ catch (error) {
322
+ if (!isRecord(error) || error.code !== 'ESRCH')
323
+ throw error;
324
+ }
325
+ await Promise.race([this.childExited, wait(3_000)]);
326
+ if (isAlive(child)) {
327
+ try {
328
+ process.kill(process.platform === 'win32' ? child.pid : -child.pid, 'SIGKILL');
329
+ }
330
+ catch (error) {
331
+ if (!isRecord(error) || error.code !== 'ESRCH')
332
+ throw error;
333
+ }
334
+ await Promise.race([this.childExited, wait(3_000)]);
335
+ }
336
+ if (isAlive(child))
337
+ throw new Error('Managed Codex process did not stop.');
338
+ }
339
+ if (this.runDirectory)
340
+ await plugins.fs.promises.rm(this.runDirectory, { recursive: true, force: true });
341
+ }
342
+ }
343
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb2RleG1hbmFnZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmNvZGV4bWFuYWdlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUE2QnJELE1BQU0sUUFBUSxHQUFHLENBQUMsS0FBYyxFQUFvQyxFQUFFLENBQ3BFLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2RSxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQXdDLEVBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLEtBQUssQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDO0FBQzVILE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBVSxFQUFpQixFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFNUYsb0dBQW9HO0FBQ3BHLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEtBQUssRUFBRSxVQUFrQixFQUFzRCxFQUFFO0lBQ3RILElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5RUFBeUUsQ0FBQyxDQUFDO0lBQzdILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxPQUFPLENBQVMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDM0QsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENB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QUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPO3dCQUFFLE1BQU0sS0FBSyxDQUFDO2dCQUFDLENBQUM7Z0JBQzlFLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsWUFBWTtZQUFFLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNHLENBQUM7Q0FDRiJ9
@@ -24,5 +24,6 @@ export * from './classes.watch.js';
24
24
  export * from './classes.watchlock.js';
25
25
  export * from './watchpolicy.js';
26
26
  export * from './classes.authorityclient.js';
27
+ export * from './classes.authoritydaemon.js';
27
28
  export * from './classes.authorityservice.js';
28
29
  export declare const runCli: (argvArg?: string[]) => Promise<void>;
package/dist_ts/index.js CHANGED
@@ -24,6 +24,7 @@ export * from './classes.watch.js';
24
24
  export * from './classes.watchlock.js';
25
25
  export * from './watchpolicy.js';
26
26
  export * from './classes.authorityclient.js';
27
+ export * from './classes.authoritydaemon.js';
27
28
  export * from './classes.authorityservice.js';
28
29
  import { AuthSwitchCli } from './classes.cli.js';
29
30
  import { AuthSwitchAuthorityService, resolveAuthSwitchAuthorityPaths, runAuthSwitchAuthorityDaemon } from './classes.authorityservice.js';
@@ -53,4 +54,4 @@ export const runCli = async (argvArg = process.argv.slice(2)) => {
53
54
  const exitCode = await new AuthSwitchCli().run(argvArg);
54
55
  process.exitCode = exitCode;
55
56
  };
56
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLCtCQUErQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsK0JBQStCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUxSSxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLFVBQW9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFpQixFQUFFO0lBQ3ZGLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQy9CLE1BQU0sS0FBSyxHQUFHLCtCQUErQixFQUFFLENBQUM7UUFDaEQsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEQsTUFBTSw0QkFBNEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JELE1BQU0sT0FBTyxHQUFHLElBQUksMEJBQTBCLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDdkUsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE9BQU8sRUFBRTtnQkFDM0QsQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE9BQU8sRUFBRTtvQkFDL0MsQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE1BQU0sRUFBRTt3QkFDOUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRTs0QkFDNUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRTtnQ0FDMUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNULElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNwQixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxPQUFPO1lBQ1QsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLCtFQUErRSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEQsT0FBTyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDOUIsQ0FBQyxDQUFDIn0=
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsK0JBQStCLENBQUM7QUFFOUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSwrQkFBK0IsRUFBRSw0QkFBNEIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTFJLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxLQUFLLEVBQUUsVUFBb0IsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQWlCLEVBQUU7SUFDdkYsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDL0IsTUFBTSxLQUFLLEdBQUcsK0JBQStCLEVBQUUsQ0FBQztRQUNoRCxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwRCxNQUFNLDRCQUE0QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsSUFBSSwwQkFBMEIsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFO2dCQUMzRCxDQUFDLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFO29CQUMvQyxDQUFDLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsTUFBTSxFQUFFO3dCQUM5QyxDQUFDLENBQUMsTUFBTSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFOzRCQUM1QyxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxFQUFFO2dDQUMxQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ1QsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3BCLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7Z0JBQ3BELE9BQU87WUFDVCxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsK0VBQStFLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLGFBQWEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUM5QixDQUFDLENBQUMifQ==
@@ -28,4 +28,5 @@ import * as flexModels from '@modelprofile.com/flexharness-models';
28
28
  import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
29
29
  import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
30
30
  import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
31
- export { flexModels, flexOpenAi, flexAuth, flexAccounts };
31
+ import * as crossharness from '@modelprofile.com/mcp-crossharness';
32
+ export { flexModels, flexOpenAi, flexAuth, flexAccounts, crossharness };
@@ -29,5 +29,6 @@ import * as flexModels from '@modelprofile.com/flexharness-models';
29
29
  import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
30
30
  import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
31
31
  import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
32
- export { flexModels, flexOpenAi, flexAuth, flexAccounts };
33
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBR3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVsRSxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRCxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEdBQWlDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7QUFLM0Y7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsR0FBNkIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBRTVGLHNCQUFzQjtBQUN0QixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUVwRiw0QkFBNEI7QUFDNUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEtBQUssVUFBVSxNQUFNLGdEQUFnRCxDQUFDO0FBQzdFLE9BQU8sS0FBSyxRQUFRLE1BQU0sOENBQThDLENBQUM7QUFDekUsT0FBTyxLQUFLLFlBQVksTUFBTSxrREFBa0QsQ0FBQztBQUNqRixPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLENBQUMifQ==
32
+ import * as crossharness from '@modelprofile.com/mcp-crossharness';
33
+ export { flexModels, flexOpenAi, flexAuth, flexAccounts, crossharness };
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBR3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVsRSxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRCxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEdBQWlDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7QUFLM0Y7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsR0FBNkIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBRTVGLHNCQUFzQjtBQUN0QixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUVwRiw0QkFBNEI7QUFDNUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEtBQUssVUFBVSxNQUFNLGdEQUFnRCxDQUFDO0FBQzdFLE9BQU8sS0FBSyxRQUFRLE1BQU0sOENBQThDLENBQUM7QUFDekUsT0FBTyxLQUFLLFlBQVksTUFBTSxrREFBa0QsQ0FBQztBQUNqRixPQUFPLEtBQUssWUFBWSxNQUFNLG9DQUFvQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelprofile.com/authswitch",
3
- "version": "6.4.0",
3
+ "version": "6.5.0",
4
4
  "private": false,
5
5
  "description": "Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status",
6
6
  "main": "dist_ts/index.js",
@@ -21,6 +21,10 @@
21
21
  "./authority-client": {
22
22
  "types": "./dist_ts/classes.authorityclient.d.ts",
23
23
  "import": "./dist_ts/classes.authorityclient.js"
24
+ },
25
+ "./authority-daemon": {
26
+ "types": "./dist_ts/classes.authoritydaemon.d.ts",
27
+ "import": "./dist_ts/classes.authoritydaemon.js"
24
28
  }
25
29
  },
26
30
  "type": "module",
@@ -45,13 +49,16 @@
45
49
  "@git.zone/tsrun": "^2.0.6",
46
50
  "@git.zone/tstest": "^6.1.1",
47
51
  "@types/node": "26.5.1",
48
- "esbuild": "^0.28.2"
52
+ "@types/ws": "8.18.1",
53
+ "esbuild": "^0.28.2",
54
+ "ws": "8.21.2"
49
55
  },
50
56
  "dependencies": {
51
57
  "@api.global/typedrequest": "8.1.0",
52
58
  "@api.global/typedrequest-interfaces": "7.1.0",
53
59
  "@modelprofile.com/flexharness-models": "^8.0.0",
54
60
  "@modelprofile.com/flexharness-providers": "^8.0.0",
61
+ "@modelprofile.com/mcp-crossharness": "5.4.0",
55
62
  "@push.rocks/smartconsole": "^1.3.0",
56
63
  "@push.rocks/smartdaemon": "2.7.0",
57
64
  "@push.rocks/smartdata": "11.14.2",
package/readme.md CHANGED
@@ -46,8 +46,33 @@ Browser code can import the credential-free DTOs from
46
46
  `@modelprofile.com/authswitch/authority-contract`. A backend binds an account to a
47
47
  runtime incarnation and keeps the returned capability private. The runtime-only socket
48
48
  resolves that binding to a current access token; its directory can be mounted into a
49
- container without exposing the management socket. Reconnect and reload a snapshot after
50
- an event gap or daemon restart.
49
+ container without exposing the management socket. A provider that rejects a specific
50
+ access-token generation can request a newer one through `rejectedGrantGeneration`; the
51
+ authority coalesces concurrent rejection callbacks and never replays an uncertain refresh.
52
+
53
+ `AuthSwitchClient.subscribe(onSnapshot, onEvent, signal, { onStatus })` reports `current`
54
+ after a fresh snapshot or verified heartbeat, `unavailable` on disconnect or resync, and
55
+ `closed` on abort. Keep cached account actions disabled while status is not `current`.
56
+ Every change-event batch supplies a fresh snapshot before `onEvent`, so a consumer does
57
+ not need to reconstruct account state from events. `lastVerifiedAt` records the last
58
+ successful daemon response, including an empty heartbeat.
59
+
60
+ A trusted in-process daemon host can call `AuthSwitchAuthorityDaemon.startManagedCodex()`
61
+ for a bound account and workspace. It owns a private Codex 0.155.1 app-server, passes only
62
+ the authority's current access token through Codex's external-token login, answers its
63
+ unauthorized callback through the authority, and revokes the binding on stop. The returned
64
+ runtime exposes an interactive `codex --remote unix://…` launch descriptor and native
65
+ `thread/start`, `thread/resume` and `turn/start` methods for noninteractive consumers.
66
+ Callers supply a private, durable `codexHomeDirectory` for Codex's own configuration and
67
+ conversation state. SmartData binds that home immutably to one account and scope, and the
68
+ daemon records its active process/socket identity before launching it. Admission refuses
69
+ an existing nonempty native home or a surviving app-server owner; a fresh empty home is
70
+ created on first use. Account removal drains its managed Codex processes before the
71
+ grant is removed, and targeted reauthentication holds new admissions until the device
72
+ operation settles. Only the private socket directory is removed on close. Codex's
73
+ credential store remains ephemeral and does not read or write `auth.json` in that home.
74
+ Codex 0.155.1 does not persist an unused thread created by `thread/start`; resume applies
75
+ after Codex has committed a rollout. The existing CLI has not yet been moved to this path.
51
76
 
52
77
  This SDK is additive at this stage. The commands documented below still use the existing
53
78
  credential stores. The authority daemon does not import those stores automatically,
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/authswitch',
6
- version: '6.4.0',
6
+ version: '6.5.0',
7
7
  description: 'Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status'
8
8
  }
@@ -16,7 +16,13 @@ export interface IReq_AuthSwitchBindAccount extends ITypedRequest {
16
16
  /** Backend-only access operation. Refresh grants never cross this interface. */
17
17
  export interface IReq_AuthSwitchResolveAccess extends ITypedRequest {
18
18
  method: 'authswitch.authority.resolveAccess';
19
- request: { bindingId: string; capability: string; minValidityMs: number };
19
+ request: {
20
+ bindingId: string;
21
+ capability: string;
22
+ minValidityMs: number;
23
+ /** The provider rejected this exact access-token generation. */
24
+ rejectedGrantGeneration?: number;
25
+ };
20
26
  response: {
21
27
  accessToken: string;
22
28
  accountId: string;
@@ -317,6 +317,13 @@ export class AuthSwitchAuthorityBroker {
317
317
  return structuredClone(operation.public);
318
318
  }
319
319
 
320
+ /** Trusted daemon lifecycle hook: hold new managed runtimes out until targeted reauth settles. */
321
+ public async waitOperation(operationId: string): Promise<void> {
322
+ const operation = this.operations.get(operationId);
323
+ if (!isUuid(operationId) || !operation) throw new Error('Account operation expired or was not found.');
324
+ await operation.task;
325
+ }
326
+
320
327
  private pruneOperations(): void {
321
328
  for (const [id, operation] of this.operations) {
322
329
  if (operation.finishedAt !== null && this.now() - operation.finishedAt > 600_000) this.operations.delete(id);
@@ -379,9 +386,19 @@ export class AuthSwitchAuthorityBroker {
379
386
  return { binding: publicBinding(updated.binding), capability };
380
387
  }
381
388
 
382
- public async resolveAccess(bindingId: string, capability: string, minValidityMs: number): Promise<IAuthSwitchResolvedAccess> {
389
+ public async revokeBinding(bindingId: string, capability: string): Promise<boolean> {
390
+ if (!isId(bindingId) || !/^[A-Za-z0-9_-]{43}$/.test(capability)) throw new Error('Invalid runtime binding revocation.');
391
+ const revoked = await this.database.revokeBinding(plugins.crypto.randomUUID(), bindingId, idHash(capability));
392
+ if (revoked) this.publish();
393
+ return revoked;
394
+ }
395
+
396
+ public async resolveAccess(bindingId: string, capability: string, minValidityMs: number,
397
+ rejectedGrantGeneration?: number): Promise<IAuthSwitchResolvedAccess> {
383
398
  if (!isId(bindingId) || !/^[A-Za-z0-9_-]{43}$/.test(capability)
384
- || !Number.isSafeInteger(minValidityMs) || minValidityMs < 0 || minValidityMs > 3_600_000) throw new Error('Invalid runtime credential request.');
399
+ || !Number.isSafeInteger(minValidityMs) || minValidityMs < 0 || minValidityMs > 3_600_000
400
+ || (rejectedGrantGeneration !== undefined && (!Number.isSafeInteger(rejectedGrantGeneration)
401
+ || rejectedGrantGeneration < 1))) throw new Error('Invalid runtime credential request.');
385
402
  const supplied = Buffer.from(idHash(capability), 'hex');
386
403
  for (let attempt = 0; attempt < 4; attempt++) {
387
404
  const initial = await this.database.readBindingContext(bindingId);
@@ -395,6 +412,9 @@ export class AuthSwitchAuthorityBroker {
395
412
  || binding.grantAuthorizationGeneration !== grant.authorizationGeneration) {
396
413
  throw new Error('Account needs reauthentication.');
397
414
  }
415
+ if (rejectedGrantGeneration !== undefined && rejectedGrantGeneration > grant.grantGeneration) {
416
+ throw new Error('Provider rejected a future account grant generation.');
417
+ }
398
418
  if (grant.state === 'exchange_may_have_been_sent') {
399
419
  const inFlight = this.refreshes.get(account.id);
400
420
  if (!inFlight) throw new Error('Account refresh is unresolved; reauthentication is required.');
@@ -405,9 +425,10 @@ export class AuthSwitchAuthorityBroker {
405
425
  || !['ready', 'retry_wait'].includes(grant.state)) {
406
426
  throw new Error('Account needs reauthentication.');
407
427
  }
408
- if (this.isDue(grant, minValidityMs)) {
428
+ const rejectedCurrent = rejectedGrantGeneration === grant.grantGeneration;
429
+ if (this.isDue(grant, minValidityMs) || rejectedCurrent) {
409
430
  if (grant.state === 'ready' || (grant.retryAt !== null && Date.parse(grant.retryAt) <= this.now())) {
410
- await this.refreshAccount(account.id);
431
+ await this.refreshAccount(account.id, rejectedCurrent ? rejectedGrantGeneration : undefined);
411
432
  continue;
412
433
  }
413
434
  throw new Error('Account access credential is not fresh enough.');
@@ -431,7 +452,8 @@ export class AuthSwitchAuthorityBroker {
431
452
  }
432
453
  if (latest.grant.grantGeneration !== grant.grantGeneration
433
454
  || latest.grant.state === 'exchange_may_have_been_sent') continue;
434
- if (!['ready', 'retry_wait'].includes(latest.grant.state) || this.isDue(latest.grant, minValidityMs)) {
455
+ if (!['ready', 'retry_wait'].includes(latest.grant.state) || this.isDue(latest.grant, minValidityMs)
456
+ || (rejectedGrantGeneration !== undefined && latest.grant.grantGeneration === rejectedGrantGeneration)) {
435
457
  throw new Error('Account access credential is not fresh enough.');
436
458
  }
437
459
  return { accessToken: credential.accessToken, accountId: account.workspaceId,
@@ -441,20 +463,20 @@ export class AuthSwitchAuthorityBroker {
441
463
  throw new Error('Account credential rotated repeatedly during resolution; retry the request.');
442
464
  }
443
465
 
444
- private async refreshAccount(accountId: string): Promise<void> {
466
+ private async refreshAccount(accountId: string, rejectedGrantGeneration?: number): Promise<void> {
445
467
  const prior = this.refreshes.get(accountId);
446
468
  if (prior) return prior;
447
- const task = this.performRefresh(accountId).finally(() => { if (this.refreshes.get(accountId) === task) this.refreshes.delete(accountId); });
469
+ const task = this.performRefresh(accountId, rejectedGrantGeneration).finally(() => { if (this.refreshes.get(accountId) === task) this.refreshes.delete(accountId); });
448
470
  this.refreshes.set(accountId, task);
449
471
  return task;
450
472
  }
451
473
 
452
- private async performRefresh(accountId: string): Promise<void> {
474
+ private async performRefresh(accountId: string, rejectedGrantGeneration?: number): Promise<void> {
453
475
  const initial = await this.database.readAccountAndPrimaryGrant(accountId);
454
476
  const initialGrant = initial.grant;
455
477
  if (!initial.account || initial.account.removed || !initialGrant || initialGrant.purpose !== 'openai_managed'
456
478
  || !['ready', 'retry_wait'].includes(initialGrant.state) || initialGrant.owner !== 'daemon'
457
- || !this.isDue(initialGrant, 0)
479
+ || (!this.isDue(initialGrant, 0) && initialGrant.grantGeneration !== rejectedGrantGeneration)
458
480
  || (initialGrant.state === 'retry_wait'
459
481
  && (initialGrant.retryAt === null || Date.parse(initialGrant.retryAt) > this.now()))) return;
460
482
  const credential = await this.unsealCredential(initial.account, initialGrant);