@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.
Files changed (96) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +88 -0
  3. package/dist/accounts/account-registry.d.ts +30 -0
  4. package/dist/accounts/account-registry.js +263 -0
  5. package/dist/accounts/account-registry.js.map +1 -0
  6. package/dist/accounts/account-resolution.d.ts +16 -0
  7. package/dist/accounts/account-resolution.js +71 -0
  8. package/dist/accounts/account-resolution.js.map +1 -0
  9. package/dist/accounts/resolve-active-account.d.ts +6 -0
  10. package/dist/accounts/resolve-active-account.js +32 -0
  11. package/dist/accounts/resolve-active-account.js.map +1 -0
  12. package/dist/cli.d.ts +1 -0
  13. package/dist/cli.js +3426 -0
  14. package/dist/cli.js.map +7 -0
  15. package/dist/commands/account-add/run-account-add-command.d.ts +2 -0
  16. package/dist/commands/account-add/run-account-add-command.js +296 -0
  17. package/dist/commands/account-add/run-account-add-command.js.map +1 -0
  18. package/dist/commands/account-list/run-account-list-command.d.ts +2 -0
  19. package/dist/commands/account-list/run-account-list-command.js +48 -0
  20. package/dist/commands/account-list/run-account-list-command.js.map +1 -0
  21. package/dist/commands/account-remove/run-account-remove-command.d.ts +2 -0
  22. package/dist/commands/account-remove/run-account-remove-command.js +52 -0
  23. package/dist/commands/account-remove/run-account-remove-command.js.map +1 -0
  24. package/dist/commands/account-use/run-account-use-command.d.ts +2 -0
  25. package/dist/commands/account-use/run-account-use-command.js +78 -0
  26. package/dist/commands/account-use/run-account-use-command.js.map +1 -0
  27. package/dist/commands/root/run-root-command.d.ts +2 -0
  28. package/dist/commands/root/run-root-command.js +175 -0
  29. package/dist/commands/root/run-root-command.js.map +1 -0
  30. package/dist/config/wrapper-config.d.ts +24 -0
  31. package/dist/config/wrapper-config.js +145 -0
  32. package/dist/config/wrapper-config.js.map +1 -0
  33. package/dist/core/bootstrap.d.ts +8 -0
  34. package/dist/core/bootstrap.js +32 -0
  35. package/dist/core/bootstrap.js.map +1 -0
  36. package/dist/core/context.d.ts +33 -0
  37. package/dist/core/context.js +72 -0
  38. package/dist/core/context.js.map +1 -0
  39. package/dist/core/paths.d.ts +12 -0
  40. package/dist/core/paths.js +30 -0
  41. package/dist/core/paths.js.map +1 -0
  42. package/dist/logging/logger.d.ts +18 -0
  43. package/dist/logging/logger.js +56 -0
  44. package/dist/logging/logger.js.map +1 -0
  45. package/dist/process/codex-launch-spec.d.ts +5 -0
  46. package/dist/process/codex-launch-spec.js +80 -0
  47. package/dist/process/codex-launch-spec.js.map +1 -0
  48. package/dist/process/find-codex-binary.d.ts +14 -0
  49. package/dist/process/find-codex-binary.js +73 -0
  50. package/dist/process/find-codex-binary.js.map +1 -0
  51. package/dist/process/run-codex-login.d.ts +14 -0
  52. package/dist/process/run-codex-login.js +97 -0
  53. package/dist/process/run-codex-login.js.map +1 -0
  54. package/dist/process/spawn-codex-command.d.ts +7 -0
  55. package/dist/process/spawn-codex-command.js +69 -0
  56. package/dist/process/spawn-codex-command.js.map +1 -0
  57. package/dist/runtime/activate-account/activate-account.d.ts +27 -0
  58. package/dist/runtime/activate-account/activate-account.js +298 -0
  59. package/dist/runtime/activate-account/activate-account.js.map +1 -0
  60. package/dist/runtime/auth-state-probe.d.ts +57 -0
  61. package/dist/runtime/auth-state-probe.js +394 -0
  62. package/dist/runtime/auth-state-probe.js.map +1 -0
  63. package/dist/runtime/init/initialize-runtime.d.ts +19 -0
  64. package/dist/runtime/init/initialize-runtime.js +275 -0
  65. package/dist/runtime/init/initialize-runtime.js.map +1 -0
  66. package/dist/runtime/lock/runtime-lock.d.ts +11 -0
  67. package/dist/runtime/lock/runtime-lock.js +99 -0
  68. package/dist/runtime/lock/runtime-lock.js.map +1 -0
  69. package/dist/runtime/login-workspace.d.ts +18 -0
  70. package/dist/runtime/login-workspace.js +171 -0
  71. package/dist/runtime/login-workspace.js.map +1 -0
  72. package/dist/runtime/runtime-contract.d.ts +44 -0
  73. package/dist/runtime/runtime-contract.js +79 -0
  74. package/dist/runtime/runtime-contract.js.map +1 -0
  75. package/dist/selection/account-auth-state.d.ts +23 -0
  76. package/dist/selection/account-auth-state.js +132 -0
  77. package/dist/selection/account-auth-state.js.map +1 -0
  78. package/dist/selection/select-account.d.ts +11 -0
  79. package/dist/selection/select-account.js +168 -0
  80. package/dist/selection/select-account.js.map +1 -0
  81. package/dist/selection/usage-cache.d.ts +24 -0
  82. package/dist/selection/usage-cache.js +106 -0
  83. package/dist/selection/usage-cache.js.map +1 -0
  84. package/dist/selection/usage-client.d.ts +23 -0
  85. package/dist/selection/usage-client.js +143 -0
  86. package/dist/selection/usage-client.js.map +1 -0
  87. package/dist/selection/usage-normalize.d.ts +7 -0
  88. package/dist/selection/usage-normalize.js +209 -0
  89. package/dist/selection/usage-normalize.js.map +1 -0
  90. package/dist/selection/usage-probe-coordinator.d.ts +18 -0
  91. package/dist/selection/usage-probe-coordinator.js +69 -0
  92. package/dist/selection/usage-probe-coordinator.js.map +1 -0
  93. package/dist/selection/usage-types.d.ts +59 -0
  94. package/dist/selection/usage-types.js +2 -0
  95. package/dist/selection/usage-types.js.map +1 -0
  96. 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,6 @@
1
+ import type { AccountRegistry, AccountRecord } from "./account-registry.js";
2
+ import type { Logger } from "../logging/logger.js";
3
+ export declare function resolveActiveAccount(input: {
4
+ logger: Logger;
5
+ registry: AccountRegistry;
6
+ }): Promise<AccountRecord>;
@@ -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 {};