@steipete/oracle 0.5.6 → 0.6.1
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 +3 -3
- package/dist/bin/oracle-cli.js +8 -2
- package/dist/src/browser/actions/assistantResponse.js +65 -6
- package/dist/src/browser/actions/modelSelection.js +22 -0
- package/dist/src/browser/actions/promptComposer.js +67 -3
- package/dist/src/browser/actions/thinkingTime.js +190 -0
- package/dist/src/browser/config.js +1 -0
- package/dist/src/browser/constants.js +1 -1
- package/dist/src/browser/index.js +106 -74
- package/dist/src/browser/pageActions.js +1 -1
- package/dist/src/browser/profileState.js +171 -0
- package/dist/src/browser/prompt.js +63 -19
- package/dist/src/browser/sessionRunner.js +10 -6
- package/dist/src/cli/browserConfig.js +6 -2
- package/dist/src/cli/sessionDisplay.js +8 -1
- package/dist/src/cli/sessionRunner.js +2 -8
- package/dist/src/cli/tui/index.js +1 -0
- package/dist/src/config.js +2 -3
- package/dist/src/oracle/config.js +38 -3
- package/dist/src/oracle/errors.js +3 -3
- package/dist/src/oracle/gemini.js +4 -1
- package/dist/src/oracle/run.js +4 -7
- package/dist/src/oracleHome.js +13 -0
- package/dist/src/remote/server.js +17 -11
- package/dist/src/sessionManager.js +10 -8
- package/dist/src/sessionStore.js +2 -2
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/dist/vendor/oracle-notifier/build-notifier.sh +0 -0
- package/dist/vendor/oracle-notifier/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/dist/vendor/oracle-notifier/oracle-notifier/build-notifier.sh +0 -0
- package/package.json +22 -38
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/vendor/oracle-notifier/build-notifier.sh +0 -0
- package/vendor/oracle-notifier/README.md +0 -24
|
@@ -19,7 +19,6 @@ import { formatElapsed } from '../oracle/format.js';
|
|
|
19
19
|
import { sanitizeOscProgress } from './oscUtils.js';
|
|
20
20
|
import { readFiles } from '../oracle/files.js';
|
|
21
21
|
import { formatUSD } from '../oracle/format.js';
|
|
22
|
-
import { SESSIONS_DIR } from '../sessionManager.js';
|
|
23
22
|
import { cwd as getCwd } from 'node:process';
|
|
24
23
|
const isTty = process.stdout.isTTY;
|
|
25
24
|
const dim = (text) => (isTty ? kleur.dim(text) : text);
|
|
@@ -361,11 +360,6 @@ export async function performSessionRun({ sessionMeta, runOptions, mode, browser
|
|
|
361
360
|
}
|
|
362
361
|
: undefined,
|
|
363
362
|
});
|
|
364
|
-
if (mode === 'browser') {
|
|
365
|
-
log(dim('Next steps (browser fallback):')); // guides users when automation breaks
|
|
366
|
-
log(dim('- Rerun with --engine api to bypass Chrome entirely.'));
|
|
367
|
-
log(dim('- Or rerun with --engine api --render-markdown [--file …] to generate a single markdown bundle you can paste into ChatGPT manually (add --browser-bundle-files if you still want attachments).'));
|
|
368
|
-
}
|
|
369
363
|
if (modelForStatus) {
|
|
370
364
|
await sessionStore.updateModelRun(sessionMeta.id, modelForStatus, {
|
|
371
365
|
status: 'error',
|
|
@@ -386,7 +380,7 @@ async function writeAssistantOutput(targetPath, content, log) {
|
|
|
386
380
|
return;
|
|
387
381
|
}
|
|
388
382
|
const normalizedTarget = path.resolve(targetPath);
|
|
389
|
-
const normalizedSessionsDir = path.resolve(
|
|
383
|
+
const normalizedSessionsDir = path.resolve(sessionStore.sessionsDir());
|
|
390
384
|
if (normalizedTarget === normalizedSessionsDir ||
|
|
391
385
|
normalizedTarget.startsWith(`${normalizedSessionsDir}${path.sep}`)) {
|
|
392
386
|
log(dim(`write-output skipped: refusing to write inside session storage (${normalizedSessionsDir}).`));
|
|
@@ -442,7 +436,7 @@ function buildFallbackPath(original) {
|
|
|
442
436
|
const dir = getCwd();
|
|
443
437
|
const candidate = ext ? `${stem}.fallback${ext}` : `${stem}.fallback`;
|
|
444
438
|
const fallback = path.join(dir, candidate);
|
|
445
|
-
const normalizedSessionsDir = path.resolve(
|
|
439
|
+
const normalizedSessionsDir = path.resolve(sessionStore.sessionsDir());
|
|
446
440
|
const normalizedFallback = path.resolve(fallback);
|
|
447
441
|
if (normalizedFallback === normalizedSessionsDir ||
|
|
448
442
|
normalizedFallback.startsWith(`${normalizedSessionsDir}${path.sep}`)) {
|
|
@@ -388,6 +388,7 @@ async function askOracleFlow(version, userConfig) {
|
|
|
388
388
|
sessionId: undefined,
|
|
389
389
|
verbose: false,
|
|
390
390
|
heartbeatIntervalMs: undefined,
|
|
391
|
+
browserAttachments: 'auto',
|
|
391
392
|
browserInlineFiles: false,
|
|
392
393
|
browserBundleFiles: false,
|
|
393
394
|
background: undefined,
|
package/dist/src/config.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
-
import os from 'node:os';
|
|
3
2
|
import path from 'node:path';
|
|
4
3
|
import JSON5 from 'json5';
|
|
4
|
+
import { getOracleHomeDir } from './oracleHome.js';
|
|
5
5
|
function resolveConfigPath() {
|
|
6
|
-
|
|
7
|
-
return path.join(oracleHome, 'config.json');
|
|
6
|
+
return path.join(getOracleHomeDir(), 'config.json');
|
|
8
7
|
}
|
|
9
8
|
export async function loadUserConfig() {
|
|
10
9
|
const CONFIG_PATH = resolveConfigPath();
|
|
@@ -3,17 +3,18 @@ import { countTokens as countTokensGpt5Pro } from 'gpt-tokenizer/model/gpt-5-pro
|
|
|
3
3
|
import { countTokens as countTokensAnthropicRaw } from '@anthropic-ai/tokenizer';
|
|
4
4
|
import { stringifyTokenizerInput } from './tokenStringifier.js';
|
|
5
5
|
export const DEFAULT_MODEL = 'gpt-5.1-pro';
|
|
6
|
-
export const PRO_MODELS = new Set(['gpt-5.1-pro', 'gpt-5-pro', 'claude-4.5-sonnet', 'claude-4.1-opus']);
|
|
6
|
+
export const PRO_MODELS = new Set(['gpt-5.1-pro', 'gpt-5-pro', 'gpt-5.2-pro', 'claude-4.5-sonnet', 'claude-4.1-opus']);
|
|
7
7
|
const countTokensAnthropic = (input) => countTokensAnthropicRaw(stringifyTokenizerInput(input));
|
|
8
8
|
export const MODEL_CONFIGS = {
|
|
9
9
|
'gpt-5.1-pro': {
|
|
10
10
|
model: 'gpt-5.1-pro',
|
|
11
|
+
apiModel: 'gpt-5.2-pro',
|
|
11
12
|
provider: 'openai',
|
|
12
13
|
tokenizer: countTokensGpt5Pro,
|
|
13
14
|
inputLimit: 196000,
|
|
14
15
|
pricing: {
|
|
15
|
-
inputPerToken:
|
|
16
|
-
outputPerToken:
|
|
16
|
+
inputPerToken: 21 / 1_000_000,
|
|
17
|
+
outputPerToken: 168 / 1_000_000,
|
|
17
18
|
},
|
|
18
19
|
reasoning: null,
|
|
19
20
|
},
|
|
@@ -50,6 +51,40 @@ export const MODEL_CONFIGS = {
|
|
|
50
51
|
},
|
|
51
52
|
reasoning: { effort: 'high' },
|
|
52
53
|
},
|
|
54
|
+
'gpt-5.2': {
|
|
55
|
+
model: 'gpt-5.2',
|
|
56
|
+
provider: 'openai',
|
|
57
|
+
tokenizer: countTokensGpt5,
|
|
58
|
+
inputLimit: 196000,
|
|
59
|
+
pricing: {
|
|
60
|
+
inputPerToken: 1.75 / 1_000_000,
|
|
61
|
+
outputPerToken: 14 / 1_000_000,
|
|
62
|
+
},
|
|
63
|
+
reasoning: { effort: 'xhigh' },
|
|
64
|
+
},
|
|
65
|
+
'gpt-5.2-instant': {
|
|
66
|
+
model: 'gpt-5.2-instant',
|
|
67
|
+
apiModel: 'gpt-5.2-chat-latest',
|
|
68
|
+
provider: 'openai',
|
|
69
|
+
tokenizer: countTokensGpt5,
|
|
70
|
+
inputLimit: 196000,
|
|
71
|
+
pricing: {
|
|
72
|
+
inputPerToken: 1.75 / 1_000_000,
|
|
73
|
+
outputPerToken: 14 / 1_000_000,
|
|
74
|
+
},
|
|
75
|
+
reasoning: null,
|
|
76
|
+
},
|
|
77
|
+
'gpt-5.2-pro': {
|
|
78
|
+
model: 'gpt-5.2-pro',
|
|
79
|
+
provider: 'openai',
|
|
80
|
+
tokenizer: countTokensGpt5Pro,
|
|
81
|
+
inputLimit: 196000,
|
|
82
|
+
pricing: {
|
|
83
|
+
inputPerToken: 21 / 1_000_000,
|
|
84
|
+
outputPerToken: 168 / 1_000_000,
|
|
85
|
+
},
|
|
86
|
+
reasoning: { effort: 'xhigh' },
|
|
87
|
+
},
|
|
53
88
|
'gemini-3-pro': {
|
|
54
89
|
model: 'gemini-3-pro',
|
|
55
90
|
provider: 'google',
|
|
@@ -95,13 +95,13 @@ export function toTransportError(error, model) {
|
|
|
95
95
|
const apiMessage = apiError.error?.message ||
|
|
96
96
|
apiError.message ||
|
|
97
97
|
(apiError.status ? `${apiError.status} OpenAI API error` : 'OpenAI API error');
|
|
98
|
-
//
|
|
99
|
-
if (model === 'gpt-5.
|
|
98
|
+
// Friendly guidance when a pro-tier model isn't available on this base URL / API key.
|
|
99
|
+
if (model === 'gpt-5.2-pro' &&
|
|
100
100
|
(code === 'model_not_found' ||
|
|
101
101
|
messageText.includes('does not exist') ||
|
|
102
102
|
messageText.includes('unknown model') ||
|
|
103
103
|
messageText.includes('model_not_found'))) {
|
|
104
|
-
return new OracleTransportError('model-unavailable', 'gpt-5.
|
|
104
|
+
return new OracleTransportError('model-unavailable', 'gpt-5.2-pro is not available on this API base/key. Try gpt-5-pro or gpt-5.2, or switch to the browser engine.', apiError);
|
|
105
105
|
}
|
|
106
106
|
if (apiError.status === 404 || apiError.status === 405) {
|
|
107
107
|
return new OracleTransportError('unsupported-endpoint', 'HTTP 404/405 from the Responses API; this base URL or gateway likely does not expose /v1/responses. Set OPENAI_BASE_URL to api.openai.com/v1, update your Azure API version/deployment, or use the browser engine.', apiError);
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { GoogleGenAI, HarmCategory, HarmBlockThreshold } from '@google/genai';
|
|
2
2
|
const MODEL_ID_MAP = {
|
|
3
3
|
'gemini-3-pro': 'gemini-3-pro-preview',
|
|
4
|
-
'gpt-5.1-pro': 'gpt-5.1-pro',
|
|
4
|
+
'gpt-5.1-pro': 'gpt-5.1-pro',
|
|
5
5
|
'gpt-5-pro': 'gpt-5-pro',
|
|
6
6
|
'gpt-5.1': 'gpt-5.1',
|
|
7
7
|
'gpt-5.1-codex': 'gpt-5.1-codex',
|
|
8
|
+
'gpt-5.2': 'gpt-5.2',
|
|
9
|
+
'gpt-5.2-instant': 'gpt-5.2-instant',
|
|
10
|
+
'gpt-5.2-pro': 'gpt-5.2-pro',
|
|
8
11
|
'claude-4.5-sonnet': 'claude-4.5-sonnet',
|
|
9
12
|
'claude-4.1-opus': 'claude-4.1-opus',
|
|
10
13
|
'grok-4.1': 'grok-4.1',
|
package/dist/src/oracle/run.js
CHANGED
|
@@ -186,17 +186,14 @@ export async function runOracle(options, deps = {}) {
|
|
|
186
186
|
: DEFAULT_TIMEOUT_NON_PRO_MS / 1000
|
|
187
187
|
: options.timeoutSeconds;
|
|
188
188
|
const timeoutMs = timeoutSeconds * 1000;
|
|
189
|
-
const apiModelFromConfig = modelConfig.apiModel ?? modelConfig.model;
|
|
190
|
-
const modelDowngraded = apiModelFromConfig === 'gpt-5.1-pro';
|
|
191
|
-
const resolvedApiModelId = modelDowngraded ? 'gpt-5-pro' : apiModelFromConfig;
|
|
192
189
|
// Track the concrete model id we dispatch to (especially for Gemini preview aliases)
|
|
193
190
|
const effectiveModelId = options.effectiveModelId ??
|
|
194
191
|
(options.model.startsWith('gemini')
|
|
195
192
|
? resolveGeminiModelId(options.model)
|
|
196
|
-
:
|
|
193
|
+
: (modelConfig.apiModel ?? modelConfig.model));
|
|
197
194
|
const headerModelLabel = richTty ? chalk.cyan(modelConfig.model) : modelConfig.model;
|
|
198
195
|
const requestBody = buildRequestBody({
|
|
199
|
-
modelConfig
|
|
196
|
+
modelConfig,
|
|
200
197
|
systemPrompt,
|
|
201
198
|
userPrompt: promptWithFiles,
|
|
202
199
|
searchEnabled,
|
|
@@ -222,8 +219,8 @@ export async function runOracle(options, deps = {}) {
|
|
|
222
219
|
if (baseUrl) {
|
|
223
220
|
log(dim(`Base URL: ${formatBaseUrlForLog(baseUrl)}`));
|
|
224
221
|
}
|
|
225
|
-
if (
|
|
226
|
-
log(dim(
|
|
222
|
+
if (effectiveModelId !== modelConfig.model) {
|
|
223
|
+
log(dim(`Resolved model: ${modelConfig.model} → ${effectiveModelId}`));
|
|
227
224
|
}
|
|
228
225
|
if (options.background && !supportsBackground) {
|
|
229
226
|
log(dim('Background runs are not supported for this model; streaming in foreground instead.'));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
let oracleHomeDirOverride = null;
|
|
4
|
+
/**
|
|
5
|
+
* Test-only hook: avoid mutating process.env (shared across Vitest worker threads).
|
|
6
|
+
* This override is scoped to the current Node worker.
|
|
7
|
+
*/
|
|
8
|
+
export function setOracleHomeDirOverrideForTest(dir) {
|
|
9
|
+
oracleHomeDirOverride = dir;
|
|
10
|
+
}
|
|
11
|
+
export function getOracleHomeDir() {
|
|
12
|
+
return oracleHomeDirOverride ?? process.env.ORACLE_HOME_DIR ?? path.join(os.homedir(), '.oracle');
|
|
13
|
+
}
|
|
@@ -4,12 +4,12 @@ import path from 'node:path';
|
|
|
4
4
|
import net from 'node:net';
|
|
5
5
|
import { randomBytes, randomUUID } from 'node:crypto';
|
|
6
6
|
import { spawn, spawnSync } from 'node:child_process';
|
|
7
|
-
import { existsSync } from 'node:fs';
|
|
8
7
|
import { mkdtemp, rm, mkdir, writeFile } from 'node:fs/promises';
|
|
9
8
|
import chalk from 'chalk';
|
|
10
9
|
import { runBrowserMode } from '../browserMode.js';
|
|
11
10
|
import { loadChromeCookies } from '../browser/chromeCookies.js';
|
|
12
11
|
import { CHATGPT_URL } from '../browser/constants.js';
|
|
12
|
+
import { cleanupStaleProfileState, readDevToolsPort, verifyDevToolsReachable, writeChromePid, writeDevToolsActivePort, } from '../browser/profileState.js';
|
|
13
13
|
import { normalizeChatgptUrl } from '../browser/utils.js';
|
|
14
14
|
async function findAvailablePort() {
|
|
15
15
|
return await new Promise((resolve, reject) => {
|
|
@@ -209,10 +209,17 @@ export async function serveRemote(options = {}) {
|
|
|
209
209
|
if (preferManualLogin) {
|
|
210
210
|
await mkdir(manualProfileDir, { recursive: true });
|
|
211
211
|
console.log(`Cookie extraction is unavailable on this platform. Using manual-login Chrome profile at ${manualProfileDir}. Remote runs will reuse this profile; sign in once when the browser opens.`);
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
const existingPort = await readDevToolsPort(manualProfileDir);
|
|
213
|
+
if (existingPort) {
|
|
214
|
+
const reachable = await verifyDevToolsReachable({ port: existingPort });
|
|
215
|
+
if (reachable.ok) {
|
|
216
|
+
console.log('Detected an existing automation Chrome session; will reuse it for manual login.');
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.log(`Found stale DevToolsActivePort (port ${existingPort}, ${reachable.error}); launching a fresh manual-login Chrome.`);
|
|
220
|
+
await cleanupStaleProfileState(manualProfileDir, console.log, { lockRemovalMode: 'never' });
|
|
221
|
+
void launchManualLoginChrome(manualProfileDir, CHATGPT_URL, console.log);
|
|
222
|
+
}
|
|
216
223
|
}
|
|
217
224
|
else {
|
|
218
225
|
void launchManualLoginChrome(manualProfileDir, CHATGPT_URL, console.log);
|
|
@@ -459,12 +466,11 @@ async function launchManualLoginChrome(profileDir, url, logger) {
|
|
|
459
466
|
});
|
|
460
467
|
const chosenPort = chrome?.port ?? debugPort ?? null;
|
|
461
468
|
if (chosenPort) {
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
await writeFile(devtoolsFileDefault, contents).catch(() => undefined);
|
|
469
|
+
// Persist DevToolsActivePort eagerly so future runs can attach/reuse this Chrome.
|
|
470
|
+
await writeDevToolsActivePort(profileDir, chosenPort);
|
|
471
|
+
if (chrome?.pid) {
|
|
472
|
+
await writeChromePid(profileDir, chrome.pid);
|
|
473
|
+
}
|
|
468
474
|
logger(`Manual-login Chrome DevTools port: ${chosenPort}`);
|
|
469
475
|
logger(`If needed, DevTools JSON at http://127.0.0.1:${chosenPort}/json/version`);
|
|
470
476
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import fs from 'node:fs/promises';
|
|
4
3
|
import { createWriteStream } from 'node:fs';
|
|
5
4
|
import { DEFAULT_MODEL } from './oracle.js';
|
|
6
5
|
import { safeModelSlug } from './oracle/modelResolver.js';
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import { getOracleHomeDir } from './oracleHome.js';
|
|
7
|
+
export function getSessionsDir() {
|
|
8
|
+
return path.join(getOracleHomeDir(), 'sessions');
|
|
9
|
+
}
|
|
9
10
|
const METADATA_FILENAME = 'meta.json';
|
|
10
11
|
const LEGACY_SESSION_FILENAME = 'session.json';
|
|
11
12
|
const LEGACY_REQUEST_FILENAME = 'request.json';
|
|
@@ -22,7 +23,7 @@ async function ensureDir(dirPath) {
|
|
|
22
23
|
await fs.mkdir(dirPath, { recursive: true });
|
|
23
24
|
}
|
|
24
25
|
export async function ensureSessionStorage() {
|
|
25
|
-
await ensureDir(
|
|
26
|
+
await ensureDir(getSessionsDir());
|
|
26
27
|
}
|
|
27
28
|
function slugify(text, maxWords = MAX_SLUG_WORDS) {
|
|
28
29
|
const normalized = text?.toLowerCase() ?? '';
|
|
@@ -50,7 +51,7 @@ export function createSessionId(prompt, customSlug) {
|
|
|
50
51
|
return slugify(prompt);
|
|
51
52
|
}
|
|
52
53
|
function sessionDir(id) {
|
|
53
|
-
return path.join(
|
|
54
|
+
return path.join(getSessionsDir(), id);
|
|
54
55
|
}
|
|
55
56
|
function metaPath(id) {
|
|
56
57
|
return path.join(sessionDir(id), METADATA_FILENAME);
|
|
@@ -191,6 +192,7 @@ export async function initializeSession(options, cwd, notifications) {
|
|
|
191
192
|
browserConfig,
|
|
192
193
|
verbose: options.verbose,
|
|
193
194
|
heartbeatIntervalMs: options.heartbeatIntervalMs,
|
|
195
|
+
browserAttachments: options.browserAttachments,
|
|
194
196
|
browserInlineFiles: options.browserInlineFiles,
|
|
195
197
|
browserBundleFiles: options.browserBundleFiles,
|
|
196
198
|
background: options.background,
|
|
@@ -287,7 +289,7 @@ export function createSessionLogWriter(sessionId, model) {
|
|
|
287
289
|
}
|
|
288
290
|
export async function listSessionsMetadata() {
|
|
289
291
|
await ensureSessionStorage();
|
|
290
|
-
const entries = await fs.readdir(
|
|
292
|
+
const entries = await fs.readdir(getSessionsDir()).catch(() => []);
|
|
291
293
|
const metas = [];
|
|
292
294
|
for (const entry of entries) {
|
|
293
295
|
let meta = await readSessionMetadata(entry);
|
|
@@ -379,7 +381,7 @@ export async function readSessionRequest(sessionId) {
|
|
|
379
381
|
}
|
|
380
382
|
export async function deleteSessionsOlderThan({ hours = 24, includeAll = false, } = {}) {
|
|
381
383
|
await ensureSessionStorage();
|
|
382
|
-
const entries = await fs.readdir(
|
|
384
|
+
const entries = await fs.readdir(getSessionsDir()).catch(() => []);
|
|
383
385
|
if (!entries.length) {
|
|
384
386
|
return { deleted: 0, remaining: 0 };
|
|
385
387
|
}
|
|
@@ -415,7 +417,7 @@ export async function deleteSessionsOlderThan({ hours = 24, includeAll = false,
|
|
|
415
417
|
export async function wait(ms) {
|
|
416
418
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
417
419
|
}
|
|
418
|
-
export {
|
|
420
|
+
export { MAX_STATUS_LIMIT };
|
|
419
421
|
export { ZOMBIE_MAX_AGE_MS };
|
|
420
422
|
export async function getSessionPaths(sessionId) {
|
|
421
423
|
const dir = sessionDir(sessionId);
|
package/dist/src/sessionStore.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensureSessionStorage, initializeSession, readSessionMetadata, updateSessionMetadata, createSessionLogWriter, readSessionLog, readModelLog, readSessionRequest, listSessionsMetadata, filterSessionsByRange, deleteSessionsOlderThan, updateModelRunMetadata, getSessionPaths,
|
|
1
|
+
import { ensureSessionStorage, initializeSession, readSessionMetadata, updateSessionMetadata, createSessionLogWriter, readSessionLog, readModelLog, readSessionRequest, listSessionsMetadata, filterSessionsByRange, deleteSessionsOlderThan, updateModelRunMetadata, getSessionPaths, getSessionsDir, } from './sessionManager.js';
|
|
2
2
|
class FileSessionStore {
|
|
3
3
|
ensureStorage() {
|
|
4
4
|
return ensureSessionStorage();
|
|
@@ -40,7 +40,7 @@ class FileSessionStore {
|
|
|
40
40
|
return getSessionPaths(sessionId);
|
|
41
41
|
}
|
|
42
42
|
sessionsDir() {
|
|
43
|
-
return
|
|
43
|
+
return getSessionsDir();
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
export const sessionStore = new FileSessionStore();
|
|
File without changes
|
|
File without changes
|
package/dist/vendor/oracle-notifier/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier
CHANGED
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steipete/oracle",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "CLI wrapper around OpenAI Responses API with GPT-5.1
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "CLI wrapper around OpenAI Responses API with GPT-5.2 Pro (via gpt-5.1-pro alias), GPT-5.2, GPT-5.1, and GPT-5.1 Codex high reasoning modes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/bin/oracle-cli.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"oracle": "dist/bin/oracle-cli.js",
|
|
9
9
|
"oracle-mcp": "dist/bin/oracle-mcp.js"
|
|
10
10
|
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"docs:list": "tsx scripts/docs-list.ts",
|
|
13
|
-
"build": "tsc -p tsconfig.build.json && pnpm run build:vendor",
|
|
14
|
-
"build:vendor": "node -e \"const fs=require('fs'); const path=require('path'); const src=path.join('vendor','oracle-notifier'); const dest=path.join('dist','vendor','oracle-notifier'); fs.mkdirSync(dest,{recursive:true}); if(fs.existsSync(src)){ fs.cpSync(src,dest,{recursive:true,force:true}); }\"",
|
|
15
|
-
"start": "pnpm run build && node ./dist/scripts/run-cli.js",
|
|
16
|
-
"oracle": "pnpm start",
|
|
17
|
-
"check": "pnpm run typecheck",
|
|
18
|
-
"typecheck": "tsc --noEmit",
|
|
19
|
-
"lint": "pnpm run typecheck && biome lint .",
|
|
20
|
-
"test": "vitest run",
|
|
21
|
-
"test:mcp": "pnpm run build && pnpm run test:mcp:unit && pnpm run test:mcp:mcporter",
|
|
22
|
-
"test:mcp:unit": "vitest run tests/mcp*.test.ts tests/mcp/**/*.test.ts",
|
|
23
|
-
"test:mcp:mcporter": "npx -y mcporter list oracle-local --schema --config config/mcporter.json && npx -y mcporter call oracle-local.sessions limit:1 --config config/mcporter.json",
|
|
24
|
-
"test:browser": "pnpm run build && tsx scripts/test-browser.ts && ./scripts/browser-smoke.sh",
|
|
25
|
-
"test:live": "ORACLE_LIVE_TEST=1 vitest run tests/live --exclude tests/live/openai-live.test.ts",
|
|
26
|
-
"test:pro": "ORACLE_LIVE_TEST=1 vitest run tests/live/openai-live.test.ts",
|
|
27
|
-
"test:coverage": "vitest run --coverage",
|
|
28
|
-
"prepare": "pnpm run build",
|
|
29
|
-
"mcp": "pnpm run build && node ./dist/bin/oracle-mcp.js"
|
|
30
|
-
},
|
|
31
11
|
"files": [
|
|
32
12
|
"dist/**/*",
|
|
33
13
|
"assets-oracle-icon.png",
|
|
@@ -103,19 +83,23 @@
|
|
|
103
83
|
"optionalDependencies": {
|
|
104
84
|
"win-dpapi": "npm:@primno/dpapi@2.0.1"
|
|
105
85
|
},
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
86
|
+
"scripts": {
|
|
87
|
+
"docs:list": "tsx scripts/docs-list.ts",
|
|
88
|
+
"build": "tsc -p tsconfig.build.json && pnpm run build:vendor",
|
|
89
|
+
"build:vendor": "node -e \"const fs=require('fs'); const path=require('path'); const src=path.join('vendor','oracle-notifier'); const dest=path.join('dist','vendor','oracle-notifier'); fs.mkdirSync(dest,{recursive:true}); if(fs.existsSync(src)){ fs.cpSync(src,dest,{recursive:true,force:true}); }\"",
|
|
90
|
+
"start": "pnpm run build && node ./dist/scripts/run-cli.js",
|
|
91
|
+
"oracle": "pnpm start",
|
|
92
|
+
"check": "pnpm run typecheck",
|
|
93
|
+
"typecheck": "tsc --noEmit",
|
|
94
|
+
"lint": "pnpm run typecheck && biome lint .",
|
|
95
|
+
"test": "vitest run",
|
|
96
|
+
"test:mcp": "pnpm run build && pnpm run test:mcp:unit && pnpm run test:mcp:mcporter",
|
|
97
|
+
"test:mcp:unit": "vitest run tests/mcp*.test.ts tests/mcp/**/*.test.ts",
|
|
98
|
+
"test:mcp:mcporter": "npx -y mcporter list oracle-local --schema --config config/mcporter.json && npx -y mcporter call oracle-local.sessions limit:1 --config config/mcporter.json",
|
|
99
|
+
"test:browser": "pnpm run build && tsx scripts/test-browser.ts && ./scripts/browser-smoke.sh",
|
|
100
|
+
"test:live": "ORACLE_LIVE_TEST=1 vitest run tests/live --exclude tests/live/openai-live.test.ts",
|
|
101
|
+
"test:pro": "ORACLE_LIVE_TEST=1 vitest run tests/live/openai-live.test.ts",
|
|
102
|
+
"test:coverage": "vitest run --coverage",
|
|
103
|
+
"mcp": "pnpm run build && node ./dist/bin/oracle-mcp.js"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Oracle Notifier helper (macOS, arm64)
|
|
2
|
-
|
|
3
|
-
Builds a tiny signed helper app for macOS notifications with the Oracle icon.
|
|
4
|
-
|
|
5
|
-
## Build
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
cd vendor/oracle-notifier
|
|
9
|
-
# Optional: notarize by setting App Store Connect key credentials
|
|
10
|
-
export APP_STORE_CONNECT_API_KEY_P8="$(cat AuthKey_XXXXXX.p8)" # with literal newlines or \n escaped
|
|
11
|
-
export APP_STORE_CONNECT_KEY_ID=XXXXXX
|
|
12
|
-
export APP_STORE_CONNECT_ISSUER_ID=YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY
|
|
13
|
-
./build-notifier.sh
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
- Requires Xcode command line tools (swiftc) and a macOS Developer ID certificate. Without a valid cert, the build fails (no ad-hoc fallback).
|
|
17
|
-
- If `APP_STORE_CONNECT_*` vars are set, the script notarizes and staples the ticket.
|
|
18
|
-
- Output: `OracleNotifier.app` (arm64 only), bundled with `OracleIcon.icns`.
|
|
19
|
-
|
|
20
|
-
## Usage
|
|
21
|
-
The CLI prefers this helper on macOS; if it fails or is missing, it falls back to toasted-notifier/terminal-notifier.
|
|
22
|
-
|
|
23
|
-
## Permissions
|
|
24
|
-
After first run, allow notifications for “Oracle Notifier” in System Settings → Notifications.
|