@modelprofile.com/authswitch 6.3.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/authority-contract.d.ts +142 -0
- package/dist_ts/authority-contract.js +3 -0
- package/dist_ts/authority-runtime-contract.d.ts +34 -0
- package/dist_ts/authority-runtime-contract.js +2 -0
- package/dist_ts/classes.authoritybroker.d.ts +76 -0
- package/dist_ts/classes.authoritybroker.js +570 -0
- package/dist_ts/classes.authorityclient.d.ts +47 -0
- package/dist_ts/classes.authorityclient.js +261 -0
- package/dist_ts/classes.authoritydaemon.d.ts +46 -0
- package/dist_ts/classes.authoritydaemon.js +492 -0
- package/dist_ts/classes.authoritydatabase.d.ts +103 -0
- package/dist_ts/classes.authoritydatabase.js +835 -0
- package/dist_ts/classes.authorityframing.d.ts +8 -0
- package/dist_ts/classes.authorityframing.js +22 -0
- package/dist_ts/classes.authoritymodels.d.ts +239 -0
- package/dist_ts/classes.authoritymodels.js +893 -0
- package/dist_ts/classes.authoritysecrets.d.ts +9 -0
- package/dist_ts/classes.authoritysecrets.js +30 -0
- package/dist_ts/classes.authorityservice.d.ts +28 -0
- package/dist_ts/classes.authorityservice.js +71 -0
- package/dist_ts/classes.codexmanaged.d.ts +80 -0
- package/dist_ts/classes.codexmanaged.js +343 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +27 -1
- package/dist_ts/plugins.d.ts +11 -3
- package/dist_ts/plugins.js +12 -4
- package/package.json +25 -4
- package/readme.md +59 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +109 -0
- package/ts/authority-runtime-contract.ts +33 -0
- package/ts/classes.authoritybroker.ts +552 -0
- package/ts/classes.authorityclient.ts +252 -0
- package/ts/classes.authoritydaemon.ts +403 -0
- package/ts/classes.authoritydatabase.ts +818 -0
- package/ts/classes.authorityframing.ts +21 -0
- package/ts/classes.authoritymodels.ts +407 -0
- package/ts/classes.authoritysecrets.ts +27 -0
- package/ts/classes.authorityservice.ts +83 -0
- package/ts/classes.codexmanaged.ts +339 -0
- package/ts/index.ts +26 -0
- package/ts/plugins.ts +11 -3
package/dist_ts/index.js
CHANGED
|
@@ -23,9 +23,35 @@ export * from './classes.service.js';
|
|
|
23
23
|
export * from './classes.watch.js';
|
|
24
24
|
export * from './classes.watchlock.js';
|
|
25
25
|
export * from './watchpolicy.js';
|
|
26
|
+
export * from './classes.authorityclient.js';
|
|
27
|
+
export * from './classes.authoritydaemon.js';
|
|
28
|
+
export * from './classes.authorityservice.js';
|
|
26
29
|
import { AuthSwitchCli } from './classes.cli.js';
|
|
30
|
+
import { AuthSwitchAuthorityService, resolveAuthSwitchAuthorityPaths, runAuthSwitchAuthorityDaemon } from './classes.authorityservice.js';
|
|
27
31
|
export const runCli = async (argvArg = process.argv.slice(2)) => {
|
|
32
|
+
if (argvArg[0] === 'authority') {
|
|
33
|
+
const paths = resolveAuthSwitchAuthorityPaths();
|
|
34
|
+
if (argvArg[1] === 'daemon' && argvArg.length === 2) {
|
|
35
|
+
await runAuthSwitchAuthorityDaemon(paths);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (argvArg[1] === 'service' && argvArg.length === 3) {
|
|
39
|
+
const service = new AuthSwitchAuthorityService(paths.runtimeDirectory);
|
|
40
|
+
const action = argvArg[2];
|
|
41
|
+
const result = action === 'install' ? await service.install()
|
|
42
|
+
: action === 'status' ? await service.inspect()
|
|
43
|
+
: action === 'enable' ? await service.enable()
|
|
44
|
+
: action === 'start' ? await service.start()
|
|
45
|
+
: action === 'stop' ? await service.stop()
|
|
46
|
+
: null;
|
|
47
|
+
if (result !== null) {
|
|
48
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw new Error('Usage: authswitch authority daemon | service install|status|enable|start|stop');
|
|
53
|
+
}
|
|
28
54
|
const exitCode = await new AuthSwitchCli().run(argvArg);
|
|
29
55
|
process.exitCode = exitCode;
|
|
30
56
|
};
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsK0JBQStCLENBQUM7QUFFOUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSwrQkFBK0IsRUFBRSw0QkFBNEIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTFJLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxLQUFLLEVBQUUsVUFBb0IsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQWlCLEVBQUU7SUFDdkYsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDL0IsTUFBTSxLQUFLLEdBQUcsK0JBQStCLEVBQUUsQ0FBQztRQUNoRCxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwRCxNQUFNLDRCQUE0QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsSUFBSSwwQkFBMEIsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFO2dCQUMzRCxDQUFDLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFO29CQUMvQyxDQUFDLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsTUFBTSxFQUFFO3dCQUM5QyxDQUFDLENBQUMsTUFBTSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFOzRCQUM1QyxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxFQUFFO2dDQUMxQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ1QsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3BCLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7Z0JBQ3BELE9BQU87WUFDVCxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsK0VBQStFLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLGFBQWEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUM5QixDQUFDLENBQUMifQ==
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ import * as os from 'node:os';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as childProcess from 'node:child_process';
|
|
5
5
|
import * as crypto from 'node:crypto';
|
|
6
|
+
import * as net from 'node:net';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
6
8
|
import type { DatabaseSync } from 'node:sqlite';
|
|
7
|
-
export { childProcess, crypto, fs, os, path };
|
|
9
|
+
export { childProcess, crypto, fileURLToPath, fs, net, os, path };
|
|
8
10
|
export type { DatabaseSync };
|
|
9
11
|
/** SQLite is needed only when accessing a Codex state database, not when hosting account APIs. */
|
|
10
12
|
export declare const loadSqlite: () => typeof import("node:sqlite");
|
|
@@ -16,9 +18,15 @@ export type TProperLockfile = typeof properLockfile;
|
|
|
16
18
|
*/
|
|
17
19
|
export declare const loadProperLockfile: () => Promise<TProperLockfile>;
|
|
18
20
|
import * as smartconsole from '@push.rocks/smartconsole';
|
|
19
|
-
|
|
21
|
+
import * as smartdata from '@push.rocks/smartdata';
|
|
22
|
+
import * as smartdb from '@push.rocks/smartdb';
|
|
23
|
+
import * as smartsecret from '@push.rocks/smartsecret';
|
|
24
|
+
import * as smartdaemon from '@push.rocks/smartdaemon';
|
|
25
|
+
import * as typedrequest from '@api.global/typedrequest';
|
|
26
|
+
export { smartconsole, smartdata, smartdb, smartsecret, smartdaemon, typedrequest };
|
|
20
27
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
21
28
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
22
29
|
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
|
23
30
|
import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
|
|
24
|
-
|
|
31
|
+
import * as crossharness from '@modelprofile.com/mcp-crossharness';
|
|
32
|
+
export { flexModels, flexOpenAi, flexAuth, flexAccounts, crossharness };
|
package/dist_ts/plugins.js
CHANGED
|
@@ -4,8 +4,10 @@ import * as os from 'node:os';
|
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import * as childProcess from 'node:child_process';
|
|
6
6
|
import * as crypto from 'node:crypto';
|
|
7
|
+
import * as net from 'node:net';
|
|
7
8
|
import { createRequire } from 'node:module';
|
|
8
|
-
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
export { childProcess, crypto, fileURLToPath, fs, net, os, path };
|
|
9
11
|
const nativeRequire = createRequire(import.meta.url);
|
|
10
12
|
/** SQLite is needed only when accessing a Codex state database, not when hosting account APIs. */
|
|
11
13
|
export const loadSqlite = () => nativeRequire('node:sqlite');
|
|
@@ -16,11 +18,17 @@ export const loadSqlite = () => nativeRequire('node:sqlite');
|
|
|
16
18
|
export const loadProperLockfile = () => import('proper-lockfile');
|
|
17
19
|
// @push.rocks modules
|
|
18
20
|
import * as smartconsole from '@push.rocks/smartconsole';
|
|
19
|
-
|
|
21
|
+
import * as smartdata from '@push.rocks/smartdata';
|
|
22
|
+
import * as smartdb from '@push.rocks/smartdb';
|
|
23
|
+
import * as smartsecret from '@push.rocks/smartsecret';
|
|
24
|
+
import * as smartdaemon from '@push.rocks/smartdaemon';
|
|
25
|
+
import * as typedrequest from '@api.global/typedrequest';
|
|
26
|
+
export { smartconsole, smartdata, smartdb, smartsecret, smartdaemon, typedrequest };
|
|
20
27
|
// @modelprofile.com modules
|
|
21
28
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
22
29
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
23
30
|
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
|
24
31
|
import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
|
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",
|
|
@@ -13,6 +13,18 @@
|
|
|
13
13
|
"./mutation": {
|
|
14
14
|
"types": "./dist_ts/mutation.d.ts",
|
|
15
15
|
"import": "./dist_ts/mutation.js"
|
|
16
|
+
},
|
|
17
|
+
"./authority-contract": {
|
|
18
|
+
"types": "./dist_ts/authority-contract.d.ts",
|
|
19
|
+
"import": "./dist_ts/authority-contract.js"
|
|
20
|
+
},
|
|
21
|
+
"./authority-client": {
|
|
22
|
+
"types": "./dist_ts/classes.authorityclient.d.ts",
|
|
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"
|
|
16
28
|
}
|
|
17
29
|
},
|
|
18
30
|
"type": "module",
|
|
@@ -37,12 +49,21 @@
|
|
|
37
49
|
"@git.zone/tsrun": "^2.0.6",
|
|
38
50
|
"@git.zone/tstest": "^6.1.1",
|
|
39
51
|
"@types/node": "26.5.1",
|
|
40
|
-
"
|
|
52
|
+
"@types/ws": "8.18.1",
|
|
53
|
+
"esbuild": "^0.28.2",
|
|
54
|
+
"ws": "8.21.2"
|
|
41
55
|
},
|
|
42
56
|
"dependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
57
|
+
"@api.global/typedrequest": "8.1.0",
|
|
58
|
+
"@api.global/typedrequest-interfaces": "7.1.0",
|
|
59
|
+
"@modelprofile.com/flexharness-models": "^8.0.0",
|
|
60
|
+
"@modelprofile.com/flexharness-providers": "^8.0.0",
|
|
61
|
+
"@modelprofile.com/mcp-crossharness": "5.4.0",
|
|
45
62
|
"@push.rocks/smartconsole": "^1.3.0",
|
|
63
|
+
"@push.rocks/smartdaemon": "2.7.0",
|
|
64
|
+
"@push.rocks/smartdata": "11.14.2",
|
|
65
|
+
"@push.rocks/smartdb": "7.0.1",
|
|
66
|
+
"@push.rocks/smartsecret": "1.8.0",
|
|
46
67
|
"@types/proper-lockfile": "^4.1.4",
|
|
47
68
|
"proper-lockfile": "^4.1.2"
|
|
48
69
|
},
|
package/readme.md
CHANGED
|
@@ -24,6 +24,65 @@ pnpm install -g @modelprofile.com/authswitch
|
|
|
24
24
|
|
|
25
25
|
Node.js 24 or newer is required.
|
|
26
26
|
|
|
27
|
+
## Authority SDK (new account registry)
|
|
28
|
+
|
|
29
|
+
The package also exports a typed client for a per-user authswitch authority daemon. Its
|
|
30
|
+
SmartData registry stores account identity separately from sealed refresh grants, runtime
|
|
31
|
+
bindings, Codex enrollment records, and native-handoff and migration journals. A daemon
|
|
32
|
+
owns OpenAI device login, targeted reauthentication, and proactive refresh for grants
|
|
33
|
+
added through this API. Management snapshots and events contain no credentials.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { AuthSwitchClient } from '@modelprofile.com/authswitch/authority-client';
|
|
37
|
+
import { resolveAuthSwitchAuthorityPaths } from '@modelprofile.com/authswitch';
|
|
38
|
+
|
|
39
|
+
const paths = resolveAuthSwitchAuthorityPaths();
|
|
40
|
+
const client = new AuthSwitchClient(paths.authoritySocketPath, paths.runtimeSocketPath);
|
|
41
|
+
const snapshot = await client.snapshotAll();
|
|
42
|
+
const operation = await client.beginAddOpenAi();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Browser code can import the credential-free DTOs from
|
|
46
|
+
`@modelprofile.com/authswitch/authority-contract`. A backend binds an account to a
|
|
47
|
+
runtime incarnation and keeps the returned capability private. The runtime-only socket
|
|
48
|
+
resolves that binding to a current access token; its directory can be mounted into a
|
|
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.
|
|
76
|
+
|
|
77
|
+
This SDK is additive at this stage. The commands documented below still use the existing
|
|
78
|
+
credential stores. The authority daemon does not import those stores automatically,
|
|
79
|
+
replace their active native sessions, or take over their refresh grants. An active
|
|
80
|
+
Codex/OpenCode native grant remains pending until its owner is idle and an explicit
|
|
81
|
+
handoff verifies the latest native source. Claude Code's own native credential files
|
|
82
|
+
remain vendor-owned; a container setup-token grant is a separate grant under the same
|
|
83
|
+
account. The one-time migration and deletion of authswitch's old stores are separate
|
|
84
|
+
cutover steps.
|
|
85
|
+
|
|
27
86
|
## Usage
|
|
28
87
|
|
|
29
88
|
Run `authswitch`, `authswitch -i`, or `authswitch --interactive` for an interactive guide. Use the arrow keys and
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ITypedRequest } from '@api.global/typedrequest-interfaces';
|
|
2
|
+
|
|
3
|
+
/** Credential-free account management contract. Safe to import in browser code. */
|
|
4
|
+
export type TAuthSwitchAccountHealth = 'ready' | 'refreshing' | 'retry_wait' | 'needs_reauth' | 'native' | 'legacy_native_pending' | 'removed';
|
|
5
|
+
|
|
6
|
+
export interface IAuthSwitchAccount {
|
|
7
|
+
id: string;
|
|
8
|
+
providerId: string;
|
|
9
|
+
label: string;
|
|
10
|
+
email: string | null;
|
|
11
|
+
plan: string | null;
|
|
12
|
+
health: TAuthSwitchAccountHealth;
|
|
13
|
+
owner: 'daemon' | 'claude_native' | 'legacy_native' | 'none';
|
|
14
|
+
grantGeneration: number;
|
|
15
|
+
revision: number;
|
|
16
|
+
accessExpiresAt: string | null;
|
|
17
|
+
retryAt: string | null;
|
|
18
|
+
problem: 'none' | 'provider_unavailable' | 'exchange_uncertain' | 'provider_rejected' | 'native_owner';
|
|
19
|
+
statusObservedAt: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface IAuthSwitchBinding {
|
|
23
|
+
id: string;
|
|
24
|
+
accountId: string;
|
|
25
|
+
runtime: 'flex' | 'codex' | 'opencode' | 'claude';
|
|
26
|
+
scopeId: string;
|
|
27
|
+
incarnationId: string;
|
|
28
|
+
revision: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IAuthSwitchSnapshot {
|
|
32
|
+
schemaVersion: 1;
|
|
33
|
+
epoch: string;
|
|
34
|
+
revision: number;
|
|
35
|
+
generatedAt: string;
|
|
36
|
+
accounts: IAuthSwitchAccount[];
|
|
37
|
+
bindings: IAuthSwitchBinding[];
|
|
38
|
+
nextAccountCursor: string | null;
|
|
39
|
+
nextBindingCursor: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IAuthSwitchAccountEvent {
|
|
43
|
+
epoch: string;
|
|
44
|
+
revision: number;
|
|
45
|
+
kind: 'account' | 'binding';
|
|
46
|
+
accountId: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type TAuthSwitchLoginPrompt =
|
|
50
|
+
| { flow: 'device'; verificationUrl: string; userCode: string }
|
|
51
|
+
| { flow: 'browser'; authUrl: string };
|
|
52
|
+
|
|
53
|
+
export interface IAuthSwitchOperation {
|
|
54
|
+
id: string;
|
|
55
|
+
state: 'pending' | 'complete' | 'failed' | 'cancelled';
|
|
56
|
+
prompt: TAuthSwitchLoginPrompt | null;
|
|
57
|
+
account: IAuthSwitchAccount | null;
|
|
58
|
+
error: string | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface IReq_AuthSwitchSnapshot extends ITypedRequest {
|
|
62
|
+
method: 'authswitch.authority.snapshot';
|
|
63
|
+
request: { accountAfter?: string; bindingAfter?: string; limit?: number };
|
|
64
|
+
response: { snapshot: IAuthSwitchSnapshot };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface IReq_AuthSwitchEvents extends ITypedRequest {
|
|
68
|
+
method: 'authswitch.authority.events';
|
|
69
|
+
request: { epoch: string; afterRevision: number; waitMs: number };
|
|
70
|
+
response: { epoch: string; revision: number; resyncRequired: boolean; events: IAuthSwitchAccountEvent[] };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface IReq_AuthSwitchBeginAdd extends ITypedRequest {
|
|
74
|
+
method: 'authswitch.authority.add';
|
|
75
|
+
request: { providerId: 'openai'; flow: 'device' };
|
|
76
|
+
response: { operation: IAuthSwitchOperation };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface IReq_AuthSwitchBeginReauth extends ITypedRequest {
|
|
80
|
+
method: 'authswitch.authority.reauth';
|
|
81
|
+
request: { accountId: string; flow: 'device' };
|
|
82
|
+
response: { operation: IAuthSwitchOperation };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface IReq_AuthSwitchGetOperation extends ITypedRequest {
|
|
86
|
+
method: 'authswitch.authority.operation';
|
|
87
|
+
request: { operationId: string };
|
|
88
|
+
response: { operation: IAuthSwitchOperation };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface IReq_AuthSwitchCancelOperation extends ITypedRequest {
|
|
92
|
+
method: 'authswitch.authority.cancel';
|
|
93
|
+
request: { operationId: string };
|
|
94
|
+
response: { operation: IAuthSwitchOperation };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface IReq_AuthSwitchRenameAccount extends ITypedRequest {
|
|
98
|
+
method: 'authswitch.authority.rename';
|
|
99
|
+
request: { accountId: string; expectedRevision: number; label: string };
|
|
100
|
+
response: { account: IAuthSwitchAccount };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface IReq_AuthSwitchRemoveAccount extends ITypedRequest {
|
|
104
|
+
method: 'authswitch.authority.remove';
|
|
105
|
+
request: { accountId: string; expectedRevision: number };
|
|
106
|
+
response: { account: IAuthSwitchAccount };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Runtime capability is returned only to trusted backend callers; do not expose this response in a browser API. */
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ITypedRequest } from '@api.global/typedrequest-interfaces';
|
|
2
|
+
import type { IAuthSwitchBinding } from './authority-contract.js';
|
|
3
|
+
|
|
4
|
+
/** Backend-only binding operation. The capability must never enter a browser-facing response. */
|
|
5
|
+
export interface IReq_AuthSwitchBindAccount extends ITypedRequest {
|
|
6
|
+
method: 'authswitch.authority.bind';
|
|
7
|
+
request: {
|
|
8
|
+
accountId: string;
|
|
9
|
+
runtime: IAuthSwitchBinding['runtime'];
|
|
10
|
+
scopeId: string;
|
|
11
|
+
incarnationId: string;
|
|
12
|
+
};
|
|
13
|
+
response: { binding: IAuthSwitchBinding; capability: string };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Backend-only access operation. Refresh grants never cross this interface. */
|
|
17
|
+
export interface IReq_AuthSwitchResolveAccess extends ITypedRequest {
|
|
18
|
+
method: 'authswitch.authority.resolveAccess';
|
|
19
|
+
request: {
|
|
20
|
+
bindingId: string;
|
|
21
|
+
capability: string;
|
|
22
|
+
minValidityMs: number;
|
|
23
|
+
/** The provider rejected this exact access-token generation. */
|
|
24
|
+
rejectedGrantGeneration?: number;
|
|
25
|
+
};
|
|
26
|
+
response: {
|
|
27
|
+
accessToken: string;
|
|
28
|
+
accountId: string;
|
|
29
|
+
isFedrampAccount: boolean;
|
|
30
|
+
expiresAt: string;
|
|
31
|
+
grantGeneration: number;
|
|
32
|
+
};
|
|
33
|
+
}
|