@mostok/codexes 0.1.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/LICENSE +15 -0
- package/README.md +88 -0
- package/dist/accounts/account-registry.d.ts +30 -0
- package/dist/accounts/account-registry.js +263 -0
- package/dist/accounts/account-registry.js.map +1 -0
- package/dist/accounts/account-resolution.d.ts +16 -0
- package/dist/accounts/account-resolution.js +71 -0
- package/dist/accounts/account-resolution.js.map +1 -0
- package/dist/accounts/resolve-active-account.d.ts +6 -0
- package/dist/accounts/resolve-active-account.js +32 -0
- package/dist/accounts/resolve-active-account.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +3426 -0
- package/dist/cli.js.map +7 -0
- package/dist/commands/account-add/run-account-add-command.d.ts +2 -0
- package/dist/commands/account-add/run-account-add-command.js +296 -0
- package/dist/commands/account-add/run-account-add-command.js.map +1 -0
- package/dist/commands/account-list/run-account-list-command.d.ts +2 -0
- package/dist/commands/account-list/run-account-list-command.js +48 -0
- package/dist/commands/account-list/run-account-list-command.js.map +1 -0
- package/dist/commands/account-remove/run-account-remove-command.d.ts +2 -0
- package/dist/commands/account-remove/run-account-remove-command.js +52 -0
- package/dist/commands/account-remove/run-account-remove-command.js.map +1 -0
- package/dist/commands/account-use/run-account-use-command.d.ts +2 -0
- package/dist/commands/account-use/run-account-use-command.js +78 -0
- package/dist/commands/account-use/run-account-use-command.js.map +1 -0
- package/dist/commands/root/run-root-command.d.ts +2 -0
- package/dist/commands/root/run-root-command.js +175 -0
- package/dist/commands/root/run-root-command.js.map +1 -0
- package/dist/config/wrapper-config.d.ts +24 -0
- package/dist/config/wrapper-config.js +145 -0
- package/dist/config/wrapper-config.js.map +1 -0
- package/dist/core/bootstrap.d.ts +8 -0
- package/dist/core/bootstrap.js +32 -0
- package/dist/core/bootstrap.js.map +1 -0
- package/dist/core/context.d.ts +33 -0
- package/dist/core/context.js +72 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/paths.d.ts +12 -0
- package/dist/core/paths.js +30 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/logging/logger.d.ts +18 -0
- package/dist/logging/logger.js +56 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/process/codex-launch-spec.d.ts +5 -0
- package/dist/process/codex-launch-spec.js +80 -0
- package/dist/process/codex-launch-spec.js.map +1 -0
- package/dist/process/find-codex-binary.d.ts +14 -0
- package/dist/process/find-codex-binary.js +73 -0
- package/dist/process/find-codex-binary.js.map +1 -0
- package/dist/process/run-codex-login.d.ts +14 -0
- package/dist/process/run-codex-login.js +97 -0
- package/dist/process/run-codex-login.js.map +1 -0
- package/dist/process/spawn-codex-command.d.ts +7 -0
- package/dist/process/spawn-codex-command.js +69 -0
- package/dist/process/spawn-codex-command.js.map +1 -0
- package/dist/runtime/activate-account/activate-account.d.ts +27 -0
- package/dist/runtime/activate-account/activate-account.js +298 -0
- package/dist/runtime/activate-account/activate-account.js.map +1 -0
- package/dist/runtime/auth-state-probe.d.ts +57 -0
- package/dist/runtime/auth-state-probe.js +394 -0
- package/dist/runtime/auth-state-probe.js.map +1 -0
- package/dist/runtime/init/initialize-runtime.d.ts +19 -0
- package/dist/runtime/init/initialize-runtime.js +275 -0
- package/dist/runtime/init/initialize-runtime.js.map +1 -0
- package/dist/runtime/lock/runtime-lock.d.ts +11 -0
- package/dist/runtime/lock/runtime-lock.js +99 -0
- package/dist/runtime/lock/runtime-lock.js.map +1 -0
- package/dist/runtime/login-workspace.d.ts +18 -0
- package/dist/runtime/login-workspace.js +171 -0
- package/dist/runtime/login-workspace.js.map +1 -0
- package/dist/runtime/runtime-contract.d.ts +44 -0
- package/dist/runtime/runtime-contract.js +79 -0
- package/dist/runtime/runtime-contract.js.map +1 -0
- package/dist/selection/account-auth-state.d.ts +23 -0
- package/dist/selection/account-auth-state.js +132 -0
- package/dist/selection/account-auth-state.js.map +1 -0
- package/dist/selection/select-account.d.ts +11 -0
- package/dist/selection/select-account.js +168 -0
- package/dist/selection/select-account.js.map +1 -0
- package/dist/selection/usage-cache.d.ts +24 -0
- package/dist/selection/usage-cache.js +106 -0
- package/dist/selection/usage-cache.js.map +1 -0
- package/dist/selection/usage-client.d.ts +23 -0
- package/dist/selection/usage-client.js +143 -0
- package/dist/selection/usage-client.js.map +1 -0
- package/dist/selection/usage-normalize.d.ts +7 -0
- package/dist/selection/usage-normalize.js +209 -0
- package/dist/selection/usage-normalize.js.map +1 -0
- package/dist/selection/usage-probe-coordinator.d.ts +18 -0
- package/dist/selection/usage-probe-coordinator.js +69 -0
- package/dist/selection/usage-probe-coordinator.js.map +1 -0
- package/dist/selection/usage-types.d.ts +59 -0
- package/dist/selection/usage-types.js +2 -0
- package/dist/selection/usage-types.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Mostok
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# codexes
|
|
2
|
+
|
|
3
|
+
> Transparent multi-account wrapper for the real `codex` CLI.
|
|
4
|
+
|
|
5
|
+
`codexes` keeps one shared Codex runtime for config, MCP wiring, and trust state while storing each account's auth material in its own profile. Before every wrapped launch it activates the selected profile, so you can switch accounts without rebuilding the rest of the runtime.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
npm test
|
|
13
|
+
node dist/cli.js --help
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Install the current checkout globally and use `codexes` from any terminal:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g .
|
|
20
|
+
codexes --help
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Install the public package from anywhere:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g @mostok/codexes
|
|
27
|
+
codexes --help
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Key Features
|
|
31
|
+
|
|
32
|
+
- Shared `CODEX_HOME` for stable `config.toml`, `mcp.json`, and `trust/`
|
|
33
|
+
- Per-account auth activation for `auth.json` and `sessions/`
|
|
34
|
+
- Runtime locking to avoid concurrent mutation of the shared Codex home
|
|
35
|
+
- Experimental account selection by remaining daily and weekly limits
|
|
36
|
+
- Packaged npm distribution with smoke coverage for real installs
|
|
37
|
+
|
|
38
|
+
## Example
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
codexes account add work
|
|
42
|
+
codexes account add personal
|
|
43
|
+
codexes account use work
|
|
44
|
+
CODEXES_ACCOUNT_SELECTION_STRATEGY=remaining-limit-experimental codexes chat --model gpt-5
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The experimental selector probes `https://chatgpt.com/backend-api/wham/usage`, compares remaining quota windows, and picks the best usable account before launching the real `codex` binary.
|
|
48
|
+
|
|
49
|
+
## Documentation
|
|
50
|
+
|
|
51
|
+
| Guide | Description |
|
|
52
|
+
|-------|-------------|
|
|
53
|
+
| [Operations Guide](docs/codexes-operations.md) | Runtime model, account lifecycle, remaining-limit selection, logs |
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
Local development:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run build
|
|
61
|
+
npm test
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Packaged tarball:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run pack:tarball
|
|
68
|
+
npm run smoke:packaged
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The generated package is written to `artifacts/` and can be installed with `npm install -g ./artifacts/mostok-codexes-<version>.tgz`.
|
|
72
|
+
|
|
73
|
+
## Publish
|
|
74
|
+
|
|
75
|
+
Publish to npmjs from your machine:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
export NPM_TOKEN=YOUR_NPM_AUTOMATION_TOKEN
|
|
79
|
+
npm ci
|
|
80
|
+
npm test
|
|
81
|
+
npm publish --access public
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or create a GitHub release and let `.github/workflows/publish-npm.yml` publish the package with repository secret `NPM_TOKEN`.
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
ISC
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Logger } from "../logging/logger.js";
|
|
2
|
+
export interface AccountRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
authDirectory: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
updatedAt: string;
|
|
8
|
+
lastUsedAt: string | null;
|
|
9
|
+
}
|
|
10
|
+
export interface AccountRegistryDocument {
|
|
11
|
+
schemaVersion: number;
|
|
12
|
+
defaultAccountId: string | null;
|
|
13
|
+
accounts: AccountRecord[];
|
|
14
|
+
}
|
|
15
|
+
export interface AccountRegistry {
|
|
16
|
+
addAccount(input: {
|
|
17
|
+
label: string;
|
|
18
|
+
authDirectory?: string;
|
|
19
|
+
}): Promise<AccountRecord>;
|
|
20
|
+
getDefaultAccount(): Promise<AccountRecord | null>;
|
|
21
|
+
listAccounts(): Promise<AccountRecord[]>;
|
|
22
|
+
removeAccount(accountId: string): Promise<AccountRecord>;
|
|
23
|
+
selectAccount(accountId: string): Promise<AccountRecord>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createAccountRegistry(input: {
|
|
26
|
+
accountRoot: string;
|
|
27
|
+
logger: Logger;
|
|
28
|
+
registryFile: string;
|
|
29
|
+
}): AccountRegistry;
|
|
30
|
+
export declare function deleteRegistryFile(registryFile: string): Promise<void>;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const REGISTRY_SCHEMA_VERSION = 1;
|
|
5
|
+
export function createAccountRegistry(input) {
|
|
6
|
+
return {
|
|
7
|
+
addAccount(details) {
|
|
8
|
+
return withRegistryMutation(input, "registry.add", async (document, now) => {
|
|
9
|
+
const normalizedLabel = normalizeLabel(details.label);
|
|
10
|
+
const duplicate = document.accounts.find((account) => account.label.toLowerCase() === normalizedLabel.toLowerCase());
|
|
11
|
+
if (duplicate) {
|
|
12
|
+
input.logger.warn("registry.duplicate_label", {
|
|
13
|
+
label: normalizedLabel,
|
|
14
|
+
existingAccountId: duplicate.id,
|
|
15
|
+
});
|
|
16
|
+
throw new Error(`An account named "${normalizedLabel}" already exists.`);
|
|
17
|
+
}
|
|
18
|
+
const accountId = randomUUID();
|
|
19
|
+
const record = {
|
|
20
|
+
id: accountId,
|
|
21
|
+
label: normalizedLabel,
|
|
22
|
+
authDirectory: details.authDirectory ?? path.join(input.accountRoot, accountId),
|
|
23
|
+
createdAt: now,
|
|
24
|
+
updatedAt: now,
|
|
25
|
+
lastUsedAt: null,
|
|
26
|
+
};
|
|
27
|
+
document.accounts.push(record);
|
|
28
|
+
if (!document.defaultAccountId) {
|
|
29
|
+
document.defaultAccountId = record.id;
|
|
30
|
+
}
|
|
31
|
+
input.logger.info("registry.account_added", {
|
|
32
|
+
accountId: record.id,
|
|
33
|
+
label: record.label,
|
|
34
|
+
authDirectory: record.authDirectory,
|
|
35
|
+
defaultAccountId: document.defaultAccountId,
|
|
36
|
+
});
|
|
37
|
+
return record;
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
async getDefaultAccount() {
|
|
41
|
+
const document = await readRegistryDocument(input);
|
|
42
|
+
const account = document.defaultAccountId
|
|
43
|
+
? document.accounts.find((entry) => entry.id === document.defaultAccountId) ?? null
|
|
44
|
+
: null;
|
|
45
|
+
input.logger.debug("registry.default_loaded", {
|
|
46
|
+
defaultAccountId: document.defaultAccountId,
|
|
47
|
+
resolvedAccountId: account?.id ?? null,
|
|
48
|
+
});
|
|
49
|
+
return account;
|
|
50
|
+
},
|
|
51
|
+
async listAccounts() {
|
|
52
|
+
const document = await readRegistryDocument(input);
|
|
53
|
+
input.logger.debug("registry.list_loaded", {
|
|
54
|
+
accountCount: document.accounts.length,
|
|
55
|
+
defaultAccountId: document.defaultAccountId,
|
|
56
|
+
});
|
|
57
|
+
return [...document.accounts];
|
|
58
|
+
},
|
|
59
|
+
removeAccount(accountId) {
|
|
60
|
+
return withRegistryMutation(input, "registry.remove", async (document, now) => {
|
|
61
|
+
const record = document.accounts.find((account) => account.id === accountId);
|
|
62
|
+
if (!record) {
|
|
63
|
+
input.logger.warn("registry.remove_missing", { accountId });
|
|
64
|
+
throw new Error(`Account "${accountId}" was not found.`);
|
|
65
|
+
}
|
|
66
|
+
document.accounts = document.accounts.filter((account) => account.id !== accountId);
|
|
67
|
+
if (document.defaultAccountId === accountId) {
|
|
68
|
+
document.defaultAccountId = document.accounts[0]?.id ?? null;
|
|
69
|
+
}
|
|
70
|
+
record.updatedAt = now;
|
|
71
|
+
input.logger.info("registry.account_removed", {
|
|
72
|
+
accountId,
|
|
73
|
+
nextDefaultAccountId: document.defaultAccountId,
|
|
74
|
+
});
|
|
75
|
+
return record;
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
selectAccount(accountId) {
|
|
79
|
+
return withRegistryMutation(input, "registry.select", async (document, now) => {
|
|
80
|
+
const record = document.accounts.find((account) => account.id === accountId);
|
|
81
|
+
if (!record) {
|
|
82
|
+
input.logger.warn("registry.select_missing", { accountId });
|
|
83
|
+
throw new Error(`Account "${accountId}" was not found.`);
|
|
84
|
+
}
|
|
85
|
+
document.defaultAccountId = record.id;
|
|
86
|
+
record.updatedAt = now;
|
|
87
|
+
record.lastUsedAt = now;
|
|
88
|
+
input.logger.info("registry.account_selected", {
|
|
89
|
+
accountId,
|
|
90
|
+
label: record.label,
|
|
91
|
+
});
|
|
92
|
+
return record;
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function withRegistryMutation(input, operation, mutate) {
|
|
98
|
+
await mkdir(input.accountRoot, { recursive: true });
|
|
99
|
+
await mkdir(path.dirname(input.registryFile), { recursive: true });
|
|
100
|
+
const document = await readRegistryDocument(input);
|
|
101
|
+
const now = new Date().toISOString();
|
|
102
|
+
input.logger.debug(`${operation}.start`, {
|
|
103
|
+
registryFile: input.registryFile,
|
|
104
|
+
accountRoot: input.accountRoot,
|
|
105
|
+
accountCount: document.accounts.length,
|
|
106
|
+
});
|
|
107
|
+
const result = await mutate(document, now);
|
|
108
|
+
await persistRegistryDocument(input, document);
|
|
109
|
+
input.logger.debug(`${operation}.complete`, {
|
|
110
|
+
registryFile: input.registryFile,
|
|
111
|
+
accountCount: document.accounts.length,
|
|
112
|
+
defaultAccountId: document.defaultAccountId,
|
|
113
|
+
});
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
async function readRegistryDocument(input) {
|
|
117
|
+
await mkdir(input.accountRoot, { recursive: true });
|
|
118
|
+
await mkdir(path.dirname(input.registryFile), { recursive: true });
|
|
119
|
+
try {
|
|
120
|
+
const raw = await readFile(input.registryFile, "utf8");
|
|
121
|
+
const parsed = JSON.parse(raw);
|
|
122
|
+
const migrated = migrateRegistryDocument(parsed, input.logger, input.registryFile);
|
|
123
|
+
input.logger.debug("registry.read_success", {
|
|
124
|
+
registryFile: input.registryFile,
|
|
125
|
+
schemaVersion: migrated.schemaVersion,
|
|
126
|
+
accountCount: migrated.accounts.length,
|
|
127
|
+
});
|
|
128
|
+
return migrated;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (isFileMissing(error)) {
|
|
132
|
+
const emptyDocument = createEmptyRegistryDocument();
|
|
133
|
+
input.logger.info("registry.read_missing", {
|
|
134
|
+
registryFile: input.registryFile,
|
|
135
|
+
action: "create_empty_registry",
|
|
136
|
+
});
|
|
137
|
+
await persistRegistryDocument(input, emptyDocument);
|
|
138
|
+
return emptyDocument;
|
|
139
|
+
}
|
|
140
|
+
const normalized = normalizeUnknownError(error);
|
|
141
|
+
const corruptionBackupPath = `${input.registryFile}.corrupt-${Date.now()}`;
|
|
142
|
+
input.logger.warn("registry.read_corrupt", {
|
|
143
|
+
registryFile: input.registryFile,
|
|
144
|
+
corruptionBackupPath,
|
|
145
|
+
message: normalized.message,
|
|
146
|
+
});
|
|
147
|
+
await rename(input.registryFile, corruptionBackupPath).catch(() => undefined);
|
|
148
|
+
const emptyDocument = createEmptyRegistryDocument();
|
|
149
|
+
await persistRegistryDocument(input, emptyDocument);
|
|
150
|
+
return emptyDocument;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function persistRegistryDocument(input, document) {
|
|
154
|
+
const tempFile = `${input.registryFile}.tmp`;
|
|
155
|
+
const serialized = JSON.stringify(document, null, 2);
|
|
156
|
+
await writeFile(tempFile, serialized, "utf8");
|
|
157
|
+
await rename(tempFile, input.registryFile);
|
|
158
|
+
input.logger.debug("registry.write_success", {
|
|
159
|
+
registryFile: input.registryFile,
|
|
160
|
+
bytes: Buffer.byteLength(serialized, "utf8"),
|
|
161
|
+
schemaVersion: document.schemaVersion,
|
|
162
|
+
defaultAccountId: document.defaultAccountId,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function migrateRegistryDocument(value, logger, registryFile) {
|
|
166
|
+
if (!isObject(value)) {
|
|
167
|
+
throw new Error("Registry document is not a JSON object.");
|
|
168
|
+
}
|
|
169
|
+
const schemaVersion = typeof value.schemaVersion === "number" ? value.schemaVersion : 0;
|
|
170
|
+
logger.debug("registry.migration_check", {
|
|
171
|
+
registryFile,
|
|
172
|
+
schemaVersion,
|
|
173
|
+
targetSchemaVersion: REGISTRY_SCHEMA_VERSION,
|
|
174
|
+
});
|
|
175
|
+
if (schemaVersion > REGISTRY_SCHEMA_VERSION) {
|
|
176
|
+
throw new Error(`Registry schema ${schemaVersion} is newer than supported schema ${REGISTRY_SCHEMA_VERSION}.`);
|
|
177
|
+
}
|
|
178
|
+
if (schemaVersion === REGISTRY_SCHEMA_VERSION) {
|
|
179
|
+
return normalizeRegistryDocument(value);
|
|
180
|
+
}
|
|
181
|
+
if (schemaVersion === 0) {
|
|
182
|
+
const migrated = normalizeRegistryDocument({
|
|
183
|
+
schemaVersion: REGISTRY_SCHEMA_VERSION,
|
|
184
|
+
defaultAccountId: value.defaultAccountId ?? null,
|
|
185
|
+
accounts: value.accounts ?? [],
|
|
186
|
+
});
|
|
187
|
+
logger.info("registry.migration_applied", {
|
|
188
|
+
registryFile,
|
|
189
|
+
fromSchemaVersion: 0,
|
|
190
|
+
toSchemaVersion: REGISTRY_SCHEMA_VERSION,
|
|
191
|
+
});
|
|
192
|
+
return migrated;
|
|
193
|
+
}
|
|
194
|
+
throw new Error(`Unsupported registry schema version ${schemaVersion}.`);
|
|
195
|
+
}
|
|
196
|
+
function normalizeRegistryDocument(value) {
|
|
197
|
+
const accounts = Array.isArray(value.accounts)
|
|
198
|
+
? value.accounts.map(normalizeAccountRecord)
|
|
199
|
+
: [];
|
|
200
|
+
const defaultAccountId = typeof value.defaultAccountId === "string"
|
|
201
|
+
? value.defaultAccountId
|
|
202
|
+
: null;
|
|
203
|
+
return {
|
|
204
|
+
schemaVersion: REGISTRY_SCHEMA_VERSION,
|
|
205
|
+
defaultAccountId: defaultAccountId && accounts.some((account) => account.id === defaultAccountId)
|
|
206
|
+
? defaultAccountId
|
|
207
|
+
: accounts[0]?.id ?? null,
|
|
208
|
+
accounts,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function normalizeAccountRecord(value) {
|
|
212
|
+
if (!isObject(value)) {
|
|
213
|
+
throw new Error("Account record is not an object.");
|
|
214
|
+
}
|
|
215
|
+
const id = typeof value.id === "string" ? value.id : randomUUID();
|
|
216
|
+
const createdAt = typeof value.createdAt === "string" ? value.createdAt : new Date(0).toISOString();
|
|
217
|
+
const updatedAt = typeof value.updatedAt === "string" ? value.updatedAt : createdAt;
|
|
218
|
+
return {
|
|
219
|
+
id,
|
|
220
|
+
label: normalizeLabel(typeof value.label === "string" ? value.label : id),
|
|
221
|
+
authDirectory: typeof value.authDirectory === "string" ? value.authDirectory : path.join("accounts", id),
|
|
222
|
+
createdAt,
|
|
223
|
+
updatedAt,
|
|
224
|
+
lastUsedAt: typeof value.lastUsedAt === "string" ? value.lastUsedAt : null,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function createEmptyRegistryDocument() {
|
|
228
|
+
return {
|
|
229
|
+
schemaVersion: REGISTRY_SCHEMA_VERSION,
|
|
230
|
+
defaultAccountId: null,
|
|
231
|
+
accounts: [],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function normalizeLabel(label) {
|
|
235
|
+
const normalized = label.trim();
|
|
236
|
+
if (!normalized) {
|
|
237
|
+
throw new Error("Account label cannot be empty.");
|
|
238
|
+
}
|
|
239
|
+
return normalized;
|
|
240
|
+
}
|
|
241
|
+
function isObject(value) {
|
|
242
|
+
return typeof value === "object" && value !== null;
|
|
243
|
+
}
|
|
244
|
+
function isFileMissing(error) {
|
|
245
|
+
return (typeof error === "object" &&
|
|
246
|
+
error !== null &&
|
|
247
|
+
"code" in error &&
|
|
248
|
+
error.code === "ENOENT");
|
|
249
|
+
}
|
|
250
|
+
function normalizeUnknownError(error) {
|
|
251
|
+
if (error instanceof Error) {
|
|
252
|
+
return { message: error.message };
|
|
253
|
+
}
|
|
254
|
+
return { message: String(error) };
|
|
255
|
+
}
|
|
256
|
+
export async function deleteRegistryFile(registryFile) {
|
|
257
|
+
const fileStats = await stat(registryFile).catch(() => null);
|
|
258
|
+
if (!fileStats) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
await rm(registryFile, { force: true });
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=account-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-registry.js","sourceRoot":"","sources":["../../src/accounts/account-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AccountRecord } from "./account-registry.js";
|
|
2
|
+
import type { Logger } from "../logging/logger.js";
|
|
3
|
+
export interface AccountPresentation {
|
|
4
|
+
account: AccountRecord;
|
|
5
|
+
authAccountId: string | null;
|
|
6
|
+
authMode: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveAccountBySelector(input: {
|
|
9
|
+
accounts: AccountRecord[];
|
|
10
|
+
logger: Logger;
|
|
11
|
+
selector: string;
|
|
12
|
+
}): AccountRecord;
|
|
13
|
+
export declare function buildAccountPresentations(input: {
|
|
14
|
+
accounts: AccountRecord[];
|
|
15
|
+
logger: Logger;
|
|
16
|
+
}): Promise<AccountPresentation[]>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function resolveAccountBySelector(input) {
|
|
4
|
+
const normalizedSelector = input.selector.trim();
|
|
5
|
+
const matches = input.accounts.filter((account) => account.id === normalizedSelector ||
|
|
6
|
+
account.label.toLowerCase() === normalizedSelector.toLowerCase());
|
|
7
|
+
input.logger.debug("account_resolution.lookup", {
|
|
8
|
+
selector: normalizedSelector,
|
|
9
|
+
accountCount: input.accounts.length,
|
|
10
|
+
matchCount: matches.length,
|
|
11
|
+
matchedAccountIds: matches.map((account) => account.id),
|
|
12
|
+
});
|
|
13
|
+
if (matches.length === 0) {
|
|
14
|
+
throw new Error(`No account matches "${normalizedSelector}".`);
|
|
15
|
+
}
|
|
16
|
+
if (matches.length > 1) {
|
|
17
|
+
throw new Error(`Selector "${normalizedSelector}" matched multiple accounts; use the account id instead.`);
|
|
18
|
+
}
|
|
19
|
+
const [match] = matches;
|
|
20
|
+
if (!match) {
|
|
21
|
+
throw new Error(`No account matches "${normalizedSelector}".`);
|
|
22
|
+
}
|
|
23
|
+
return match;
|
|
24
|
+
}
|
|
25
|
+
export async function buildAccountPresentations(input) {
|
|
26
|
+
const presentations = [];
|
|
27
|
+
for (const account of input.accounts) {
|
|
28
|
+
presentations.push({
|
|
29
|
+
account,
|
|
30
|
+
...(await readAccountMetadataSummary(account, input.logger)),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return presentations;
|
|
34
|
+
}
|
|
35
|
+
async function readAccountMetadataSummary(account, logger) {
|
|
36
|
+
const metadataFile = path.join(account.authDirectory, "account.json");
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(metadataFile, "utf8");
|
|
39
|
+
const parsed = JSON.parse(raw);
|
|
40
|
+
const summary = {
|
|
41
|
+
authAccountId: typeof parsed.authAccountId === "string" ? parsed.authAccountId : null,
|
|
42
|
+
authMode: typeof parsed.authMode === "string" ? parsed.authMode : null,
|
|
43
|
+
};
|
|
44
|
+
logger.debug("account_resolution.metadata_loaded", {
|
|
45
|
+
accountId: account.id,
|
|
46
|
+
metadataFile,
|
|
47
|
+
authAccountId: summary.authAccountId,
|
|
48
|
+
authMode: summary.authMode,
|
|
49
|
+
});
|
|
50
|
+
return summary;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (typeof error === "object" &&
|
|
54
|
+
error !== null &&
|
|
55
|
+
"code" in error &&
|
|
56
|
+
error.code === "ENOENT") {
|
|
57
|
+
logger.debug("account_resolution.metadata_missing", {
|
|
58
|
+
accountId: account.id,
|
|
59
|
+
metadataFile,
|
|
60
|
+
});
|
|
61
|
+
return { authAccountId: null, authMode: null };
|
|
62
|
+
}
|
|
63
|
+
logger.warn("account_resolution.metadata_failed", {
|
|
64
|
+
accountId: account.id,
|
|
65
|
+
metadataFile,
|
|
66
|
+
message: error instanceof Error ? error.message : String(error),
|
|
67
|
+
});
|
|
68
|
+
return { authAccountId: null, authMode: null };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=account-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-resolution.js","sourceRoot":"","sources":["../../src/accounts/account-resolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export async function resolveActiveAccount(input) {
|
|
2
|
+
const accounts = await input.registry.listAccounts();
|
|
3
|
+
if (accounts.length === 0) {
|
|
4
|
+
input.logger.warn("active_account.none");
|
|
5
|
+
throw new Error("No accounts configured. Add one with `codexes account add <label>`.");
|
|
6
|
+
}
|
|
7
|
+
const defaultAccount = await input.registry.getDefaultAccount();
|
|
8
|
+
if (defaultAccount) {
|
|
9
|
+
input.logger.info("active_account.default_selected", {
|
|
10
|
+
accountId: defaultAccount.id,
|
|
11
|
+
label: defaultAccount.label,
|
|
12
|
+
accountCount: accounts.length,
|
|
13
|
+
});
|
|
14
|
+
return defaultAccount;
|
|
15
|
+
}
|
|
16
|
+
if (accounts.length === 1) {
|
|
17
|
+
const [singleAccount] = accounts;
|
|
18
|
+
if (!singleAccount) {
|
|
19
|
+
throw new Error("No accounts configured.");
|
|
20
|
+
}
|
|
21
|
+
input.logger.info("active_account.single_account_selected", {
|
|
22
|
+
accountId: singleAccount.id,
|
|
23
|
+
label: singleAccount.label,
|
|
24
|
+
});
|
|
25
|
+
return input.registry.selectAccount(singleAccount.id);
|
|
26
|
+
}
|
|
27
|
+
input.logger.warn("active_account.missing_default", {
|
|
28
|
+
accountCount: accounts.length,
|
|
29
|
+
});
|
|
30
|
+
throw new Error("Multiple accounts are configured but no default account is selected. Use `codexes account use <account-id-or-label>` first.");
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=resolve-active-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-active-account.js","sourceRoot":"","sources":["../../src/accounts/resolve-active-account.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAG1C;IACC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;IAErD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAChE,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE;YACnD,SAAS,EAAE,cAAc,CAAC,EAAE;YAC5B,KAAK,EAAE,cAAc,CAAC,KAAK;YAC3B,YAAY,EAAE,QAAQ,CAAC,MAAM;SAC9B,CAAC,CAAC;QACH,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;QACjC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;YAC1D,SAAS,EAAE,aAAa,CAAC,EAAE;YAC3B,KAAK,EAAE,aAAa,CAAC,KAAK;SAC3B,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;QAClD,YAAY,EAAE,QAAQ,CAAC,MAAM;KAC9B,CAAC,CAAC;IACH,MAAM,IAAI,KAAK,CACb,6HAA6H,CAC9H,CAAC;AACJ,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|