camo-gemini 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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +242 -0
  3. package/dist/client/camofox-client.d.ts +21 -0
  4. package/dist/client/camofox-client.d.ts.map +1 -0
  5. package/dist/client/camofox-client.js +260 -0
  6. package/dist/client/camofox-client.js.map +1 -0
  7. package/dist/config.d.ts +3 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +94 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/core/browser-js.d.ts +27 -0
  12. package/dist/core/browser-js.d.ts.map +1 -0
  13. package/dist/core/browser-js.js +172 -0
  14. package/dist/core/browser-js.js.map +1 -0
  15. package/dist/core/constants.d.ts +78 -0
  16. package/dist/core/constants.d.ts.map +1 -0
  17. package/dist/core/constants.js +115 -0
  18. package/dist/core/constants.js.map +1 -0
  19. package/dist/core/error-messages.d.ts +8 -0
  20. package/dist/core/error-messages.d.ts.map +1 -0
  21. package/dist/core/error-messages.js +121 -0
  22. package/dist/core/error-messages.js.map +1 -0
  23. package/dist/core/failover.d.ts +21 -0
  24. package/dist/core/failover.d.ts.map +1 -0
  25. package/dist/core/failover.js +47 -0
  26. package/dist/core/failover.js.map +1 -0
  27. package/dist/core/logger.d.ts +13 -0
  28. package/dist/core/logger.d.ts.map +1 -0
  29. package/dist/core/logger.js +37 -0
  30. package/dist/core/logger.js.map +1 -0
  31. package/dist/core/request-builder.d.ts +20 -0
  32. package/dist/core/request-builder.d.ts.map +1 -0
  33. package/dist/core/request-builder.js +210 -0
  34. package/dist/core/request-builder.js.map +1 -0
  35. package/dist/core/response-parser.d.ts +12 -0
  36. package/dist/core/response-parser.d.ts.map +1 -0
  37. package/dist/core/response-parser.js +221 -0
  38. package/dist/core/response-parser.js.map +1 -0
  39. package/dist/core/retry.d.ts +10 -0
  40. package/dist/core/retry.d.ts.map +1 -0
  41. package/dist/core/retry.js +132 -0
  42. package/dist/core/retry.js.map +1 -0
  43. package/dist/core/stream-parser.d.ts +9 -0
  44. package/dist/core/stream-parser.d.ts.map +1 -0
  45. package/dist/core/stream-parser.js +69 -0
  46. package/dist/core/stream-parser.js.map +1 -0
  47. package/dist/core/token-manager.d.ts +9 -0
  48. package/dist/core/token-manager.d.ts.map +1 -0
  49. package/dist/core/token-manager.js +64 -0
  50. package/dist/core/token-manager.js.map +1 -0
  51. package/dist/core/utils.d.ts +2 -0
  52. package/dist/core/utils.d.ts.map +1 -0
  53. package/dist/core/utils.js +15 -0
  54. package/dist/core/utils.js.map +1 -0
  55. package/dist/dashboard/server.d.ts +31 -0
  56. package/dist/dashboard/server.d.ts.map +1 -0
  57. package/dist/dashboard/server.js +190 -0
  58. package/dist/dashboard/server.js.map +1 -0
  59. package/dist/errors.d.ts +32 -0
  60. package/dist/errors.d.ts.map +1 -0
  61. package/dist/errors.js +59 -0
  62. package/dist/errors.js.map +1 -0
  63. package/dist/index.d.ts +3 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +36 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/server.d.ts +31 -0
  68. package/dist/server.d.ts.map +1 -0
  69. package/dist/server.js +54 -0
  70. package/dist/server.js.map +1 -0
  71. package/dist/services/account.d.ts +16 -0
  72. package/dist/services/account.d.ts.map +1 -0
  73. package/dist/services/account.js +55 -0
  74. package/dist/services/account.js.map +1 -0
  75. package/dist/services/auth.d.ts +39 -0
  76. package/dist/services/auth.d.ts.map +1 -0
  77. package/dist/services/auth.js +285 -0
  78. package/dist/services/auth.js.map +1 -0
  79. package/dist/services/chat.d.ts +18 -0
  80. package/dist/services/chat.d.ts.map +1 -0
  81. package/dist/services/chat.js +151 -0
  82. package/dist/services/chat.js.map +1 -0
  83. package/dist/services/cookie-rotation.d.ts +25 -0
  84. package/dist/services/cookie-rotation.d.ts.map +1 -0
  85. package/dist/services/cookie-rotation.js +138 -0
  86. package/dist/services/cookie-rotation.js.map +1 -0
  87. package/dist/services/gems.d.ts +33 -0
  88. package/dist/services/gems.d.ts.map +1 -0
  89. package/dist/services/gems.js +202 -0
  90. package/dist/services/gems.js.map +1 -0
  91. package/dist/services/generate.d.ts +27 -0
  92. package/dist/services/generate.d.ts.map +1 -0
  93. package/dist/services/generate.js +149 -0
  94. package/dist/services/generate.js.map +1 -0
  95. package/dist/services/health.d.ts +20 -0
  96. package/dist/services/health.d.ts.map +1 -0
  97. package/dist/services/health.js +77 -0
  98. package/dist/services/health.js.map +1 -0
  99. package/dist/services/upload.d.ts +17 -0
  100. package/dist/services/upload.d.ts.map +1 -0
  101. package/dist/services/upload.js +120 -0
  102. package/dist/services/upload.js.map +1 -0
  103. package/dist/setup.d.ts +7 -0
  104. package/dist/setup.d.ts.map +1 -0
  105. package/dist/setup.js +165 -0
  106. package/dist/setup.js.map +1 -0
  107. package/dist/state.d.ts +57 -0
  108. package/dist/state.d.ts.map +1 -0
  109. package/dist/state.js +260 -0
  110. package/dist/state.js.map +1 -0
  111. package/dist/tools/account.d.ts +4 -0
  112. package/dist/tools/account.d.ts.map +1 -0
  113. package/dist/tools/account.js +29 -0
  114. package/dist/tools/account.js.map +1 -0
  115. package/dist/tools/auth.d.ts +4 -0
  116. package/dist/tools/auth.d.ts.map +1 -0
  117. package/dist/tools/auth.js +56 -0
  118. package/dist/tools/auth.js.map +1 -0
  119. package/dist/tools/chat.d.ts +4 -0
  120. package/dist/tools/chat.d.ts.map +1 -0
  121. package/dist/tools/chat.js +101 -0
  122. package/dist/tools/chat.js.map +1 -0
  123. package/dist/tools/gems.d.ts +4 -0
  124. package/dist/tools/gems.d.ts.map +1 -0
  125. package/dist/tools/gems.js +93 -0
  126. package/dist/tools/gems.js.map +1 -0
  127. package/dist/tools/health.d.ts +4 -0
  128. package/dist/tools/health.d.ts.map +1 -0
  129. package/dist/tools/health.js +13 -0
  130. package/dist/tools/health.js.map +1 -0
  131. package/dist/tools/media.d.ts +4 -0
  132. package/dist/tools/media.d.ts.map +1 -0
  133. package/dist/tools/media.js +65 -0
  134. package/dist/tools/media.js.map +1 -0
  135. package/dist/types.d.ts +292 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +2 -0
  138. package/dist/types.js.map +1 -0
  139. package/package.json +66 -0
