@steipete/oracle 0.9.0 → 0.11.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 (194) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +107 -49
  3. package/dist/bin/oracle-cli.js +551 -410
  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/archiveConversation.js +224 -0
  18. package/dist/src/browser/actions/assistantResponse.js +175 -101
  19. package/dist/src/browser/actions/attachmentDataTransfer.js +49 -47
  20. package/dist/src/browser/actions/attachments.js +246 -150
  21. package/dist/src/browser/actions/deepResearch.js +662 -0
  22. package/dist/src/browser/actions/domEvents.js +2 -2
  23. package/dist/src/browser/actions/modelSelection.js +342 -119
  24. package/dist/src/browser/actions/navigation.js +183 -137
  25. package/dist/src/browser/actions/projectSources.js +491 -0
  26. package/dist/src/browser/actions/promptComposer.js +152 -91
  27. package/dist/src/browser/actions/remoteFileTransfer.js +10 -10
  28. package/dist/src/browser/actions/thinkingStatus.js +391 -0
  29. package/dist/src/browser/actions/thinkingTime.js +207 -110
  30. package/dist/src/browser/artifacts.js +150 -0
  31. package/dist/src/browser/attachRunning.js +31 -0
  32. package/dist/src/browser/chatgptImages.js +315 -0
  33. package/dist/src/browser/chromeLifecycle.js +276 -63
  34. package/dist/src/browser/config.js +59 -16
  35. package/dist/src/browser/constants.js +25 -12
  36. package/dist/src/browser/controlPlan.js +81 -0
  37. package/dist/src/browser/cookies.js +19 -19
  38. package/dist/src/browser/detect.js +250 -77
  39. package/dist/src/browser/domDebug.js +50 -1
  40. package/dist/src/browser/index.js +1559 -692
  41. package/dist/src/browser/liveTabs.js +434 -0
  42. package/dist/src/browser/modelStrategy.js +1 -1
  43. package/dist/src/browser/pageActions.js +5 -5
  44. package/dist/src/browser/policies.js +16 -13
  45. package/dist/src/browser/profileState.js +127 -42
  46. package/dist/src/browser/projectSourcesRunner.js +366 -0
  47. package/dist/src/browser/prompt.js +72 -42
  48. package/dist/src/browser/promptSummary.js +5 -5
  49. package/dist/src/browser/providerDomFlow.js +1 -1
  50. package/dist/src/browser/providers/chatgptDomProvider.js +9 -9
  51. package/dist/src/browser/providers/geminiDeepThinkDomProvider.js +51 -42
  52. package/dist/src/browser/providers/index.js +2 -2
  53. package/dist/src/browser/reattach.js +178 -73
  54. package/dist/src/browser/reattachHelpers.js +32 -27
  55. package/dist/src/browser/sessionRunner.js +89 -25
  56. package/dist/src/browser/tabLeaseRegistry.js +182 -0
  57. package/dist/src/browser/utils.js +9 -9
  58. package/dist/src/browserMode.js +1 -1
  59. package/dist/src/cli/bridge/claudeConfig.js +24 -20
  60. package/dist/src/cli/bridge/client.js +28 -20
  61. package/dist/src/cli/bridge/codexConfig.js +16 -16
  62. package/dist/src/cli/bridge/doctor.js +47 -39
  63. package/dist/src/cli/bridge/host.js +58 -56
  64. package/dist/src/cli/browserConfig.js +102 -48
  65. package/dist/src/cli/browserDefaults.js +51 -26
  66. package/dist/src/cli/browserTabs.js +228 -0
  67. package/dist/src/cli/bundleWarnings.js +1 -1
  68. package/dist/src/cli/clipboard.js +11 -2
  69. package/dist/src/cli/detach.js +2 -2
  70. package/dist/src/cli/dryRun.js +62 -26
  71. package/dist/src/cli/duplicatePromptGuard.js +12 -4
  72. package/dist/src/cli/engine.js +9 -9
  73. package/dist/src/cli/errorUtils.js +1 -1
  74. package/dist/src/cli/fileSize.js +3 -3
  75. package/dist/src/cli/format.js +2 -2
  76. package/dist/src/cli/help.js +28 -28
  77. package/dist/src/cli/hiddenAliases.js +3 -3
  78. package/dist/src/cli/markdownBundle.js +7 -7
  79. package/dist/src/cli/markdownRenderer.js +15 -15
  80. package/dist/src/cli/notifier.js +77 -67
  81. package/dist/src/cli/options.js +131 -106
  82. package/dist/src/cli/oscUtils.js +1 -1
  83. package/dist/src/cli/projectSources.js +116 -0
  84. package/dist/src/cli/promptRequirement.js +2 -2
  85. package/dist/src/cli/renderOutput.js +1 -1
  86. package/dist/src/cli/rootAlias.js +1 -1
  87. package/dist/src/cli/runOptions.js +32 -28
  88. package/dist/src/cli/sessionCommand.js +82 -21
  89. package/dist/src/cli/sessionDisplay.js +213 -87
  90. package/dist/src/cli/sessionLineage.js +6 -2
  91. package/dist/src/cli/sessionRunner.js +149 -95
  92. package/dist/src/cli/sessionTable.js +26 -23
  93. package/dist/src/cli/stdin.js +22 -0
  94. package/dist/src/cli/tagline.js +121 -124
  95. package/dist/src/cli/tui/index.js +139 -128
  96. package/dist/src/cli/writeOutputPath.js +5 -5
  97. package/dist/src/config.js +7 -7
  98. package/dist/src/gemini-web/browserSessionManager.js +19 -15
  99. package/dist/src/gemini-web/client.js +76 -70
  100. package/dist/src/gemini-web/executionMode.js +6 -8
  101. package/dist/src/gemini-web/executor.js +98 -93
  102. package/dist/src/gemini-web/index.js +1 -1
  103. package/dist/src/mcp/consultPresets.js +19 -0
  104. package/dist/src/mcp/server.js +18 -12
  105. package/dist/src/mcp/tools/consult.js +246 -67
  106. package/dist/src/mcp/tools/projectSources.js +123 -0
  107. package/dist/src/mcp/tools/sessionResources.js +12 -12
  108. package/dist/src/mcp/tools/sessions.js +26 -17
  109. package/dist/src/mcp/types.js +12 -5
  110. package/dist/src/mcp/utils.js +21 -8
  111. package/dist/src/oracle/background.js +15 -15
  112. package/dist/src/oracle/claude.js +53 -25
  113. package/dist/src/oracle/client.js +50 -41
  114. package/dist/src/oracle/config.js +96 -66
  115. package/dist/src/oracle/errors.js +38 -38
  116. package/dist/src/oracle/files.js +55 -46
  117. package/dist/src/oracle/finishLine.js +10 -8
  118. package/dist/src/oracle/format.js +3 -3
  119. package/dist/src/oracle/gemini.js +37 -33
  120. package/dist/src/oracle/logging.js +7 -7
  121. package/dist/src/oracle/markdown.js +28 -28
  122. package/dist/src/oracle/modelResolver.js +16 -16
  123. package/dist/src/oracle/multiModelRunner.js +12 -12
  124. package/dist/src/oracle/oscProgress.js +8 -8
  125. package/dist/src/oracle/promptAssembly.js +6 -3
  126. package/dist/src/oracle/request.js +16 -13
  127. package/dist/src/oracle/run.js +160 -135
  128. package/dist/src/oracle/runUtils.js +8 -5
  129. package/dist/src/oracle/tokenEstimate.js +6 -6
  130. package/dist/src/oracle/tokenStats.js +5 -5
  131. package/dist/src/oracle/tokenStringifier.js +5 -5
  132. package/dist/src/oracle.js +12 -12
  133. package/dist/src/oracleHome.js +3 -3
  134. package/dist/src/projectSources/plan.js +27 -0
  135. package/dist/src/projectSources/url.js +23 -0
  136. package/dist/src/remote/client.js +25 -25
  137. package/dist/src/remote/health.js +20 -20
  138. package/dist/src/remote/remoteServiceConfig.js +9 -9
  139. package/dist/src/remote/server.js +129 -118
  140. package/dist/src/sessionManager.js +78 -75
  141. package/dist/src/sessionStore.js +3 -3
  142. package/dist/src/version.js +10 -10
  143. package/dist/vendor/oracle-notifier/README.md +2 -0
  144. package/package.json +67 -62
  145. package/vendor/oracle-notifier/README.md +2 -0
  146. package/dist/markdansi/types/index.js +0 -4
  147. package/dist/oracle/bin/oracle-cli.js +0 -472
  148. package/dist/oracle/src/browser/actions/assistantResponse.js +0 -471
  149. package/dist/oracle/src/browser/actions/attachments.js +0 -82
  150. package/dist/oracle/src/browser/actions/modelSelection.js +0 -190
  151. package/dist/oracle/src/browser/actions/navigation.js +0 -75
  152. package/dist/oracle/src/browser/actions/promptComposer.js +0 -167
  153. package/dist/oracle/src/browser/chromeLifecycle.js +0 -104
  154. package/dist/oracle/src/browser/config.js +0 -33
  155. package/dist/oracle/src/browser/constants.js +0 -40
  156. package/dist/oracle/src/browser/cookies.js +0 -210
  157. package/dist/oracle/src/browser/domDebug.js +0 -36
  158. package/dist/oracle/src/browser/index.js +0 -331
  159. package/dist/oracle/src/browser/pageActions.js +0 -5
  160. package/dist/oracle/src/browser/prompt.js +0 -88
  161. package/dist/oracle/src/browser/promptSummary.js +0 -20
  162. package/dist/oracle/src/browser/sessionRunner.js +0 -80
  163. package/dist/oracle/src/browser/utils.js +0 -62
  164. package/dist/oracle/src/browserMode.js +0 -1
  165. package/dist/oracle/src/cli/browserConfig.js +0 -44
  166. package/dist/oracle/src/cli/dryRun.js +0 -59
  167. package/dist/oracle/src/cli/engine.js +0 -17
  168. package/dist/oracle/src/cli/errorUtils.js +0 -9
  169. package/dist/oracle/src/cli/help.js +0 -70
  170. package/dist/oracle/src/cli/markdownRenderer.js +0 -15
  171. package/dist/oracle/src/cli/options.js +0 -103
  172. package/dist/oracle/src/cli/promptRequirement.js +0 -14
  173. package/dist/oracle/src/cli/rootAlias.js +0 -30
  174. package/dist/oracle/src/cli/sessionCommand.js +0 -77
  175. package/dist/oracle/src/cli/sessionDisplay.js +0 -270
  176. package/dist/oracle/src/cli/sessionRunner.js +0 -94
  177. package/dist/oracle/src/heartbeat.js +0 -43
  178. package/dist/oracle/src/oracle/client.js +0 -48
  179. package/dist/oracle/src/oracle/config.js +0 -29
  180. package/dist/oracle/src/oracle/errors.js +0 -101
  181. package/dist/oracle/src/oracle/files.js +0 -220
  182. package/dist/oracle/src/oracle/format.js +0 -33
  183. package/dist/oracle/src/oracle/fsAdapter.js +0 -7
  184. package/dist/oracle/src/oracle/oscProgress.js +0 -60
  185. package/dist/oracle/src/oracle/request.js +0 -48
  186. package/dist/oracle/src/oracle/run.js +0 -444
  187. package/dist/oracle/src/oracle/tokenStats.js +0 -39
  188. package/dist/oracle/src/oracle/types.js +0 -1
  189. package/dist/oracle/src/oracle.js +0 -9
  190. package/dist/oracle/src/sessionManager.js +0 -205
  191. package/dist/oracle/src/version.js +0 -39
  192. package/dist/scripts/chrome/browser-tools.js +0 -295
  193. package/dist/src/browser/profileSync.js +0 -141
  194. /package/dist/{oracle/src/browser → src/projectSources}/types.js +0 -0
