@jsonstudio/rcc 0.89.1457 → 0.89.1489
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/configsamples/config.json +12 -4
- package/dist/build-info.js +2 -2
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +53 -26
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +4 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.js +130 -2
- package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -1
- package/dist/manager/modules/quota/provider-quota-daemon.events.js +63 -2
- package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -1
- package/dist/modules/llmswitch/bridge.js +17 -4
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/llmswitch/core-loader.d.ts +1 -1
- package/dist/modules/llmswitch/core-loader.js +15 -3
- package/dist/modules/llmswitch/core-loader.js.map +1 -1
- package/dist/providers/auth/antigravity-userinfo-helper.d.ts +3 -1
- package/dist/providers/auth/antigravity-userinfo-helper.js +41 -7
- package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -1
- package/dist/providers/auth/gemini-cli-userinfo-helper.js +66 -4
- package/dist/providers/auth/gemini-cli-userinfo-helper.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +112 -1
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/tokenfile-auth.d.ts +12 -0
- package/dist/providers/auth/tokenfile-auth.js +92 -1
- package/dist/providers/auth/tokenfile-auth.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +0 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +118 -78
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.js +10 -3
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/runtime/wasm-runtime/wasm-config.d.ts +73 -0
- package/dist/runtime/wasm-runtime/wasm-config.js +124 -0
- package/dist/runtime/wasm-runtime/wasm-config.js.map +1 -0
- package/dist/runtime/wasm-runtime/wasm-loader.d.ts +40 -0
- package/dist/runtime/wasm-runtime/wasm-loader.js +62 -0
- package/dist/runtime/wasm-runtime/wasm-loader.js.map +1 -0
- package/dist/server/runtime/http-server/index.js +53 -1
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/docs/antigravity-gemini-format-cleanup.md +54 -13
- package/docs/llms-wasm-migration.md +331 -0
- package/docs/llms-wasm-module-boundaries.md +588 -0
- package/docs/llms-wasm-replay-baseline.md +171 -0
- package/docs/plans/llms-wasm-migration-plan.md +401 -0
- package/package.json +2 -2
- package/scripts/antigravity-token-bridge.mjs +283 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import { existsSync, readdirSync } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const opts = new Set(args);
|
|
9
|
+
|
|
10
|
+
const direction = args.includes('--to-routecodex') ? 'ag-to-rc' : 'rc-to-ag';
|
|
11
|
+
const dryRun = opts.has('--dry-run');
|
|
12
|
+
|
|
13
|
+
const home = os.homedir();
|
|
14
|
+
const rcAuthDir = path.join(home, '.routecodex', 'auth');
|
|
15
|
+
const agDataDir = path.join(home, '.antigravity_tools');
|
|
16
|
+
const agAccountsDir = path.join(agDataDir, 'accounts');
|
|
17
|
+
const agIndexPath = path.join(agDataDir, 'accounts.json');
|
|
18
|
+
|
|
19
|
+
function nowSeconds() {
|
|
20
|
+
return Math.floor(Date.now() / 1000);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizeExpirySeconds(token) {
|
|
24
|
+
const expiry = token.expiry_timestamp;
|
|
25
|
+
if (typeof expiry === 'number') {
|
|
26
|
+
return expiry > 10_000_000_000 ? Math.floor(expiry / 1000) : Math.floor(expiry);
|
|
27
|
+
}
|
|
28
|
+
const expiresAt = token.expires_at;
|
|
29
|
+
if (typeof expiresAt === 'number') {
|
|
30
|
+
return expiresAt > 10_000_000_000 ? Math.floor(expiresAt / 1000) : Math.floor(expiresAt);
|
|
31
|
+
}
|
|
32
|
+
const expiresIn = token.expires_in;
|
|
33
|
+
if (typeof expiresIn === 'number') {
|
|
34
|
+
return nowSeconds() + Math.max(0, Math.floor(expiresIn));
|
|
35
|
+
}
|
|
36
|
+
return nowSeconds() + 3600;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function normalizeRcToken(raw) {
|
|
40
|
+
if (!raw || typeof raw !== 'object') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (raw.token && typeof raw.token === 'object' && raw.token.access_token) {
|
|
44
|
+
return { ...raw.token, ...raw };
|
|
45
|
+
}
|
|
46
|
+
return raw;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function ensureDir(p) {
|
|
50
|
+
await fs.mkdir(p, { recursive: true });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function pickEmail(token) {
|
|
54
|
+
if (typeof token.email === 'string' && token.email.trim()) {
|
|
55
|
+
return token.email.trim();
|
|
56
|
+
}
|
|
57
|
+
if (token.id_token && typeof token.id_token === 'string') {
|
|
58
|
+
// avoid parsing JWT here to keep script simple
|
|
59
|
+
}
|
|
60
|
+
return '';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function loadExistingAccounts() {
|
|
64
|
+
if (!existsSync(agAccountsDir)) {
|
|
65
|
+
return { byEmail: new Map(), accounts: [] };
|
|
66
|
+
}
|
|
67
|
+
const byEmail = new Map();
|
|
68
|
+
const accounts = [];
|
|
69
|
+
for (const name of readdirSync(agAccountsDir)) {
|
|
70
|
+
if (!name.endsWith('.json')) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const filePath = path.join(agAccountsDir, name);
|
|
74
|
+
try {
|
|
75
|
+
const raw = JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
76
|
+
accounts.push({ filePath, data: raw });
|
|
77
|
+
if (raw && typeof raw.email === 'string') {
|
|
78
|
+
byEmail.set(raw.email, { filePath, data: raw });
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// ignore malformed file
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { byEmail, accounts };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function loadAccountsIndex() {
|
|
88
|
+
try {
|
|
89
|
+
const raw = JSON.parse(await fs.readFile(agIndexPath, 'utf-8'));
|
|
90
|
+
if (raw && typeof raw === 'object' && Array.isArray(raw.accounts)) {
|
|
91
|
+
return raw;
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
// ignore
|
|
95
|
+
}
|
|
96
|
+
return { version: '2.0', accounts: [], current_account_id: null };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function upsertIndexEntry(index, account) {
|
|
100
|
+
const idx = index.accounts.findIndex((item) => item.id === account.id);
|
|
101
|
+
const summary = {
|
|
102
|
+
id: account.id,
|
|
103
|
+
email: account.email,
|
|
104
|
+
name: account.name ?? null,
|
|
105
|
+
disabled: !!account.disabled,
|
|
106
|
+
proxy_disabled: !!account.proxy_disabled,
|
|
107
|
+
created_at: account.created_at,
|
|
108
|
+
last_used: account.last_used
|
|
109
|
+
};
|
|
110
|
+
if (idx >= 0) {
|
|
111
|
+
index.accounts[idx] = summary;
|
|
112
|
+
} else {
|
|
113
|
+
index.accounts.push(summary);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function rcToAg() {
|
|
118
|
+
if (!existsSync(rcAuthDir)) {
|
|
119
|
+
throw new Error(`RouteCodex auth dir not found: ${rcAuthDir}`);
|
|
120
|
+
}
|
|
121
|
+
await ensureDir(agAccountsDir);
|
|
122
|
+
|
|
123
|
+
const { byEmail } = await loadExistingAccounts();
|
|
124
|
+
const index = await loadAccountsIndex();
|
|
125
|
+
|
|
126
|
+
const files = readdirSync(rcAuthDir).filter((name) => /^antigravity-oauth-.*\.json$/i.test(name));
|
|
127
|
+
if (!files.length) {
|
|
128
|
+
console.log('No antigravity token files found in ~/.routecodex/auth');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (const name of files) {
|
|
133
|
+
const filePath = path.join(rcAuthDir, name);
|
|
134
|
+
let tokenRaw;
|
|
135
|
+
try {
|
|
136
|
+
tokenRaw = JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
137
|
+
} catch {
|
|
138
|
+
console.log(`Skip unreadable token: ${filePath}`);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const token = normalizeRcToken(tokenRaw);
|
|
142
|
+
if (!token || typeof token.access_token !== 'string' || typeof token.refresh_token !== 'string') {
|
|
143
|
+
console.log(`Skip invalid token (missing access/refresh): ${filePath}`);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const email = pickEmail(token);
|
|
148
|
+
if (!email) {
|
|
149
|
+
console.log(`Skip token without email: ${filePath}`);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const now = nowSeconds();
|
|
154
|
+
const expiryTimestamp = normalizeExpirySeconds(token);
|
|
155
|
+
const projectId = typeof token.project_id === 'string' ? token.project_id : (typeof token.projectId === 'string' ? token.projectId : undefined);
|
|
156
|
+
|
|
157
|
+
const baseAccount = {
|
|
158
|
+
created_at: now,
|
|
159
|
+
disabled: token.disabled === true,
|
|
160
|
+
email,
|
|
161
|
+
id: crypto.randomUUID(),
|
|
162
|
+
last_used: now,
|
|
163
|
+
name: typeof token.name === 'string' ? token.name : null,
|
|
164
|
+
proxy_disabled: token.proxy_disabled === true || token.proxyDisabled === true,
|
|
165
|
+
proxy_disabled_at: token.proxy_disabled_at ?? null,
|
|
166
|
+
proxy_disabled_reason: token.proxy_disabled_reason ?? null,
|
|
167
|
+
quota: null,
|
|
168
|
+
protected_models: Array.isArray(token.protected_models)
|
|
169
|
+
? token.protected_models
|
|
170
|
+
: Array.isArray(token.protectedModels)
|
|
171
|
+
? token.protectedModels
|
|
172
|
+
: [],
|
|
173
|
+
disabled_reason: token.disabled_reason ?? null,
|
|
174
|
+
disabled_at: token.disabled_at ?? null,
|
|
175
|
+
token: {
|
|
176
|
+
access_token: token.access_token,
|
|
177
|
+
refresh_token: token.refresh_token,
|
|
178
|
+
expires_in: typeof token.expires_in === 'number' ? token.expires_in : 3600,
|
|
179
|
+
expiry_timestamp: expiryTimestamp,
|
|
180
|
+
token_type: typeof token.token_type === 'string' ? token.token_type : 'Bearer',
|
|
181
|
+
email,
|
|
182
|
+
project_id: projectId
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const existing = byEmail.get(email);
|
|
187
|
+
let account = baseAccount;
|
|
188
|
+
let targetPath;
|
|
189
|
+
if (existing) {
|
|
190
|
+
account = { ...existing.data, ...baseAccount };
|
|
191
|
+
account.id = existing.data.id || baseAccount.id;
|
|
192
|
+
account.created_at = existing.data.created_at || baseAccount.created_at;
|
|
193
|
+
account.last_used = now;
|
|
194
|
+
account.token = { ...(existing.data.token || {}), ...(baseAccount.token || {}) };
|
|
195
|
+
targetPath = existing.filePath;
|
|
196
|
+
} else {
|
|
197
|
+
targetPath = path.join(agAccountsDir, `${account.id}.json`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (dryRun) {
|
|
201
|
+
console.log(`[dry-run] write ${targetPath}`);
|
|
202
|
+
} else {
|
|
203
|
+
await fs.writeFile(targetPath, `${JSON.stringify(account, null, 2)}\n`, 'utf-8');
|
|
204
|
+
upsertIndexEntry(index, account);
|
|
205
|
+
console.log(`Wrote ${targetPath}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!dryRun) {
|
|
210
|
+
await fs.writeFile(agIndexPath, `${JSON.stringify(index, null, 2)}\n`, 'utf-8');
|
|
211
|
+
console.log(`Updated ${agIndexPath}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function agToRc() {
|
|
216
|
+
if (!existsSync(agAccountsDir)) {
|
|
217
|
+
throw new Error(`Antigravity accounts dir not found: ${agAccountsDir}`);
|
|
218
|
+
}
|
|
219
|
+
await ensureDir(rcAuthDir);
|
|
220
|
+
|
|
221
|
+
const files = readdirSync(agAccountsDir).filter((name) => name.endsWith('.json'));
|
|
222
|
+
if (!files.length) {
|
|
223
|
+
console.log('No antigravity account files found in ~/.antigravity_tools/accounts');
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let seq = 1;
|
|
228
|
+
for (const name of files) {
|
|
229
|
+
const filePath = path.join(agAccountsDir, name);
|
|
230
|
+
let account;
|
|
231
|
+
try {
|
|
232
|
+
account = JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
233
|
+
} catch {
|
|
234
|
+
console.log(`Skip unreadable account: ${filePath}`);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const token = account?.token;
|
|
238
|
+
if (!token || typeof token.access_token !== 'string') {
|
|
239
|
+
console.log(`Skip account without token: ${filePath}`);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const alias = typeof account.email === 'string' ? account.email.split('@')[0] : 'imported';
|
|
243
|
+
const rcPath = path.join(rcAuthDir, `antigravity-oauth-${seq}-${alias}.json`);
|
|
244
|
+
seq += 1;
|
|
245
|
+
|
|
246
|
+
const payload = {
|
|
247
|
+
access_token: token.access_token,
|
|
248
|
+
refresh_token: token.refresh_token,
|
|
249
|
+
token_type: token.token_type || 'Bearer',
|
|
250
|
+
expires_in: token.expires_in,
|
|
251
|
+
expires_at: typeof token.expiry_timestamp === 'number' ? token.expiry_timestamp * 1000 : undefined,
|
|
252
|
+
email: account.email,
|
|
253
|
+
name: account.name ?? undefined,
|
|
254
|
+
project_id: token.project_id || account.project_id || account.projectId,
|
|
255
|
+
projectId: token.project_id || account.projectId || account.project_id,
|
|
256
|
+
disabled: account.disabled === true,
|
|
257
|
+
disabled_reason: account.disabled_reason ?? undefined,
|
|
258
|
+
disabled_at: account.disabled_at ?? undefined,
|
|
259
|
+
proxy_disabled: account.proxy_disabled === true,
|
|
260
|
+
proxy_disabled_reason: account.proxy_disabled_reason ?? undefined,
|
|
261
|
+
proxy_disabled_at: account.proxy_disabled_at ?? undefined,
|
|
262
|
+
protected_models: Array.isArray(account.protected_models) ? account.protected_models : undefined
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
if (dryRun) {
|
|
266
|
+
console.log(`[dry-run] write ${rcPath}`);
|
|
267
|
+
} else {
|
|
268
|
+
await fs.writeFile(rcPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf-8');
|
|
269
|
+
console.log(`Wrote ${rcPath}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
if (direction === 'ag-to-rc') {
|
|
276
|
+
await agToRc();
|
|
277
|
+
} else {
|
|
278
|
+
await rcToAg();
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|