@steipete/oracle 1.0.8 → 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.
Files changed (58) hide show
  1. package/README.md +3 -0
  2. package/dist/.DS_Store +0 -0
  3. package/dist/bin/oracle-cli.js +9 -3
  4. package/dist/markdansi/types/index.js +4 -0
  5. package/dist/oracle/bin/oracle-cli.js +472 -0
  6. package/dist/oracle/src/browser/actions/assistantResponse.js +471 -0
  7. package/dist/oracle/src/browser/actions/attachments.js +82 -0
  8. package/dist/oracle/src/browser/actions/modelSelection.js +190 -0
  9. package/dist/oracle/src/browser/actions/navigation.js +75 -0
  10. package/dist/oracle/src/browser/actions/promptComposer.js +167 -0
  11. package/dist/oracle/src/browser/chromeLifecycle.js +104 -0
  12. package/dist/oracle/src/browser/config.js +33 -0
  13. package/dist/oracle/src/browser/constants.js +40 -0
  14. package/dist/oracle/src/browser/cookies.js +210 -0
  15. package/dist/oracle/src/browser/domDebug.js +36 -0
  16. package/dist/oracle/src/browser/index.js +331 -0
  17. package/dist/oracle/src/browser/pageActions.js +5 -0
  18. package/dist/oracle/src/browser/prompt.js +88 -0
  19. package/dist/oracle/src/browser/promptSummary.js +20 -0
  20. package/dist/oracle/src/browser/sessionRunner.js +80 -0
  21. package/dist/oracle/src/browser/types.js +1 -0
  22. package/dist/oracle/src/browser/utils.js +62 -0
  23. package/dist/oracle/src/browserMode.js +1 -0
  24. package/dist/oracle/src/cli/browserConfig.js +44 -0
  25. package/dist/oracle/src/cli/dryRun.js +59 -0
  26. package/dist/oracle/src/cli/engine.js +17 -0
  27. package/dist/oracle/src/cli/errorUtils.js +9 -0
  28. package/dist/oracle/src/cli/help.js +70 -0
  29. package/dist/oracle/src/cli/markdownRenderer.js +15 -0
  30. package/dist/oracle/src/cli/options.js +103 -0
  31. package/dist/oracle/src/cli/promptRequirement.js +14 -0
  32. package/dist/oracle/src/cli/rootAlias.js +30 -0
  33. package/dist/oracle/src/cli/sessionCommand.js +77 -0
  34. package/dist/oracle/src/cli/sessionDisplay.js +270 -0
  35. package/dist/oracle/src/cli/sessionRunner.js +94 -0
  36. package/dist/oracle/src/heartbeat.js +43 -0
  37. package/dist/oracle/src/oracle/client.js +48 -0
  38. package/dist/oracle/src/oracle/config.js +29 -0
  39. package/dist/oracle/src/oracle/errors.js +101 -0
  40. package/dist/oracle/src/oracle/files.js +220 -0
  41. package/dist/oracle/src/oracle/format.js +33 -0
  42. package/dist/oracle/src/oracle/fsAdapter.js +7 -0
  43. package/dist/oracle/src/oracle/oscProgress.js +60 -0
  44. package/dist/oracle/src/oracle/request.js +48 -0
  45. package/dist/oracle/src/oracle/run.js +444 -0
  46. package/dist/oracle/src/oracle/tokenStats.js +39 -0
  47. package/dist/oracle/src/oracle/types.js +1 -0
  48. package/dist/oracle/src/oracle.js +9 -0
  49. package/dist/oracle/src/sessionManager.js +205 -0
  50. package/dist/oracle/src/version.js +39 -0
  51. package/dist/src/cli/markdownRenderer.js +18 -0
  52. package/dist/src/cli/rootAlias.js +14 -0
  53. package/dist/src/cli/sessionCommand.js +60 -2
  54. package/dist/src/cli/sessionDisplay.js +129 -4
  55. package/dist/src/oracle/oscProgress.js +60 -0
  56. package/dist/src/oracle/run.js +63 -51
  57. package/dist/src/sessionManager.js +17 -0
  58. package/package.json +14 -22
@@ -13,6 +13,7 @@ import { getFileTokenStats, printFileTokenStats } from './tokenStats.js';
13
13
  import { OracleResponseError, OracleTransportError, PromptValidationError, describeTransportError, toTransportError, } from './errors.js';
14
14
  import { createDefaultClientFactory } from './client.js';
15
15
  import { startHeartbeat } from '../heartbeat.js';