@@ -1,11 +1,11 @@
1
- import os from 'node:os';
2
- import chalk from 'chalk';
3
- import { getCliVersion } from '../../version.js';
4
- import { loadUserConfig } from '../../config.js';
5
- import { resolveRemoteServiceConfig } from '../../remote/remoteServiceConfig.js';
6
- import { checkTcpConnection, checkRemoteHealth } from '../../remote/health.js';
7
- import { detectChromeBinary, detectChromeCookieDb } from '../../browser/detect.js';
8
- import { formatCodexMcpSnippet } from './codexConfig.js';
1
+ import os from "node:os";
2
+ import chalk from "chalk";
3
+ import { getCliVersion } from "../../version.js";
4
+ import { loadUserConfig } from "../../config.js";
5
+ import { resolveRemoteServiceConfig } from "../../remote/remoteServiceConfig.js";
6
+ import { checkTcpConnection, checkRemoteHealth } from "../../remote/health.js";
7
+ import { detectChromeBinary, detectChromeCookieDb } from "../../browser/detect.js";
8
+ import { formatCodexMcpSnippet } from "./codexConfig.js";
9
9
  export async function runBridgeDoctor(_options) {
10
10
  const { config: userConfig, path: configPath, loaded } = await loadUserConfig();
11
11
  const version = getCliVersion();
@@ -18,90 +18,98 @@ export async function runBridgeDoctor(_options) {
18
18
  const lines = [];
19
19
  const fail = [];
20
20
  const warn = [];
21
- lines.push(chalk.bold('Bridge doctor'));
21
+ lines.push(chalk.bold("Bridge doctor"));
22
22
  lines.push(chalk.dim(`OS: ${process.platform} ${os.release()} (${process.arch})`));
23
23
  lines.push(chalk.dim(`Node: ${process.version}`));
24
24
  lines.push(chalk.dim(`Oracle: ${version}`));
25
- lines.push(chalk.dim(`Config: ${loaded ? configPath : '(missing)'}`));
25
+ lines.push(chalk.dim(`Config: ${loaded ? configPath : "(missing)"}`));
26
26
  if (userConfig.engine) {
27
27
  lines.push(chalk.dim(`Default engine: ${userConfig.engine}`));
28
28
  }
29
29
  if (userConfig.model) {
30
30
  lines.push(chalk.dim(`Default model: ${userConfig.model}`));
31
31
  }
32
- lines.push('');
33
- lines.push(chalk.bold('Browser mode'));
32
+ lines.push("");
33
+ lines.push(chalk.bold("Browser mode"));
34
34
  if (resolvedRemote.host) {
35
- lines.push(`Remote service: ${chalk.green('configured')}`);
35
+ lines.push(`Remote service: ${chalk.green("configured")}`);
36
36
  lines.push(chalk.dim(`remoteHost: ${resolvedRemote.host} (${resolvedRemote.sources.host})`));
37
- lines.push(chalk.dim(`remoteToken: ${resolvedRemote.token ? 'set' : 'missing'} (${resolvedRemote.sources.token})`));
37
+ lines.push(chalk.dim(`remoteToken: ${resolvedRemote.token ? "set" : "missing"} (${resolvedRemote.sources.token})`));
38
38
  const tcp = await checkTcpConnection(resolvedRemote.host, 2000);
39
39
  if (tcp.ok) {
40
- lines.push(chalk.dim(`TCP connect: ${chalk.green('ok')}`));
40
+ lines.push(chalk.dim(`TCP connect: ${chalk.green("ok")}`));
41
41
  }
42
42
  else {
43
- fail.push(`Cannot reach ${resolvedRemote.host} (${tcp.error ?? 'unknown error'}).`);
44
- lines.push(chalk.dim(`TCP connect: ${chalk.red(`failed (${tcp.error ?? 'unknown error'})`)}`));
43
+ fail.push(`Cannot reach ${resolvedRemote.host} (${tcp.error ?? "unknown error"}).`);
44
+ lines.push(chalk.dim(`TCP connect: ${chalk.red(`failed (${tcp.error ?? "unknown error"})`)}`));
45
45
  }
46
46
  if (!resolvedRemote.token) {
47
- fail.push('Remote token is missing. Run `oracle bridge client --connect <...> --write-config` or set ORACLE_REMOTE_TOKEN.');
47
+ fail.push("Remote token is missing. Run `oracle bridge client --connect <...> --write-config` or set ORACLE_REMOTE_TOKEN.");
48
48
  }
49
49
  else if (tcp.ok) {
50
- const health = await checkRemoteHealth({ host: resolvedRemote.host, token: resolvedRemote.token, timeoutMs: 5000 });
50
+ const health = await checkRemoteHealth({
51
+ host: resolvedRemote.host,
52
+ token: resolvedRemote.token,
53
+ timeoutMs: 5000,
54
+ });
51
55
  if (health.ok) {
52
- const meta = health.version ? `oracle ${health.version}` : 'ok';
56
+ const meta = health.version ? `oracle ${health.version}` : "ok";
53
57
  lines.push(chalk.dim(`Auth (/health): ${chalk.green(meta)}`));
54
58
  }
55
59
  else {
56
- const detail = health.error ?? 'unknown error';
60
+ const detail = health.error ?? "unknown error";
57
61
  fail.push(`Remote auth failed: ${detail}`);
58
- const suffix = health.statusCode ? `HTTP ${health.statusCode}` : 'network';
62
+ const suffix = health.statusCode ? `HTTP ${health.statusCode}` : "network";
59
63
  lines.push(chalk.dim(`Auth (/health): ${chalk.red(`${suffix} (${detail})`)}`));
60
64
  }
61
65
  }
62
66
  }
63
67
  else {
64
- lines.push(`Remote service: ${chalk.yellow('not configured')}`);
68
+ lines.push(`Remote service: ${chalk.yellow("not configured")}`);
65
69
  const chrome = await detectChromeBinary();
66
70
  if (chrome.path) {
67
71
  lines.push(chalk.dim(`Chrome: ${chalk.green(chrome.path)}`));
68
72
  }
69
73
  else {
70
- fail.push('No Chrome installation detected. Install Chrome/Chromium or set --browser-chrome-path.');
71
- lines.push(chalk.dim(`Chrome: ${chalk.red('not found')}`));
74
+ fail.push("No Chrome installation detected. Install Chrome/Chromium or set --browser-chrome-path.");
75
+ lines.push(chalk.dim(`Chrome: ${chalk.red("not found")}`));
72
76
  }
73
- if (process.platform === 'win32') {
74
- warn.push('Cookie sync is disabled on Windows; use --browser-manual-login or run browser automation on another host.');
75
- lines.push(chalk.dim('Cookies: (cookie sync disabled on Windows)'));
77
+ if (process.platform === "win32") {
78
+ warn.push("Cookie sync is disabled on Windows; use --browser-manual-login or run browser automation on another host.");
79
+ lines.push(chalk.dim("Cookies: (cookie sync disabled on Windows)"));
76
80
  }
77
81
  else {
78
- const cookieDb = await detectChromeCookieDb({ profile: 'Default' });
82
+ const cookieDb = await detectChromeCookieDb({ profile: "Default" });
79
83
  if (cookieDb) {
80
84
  lines.push(chalk.dim(`Cookies DB: ${chalk.green(cookieDb)}`));
81
85
  }
82
86
  else {
83
- warn.push('Chrome cookies DB not detected. You may need --browser-cookie-path or --browser-manual-login.');
84
- lines.push(chalk.dim(`Cookies DB: ${chalk.yellow('not found')}`));
87
+ warn.push("Chrome cookies DB not detected. You may need --browser-cookie-path or --browser-manual-login.");
88
+ lines.push(chalk.dim(`Cookies DB: ${chalk.yellow("not found")}`));
85
89
  }
86
90
  }
87
91
  }
88
- lines.push('');
89
- lines.push(chalk.bold('Codex MCP'));
90
- lines.push(formatCodexMcpSnippet({ remoteHost: resolvedRemote.host, remoteToken: resolvedRemote.token, includeToken: false }));
92
+ lines.push("");
93
+ lines.push(chalk.bold("Codex MCP"));
94
+ lines.push(formatCodexMcpSnippet({
95
+ remoteHost: resolvedRemote.host,
96
+ remoteToken: resolvedRemote.token,
97
+ includeToken: false,
98
+ }));
91
99
  if (warn.length) {
92
- lines.push('');
93
- lines.push(chalk.yellowBright('Warnings:'));
100
+ lines.push("");
101
+ lines.push(chalk.yellowBright("Warnings:"));
94
102
  for (const message of warn) {
95
103
  lines.push(chalk.yellow(`- ${message}`));
96
104
  }
97
105
  }
98
106
  if (fail.length) {
99
- lines.push('');
100
- lines.push(chalk.redBright('Problems:'));
107
+ lines.push("");
108
+ lines.push(chalk.redBright("Problems:"));
101
109
  for (const message of fail) {
102
110
  lines.push(chalk.red(`- ${message}`));
103
111
  }
104
112
  }
105
- console.log(lines.join('\n'));
113
+ console.log(lines.join("\n"));
106
114
  process.exitCode = fail.length ? 1 : 0;
107
115
  }
@@ -1,26 +1,28 @@
1
- import { spawn } from 'node:child_process';
2
- import fs from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { randomBytes } from 'node:crypto';
5
- import chalk from 'chalk';
6
- import { getOracleHomeDir } from '../../oracleHome.js';
7
- import { parseHostPort, normalizeHostPort, formatBridgeConnectionString } from '../../bridge/connection.js';
8
- import { serveRemote } from '../../remote/server.js';
1
+ import { spawn } from "node:child_process";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { randomBytes } from "node:crypto";
5
+ import chalk from "chalk";
6
+ import { getOracleHomeDir } from "../../oracleHome.js";
7
+ import { parseHostPort, normalizeHostPort, formatBridgeConnectionString, } from "../../bridge/connection.js";
8
+ import { serveRemote } from "../../remote/server.js";
9
9
  export async function runBridgeHost(options) {
10
- const bindRaw = options.bind?.trim() || '127.0.0.1:9473';
10
+ const bindRaw = options.bind?.trim() || "127.0.0.1:9473";
11
11
  const { hostname: bindHost, port: bindPort } = parseHostPort(bindRaw);
12
- const tokenRaw = options.token?.trim() || 'auto';
13
- const token = tokenRaw === 'auto' ? randomBytes(16).toString('hex') : tokenRaw;
12
+ const tokenRaw = options.token?.trim() || "auto";
13
+ const token = tokenRaw === "auto" ? randomBytes(16).toString("hex") : tokenRaw;
14
14
  if (!token.trim()) {
15
- throw new Error('Token is required (use --token auto to generate one).');
15
+ throw new Error("Token is required (use --token auto to generate one).");
16
16
  }
17
- const writeConnectionPath = options.writeConnection?.trim() || path.join(getOracleHomeDir(), 'bridge-connection.json');
17
+ const writeConnectionPath = options.writeConnection?.trim() || path.join(getOracleHomeDir(), "bridge-connection.json");
18
18
  const sshTarget = options.ssh?.trim();
19
- const sshRemotePort = typeof options.sshRemotePort === 'number' ? options.sshRemotePort : bindPort;
19
+ const sshRemotePort = typeof options.sshRemotePort === "number" ? options.sshRemotePort : bindPort;
20
20
  if (sshRemotePort <= 0 || sshRemotePort > 65_535) {
21
21
  throw new Error(`Invalid --ssh-remote-port: ${sshRemotePort}. Expected 1-65535.`);
22
22
  }
23
- const connectionHostForClient = sshTarget ? normalizeHostPort('127.0.0.1', sshRemotePort) : normalizeHostPort(bindHost === '0.0.0.0' || bindHost === '::' ? '127.0.0.1' : bindHost, bindPort);
23
+ const connectionHostForClient = sshTarget
24
+ ? normalizeHostPort("127.0.0.1", sshRemotePort)
25
+ : normalizeHostPort(bindHost === "0.0.0.0" || bindHost === "::" ? "127.0.0.1" : bindHost, bindPort);
24
26
  const artifact = await upsertConnectionArtifact(writeConnectionPath, {
25
27
  remoteHost: connectionHostForClient,
26
28
  remoteToken: token,
@@ -52,11 +54,11 @@ export async function runBridgeHost(options) {
52
54
  });
53
55
  return;
54
56
  }
55
- console.log(chalk.cyanBright('Bridge host starting...'));
57
+ console.log(chalk.cyanBright("Bridge host starting..."));
56
58
  console.log(chalk.dim(`- Local bind: ${normalizeHostPort(bindHost, bindPort)}`));
57
59
  console.log(chalk.dim(`- Connection artifact: ${writeConnectionPath}`));
58
60
  console.log(chalk.dim(`- Client remoteHost: ${artifact.remoteHost}`));
59
- console.log(chalk.dim('Token stored in connection artifact (not printed). Use --print or --print-token if needed.'));
61
+ console.log(chalk.dim("Token stored in connection artifact (not printed). Use --print or --print-token if needed."));
60
62
  let tunnel = null;
61
63
  if (sshTarget) {
62
64
  tunnel = startReverseTunnel({
@@ -70,7 +72,7 @@ export async function runBridgeHost(options) {
70
72
  console.log(chalk.dim(`Reverse SSH tunnel active (remote 127.0.0.1:${sshRemotePort} -> local 127.0.0.1:${bindPort})`));
71
73
  }
72
74
  const filteredServeLogger = (message) => {
73
- if (message.includes('Access token:')) {
75
+ if (message.includes("Access token:")) {
74
76
  return;
75
77
  }
76
78
  console.log(message);
@@ -91,12 +93,12 @@ async function upsertConnectionArtifact(filePath, input) {
91
93
  const dir = path.dirname(filePath);
92
94
  await fs.mkdir(dir, { recursive: true, mode: 0o700 });
93
95
  const now = new Date().toISOString();
94
- const existing = await fs.readFile(filePath, 'utf8').catch(() => null);
96
+ const existing = await fs.readFile(filePath, "utf8").catch(() => null);
95
97
  let createdAt = now;
96
98
  if (existing) {
97
99
  try {
98
100
  const parsed = JSON.parse(existing);
99
- if (typeof parsed.createdAt === 'string' && parsed.createdAt.trim().length > 0) {
101
+ if (typeof parsed.createdAt === "string" && parsed.createdAt.trim().length > 0) {
100
102
  createdAt = parsed.createdAt;
101
103
  }
102
104
  }
@@ -113,9 +115,9 @@ async function upsertConnectionArtifact(filePath, input) {
113
115
  };
114
116
  const contents = `${JSON.stringify(artifact, null, 2)}\n`;
115
117
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
116
- await fs.writeFile(tempPath, contents, { encoding: 'utf8', mode: 0o600 });
118
+ await fs.writeFile(tempPath, contents, { encoding: "utf8", mode: 0o600 });
117
119
  await fs.rename(tempPath, filePath);
118
- if (process.platform !== 'win32') {
120
+ if (process.platform !== "win32") {
119
121
  await fs.chmod(filePath, 0o600).catch(() => undefined);
120
122
  }
121
123
  return artifact;
@@ -129,27 +131,27 @@ function startReverseTunnel({ sshTarget, remotePort, localPort, identity, extraA
129
131
  if (stopped)
130
132
  return;
131
133
  const args = [
132
- '-N',
133
- '-R',
134
+ "-N",
135
+ "-R",
134
136
  `${remotePort}:127.0.0.1:${localPort}`,
135
- '-o',
136
- 'ExitOnForwardFailure=yes',
137
- '-o',
138
- 'ServerAliveInterval=30',
139
- '-o',
140
- 'ServerAliveCountMax=3',
137
+ "-o",
138
+ "ExitOnForwardFailure=yes",
139
+ "-o",
140
+ "ServerAliveInterval=30",
141
+ "-o",
142
+ "ServerAliveCountMax=3",
141
143
  ];
142
144
  if (identity) {
143
- args.push('-i', identity);
145
+ args.push("-i", identity);
144
146
  }
145
147
  if (extraArgs) {
146
148
  args.push(...splitArgs(extraArgs));
147
149
  }
148
150
  args.push(sshTarget);
149
- child = spawn('ssh', args, { stdio: 'ignore' });
151
+ child = spawn("ssh", args, { stdio: "ignore" });
150
152
  const pid = child.pid;
151
- log(`[bridge host] ssh tunnel started${pid ? ` (pid ${pid})` : ''}: ${sshTarget}`);
152
- child.once('exit', (code, signal) => {
153
+ log(`[bridge host] ssh tunnel started${pid ? ` (pid ${pid})` : ""}: ${sshTarget}`);
154
+ child.once("exit", (code, signal) => {
153
155
  child = null;
154
156
  if (stopped)
155
157
  return;
@@ -179,16 +181,16 @@ function startReverseTunnel({ sshTarget, remotePort, localPort, identity, extraA
179
181
  }
180
182
  function splitArgs(input) {
181
183
  const args = [];
182
- let current = '';
184
+ let current = "";
183
185
  let quote = null;
184
186
  const push = () => {
185
187
  const trimmed = current.trim();
186
188
  if (trimmed.length)
187
189
  args.push(trimmed);
188
- current = '';
190
+ current = "";
189
191
  };
190
192
  for (let i = 0; i < input.length; i += 1) {
191
- const ch = input[i] ?? '';
193
+ const ch = input[i] ?? "";
192
194
  if (quote) {
193
195
  if (ch === quote) {
194
196
  quote = null;
@@ -214,46 +216,46 @@ function splitArgs(input) {
214
216
  async function spawnBridgeHostInBackground({ bind, token, writeConnectionPath, sshTarget, sshRemotePort, sshIdentity, sshExtraArgs, }) {
215
217
  const oracleHome = getOracleHomeDir();
216
218
  await fs.mkdir(oracleHome, { recursive: true, mode: 0o700 });
217
- const logPath = path.join(oracleHome, 'bridge-host.log');
218
- const pidPath = path.join(oracleHome, 'bridge-host.pid');
219
- const logHandle = await fs.open(logPath, 'a');
220
- const stdio = ['ignore', logHandle.fd, logHandle.fd];
219
+ const logPath = path.join(oracleHome, "bridge-host.log");
220
+ const pidPath = path.join(oracleHome, "bridge-host.pid");
221
+ const logHandle = await fs.open(logPath, "a");
222
+ const stdio = ["ignore", logHandle.fd, logHandle.fd];
221
223
  const scriptPath = process.argv[1];
222
224
  if (!scriptPath) {
223
- throw new Error('Unable to determine CLI entrypoint for background mode.');
225
+ throw new Error("Unable to determine CLI entrypoint for background mode.");
224
226
  }
225
227
  const args = [
226
228
  scriptPath,
227
- 'bridge',
228
- 'host',
229
- '--foreground',
230
- '--bind',
229
+ "bridge",
230
+ "host",
231
+ "--foreground",
232
+ "--bind",
231
233
  bind,
232
- '--token',
234
+ "--token",
233
235
  token,
234
- '--write-connection',
236
+ "--write-connection",
235
237
  writeConnectionPath,
236
238
  ];
237
239
  if (sshTarget) {
238
- args.push('--ssh', sshTarget);
240
+ args.push("--ssh", sshTarget);
239
241
  }
240
- if (typeof sshRemotePort === 'number') {
241
- args.push('--ssh-remote-port', String(sshRemotePort));
242
+ if (typeof sshRemotePort === "number") {
243
+ args.push("--ssh-remote-port", String(sshRemotePort));
242
244
  }
243
245
  if (sshIdentity) {
244
- args.push('--ssh-identity', sshIdentity);
246
+ args.push("--ssh-identity", sshIdentity);
245
247
  }
246
248
  if (sshExtraArgs) {
247
- args.push('--ssh-extra-args', sshExtraArgs);
249
+ args.push("--ssh-extra-args", sshExtraArgs);
248
250
  }
249
251
  const child = spawn(process.execPath, args, { detached: true, stdio });
250
252
  child.unref();
251
- await fs.writeFile(pidPath, `${child.pid ?? ''}\n`, { encoding: 'utf8', mode: 0o600 });
252
- if (process.platform !== 'win32') {
253
+ await fs.writeFile(pidPath, `${child.pid ?? ""}\n`, { encoding: "utf8", mode: 0o600 });
254
+ if (process.platform !== "win32") {
253
255
  await fs.chmod(pidPath, 0o600).catch(() => undefined);
254
256
  }
255
257
  await logHandle.close();
256
- console.log(chalk.green(`Bridge host running in background (pid ${child.pid ?? '?'})`));
258
+ console.log(chalk.green(`Bridge host running in background (pid ${child.pid ?? "?"})`));
257
259
  console.log(chalk.dim(`- Log: ${logPath}`));
258
260
  console.log(chalk.dim(`- PID: ${pidPath}`));
259
261
  }