@steipete/oracle 0.9.0 → 0.10.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/LICENSE +1 -1
- package/README.md +61 -48
- package/dist/bin/oracle-cli.js +455 -402
- package/dist/bin/oracle-mcp.js +2 -2
- package/dist/bin/oracle.js +165 -279
- package/dist/scripts/agent-send.js +31 -31
- package/dist/scripts/check.js +6 -6
- package/dist/scripts/debug/extract-chatgpt-response.js +10 -10
- package/dist/scripts/docs-list.js +30 -30
- package/dist/scripts/git-policy.js +25 -23
- package/dist/scripts/run-cli.js +8 -8
- package/dist/scripts/runner.js +203 -195
- package/dist/scripts/test-browser.js +21 -18
- package/dist/scripts/test-remote-chrome.js +20 -20
- package/dist/src/bridge/connection.js +18 -18
- package/dist/src/bridge/userConfigFile.js +7 -7
- package/dist/src/browser/actions/assistantResponse.js +149 -101
- package/dist/src/browser/actions/attachmentDataTransfer.js +49 -47
- package/dist/src/browser/actions/attachments.js +246 -150
- package/dist/src/browser/actions/domEvents.js +2 -2
- package/dist/src/browser/actions/modelSelection.js +275 -117
- package/dist/src/browser/actions/navigation.js +161 -137
- package/dist/src/browser/actions/promptComposer.js +100 -64
- package/dist/src/browser/actions/remoteFileTransfer.js +10 -10
- package/dist/src/browser/actions/thinkingTime.js +207 -110
- package/dist/src/browser/chromeLifecycle.js +62 -60
- package/dist/src/browser/config.js +34 -15
- package/dist/src/browser/constants.js +17 -12
- package/dist/src/browser/cookies.js +19 -19
- package/dist/src/browser/detect.js +62 -62
- package/dist/src/browser/domDebug.js +1 -1
- package/dist/src/browser/index.js +390 -295
- package/dist/src/browser/modelStrategy.js +1 -1
- package/dist/src/browser/pageActions.js +5 -5
- package/dist/src/browser/policies.js +16 -13
- package/dist/src/browser/profileState.js +44 -39
- package/dist/src/browser/prompt.js +72 -42
- package/dist/src/browser/promptSummary.js +5 -5
- package/dist/src/browser/providerDomFlow.js +1 -1
- package/dist/src/browser/providers/chatgptDomProvider.js +9 -9
- package/dist/src/browser/providers/geminiDeepThinkDomProvider.js +51 -42
- package/dist/src/browser/providers/index.js +2 -2
- package/dist/src/browser/reattach.js +67 -34
- package/dist/src/browser/reattachHelpers.js +31 -26
- package/dist/src/browser/sessionRunner.js +37 -25
- package/dist/src/browser/utils.js +9 -9
- package/dist/src/browserMode.js +1 -1
- package/dist/src/cli/bridge/claudeConfig.js +16 -16
- package/dist/src/cli/bridge/client.js +28 -20
- package/dist/src/cli/bridge/codexConfig.js +16 -16
- package/dist/src/cli/bridge/doctor.js +47 -39
- package/dist/src/cli/bridge/host.js +58 -56
- package/dist/src/cli/browserConfig.js +62 -48
- package/dist/src/cli/browserDefaults.js +27 -26
- package/dist/src/cli/bundleWarnings.js +1 -1
- package/dist/src/cli/clipboard.js +11 -2
- package/dist/src/cli/detach.js +2 -2
- package/dist/src/cli/dryRun.js +29 -25
- package/dist/src/cli/duplicatePromptGuard.js +3 -3
- package/dist/src/cli/engine.js +9 -9
- package/dist/src/cli/errorUtils.js +1 -1
- package/dist/src/cli/fileSize.js +3 -3
- package/dist/src/cli/format.js +2 -2
- package/dist/src/cli/help.js +28 -28
- package/dist/src/cli/hiddenAliases.js +3 -3
- package/dist/src/cli/markdownBundle.js +7 -7
- package/dist/src/cli/markdownRenderer.js +15 -15
- package/dist/src/cli/notifier.js +77 -67
- package/dist/src/cli/options.js +127 -106
- package/dist/src/cli/oscUtils.js +1 -1
- package/dist/src/cli/promptRequirement.js +2 -2
- package/dist/src/cli/renderOutput.js +1 -1
- package/dist/src/cli/rootAlias.js +1 -1
- package/dist/src/cli/runOptions.js +32 -28
- package/dist/src/cli/sessionCommand.js +31 -21
- package/dist/src/cli/sessionDisplay.js +95 -81
- package/dist/src/cli/sessionLineage.js +6 -2
- package/dist/src/cli/sessionRunner.js +103 -93
- package/dist/src/cli/sessionTable.js +26 -23
- package/dist/src/cli/stdin.js +22 -0
- package/dist/src/cli/tagline.js +121 -124
- package/dist/src/cli/tui/index.js +139 -128
- package/dist/src/cli/writeOutputPath.js +5 -5
- package/dist/src/config.js +7 -7
- package/dist/src/gemini-web/browserSessionManager.js +19 -15
- package/dist/src/gemini-web/client.js +76 -70
- package/dist/src/gemini-web/executionMode.js +6 -8
- package/dist/src/gemini-web/executor.js +98 -93
- package/dist/src/gemini-web/index.js +1 -1
- package/dist/src/mcp/server.js +16 -12
- package/dist/src/mcp/tools/consult.js +51 -47
- package/dist/src/mcp/tools/sessionResources.js +12 -12
- package/dist/src/mcp/tools/sessions.js +26 -17
- package/dist/src/mcp/types.js +5 -5
- package/dist/src/mcp/utils.js +15 -7
- package/dist/src/oracle/background.js +15 -15
- package/dist/src/oracle/claude.js +53 -25
- package/dist/src/oracle/client.js +50 -41
- package/dist/src/oracle/config.js +96 -66
- package/dist/src/oracle/errors.js +38 -38
- package/dist/src/oracle/files.js +55 -46
- package/dist/src/oracle/finishLine.js +10 -8
- package/dist/src/oracle/format.js +3 -3
- package/dist/src/oracle/gemini.js +37 -33
- package/dist/src/oracle/logging.js +7 -7
- package/dist/src/oracle/markdown.js +28 -28
- package/dist/src/oracle/modelResolver.js +16 -16
- package/dist/src/oracle/multiModelRunner.js +12 -12
- package/dist/src/oracle/oscProgress.js +8 -8
- package/dist/src/oracle/promptAssembly.js +6 -3
- package/dist/src/oracle/request.js +16 -13
- package/dist/src/oracle/run.js +156 -134
- package/dist/src/oracle/runUtils.js +8 -5
- package/dist/src/oracle/tokenEstimate.js +6 -6
- package/dist/src/oracle/tokenStats.js +5 -5
- package/dist/src/oracle/tokenStringifier.js +5 -5
- package/dist/src/oracle.js +12 -12
- package/dist/src/oracleHome.js +3 -3
- package/dist/src/remote/client.js +25 -25
- package/dist/src/remote/health.js +20 -20
- package/dist/src/remote/remoteServiceConfig.js +9 -9
- package/dist/src/remote/server.js +129 -118
- package/dist/src/sessionManager.js +77 -75
- package/dist/src/sessionStore.js +3 -3
- package/dist/src/version.js +10 -10
- package/dist/vendor/oracle-notifier/README.md +2 -0
- package/package.json +66 -62
- package/vendor/oracle-notifier/README.md +2 -0
- package/dist/markdansi/types/index.js +0 -4
- package/dist/oracle/bin/oracle-cli.js +0 -472
- package/dist/oracle/src/browser/actions/assistantResponse.js +0 -471
- package/dist/oracle/src/browser/actions/attachments.js +0 -82
- package/dist/oracle/src/browser/actions/modelSelection.js +0 -190
- package/dist/oracle/src/browser/actions/navigation.js +0 -75
- package/dist/oracle/src/browser/actions/promptComposer.js +0 -167
- package/dist/oracle/src/browser/chromeLifecycle.js +0 -104
- package/dist/oracle/src/browser/config.js +0 -33
- package/dist/oracle/src/browser/constants.js +0 -40
- package/dist/oracle/src/browser/cookies.js +0 -210
- package/dist/oracle/src/browser/domDebug.js +0 -36
- package/dist/oracle/src/browser/index.js +0 -331
- package/dist/oracle/src/browser/pageActions.js +0 -5
- package/dist/oracle/src/browser/prompt.js +0 -88
- package/dist/oracle/src/browser/promptSummary.js +0 -20
- package/dist/oracle/src/browser/sessionRunner.js +0 -80
- package/dist/oracle/src/browser/types.js +0 -1
- package/dist/oracle/src/browser/utils.js +0 -62
- package/dist/oracle/src/browserMode.js +0 -1
- package/dist/oracle/src/cli/browserConfig.js +0 -44
- package/dist/oracle/src/cli/dryRun.js +0 -59
- package/dist/oracle/src/cli/engine.js +0 -17
- package/dist/oracle/src/cli/errorUtils.js +0 -9
- package/dist/oracle/src/cli/help.js +0 -70
- package/dist/oracle/src/cli/markdownRenderer.js +0 -15
- package/dist/oracle/src/cli/options.js +0 -103
- package/dist/oracle/src/cli/promptRequirement.js +0 -14
- package/dist/oracle/src/cli/rootAlias.js +0 -30
- package/dist/oracle/src/cli/sessionCommand.js +0 -77
- package/dist/oracle/src/cli/sessionDisplay.js +0 -270
- package/dist/oracle/src/cli/sessionRunner.js +0 -94
- package/dist/oracle/src/heartbeat.js +0 -43
- package/dist/oracle/src/oracle/client.js +0 -48
- package/dist/oracle/src/oracle/config.js +0 -29
- package/dist/oracle/src/oracle/errors.js +0 -101
- package/dist/oracle/src/oracle/files.js +0 -220
- package/dist/oracle/src/oracle/format.js +0 -33
- package/dist/oracle/src/oracle/fsAdapter.js +0 -7
- package/dist/oracle/src/oracle/oscProgress.js +0 -60
- package/dist/oracle/src/oracle/request.js +0 -48
- package/dist/oracle/src/oracle/run.js +0 -444
- package/dist/oracle/src/oracle/tokenStats.js +0 -39
- package/dist/oracle/src/oracle/types.js +0 -1
- package/dist/oracle/src/oracle.js +0 -9
- package/dist/oracle/src/sessionManager.js +0 -205
- package/dist/oracle/src/version.js +0 -39
- package/dist/scripts/chrome/browser-tools.js +0 -295
- package/dist/src/browser/profileSync.js +0 -141
package/dist/src/cli/options.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { InvalidArgumentError } from
|
|
2
|
-
import { parseDuration } from
|
|
3
|
-
import path from
|
|
4
|
-
import fg from
|
|
5
|
-
import { DEFAULT_MODEL, MODEL_CONFIGS } from
|
|
1
|
+
import { InvalidArgumentError } from "commander";
|
|
2
|
+
import { parseDuration } from "../browserMode.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fg from "fast-glob";
|
|
5
|
+
import { DEFAULT_MODEL, MODEL_CONFIGS } from "../oracle.js";
|
|
6
6
|
export function collectPaths(value, previous = []) {
|
|
7
7
|
if (!value) {
|
|
8
8
|
return previous;
|
|
9
9
|
}
|
|
10
10
|
const nextValues = Array.isArray(value) ? value : [value];
|
|
11
|
-
return previous.concat(nextValues
|
|
11
|
+
return previous.concat(nextValues
|
|
12
|
+
.flatMap((entry) => entry.split(","))
|
|
13
|
+
.map((entry) => entry.trim())
|
|
14
|
+
.filter(Boolean));
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
17
|
* Merge all path-like CLI inputs (file/include aliases) into a single list, preserving order.
|
|
@@ -29,7 +32,7 @@ export function dedupePathInputs(inputs, { cwd = process.cwd() } = {}) {
|
|
|
29
32
|
if (!raw)
|
|
30
33
|
continue;
|
|
31
34
|
let key = raw;
|
|
32
|
-
if (!raw.startsWith(
|
|
35
|
+
if (!raw.startsWith("!") && !fg.isDynamicPattern(raw)) {
|
|
33
36
|
const absolute = path.isAbsolute(raw) ? raw : path.resolve(cwd, raw);
|
|
34
37
|
key = `path:${path.normalize(absolute)}`;
|
|
35
38
|
}
|
|
@@ -50,7 +53,7 @@ export function collectModelList(value, previous = []) {
|
|
|
50
53
|
return previous;
|
|
51
54
|
}
|
|
52
55
|
const entries = value
|
|
53
|
-
.split(
|
|
56
|
+
.split(",")
|
|
54
57
|
.map((entry) => entry.trim())
|
|
55
58
|
.filter((entry) => entry.length > 0);
|
|
56
59
|
return previous.concat(entries);
|
|
@@ -58,7 +61,7 @@ export function collectModelList(value, previous = []) {
|
|
|
58
61
|
export function parseFloatOption(value) {
|
|
59
62
|
const parsed = Number.parseFloat(value);
|
|
60
63
|
if (Number.isNaN(parsed)) {
|
|
61
|
-
throw new InvalidArgumentError(
|
|
64
|
+
throw new InvalidArgumentError("Value must be a number.");
|
|
62
65
|
}
|
|
63
66
|
return parsed;
|
|
64
67
|
}
|
|
@@ -68,7 +71,7 @@ export function parseIntOption(value) {
|
|
|
68
71
|
}
|
|
69
72
|
const parsed = Number.parseInt(value, 10);
|
|
70
73
|
if (Number.isNaN(parsed)) {
|
|
71
|
-
throw new InvalidArgumentError(
|
|
74
|
+
throw new InvalidArgumentError("Value must be an integer.");
|
|
72
75
|
}
|
|
73
76
|
return parsed;
|
|
74
77
|
}
|
|
@@ -76,9 +79,9 @@ export function parseHeartbeatOption(value) {
|
|
|
76
79
|
if (value == null) {
|
|
77
80
|
return 30;
|
|
78
81
|
}
|
|
79
|
-
if (typeof value ===
|
|
82
|
+
if (typeof value === "number") {
|
|
80
83
|
if (Number.isNaN(value) || value < 0) {
|
|
81
|
-
throw new InvalidArgumentError(
|
|
84
|
+
throw new InvalidArgumentError("Heartbeat interval must be zero or a positive number.");
|
|
82
85
|
}
|
|
83
86
|
return value;
|
|
84
87
|
}
|
|
@@ -86,42 +89,42 @@ export function parseHeartbeatOption(value) {
|
|
|
86
89
|
if (normalized.length === 0) {
|
|
87
90
|
return 30;
|
|
88
91
|
}
|
|
89
|
-
if (normalized ===
|
|
92
|
+
if (normalized === "false" || normalized === "off") {
|
|
90
93
|
return 0;
|
|
91
94
|
}
|
|
92
95
|
const parsed = Number.parseFloat(normalized);
|
|
93
96
|
if (Number.isNaN(parsed) || parsed < 0) {
|
|
94
|
-
throw new InvalidArgumentError(
|
|
97
|
+
throw new InvalidArgumentError("Heartbeat interval must be zero or a positive number.");
|
|
95
98
|
}
|
|
96
99
|
return parsed;
|
|
97
100
|
}
|
|
98
101
|
export function usesDefaultStatusFilters(cmd) {
|
|
99
|
-
const hoursSource = cmd.getOptionValueSource?.(
|
|
100
|
-
const limitSource = cmd.getOptionValueSource?.(
|
|
101
|
-
const allSource = cmd.getOptionValueSource?.(
|
|
102
|
-
return hoursSource ===
|
|
102
|
+
const hoursSource = cmd.getOptionValueSource?.("hours") ?? "default";
|
|
103
|
+
const limitSource = cmd.getOptionValueSource?.("limit") ?? "default";
|
|
104
|
+
const allSource = cmd.getOptionValueSource?.("all") ?? "default";
|
|
105
|
+
return hoursSource === "default" && limitSource === "default" && allSource === "default";
|
|
103
106
|
}
|
|
104
107
|
export function resolvePreviewMode(value) {
|
|
105
|
-
if (typeof value ===
|
|
108
|
+
if (typeof value === "string" && value.length > 0) {
|
|
106
109
|
return value;
|
|
107
110
|
}
|
|
108
111
|
if (value === true) {
|
|
109
|
-
return
|
|
112
|
+
return "summary";
|
|
110
113
|
}
|
|
111
114
|
return undefined;
|
|
112
115
|
}
|
|
113
116
|
export function parseSearchOption(value) {
|
|
114
117
|
const normalized = value.trim().toLowerCase();
|
|
115
|
-
if ([
|
|
118
|
+
if (["on", "true", "1", "yes"].includes(normalized)) {
|
|
116
119
|
return true;
|
|
117
120
|
}
|
|
118
|
-
if ([
|
|
121
|
+
if (["off", "false", "0", "no"].includes(normalized)) {
|
|
119
122
|
return false;
|
|
120
123
|
}
|
|
121
124
|
throw new InvalidArgumentError('Search mode must be "on" or "off".');
|
|
122
125
|
}
|
|
123
126
|
export function normalizeModelOption(value) {
|
|
124
|
-
return (value ??
|
|
127
|
+
return (value ?? "").trim();
|
|
125
128
|
}
|
|
126
129
|
export function normalizeBaseUrl(value) {
|
|
127
130
|
const trimmed = value?.trim();
|
|
@@ -131,8 +134,8 @@ export function parseTimeoutOption(value) {
|
|
|
131
134
|
if (value == null)
|
|
132
135
|
return undefined;
|
|
133
136
|
const normalized = value.trim().toLowerCase();
|
|
134
|
-
if (normalized ===
|
|
135
|
-
return
|
|
137
|
+
if (normalized === "auto")
|
|
138
|
+
return "auto";
|
|
136
139
|
const parsed = Number.parseFloat(normalized);
|
|
137
140
|
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
138
141
|
throw new InvalidArgumentError('Timeout must be a positive number of seconds or "auto".');
|
|
@@ -153,68 +156,74 @@ export function parseDurationOption(value, label) {
|
|
|
153
156
|
return parsed;
|
|
154
157
|
}
|
|
155
158
|
function isGeminiDeepThinkAlias(normalized) {
|
|
156
|
-
return ((normalized.includes(
|
|
157
|
-
normalized.includes(
|
|
158
|
-
normalized.includes(
|
|
159
|
-
normalized.includes(
|
|
159
|
+
return ((normalized.includes("gemini") && normalized.includes("deep")) ||
|
|
160
|
+
normalized.includes("deep-think") ||
|
|
161
|
+
normalized.includes("deep_think") ||
|
|
162
|
+
normalized.includes("deepthink"));
|
|
160
163
|
}
|
|
161
164
|
export function resolveApiModel(modelValue) {
|
|
162
165
|
const normalized = normalizeModelOption(modelValue).toLowerCase();
|
|
163
166
|
if (normalized in MODEL_CONFIGS) {
|
|
164
167
|
return normalized;
|
|
165
168
|
}
|
|
166
|
-
if (normalized.includes(
|
|
169
|
+
if (normalized.includes("/")) {
|
|
167
170
|
return normalized;
|
|
168
171
|
}
|
|
169
|
-
if (normalized.includes(
|
|
170
|
-
return
|
|
172
|
+
if (normalized.includes("grok")) {
|
|
173
|
+
return "grok-4.1";
|
|
174
|
+
}
|
|
175
|
+
if (normalized.includes("claude") && normalized.includes("sonnet")) {
|
|
176
|
+
return "claude-4.6-sonnet";
|
|
177
|
+
}
|
|
178
|
+
if (normalized.includes("claude") && normalized.includes("opus")) {
|
|
179
|
+
return "claude-4.1-opus";
|
|
171
180
|
}
|
|
172
|
-
if (normalized.includes(
|
|
173
|
-
return
|
|
181
|
+
if (normalized.includes("5.5") && normalized.includes("pro")) {
|
|
182
|
+
return "gpt-5.5-pro";
|
|
174
183
|
}
|
|
175
|
-
if (normalized.includes(
|
|
176
|
-
return
|
|
184
|
+
if (normalized.includes("5.5")) {
|
|
185
|
+
return "gpt-5.5";
|
|
177
186
|
}
|
|
178
|
-
if (normalized.includes(
|
|
179
|
-
return
|
|
187
|
+
if (normalized.includes("5.4") && normalized.includes("pro")) {
|
|
188
|
+
return "gpt-5.4-pro";
|
|
180
189
|
}
|
|
181
|
-
if (normalized.includes(
|
|
182
|
-
return
|
|
190
|
+
if (normalized.includes("5.4")) {
|
|
191
|
+
return "gpt-5.4";
|
|
183
192
|
}
|
|
184
|
-
if (normalized ===
|
|
185
|
-
return
|
|
193
|
+
if (normalized === "claude" || normalized === "sonnet" || /(^|\b)sonnet(\b|$)/.test(normalized)) {
|
|
194
|
+
return "claude-4.6-sonnet";
|
|
186
195
|
}
|
|
187
|
-
if (normalized ===
|
|
188
|
-
return
|
|
196
|
+
if (normalized === "opus" || normalized === "claude-4.1") {
|
|
197
|
+
return "claude-4.1-opus";
|
|
189
198
|
}
|
|
190
|
-
if (normalized.includes(
|
|
191
|
-
return
|
|
199
|
+
if (normalized.includes("5.0") || normalized === "gpt-5-pro" || normalized === "gpt-5") {
|
|
200
|
+
return "gpt-5-pro";
|
|
192
201
|
}
|
|
193
|
-
if (normalized.includes(
|
|
194
|
-
return
|
|
202
|
+
if (normalized.includes("5-pro") && !normalized.includes("5.1")) {
|
|
203
|
+
return "gpt-5-pro";
|
|
195
204
|
}
|
|
196
|
-
if (normalized.includes(
|
|
197
|
-
return
|
|
205
|
+
if (normalized.includes("5.2") && normalized.includes("pro")) {
|
|
206
|
+
return "gpt-5.2-pro";
|
|
198
207
|
}
|
|
199
|
-
if (normalized.includes(
|
|
200
|
-
return
|
|
208
|
+
if (normalized.includes("5.1") && normalized.includes("pro")) {
|
|
209
|
+
return "gpt-5.1-pro";
|
|
201
210
|
}
|
|
202
|
-
if (normalized.includes(
|
|
203
|
-
if (normalized.includes(
|
|
204
|
-
throw new InvalidArgumentError(
|
|
211
|
+
if (normalized.includes("codex")) {
|
|
212
|
+
if (normalized.includes("max")) {
|
|
213
|
+
throw new InvalidArgumentError("gpt-5.1-codex-max is not available yet. OpenAI has not released the API.");
|
|
205
214
|
}
|
|
206
|
-
return
|
|
215
|
+
return "gpt-5.1-codex";
|
|
207
216
|
}
|
|
208
217
|
if (isGeminiDeepThinkAlias(normalized)) {
|
|
209
|
-
throw new InvalidArgumentError(
|
|
218
|
+
throw new InvalidArgumentError("Gemini Deep Think is browser-only today. Use --engine browser --model gemini-3-deep-think.");
|
|
210
219
|
}
|
|
211
|
-
if (normalized.includes(
|
|
212
|
-
if (normalized.includes(
|
|
213
|
-
return
|
|
220
|
+
if (normalized.includes("gemini")) {
|
|
221
|
+
if (normalized.includes("3.1") || normalized.includes("3_1")) {
|
|
222
|
+
return "gemini-3.1-pro";
|
|
214
223
|
}
|
|
215
|
-
return
|
|
224
|
+
return "gemini-3-pro";
|
|
216
225
|
}
|
|
217
|
-
if (normalized.includes(
|
|
226
|
+
if (normalized.includes("pro")) {
|
|
218
227
|
return DEFAULT_MODEL;
|
|
219
228
|
}
|
|
220
229
|
// Passthrough for custom/OpenRouter model IDs.
|
|
@@ -228,73 +237,85 @@ export function inferModelFromLabel(modelValue) {
|
|
|
228
237
|
if (normalized in MODEL_CONFIGS) {
|
|
229
238
|
return normalized;
|
|
230
239
|
}
|
|
231
|
-
if (normalized.includes(
|
|
240
|
+
if (normalized.includes("/")) {
|
|
232
241
|
return normalized;
|
|
233
242
|
}
|
|
234
|
-
if (normalized.includes(
|
|
235
|
-
return
|
|
243
|
+
if (normalized.includes("grok")) {
|
|
244
|
+
return "grok-4.1";
|
|
236
245
|
}
|
|
237
|
-
if (normalized.includes(
|
|
238
|
-
return
|
|
246
|
+
if (normalized.includes("claude") && normalized.includes("sonnet")) {
|
|
247
|
+
return "claude-4.6-sonnet";
|
|
239
248
|
}
|
|
240
|
-
if (normalized.includes(
|
|
241
|
-
return
|
|
249
|
+
if (normalized.includes("claude") && normalized.includes("opus")) {
|
|
250
|
+
return "claude-4.1-opus";
|
|
242
251
|
}
|
|
243
|
-
if (normalized.includes(
|
|
244
|
-
return
|
|
252
|
+
if (normalized.includes("codex")) {
|
|
253
|
+
return "gpt-5.1-codex";
|
|
245
254
|
}
|
|
246
255
|
if (isGeminiDeepThinkAlias(normalized)) {
|
|
247
|
-
return
|
|
256
|
+
return "gemini-3-pro-deep-think";
|
|
248
257
|
}
|
|
249
|
-
if (normalized.includes(
|
|
250
|
-
if (normalized.includes(
|
|
251
|
-
return
|
|
258
|
+
if (normalized.includes("gemini")) {
|
|
259
|
+
if (normalized.includes("3.1") || normalized.includes("3_1")) {
|
|
260
|
+
return "gemini-3.1-pro";
|
|
252
261
|
}
|
|
253
|
-
return
|
|
262
|
+
return "gemini-3-pro";
|
|
263
|
+
}
|
|
264
|
+
if (normalized.includes("classic")) {
|
|
265
|
+
return "gpt-5-pro";
|
|
266
|
+
}
|
|
267
|
+
if (normalized.includes("thinking") && normalized.includes("heavy")) {
|
|
268
|
+
return "gpt-5.5";
|
|
269
|
+
}
|
|
270
|
+
if ((normalized.includes("5.5") || normalized.includes("5_5")) && normalized.includes("pro")) {
|
|
271
|
+
return "gpt-5.5-pro";
|
|
254
272
|
}
|
|
255
|
-
if (normalized.includes(
|
|
256
|
-
return
|
|
273
|
+
if (normalized.includes("5.5") || normalized.includes("5_5")) {
|
|
274
|
+
return "gpt-5.5";
|
|
257
275
|
}
|
|
258
|
-
if ((normalized.includes(
|
|
259
|
-
return
|
|
276
|
+
if ((normalized.includes("5.4") || normalized.includes("5_4")) && normalized.includes("pro")) {
|
|
277
|
+
return "gpt-5.4-pro";
|
|
260
278
|
}
|
|
261
|
-
if (normalized.includes(
|
|
262
|
-
return
|
|
279
|
+
if (normalized.includes("5.4") || normalized.includes("5_4")) {
|
|
280
|
+
return "gpt-5.4";
|
|
263
281
|
}
|
|
264
|
-
if ((normalized.includes(
|
|
265
|
-
return
|
|
282
|
+
if ((normalized.includes("5.2") || normalized.includes("5_2")) && normalized.includes("pro")) {
|
|
283
|
+
return "gpt-5.2-pro";
|
|
266
284
|
}
|
|
267
285
|
// Browser-only: pass through 5.2 thinking/instant variants for browser label mapping
|
|
268
|
-
if ((normalized.includes(
|
|
269
|
-
|
|
286
|
+
if ((normalized.includes("5.2") || normalized.includes("5_2")) &&
|
|
287
|
+
normalized.includes("thinking")) {
|
|
288
|
+
return "gpt-5.2-thinking";
|
|
270
289
|
}
|
|
271
|
-
if ((normalized.includes(
|
|
272
|
-
|
|
290
|
+
if ((normalized.includes("5.2") || normalized.includes("5_2")) &&
|
|
291
|
+
normalized.includes("instant")) {
|
|
292
|
+
return "gpt-5.2-instant";
|
|
273
293
|
}
|
|
274
|
-
if (normalized.includes(
|
|
275
|
-
return
|
|
294
|
+
if (normalized.includes("5.0") || normalized.includes("5-pro")) {
|
|
295
|
+
return "gpt-5-pro";
|
|
276
296
|
}
|
|
277
|
-
if (normalized.includes(
|
|
278
|
-
normalized.includes(
|
|
279
|
-
!normalized.includes(
|
|
280
|
-
!normalized.includes(
|
|
281
|
-
!normalized.includes(
|
|
282
|
-
|
|
297
|
+
if (normalized.includes("gpt-5") &&
|
|
298
|
+
normalized.includes("pro") &&
|
|
299
|
+
!normalized.includes("5.1") &&
|
|
300
|
+
!normalized.includes("5.2") &&
|
|
301
|
+
!normalized.includes("5.5") &&
|
|
302
|
+
!normalized.includes("5.4")) {
|
|
303
|
+
return "gpt-5-pro";
|
|
283
304
|
}
|
|
284
|
-
if ((normalized.includes(
|
|
285
|
-
return
|
|
305
|
+
if ((normalized.includes("5.1") || normalized.includes("5_1")) && normalized.includes("pro")) {
|
|
306
|
+
return "gpt-5.1-pro";
|
|
286
307
|
}
|
|
287
|
-
if (normalized.includes(
|
|
308
|
+
if (normalized.includes("pro")) {
|
|
288
309
|
return DEFAULT_MODEL;
|
|
289
310
|
}
|
|
290
|
-
if (normalized.includes(
|
|
291
|
-
return
|
|
311
|
+
if (normalized.includes("5.1") || normalized.includes("5_1")) {
|
|
312
|
+
return "gpt-5.1";
|
|
292
313
|
}
|
|
293
|
-
if (normalized.includes(
|
|
294
|
-
return
|
|
314
|
+
if (normalized.includes("thinking")) {
|
|
315
|
+
return "gpt-5.2-thinking";
|
|
295
316
|
}
|
|
296
|
-
if (normalized.includes(
|
|
297
|
-
return
|
|
317
|
+
if (normalized.includes("instant") || normalized.includes("fast")) {
|
|
318
|
+
return "gpt-5.2-instant";
|
|
298
319
|
}
|
|
299
|
-
return
|
|
320
|
+
return "gpt-5.2";
|
|
300
321
|
}
|
package/dist/src/cli/oscUtils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Utilities for handling OSC progress codes embedded in stored logs.
|
|
2
|
-
export { sanitizeOscProgress } from
|
|
2
|
+
export { sanitizeOscProgress } from "osc-progress";
|
|
@@ -10,8 +10,8 @@ export function shouldRequirePrompt(rawArgs, options) {
|
|
|
10
10
|
options.execSession ||
|
|
11
11
|
options.status ||
|
|
12
12
|
options.debugHelp ||
|
|
13
|
-
firstArg ===
|
|
14
|
-
firstArg ===
|
|
13
|
+
firstArg === "status" ||
|
|
14
|
+
firstArg === "session");
|
|
15
15
|
const requiresPrompt = options.renderMarkdown || Boolean(options.preview) || Boolean(options.dryRun) || !bypassPrompt;
|
|
16
16
|
return requiresPrompt && !options.prompt;
|
|
17
17
|
}
|
|
@@ -1,51 +1,55 @@
|
|
|
1
|
-
import { DEFAULT_MODEL, MODEL_CONFIGS } from
|
|
2
|
-
import { resolveEngine } from
|
|
3
|
-
import { normalizeModelOption, inferModelFromLabel, resolveApiModel, normalizeBaseUrl } from
|
|
4
|
-
import { resolveGeminiModelId } from
|
|
5
|
-
import { PromptValidationError } from
|
|
6
|
-
import { normalizeChatGptModelForBrowser } from
|
|
7
|
-
import { resolveConfiguredMaxFileSizeBytes } from
|
|
1
|
+
import { DEFAULT_MODEL, MODEL_CONFIGS } from "../oracle.js";
|
|
2
|
+
import { resolveEngine } from "./engine.js";
|
|
3
|
+
import { normalizeModelOption, inferModelFromLabel, resolveApiModel, normalizeBaseUrl, } from "./options.js";
|
|
4
|
+
import { resolveGeminiModelId } from "../oracle/gemini.js";
|
|
5
|
+
import { PromptValidationError } from "../oracle/errors.js";
|
|
6
|
+
import { normalizeChatGptModelForBrowser } from "./browserConfig.js";
|
|
7
|
+
import { resolveConfiguredMaxFileSizeBytes } from "./fileSize.js";
|
|
8
8
|
export function resolveRunOptionsFromConfig({ prompt, files = [], model, models, engine, userConfig, env = process.env, }) {
|
|
9
9
|
const resolvedEngine = resolveEngineWithConfig({ engine, configEngine: userConfig?.engine, env });
|
|
10
|
-
const browserRequested = engine ===
|
|
11
|
-
const browserConfigured = userConfig?.engine ===
|
|
10
|
+
const browserRequested = engine === "browser";
|
|
11
|
+
const browserConfigured = userConfig?.engine === "browser";
|
|
12
12
|
const requestedModelList = Array.isArray(models) ? models : [];
|
|
13
|
-
const normalizedRequestedModels = requestedModelList
|
|
13
|
+
const normalizedRequestedModels = requestedModelList
|
|
14
|
+
.map((entry) => normalizeModelOption(entry))
|
|
15
|
+
.filter(Boolean);
|
|
14
16
|
const cliModelArg = normalizeModelOption(model ?? userConfig?.model) || DEFAULT_MODEL;
|
|
15
|
-
const inferredModel = resolvedEngine ===
|
|
17
|
+
const inferredModel = resolvedEngine === "browser" && normalizedRequestedModels.length === 0
|
|
16
18
|
? inferModelFromLabel(cliModelArg)
|
|
17
19
|
: resolveApiModel(cliModelArg);
|
|
18
|
-
// Browser engine maps Pro/legacy aliases to the latest ChatGPT picker targets
|
|
19
|
-
const resolvedModel = resolvedEngine ===
|
|
20
|
-
const isCodex = resolvedModel.startsWith(
|
|
21
|
-
const isClaude = resolvedModel.startsWith(
|
|
22
|
-
const isGrok = resolvedModel.startsWith(
|
|
23
|
-
const isGeminiApiOnly = resolvedModel ===
|
|
24
|
-
const engineWasBrowser = resolvedEngine ===
|
|
20
|
+
// Browser engine maps Pro/legacy aliases to the latest ChatGPT picker targets.
|
|
21
|
+
const resolvedModel = resolvedEngine === "browser" ? normalizeChatGptModelForBrowser(inferredModel) : inferredModel;
|
|
22
|
+
const isCodex = resolvedModel.startsWith("gpt-5.1-codex");
|
|
23
|
+
const isClaude = resolvedModel.startsWith("claude");
|
|
24
|
+
const isGrok = resolvedModel.startsWith("grok");
|
|
25
|
+
const isGeminiApiOnly = resolvedModel === "gemini-3.1-pro";
|
|
26
|
+
const engineWasBrowser = resolvedEngine === "browser";
|
|
25
27
|
const allModels = normalizedRequestedModels.length > 0
|
|
26
28
|
? Array.from(new Set(normalizedRequestedModels.map((entry) => resolveApiModel(entry))))
|
|
27
29
|
: [resolvedModel];
|
|
28
|
-
const includesGeminiApiOnly = allModels.some((m) => m ===
|
|
30
|
+
const includesGeminiApiOnly = allModels.some((m) => m === "gemini-3.1-pro");
|
|
29
31
|
if ((browserRequested || browserConfigured) && includesGeminiApiOnly) {
|
|
30
|
-
throw new PromptValidationError(
|
|
32
|
+
throw new PromptValidationError("gemini-3.1-pro is API-only today. Use --engine api or switch to gemini-3-pro for Gemini web.", { engine: "browser", models: allModels });
|
|
31
33
|
}
|
|
32
|
-
const isBrowserCompatible = (m) => m.startsWith(
|
|
34
|
+
const isBrowserCompatible = (m) => m.startsWith("gpt-") || m.startsWith("gemini");
|
|
33
35
|
const hasNonBrowserCompatibleTarget = (browserRequested || browserConfigured) && allModels.some((m) => !isBrowserCompatible(m));
|
|
34
36
|
if (hasNonBrowserCompatibleTarget) {
|
|
35
|
-
throw new PromptValidationError(
|
|
37
|
+
throw new PromptValidationError("Browser engine only supports GPT and Gemini models. Re-run with --engine api for Grok, Claude, or other models.", { engine: "browser", models: allModels });
|
|
36
38
|
}
|
|
37
39
|
const engineCoercedToApi = engineWasBrowser && (isCodex || isClaude || isGrok || isGeminiApiOnly);
|
|
38
|
-
const fixedEngine = isCodex || isClaude || isGrok || isGeminiApiOnly || normalizedRequestedModels.length > 0
|
|
40
|
+
const fixedEngine = isCodex || isClaude || isGrok || isGeminiApiOnly || normalizedRequestedModels.length > 0
|
|
41
|
+
? "api"
|
|
42
|
+
: resolvedEngine;
|
|
39
43
|
const promptWithSuffix = userConfig?.promptSuffix && userConfig.promptSuffix.trim().length > 0
|
|
40
44
|
? `${prompt.trim()}\n${userConfig.promptSuffix}`
|
|
41
45
|
: prompt;
|
|
42
|
-
const search = userConfig?.search !==
|
|
46
|
+
const search = userConfig?.search !== "off";
|
|
43
47
|
const heartbeatIntervalMs = userConfig?.heartbeatSeconds !== undefined ? userConfig.heartbeatSeconds * 1000 : 30_000;
|
|
44
48
|
const maxFileSizeBytes = resolveConfiguredMaxFileSizeBytes(userConfig, env);
|
|
45
49
|
const baseUrl = normalizeBaseUrl(userConfig?.apiBaseUrl ??
|
|
46
50
|
(isClaude ? env.ANTHROPIC_BASE_URL : isGrok ? env.XAI_BASE_URL : env.OPENAI_BASE_URL));
|
|
47
51
|
const uniqueMultiModels = normalizedRequestedModels.length > 0 ? allModels : [];
|
|
48
|
-
const includesCodexMultiModel = uniqueMultiModels.some((entry) => entry.startsWith(
|
|
52
|
+
const includesCodexMultiModel = uniqueMultiModels.some((entry) => entry.startsWith("gpt-5.1-codex"));
|
|
49
53
|
if (includesCodexMultiModel && browserRequested) {
|
|
50
54
|
// Silent coerce; multi-model still forces API.
|
|
51
55
|
}
|
|
@@ -69,8 +73,8 @@ export function resolveRunOptionsFromConfig({ prompt, files = [], model, models,
|
|
|
69
73
|
function resolveEngineWithConfig({ engine, configEngine, env, }) {
|
|
70
74
|
if (engine)
|
|
71
75
|
return engine;
|
|
72
|
-
const envOverride = (env.ORACLE_ENGINE ??
|
|
73
|
-
if (envOverride ===
|
|
76
|
+
const envOverride = (env.ORACLE_ENGINE ?? "").trim().toLowerCase();
|
|
77
|
+
if (envOverride === "api" || envOverride === "browser") {
|
|
74
78
|
return envOverride;
|
|
75
79
|
}
|
|
76
80
|
if (configEngine)
|
|
@@ -78,7 +82,7 @@ function resolveEngineWithConfig({ engine, configEngine, env, }) {
|
|
|
78
82
|
return resolveEngine({ engine: undefined, env });
|
|
79
83
|
}
|
|
80
84
|
function resolveEffectiveModelId(model) {
|
|
81
|
-
if (typeof model ===
|
|
85
|
+
if (typeof model === "string" && model.startsWith("gemini")) {
|
|
82
86
|
return resolveGeminiModelId(model);
|
|
83
87
|
}
|
|
84
88
|
const config = MODEL_CONFIGS[model];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import chalk from
|
|
2
|
-
import { usesDefaultStatusFilters } from
|
|
3
|
-
import { attachSession, showStatus } from
|
|
4
|
-
import { sessionStore } from
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { usesDefaultStatusFilters } from "./options.js";
|
|
3
|
+
import { attachSession, showStatus, } from "./sessionDisplay.js";
|
|
4
|
+
import { sessionStore } from "../sessionStore.js";
|
|
5
5
|
const defaultDependencies = {
|
|
6
6
|
showStatus,
|
|
7
7
|
attachSession,
|
|
@@ -9,39 +9,49 @@ const defaultDependencies = {
|
|
|
9
9
|
deleteSessionsOlderThan: (options) => sessionStore.deleteOlderThan(options),
|
|
10
10
|
getSessionPaths: (sessionId) => sessionStore.getPaths(sessionId),
|
|
11
11
|
};
|
|
12
|
-
const SESSION_OPTION_KEYS = new Set([
|
|
12
|
+
const SESSION_OPTION_KEYS = new Set([
|
|
13
|
+
"hours",
|
|
14
|
+
"limit",
|
|
15
|
+
"all",
|
|
16
|
+
"clear",
|
|
17
|
+
"clean",
|
|
18
|
+
"render",
|
|
19
|
+
"renderMarkdown",
|
|
20
|
+
"path",
|
|
21
|
+
"model",
|
|
22
|
+
]);
|
|
13
23
|
export async function handleSessionCommand(sessionId, command, deps = defaultDependencies) {
|
|
14
24
|
const sessionOptions = command.opts();
|
|
15
25
|
if (sessionOptions.verboseRender) {
|
|
16
|
-
process.env.ORACLE_VERBOSE_RENDER =
|
|
26
|
+
process.env.ORACLE_VERBOSE_RENDER = "1";
|
|
17
27
|
}
|
|
18
|
-
const renderSource = command.getOptionValueSource?.(
|
|
19
|
-
const renderMarkdownSource = command.getOptionValueSource?.(
|
|
20
|
-
const renderExplicit = renderSource ===
|
|
28
|
+
const renderSource = command.getOptionValueSource?.("render");
|
|
29
|
+
const renderMarkdownSource = command.getOptionValueSource?.("renderMarkdown");
|
|
30
|
+
const renderExplicit = renderSource === "cli" || renderMarkdownSource === "cli";
|
|
21
31
|
const autoRender = !renderExplicit && process.stdout.isTTY;
|
|
22
32
|
const pathRequested = Boolean(sessionOptions.path);
|
|
23
33
|
const clearRequested = Boolean(sessionOptions.clear || sessionOptions.clean);
|
|
24
34
|
if (clearRequested) {
|
|
25
35
|
if (sessionId) {
|
|
26
|
-
console.error(
|
|
36
|
+
console.error("Cannot combine a session ID with --clear. Remove the ID to delete cached sessions.");
|
|
27
37
|
process.exitCode = 1;
|
|
28
38
|
return;
|
|
29
39
|
}
|
|
30
40
|
const hours = sessionOptions.hours;
|
|
31
41
|
const includeAll = sessionOptions.all;
|
|
32
42
|
const result = await deps.deleteSessionsOlderThan({ hours, includeAll });
|
|
33
|
-
const scope = includeAll ?
|
|
43
|
+
const scope = includeAll ? "all stored sessions" : `sessions older than ${hours}h`;
|
|
34
44
|
console.log(formatSessionCleanupMessage(result, scope));
|
|
35
45
|
return;
|
|
36
46
|
}
|
|
37
|
-
if (sessionId ===
|
|
47
|
+
if (sessionId === "clear" || sessionId === "clean") {
|
|
38
48
|
console.error('Session cleanup now uses --clear. Run "oracle session --clear --hours <n>" instead.');
|
|
39
49
|
process.exitCode = 1;
|
|
40
50
|
return;
|
|
41
51
|
}
|
|
42
52
|
if (pathRequested) {
|
|
43
53
|
if (!sessionId) {
|
|
44
|
-
console.error(
|
|
54
|
+
console.error("The --path flag requires a session ID.");
|
|
45
55
|
process.exitCode = 1;
|
|
46
56
|
return;
|
|
47
57
|
}
|
|
@@ -50,10 +60,10 @@ export async function handleSessionCommand(sessionId, command, deps = defaultDep
|
|
|
50
60
|
const richTty = Boolean(process.stdout.isTTY && chalk.level > 0);
|
|
51
61
|
const label = (text) => (richTty ? chalk.cyan(text) : text);
|
|
52
62
|
const value = (text) => (richTty ? chalk.dim(text) : text);
|
|
53
|
-
console.log(`${label(
|
|
54
|
-
console.log(`${label(
|
|
55
|
-
console.log(`${label(
|
|
56
|
-
console.log(`${label(
|
|
63
|
+
console.log(`${label("Session dir:")} ${value(paths.dir)}`);
|
|
64
|
+
console.log(`${label("Metadata:")} ${value(paths.metadata)}`);
|
|
65
|
+
console.log(`${label("Request:")} ${value(paths.request)}`);
|
|
66
|
+
console.log(`${label("Log:")} ${value(paths.log)}`);
|
|
57
67
|
}
|
|
58
68
|
catch (error) {
|
|
59
69
|
console.error(error instanceof Error ? error.message : String(error));
|
|
@@ -75,7 +85,7 @@ export async function handleSessionCommand(sessionId, command, deps = defaultDep
|
|
|
75
85
|
// Surface any root-level flags that were provided but are ignored when attaching to a session.
|
|
76
86
|
const ignoredFlags = listIgnoredFlags(command);
|
|
77
87
|
if (ignoredFlags.length > 0) {
|
|
78
|
-
console.log(`Ignoring flags on session attach: ${ignoredFlags.join(
|
|
88
|
+
console.log(`Ignoring flags on session attach: ${ignoredFlags.join(", ")}`);
|
|
79
89
|
}
|
|
80
90
|
const renderMarkdown = Boolean(sessionOptions.render || sessionOptions.renderMarkdown || autoRender);
|
|
81
91
|
await deps.attachSession(sessionId, {
|
|
@@ -85,8 +95,8 @@ export async function handleSessionCommand(sessionId, command, deps = defaultDep
|
|
|
85
95
|
});
|
|
86
96
|
}
|
|
87
97
|
export function formatSessionCleanupMessage(result, scope) {
|
|
88
|
-
const deletedLabel = `${result.deleted} ${result.deleted === 1 ?
|
|
89
|
-
const remainingLabel = `${result.remaining} ${result.remaining === 1 ?
|
|
98
|
+
const deletedLabel = `${result.deleted} ${result.deleted === 1 ? "session" : "sessions"}`;
|
|
99
|
+
const remainingLabel = `${result.remaining} ${result.remaining === 1 ? "session" : "sessions"} remain`;
|
|
90
100
|
const hint = 'Run "oracle session --clear --all" to delete everything.';
|
|
91
101
|
return `Deleted ${deletedLabel} (${scope}). ${remainingLabel}.\n${hint}`;
|
|
92
102
|
}
|
|
@@ -98,7 +108,7 @@ function listIgnoredFlags(command) {
|
|
|
98
108
|
continue;
|
|
99
109
|
}
|
|
100
110
|
const source = command.getOptionValueSource?.(key);
|
|
101
|
-
if (source !==
|
|
111
|
+
if (source !== "cli" && source !== "env") {
|
|
102
112
|
continue;
|
|
103
113
|
}
|
|
104
114
|
const value = opts[key];
|