16
+ import { startOscProgress } from './oscProgress.js';
16
17
  import { getCliVersion } from '../version.js';
17
18
  import { createFsAdapter } from './fsAdapter.js';
18
19
  const isTty = process.stdout.isTTY;
@@ -142,6 +143,11 @@ export async function runOracle(options, deps = {}) {
142
143
  }
143
144
  const openAiClient = client ?? clientFactory(apiKey);
144
145
  logVerbose('Dispatching request to OpenAI Responses API...');
146
+ const stopOscProgress = startOscProgress({
147
+ label: useBackground ? 'Waiting for OpenAI (background)' : 'Waiting for OpenAI',
148
+ targetMs: useBackground ? BACKGROUND_MAX_WAIT_MS : 10 * 60_000,
149
+ write,
150
+ });
145
151
  const runStart = now();
146
152
  let response = null;
147
153
  let elapsedMs = 0;
@@ -154,65 +160,71 @@ export async function runOracle(options, deps = {}) {
154
160
  answerHeaderPrinted = true;
155
161
  }
156
162
  };
157
- if (useBackground) {
158
- response = await executeBackgroundResponse({
159
- client: openAiClient,
160
- requestBody,
161
- log,
162
- wait,
163
- heartbeatIntervalMs: options.heartbeatIntervalMs,
164
- now,
165
- });
166
- elapsedMs = now() - runStart;
167
- }
168
- else {
169
- const stream = await openAiClient.responses.stream(requestBody);
170
- let heartbeatActive = false;
171
- let stopHeartbeat = null;
172
- const stopHeartbeatNow = () => {
173
- if (!heartbeatActive) {
174
- return;
175
- }
176
- heartbeatActive = false;
177
- stopHeartbeat?.();
178
- stopHeartbeat = null;
179
- };
180
- if (options.heartbeatIntervalMs && options.heartbeatIntervalMs > 0) {
181
- heartbeatActive = true;
182
- stopHeartbeat = startHeartbeat({
183
- intervalMs: options.heartbeatIntervalMs,
184
- log: (message) => log(message),
185
- isActive: () => heartbeatActive,
186
- makeMessage: (elapsedMs) => {
187
- const elapsedText = formatElapsed(elapsedMs);
188
- return `API connection active — ${elapsedText} elapsed. Expect up to ~10 min before GPT-5 responds.`;
189
- },
163
+ try {
164
+ if (useBackground) {
165
+ response = await executeBackgroundResponse({
166
+ client: openAiClient,
167
+ requestBody,
168
+ log,
169
+ wait,
170
+ heartbeatIntervalMs: options.heartbeatIntervalMs,
171
+ now,
190
172
  });
173
+ elapsedMs = now() - runStart;
191
174
  }
192
- try {
193
- for await (const event of stream) {
194
- if (event.type === 'response.output_text.delta') {
195
- stopHeartbeatNow();
196
- sawTextDelta = true;
197
- ensureAnswerHeader();
198
- if (!options.silent && typeof event.delta === 'string') {
199
- write(event.delta);
175
+ else {
176
+ const stream = await openAiClient.responses.stream(requestBody);
177
+ let heartbeatActive = false;
178
+ let stopHeartbeat = null;
179
+ const stopHeartbeatNow = () => {
180
+ if (!heartbeatActive) {
181
+ return;
182
+ }
183
+ heartbeatActive = false;
184
+ stopHeartbeat?.();
185
+ stopHeartbeat = null;
186
+ };
187
+ if (options.heartbeatIntervalMs && options.heartbeatIntervalMs > 0) {
188
+ heartbeatActive = true;
189
+ stopHeartbeat = startHeartbeat({
190
+ intervalMs: options.heartbeatIntervalMs,
191
+ log: (message) => log(message),
192
+ isActive: () => heartbeatActive,
193
+ makeMessage: (elapsedMs) => {
194
+ const elapsedText = formatElapsed(elapsedMs);
195
+ return `API connection active — ${elapsedText} elapsed. Expect up to ~10 min before GPT-5 responds.`;
196
+ },
197
+ });
198
+ }
199
+ try {
200
+ for await (const event of stream) {
201
+ if (event.type === 'response.output_text.delta') {
202
+ stopOscProgress();
203
+ stopHeartbeatNow();
204
+ sawTextDelta = true;
205
+ ensureAnswerHeader();
206
+ if (!options.silent && typeof event.delta === 'string') {
207
+ write(event.delta);
208
+ }
200
209
  }
201
210
  }
202
211
  }
203
- }
204
- catch (streamError) {
205
- if (typeof stream.abort === 'function') {
206
- stream.abort();
212
+ catch (streamError) {
213
+ if (typeof stream.abort === 'function') {
214
+ stream.abort();
215
+ }
216
+ stopHeartbeatNow();
217
+ const transportError = toTransportError(streamError);
218
+ log(chalk.yellow(describeTransportError(transportError)));
219
+ throw transportError;
207
220
  }
221
+ response = await stream.finalResponse();
208
222
  stopHeartbeatNow();
209
- const transportError = toTransportError(streamError);
210
- log(chalk.yellow(describeTransportError(transportError)));
211
- throw transportError;
223
+ elapsedMs = now() - runStart;
212
224
  }
213
- response = await stream.finalResponse();
214
- stopHeartbeatNow();
215
- elapsedMs = now() - runStart;
225
+ }
226
+ finally {
227
+ stopOscProgress();
216
228
  }
217
229
  if (!response) {
218
230
  throw new Error('OpenAI did not return a response.');
@@ -203,3 +203,20 @@ export async function wait(ms) {
203
203
  return new Promise((resolve) => setTimeout(resolve, ms));
204
204
  }
205
205
  export { ORACLE_HOME, SESSIONS_DIR, MAX_STATUS_LIMIT };
206
+ export async function getSessionPaths(sessionId) {
207
+ const dir = sessionDir(sessionId);
208
+ const metadata = metaPath(sessionId);
209
+ const log = logPath(sessionId);
210
+ const request = requestPath(sessionId);
211
+ const required = [metadata, log, request];
212
+ const missing = [];
213
+ for (const file of required) {
214
+ if (!(await fileExists(file))) {
215
+ missing.push(path.basename(file));
216
+ }
217
+ }
218
+ if (missing.length > 0) {
219
+ throw new Error(`Session "${sessionId}" is missing: ${missing.join(', ')}`);
220
+ }
221
+ return { dir, metadata, log, request };
222
+ }
package/package.json CHANGED
@@ -1,22 +1,12 @@
1
1
  {
2
2
  "name": "@steipete/oracle",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "CLI wrapper around OpenAI Responses API with GPT-5 Pro and GPT-5.1 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
  },
10
- "scripts": {
11
- "build": "tsc -p tsconfig.build.json",
12
- "start": "pnpm run build && node ./dist/scripts/run-cli.js",
13
- "oracle": "pnpm start",
14
- "typecheck": "tsc --noEmit",
15
- "lint": "pnpm run typecheck && biome lint .",
16
- "test": "vitest run",
17
- "test:coverage": "vitest run --coverage",
18
- "prepare": "pnpm run build"
19
- },
20
10
  "files": [
21
11
  "dist/**/*",
22
12
  "README.md",
@@ -44,6 +34,7 @@
44
34
  "gpt-tokenizer": "^3.4.0",
45
35
  "keytar": "^7.9.0",
46
36
  "kleur": "^4.1.5",
37
+ "markdansi": "^0.1.2",
47
38
  "openai": "^6.9.0",
48
39
  "sqlite3": "^5.1.7"
49
40
  },
@@ -52,18 +43,19 @@
52
43
  "@types/chrome-remote-interface": "^0.31.14",
53
44
  "@types/node": "^24.10.1",
54
45
  "@vitest/coverage-v8": "4.0.9",
55
- "bun-types": "^1.3.2",
56
- "devtools-protocol": "^0.0.1543509",
57
- "puppeteer-core": "^23.10.4",
58
- "tsx": "^4.20.0",
46
+ "devtools-protocol": "^0.0.1545402",
47
+ "puppeteer-core": "^24.30.0",
48
+ "tsx": "^4.20.6",
59
49
  "typescript": "^5.9.3",
60
50
  "vitest": "^4.0.9"
61
51
  },
62
- "pnpm": {
63
- "onlyBuiltDependencies": [
64
- "chrome-cookies-secure",
65
- "keytar",
66
- "sqlite3"
67
- ]
52
+ "scripts": {
53
+ "build": "tsc -p tsconfig.build.json",
54
+ "start": "pnpm run build && node ./dist/scripts/run-cli.js",
55
+ "oracle": "pnpm start",
56
+ "typecheck": "tsc --noEmit",
57
+ "lint": "pnpm run typecheck && biome lint .",
58
+ "test": "vitest run",
59
+ "test:coverage": "vitest run --coverage"
68
60
  }
69
- }
61
+ }