@benzsiangco/jarvis 1.0.0 → 1.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.
- package/README.md +5 -0
- package/bin/{jarvis.js → jarvis} +1 -1
- package/dist/cli.js +476 -350
- package/dist/electron/main.js +160 -0
- package/dist/electron/preload.js +19 -0
- package/package.json +21 -8
- package/skills.md +147 -0
- package/src/agents/index.ts +248 -0
- package/src/brain/loader.ts +136 -0
- package/src/cli.ts +411 -0
- package/src/config/index.ts +363 -0
- package/src/core/executor.ts +222 -0
- package/src/core/plugins.ts +148 -0
- package/src/core/types.ts +217 -0
- package/src/electron/main.ts +192 -0
- package/src/electron/preload.ts +25 -0
- package/src/electron/types.d.ts +20 -0
- package/src/index.ts +12 -0
- package/src/providers/antigravity-loader.ts +233 -0
- package/src/providers/antigravity.ts +585 -0
- package/src/providers/index.ts +523 -0
- package/src/sessions/index.ts +194 -0
- package/src/tools/index.ts +436 -0
- package/src/tui/index.tsx +784 -0
- package/src/utils/auth-prompt.ts +394 -0
- package/src/utils/index.ts +180 -0
- package/src/utils/native-picker.ts +71 -0
- package/src/utils/skills.ts +99 -0
- package/src/utils/table-integration-examples.ts +617 -0
- package/src/utils/table-utils.ts +401 -0
- package/src/web/build-ui.ts +27 -0
- package/src/web/server.ts +674 -0
- package/src/web/ui/dist/.gitkeep +0 -0
- package/src/web/ui/dist/main.css +1 -0
- package/src/web/ui/dist/main.js +320 -0
- package/src/web/ui/dist/main.js.map +20 -0
- package/src/web/ui/index.html +46 -0
- package/src/web/ui/src/App.tsx +143 -0
- package/src/web/ui/src/Modules/Safety/GuardianModal.tsx +83 -0
- package/src/web/ui/src/components/Layout/ContextPanel.tsx +243 -0
- package/src/web/ui/src/components/Layout/Header.tsx +91 -0
- package/src/web/ui/src/components/Layout/ModelSelector.tsx +235 -0
- package/src/web/ui/src/components/Layout/SessionStats.tsx +369 -0
- package/src/web/ui/src/components/Layout/Sidebar.tsx +895 -0
- package/src/web/ui/src/components/Modules/Chat/ChatStage.tsx +620 -0
- package/src/web/ui/src/components/Modules/Chat/MessageItem.tsx +446 -0
- package/src/web/ui/src/components/Modules/Editor/CommandInspector.tsx +71 -0
- package/src/web/ui/src/components/Modules/Editor/DiffViewer.tsx +83 -0
- package/src/web/ui/src/components/Modules/Terminal/TabbedTerminal.tsx +202 -0
- package/src/web/ui/src/components/Settings/SettingsModal.tsx +935 -0
- package/src/web/ui/src/config/models.ts +70 -0
- package/src/web/ui/src/main.tsx +13 -0
- package/src/web/ui/src/store/agentStore.ts +41 -0
- package/src/web/ui/src/store/uiStore.ts +64 -0
- package/src/web/ui/src/types/index.ts +54 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// Antigravity plugin loader adapter for Jarvis
|
|
2
|
+
// This uses Jarvis's own account storage instead of the plugin's storage
|
|
3
|
+
import { loadAccounts as loadJarvisAccounts, saveAccounts as saveJarvisAccounts, refreshAccountToken as jarvisRefreshToken } from './antigravity.js';
|
|
4
|
+
import type { AntigravityAccount, AccountsConfig } from './antigravity.js';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { homedir } from 'os';
|
|
7
|
+
import crypto from 'crypto';
|
|
8
|
+
|
|
9
|
+
// Import only the request transformation functions, not the full plugin
|
|
10
|
+
import { prepareAntigravityRequest, transformAntigravityResponse } from 'opencode-antigravity-auth/dist/src/plugin/request.js';
|
|
11
|
+
|
|
12
|
+
// Ensure accounts have required fields
|
|
13
|
+
function ensureAccountFields(accounts: AccountsConfig): AccountsConfig {
|
|
14
|
+
const updated = { ...accounts };
|
|
15
|
+
updated.accounts = accounts.accounts.map((acc: any, index) => ({
|
|
16
|
+
id: acc.id || `acc_${Date.now()}_${index}`,
|
|
17
|
+
email: acc.email,
|
|
18
|
+
refreshToken: acc.refreshToken,
|
|
19
|
+
accessToken: acc.accessToken,
|
|
20
|
+
expiresAt: acc.expiresAt,
|
|
21
|
+
projectId: acc.projectId,
|
|
22
|
+
rateLimitedUntil: acc.rateLimitedUntil,
|
|
23
|
+
requestCount: acc.requestCount || 0,
|
|
24
|
+
lastUsed: acc.lastUsed || Date.now(),
|
|
25
|
+
}));
|
|
26
|
+
return updated;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get next available account with token refresh
|
|
30
|
+
async function getAccountWithToken(): Promise<AntigravityAccount | null> {
|
|
31
|
+
const accountsConfig = ensureAccountFields(loadJarvisAccounts());
|
|
32
|
+
|
|
33
|
+
if (accountsConfig.accounts.length === 0) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const account = accountsConfig.accounts[accountsConfig.activeIndex || 0];
|
|
38
|
+
|
|
39
|
+
if (!account) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// If no access token or expired, refresh it
|
|
44
|
+
if (!account.accessToken || (account.expiresAt && account.expiresAt < Date.now() + 5 * 60 * 1000)) {
|
|
45
|
+
const refreshed = await jarvisRefreshToken(account);
|
|
46
|
+
if (refreshed) {
|
|
47
|
+
return refreshed;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return account;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Track usage
|
|
55
|
+
function trackUsage(accountId: string) {
|
|
56
|
+
const accounts = loadJarvisAccounts();
|
|
57
|
+
const account = accounts.accounts.find(a => (a as any).id === accountId);
|
|
58
|
+
if (account) {
|
|
59
|
+
(account as any).requestCount = ((account as any).requestCount || 0) + 1;
|
|
60
|
+
(account as any).lastUsed = Date.now();
|
|
61
|
+
saveJarvisAccounts(accounts);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Mark rate limited
|
|
66
|
+
function markRateLimited(accountId: string, durationMs: number) {
|
|
67
|
+
const accounts = loadJarvisAccounts();
|
|
68
|
+
const account = accounts.accounts.find(a => (a as any).id === accountId);
|
|
69
|
+
if (account) {
|
|
70
|
+
(account as any).rateLimitedUntil = Date.now() + durationMs;
|
|
71
|
+
saveJarvisAccounts(accounts);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Create a custom fetch function using Jarvis's accounts
|
|
76
|
+
export async function createJarvisAntigravityFetch() {
|
|
77
|
+
// Generate a session ID for signature caching
|
|
78
|
+
const sessionId = `jarvis-${crypto.randomUUID()}`;
|
|
79
|
+
|
|
80
|
+
return async (url: string | URL | Request, init?: RequestInit): Promise<Response> => {
|
|
81
|
+
// Get current account from Jarvis's storage
|
|
82
|
+
let account = await getAccountWithToken();
|
|
83
|
+
|
|
84
|
+
if (!account || !account.accessToken) {
|
|
85
|
+
throw new Error('No Antigravity account available. Run "jarvis auth login"');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const urlString = typeof url === 'string' ? url : url instanceof URL ? url.toString() : url.url;
|
|
89
|
+
|
|
90
|
+
// Only process Google Generative Language API requests
|
|
91
|
+
if (!urlString.includes('generativelanguage.googleapis.com')) {
|
|
92
|
+
return fetch(url, init);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Force thinking recovery for all models that may have function calls
|
|
96
|
+
// The thought_signature error happens when function calls are made with thinking models
|
|
97
|
+
// We need to enable forceThinkingRecovery to properly handle the thought signatures
|
|
98
|
+
const bodyStr = typeof init?.body === 'string' ? init.body : '';
|
|
99
|
+
const hasToolsOrFunctions = bodyStr.includes('"tools"') ||
|
|
100
|
+
bodyStr.includes('"functions"') ||
|
|
101
|
+
bodyStr.includes('"function_declarations"') ||
|
|
102
|
+
bodyStr.includes('"functionDeclarations"');
|
|
103
|
+
|
|
104
|
+
// Gemini 3 models and any model with tools need thinking recovery
|
|
105
|
+
const isGemini3 = urlString.includes('gemini-3') || urlString.includes('gemini-2');
|
|
106
|
+
const needsThinkingRecovery = hasToolsOrFunctions && isGemini3;
|
|
107
|
+
|
|
108
|
+
// Extract model name from URL
|
|
109
|
+
const modelMatch = urlString.match(/models\/([^:\/]+)/);
|
|
110
|
+
const requestedModel = modelMatch ? modelMatch[1] : 'unknown';
|
|
111
|
+
const endpoint = 'https://daily-cloudcode-pa.sandbox.googleapis.com';
|
|
112
|
+
const projectId = account.projectId || 'jarvis-default-project';
|
|
113
|
+
|
|
114
|
+
// Use plugin's request preparation
|
|
115
|
+
const prepared = prepareAntigravityRequest(
|
|
116
|
+
urlString,
|
|
117
|
+
init,
|
|
118
|
+
account.accessToken!,
|
|
119
|
+
projectId,
|
|
120
|
+
endpoint,
|
|
121
|
+
'antigravity',
|
|
122
|
+
needsThinkingRecovery, // Enable forceThinkingRecovery when tools are used
|
|
123
|
+
{} // Options
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const response = await fetch(prepared.request, prepared.init);
|
|
127
|
+
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const errorText = await response.text();
|
|
130
|
+
let errorMessage = `Antigravity error ${response.status}`;
|
|
131
|
+
try {
|
|
132
|
+
const errorJson = JSON.parse(errorText);
|
|
133
|
+
errorMessage = errorJson.error?.message || errorMessage;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
errorMessage = errorText || errorMessage;
|
|
136
|
+
}
|
|
137
|
+
throw new Error(errorMessage);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Handle rate limiting
|
|
141
|
+
if (response.status === 429) {
|
|
142
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
143
|
+
const duration = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
|
|
144
|
+
markRateLimited(account.id, duration);
|
|
145
|
+
|
|
146
|
+
// Try to get another account
|
|
147
|
+
const nextAccount = await getAccountWithToken();
|
|
148
|
+
if (nextAccount && nextAccount.id !== account.id && nextAccount.accessToken) {
|
|
149
|
+
const nextPrepared = prepareAntigravityRequest(
|
|
150
|
+
urlString,
|
|
151
|
+
init,
|
|
152
|
+
nextAccount.accessToken,
|
|
153
|
+
nextAccount.projectId || 'jarvis-default-project',
|
|
154
|
+
endpoint,
|
|
155
|
+
'antigravity',
|
|
156
|
+
needsThinkingRecovery,
|
|
157
|
+
{}
|
|
158
|
+
);
|
|
159
|
+
const retryResponse = await fetch(nextPrepared.request, nextPrepared.init);
|
|
160
|
+
return transformAntigravityResponse(
|
|
161
|
+
retryResponse,
|
|
162
|
+
prepared.streaming,
|
|
163
|
+
null, // debugContext
|
|
164
|
+
requestedModel,
|
|
165
|
+
projectId,
|
|
166
|
+
endpoint,
|
|
167
|
+
requestedModel, // effectiveModel
|
|
168
|
+
sessionId
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Handle auth errors
|
|
174
|
+
if (response.status === 401 || response.status === 403) {
|
|
175
|
+
const refreshed = await jarvisRefreshToken(account);
|
|
176
|
+
if (refreshed) {
|
|
177
|
+
const refreshedPrepared = prepareAntigravityRequest(
|
|
178
|
+
urlString,
|
|
179
|
+
init,
|
|
180
|
+
refreshed.accessToken!,
|
|
181
|
+
refreshed.projectId || 'jarvis-default-project',
|
|
182
|
+
endpoint,
|
|
183
|
+
'antigravity',
|
|
184
|
+
needsThinkingRecovery,
|
|
185
|
+
{}
|
|
186
|
+
);
|
|
187
|
+
const retryResponse = await fetch(refreshedPrepared.request, refreshedPrepared.init);
|
|
188
|
+
return transformAntigravityResponse(
|
|
189
|
+
retryResponse,
|
|
190
|
+
prepared.streaming,
|
|
191
|
+
null,
|
|
192
|
+
requestedModel,
|
|
193
|
+
projectId,
|
|
194
|
+
endpoint,
|
|
195
|
+
requestedModel,
|
|
196
|
+
sessionId
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Track usage
|
|
202
|
+
if (response.ok) {
|
|
203
|
+
trackUsage(account.id);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Transform the response using plugin's logic with full parameters
|
|
207
|
+
return transformAntigravityResponse(
|
|
208
|
+
response,
|
|
209
|
+
prepared.streaming,
|
|
210
|
+
null, // debugContext
|
|
211
|
+
requestedModel,
|
|
212
|
+
projectId,
|
|
213
|
+
endpoint,
|
|
214
|
+
requestedModel, // effectiveModel
|
|
215
|
+
sessionId
|
|
216
|
+
);
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Initialize with Jarvis's accounts only
|
|
221
|
+
export async function initializeAntigravityLoader() {
|
|
222
|
+
try {
|
|
223
|
+
// Ensure accounts have proper format
|
|
224
|
+
const accounts = ensureAccountFields(loadJarvisAccounts());
|
|
225
|
+
saveJarvisAccounts(accounts);
|
|
226
|
+
|
|
227
|
+
// Return the custom fetch function that uses Jarvis accounts
|
|
228
|
+
return await createJarvisAntigravityFetch();
|
|
229
|
+
} catch (error) {
|
|
230
|
+
console.error('Failed to initialize Antigravity loader:', error);
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|