openzoo 0.50.96 → 0.50.98
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/bin/cursor-backend.js +1 -1
- package/bin/openzoo.js +35 -2
- package/lib/cursorapi.js +65 -0
- package/lib/cursorbackend.js +817 -78
- package/lib/cursorbackend.js.bak-hiddenbots +4072 -0
- package/lib/grokbotAccount.js +195 -4
- package/lib/grokbotAccount.js.bak-hiddenbots +386 -0
- package/lib/grokbotFetch.js +258 -0
- package/lib/grokbotweb.js +23 -7
- package/lib/grokcli.js +527 -35
- package/lib/grokui.mjs +6524 -0
- package/lib/launch.js +37 -6
- package/lib/modelroute/README.md +1 -0
- package/lib/modelroute/catalog.json +1 -0
- package/lib/modelroute/outcomes.json +1566 -0
- package/lib/modelroute/router.json +1 -0
- package/lib/modelroute.js +737 -0
- package/lib/models.js +40 -0
- package/lib/openzooPathShim.js +60 -0
- package/lib/ozSpendChip.js +80 -3
- package/lib/pay.js +30 -2
- package/lib/podagent.mjs +1427 -0
- package/lib/proxy.js +89 -4
- package/lib/runguard.js +31 -0
- package/lib/setup.js +1 -1
- package/lib/spill.js +2031 -0
- package/lib/subscription.js +207 -0
- package/lib/websearch.js +31 -0
- package/lib/worktree.mjs +424 -0
- package/package.json +1 -1
package/bin/cursor-backend.js
CHANGED
|
@@ -45,5 +45,5 @@ process.on('unhandledRejection', (e) => {
|
|
|
45
45
|
log(`cursor-backend: UNHANDLED REJECTION ${e && e.message ? e.message : e}`);
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
startCursorBackend({ port, models, log });
|
|
48
|
+
await startCursorBackend({ port, models, log });
|
|
49
49
|
log(`cursor-backend: standalone up on :${port} (${models.length} models)`);
|
package/bin/openzoo.js
CHANGED
|
@@ -96,7 +96,16 @@ usage:
|
|
|
96
96
|
After a reboot the login item comes back without
|
|
97
97
|
that env — bot bounces it so send works. Already-
|
|
98
98
|
hijacked sessions are left alone.
|
|
99
|
+
Missing Grok Bot is fetched from the grokbot-v*
|
|
100
|
+
multiarch GitHub release (vendor feed fallback).
|
|
99
101
|
--quit force bounce · --no-quit never bounce
|
|
102
|
+
--no-fetch do not download Grok Bot if missing
|
|
103
|
+
--daemon / -d fork the sidecar to background
|
|
104
|
+
(pid ~/.openzoo/bot.pid, log bot.log)
|
|
105
|
+
then launch Grok Bot. Needed from the
|
|
106
|
+
OpenZoo Bot AppImage so this process
|
|
107
|
+
is not the GUI.
|
|
108
|
+
--stop kill the --daemon sidecar
|
|
100
109
|
--verbose print every request the app makes
|
|
101
110
|
(default is quiet: milestones + problems)
|
|
102
111
|
--web serve the renderer in a browser instead of
|
|
@@ -330,7 +339,7 @@ async function main() {
|
|
|
330
339
|
}
|
|
331
340
|
case 'ask': {
|
|
332
341
|
const question = process.argv[3];
|
|
333
|
-
if (!question) throw new Error('usage: openzoo ask "<question>" [--context <id>] [--model <id>] [--system <text>]');
|
|
342
|
+
if (!question) throw new Error('usage: openzoo ask "<question>" [--context <id>] [--model <id>] [--system <text>] [--web [--web-results N]]');
|
|
334
343
|
const ci = process.argv.indexOf('--context');
|
|
335
344
|
const mi = process.argv.indexOf('--model');
|
|
336
345
|
// A BARE QUESTION IS A DIFFERENT PRODUCT FROM A BRIEFED ONE.
|
|
@@ -344,7 +353,20 @@ async function main() {
|
|
|
344
353
|
// DHH, Hyprland and theming. Same gateway, same product, one had context.
|
|
345
354
|
// A caller that knows where it is running can now say so.
|
|
346
355
|
const si = process.argv.indexOf('--system');
|
|
347
|
-
|
|
356
|
+
let system = si !== -1 ? process.argv[si + 1] : '';
|
|
357
|
+
// --web: a keyless DuckDuckGo search, top results injected into THIS
|
|
358
|
+
// call's system prompt. The x402 rail strips OpenRouter's `plugins`
|
|
359
|
+
// field, so search-then-inject has to happen here, on the caller's
|
|
360
|
+
// side. EGRESS: the question text goes to duckduckgo.com. Also on with
|
|
361
|
+
// OPENZOO_ASK_WEB=1; --web-results N caps the count (default 5).
|
|
362
|
+
const wantWeb = process.argv.includes('--web') || process.env.OPENZOO_ASK_WEB === '1';
|
|
363
|
+
if (wantWeb) {
|
|
364
|
+
const wi = process.argv.indexOf('--web-results');
|
|
365
|
+
const n = wi !== -1 ? Number(process.argv[wi + 1]) || 5 : 5;
|
|
366
|
+
const { webSearch, formatWebResults } = await import('../lib/websearch.js');
|
|
367
|
+
const hits = await webSearch(question, n).catch((e) => { console.error(`web search failed: ${e.message}`); return []; });
|
|
368
|
+
if (hits.length) system = (system ? system + '\n\n' : '') + formatWebResults(question, hits);
|
|
369
|
+
}
|
|
348
370
|
const { PayClient } = await import('../lib/pay.js');
|
|
349
371
|
const { config } = await import('../lib/config.js');
|
|
350
372
|
const client = new PayClient();
|
|
@@ -389,6 +411,17 @@ async function main() {
|
|
|
389
411
|
case '-h':
|
|
390
412
|
console.log(HELP);
|
|
391
413
|
break;
|
|
414
|
+
case 'version':
|
|
415
|
+
case '--version':
|
|
416
|
+
case '-v':
|
|
417
|
+
case '-V': {
|
|
418
|
+
// Every installer, mise shim and shell script that probes a CLI asks
|
|
419
|
+
// this first; answering "unknown command" to it failed real installs.
|
|
420
|
+
const { readFileSync } = await import('fs');
|
|
421
|
+
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
422
|
+
console.log(pkg.version);
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
392
425
|
default:
|
|
393
426
|
console.error(`unknown command: ${cmd}\n`);
|
|
394
427
|
console.log(HELP);
|
package/lib/cursorapi.js
CHANGED
|
@@ -305,3 +305,68 @@ export function connectFrame(payload) {
|
|
|
305
305
|
head.writeUInt32BE(payload.length, 1);
|
|
306
306
|
return Buffer.concat([head, payload]);
|
|
307
307
|
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Fake Cursor login. Grok Bot polls GET /auth/poll until the JSON has
|
|
311
|
+
* accessToken + refreshToken (asar SandBackendLoginManager.waitForResult).
|
|
312
|
+
* empty-ok `{}` is a 200 without those keys → login fails → "Log in with Cursor".
|
|
313
|
+
* accessToken is JWT-decoded for sub/email/exp (createLoggedInStatus).
|
|
314
|
+
*/
|
|
315
|
+
export function fakeCursorJwt({
|
|
316
|
+
sub = 'openzoo-user',
|
|
317
|
+
email = 'user@openzoo.local',
|
|
318
|
+
name = 'openzoo',
|
|
319
|
+
now = Math.floor(Date.now() / 1000),
|
|
320
|
+
} = {}) {
|
|
321
|
+
const b64url = (obj) => Buffer.from(JSON.stringify(obj)).toString('base64url');
|
|
322
|
+
return `${b64url({ alg: 'none', typ: 'JWT' })}.${b64url({
|
|
323
|
+
sub, email, name, exp: now + 365 * 86400, iat: now,
|
|
324
|
+
})}.oz`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export function fakeCursorTokens() {
|
|
328
|
+
const accessToken = fakeCursorJwt();
|
|
329
|
+
const refreshToken = fakeCursorJwt();
|
|
330
|
+
return { accessToken, refreshToken, authId: 'openzoo-user' };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const LOGIN_DEEP_HTML = `<!doctype html>
|
|
334
|
+
<html lang="en"><head>
|
|
335
|
+
<meta charset="utf-8">
|
|
336
|
+
<meta http-equiv="refresh" content="0;url=about:blank">
|
|
337
|
+
<title></title>
|
|
338
|
+
</head>
|
|
339
|
+
<body data-component="oz-fake-login">
|
|
340
|
+
<script>
|
|
341
|
+
try { window.open('', '_self'); } catch (e) {}
|
|
342
|
+
try { window.close(); } catch (e) {}
|
|
343
|
+
try { location.replace('about:blank'); } catch (e) {}
|
|
344
|
+
</script>
|
|
345
|
+
</body></html>
|
|
346
|
+
`;
|
|
347
|
+
|
|
348
|
+
/** Path without query. Returns a reply descriptor or null. */
|
|
349
|
+
export function fakeCursorAuthReply(urlPath, { passthrough = false } = {}) {
|
|
350
|
+
if (passthrough) return null;
|
|
351
|
+
const path0 = String(urlPath || '').split('?')[0];
|
|
352
|
+
const tok = fakeCursorTokens();
|
|
353
|
+
if (path0 === '/auth/poll') {
|
|
354
|
+
return { kind: 'poll', contentType: 'application/json', body: JSON.stringify(tok) };
|
|
355
|
+
}
|
|
356
|
+
if (path0 === '/oauth/token') {
|
|
357
|
+
return {
|
|
358
|
+
kind: 'oauth',
|
|
359
|
+
contentType: 'application/json',
|
|
360
|
+
body: JSON.stringify({
|
|
361
|
+
access_token: tok.accessToken,
|
|
362
|
+
refresh_token: tok.refreshToken,
|
|
363
|
+
token_type: 'Bearer',
|
|
364
|
+
expires_in: 365 * 86400,
|
|
365
|
+
}),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (path0 === '/loginDeepControl') {
|
|
369
|
+
return { kind: 'login-page', contentType: 'text/html; charset=utf-8', body: LOGIN_DEEP_HTML };
|
|
370
|
+
}
|
|
371
|
+
return null;
|
|
372
|
+
}
|