oc-codex-multi-account 1.0.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/README.md +321 -0
- package/dist/auth-sync.d.ts +3 -0
- package/dist/auth-sync.d.ts.map +1 -0
- package/dist/auth-sync.js +105 -0
- package/dist/auth-sync.js.map +1 -0
- package/dist/auth.d.ts +15 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +236 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +160 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-auth.d.ts +28 -0
- package/dist/codex-auth.d.ts.map +1 -0
- package/dist/codex-auth.js +174 -0
- package/dist/codex-auth.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +730 -0
- package/dist/index.js.map +1 -0
- package/dist/limits-refresh.d.ts +9 -0
- package/dist/limits-refresh.d.ts.map +1 -0
- package/dist/limits-refresh.js +48 -0
- package/dist/limits-refresh.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +52 -0
- package/dist/logger.js.map +1 -0
- package/dist/models.d.ts +7 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +121 -0
- package/dist/models.js.map +1 -0
- package/dist/probe-limits.d.ts +10 -0
- package/dist/probe-limits.d.ts.map +1 -0
- package/dist/probe-limits.js +160 -0
- package/dist/probe-limits.js.map +1 -0
- package/dist/rate-limits.d.ts +6 -0
- package/dist/rate-limits.d.ts.map +1 -0
- package/dist/rate-limits.js +117 -0
- package/dist/rate-limits.js.map +1 -0
- package/dist/refresh-queue.d.ts +18 -0
- package/dist/refresh-queue.d.ts.map +1 -0
- package/dist/refresh-queue.js +78 -0
- package/dist/refresh-queue.js.map +1 -0
- package/dist/rotation.d.ts +20 -0
- package/dist/rotation.d.ts.map +1 -0
- package/dist/rotation.js +273 -0
- package/dist/rotation.js.map +1 -0
- package/dist/sessions-limits.d.ts +11 -0
- package/dist/sessions-limits.d.ts.map +1 -0
- package/dist/sessions-limits.js +123 -0
- package/dist/sessions-limits.js.map +1 -0
- package/dist/store.d.ts +23 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +339 -0
- package/dist/store.js.map +1 -0
- package/dist/systemd.d.ts +10 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +53 -0
- package/dist/systemd.js.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/web.d.ts +6 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +1857 -0
- package/dist/web.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
const DEFAULT_SESSIONS_DIR = path.join(os.homedir(), '.codex', 'sessions');
|
|
5
|
+
function toEpochMs(value) {
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return undefined;
|
|
8
|
+
if (value > 1e12)
|
|
9
|
+
return value;
|
|
10
|
+
if (value > 1e9)
|
|
11
|
+
return value * 1000;
|
|
12
|
+
return value * 1000;
|
|
13
|
+
}
|
|
14
|
+
function parseTimestamp(value) {
|
|
15
|
+
if (!value)
|
|
16
|
+
return undefined;
|
|
17
|
+
const parsed = Date.parse(value);
|
|
18
|
+
if (Number.isNaN(parsed))
|
|
19
|
+
return undefined;
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
function isWeekly(limit) {
|
|
23
|
+
const minutes = limit?.window_minutes;
|
|
24
|
+
if (!minutes)
|
|
25
|
+
return false;
|
|
26
|
+
return minutes >= 1000;
|
|
27
|
+
}
|
|
28
|
+
function buildWindow(limit, eventTs) {
|
|
29
|
+
if (!limit)
|
|
30
|
+
return undefined;
|
|
31
|
+
const used = limit.used_percent;
|
|
32
|
+
const remaining = typeof used === 'number' ? Math.max(0, 100 - used) : undefined;
|
|
33
|
+
const resetAt = toEpochMs(limit.resets_at ?? limit.reset_at) ??
|
|
34
|
+
(typeof limit.resets_in_seconds === 'number' && eventTs
|
|
35
|
+
? eventTs + limit.resets_in_seconds * 1000
|
|
36
|
+
: undefined);
|
|
37
|
+
return {
|
|
38
|
+
limit: 100,
|
|
39
|
+
remaining,
|
|
40
|
+
resetAt,
|
|
41
|
+
updatedAt: eventTs
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function listSessionFiles(dir) {
|
|
45
|
+
const entries = [];
|
|
46
|
+
if (!fs.existsSync(dir))
|
|
47
|
+
return entries;
|
|
48
|
+
const stack = [dir];
|
|
49
|
+
while (stack.length > 0) {
|
|
50
|
+
const current = stack.pop();
|
|
51
|
+
if (!current)
|
|
52
|
+
continue;
|
|
53
|
+
const items = fs.readdirSync(current, { withFileTypes: true });
|
|
54
|
+
for (const item of items) {
|
|
55
|
+
const fullPath = path.join(current, item.name);
|
|
56
|
+
if (item.isDirectory()) {
|
|
57
|
+
stack.push(fullPath);
|
|
58
|
+
}
|
|
59
|
+
else if (item.isFile() && item.name.endsWith('.jsonl')) {
|
|
60
|
+
const stat = fs.statSync(fullPath);
|
|
61
|
+
entries.push({ path: fullPath, mtimeMs: stat.mtimeMs });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return entries.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
66
|
+
}
|
|
67
|
+
function parseLatestTokenCountFromFile(filePath, options) {
|
|
68
|
+
let contents = '';
|
|
69
|
+
try {
|
|
70
|
+
contents = fs.readFileSync(filePath, 'utf-8');
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const lines = contents.split('\n').filter(Boolean);
|
|
76
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
77
|
+
let parsed = null;
|
|
78
|
+
try {
|
|
79
|
+
parsed = JSON.parse(lines[i]);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const payload = parsed?.payload;
|
|
85
|
+
if (payload?.type !== 'token_count')
|
|
86
|
+
continue;
|
|
87
|
+
const eventTs = parseTimestamp(parsed.timestamp);
|
|
88
|
+
if (!eventTs)
|
|
89
|
+
continue;
|
|
90
|
+
if (options?.sinceMs && eventTs < options.sinceMs)
|
|
91
|
+
continue;
|
|
92
|
+
if (options?.untilMs && eventTs > options.untilMs)
|
|
93
|
+
continue;
|
|
94
|
+
const primary = payload.rate_limits?.primary;
|
|
95
|
+
const secondary = payload.rate_limits?.secondary;
|
|
96
|
+
const fiveHour = isWeekly(primary) ? secondary : primary;
|
|
97
|
+
const weekly = isWeekly(primary) ? primary : secondary;
|
|
98
|
+
return {
|
|
99
|
+
eventTs,
|
|
100
|
+
rateLimits: {
|
|
101
|
+
fiveHour: buildWindow(fiveHour, eventTs),
|
|
102
|
+
weekly: buildWindow(weekly, eventTs)
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
export function findLatestSessionRateLimits(options) {
|
|
109
|
+
const sessionsDir = options?.sessionsDir || DEFAULT_SESSIONS_DIR;
|
|
110
|
+
const files = listSessionFiles(sessionsDir);
|
|
111
|
+
for (const file of files) {
|
|
112
|
+
const parsed = parseLatestTokenCountFromFile(file.path, options);
|
|
113
|
+
if (parsed?.rateLimits) {
|
|
114
|
+
return {
|
|
115
|
+
rateLimits: parsed.rateLimits,
|
|
116
|
+
eventTs: parsed.eventTs,
|
|
117
|
+
sourceFile: file.path
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=sessions-limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions-limits.js","sourceRoot":"","sources":["../src/sessions-limits.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AccountStore, AccountCredentials } from './types.js';
|
|
2
|
+
export declare function loadStore(): AccountStore;
|
|
3
|
+
export declare function saveStore(store: AccountStore): void;
|
|
4
|
+
export declare function getStoreDiagnostics(): {
|
|
5
|
+
storeDir: string;
|
|
6
|
+
storeFile: string;
|
|
7
|
+
locked: boolean;
|
|
8
|
+
encrypted: boolean;
|
|
9
|
+
error: string | null;
|
|
10
|
+
};
|
|
11
|
+
export declare function addAccount(alias: string, creds: Omit<AccountCredentials, 'alias' | 'usageCount'>): AccountStore;
|
|
12
|
+
export declare function removeAccount(alias: string): AccountStore;
|
|
13
|
+
export declare function updateAccount(alias: string, updates: Partial<AccountCredentials>): AccountStore;
|
|
14
|
+
export declare function setActiveAlias(alias: string | null): AccountStore;
|
|
15
|
+
export declare function getActiveAccount(): AccountCredentials | null;
|
|
16
|
+
export declare function listAccounts(): AccountCredentials[];
|
|
17
|
+
export declare function getStorePath(): string;
|
|
18
|
+
export declare function getStoreStatus(): {
|
|
19
|
+
locked: boolean;
|
|
20
|
+
encrypted: boolean;
|
|
21
|
+
error: string | null;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,YAAY,CAAA;AAwJnB,wBAAgB,SAAS,IAAI,YAAY,CAoCxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAqEnD;AAED,wBAAgB,mBAAmB,IAAI;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB,CAQA;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG,YAAY,CAc/G;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAe/F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,CA+BjE;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,GAAG,IAAI,CAI5D;AAED,wBAAgB,YAAY,IAAI,kBAAkB,EAAE,CAGnD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAG9F"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as crypto from 'node:crypto';
|
|
5
|
+
const STORE_DIR_ENV = 'OPENCODE_MULTI_AUTH_STORE_DIR';
|
|
6
|
+
const STORE_FILE_ENV = 'OPENCODE_MULTI_AUTH_STORE_FILE';
|
|
7
|
+
const DEFAULT_STORE_DIR = path.join(os.homedir(), '.config', 'oc-codex-multi-account');
|
|
8
|
+
const DEFAULT_STORE_FILE = 'accounts.json';
|
|
9
|
+
const LEGACY_STORE_FILE = path.join(os.homedir(), '.config', 'opencode-multi-auth', 'accounts.json');
|
|
10
|
+
function getStoreDir() {
|
|
11
|
+
const override = process.env[STORE_DIR_ENV];
|
|
12
|
+
if (override && override.trim())
|
|
13
|
+
return path.resolve(override.trim());
|
|
14
|
+
return DEFAULT_STORE_DIR;
|
|
15
|
+
}
|
|
16
|
+
function getStoreFile() {
|
|
17
|
+
const override = process.env[STORE_FILE_ENV];
|
|
18
|
+
if (override && override.trim())
|
|
19
|
+
return path.resolve(override.trim());
|
|
20
|
+
return path.join(getStoreDir(), DEFAULT_STORE_FILE);
|
|
21
|
+
}
|
|
22
|
+
const STORE_ENV_PASSPHRASE = 'CODEX_SOFT_STORE_PASSPHRASE';
|
|
23
|
+
const STORE_VERSION = 1;
|
|
24
|
+
let storeLocked = false;
|
|
25
|
+
let lastStoreError = null;
|
|
26
|
+
let lastStoreEncrypted = false;
|
|
27
|
+
function ensureDir() {
|
|
28
|
+
const dir = getStoreDir();
|
|
29
|
+
if (!fs.existsSync(dir)) {
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function migrateLegacyStoreIfNeeded() {
|
|
34
|
+
const target = getStoreFile();
|
|
35
|
+
if (fs.existsSync(target))
|
|
36
|
+
return;
|
|
37
|
+
if (!fs.existsSync(LEGACY_STORE_FILE))
|
|
38
|
+
return;
|
|
39
|
+
try {
|
|
40
|
+
fs.copyFileSync(LEGACY_STORE_FILE, target);
|
|
41
|
+
fs.chmodSync(target, 0o600);
|
|
42
|
+
console.log(`[multi-auth] Migrated credentials store to ${target}`);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.error('[multi-auth] Failed to migrate legacy credentials store:', err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function emptyStore() {
|
|
49
|
+
return {
|
|
50
|
+
accounts: {},
|
|
51
|
+
activeAlias: null,
|
|
52
|
+
rotationIndex: 0,
|
|
53
|
+
lastRotation: Date.now()
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function getPassphrase() {
|
|
57
|
+
const value = process.env[STORE_ENV_PASSPHRASE];
|
|
58
|
+
return value && value.trim().length > 0 ? value : null;
|
|
59
|
+
}
|
|
60
|
+
function isEncryptedFile(payload) {
|
|
61
|
+
return Boolean(payload && payload.encrypted === true && typeof payload.data === 'string');
|
|
62
|
+
}
|
|
63
|
+
function deriveKey(passphrase, salt) {
|
|
64
|
+
return crypto.scryptSync(passphrase, salt, 32);
|
|
65
|
+
}
|
|
66
|
+
function encryptStore(store, passphrase) {
|
|
67
|
+
const salt = crypto.randomBytes(16);
|
|
68
|
+
const iv = crypto.randomBytes(12);
|
|
69
|
+
const key = deriveKey(passphrase, salt);
|
|
70
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
71
|
+
const serialized = JSON.stringify(store);
|
|
72
|
+
const encrypted = Buffer.concat([cipher.update(serialized, 'utf8'), cipher.final()]);
|
|
73
|
+
const tag = cipher.getAuthTag();
|
|
74
|
+
return {
|
|
75
|
+
encrypted: true,
|
|
76
|
+
version: STORE_VERSION,
|
|
77
|
+
salt: salt.toString('base64'),
|
|
78
|
+
iv: iv.toString('base64'),
|
|
79
|
+
tag: tag.toString('base64'),
|
|
80
|
+
data: encrypted.toString('base64')
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function decryptStore(file, passphrase) {
|
|
84
|
+
const salt = Buffer.from(file.salt, 'base64');
|
|
85
|
+
const iv = Buffer.from(file.iv, 'base64');
|
|
86
|
+
const tag = Buffer.from(file.tag, 'base64');
|
|
87
|
+
const data = Buffer.from(file.data, 'base64');
|
|
88
|
+
const key = deriveKey(passphrase, salt);
|
|
89
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
90
|
+
decipher.setAuthTag(tag);
|
|
91
|
+
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8');
|
|
92
|
+
return JSON.parse(decrypted);
|
|
93
|
+
}
|
|
94
|
+
function buildSnapshot(window) {
|
|
95
|
+
if (!window)
|
|
96
|
+
return undefined;
|
|
97
|
+
return {
|
|
98
|
+
remaining: window.remaining,
|
|
99
|
+
limit: window.limit,
|
|
100
|
+
resetAt: window.resetAt
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function buildHistoryEntry(rateLimits) {
|
|
104
|
+
if (!rateLimits?.fiveHour && !rateLimits?.weekly)
|
|
105
|
+
return null;
|
|
106
|
+
const updatedAtValues = [rateLimits?.fiveHour?.updatedAt, rateLimits?.weekly?.updatedAt].filter((value) => typeof value === 'number');
|
|
107
|
+
const at = updatedAtValues.length > 0 ? Math.max(...updatedAtValues) : Date.now();
|
|
108
|
+
return {
|
|
109
|
+
at,
|
|
110
|
+
fiveHour: buildSnapshot(rateLimits?.fiveHour),
|
|
111
|
+
weekly: buildSnapshot(rateLimits?.weekly)
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function appendHistory(history, entry) {
|
|
115
|
+
const next = history ? [...history] : [];
|
|
116
|
+
const last = next[next.length - 1];
|
|
117
|
+
const same = last &&
|
|
118
|
+
last.fiveHour?.remaining === entry.fiveHour?.remaining &&
|
|
119
|
+
last.weekly?.remaining === entry.weekly?.remaining &&
|
|
120
|
+
last.fiveHour?.resetAt === entry.fiveHour?.resetAt &&
|
|
121
|
+
last.weekly?.resetAt === entry.weekly?.resetAt;
|
|
122
|
+
if (!same) {
|
|
123
|
+
next.push(entry);
|
|
124
|
+
}
|
|
125
|
+
if (next.length > 160) {
|
|
126
|
+
return next.slice(next.length - 160);
|
|
127
|
+
}
|
|
128
|
+
return next;
|
|
129
|
+
}
|
|
130
|
+
export function loadStore() {
|
|
131
|
+
storeLocked = false;
|
|
132
|
+
lastStoreError = null;
|
|
133
|
+
lastStoreEncrypted = false;
|
|
134
|
+
ensureDir();
|
|
135
|
+
migrateLegacyStoreIfNeeded();
|
|
136
|
+
const file = getStoreFile();
|
|
137
|
+
if (fs.existsSync(file)) {
|
|
138
|
+
try {
|
|
139
|
+
const data = fs.readFileSync(file, 'utf-8');
|
|
140
|
+
const parsed = JSON.parse(data);
|
|
141
|
+
if (isEncryptedFile(parsed)) {
|
|
142
|
+
lastStoreEncrypted = true;
|
|
143
|
+
const passphrase = getPassphrase();
|
|
144
|
+
if (!passphrase) {
|
|
145
|
+
storeLocked = true;
|
|
146
|
+
lastStoreError = `Store is encrypted. Set ${STORE_ENV_PASSPHRASE} to unlock.`;
|
|
147
|
+
return emptyStore();
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
return decryptStore(parsed, passphrase);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
storeLocked = true;
|
|
154
|
+
lastStoreError = 'Failed to decrypt store. Check passphrase.';
|
|
155
|
+
console.error('[multi-auth] Failed to decrypt store:', err);
|
|
156
|
+
return emptyStore();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return parsed;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
storeLocked = true;
|
|
163
|
+
lastStoreError = 'Failed to parse store. Store locked until fixed.';
|
|
164
|
+
console.error('[multi-auth] Failed to parse store, resetting');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return emptyStore();
|
|
168
|
+
}
|
|
169
|
+
export function saveStore(store) {
|
|
170
|
+
ensureDir();
|
|
171
|
+
if (storeLocked) {
|
|
172
|
+
console.error('[multi-auth] Store locked; refusing to overwrite encrypted file.');
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const file = getStoreFile();
|
|
176
|
+
const passphrase = getPassphrase();
|
|
177
|
+
const payload = passphrase ? encryptStore(store, passphrase) : store;
|
|
178
|
+
const json = JSON.stringify(payload, null, 2);
|
|
179
|
+
// Best-effort backup to help recover from crashes/corruption.
|
|
180
|
+
try {
|
|
181
|
+
if (fs.existsSync(file)) {
|
|
182
|
+
fs.copyFileSync(file, `${file}.bak`);
|
|
183
|
+
fs.chmodSync(`${file}.bak`, 0o600);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// ignore backup failures
|
|
188
|
+
}
|
|
189
|
+
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
190
|
+
let fd = null;
|
|
191
|
+
try {
|
|
192
|
+
fd = fs.openSync(tmp, 'w', 0o600);
|
|
193
|
+
fs.writeFileSync(fd, json, { encoding: 'utf-8' });
|
|
194
|
+
try {
|
|
195
|
+
fs.fsyncSync(fd);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// fsync not supported everywhere; best-effort
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
if (fd !== null) {
|
|
203
|
+
try {
|
|
204
|
+
fs.closeSync(fd);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// ignore
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
fs.renameSync(tmp, file);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
// Windows can fail to rename over an existing file.
|
|
216
|
+
if (err?.code === 'EPERM' || err?.code === 'EEXIST') {
|
|
217
|
+
try {
|
|
218
|
+
fs.unlinkSync(file);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// ignore
|
|
222
|
+
}
|
|
223
|
+
fs.renameSync(tmp, file);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
try {
|
|
227
|
+
fs.unlinkSync(tmp);
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// ignore
|
|
231
|
+
}
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
fs.chmodSync(file, 0o600);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// ignore
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export function getStoreDiagnostics() {
|
|
243
|
+
return {
|
|
244
|
+
storeDir: getStoreDir(),
|
|
245
|
+
storeFile: getStoreFile(),
|
|
246
|
+
locked: storeLocked,
|
|
247
|
+
encrypted: lastStoreEncrypted,
|
|
248
|
+
error: lastStoreError
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
export function addAccount(alias, creds) {
|
|
252
|
+
const store = loadStore();
|
|
253
|
+
const entry = buildHistoryEntry(creds.rateLimits);
|
|
254
|
+
store.accounts[alias] = {
|
|
255
|
+
...creds,
|
|
256
|
+
alias,
|
|
257
|
+
usageCount: 0,
|
|
258
|
+
rateLimitHistory: entry ? [entry] : creds.rateLimitHistory
|
|
259
|
+
};
|
|
260
|
+
if (!store.activeAlias) {
|
|
261
|
+
store.activeAlias = alias;
|
|
262
|
+
}
|
|
263
|
+
saveStore(store);
|
|
264
|
+
return store;
|
|
265
|
+
}
|
|
266
|
+
export function removeAccount(alias) {
|
|
267
|
+
const store = loadStore();
|
|
268
|
+
delete store.accounts[alias];
|
|
269
|
+
if (store.activeAlias === alias) {
|
|
270
|
+
const remaining = Object.keys(store.accounts);
|
|
271
|
+
store.activeAlias = remaining[0] || null;
|
|
272
|
+
}
|
|
273
|
+
saveStore(store);
|
|
274
|
+
return store;
|
|
275
|
+
}
|
|
276
|
+
export function updateAccount(alias, updates) {
|
|
277
|
+
const store = loadStore();
|
|
278
|
+
if (store.accounts[alias]) {
|
|
279
|
+
const current = store.accounts[alias];
|
|
280
|
+
const next = { ...current, ...updates };
|
|
281
|
+
if (updates.rateLimits || next.rateLimits) {
|
|
282
|
+
const entry = buildHistoryEntry(next.rateLimits);
|
|
283
|
+
if (entry) {
|
|
284
|
+
next.rateLimitHistory = appendHistory(current.rateLimitHistory, entry);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
store.accounts[alias] = next;
|
|
288
|
+
saveStore(store);
|
|
289
|
+
}
|
|
290
|
+
return store;
|
|
291
|
+
}
|
|
292
|
+
export function setActiveAlias(alias) {
|
|
293
|
+
const store = loadStore();
|
|
294
|
+
const now = Date.now();
|
|
295
|
+
const previousAlias = store.activeAlias;
|
|
296
|
+
if (alias === null) {
|
|
297
|
+
store.activeAlias = null;
|
|
298
|
+
}
|
|
299
|
+
else if (store.accounts[alias]) {
|
|
300
|
+
if (previousAlias && previousAlias !== alias && store.accounts[previousAlias]) {
|
|
301
|
+
store.accounts[previousAlias] = {
|
|
302
|
+
...store.accounts[previousAlias],
|
|
303
|
+
lastActiveUntil: now
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
store.activeAlias = alias;
|
|
307
|
+
store.accounts[alias] = {
|
|
308
|
+
...store.accounts[alias],
|
|
309
|
+
lastSeenAt: now,
|
|
310
|
+
lastActiveUntil: undefined
|
|
311
|
+
};
|
|
312
|
+
const aliases = Object.keys(store.accounts);
|
|
313
|
+
const idx = aliases.indexOf(alias);
|
|
314
|
+
if (idx >= 0) {
|
|
315
|
+
store.rotationIndex = idx;
|
|
316
|
+
}
|
|
317
|
+
store.lastRotation = now;
|
|
318
|
+
}
|
|
319
|
+
saveStore(store);
|
|
320
|
+
return store;
|
|
321
|
+
}
|
|
322
|
+
export function getActiveAccount() {
|
|
323
|
+
const store = loadStore();
|
|
324
|
+
if (!store.activeAlias)
|
|
325
|
+
return null;
|
|
326
|
+
return store.accounts[store.activeAlias] || null;
|
|
327
|
+
}
|
|
328
|
+
export function listAccounts() {
|
|
329
|
+
const store = loadStore();
|
|
330
|
+
return Object.values(store.accounts);
|
|
331
|
+
}
|
|
332
|
+
export function getStorePath() {
|
|
333
|
+
return getStoreFile();
|
|
334
|
+
}
|
|
335
|
+
export function getStoreStatus() {
|
|
336
|
+
const diag = getStoreDiagnostics();
|
|
337
|
+
return { locked: diag.locked, encrypted: diag.encrypted, error: diag.error };
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ServiceOptions {
|
|
2
|
+
cliPath: string;
|
|
3
|
+
host?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function getServiceFilePath(): string;
|
|
7
|
+
export declare function installService(options: ServiceOptions): string;
|
|
8
|
+
export declare function disableService(): void;
|
|
9
|
+
export declare function serviceStatus(): void;
|
|
10
|
+
//# sourceMappingURL=systemd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.d.ts","sourceRoot":"","sources":["../src/systemd.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAaD,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA2B9D;AAED,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
package/dist/systemd.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { execFileSync } from 'node:child_process';
|
|
5
|
+
const SERVICE_NAME = 'codex-soft';
|
|
6
|
+
function getServiceDir() {
|
|
7
|
+
return path.join(os.homedir(), '.config', 'systemd', 'user');
|
|
8
|
+
}
|
|
9
|
+
export function getServiceFilePath() {
|
|
10
|
+
return path.join(getServiceDir(), `${SERVICE_NAME}.service`);
|
|
11
|
+
}
|
|
12
|
+
function ensureDir() {
|
|
13
|
+
const dir = getServiceDir();
|
|
14
|
+
if (!fs.existsSync(dir)) {
|
|
15
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function runSystemctl(args) {
|
|
19
|
+
execFileSync('systemctl', ['--user', ...args], { stdio: 'inherit' });
|
|
20
|
+
}
|
|
21
|
+
export function installService(options) {
|
|
22
|
+
const host = options.host || '127.0.0.1';
|
|
23
|
+
const port = options.port || 3434;
|
|
24
|
+
const serviceFile = getServiceFilePath();
|
|
25
|
+
const workingDir = path.dirname(options.cliPath);
|
|
26
|
+
const execStart = `${process.execPath} ${options.cliPath} web --host ${host} --port ${port}`;
|
|
27
|
+
ensureDir();
|
|
28
|
+
const unit = `[Unit]
|
|
29
|
+
Description=Codex Soft Dashboard
|
|
30
|
+
After=network.target
|
|
31
|
+
|
|
32
|
+
[Service]
|
|
33
|
+
Type=simple
|
|
34
|
+
WorkingDirectory=${workingDir}
|
|
35
|
+
ExecStart=${execStart}
|
|
36
|
+
Restart=on-failure
|
|
37
|
+
RestartSec=3
|
|
38
|
+
|
|
39
|
+
[Install]
|
|
40
|
+
WantedBy=default.target
|
|
41
|
+
`;
|
|
42
|
+
fs.writeFileSync(serviceFile, unit, { mode: 0o600 });
|
|
43
|
+
runSystemctl(['daemon-reload']);
|
|
44
|
+
runSystemctl(['enable', '--now', `${SERVICE_NAME}.service`]);
|
|
45
|
+
return serviceFile;
|
|
46
|
+
}
|
|
47
|
+
export function disableService() {
|
|
48
|
+
runSystemctl(['disable', '--now', `${SERVICE_NAME}.service`]);
|
|
49
|
+
}
|
|
50
|
+
export function serviceStatus() {
|
|
51
|
+
runSystemctl(['status', `${SERVICE_NAME}.service`, '--no-pager']);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=systemd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.js","sourceRoot":"","sources":["../src/systemd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,YAAY,GAAG,YAAY,CAAA;AAQjC,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,YAAY,UAAU,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAA;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACrD,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAc;IAClC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAA;IACjC,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAA;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAChD,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,eAAe,IAAI,WAAW,IAAI,EAAE,CAAA;IAE5F,SAAS,EAAE,CAAA;IACX,MAAM,IAAI,GAAG;;;;;;mBAMI,UAAU;YACjB,SAAS;;;;;;CAMpB,CAAA;IAEC,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACpD,YAAY,CAAC,CAAC,eAAe,CAAC,CAAC,CAAA;IAC/B,YAAY,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,YAAY,UAAU,CAAC,CAAC,CAAA;IAC5D,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,YAAY,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,YAAY,UAAU,CAAC,CAAC,CAAA;AAC/D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,YAAY,CAAC,CAAC,QAAQ,EAAE,GAAG,YAAY,UAAU,EAAE,YAAY,CAAC,CAAC,CAAA;AACnE,CAAC"}
|