@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.
Files changed (177) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +61 -48
  3. package/dist/bin/oracle-cli.js +455 -402
  4. package/dist/bin/oracle-mcp.js +2 -2
  5. package/dist/bin/oracle.js +165 -279
  6. package/dist/scripts/agent-send.js +31 -31
  7. package/dist/scripts/check.js +6 -6
  8. package/dist/scripts/debug/extract-chatgpt-response.js +10 -10
  9. package/dist/scripts/docs-list.js +30 -30
  10. package/dist/scripts/git-policy.js +25 -23
  11. package/dist/scripts/run-cli.js +8 -8
  12. package/dist/scripts/runner.js +203 -195
  13. package/dist/scripts/test-browser.js +21 -18
  14. package/dist/scripts/test-remote-chrome.js +20 -20
  15. package/dist/src/bridge/connection.js +18 -18
  16. package/dist/src/bridge/userConfigFile.js +7 -7
  17. package/dist/src/browser/actions/assistantResponse.js +149 -101
  18. package/dist/src/browser/actions/attachmentDataTransfer.js +49 -47
  19. package/dist/src/browser/actions/attachments.js +246 -150
  20. package/dist/src/browser/actions/domEvents.js +2 -2
  21. package/dist/src/browser/actions/modelSelection.js +275 -117
  22. package/dist/src/browser/actions/navigation.js +161 -137
  23. package/dist/src/browser/actions/promptComposer.js +100 -64
  24. package/dist/src/browser/actions/remoteFileTransfer.js +10 -10
  25. package/dist/src/browser/actions/thinkingTime.js +207 -110
  26. package/dist/src/browser/chromeLifecycle.js +62 -60
  27. package/dist/src/browser/config.js +34 -15
  28. package/dist/src/browser/constants.js +17 -12
  29. package/dist/src/browser/cookies.js +19 -19
  30. package/dist/src/browser/detect.js +62 -62
  31. package/dist/src/browser/domDebug.js +1 -1
  32. package/dist/src/browser/index.js +390 -295
  33. package/dist/src/browser/modelStrategy.js +1 -1
  34. package/dist/src/browser/pageActions.js +5 -5
  35. package/dist/src/browser/policies.js +16 -13
  36. package/dist/src/browser/profileState.js +44 -39
  37. package/dist/src/browser/prompt.js +72 -42
  38. package/dist/src/browser/promptSummary.js +5 -5
  39. package/dist/src/browser/providerDomFlow.js +1 -1
  40. package/dist/src/browser/providers/chatgptDomProvider.js +9 -9
  41. package/dist/src/browser/providers/geminiDeepThinkDomProvider.js +51 -42
  42. package/dist/src/browser/providers/index.js +2 -2
  43. package/dist/src/browser/reattach.js +67 -34
  44. package/dist/src/browser/reattachHelpers.js +31 -26
  45. package/dist/src/browser/sessionRunner.js +37 -25
  46. package/dist/src/browser/utils.js +9 -9
  47. package/dist/src/browserMode.js +1 -1
  48. package/dist/src/cli/bridge/claudeConfig.js +16 -16
  49. package/dist/src/cli/bridge/client.js +28 -20
  50. package/dist/src/cli/bridge/codexConfig.js +16 -16
  51. package/dist/src/cli/bridge/doctor.js +47 -39
  52. package/dist/src/cli/bridge/host.js +58 -56
  53. package/dist/src/cli/browserConfig.js +62 -48
  54. package/dist/src/cli/browserDefaults.js +27 -26
  55. package/dist/src/cli/bundleWarnings.js +1 -1
  56. package/dist/src/cli/clipboard.js +11 -2
  57. package/dist/src/cli/detach.js +2 -2
  58. package/dist/src/cli/dryRun.js +29 -25
  59. package/dist/src/cli/duplicatePromptGuard.js +3 -3
  60. package/dist/src/cli/engine.js +9 -9
  61. package/dist/src/cli/errorUtils.js +1 -1
  62. package/dist/src/cli/fileSize.js +3 -3
  63. package/dist/src/cli/format.js +2 -2
  64. package/dist/src/cli/help.js +28 -28
  65. package/dist/src/cli/hiddenAliases.js +3 -3
  66. package/dist/src/cli/markdownBundle.js +7 -7
  67. package/dist/src/cli/markdownRenderer.js +15 -15
  68. package/dist/src/cli/notifier.js +77 -67
  69. package/dist/src/cli/options.js +127 -106
  70. package/dist/src/cli/oscUtils.js +1 -1
  71. package/dist/src/cli/promptRequirement.js +2 -2
  72. package/dist/src/cli/renderOutput.js +1 -1
  73. package/dist/src/cli/rootAlias.js +1 -1
  74. package/dist/src/cli/runOptions.js +32 -28
  75. package/dist/src/cli/sessionCommand.js +31 -21
  76. package/dist/src/cli/sessionDisplay.js +95 -81
  77. package/dist/src/cli/sessionLineage.js +6 -2
  78. package/dist/src/cli/sessionRunner.js +103 -93
  79. package/dist/src/cli/sessionTable.js +26 -23
  80. package/dist/src/cli/stdin.js +22 -0
  81. package/dist/src/cli/tagline.js +121 -124
  82. package/dist/src/cli/tui/index.js +139 -128
  83. package/dist/src/cli/writeOutputPath.js +5 -5
  84. package/dist/src/config.js +7 -7
  85. package/dist/src/gemini-web/browserSessionManager.js +19 -15
  86. package/dist/src/gemini-web/client.js +76 -70
  87. package/dist/src/gemini-web/executionMode.js +6 -8
  88. package/dist/src/gemini-web/executor.js +98 -93
  89. package/dist/src/gemini-web/index.js +1 -1
  90. package/dist/src/mcp/server.js +16 -12
  91. package/dist/src/mcp/tools/consult.js +51 -47
  92. package/dist/src/mcp/tools/sessionResources.js +12 -12
  93. package/dist/src/mcp/tools/sessions.js +26 -17
  94. package/dist/src/mcp/types.js +5 -5
  95. package/dist/src/mcp/utils.js +15 -7
  96. package/dist/src/oracle/background.js +15 -15
  97. package/dist/src/oracle/claude.js +53 -25
  98. package/dist/src/oracle/client.js +50 -41
  99. package/dist/src/oracle/config.js +96 -66
  100. package/dist/src/oracle/errors.js +38 -38
  101. package/dist/src/oracle/files.js +55 -46
  102. package/dist/src/oracle/finishLine.js +10 -8
  103. package/dist/src/oracle/format.js +3 -3
  104. package/dist/src/oracle/gemini.js +37 -33
  105. package/dist/src/oracle/logging.js +7 -7
  106. package/dist/src/oracle/markdown.js +28 -28
  107. package/dist/src/oracle/modelResolver.js +16 -16
  108. package/dist/src/oracle/multiModelRunner.js +12 -12
  109. package/dist/src/oracle/oscProgress.js +8 -8
  110. package/dist/src/oracle/promptAssembly.js +6 -3
  111. package/dist/src/oracle/request.js +16 -13
  112. package/dist/src/oracle/run.js +156 -134
  113. package/dist/src/oracle/runUtils.js +8 -5
  114. package/dist/src/oracle/tokenEstimate.js +6 -6
  115. package/dist/src/oracle/tokenStats.js +5 -5
  116. package/dist/src/oracle/tokenStringifier.js +5 -5
  117. package/dist/src/oracle.js +12 -12
  118. package/dist/src/oracleHome.js +3 -3
  119. package/dist/src/remote/client.js +25 -25
  120. package/dist/src/remote/health.js +20 -20
  121. package/dist/src/remote/remoteServiceConfig.js +9 -9
  122. package/dist/src/remote/server.js +129 -118
  123. package/dist/src/sessionManager.js +77 -75
  124. package/dist/src/sessionStore.js +3 -3
  125. package/dist/src/version.js +10 -10
  126. package/dist/vendor/oracle-notifier/README.md +2 -0
  127. package/package.json +66 -62
  128. package/vendor/oracle-notifier/README.md +2 -0
  129. package/dist/markdansi/types/index.js +0 -4
  130. package/dist/oracle/bin/oracle-cli.js +0 -472
  131. package/dist/oracle/src/browser/actions/assistantResponse.js +0 -471
  132. package/dist/oracle/src/browser/actions/attachments.js +0 -82
  133. package/dist/oracle/src/browser/actions/modelSelection.js +0 -190
  134. package/dist/oracle/src/browser/actions/navigation.js +0 -75
  135. package/dist/oracle/src/browser/actions/promptComposer.js +0 -167
  136. package/dist/oracle/src/browser/chromeLifecycle.js +0 -104
  137. package/dist/oracle/src/browser/config.js +0 -33
  138. package/dist/oracle/src/browser/constants.js +0 -40
  139. package/dist/oracle/src/browser/cookies.js +0 -210
  140. package/dist/oracle/src/browser/domDebug.js +0 -36
  141. package/dist/oracle/src/browser/index.js +0 -331
  142. package/dist/oracle/src/browser/pageActions.js +0 -5
  143. package/dist/oracle/src/browser/prompt.js +0 -88
  144. package/dist/oracle/src/browser/promptSummary.js +0 -20
  145. package/dist/oracle/src/browser/sessionRunner.js +0 -80
  146. package/dist/oracle/src/browser/types.js +0 -1
  147. package/dist/oracle/src/browser/utils.js +0 -62
  148. package/dist/oracle/src/browserMode.js +0 -1
  149. package/dist/oracle/src/cli/browserConfig.js +0 -44
  150. package/dist/oracle/src/cli/dryRun.js +0 -59
  151. package/dist/oracle/src/cli/engine.js +0 -17
  152. package/dist/oracle/src/cli/errorUtils.js +0 -9
  153. package/dist/oracle/src/cli/help.js +0 -70
  154. package/dist/oracle/src/cli/markdownRenderer.js +0 -15
  155. package/dist/oracle/src/cli/options.js +0 -103
  156. package/dist/oracle/src/cli/promptRequirement.js +0 -14
  157. package/dist/oracle/src/cli/rootAlias.js +0 -30
  158. package/dist/oracle/src/cli/sessionCommand.js +0 -77
  159. package/dist/oracle/src/cli/sessionDisplay.js +0 -270
  160. package/dist/oracle/src/cli/sessionRunner.js +0 -94
  161. package/dist/oracle/src/heartbeat.js +0 -43
  162. package/dist/oracle/src/oracle/client.js +0 -48
  163. package/dist/oracle/src/oracle/config.js +0 -29
  164. package/dist/oracle/src/oracle/errors.js +0 -101
  165. package/dist/oracle/src/oracle/files.js +0 -220
  166. package/dist/oracle/src/oracle/format.js +0 -33
  167. package/dist/oracle/src/oracle/fsAdapter.js +0 -7
  168. package/dist/oracle/src/oracle/oscProgress.js +0 -60
  169. package/dist/oracle/src/oracle/request.js +0 -48
  170. package/dist/oracle/src/oracle/run.js +0 -444
  171. package/dist/oracle/src/oracle/tokenStats.js +0 -39
  172. package/dist/oracle/src/oracle/types.js +0 -1
  173. package/dist/oracle/src/oracle.js +0 -9
  174. package/dist/oracle/src/sessionManager.js +0 -205
  175. package/dist/oracle/src/version.js +0 -39
  176. package/dist/scripts/chrome/browser-tools.js +0 -295
  177. package/dist/src/browser/profileSync.js +0 -141
