antigravity-auth 1.6.0 → 1.7.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 (258) hide show
  1. package/README.md +79 -41
  2. package/dist/cli.js +2868 -0
  3. package/dist/handler.js +25119 -0
  4. package/dist/index.js +25110 -5
  5. package/package.json +66 -54
  6. package/dist/antigravity/oauth.d.ts +0 -30
  7. package/dist/antigravity/oauth.js +0 -170
  8. package/dist/claude/login.d.ts +0 -7
  9. package/dist/claude/login.js +0 -480
  10. package/dist/claude/menu-helpers.d.ts +0 -22
  11. package/dist/claude/menu-helpers.js +0 -281
  12. package/dist/claude/proxy-manager.d.ts +0 -11
  13. package/dist/claude/proxy-manager.js +0 -129
  14. package/dist/claude/proxy.d.ts +0 -1
  15. package/dist/claude/proxy.js +0 -733
  16. package/dist/constants.d.ts +0 -138
  17. package/dist/constants.js +0 -216
  18. package/dist/hooks/auto-update-checker/cache.d.ts +0 -2
  19. package/dist/hooks/auto-update-checker/cache.js +0 -70
  20. package/dist/hooks/auto-update-checker/checker.d.ts +0 -15
  21. package/dist/hooks/auto-update-checker/checker.js +0 -233
  22. package/dist/hooks/auto-update-checker/constants.d.ts +0 -8
  23. package/dist/hooks/auto-update-checker/constants.js +0 -22
  24. package/dist/hooks/auto-update-checker/index.d.ts +0 -33
  25. package/dist/hooks/auto-update-checker/index.js +0 -121
  26. package/dist/hooks/auto-update-checker/logging.d.ts +0 -2
  27. package/dist/hooks/auto-update-checker/logging.js +0 -8
  28. package/dist/hooks/auto-update-checker/types.d.ts +0 -24
  29. package/dist/hooks/auto-update-checker/types.js +0 -1
  30. package/dist/index.d.ts +0 -6
  31. package/dist/opencode/hooks/auto-update-checker/cache.d.ts +0 -2
  32. package/dist/opencode/hooks/auto-update-checker/cache.js +0 -70
  33. package/dist/opencode/hooks/auto-update-checker/checker.d.ts +0 -15
  34. package/dist/opencode/hooks/auto-update-checker/checker.js +0 -233
  35. package/dist/opencode/hooks/auto-update-checker/constants.d.ts +0 -8
  36. package/dist/opencode/hooks/auto-update-checker/constants.js +0 -22
  37. package/dist/opencode/hooks/auto-update-checker/index.d.ts +0 -33
  38. package/dist/opencode/hooks/auto-update-checker/index.js +0 -121
  39. package/dist/opencode/hooks/auto-update-checker/logging.d.ts +0 -2
  40. package/dist/opencode/hooks/auto-update-checker/logging.js +0 -8
  41. package/dist/opencode/hooks/auto-update-checker/types.d.ts +0 -24
  42. package/dist/opencode/hooks/auto-update-checker/types.js +0 -1
  43. package/dist/opencode/plugin.d.ts +0 -29
  44. package/dist/opencode/plugin.js +0 -2954
  45. package/dist/plugin/accounts.d.ts +0 -173
  46. package/dist/plugin/accounts.js +0 -966
  47. package/dist/plugin/auth.d.ts +0 -20
  48. package/dist/plugin/auth.js +0 -44
  49. package/dist/plugin/cache/index.d.ts +0 -4
  50. package/dist/plugin/cache/index.js +0 -4
  51. package/dist/plugin/cache/signature-cache.d.ts +0 -110
  52. package/dist/plugin/cache/signature-cache.js +0 -347
  53. package/dist/plugin/cache.d.ts +0 -43
  54. package/dist/plugin/cache.js +0 -180
  55. package/dist/plugin/cli.d.ts +0 -26
  56. package/dist/plugin/cli.js +0 -126
  57. package/dist/plugin/config/index.d.ts +0 -15
  58. package/dist/plugin/config/index.js +0 -15
  59. package/dist/plugin/config/loader.d.ts +0 -38
  60. package/dist/plugin/config/loader.js +0 -150
  61. package/dist/plugin/config/models.d.ts +0 -26
  62. package/dist/plugin/config/models.js +0 -95
  63. package/dist/plugin/config/schema.d.ts +0 -144
  64. package/dist/plugin/config/schema.js +0 -458
  65. package/dist/plugin/config/updater.d.ts +0 -76
  66. package/dist/plugin/config/updater.js +0 -205
  67. package/dist/plugin/core/streaming/index.d.ts +0 -2
  68. package/dist/plugin/core/streaming/index.js +0 -2
  69. package/dist/plugin/core/streaming/transformer.d.ts +0 -9
  70. package/dist/plugin/core/streaming/transformer.js +0 -301
  71. package/dist/plugin/core/streaming/types.d.ts +0 -28
  72. package/dist/plugin/core/streaming/types.js +0 -1
  73. package/dist/plugin/debug.d.ts +0 -93
  74. package/dist/plugin/debug.js +0 -375
  75. package/dist/plugin/errors.d.ts +0 -27
  76. package/dist/plugin/errors.js +0 -41
  77. package/dist/plugin/fingerprint.d.ts +0 -69
  78. package/dist/plugin/fingerprint.js +0 -137
  79. package/dist/plugin/image-saver.d.ts +0 -24
  80. package/dist/plugin/image-saver.js +0 -78
  81. package/dist/plugin/logger.d.ts +0 -35
  82. package/dist/plugin/logger.js +0 -67
  83. package/dist/plugin/logging-utils.d.ts +0 -22
  84. package/dist/plugin/logging-utils.js +0 -91
  85. package/dist/plugin/project.d.ts +0 -32
  86. package/dist/plugin/project.js +0 -229
  87. package/dist/plugin/quota.d.ts +0 -34
  88. package/dist/plugin/quota.js +0 -261
  89. package/dist/plugin/recovery/constants.d.ts +0 -21
  90. package/dist/plugin/recovery/constants.js +0 -42
  91. package/dist/plugin/recovery/index.d.ts +0 -11
  92. package/dist/plugin/recovery/index.js +0 -11
  93. package/dist/plugin/recovery/storage.d.ts +0 -23
  94. package/dist/plugin/recovery/storage.js +0 -340
  95. package/dist/plugin/recovery/types.d.ts +0 -115
  96. package/dist/plugin/recovery/types.js +0 -6
  97. package/dist/plugin/recovery.d.ts +0 -60
  98. package/dist/plugin/recovery.js +0 -360
  99. package/dist/plugin/refresh-queue.d.ts +0 -99
  100. package/dist/plugin/refresh-queue.js +0 -235
  101. package/dist/plugin/request-helpers.d.ts +0 -281
  102. package/dist/plugin/request-helpers.js +0 -2200
  103. package/dist/plugin/request.d.ts +0 -110
  104. package/dist/plugin/request.js +0 -1489
  105. package/dist/plugin/rotation.d.ts +0 -182
  106. package/dist/plugin/rotation.js +0 -364
  107. package/dist/plugin/search.d.ts +0 -31
  108. package/dist/plugin/search.js +0 -185
  109. package/dist/plugin/server.d.ts +0 -22
  110. package/dist/plugin/server.js +0 -306
  111. package/dist/plugin/storage.d.ts +0 -136
  112. package/dist/plugin/storage.js +0 -599
  113. package/dist/plugin/stores/signature-store.d.ts +0 -4
  114. package/dist/plugin/stores/signature-store.js +0 -24
  115. package/dist/plugin/thinking-recovery.d.ts +0 -89
  116. package/dist/plugin/thinking-recovery.js +0 -289
  117. package/dist/plugin/token.d.ts +0 -18
  118. package/dist/plugin/token.js +0 -127
  119. package/dist/plugin/transform/claude.d.ts +0 -79
  120. package/dist/plugin/transform/claude.js +0 -256
  121. package/dist/plugin/transform/cross-model-sanitizer.d.ts +0 -34
  122. package/dist/plugin/transform/cross-model-sanitizer.js +0 -224
  123. package/dist/plugin/transform/gemini.d.ts +0 -132
  124. package/dist/plugin/transform/gemini.js +0 -659
  125. package/dist/plugin/transform/index.d.ts +0 -14
  126. package/dist/plugin/transform/index.js +0 -9
  127. package/dist/plugin/transform/model-resolver.d.ts +0 -98
  128. package/dist/plugin/transform/model-resolver.js +0 -320
  129. package/dist/plugin/transform/types.d.ts +0 -110
  130. package/dist/plugin/transform/types.js +0 -1
  131. package/dist/plugin/types.d.ts +0 -95
  132. package/dist/plugin/types.js +0 -1
  133. package/dist/plugin/ui/ansi.d.ts +0 -31
  134. package/dist/plugin/ui/ansi.js +0 -45
  135. package/dist/plugin/ui/auth-menu.d.ts +0 -47
  136. package/dist/plugin/ui/auth-menu.js +0 -199
  137. package/dist/plugin/ui/confirm.d.ts +0 -1
  138. package/dist/plugin/ui/confirm.js +0 -14
  139. package/dist/plugin/ui/select.d.ts +0 -22
  140. package/dist/plugin/ui/select.js +0 -243
  141. package/dist/plugin/version.d.ts +0 -18
  142. package/dist/plugin/version.js +0 -79
  143. package/dist/src/antigravity/oauth.d.ts +0 -30
  144. package/dist/src/antigravity/oauth.js +0 -170
  145. package/dist/src/constants.d.ts +0 -138
  146. package/dist/src/constants.js +0 -216
  147. package/dist/src/hooks/auto-update-checker/cache.d.ts +0 -2
  148. package/dist/src/hooks/auto-update-checker/cache.js +0 -70
  149. package/dist/src/hooks/auto-update-checker/checker.d.ts +0 -15
  150. package/dist/src/hooks/auto-update-checker/checker.js +0 -233
  151. package/dist/src/hooks/auto-update-checker/constants.d.ts +0 -8
  152. package/dist/src/hooks/auto-update-checker/constants.js +0 -22
  153. package/dist/src/hooks/auto-update-checker/index.d.ts +0 -33
  154. package/dist/src/hooks/auto-update-checker/index.js +0 -121
  155. package/dist/src/hooks/auto-update-checker/logging.d.ts +0 -2
  156. package/dist/src/hooks/auto-update-checker/logging.js +0 -8
  157. package/dist/src/hooks/auto-update-checker/types.d.ts +0 -24
  158. package/dist/src/hooks/auto-update-checker/types.js +0 -1
  159. package/dist/src/index.d.ts +0 -6
  160. package/dist/src/index.js +0 -5
  161. package/dist/src/plugin/accounts.d.ts +0 -173
  162. package/dist/src/plugin/accounts.js +0 -966
  163. package/dist/src/plugin/auth.d.ts +0 -20
  164. package/dist/src/plugin/auth.js +0 -44
  165. package/dist/src/plugin/cache/index.d.ts +0 -4
  166. package/dist/src/plugin/cache/index.js +0 -4
  167. package/dist/src/plugin/cache/signature-cache.d.ts +0 -110
  168. package/dist/src/plugin/cache/signature-cache.js +0 -347
  169. package/dist/src/plugin/cache.d.ts +0 -43
  170. package/dist/src/plugin/cache.js +0 -180
  171. package/dist/src/plugin/cli.d.ts +0 -26
  172. package/dist/src/plugin/cli.js +0 -126
  173. package/dist/src/plugin/config/index.d.ts +0 -15
  174. package/dist/src/plugin/config/index.js +0 -15
  175. package/dist/src/plugin/config/loader.d.ts +0 -38
  176. package/dist/src/plugin/config/loader.js +0 -150
  177. package/dist/src/plugin/config/models.d.ts +0 -26
  178. package/dist/src/plugin/config/models.js +0 -95
  179. package/dist/src/plugin/config/schema.d.ts +0 -144
  180. package/dist/src/plugin/config/schema.js +0 -458
  181. package/dist/src/plugin/config/updater.d.ts +0 -76
  182. package/dist/src/plugin/config/updater.js +0 -205
  183. package/dist/src/plugin/core/streaming/index.d.ts +0 -2
  184. package/dist/src/plugin/core/streaming/index.js +0 -2
  185. package/dist/src/plugin/core/streaming/transformer.d.ts +0 -9
  186. package/dist/src/plugin/core/streaming/transformer.js +0 -301
  187. package/dist/src/plugin/core/streaming/types.d.ts +0 -28
  188. package/dist/src/plugin/core/streaming/types.js +0 -1
  189. package/dist/src/plugin/debug.d.ts +0 -93
  190. package/dist/src/plugin/debug.js +0 -375
  191. package/dist/src/plugin/errors.d.ts +0 -27
  192. package/dist/src/plugin/errors.js +0 -41
  193. package/dist/src/plugin/fingerprint.d.ts +0 -69
  194. package/dist/src/plugin/fingerprint.js +0 -137
  195. package/dist/src/plugin/image-saver.d.ts +0 -24
  196. package/dist/src/plugin/image-saver.js +0 -78
  197. package/dist/src/plugin/logger.d.ts +0 -35
  198. package/dist/src/plugin/logger.js +0 -67
  199. package/dist/src/plugin/logging-utils.d.ts +0 -22
  200. package/dist/src/plugin/logging-utils.js +0 -91
  201. package/dist/src/plugin/project.d.ts +0 -32
  202. package/dist/src/plugin/project.js +0 -229
  203. package/dist/src/plugin/quota.d.ts +0 -34
  204. package/dist/src/plugin/quota.js +0 -261
  205. package/dist/src/plugin/recovery/constants.d.ts +0 -21
  206. package/dist/src/plugin/recovery/constants.js +0 -42
  207. package/dist/src/plugin/recovery/index.d.ts +0 -11
  208. package/dist/src/plugin/recovery/index.js +0 -11
  209. package/dist/src/plugin/recovery/storage.d.ts +0 -23
  210. package/dist/src/plugin/recovery/storage.js +0 -340
  211. package/dist/src/plugin/recovery/types.d.ts +0 -115
  212. package/dist/src/plugin/recovery/types.js +0 -6
  213. package/dist/src/plugin/recovery.d.ts +0 -60
  214. package/dist/src/plugin/recovery.js +0 -360
  215. package/dist/src/plugin/refresh-queue.d.ts +0 -99
  216. package/dist/src/plugin/refresh-queue.js +0 -235
  217. package/dist/src/plugin/request-helpers.d.ts +0 -281
  218. package/dist/src/plugin/request-helpers.js +0 -2200
  219. package/dist/src/plugin/request.d.ts +0 -110
  220. package/dist/src/plugin/request.js +0 -1489
  221. package/dist/src/plugin/rotation.d.ts +0 -182
  222. package/dist/src/plugin/rotation.js +0 -364
  223. package/dist/src/plugin/search.d.ts +0 -31
  224. package/dist/src/plugin/search.js +0 -185
  225. package/dist/src/plugin/server.d.ts +0 -22
  226. package/dist/src/plugin/server.js +0 -306
  227. package/dist/src/plugin/storage.d.ts +0 -136
  228. package/dist/src/plugin/storage.js +0 -599
  229. package/dist/src/plugin/stores/signature-store.d.ts +0 -4
  230. package/dist/src/plugin/stores/signature-store.js +0 -24
  231. package/dist/src/plugin/thinking-recovery.d.ts +0 -89
  232. package/dist/src/plugin/thinking-recovery.js +0 -289
  233. package/dist/src/plugin/token.d.ts +0 -18
  234. package/dist/src/plugin/token.js +0 -127
  235. package/dist/src/plugin/transform/claude.d.ts +0 -79
  236. package/dist/src/plugin/transform/claude.js +0 -256
  237. package/dist/src/plugin/transform/cross-model-sanitizer.d.ts +0 -34
  238. package/dist/src/plugin/transform/cross-model-sanitizer.js +0 -224
  239. package/dist/src/plugin/transform/gemini.d.ts +0 -132
  240. package/dist/src/plugin/transform/gemini.js +0 -659
  241. package/dist/src/plugin/transform/index.d.ts +0 -14
  242. package/dist/src/plugin/transform/index.js +0 -9
  243. package/dist/src/plugin/transform/model-resolver.d.ts +0 -98
  244. package/dist/src/plugin/transform/model-resolver.js +0 -320
  245. package/dist/src/plugin/transform/types.d.ts +0 -110
  246. package/dist/src/plugin/transform/types.js +0 -1
  247. package/dist/src/plugin/types.d.ts +0 -95
  248. package/dist/src/plugin/types.js +0 -1
  249. package/dist/src/plugin/ui/ansi.d.ts +0 -31
  250. package/dist/src/plugin/ui/ansi.js +0 -45
  251. package/dist/src/plugin/ui/auth-menu.d.ts +0 -47
  252. package/dist/src/plugin/ui/auth-menu.js +0 -199
  253. package/dist/src/plugin/ui/confirm.d.ts +0 -1
  254. package/dist/src/plugin/ui/confirm.js +0 -14
  255. package/dist/src/plugin/ui/select.d.ts +0 -22
  256. package/dist/src/plugin/ui/select.js +0 -243
  257. package/dist/src/plugin/version.d.ts +0 -18
  258. package/dist/src/plugin/version.js +0 -79