@@ -0,0 +1,57 @@
1
+ import type { AccountEntry, AccountHealth, ChatSession, GeminiSession } from "./types.js";
2
+ export declare class StateManager {
3
+ /** Per-account state registry */
4
+ private accounts;
5
+ /** Currently active account index */
6
+ private activeIndex;
7
+ private chats;
8
+ /** Register a new account entry */
9
+ addAccount(accountIndex: number, camofoxUserId: string): AccountEntry;
10
+ /** Remove an account */
11
+ removeAccount(accountIndex: number): boolean;
12
+ /** Get account entry */
13
+ getAccount(accountIndex: number): AccountEntry | undefined;
14
+ /** Get all accounts */
15
+ getAllAccounts(): AccountEntry[];
16
+ /** Check if account exists */
17
+ hasAccount(accountIndex: number): boolean;
18
+ /** Get active account index */
19
+ get activeAccountIndex(): number | null;
20
+ /** Set active account */
21
+ setActiveAccount(accountIndex: number): void;
22
+ /** Get active account entry */
23
+ getActiveAccount(): AccountEntry | undefined;
24
+ /** Get session for account (or active account if not specified) */
25
+ getSession(accountIndex?: number): GeminiSession | null;
26
+ setSession(accountIndex: number, session: GeminiSession): void;
27
+ setSession(session: GeminiSession): void;
28
+ clearSession(accountIndex?: number): void;
29
+ /** @deprecated Use getSession(accountIndex) instead */
30
+ get session(): GeminiSession | null;
31
+ set session(value: GeminiSession | null);
32
+ isAuthenticated(accountIndex?: number): boolean;
33
+ updateTokens(tokens: NonNullable<GeminiSession["tokens"]>, accountIndex?: number): void;
34
+ recordRotation(accountIndex?: number): void;
35
+ isRotationOverdue(accountIndex?: number): boolean;
36
+ /** Record a successful operation for account */
37
+ recordSuccess(accountIndex: number): void;
38
+ /** Record an error for account */
39
+ recordError(accountIndex: number): void;
40
+ /** Set account health directly */
41
+ setHealth(accountIndex: number, health: AccountHealth): void;
42
+ /** Get healthy accounts (healthy or degraded, not in cooldown) */
43
+ getHealthyAccounts(): AccountEntry[];
44
+ /** Get next healthy account for failover (round-robin from active) */
45
+ getNextHealthyAccount(excludeIndex?: number): AccountEntry | undefined;
46
+ /** Set tab ID for account */
47
+ setTabId(accountIndex: number, tabId: string): void;
48
+ /** Get tab ID for account */
49
+ getTabId(accountIndex?: number): string | null;
50
+ getChat(conversationId: string): ChatSession | undefined;
51
+ setChat(conversationId: string, chat: ChatSession): void;
52
+ deleteChat(conversationId: string): boolean;
53
+ listChats(): ChatSession[];
54
+ /** Clear all state */
55
+ clear(): void;
56
+ }
57
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1F,qBAAa,YAAY;IACvB,iCAAiC;IACjC,OAAO,CAAC,QAAQ,CAAmC;IACnD,qCAAqC;IACrC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,KAAK,CAAuC;IAIpD,mCAAmC;IACnC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,YAAY;IAsBrE,wBAAwB;IACxB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAQ5C,wBAAwB;IACxB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI1D,uBAAuB;IACvB,cAAc,IAAI,YAAY,EAAE;IAIhC,8BAA8B;IAC9B,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAMzC,+BAA+B;IAC/B,IAAI,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAEtC;IAED,yBAAyB;IACzB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAQ5C,+BAA+B;IAC/B,gBAAgB,IAAI,YAAY,GAAG,SAAS;IAO5C,mEAAmE;IACnE,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAMvD,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAC9D,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA2BxC,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAqBzC,uDAAuD;IACvD,IAAI,OAAO,IAAI,aAAa,GAAG,IAAI,CAElC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,EAkBtC;IAED,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO;IAI/C,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAOvF,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAO3C,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO;IAQjD,gDAAgD;IAChD,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAWzC,kCAAkC;IAClC,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAkBvC,kCAAkC;IAClC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI;IAU5D,kEAAkE;IAClE,kBAAkB,IAAI,YAAY,EAAE;IAWpC,sEAAsE;IACtE,qBAAqB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAmBtE,6BAA6B;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAUnD,6BAA6B;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAM9C,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxD,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI;IAIxD,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAI3C,SAAS,IAAI,WAAW,EAAE;IAM1B,sBAAsB;IACtB,KAAK,IAAI,IAAI;CAKd"}
package/dist/state.js ADDED
@@ -0,0 +1,260 @@
1
+ import { COOKIE_ROTATION_INTERVAL_MS, HEALTH_BACKOFF_BASE_MS, HEALTH_BACKOFF_CAP_MS } from "./core/constants.js";
2
+ export class StateManager {
3
+ /** Per-account state registry */
4
+ accounts = new Map();
5
+ /** Currently active account index */
6
+ activeIndex = null;
7
+ chats = new Map();
8
+ // === Account Registry ===
9
+ /** Register a new account entry */
10
+ addAccount(accountIndex, camofoxUserId) {
11
+ if (this.accounts.has(accountIndex)) {
12
+ return this.accounts.get(accountIndex);
13
+ }
14
+ const entry = {
15
+ accountIndex,
16
+ session: null,
17
+ health: "offline",
18
+ camofoxUserId,
19
+ tabId: null,
20
+ lastSuccessAt: 0,
21
+ lastErrorAt: 0,
22
+ consecutiveErrors: 0,
23
+ cooldownUntil: 0,
24
+ isLoggedIn: false
25
+ };
26
+ this.accounts.set(accountIndex, entry);
27
+ return entry;
28
+ }
29
+ /** Remove an account */
30
+ removeAccount(accountIndex) {
31
+ if (this.activeIndex === accountIndex) {
32
+ this.activeIndex = null;
33
+ }
34
+ return this.accounts.delete(accountIndex);
35
+ }
36
+ /** Get account entry */
37
+ getAccount(accountIndex) {
38
+ return this.accounts.get(accountIndex);
39
+ }
40
+ /** Get all accounts */
41
+ getAllAccounts() {
42
+ return Array.from(this.accounts.values());
43
+ }
44
+ /** Check if account exists */
45
+ hasAccount(accountIndex) {
46
+ return this.accounts.has(accountIndex);
47
+ }
48
+ // === Active Account ===
49
+ /** Get active account index */
50
+ get activeAccountIndex() {
51
+ return this.activeIndex;
52
+ }
53
+ /** Set active account */
54
+ setActiveAccount(accountIndex) {
55
+ if (!this.accounts.has(accountIndex)) {
56
+ throw new Error(`Account ${accountIndex} not registered`);
57
+ }
58
+ this.activeIndex = accountIndex;
59
+ }
60
+ /** Get active account entry */
61
+ getActiveAccount() {
62
+ if (this.activeIndex === null)
63
+ return undefined;
64
+ return this.accounts.get(this.activeIndex);
65
+ }
66
+ // === Session Management (backward compatible) ===
67
+ /** Get session for account (or active account if not specified) */
68
+ getSession(accountIndex) {
69
+ const idx = accountIndex ?? this.activeIndex;
70
+ if (idx === null)
71
+ return null;
72
+ return this.accounts.get(idx)?.session ?? null;
73
+ }
74
+ /** Set session for account */
75
+ setSession(accountIndexOrSession, maybeSession) {
76
+ if (typeof accountIndexOrSession === "number") {
77
+ const entry = this.accounts.get(accountIndexOrSession);
78
+ if (!entry || !maybeSession) {
79
+ throw new Error(`Account ${accountIndexOrSession} not registered`);
80
+ }
81
+ entry.session = maybeSession;
82
+ entry.isLoggedIn = true;
83
+ entry.health = "healthy";
84
+ entry.consecutiveErrors = 0;
85
+ entry.lastSuccessAt = Date.now();
86
+ entry.tabId = maybeSession.tabId;
87
+ this.activeIndex = accountIndexOrSession;
88
+ return;
89
+ }
90
+ const session = accountIndexOrSession;
91
+ const accountIndex = session.accountIndex;
92
+ if (!this.accounts.has(accountIndex)) {
93
+ this.addAccount(accountIndex, session.userId || `camo-gemini-acct${accountIndex}`);
94
+ }
95
+ this.setSession(accountIndex, session);
96
+ }
97
+ clearSession(accountIndex) {
98
+ const idx = accountIndex ?? this.activeIndex;
99
+ if (idx === null) {
100
+ return;
101
+ }
102
+ const entry = this.accounts.get(idx);
103
+ if (entry) {
104
+ entry.session = null;
105
+ entry.isLoggedIn = false;
106
+ entry.health = "offline";
107
+ entry.tabId = null;
108
+ }
109
+ if (accountIndex === undefined && this.activeIndex === idx) {
110
+ this.activeIndex = null;
111
+ }
112
+ }
113
+ // === Backward-compatible property (legacy single-session access) ===
114
+ /** @deprecated Use getSession(accountIndex) instead */
115
+ get session() {
116
+ return this.getSession();
117
+ }
118
+ set session(value) {
119
+ if (value === null) {
120
+ if (this.activeIndex !== null) {
121
+ this.clearSession(this.activeIndex);
122
+ }
123
+ return;
124
+ }
125
+ // Legacy: auto-create account 0 if none exists
126
+ if (this.activeIndex === null) {
127
+ if (!this.accounts.has(0)) {
128
+ // This should be set by AuthService, but fallback for backward compat
129
+ this.addAccount(0, "camo-gemini-acct0");
130
+ }
131
+ this.activeIndex = 0;
132
+ }
133
+ this.setSession(this.activeIndex, value);
134
+ }
135
+ isAuthenticated(accountIndex) {
136
+ return this.getSession(accountIndex)?.authenticated === true;
137
+ }
138
+ updateTokens(tokens, accountIndex) {
139
+ const session = this.getSession(accountIndex);
140
+ if (session) {
141
+ session.tokens = tokens;
142
+ }
143
+ }
144
+ recordRotation(accountIndex) {
145
+ const session = this.getSession(accountIndex);
146
+ if (session) {
147
+ session.lastRotation = Date.now();
148
+ }
149
+ }
150
+ isRotationOverdue(accountIndex) {
151
+ const session = this.getSession(accountIndex);
152
+ if (!session)
153
+ return false;
154
+ return Date.now() - session.lastRotation > COOKIE_ROTATION_INTERVAL_MS;
155
+ }
156
+ // === Health Tracking ===
157
+ /** Record a successful operation for account */
158
+ recordSuccess(accountIndex) {
159
+ const entry = this.accounts.get(accountIndex);
160
+ if (entry) {
161
+ entry.lastSuccessAt = Date.now();
162
+ entry.consecutiveErrors = 0;
163
+ if (entry.health === "degraded") {
164
+ entry.health = "healthy";
165
+ }
166
+ }
167
+ }
168
+ /** Record an error for account */
169
+ recordError(accountIndex) {
170
+ const entry = this.accounts.get(accountIndex);
171
+ if (entry) {
172
+ entry.lastErrorAt = Date.now();
173
+ entry.consecutiveErrors += 1;
174
+ // Health state transitions
175
+ if (entry.consecutiveErrors >= 5) {
176
+ entry.health = "cooldown";
177
+ // Exponential backoff: 30s, 60s, 120s, 240s... capped at 600s
178
+ const backoff = Math.min(HEALTH_BACKOFF_BASE_MS * Math.pow(2, entry.consecutiveErrors - 5), HEALTH_BACKOFF_CAP_MS);
179
+ entry.cooldownUntil = Date.now() + backoff;
180
+ }
181
+ else if (entry.consecutiveErrors >= 2) {
182
+ entry.health = "degraded";
183
+ }
184
+ }
185
+ }
186
+ /** Set account health directly */
187
+ setHealth(accountIndex, health) {
188
+ const entry = this.accounts.get(accountIndex);
189
+ if (entry) {
190
+ entry.health = health;
191
+ if (health === "cooldown") {
192
+ entry.cooldownUntil = Date.now() + 60000;
193
+ }
194
+ }
195
+ }
196
+ /** Get healthy accounts (healthy or degraded, not in cooldown) */
197
+ getHealthyAccounts() {
198
+ const now = Date.now();
199
+ return this.getAllAccounts().filter((account) => {
200
+ if (account.health === "cooldown" && now >= account.cooldownUntil) {
201
+ account.health = "degraded";
202
+ }
203
+ return account.isLoggedIn && (account.health === "healthy" || account.health === "degraded");
204
+ });
205
+ }
206
+ /** Get next healthy account for failover (round-robin from active) */
207
+ getNextHealthyAccount(excludeIndex) {
208
+ const healthy = this.getHealthyAccounts().filter((account) => account.accountIndex !== excludeIndex);
209
+ if (healthy.length === 0)
210
+ return undefined;
211
+ // Prefer healthy over degraded
212
+ const fullyHealthy = healthy.filter((account) => account.health === "healthy");
213
+ if (fullyHealthy.length > 0) {
214
+ // Sort by last success time (most recently successful first)
215
+ fullyHealthy.sort((a, b) => b.lastSuccessAt - a.lastSuccessAt);
216
+ return fullyHealthy[0];
217
+ }
218
+ // Fall back to degraded
219
+ healthy.sort((a, b) => a.consecutiveErrors - b.consecutiveErrors);
220
+ return healthy[0];
221
+ }
222
+ // === Tab Tracking ===
223
+ /** Set tab ID for account */
224
+ setTabId(accountIndex, tabId) {
225
+ const entry = this.accounts.get(accountIndex);
226
+ if (entry) {
227
+ entry.tabId = tabId;
228
+ if (entry.session) {
229
+ entry.session.tabId = tabId;
230
+ }
231
+ }
232
+ }
233
+ /** Get tab ID for account */
234
+ getTabId(accountIndex) {
235
+ const idx = accountIndex ?? this.activeIndex;
236
+ if (idx === null)
237
+ return null;
238
+ return this.accounts.get(idx)?.tabId ?? this.accounts.get(idx)?.session?.tabId ?? null;
239
+ }
240
+ getChat(conversationId) {
241
+ return this.chats.get(conversationId);
242
+ }
243
+ setChat(conversationId, chat) {
244
+ this.chats.set(conversationId, chat);
245
+ }
246
+ deleteChat(conversationId) {
247
+ return this.chats.delete(conversationId);
248
+ }
249
+ listChats() {
250
+ return Array.from(this.chats.values());
251
+ }
252
+ // === Reset ===
253
+ /** Clear all state */
254
+ clear() {
255
+ this.accounts.clear();
256
+ this.activeIndex = null;
257
+ this.chats.clear();
258
+ }
259
+ }
260
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolDeps } from "../server.js";
3
+ export declare function registerAccountTools(server: McpServer, deps: ToolDeps): void;
4
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAM7C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CA+B5E"}
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import { okResult, toErrorResult } from "../errors.js";
3
+ const AddAccountSchema = z.object({
4
+ accountIndex: z.number().int().min(0).max(9)
5
+ });
6
+ export function registerAccountTools(server, deps) {
7
+ server.tool("gemini_add_account", "Add Google account for Gemini", {
8
+ accountIndex: z.number().int().min(0).max(9).describe("Google account index (0-9)")
9
+ }, async (input) => {
10
+ try {
11
+ const parsed = AddAccountSchema.parse(input);
12
+ const result = await deps.accountService.addAccount(parsed.accountIndex);
13
+ return okResult(result);
14
+ }
15
+ catch (error) {
16
+ return toErrorResult(error);
17
+ }
18
+ });
19
+ server.tool("gemini_list_accounts", "List configured accounts", {}, async () => {
20
+ try {
21
+ const result = deps.accountService.listAccounts();
22
+ return okResult(result);
23
+ }
24
+ catch (error) {
25
+ return toErrorResult(error);
26
+ }
27
+ });
28
+ }
29
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,IAAc;IACpE,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,+BAA+B,EAC/B;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;KACpF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACzE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,0BAA0B,EAC1B,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;YAClD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolDeps } from "../server.js";
3
+ export declare function registerAuthTools(server: McpServer, deps: ToolDeps): void;
4
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAmEzE"}
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import { okResult, toErrorResult } from "../errors.js";
3
+ export function registerAuthTools(server, deps) {
4
+ let healthCheckStarted = false;
5
+ server.tool("gemini_login", "Connect to an existing Gemini session in CamoFox browser. This tool does NOT perform credential-based login — it validates and connects to a pre-authenticated browser session. User must already be logged into Google in the CamoFox browser profile.", {
6
+ accountIndex: z
7
+ .number()
8
+ .int()
9
+ .min(0)
10
+ .max(9)
11
+ .optional()
12
+ .describe("Google account index (0 = default, 1+ = additional accounts)")
13
+ }, async (input) => {
14
+ try {
15
+ const args = z.object({ accountIndex: z.number().int().min(0).max(9).optional() }).parse(input);
16
+ const session = await deps.auth.login(args.accountIndex ?? 0);
17
+ if (!healthCheckStarted) {
18
+ deps.health.startPeriodicCheck();
19
+ healthCheckStarted = true;
20
+ }
21
+ const result = {
22
+ authenticated: session.authenticated,
23
+ accountIndex: session.accountIndex,
24
+ tabId: session.tabId,
25
+ tokensExtracted: !!session.tokens,
26
+ rotationStarted: !!session.tokens,
27
+ authenticatedEmail: session.authenticatedEmail ?? null,
28
+ sessionBased: true,
29
+ note: "Session-based authentication — connected to existing CamoFox browser profile. No credentials were validated."
30
+ };
31
+ return okResult(result);
32
+ }
33
+ catch (error) {
34
+ return toErrorResult(error);
35
+ }
36
+ });
37
+ server.tool("gemini_auth_status", "Check authentication status", {}, async () => {
38
+ try {
39
+ const status = deps.auth.getStatus();
40
+ return okResult(status);
41
+ }
42
+ catch (error) {
43
+ return toErrorResult(error);
44
+ }
45
+ });
46
+ server.tool("gemini_logout", "Logout from Gemini. Stops cookie rotation, closes the browser tab, and clears session state.", {}, async () => {
47
+ try {
48
+ await deps.auth.logout();
49
+ return okResult({ loggedOut: true });
50
+ }
51
+ catch (error) {
52
+ return toErrorResult(error);
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,IAAc;IACjE,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,MAAM,CAAC,IAAI,CACT,cAAc,EACd,yPAAyP,EACzP;QACE,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,8DAA8D,CAAC;KAC5E,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBACjC,kBAAkB,GAAG,IAAI,CAAC;YAC5B,CAAC;YACD,MAAM,MAAM,GAAG;gBACb,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM;gBACjC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM;gBACjC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,IAAI;gBACtD,YAAY,EAAE,IAAI;gBAClB,IAAI,EAAE,8GAA8G;aACrH,CAAC;YACF,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,6BAA6B,EAC7B,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,8FAA8F,EAC9F,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolDeps } from "../server.js";
3
+ export declare function registerChatTools(server: McpServer, deps: ToolDeps): void;
4
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/tools/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAgB7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAoGzE"}
@@ -0,0 +1,101 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { z } from "zod";
3
+ import { okResult, toErrorResult } from "../errors.js";
4
+ const PromptSchema = z.object({
5
+ prompt: z.string().min(1),
6
+ model: z.string().optional(),
7
+ accountIndex: z.number().int().min(0).optional(),
8
+ autoDelete: z.boolean().optional().default(true)
9
+ });
10
+ const ChatSchema = z.object({
11
+ prompt: z.string().min(1),
12
+ conversationId: z.string().min(1).optional(),
13
+ model: z.string().optional(),
14
+ accountIndex: z.number().int().min(0).optional()
15
+ });
16
+ export function registerChatTools(server, deps) {
17
+ server.tool("gemini_generate", "Generate text with Google Gemini", {
18
+ prompt: z.string().min(1).describe("Prompt text to send to Gemini"),
19
+ model: z.string().optional().describe("Optional Gemini model name or alias"),
20
+ accountIndex: z.number().int().min(0).optional().describe("Optional account index"),
21
+ autoDelete: z.boolean().optional().default(true).describe("Auto-delete chat history after generation (default: true)")
22
+ }, async (input) => {
23
+ try {
24
+ const args = PromptSchema.parse(input);
25
+ const result = await deps.generate.generate({
26
+ prompt: args.prompt,
27
+ model: args.model,
28
+ accountIndex: args.accountIndex
29
+ });
30
+ const accountIndex = args.accountIndex ?? deps.state.activeAccountIndex ?? 0;
31
+ const shouldAutoDelete = (args.autoDelete ?? true) && deps.config.AUTO_DELETE_CHAT;
32
+ if (shouldAutoDelete && result.conversationId) {
33
+ try {
34
+ await deps.generate.deleteConversation(accountIndex, result.conversationId);
35
+ }
36
+ catch {
37
+ // non-critical cleanup
38
+ }
39
+ }
40
+ return okResult({ text: result.output.candidates[0]?.text ?? "" });
41
+ }
42
+ catch (error) {
43
+ return toErrorResult(error);
44
+ }
45
+ });
46
+ server.tool("gemini_stream", "Stream text generation", {
47
+ prompt: z.string().min(1).describe("Prompt text to send to Gemini"),
48
+ model: z.string().optional().describe("Optional Gemini model name or alias"),
49
+ accountIndex: z.number().int().min(0).optional().describe("Optional account index"),
50
+ autoDelete: z.boolean().optional().default(true).describe("Auto-delete chat history after generation (default: true)")
51
+ }, async (input) => {
52
+ try {
53
+ const args = PromptSchema.parse(input);
54
+ const result = await deps.generate.generate({
55
+ prompt: args.prompt,
56
+ model: args.model,
57
+ accountIndex: args.accountIndex
58
+ });
59
+ const accountIndex = args.accountIndex ?? deps.state.activeAccountIndex ?? 0;
60
+ const shouldAutoDelete = (args.autoDelete ?? true) && deps.config.AUTO_DELETE_CHAT;
61
+ if (shouldAutoDelete && result.conversationId) {
62
+ try {
63
+ await deps.generate.deleteConversation(accountIndex, result.conversationId);
64
+ }
65
+ catch {
66
+ // non-critical cleanup
67
+ }
68
+ }
69
+ return okResult({ text: result.output.candidates[0]?.text ?? "" });
70
+ }
71
+ catch (error) {
72
+ return toErrorResult(error);
73
+ }
74
+ });
75
+ server.tool("gemini_chat", "Continue a conversation", {
76
+ prompt: z.string().min(1).describe("Prompt text to send to Gemini"),
77
+ conversationId: z.string().min(1).optional().describe("Conversation ID (optional; generated if omitted)"),
78
+ model: z.string().optional().describe("Optional Gemini model name or alias"),
79
+ accountIndex: z.number().int().min(0).optional().describe("Optional account index")
80
+ }, async (input) => {
81
+ try {
82
+ const args = ChatSchema.parse(input);
83
+ const result = await deps.chat.chat(args.conversationId ?? randomUUID(), args.prompt, {
84
+ model: args.model,
85
+ accountIndex: args.accountIndex
86
+ });
87
+ return okResult({
88
+ text: result.text,
89
+ conversationId: result.sessionId,
90
+ turnNumber: result.turnNumber,
91
+ isNewSession: result.isNewSession,
92
+ candidateCount: result.candidates.length,
93
+ model: args.model
94
+ });
95
+ }
96
+ catch (error) {
97
+ return toErrorResult(error);
98
+ }
99
+ });
100
+ }
101
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/tools/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolDeps } from "../server.js";
3
+ export declare function registerGemsTools(server: McpServer, deps: ToolDeps): void;
4
+ //# sourceMappingURL=gems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gems.d.ts","sourceRoot":"","sources":["../../src/tools/gems.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0B7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAyFzE"}