@@ -1,4 +1,4 @@
1
- import { TOKENIZER_OPTIONS } from './config.js';
1
+ import { TOKENIZER_OPTIONS } from "./config.js";
2
2
  /**
3
3
  * Estimate input tokens from the full request body instead of just system/user text.
4
4
  * This is a conservative approximation: we tokenize the key textual fields and add a fixed buffer
@@ -12,7 +12,7 @@ export function estimateRequestTokens(requestBody, modelConfig, bufferTokens = 2
12
12
  }
13
13
  for (const turn of requestBody.input ?? []) {
14
14
  for (const content of turn.content ?? []) {
15
- if (typeof content.text === 'string') {
15
+ if (typeof content.text === "string") {
16
16
  parts.push(content.text);
17
17
  }
18
18
  }
@@ -24,14 +24,14 @@ export function estimateRequestTokens(requestBody, modelConfig, bufferTokens = 2
24
24
  parts.push(JSON.stringify(requestBody.reasoning));
25
25
  }
26
26
  if (requestBody.background) {
27
- parts.push('background:true');
27
+ parts.push("background:true");
28
28
  }
29
29
  if (requestBody.store) {
30
- parts.push('store:true');
30
+ parts.push("store:true");
31
31
  }
32
- const concatenated = parts.join('\n');
32
+ const concatenated = parts.join("\n");
33
33
  const baseEstimate = modelConfig.tokenizer(concatenated, TOKENIZER_OPTIONS);
34
- const hasWebSearch = requestBody.tools?.some((tool) => tool?.type === 'web_search_preview');
34
+ const hasWebSearch = requestBody.tools?.some((tool) => tool?.type === "web_search_preview");
35
35
  const searchBuffer = hasWebSearch ? SEARCH_RESULT_BUFFER_TOKENS : 0;
36
36
  return baseEstimate + bufferTokens + searchBuffer;
37
37
  }
@@ -1,5 +1,5 @@
1
- import chalk from 'chalk';
2
- import { createFileSections } from './files.js';
1
+ import chalk from "chalk";
2
+ import { createFileSections } from "./files.js";
3
3
  export function getFileTokenStats(files, { cwd = process.cwd(), tokenizer, tokenizerOptions, inputTokenBudget, }) {
4
4
  if (!files.length) {
5
5
  return { stats: [], totalTokens: 0 };
@@ -20,13 +20,13 @@ export function getFileTokenStats(files, { cwd = process.cwd(), tokenizer, token
20
20
  const totalTokens = stats.reduce((sum, entry) => sum + entry.tokens, 0);
21
21
  return { stats, totalTokens };
22
22
  }
23
- export function printFileTokenStats({ stats, totalTokens }, { inputTokenBudget, log = console.log }) {
23
+ export function printFileTokenStats({ stats, totalTokens }, { inputTokenBudget, log = console.log, }) {
24
24
  if (!stats.length) {
25
25
  return;
26
26
  }
27
- log(chalk.bold('File Token Usage'));
27
+ log(chalk.bold("File Token Usage"));
28
28
  for (const entry of stats) {
29
- const percentLabel = inputTokenBudget && entry.percent != null ? `${entry.percent.toFixed(2)}%` : 'n/a';
29
+ const percentLabel = inputTokenBudget && entry.percent != null ? `${entry.percent.toFixed(2)}%` : "n/a";
30
30
  log(`${entry.tokens.toLocaleString().padStart(10)} ${percentLabel.padStart(8)} ${entry.displayPath}`);
31
31
  }
32
32
  if (inputTokenBudget) {
@@ -1,14 +1,14 @@
1
1
  // Minimal helper to stringify arbitrary input for tokenizer consumption.
2
2
  // Anthropic's tokenizer expects a string; we accept unknown and coerce safely.
3
3
  export function stringifyTokenizerInput(input) {
4
- if (typeof input === 'string')
4
+ if (typeof input === "string")
5
5
  return input;
6
6
  if (input === null || input === undefined)
7
- return '';
8
- if (typeof input === 'number' || typeof input === 'boolean' || typeof input === 'bigint') {
7
+ return "";
8
+ if (typeof input === "number" || typeof input === "boolean" || typeof input === "bigint") {
9
9
  return String(input);
10
10
  }
11
- if (typeof input === 'object') {
11
+ if (typeof input === "object") {
12
12
  try {
13
13
  return JSON.stringify(input);
14
14
  }
@@ -16,7 +16,7 @@ export function stringifyTokenizerInput(input) {
16
16
  // fall through to generic stringification
17
17
  }
18
18
  }
19
- if (typeof input === 'function') {
19
+ if (typeof input === "function") {
20
20
  return input.toString();
21
21
  }
22
22
  return String(input);
@@ -1,12 +1,12 @@
1
- export * from './oracle/types.js';
2
- export { MODEL_CONFIGS, DEFAULT_MODEL, PRO_MODELS, DEFAULT_SYSTEM_PROMPT, TOKENIZER_OPTIONS, } from './oracle/config.js';
3
- export { readFiles, createFileSections } from './oracle/files.js';
4
- export { buildPrompt, buildRequestBody, renderPromptMarkdown } from './oracle/request.js';
5
- export { estimateRequestTokens } from './oracle/tokenEstimate.js';
6
- export { formatUSD, formatNumber, formatElapsed } from './oracle/format.js';
7
- export { formatFileSection } from './oracle/markdown.js';
8
- export { getFileTokenStats, printFileTokenStats } from './oracle/tokenStats.js';
9
- export { OracleResponseError, OracleTransportError, OracleUserError, FileValidationError, BrowserAutomationError, PromptValidationError, describeTransportError, extractResponseMetadata, asOracleUserError, toTransportError, } from './oracle/errors.js';
10
- export { createDefaultClientFactory } from './oracle/client.js';
11
- export { runOracle, extractTextOutput } from './oracle/run.js';
12
- export { resolveGeminiModelId } from './oracle/gemini.js';
1
+ export * from "./oracle/types.js";
2
+ export { MODEL_CONFIGS, DEFAULT_MODEL, PRO_MODELS, DEFAULT_SYSTEM_PROMPT, TOKENIZER_OPTIONS, } from "./oracle/config.js";
3
+ export { readFiles, createFileSections } from "./oracle/files.js";
4
+ export { buildPrompt, buildRequestBody, renderPromptMarkdown } from "./oracle/request.js";
5
+ export { estimateRequestTokens } from "./oracle/tokenEstimate.js";
6
+ export { formatUSD, formatNumber, formatElapsed } from "./oracle/format.js";
7
+ export { formatFileSection } from "./oracle/markdown.js";
8
+ export { getFileTokenStats, printFileTokenStats } from "./oracle/tokenStats.js";
9
+ export { OracleResponseError, OracleTransportError, OracleUserError, FileValidationError, BrowserAutomationError, PromptValidationError, describeTransportError, extractResponseMetadata, asOracleUserError, toTransportError, } from "./oracle/errors.js";
10
+ export { createDefaultClientFactory } from "./oracle/client.js";
11
+ export { runOracle, extractTextOutput } from "./oracle/run.js";
12
+ export { resolveGeminiModelId } from "./oracle/gemini.js";
@@ -1,5 +1,5 @@
1
- import os from 'node:os';
2
- import path from 'node:path';
1
+ import os from "node:os";
2
+ import path from "node:path";
3
3
  let oracleHomeDirOverride = null;
4
4
  /**
5
5
  * Test-only hook: avoid mutating process.env (shared across Vitest worker threads).
@@ -9,5 +9,5 @@ export function setOracleHomeDirOverrideForTest(dir) {
9
9
  oracleHomeDirOverride = dir;
10
10
  }
11
11
  export function getOracleHomeDir() {
12
- return oracleHomeDirOverride ?? process.env.ORACLE_HOME_DIR ?? path.join(os.homedir(), '.oracle');
12
+ return oracleHomeDirOverride ?? process.env.ORACLE_HOME_DIR ?? path.join(os.homedir(), ".oracle");
13
13
  }
@@ -1,7 +1,7 @@
1
- import http from 'node:http';
2
- import path from 'node:path';
3
- import { readFile } from 'node:fs/promises';
4
- import { parseHostPort } from '../bridge/connection.js';
1
+ import http from "node:http";
2
+ import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
+ import { parseHostPort } from "../bridge/connection.js";
5
5
  export function createRemoteBrowserExecutor({ host, token }) {
6
6
  // Return a drop-in replacement for runBrowserMode so the browser session runner can stay unchanged.
7
7
  return async function remoteBrowserExecutor(options) {
@@ -20,11 +20,11 @@ export function createRemoteBrowserExecutor({ host, token }) {
20
20
  const req = http.request({
21
21
  hostname,
22
22
  port,
23
- path: '/runs',
24
- method: 'POST',
23
+ path: "/runs",
24
+ method: "POST",
25
25
  headers: {
26
- 'Content-Type': 'application/json',
27
- 'Content-Length': body.length,
26
+ "Content-Type": "application/json",
27
+ "Content-Length": body.length,
28
28
  ...(token ? { authorization: `Bearer ${token}` } : {}),
29
29
  },
30
30
  }, (res) => {
@@ -34,12 +34,12 @@ export function createRemoteBrowserExecutor({ host, token }) {
34
34
  .catch(reject);
35
35
  return;
36
36
  }
37
- res.setEncoding('utf8');
38
- let buffer = '';
37
+ res.setEncoding("utf8");
38
+ let buffer = "";
39
39
  let resolved = null;
40
- res.on('data', (chunk) => {
40
+ res.on("data", (chunk) => {
41
41
  buffer += chunk;
42
- let newlineIndex = buffer.indexOf('\n');
42
+ let newlineIndex = buffer.indexOf("\n");
43
43
  while (newlineIndex !== -1) {
44
44
  const line = buffer.slice(0, newlineIndex).trim();
45
45
  buffer = buffer.slice(newlineIndex + 1);
@@ -48,18 +48,18 @@ export function createRemoteBrowserExecutor({ host, token }) {
48
48
  resolved = result;
49
49
  }, reject);
50
50
  }
51
- newlineIndex = buffer.indexOf('\n');
51
+ newlineIndex = buffer.indexOf("\n");
52
52
  }
53
53
  });
54
- res.on('end', () => {
54
+ res.on("end", () => {
55
55
  if (resolved) {
56
56
  resolve(resolved);
57
57
  return;
58
58
  }
59
- reject(new Error('Remote browser run completed without a result.'));
59
+ reject(new Error("Remote browser run completed without a result."));
60
60
  });
61
61
  });
62
- req.on('error', reject);
62
+ req.on("error", reject);
63
63
  req.write(body);
64
64
  req.end();
65
65
  });
@@ -74,7 +74,7 @@ async function serializeAttachments(attachments) {
74
74
  fileName: path.basename(attachment.path),
75
75
  displayPath: attachment.displayPath,
76
76
  sizeBytes: attachment.sizeBytes,
77
- contentBase64: content.toString('base64'),
77
+ contentBase64: content.toString("base64"),
78
78
  });
79
79
  }
80
80
  return serialized;
@@ -96,26 +96,26 @@ function handleEvent(line, options, onResult, onError) {
96
96
  onError(new Error(`Failed to parse remote event: ${error instanceof Error ? error.message : String(error)}`));
97
97
  return;
98
98
  }
99
- if (event.type === 'log') {
99
+ if (event.type === "log") {
100
100
  options.log?.(event.message);
101
101
  return;
102
102
  }
103
- if (event.type === 'error') {
103
+ if (event.type === "error") {
104
104
  onError(new Error(event.message));
105
105
  return;
106
106
  }
107
- if (event.type === 'result') {
107
+ if (event.type === "result") {
108
108
  onResult(event.result);
109
109
  }
110
110
  }
111
111
  function collectError(res) {
112
112
  return new Promise((resolve, reject) => {
113
113
  const chunks = [];
114
- res.on('data', (chunk) => {
115
- chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
114
+ res.on("data", (chunk) => {
115
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
116
116
  });
117
- res.on('end', () => {
118
- const raw = Buffer.concat(chunks).toString('utf8');
117
+ res.on("end", () => {
118
+ const raw = Buffer.concat(chunks).toString("utf8");
119
119
  try {
120
120
  const parsed = JSON.parse(raw);
121
121
  resolve(parsed.error ?? `Remote host responded with status ${res.statusCode}`);
@@ -124,6 +124,6 @@ function collectError(res) {
124
124
  resolve(raw || `Remote host responded with status ${res.statusCode}`);
125
125
  }
126
126
  });
127
- res.on('error', reject);
127
+ res.on("error", reject);
128
128
  });
129
129
  }
@@ -1,6 +1,6 @@
1
- import http from 'node:http';
2
- import net from 'node:net';
3
- import { parseHostPort } from '../bridge/connection.js';
1
+ import http from "node:http";
2
+ import net from "node:net";
3
+ import { parseHostPort } from "../bridge/connection.js";
4
4
  export async function checkTcpConnection(host, timeoutMs = 2000) {
5
5
  const { hostname, port } = parseHostPort(host);
6
6
  return await new Promise((resolve) => {
@@ -24,14 +24,14 @@ export async function checkTcpConnection(host, timeoutMs = 2000) {
24
24
  socket.unref();
25
25
  };
26
26
  socket.setTimeout(timeoutMs);
27
- socket.once('error', onError);
28
- socket.once('connect', onConnect);
29
- socket.once('timeout', onTimeout);
27
+ socket.once("error", onError);
28
+ socket.once("connect", onConnect);
29
+ socket.once("timeout", onTimeout);
30
30
  });
31
31
  }
32
32
  export async function checkRemoteHealth({ host, token, timeoutMs = 5000, }) {
33
33
  const { hostname, port } = parseHostPort(host);
34
- const headers = { accept: 'application/json' };
34
+ const headers = { accept: "application/json" };
35
35
  if (token) {
36
36
  headers.authorization = `Bearer ${token}`;
37
37
  }
@@ -39,26 +39,26 @@ export async function checkRemoteHealth({ host, token, timeoutMs = 5000, }) {
39
39
  const response = await requestJson({
40
40
  hostname,
41
41
  port,
42
- path: '/health',
42
+ path: "/health",
43
43
  headers,
44
44
  timeoutMs,
45
45
  });
46
- if (response.statusCode === 200 && typeof response.json === 'object' && response.json) {
46
+ if (response.statusCode === 200 && typeof response.json === "object" && response.json) {
47
47
  const ok = response.json.ok === true;
48
48
  const version = response.json.version;
49
49
  const uptimeSeconds = response.json.uptimeSeconds;
50
50
  return {
51
51
  ok,
52
52
  statusCode: response.statusCode,
53
- version: typeof version === 'string' ? version : undefined,
54
- uptimeSeconds: typeof uptimeSeconds === 'number' ? uptimeSeconds : undefined,
53
+ version: typeof version === "string" ? version : undefined,
54
+ uptimeSeconds: typeof uptimeSeconds === "number" ? uptimeSeconds : undefined,
55
55
  };
56
56
  }
57
57
  if (response.statusCode === 404) {
58
58
  return {
59
59
  ok: false,
60
60
  statusCode: response.statusCode,
61
- error: 'remote host does not expose /health (upgrade oracle on the host and retry)',
61
+ error: "remote host does not expose /health (upgrade oracle on the host and retry)",
62
62
  };
63
63
  }
64
64
  const error = extractErrorMessage(response.json, response.bodyText) ?? `HTTP ${response.statusCode}`;
@@ -69,9 +69,9 @@ export async function checkRemoteHealth({ host, token, timeoutMs = 5000, }) {
69
69
  }
70
70
  }
71
71
  function extractErrorMessage(json, bodyText) {
72
- if (json && typeof json === 'object') {
72
+ if (json && typeof json === "object") {
73
73
  const err = json.error;
74
- if (typeof err === 'string' && err.trim().length > 0) {
74
+ if (typeof err === "string" && err.trim().length > 0) {
75
75
  return err.trim();
76
76
  }
77
77
  }
@@ -84,15 +84,15 @@ async function requestJson({ hostname, port, path, headers, timeoutMs, }) {
84
84
  hostname,
85
85
  port,
86
86
  path,
87
- method: 'GET',
87
+ method: "GET",
88
88
  headers,
89
89
  }, (res) => {
90
- res.setEncoding('utf8');
91
- let body = '';
92
- res.on('data', (chunk) => {
90
+ res.setEncoding("utf8");
91
+ let body = "";
92
+ res.on("data", (chunk) => {
93
93
  body += chunk;
94
94
  });
95
- res.on('end', () => {
95
+ res.on("end", () => {
96
96
  const statusCode = res.statusCode ?? 0;
97
97
  let json = null;
98
98
  try {
@@ -107,7 +107,7 @@ async function requestJson({ hostname, port, path, headers, timeoutMs, }) {
107
107
  req.setTimeout(timeoutMs, () => {
108
108
  req.destroy(new Error(`timeout after ${timeoutMs}ms`));
109
109
  });
110
- req.on('error', reject);
110
+ req.on("error", reject);
111
111
  req.end();
112
112
  });
113
113
  }
@@ -1,5 +1,5 @@
1
1
  function normalizeString(value) {
2
- if (typeof value !== 'string')
2
+ if (typeof value !== "string")
3
3
  return undefined;
4
4
  const trimmed = value.trim();
5
5
  return trimmed.length ? trimmed : undefined;
@@ -14,18 +14,18 @@ export function resolveRemoteServiceConfig({ cliHost, cliToken, userConfig, env
14
14
  const host = cliHostValue ?? configBrowserHost ?? envHost;
15
15
  const token = cliTokenValue ?? configBrowserToken ?? envToken;
16
16
  const hostSource = cliHostValue
17
- ? 'cli'
17
+ ? "cli"
18
18
  : configBrowserHost
19
- ? 'config.browser'
19
+ ? "config.browser"
20
20
  : envHost
21
- ? 'env'
22
- : 'unset';
21
+ ? "env"
22
+ : "unset";
23
23
  const tokenSource = cliTokenValue
24
- ? 'cli'
24
+ ? "cli"
25
25
  : configBrowserToken
26
- ? 'config.browser'
26
+ ? "config.browser"
27
27
  : envToken
28
- ? 'env'
29
- : 'unset';
28
+ ? "env"
29
+ : "unset";
30
30
  return { host, token, sources: { host: hostSource, token: tokenSource } };
31
31
  }