oh-my-opencode 5.0.0-beta.80 → 5.0.0-beta.81
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/dist/cli/index.js +6830 -3346
- package/dist/cli-node/index.js +6830 -3346
- package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +1 -1
- package/dist/index.js +4304 -1671
- package/dist/oh-my-opencode.schema.json +3 -7
- package/dist/skills/frontend/SKILL.md +1 -0
- package/dist/skills/frontend/references/design/README.md +3 -2
- package/dist/skills/frontend/references/design/design-system-architecture.md +1 -0
- package/dist/skills/frontend/references/perfection/README.md +1 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/tui.js +2546 -1338
- package/package.json +31 -29
- package/packages/lsp-daemon/dist/cli.js +591 -555
- package/packages/lsp-daemon/dist/client.js +34 -5
- package/packages/lsp-daemon/dist/daemon-client.d.ts +2 -0
- package/packages/lsp-daemon/dist/daemon-client.js +20 -3
- package/packages/lsp-daemon/dist/ensure-daemon.js +17 -3
- package/packages/lsp-daemon/dist/index.js +34 -5
- package/packages/lsp-daemon/package.json +4 -3
- package/packages/lsp-tools-mcp/package.json +4 -3
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2537 -1310
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -4
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -4
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +34 -5
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +5 -4
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +5 -4
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +4 -3
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +4944 -2767
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +4944 -2767
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +5 -4
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -4
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +5 -4
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -4
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +481 -322
- package/packages/omo-codex/plugin/package.json +5 -1
- package/packages/omo-codex/plugin/shared/package.json +1 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +3 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +1 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +7594 -4136
- package/packages/shared-skills/skills/frontend/SKILL.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/README.md +3 -2
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +1 -0
- package/packages/shared-skills/skills/frontend/references/perfection/README.md +1 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
|
@@ -6,6 +6,7 @@ import { isAbsolute as isAbsolute6 } from "node:path";
|
|
|
6
6
|
import { connect } from "node:net";
|
|
7
7
|
import { homedir as homedir3 } from "node:os";
|
|
8
8
|
import { join as join8 } from "node:path";
|
|
9
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
9
10
|
|
|
10
11
|
// ../lsp-core/src/request-context.ts
|
|
11
12
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -645,9 +646,11 @@ function createLineDecoder(onMessage, onParseError) {
|
|
|
645
646
|
}
|
|
646
647
|
|
|
647
648
|
// src/ensure-daemon.ts
|
|
648
|
-
var PROBE_TIMEOUT_MS =
|
|
649
|
+
var PROBE_TIMEOUT_MS = 2000;
|
|
649
650
|
var DEFAULT_READY_TIMEOUT_MS = 5000;
|
|
650
651
|
var DEFAULT_POLL_INTERVAL_MS = 100;
|
|
652
|
+
var FAILED_SPAWN_COOLDOWN_MS = 5000;
|
|
653
|
+
var failedSpawnUntil = new Map;
|
|
651
654
|
|
|
652
655
|
class DaemonUnreachableError extends Error {
|
|
653
656
|
constructor(socketPath) {
|
|
@@ -660,11 +663,22 @@ async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), opti
|
|
|
660
663
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
661
664
|
const signal = options.signal;
|
|
662
665
|
throwIfAborted(signal);
|
|
663
|
-
if (await awaitWithSignal(deps.probe(paths, signal), signal))
|
|
666
|
+
if (await awaitWithSignal(deps.probe(paths, signal), signal)) {
|
|
667
|
+
failedSpawnUntil.delete(paths.socket);
|
|
664
668
|
return;
|
|
669
|
+
}
|
|
665
670
|
throwIfAborted(signal);
|
|
671
|
+
const retryAt = failedSpawnUntil.get(paths.socket);
|
|
672
|
+
if (retryAt !== undefined && deps.now() < retryAt)
|
|
673
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
674
|
+
failedSpawnUntil.delete(paths.socket);
|
|
666
675
|
deps.spawnDaemon(paths);
|
|
667
|
-
|
|
676
|
+
try {
|
|
677
|
+
await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
|
|
680
|
+
throw error;
|
|
681
|
+
}
|
|
668
682
|
}
|
|
669
683
|
async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
|
|
670
684
|
const deadline = deps.now() + readyTimeoutMs;
|
|
@@ -6332,6 +6346,7 @@ function parseContext(value) {
|
|
|
6332
6346
|
|
|
6333
6347
|
// src/daemon-client.ts
|
|
6334
6348
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
6349
|
+
var STARTUP_BACKOFF_MS = [0, 100, 300];
|
|
6335
6350
|
var nextProxyRequestId = 1;
|
|
6336
6351
|
async function callToolViaDaemon(name, args, options) {
|
|
6337
6352
|
const context = requireContext(options.context);
|
|
@@ -6339,17 +6354,31 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
6339
6354
|
const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
|
|
6340
6355
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
6341
6356
|
const requestArgs = withContext(args, context);
|
|
6357
|
+
const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
|
|
6358
|
+
const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
|
|
6342
6359
|
let lastError;
|
|
6343
6360
|
let authRefreshUsed = false;
|
|
6344
|
-
for (
|
|
6361
|
+
for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
|
|
6345
6362
|
try {
|
|
6346
|
-
|
|
6363
|
+
if (backoffMs > 0)
|
|
6364
|
+
await sleep(backoffMs, options.signal);
|
|
6365
|
+
if (options.signal?.aborted)
|
|
6366
|
+
throw new DaemonRequestCancelledError(false);
|
|
6367
|
+
if (attempt === 0) {
|
|
6368
|
+
await ensureDaemonAvailable(paths, ensure, options.signal);
|
|
6369
|
+
} else if (!await probe(paths, options.signal)) {
|
|
6370
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
6371
|
+
}
|
|
6347
6372
|
const token = readAuthToken(paths);
|
|
6348
6373
|
if (!token)
|
|
6349
6374
|
throw new DaemonRequestError("daemon auth token missing", false);
|
|
6350
6375
|
const sendOptions = options.signal === undefined ? { timeoutMs } : { timeoutMs, signal: options.signal };
|
|
6351
6376
|
return await sendToolCall(paths, token, name, requestArgs, sendOptions);
|
|
6352
6377
|
} catch (error) {
|
|
6378
|
+
if (options.signal?.aborted) {
|
|
6379
|
+
lastError = new DaemonRequestCancelledError(false);
|
|
6380
|
+
break;
|
|
6381
|
+
}
|
|
6353
6382
|
lastError = error;
|
|
6354
6383
|
if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
|
|
6355
6384
|
authRefreshUsed = true;
|
|
@@ -8,6 +8,8 @@ export interface CallToolOptions {
|
|
|
8
8
|
requestTimeoutMs?: number;
|
|
9
9
|
signal?: AbortSignal;
|
|
10
10
|
ensure?: (paths: DaemonPaths, signal?: AbortSignal) => Promise<void>;
|
|
11
|
+
probe?: (paths: DaemonPaths, signal?: AbortSignal) => Promise<boolean>;
|
|
12
|
+
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
11
13
|
}
|
|
12
14
|
export declare function callToolViaDaemon(name: string, args: Record<string, unknown>, options: CallToolOptions): Promise<ToolExecutionResult>;
|
|
13
15
|
export declare function callDiagnosticsViaDaemon(filePath: string, options: CallToolOptions): Promise<ToolExecutionResult>;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { connect } from "node:net";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
4
5
|
import { parseLspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
|
|
5
6
|
import { isPlainRecord } from "@oh-my-opencode/mcp-stdio-core/record";
|
|
6
7
|
import { daemonFailureResult } from "./daemon-failure-result.js";
|
|
7
8
|
import { DaemonAuthenticationRejectedError, DaemonRequestCancelledError, DaemonRequestError, DaemonRequestTimedOutError, } from "./daemon-request-error.js";
|
|
8
|
-
import { ensureDaemonRunning } from "./ensure-daemon.js";
|
|
9
|
+
import { DaemonUnreachableError, ensureDaemonRunning, probeDaemon } from "./ensure-daemon.js";
|
|
9
10
|
import { authEnvelope, isAuthErrorResponse, readAuthToken } from "./ipc-protocol.js";
|
|
10
11
|
import { daemonPaths } from "./paths.js";
|
|
11
12
|
import { CONTEXT_KEY } from "./request-routing.js";
|
|
12
13
|
import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
|
|
13
14
|
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
15
|
+
const STARTUP_BACKOFF_MS = [0, 100, 300];
|
|
14
16
|
let nextProxyRequestId = 1;
|
|
15
17
|
export async function callToolViaDaemon(name, args, options) {
|
|
16
18
|
const context = requireContext(options.context);
|
|
@@ -19,11 +21,22 @@ export async function callToolViaDaemon(name, args, options) {
|
|
|
19
21
|
((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
|
|
20
22
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
21
23
|
const requestArgs = withContext(args, context);
|
|
24
|
+
const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
|
|
25
|
+
const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
|
|
22
26
|
let lastError;
|
|
23
27
|
let authRefreshUsed = false;
|
|
24
|
-
for (
|
|
28
|
+
for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
|
|
25
29
|
try {
|
|
26
|
-
|
|
30
|
+
if (backoffMs > 0)
|
|
31
|
+
await sleep(backoffMs, options.signal);
|
|
32
|
+
if (options.signal?.aborted)
|
|
33
|
+
throw new DaemonRequestCancelledError(false);
|
|
34
|
+
if (attempt === 0) {
|
|
35
|
+
await ensureDaemonAvailable(paths, ensure, options.signal);
|
|
36
|
+
}
|
|
37
|
+
else if (!(await probe(paths, options.signal))) {
|
|
38
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
39
|
+
}
|
|
27
40
|
const token = readAuthToken(paths);
|
|
28
41
|
if (!token)
|
|
29
42
|
throw new DaemonRequestError("daemon auth token missing", false);
|
|
@@ -31,6 +44,10 @@ export async function callToolViaDaemon(name, args, options) {
|
|
|
31
44
|
return await sendToolCall(paths, token, name, requestArgs, sendOptions);
|
|
32
45
|
}
|
|
33
46
|
catch (error) {
|
|
47
|
+
if (options.signal?.aborted) {
|
|
48
|
+
lastError = new DaemonRequestCancelledError(false);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
34
51
|
lastError = error;
|
|
35
52
|
if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
|
|
36
53
|
authRefreshUsed = true;
|
|
@@ -8,9 +8,11 @@ import { packagedRuntimeDefaults } from "./paths.js";
|
|
|
8
8
|
import { resolveDaemonRuntime } from "./runtime-contract.js";
|
|
9
9
|
import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
|
|
10
10
|
export { InvalidRuntimeOverrideError, OMO_LSP_DAEMON_CLI, resolveDaemonRuntime } from "./runtime-contract.js";
|
|
11
|
-
const PROBE_TIMEOUT_MS =
|
|
11
|
+
const PROBE_TIMEOUT_MS = 2_000;
|
|
12
12
|
const DEFAULT_READY_TIMEOUT_MS = 5_000;
|
|
13
13
|
const DEFAULT_POLL_INTERVAL_MS = 100;
|
|
14
|
+
const FAILED_SPAWN_COOLDOWN_MS = 5_000;
|
|
15
|
+
const failedSpawnUntil = new Map();
|
|
14
16
|
export class DaemonUnreachableError extends Error {
|
|
15
17
|
constructor(socketPath) {
|
|
16
18
|
super(`LSP daemon did not become reachable at ${socketPath}`);
|
|
@@ -22,11 +24,23 @@ export async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(
|
|
|
22
24
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
23
25
|
const signal = options.signal;
|
|
24
26
|
throwIfAborted(signal);
|
|
25
|
-
if (await awaitWithSignal(deps.probe(paths, signal), signal))
|
|
27
|
+
if (await awaitWithSignal(deps.probe(paths, signal), signal)) {
|
|
28
|
+
failedSpawnUntil.delete(paths.socket);
|
|
26
29
|
return;
|
|
30
|
+
}
|
|
27
31
|
throwIfAborted(signal);
|
|
32
|
+
const retryAt = failedSpawnUntil.get(paths.socket);
|
|
33
|
+
if (retryAt !== undefined && deps.now() < retryAt)
|
|
34
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
35
|
+
failedSpawnUntil.delete(paths.socket);
|
|
28
36
|
deps.spawnDaemon(paths);
|
|
29
|
-
|
|
37
|
+
try {
|
|
38
|
+
await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
30
44
|
}
|
|
31
45
|
async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
|
|
32
46
|
const deadline = deps.now() + readyTimeoutMs;
|
|
@@ -3150,6 +3150,7 @@ async function disposeDefaultLspManager() {
|
|
|
3150
3150
|
import { connect } from "node:net";
|
|
3151
3151
|
import { homedir as homedir3 } from "node:os";
|
|
3152
3152
|
import { join as join8 } from "node:path";
|
|
3153
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
3153
3154
|
|
|
3154
3155
|
// ../lsp-core/src/request-context.ts
|
|
3155
3156
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -3789,9 +3790,11 @@ function createLineDecoder(onMessage, onParseError) {
|
|
|
3789
3790
|
}
|
|
3790
3791
|
|
|
3791
3792
|
// src/ensure-daemon.ts
|
|
3792
|
-
var PROBE_TIMEOUT_MS =
|
|
3793
|
+
var PROBE_TIMEOUT_MS = 2000;
|
|
3793
3794
|
var DEFAULT_READY_TIMEOUT_MS = 5000;
|
|
3794
3795
|
var DEFAULT_POLL_INTERVAL_MS = 100;
|
|
3796
|
+
var FAILED_SPAWN_COOLDOWN_MS = 5000;
|
|
3797
|
+
var failedSpawnUntil = new Map;
|
|
3795
3798
|
|
|
3796
3799
|
class DaemonUnreachableError extends Error {
|
|
3797
3800
|
constructor(socketPath) {
|
|
@@ -3804,11 +3807,22 @@ async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), opti
|
|
|
3804
3807
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
3805
3808
|
const signal = options.signal;
|
|
3806
3809
|
throwIfAborted(signal);
|
|
3807
|
-
if (await awaitWithSignal2(deps.probe(paths, signal), signal))
|
|
3810
|
+
if (await awaitWithSignal2(deps.probe(paths, signal), signal)) {
|
|
3811
|
+
failedSpawnUntil.delete(paths.socket);
|
|
3808
3812
|
return;
|
|
3813
|
+
}
|
|
3809
3814
|
throwIfAborted(signal);
|
|
3815
|
+
const retryAt = failedSpawnUntil.get(paths.socket);
|
|
3816
|
+
if (retryAt !== undefined && deps.now() < retryAt)
|
|
3817
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
3818
|
+
failedSpawnUntil.delete(paths.socket);
|
|
3810
3819
|
deps.spawnDaemon(paths);
|
|
3811
|
-
|
|
3820
|
+
try {
|
|
3821
|
+
await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
|
|
3822
|
+
} catch (error) {
|
|
3823
|
+
failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
|
|
3824
|
+
throw error;
|
|
3825
|
+
}
|
|
3812
3826
|
}
|
|
3813
3827
|
async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
|
|
3814
3828
|
const deadline = deps.now() + readyTimeoutMs;
|
|
@@ -6327,6 +6341,7 @@ function parseContext(value) {
|
|
|
6327
6341
|
|
|
6328
6342
|
// src/daemon-client.ts
|
|
6329
6343
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
6344
|
+
var STARTUP_BACKOFF_MS = [0, 100, 300];
|
|
6330
6345
|
var nextProxyRequestId = 1;
|
|
6331
6346
|
async function callToolViaDaemon(name, args, options) {
|
|
6332
6347
|
const context = requireContext(options.context);
|
|
@@ -6334,17 +6349,31 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
6334
6349
|
const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
|
|
6335
6350
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
6336
6351
|
const requestArgs = withContext(args, context);
|
|
6352
|
+
const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
|
|
6353
|
+
const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
|
|
6337
6354
|
let lastError;
|
|
6338
6355
|
let authRefreshUsed = false;
|
|
6339
|
-
for (
|
|
6356
|
+
for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
|
|
6340
6357
|
try {
|
|
6341
|
-
|
|
6358
|
+
if (backoffMs > 0)
|
|
6359
|
+
await sleep(backoffMs, options.signal);
|
|
6360
|
+
if (options.signal?.aborted)
|
|
6361
|
+
throw new DaemonRequestCancelledError(false);
|
|
6362
|
+
if (attempt === 0) {
|
|
6363
|
+
await ensureDaemonAvailable(paths, ensure, options.signal);
|
|
6364
|
+
} else if (!await probe(paths, options.signal)) {
|
|
6365
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
6366
|
+
}
|
|
6342
6367
|
const token = readAuthToken(paths);
|
|
6343
6368
|
if (!token)
|
|
6344
6369
|
throw new DaemonRequestError("daemon auth token missing", false);
|
|
6345
6370
|
const sendOptions = options.signal === undefined ? { timeoutMs } : { timeoutMs, signal: options.signal };
|
|
6346
6371
|
return await sendToolCall(paths, token, name, requestArgs, sendOptions);
|
|
6347
6372
|
} catch (error) {
|
|
6373
|
+
if (options.signal?.aborted) {
|
|
6374
|
+
lastError = new DaemonRequestCancelledError(false);
|
|
6375
|
+
break;
|
|
6376
|
+
}
|
|
6348
6377
|
lastError = error;
|
|
6349
6378
|
if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
|
|
6350
6379
|
authRefreshUsed = true;
|
|
@@ -35,12 +35,13 @@
|
|
|
35
35
|
"check": "tsc --noEmit && biome check . && npm run build"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@
|
|
38
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
39
|
+
"@biomejs/biome": "2.5.14",
|
|
39
40
|
"@oh-my-opencode/lsp-core": "file:../lsp-core",
|
|
40
41
|
"@oh-my-opencode/mcp-stdio-core": "file:../mcp-stdio-core",
|
|
41
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^26.6.2",
|
|
42
43
|
"typescript": "^6.0.3",
|
|
43
|
-
"vitest": "
|
|
44
|
+
"vitest": "5.0.1"
|
|
44
45
|
},
|
|
45
46
|
"engines": {
|
|
46
47
|
"node": ">=20.0.0"
|
|
@@ -41,12 +41,13 @@
|
|
|
41
41
|
"check": "tsc --noEmit && biome check . && npm run build"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
44
45
|
"@oh-my-opencode/lsp-core": "file:../lsp-core",
|
|
45
46
|
"@oh-my-opencode/mcp-stdio-core": "file:../mcp-stdio-core",
|
|
46
|
-
"@biomejs/biome": "2.
|
|
47
|
-
"@types/node": "^
|
|
47
|
+
"@biomejs/biome": "2.5.14",
|
|
48
|
+
"@types/node": "^26.6.2",
|
|
48
49
|
"typescript": "^6.0.3",
|
|
49
|
-
"vitest": "
|
|
50
|
+
"vitest": "5.0.1"
|
|
50
51
|
},
|
|
51
52
|
"engines": {
|
|
52
53
|
"node": ">=20.0.0"
|