@@ -1,599 +0,0 @@
1
- import { promises as fs } from "node:fs";
2
- import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, renameSync, copyFileSync, unlinkSync, } from "node:fs";
3
- import { dirname, join } from "node:path";
4
- import { homedir } from "node:os";
5
- import { randomBytes } from "node:crypto";
6
- import lockfile from "proper-lockfile";
7
- import { createLogger } from "./logger";
8
- const log = createLogger("storage");
9
- /**
10
- * Files/directories that should be gitignored in the config directory.
11
- * These contain sensitive data or machine-specific state.
12
- */
13
- export const GITIGNORE_ENTRIES = [
14
- "antigravity-accounts.json",
15
- "antigravity-accounts.json.*.tmp",
16
- "antigravity-signature-cache.json",
17
- "antigravity-logs/",
18
- ];
19
- /**
20
- * Ensures a .gitignore file exists in the config directory with entries
21
- * for sensitive files. Creates the file if missing, or appends missing
22
- * entries if it already exists.
23
- */
24
- export async function ensureGitignore(configDir) {
25
- const gitignorePath = join(configDir, ".gitignore");
26
- try {
27
- let content;
28
- let existingLines = [];
29
- try {
30
- content = await fs.readFile(gitignorePath, "utf-8");
31
- existingLines = content.split(/\r?\n/).map((line) => line.trim());
32
- }
33
- catch (error) {
34
- if (error.code !== "ENOENT") {
35
- return;
36
- }
37
- content = "";
38
- }
39
- const missingEntries = GITIGNORE_ENTRIES.filter((entry) => !existingLines.includes(entry));
40
- if (missingEntries.length === 0) {
41
- return;
42
- }
43
- if (content === "") {
44
- await fs.writeFile(gitignorePath, missingEntries.join("\n") + "\n", "utf-8");
45
- log.info("Created .gitignore in config directory");
46
- }
47
- else {
48
- const suffix = content.endsWith("\n") ? "" : "\n";
49
- await fs.appendFile(gitignorePath, suffix + missingEntries.join("\n") + "\n", "utf-8");
50
- log.info("Updated .gitignore with missing entries", {
51
- added: missingEntries,
52
- });
53
- }
54
- }
55
- catch {
56
- }
57
- }
58
- /**
59
- * Synchronous version of ensureGitignore for use in sync code paths.
60
- */
61
- export function ensureGitignoreSync(configDir) {
62
- const gitignorePath = join(configDir, ".gitignore");
63
- try {
64
- let content;
65
- let existingLines = [];
66
- if (existsSync(gitignorePath)) {
67
- content = readFileSync(gitignorePath, "utf-8");
68
- existingLines = content.split(/\r?\n/).map((line) => line.trim());
69
- }
70
- else {
71
- content = "";
72
- }
73
- const missingEntries = GITIGNORE_ENTRIES.filter((entry) => !existingLines.includes(entry));
74
- if (missingEntries.length === 0) {
75
- return;
76
- }
77
- if (content === "") {
78
- writeFileSync(gitignorePath, missingEntries.join("\n") + "\n", "utf-8");
79
- log.info("Created .gitignore in config directory");
80
- }
81
- else {
82
- const suffix = content.endsWith("\n") ? "" : "\n";
83
- appendFileSync(gitignorePath, suffix + missingEntries.join("\n") + "\n", "utf-8");
84
- log.info("Updated .gitignore with missing entries", {
85
- added: missingEntries,
86
- });
87
- }
88
- }
89
- catch {
90
- }
91
- }
92
- /**
93
- * Gets the legacy Windows config directory (%APPDATA%\opencode).
94
- * Used for migration from older plugin versions.
95
- */
96
- function getLegacyWindowsConfigDir() {
97
- return join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "opencode");
98
- }
99
- /**
100
- * Gets the config directory path, with the following precedence:
101
- * 1. OPENCODE_CONFIG_DIR env var (if set)
102
- * 2. ~/.config/opencode (all platforms, including Windows)
103
- *
104
- * On Windows, also checks for legacy %APPDATA%\opencode path for migration.
105
- */
106
- function getConfigDir() {
107
- // 1. Check for explicit override via env var
108
- if (process.env.OPENCODE_CONFIG_DIR) {
109
- return process.env.OPENCODE_CONFIG_DIR;
110
- }
111
- // 2. Use ~/.config/opencode on all platforms (including Windows)
112
- const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
113
- return join(xdgConfig, "opencode");
114
- }
115
- /**
116
- * Migrates config from legacy Windows location to the new path.
117
- * Moves the file if legacy exists and new doesn't.
118
- * Returns true if migration was performed.
119
- */
120
- function migrateLegacyWindowsConfig() {
121
- if (process.platform !== "win32") {
122
- return false;
123
- }
124
- const configSubDir = join(getConfigDir(), "config");
125
- const newPath = join(configSubDir, "antigravity-accounts.json");
126
- const legacyPath = join(getLegacyWindowsConfigDir(), "antigravity-accounts.json");
127
- if (!existsSync(legacyPath) || existsSync(newPath)) {
128
- return false;
129
- }
130
- try {
131
- mkdirSync(configSubDir, { recursive: true });
132
- try {
133
- renameSync(legacyPath, newPath);
134
- log.info("Migrated Windows config via rename", { from: legacyPath, to: newPath });
135
- }
136
- catch {
137
- copyFileSync(legacyPath, newPath);
138
- unlinkSync(legacyPath);
139
- log.info("Migrated Windows config via copy+delete", { from: legacyPath, to: newPath });
140
- }
141
- return true;
142
- }
143
- catch (error) {
144
- log.warn("Failed to migrate legacy Windows config, will use legacy path", {
145
- legacyPath,
146
- newPath,
147
- error: String(error),
148
- });
149
- return false;
150
- }
151
- }
152
- /**
153
- * Gets the storage path, migrating from legacy Windows location if needed.
154
- * On Windows, attempts to move legacy config to new path for alignment.
155
- */
156
- function getStoragePathWithMigration() {
157
- const configSubDir = join(getConfigDir(), "config");
158
- const newPath = join(configSubDir, "antigravity-accounts.json");
159
- if (!existsSync(configSubDir)) {
160
- try {
161
- mkdirSync(configSubDir, { recursive: true });
162
- }
163
- catch { }
164
- }
165
- const rootPath = join(getConfigDir(), "antigravity-accounts.json");
166
- if (existsSync(rootPath) && !existsSync(newPath)) {
167
- try {
168
- copyFileSync(rootPath, newPath);
169
- log.info("Migrated accounts to config/ subfolder", { from: rootPath, to: newPath });
170
- try {
171
- unlinkSync(rootPath);
172
- }
173
- catch { }
174
- }
175
- catch { }
176
- }
177
- if (process.platform === "win32") {
178
- migrateLegacyWindowsConfig();
179
- if (!existsSync(newPath)) {
180
- const legacyPath = join(getLegacyWindowsConfigDir(), "antigravity-accounts.json");
181
- if (existsSync(legacyPath)) {
182
- log.info("Using legacy Windows config path (migration failed)", {
183
- legacyPath,
184
- newPath,
185
- });
186
- return legacyPath;
187
- }
188
- }
189
- }
190
- return newPath;
191
- }
192
- export function getStoragePath() {
193
- return getStoragePathWithMigration();
194
- }
195
- /**
196
- * Gets the config directory path. Exported for use by other modules.
197
- */
198
- export { getConfigDir };
199
- const LOCK_OPTIONS = {
200
- stale: 10000,
201
- retries: {
202
- retries: 5,
203
- minTimeout: 100,
204
- maxTimeout: 1000,
205
- factor: 2,
206
- },
207
- };
208
- /**
209
- * Ensures the file has secure permissions (0600) on POSIX systems.
210
- * This is a best-effort operation and ignores errors on Windows/unsupported FS.
211
- */
212
- async function ensureSecurePermissions(path) {
213
- try {
214
- await fs.chmod(path, 0o600);
215
- }
216
- catch {
217
- }
218
- }
219
- async function ensureFileExists(path) {
220
- try {
221
- await fs.access(path);
222
- }
223
- catch {
224
- await fs.mkdir(dirname(path), { recursive: true });
225
- await fs.writeFile(path, JSON.stringify({ version: 4, accounts: [], activeIndex: 0 }, null, 2), { encoding: "utf-8", mode: 0o600 });
226
- }
227
- }
228
- async function withFileLock(path, fn) {
229
- await ensureFileExists(path);
230
- let release = null;
231
- try {
232
- release = await lockfile.lock(path, LOCK_OPTIONS);
233
- return await fn();
234
- }
235
- finally {
236
- if (release) {
237
- try {
238
- await release();
239
- }
240
- catch (unlockError) {
241
- log.warn("Failed to release lock", { error: String(unlockError) });
242
- }
243
- }
244
- }
245
- }
246
- function mergeAccountStorage(existing, incoming) {
247
- const accountMap = new Map();
248
- for (const acc of existing.accounts) {
249
- if (acc.refreshToken) {
250
- accountMap.set(acc.refreshToken, acc);
251
- }
252
- }
253
- for (const acc of incoming.accounts) {
254
- if (acc.refreshToken) {
255
- const existingAcc = accountMap.get(acc.refreshToken);
256
- if (existingAcc) {
257
- const mergedRateLimits = { ...(existingAcc.rateLimitResetTimes || {}) };
258
- const incomingRateLimits = acc.rateLimitResetTimes || {};
259
- for (const [key, resetTime] of Object.entries(incomingRateLimits)) {
260
- if (typeof resetTime === 'number') {
261
- const existingTime = mergedRateLimits[key] || 0;
262
- mergedRateLimits[key] = Math.max(existingTime, resetTime);
263
- }
264
- }
265
- const coolingDownUntil = Math.max(existingAcc.coolingDownUntil || 0, acc.coolingDownUntil || 0) || undefined;
266
- let cooldownReason = undefined;
267
- if (coolingDownUntil) {
268
- cooldownReason = (coolingDownUntil === acc.coolingDownUntil) ? acc.cooldownReason : existingAcc.cooldownReason;
269
- }
270
- const verificationRequired = existingAcc.verificationRequired || acc.verificationRequired;
271
- const verificationRequiredAt = Math.max(existingAcc.verificationRequiredAt || 0, acc.verificationRequiredAt || 0) || undefined;
272
- accountMap.set(acc.refreshToken, {
273
- ...existingAcc,
274
- ...acc,
275
- projectId: acc.projectId ?? existingAcc.projectId,
276
- managedProjectId: acc.managedProjectId ?? existingAcc.managedProjectId,
277
- rateLimitResetTimes: mergedRateLimits,
278
- lastUsed: Math.max(existingAcc.lastUsed || 0, acc.lastUsed || 0),
279
- coolingDownUntil,
280
- cooldownReason,
281
- verificationRequired,
282
- verificationRequiredAt,
283
- verificationRequiredReason: acc.verificationRequiredReason || existingAcc.verificationRequiredReason,
284
- verificationUrl: acc.verificationUrl || existingAcc.verificationUrl,
285
- enabled: acc.enabled !== undefined ? acc.enabled : existingAcc.enabled,
286
- });
287
- }
288
- else {
289
- accountMap.set(acc.refreshToken, acc);
290
- }
291
- }
292
- }
293
- return {
294
- version: 4,
295
- accounts: Array.from(accountMap.values()),
296
- activeIndex: incoming.activeIndex,
297
- activeIndexByFamily: incoming.activeIndexByFamily,
298
- };
299
- }
300
- export function deduplicateAccountsByEmail(accounts) {
301
- const emailToNewestIndex = new Map();
302
- const indicesToKeep = new Set();
303
- for (let i = 0; i < accounts.length; i++) {
304
- const acc = accounts[i];
305
- if (!acc)
306
- continue;
307
- if (!acc.email) {
308
- indicesToKeep.add(i);
309
- continue;
310
- }
311
- const existingIndex = emailToNewestIndex.get(acc.email);
312
- if (existingIndex === undefined) {
313
- emailToNewestIndex.set(acc.email, i);
314
- continue;
315
- }
316
- const existing = accounts[existingIndex];
317
- if (!existing) {
318
- emailToNewestIndex.set(acc.email, i);
319
- continue;
320
- }
321
- const currLastUsed = acc.lastUsed || 0;
322
- const existLastUsed = existing.lastUsed || 0;
323
- const currAddedAt = acc.addedAt || 0;
324
- const existAddedAt = existing.addedAt || 0;
325
- const isNewer = currLastUsed > existLastUsed ||
326
- (currLastUsed === existLastUsed && currAddedAt > existAddedAt);
327
- if (isNewer) {
328
- emailToNewestIndex.set(acc.email, i);
329
- }
330
- }
331
- for (const idx of emailToNewestIndex.values()) {
332
- indicesToKeep.add(idx);
333
- }
334
- const result = [];
335
- for (let i = 0; i < accounts.length; i++) {
336
- if (indicesToKeep.has(i)) {
337
- const acc = accounts[i];
338
- if (acc) {
339
- result.push(acc);
340
- }
341
- }
342
- }
343
- return result;
344
- }
345
- function migrateV1ToV2(v1) {
346
- return {
347
- version: 2,
348
- accounts: v1.accounts.map((acc) => {
349
- const rateLimitResetTimes = {};
350
- if (acc.isRateLimited &&
351
- acc.rateLimitResetTime &&
352
- acc.rateLimitResetTime > Date.now()) {
353
- rateLimitResetTimes.claude = acc.rateLimitResetTime;
354
- rateLimitResetTimes.gemini = acc.rateLimitResetTime;
355
- }
356
- return {
357
- email: acc.email,
358
- refreshToken: acc.refreshToken,
359
- projectId: acc.projectId,
360
- managedProjectId: acc.managedProjectId,
361
- addedAt: acc.addedAt,
362
- lastUsed: acc.lastUsed,
363
- lastSwitchReason: acc.lastSwitchReason,
364
- rateLimitResetTimes: Object.keys(rateLimitResetTimes).length > 0
365
- ? rateLimitResetTimes
366
- : undefined,
367
- };
368
- }),
369
- activeIndex: v1.activeIndex,
370
- };
371
- }
372
- export function migrateV2ToV3(v2) {
373
- return {
374
- version: 3,
375
- accounts: v2.accounts.map((acc) => {
376
- const rateLimitResetTimes = {};
377
- if (acc.rateLimitResetTimes?.claude &&
378
- acc.rateLimitResetTimes.claude > Date.now()) {
379
- rateLimitResetTimes.claude = acc.rateLimitResetTimes.claude;
380
- }
381
- if (acc.rateLimitResetTimes?.gemini &&
382
- acc.rateLimitResetTimes.gemini > Date.now()) {
383
- rateLimitResetTimes["gemini-antigravity"] =
384
- acc.rateLimitResetTimes.gemini;
385
- }
386
- return {
387
- email: acc.email,
388
- refreshToken: acc.refreshToken,
389
- projectId: acc.projectId,
390
- managedProjectId: acc.managedProjectId,
391
- addedAt: acc.addedAt,
392
- lastUsed: acc.lastUsed,
393
- lastSwitchReason: acc.lastSwitchReason,
394
- rateLimitResetTimes: Object.keys(rateLimitResetTimes).length > 0
395
- ? rateLimitResetTimes
396
- : undefined,
397
- };
398
- }),
399
- activeIndex: v2.activeIndex,
400
- };
401
- }
402
- export function migrateV3ToV4(v3) {
403
- return {
404
- version: 4,
405
- accounts: v3.accounts.map((acc) => ({
406
- ...acc,
407
- fingerprint: undefined,
408
- fingerprintHistory: undefined,
409
- })),
410
- activeIndex: v3.activeIndex,
411
- activeIndexByFamily: v3.activeIndexByFamily,
412
- };
413
- }
414
- export async function loadAccounts() {
415
- try {
416
- const path = getStoragePath();
417
- await ensureSecurePermissions(path);
418
- const content = await fs.readFile(path, "utf-8");
419
- const data = JSON.parse(content);
420
- if (!Array.isArray(data.accounts)) {
421
- log.warn("Invalid storage format, ignoring");
422
- return null;
423
- }
424
- let storage;
425
- if (data.version === 1) {
426
- log.info("Migrating account storage from v1 to v4");
427
- const v2 = migrateV1ToV2(data);
428
- const v3 = migrateV2ToV3(v2);
429
- storage = migrateV3ToV4(v3);
430
- try {
431
- await saveAccounts(storage);
432
- log.info("Migration to v4 complete");
433
- }
434
- catch (saveError) {
435
- log.warn("Failed to persist migrated storage", {
436
- error: String(saveError),
437
- });
438
- }
439
- }
440
- else if (data.version === 2) {
441
- log.info("Migrating account storage from v2 to v4");
442
- const v3 = migrateV2ToV3(data);
443
- storage = migrateV3ToV4(v3);
444
- try {
445
- await saveAccounts(storage);
446
- log.info("Migration to v4 complete");
447
- }
448
- catch (saveError) {
449
- log.warn("Failed to persist migrated storage", {
450
- error: String(saveError),
451
- });
452
- }
453
- }
454
- else if (data.version === 3) {
455
- log.info("Migrating account storage from v3 to v4");
456
- storage = migrateV3ToV4(data);
457
- try {
458
- await saveAccounts(storage);
459
- log.info("Migration to v4 complete");
460
- }
461
- catch (saveError) {
462
- log.warn("Failed to persist migrated storage", {
463
- error: String(saveError),
464
- });
465
- }
466
- }
467
- else if (data.version === 4) {
468
- storage = data;
469
- }
470
- else {
471
- log.warn("Unknown storage version, ignoring", {
472
- version: data.version,
473
- });
474
- return null;
475
- }
476
- const validAccounts = storage.accounts.filter((a) => {
477
- return (!!a &&
478
- typeof a === "object" &&
479
- typeof a.refreshToken === "string");
480
- });
481
- const deduplicatedAccounts = deduplicateAccountsByEmail(validAccounts);
482
- let activeIndex = typeof storage.activeIndex === "number" &&
483
- Number.isFinite(storage.activeIndex)
484
- ? storage.activeIndex
485
- : 0;
486
- if (deduplicatedAccounts.length > 0) {
487
- activeIndex = Math.min(activeIndex, deduplicatedAccounts.length - 1);
488
- activeIndex = Math.max(activeIndex, 0);
489
- }
490
- else {
491
- activeIndex = 0;
492
- }
493
- return {
494
- version: 4,
495
- accounts: deduplicatedAccounts,
496
- activeIndex,
497
- activeIndexByFamily: storage.activeIndexByFamily,
498
- };
499
- }
500
- catch (error) {
501
- const code = error.code;
502
- if (code === "ENOENT") {
503
- return null;
504
- }
505
- log.error("Failed to load account storage", { error: String(error) });
506
- return null;
507
- }
508
- }
509
- export async function saveAccounts(storage) {
510
- const path = getStoragePath();
511
- const configDir = dirname(path);
512
- await fs.mkdir(configDir, { recursive: true });
513
- await ensureGitignore(configDir);
514
- await withFileLock(path, async () => {
515
- const existing = await loadAccountsUnsafe();
516
- const merged = existing ? mergeAccountStorage(existing, storage) : storage;
517
- const tempPath = `${path}.${randomBytes(6).toString("hex")}.tmp`;
518
- const content = JSON.stringify(merged, null, 2);
519
- try {
520
- await fs.writeFile(tempPath, content, { encoding: "utf-8", mode: 0o600 });
521
- await fs.rename(tempPath, path);
522
- }
523
- catch (error) {
524
- try {
525
- await fs.unlink(tempPath);
526
- }
527
- catch {
528
- }
529
- throw error;
530
- }
531
- });
532
- }
533
- /**
534
- * Save accounts storage by replacing the entire file (no merge).
535
- * Use this for destructive operations like delete where we need to
536
- * remove accounts that would otherwise be merged back from existing storage.
537
- */
538
- export async function saveAccountsReplace(storage) {
539
- const path = getStoragePath();
540
- const configDir = dirname(path);
541
- await fs.mkdir(configDir, { recursive: true });
542
- await ensureGitignore(configDir);
543
- await withFileLock(path, async () => {
544
- const tempPath = `${path}.${randomBytes(6).toString("hex")}.tmp`;
545
- const content = JSON.stringify(storage, null, 2);
546
- try {
547
- await fs.writeFile(tempPath, content, { encoding: "utf-8", mode: 0o600 });
548
- await fs.rename(tempPath, path);
549
- }
550
- catch (error) {
551
- try {
552
- await fs.unlink(tempPath);
553
- }
554
- catch {
555
- }
556
- throw error;
557
- }
558
- });
559
- }
560
- async function loadAccountsUnsafe() {
561
- try {
562
- const path = getStoragePath();
563
- await ensureSecurePermissions(path);
564
- const content = await fs.readFile(path, "utf-8");
565
- const parsed = JSON.parse(content);
566
- if (parsed.version === 1) {
567
- return migrateV3ToV4(migrateV2ToV3(migrateV1ToV2(parsed)));
568
- }
569
- if (parsed.version === 2) {
570
- return migrateV3ToV4(migrateV2ToV3(parsed));
571
- }
572
- if (parsed.version === 3) {
573
- return migrateV3ToV4(parsed);
574
- }
575
- return {
576
- ...parsed,
577
- accounts: deduplicateAccountsByEmail(parsed.accounts),
578
- };
579
- }
580
- catch (error) {
581
- const code = error.code;
582
- if (code === "ENOENT") {
583
- return null;
584
- }
585
- return null;
586
- }
587
- }
588
- export async function clearAccounts() {
589
- try {
590
- const path = getStoragePath();
591
- await fs.unlink(path);
592
- }
593
- catch (error) {
594
- const code = error.code;
595
- if (code !== "ENOENT") {
596
- log.error("Failed to clear account storage", { error: String(error) });
597
- }
598
- }
599
- }
@@ -1,4 +0,0 @@
1
- import type { SignatureStore, ThoughtBuffer } from '../core/streaming/types';
2
- export declare function createSignatureStore(): SignatureStore;
3
- export declare function createThoughtBuffer(): ThoughtBuffer;
4
- export declare const defaultSignatureStore: SignatureStore;
@@ -1,24 +0,0 @@
1
- export function createSignatureStore() {
2
- const store = new Map();
3
- return {
4
- get: (key) => store.get(key),
5
- set: (key, value) => {
6
- store.set(key, value);
7
- },
8
- has: (key) => store.has(key),
9
- delete: (key) => {
10
- store.delete(key);
11
- },
12
- };
13
- }
14
- export function createThoughtBuffer() {
15
- const buffer = new Map();
16
- return {
17
- get: (index) => buffer.get(index),
18
- set: (index, text) => {
19
- buffer.set(index, text);
20
- },
21
- clear: () => buffer.clear(),
22
- };
23
- }
24
- export const defaultSignatureStore = createSignatureStore();