@openscout/scout 0.2.73 → 0.2.75
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/bin/scoutd +0 -0
- package/dist/build-manifest.json +9 -0
- package/dist/client/assets/{RepoDiffViewer-D8gg36W3.js → RepoDiffViewer-CTXJvjIL.js} +1 -1
- package/dist/client/assets/{addon-fit-D4KdY-pj.js → addon-fit-3IrvLm2n.js} +1 -1
- package/dist/client/assets/{addon-webgl-Bo_tmKBp.js → addon-webgl-BgxIDUI-.js} +1 -1
- package/dist/client/assets/{arc.es-D0gujIKy.js → arc.es-Bh8P_xre.js} +1 -1
- package/dist/client/assets/c-BIGW1oBm.js +1 -0
- package/dist/client/assets/cpp-DIPi6g--.js +1 -0
- package/dist/client/assets/css-CLj8gQPS.js +1 -0
- package/dist/client/assets/dart-bE4Kk8sk.js +1 -0
- package/dist/client/assets/docker-BcOcwvcX.js +1 -0
- package/dist/client/assets/{embed-entry-CUVNwyB_.js → embed-entry-wAEtYUEM.js} +1 -1
- package/dist/client/assets/go-C27-OAKa.js +1 -0
- package/dist/client/assets/html-pp8916En.js +1 -0
- package/dist/client/assets/index-BK3mRYyN.js +272 -0
- package/dist/client/assets/index-Dm1ZQS9G.css +1 -0
- package/dist/client/assets/java-CylS5w8V.js +1 -0
- package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/client/assets/json-Cp-IABpG.js +1 -0
- package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/client/assets/make-CHLpvVh8.js +1 -0
- package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/client/assets/python-B6aJPvgy.js +1 -0
- package/dist/client/assets/ruby-B13GW9FM.js +1 -0
- package/dist/client/assets/rust-B1yitclQ.js +1 -0
- package/dist/client/assets/scss-D5BDwBP9.js +1 -0
- package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/client/assets/sql-CRqJ_cUM.js +1 -0
- package/dist/client/assets/swift-D82vCrfD.js +1 -0
- package/dist/client/assets/toml-vGWfd6FD.js +1 -0
- package/dist/client/assets/tsx-COt5Ahok.js +1 -0
- package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/client/assets/{xterm-RfflDFod.js → xterm-CoGJTxj9.js} +1 -1
- package/dist/client/assets/yaml-Buea-lGh.js +1 -0
- package/dist/client/index.html +2 -2
- package/dist/main.mjs +887 -584
- package/dist/node/main.mjs +115 -1
- package/dist/pairing-runtime-controller.mjs +2525 -895
- package/dist/runtime/base-daemon.mjs +77 -20
- package/dist/runtime/broker-daemon.mjs +1403 -705
- package/dist/runtime/broker-process-manager.mjs +29 -0
- package/dist/runtime/mesh-discover.mjs +29 -0
- package/dist/scout-control-plane-web.mjs +2970 -1116
- package/dist/scout-web-server.mjs +2970 -1116
- package/package.json +1 -1
- package/dist/client/assets/index-CRkjiso5.js +0 -257
- package/dist/client/assets/index-D_RX2cRb.css +0 -1
package/dist/main.mjs
CHANGED
|
@@ -119,6 +119,7 @@ var init_actors = __esm(() => {
|
|
|
119
119
|
"claude",
|
|
120
120
|
"grok",
|
|
121
121
|
"grok-acp",
|
|
122
|
+
"kimi",
|
|
122
123
|
"flue",
|
|
123
124
|
"cursor",
|
|
124
125
|
"native",
|
|
@@ -3548,6 +3549,13 @@ var init_codex_executable = () => {};
|
|
|
3548
3549
|
import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
|
|
3549
3550
|
import { homedir } from "os";
|
|
3550
3551
|
import { join as join2 } from "path";
|
|
3552
|
+
function assertTestIsolatedUserData(operation, isolationEnvKey) {
|
|
3553
|
+
if (true)
|
|
3554
|
+
return;
|
|
3555
|
+
if (process.env[isolationEnvKey]?.trim())
|
|
3556
|
+
return;
|
|
3557
|
+
throw new Error(`Refusing to ${operation} while NODE_ENV=test without ${isolationEnvKey} set. ` + "Tests must isolate OpenScout user data in a temp directory (see prepareHome in onboarding.test.ts).");
|
|
3558
|
+
}
|
|
3551
3559
|
function resolveOpenScoutSupportPaths() {
|
|
3552
3560
|
const home = homedir();
|
|
3553
3561
|
const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join2(home, "Library", "Application Support", "OpenScout");
|
|
@@ -3592,6 +3600,7 @@ function relayAgentLogsDirectory(agentId) {
|
|
|
3592
3600
|
return localAgentLogsDirectory(agentId);
|
|
3593
3601
|
}
|
|
3594
3602
|
function ensureOpenScoutCleanSlateSync() {
|
|
3603
|
+
assertTestIsolatedUserData("reset the OpenScout support directory", "OPENSCOUT_SUPPORT_DIRECTORY");
|
|
3595
3604
|
const paths = resolveOpenScoutSupportPaths();
|
|
3596
3605
|
if (existsSync(paths.cutoverMarkerPath)) {
|
|
3597
3606
|
return;
|
|
@@ -3693,6 +3702,17 @@ function mergeLaunch(base, override) {
|
|
|
3693
3702
|
args: override?.args ?? base?.args ?? []
|
|
3694
3703
|
};
|
|
3695
3704
|
}
|
|
3705
|
+
function mergeSessionDefaults(base, override) {
|
|
3706
|
+
const defaultTransport = override?.defaultTransport ?? base?.defaultTransport;
|
|
3707
|
+
if (!defaultTransport)
|
|
3708
|
+
return;
|
|
3709
|
+
return {
|
|
3710
|
+
...base ?? {},
|
|
3711
|
+
...override ?? {},
|
|
3712
|
+
defaultTransport,
|
|
3713
|
+
fallbackTransports: override?.fallbackTransports ? [...override.fallbackTransports] : base?.fallbackTransports ? [...base.fallbackTransports] : undefined
|
|
3714
|
+
};
|
|
3715
|
+
}
|
|
3696
3716
|
function formatRequirement(requirement) {
|
|
3697
3717
|
if (requirement.label?.trim())
|
|
3698
3718
|
return requirement.label.trim();
|
|
@@ -3753,6 +3773,10 @@ function createBuiltInHarnessCatalog() {
|
|
|
3753
3773
|
} : undefined,
|
|
3754
3774
|
launch: entry.launch ? { ...entry.launch, args: [...entry.launch.args] } : undefined,
|
|
3755
3775
|
resume: entry.resume ? { ...entry.resume } : undefined,
|
|
3776
|
+
sessionDefaults: entry.sessionDefaults ? {
|
|
3777
|
+
...entry.sessionDefaults,
|
|
3778
|
+
fallbackTransports: entry.sessionDefaults.fallbackTransports ? [...entry.sessionDefaults.fallbackTransports] : undefined
|
|
3779
|
+
} : undefined,
|
|
3756
3780
|
resolveEnv: entry.resolveEnv ? [...entry.resolveEnv] : undefined,
|
|
3757
3781
|
capabilities: [...entry.capabilities],
|
|
3758
3782
|
metadata: entry.metadata ? { ...entry.metadata } : undefined
|
|
@@ -3770,6 +3794,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
3770
3794
|
install: mergeInstall(entry.install, override.install),
|
|
3771
3795
|
readiness: mergeReadiness(entry.readiness, override.readiness),
|
|
3772
3796
|
launch: mergeLaunch(entry.launch, override.launch),
|
|
3797
|
+
sessionDefaults: mergeSessionDefaults(entry.sessionDefaults, override.sessionDefaults),
|
|
3773
3798
|
resume: override.resume && entry.resume ? { ...entry.resume, ...override.resume } : entry.resume,
|
|
3774
3799
|
tags: override.tags ? [...override.tags] : entry.tags,
|
|
3775
3800
|
capabilities: override.capabilities ? [...override.capabilities] : entry.capabilities,
|
|
@@ -3800,6 +3825,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
3800
3825
|
readiness: mergeReadiness(undefined, override.readiness),
|
|
3801
3826
|
launch: mergeLaunch(undefined, override.launch),
|
|
3802
3827
|
resume: override.resume?.command && override.resume?.sessionFlag ? { command: override.resume.command, sessionFlag: override.resume.sessionFlag, cwdFlag: override.resume.cwdFlag } : undefined,
|
|
3828
|
+
sessionDefaults: mergeSessionDefaults(undefined, override.sessionDefaults),
|
|
3803
3829
|
resolveEnv: override.resolveEnv ? [...override.resolveEnv] : undefined,
|
|
3804
3830
|
capabilities: [...override.capabilities],
|
|
3805
3831
|
metadata: override.metadata ? { ...override.metadata } : undefined
|
|
@@ -3961,6 +3987,10 @@ var init_harness_catalog = __esm(() => {
|
|
|
3961
3987
|
command: "claude",
|
|
3962
3988
|
sessionFlag: "--resume"
|
|
3963
3989
|
},
|
|
3990
|
+
sessionDefaults: {
|
|
3991
|
+
defaultTransport: "tmux",
|
|
3992
|
+
fallbackTransports: ["claude_stream_json"]
|
|
3993
|
+
},
|
|
3964
3994
|
capabilities: ["chat", "invoke", "deliver", "summarize", "review"]
|
|
3965
3995
|
},
|
|
3966
3996
|
{
|
|
@@ -3997,6 +4027,10 @@ var init_harness_catalog = __esm(() => {
|
|
|
3997
4027
|
command: "grok",
|
|
3998
4028
|
sessionFlag: "--resume"
|
|
3999
4029
|
},
|
|
4030
|
+
sessionDefaults: {
|
|
4031
|
+
defaultHarness: "grok-acp",
|
|
4032
|
+
defaultTransport: "grok_acp"
|
|
4033
|
+
},
|
|
4000
4034
|
capabilities: ["chat", "invoke", "deliver", "summarize", "review"],
|
|
4001
4035
|
metadata: {
|
|
4002
4036
|
invocationModel: "tmux_interactive"
|
|
@@ -4036,6 +4070,9 @@ var init_harness_catalog = __esm(() => {
|
|
|
4036
4070
|
sessionFlag: "resume",
|
|
4037
4071
|
cwdFlag: "-C"
|
|
4038
4072
|
},
|
|
4073
|
+
sessionDefaults: {
|
|
4074
|
+
defaultTransport: "codex_app_server"
|
|
4075
|
+
},
|
|
4039
4076
|
capabilities: ["chat", "invoke", "deliver", "review", "execute"]
|
|
4040
4077
|
},
|
|
4041
4078
|
{
|
|
@@ -4068,12 +4105,53 @@ var init_harness_catalog = __esm(() => {
|
|
|
4068
4105
|
loginCommand: "grok login",
|
|
4069
4106
|
notReadyMessage: "Grok ACP is installed but still needs a cached login or XAI_API_KEY."
|
|
4070
4107
|
},
|
|
4108
|
+
sessionDefaults: {
|
|
4109
|
+
defaultTransport: "grok_acp"
|
|
4110
|
+
},
|
|
4071
4111
|
capabilities: ["chat", "invoke", "deliver", "review", "execute"],
|
|
4072
4112
|
metadata: {
|
|
4073
4113
|
adapterType: "grok-acp",
|
|
4074
4114
|
transport: "acp_stdio"
|
|
4075
4115
|
}
|
|
4076
4116
|
},
|
|
4117
|
+
{
|
|
4118
|
+
name: "kimi",
|
|
4119
|
+
harness: "kimi",
|
|
4120
|
+
label: "Kimi Code",
|
|
4121
|
+
description: "Kimi Code CLI coding agent over ACP",
|
|
4122
|
+
homepage: "https://www.kimi.com/code/docs/en/",
|
|
4123
|
+
tags: ["coding", "cli", "kimi", "moonshot", "acp"],
|
|
4124
|
+
featured: true,
|
|
4125
|
+
order: 4,
|
|
4126
|
+
support: {
|
|
4127
|
+
...DEFAULT_SUPPORT,
|
|
4128
|
+
workspace: true,
|
|
4129
|
+
collaboration: true,
|
|
4130
|
+
files: true
|
|
4131
|
+
},
|
|
4132
|
+
install: {
|
|
4133
|
+
binary: "kimi",
|
|
4134
|
+
requires: ["curl"],
|
|
4135
|
+
macos: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
|
|
4136
|
+
linux: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
|
|
4137
|
+
windows: "irm https://code.kimi.com/kimi-code/install.ps1 | iex"
|
|
4138
|
+
},
|
|
4139
|
+
readiness: {
|
|
4140
|
+
anyOf: [
|
|
4141
|
+
{ kind: "file", path: "~/.kimi-code/credentials", label: "~/.kimi-code/credentials", fileType: "directory" }
|
|
4142
|
+
],
|
|
4143
|
+
loginCommand: "kimi login",
|
|
4144
|
+
notReadyMessage: "Kimi Code is installed but still needs a cached login from kimi login."
|
|
4145
|
+
},
|
|
4146
|
+
sessionDefaults: {
|
|
4147
|
+
defaultTransport: "kimi_acp"
|
|
4148
|
+
},
|
|
4149
|
+
capabilities: ["chat", "invoke", "deliver", "review", "execute"],
|
|
4150
|
+
metadata: {
|
|
4151
|
+
adapterType: "kimi-acp",
|
|
4152
|
+
transport: "acp_stdio"
|
|
4153
|
+
}
|
|
4154
|
+
},
|
|
4077
4155
|
{
|
|
4078
4156
|
name: "cursor",
|
|
4079
4157
|
harness: "cursor",
|
|
@@ -5837,6 +5915,7 @@ function resolveOpenScoutSetupContextRoot(options = {}) {
|
|
|
5837
5915
|
return normalizePath(process.cwd());
|
|
5838
5916
|
}
|
|
5839
5917
|
async function writeOpenScoutSettings(settings, options = {}) {
|
|
5918
|
+
assertTestIsolatedUserData("write OpenScout settings", "OPENSCOUT_SUPPORT_DIRECTORY");
|
|
5840
5919
|
ensureOpenScoutCleanSlateSync();
|
|
5841
5920
|
const current = await readOpenScoutSettings(options);
|
|
5842
5921
|
const merged = {
|
|
@@ -9222,6 +9301,7 @@ function resolveHost() {
|
|
|
9222
9301
|
return resolveEffectiveLocalConfig().host ?? DEFAULT_LOCAL_CONFIG.host;
|
|
9223
9302
|
}
|
|
9224
9303
|
function writeLocalConfig(config) {
|
|
9304
|
+
assertTestIsolatedUserData("write the OpenScout local config", "OPENSCOUT_HOME");
|
|
9225
9305
|
const configPath = localConfigPath();
|
|
9226
9306
|
mkdirSync2(dirname6(configPath), { recursive: true });
|
|
9227
9307
|
const body = JSON.stringify({ ...config, version: LOCAL_CONFIG_VERSION }, null, 2) + `
|
|
@@ -9235,6 +9315,7 @@ function localConfigExists() {
|
|
|
9235
9315
|
}
|
|
9236
9316
|
var LOCAL_CONFIG_VERSION = 1, DEFAULT_SCOUT_WEB_PORTAL_HOST = "scout.local", DEFAULT_SCOUT_WEB_DEV_HOST, DEFAULT_SCOUT_WEB_VITE_HMR_PATH = "/ws/hmr", OPENSCOUT_PORTS, DEFAULT_LOCAL_CONFIG;
|
|
9237
9317
|
var init_local_config = __esm(() => {
|
|
9318
|
+
init_support_paths();
|
|
9238
9319
|
DEFAULT_SCOUT_WEB_DEV_HOST = `dev.${DEFAULT_SCOUT_WEB_PORTAL_HOST}`;
|
|
9239
9320
|
OPENSCOUT_PORTS = {
|
|
9240
9321
|
broker: 43110,
|
|
@@ -9906,6 +9987,29 @@ function readNumber2(value) {
|
|
|
9906
9987
|
function readHealthTransport(value) {
|
|
9907
9988
|
return value === "unix_socket" || value === "http" || value === "in_process" ? value : undefined;
|
|
9908
9989
|
}
|
|
9990
|
+
function readRuntimeFreshness(value) {
|
|
9991
|
+
if (!isRecord4(value))
|
|
9992
|
+
return;
|
|
9993
|
+
const state = readString2(value.state);
|
|
9994
|
+
const basis = readString2(value.basis);
|
|
9995
|
+
const detail = readString2(value.detail);
|
|
9996
|
+
if (!state || !basis || !detail)
|
|
9997
|
+
return;
|
|
9998
|
+
return {
|
|
9999
|
+
state,
|
|
10000
|
+
intentional: readBoolean(value.intentional) ?? false,
|
|
10001
|
+
basis,
|
|
10002
|
+
artifactCommit: readString2(value.artifactCommit) ?? null,
|
|
10003
|
+
expectedCommit: readString2(value.expectedCommit) ?? null,
|
|
10004
|
+
pin: readString2(value.pin) ?? null,
|
|
10005
|
+
pinReason: readString2(value.pinReason) ?? null,
|
|
10006
|
+
manifestPath: readString2(value.manifestPath) ?? null,
|
|
10007
|
+
version: readString2(value.version) ?? null,
|
|
10008
|
+
builtAt: readString2(value.builtAt) ?? null,
|
|
10009
|
+
sourceDirty: readBoolean(value.sourceDirty) ?? null,
|
|
10010
|
+
detail
|
|
10011
|
+
};
|
|
10012
|
+
}
|
|
9909
10013
|
function normalizeNativeServiceStatus(input, config) {
|
|
9910
10014
|
const healthRecord = isRecord4(input.health) ? input.health : {};
|
|
9911
10015
|
const healthReachable = readBoolean(healthRecord.reachable) ?? readBoolean(input.reachable) ?? false;
|
|
@@ -9921,6 +10025,7 @@ function normalizeNativeServiceStatus(input, config) {
|
|
|
9921
10025
|
const stdoutLogPath = readString2(input.stdoutLogPath) ?? config.stdoutLogPath;
|
|
9922
10026
|
const stderrLogPath = readString2(input.stderrLogPath) ?? config.stderrLogPath;
|
|
9923
10027
|
const lastLogLine = readString2(input.lastLogLine) ?? (healthReachable ? readLastLogLine([stdoutLogPath, stderrLogPath]) : readLastLogLine([stderrLogPath, stdoutLogPath]));
|
|
10028
|
+
const runtimeFreshness = readRuntimeFreshness(input.runtimeFreshness);
|
|
9924
10029
|
return {
|
|
9925
10030
|
label: readString2(input.label) ?? config.label,
|
|
9926
10031
|
mode: readString2(input.mode) ?? config.mode,
|
|
@@ -9955,6 +10060,7 @@ function normalizeNativeServiceStatus(input, config) {
|
|
|
9955
10060
|
...isRecord4(healthRecord.services) ? { services: healthRecord.services } : {},
|
|
9956
10061
|
error: healthError
|
|
9957
10062
|
},
|
|
10063
|
+
...runtimeFreshness ? { runtimeFreshness } : {},
|
|
9958
10064
|
lastLogLine
|
|
9959
10065
|
};
|
|
9960
10066
|
}
|
|
@@ -10256,8 +10362,12 @@ function formatBrokerServiceStatus(status) {
|
|
|
10256
10362
|
`reachable: ${status.reachable ? "yes" : "no"}`,
|
|
10257
10363
|
`health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
|
|
10258
10364
|
`health transport: ${status.health.transport ?? "unknown"}`,
|
|
10365
|
+
`runtime freshness: ${status.runtimeFreshness?.state ?? "unavailable"}`,
|
|
10259
10366
|
`logs: ${status.stdoutLogPath}`
|
|
10260
10367
|
];
|
|
10368
|
+
if (status.runtimeFreshness) {
|
|
10369
|
+
lines.push(`runtime freshness detail: ${status.runtimeFreshness.detail}`);
|
|
10370
|
+
}
|
|
10261
10371
|
if (status.health.socketFallbackError) {
|
|
10262
10372
|
lines.push(`socket fallback: ${status.health.socketFallbackError}`);
|
|
10263
10373
|
}
|
|
@@ -11478,6 +11588,13 @@ async function readTmuxPaneLocal(key, ctx) {
|
|
|
11478
11588
|
throw error;
|
|
11479
11589
|
}
|
|
11480
11590
|
}
|
|
11591
|
+
async function readTmuxSessionExists(sessionName, options = {}) {
|
|
11592
|
+
const name = sessionName.trim();
|
|
11593
|
+
if (!name)
|
|
11594
|
+
return false;
|
|
11595
|
+
const snapshot = await tmuxSessionsProbe.for({ env: options.env, socketPath: options.socketPath }).fresh({ maxAgeMs: options.maxAgeMs ?? TMUX_TTL_MS });
|
|
11596
|
+
return Boolean(snapshot.value?.some((session) => session.name === name));
|
|
11597
|
+
}
|
|
11481
11598
|
function readTmuxSessionExistsSnapshot(sessionName, options = {}) {
|
|
11482
11599
|
const name = sessionName.trim();
|
|
11483
11600
|
if (!name)
|
|
@@ -14680,6 +14797,10 @@ function normalizeCodexModelValue(value) {
|
|
|
14680
14797
|
if (!trimmed) {
|
|
14681
14798
|
return null;
|
|
14682
14799
|
}
|
|
14800
|
+
const lower = trimmed.toLowerCase();
|
|
14801
|
+
if (lower === "5.6" || lower === "gpt-5.6") {
|
|
14802
|
+
return "gpt-5.6-sol";
|
|
14803
|
+
}
|
|
14683
14804
|
if (/^\d+(?:\.\d+)*(?:-[A-Za-z0-9][A-Za-z0-9._-]*)?$/.test(trimmed)) {
|
|
14684
14805
|
return `gpt-${trimmed}`;
|
|
14685
14806
|
}
|
|
@@ -18463,6 +18584,73 @@ var init_grok_acp = __esm(() => {
|
|
|
18463
18584
|
init_adapter4();
|
|
18464
18585
|
});
|
|
18465
18586
|
|
|
18587
|
+
// ../agent-sessions/src/adapters/kimi-acp/adapter.ts
|
|
18588
|
+
import { existsSync as existsSync17 } from "fs";
|
|
18589
|
+
import { homedir as homedir18 } from "os";
|
|
18590
|
+
import { join as join20 } from "path";
|
|
18591
|
+
function isRecord8(value) {
|
|
18592
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
18593
|
+
}
|
|
18594
|
+
function stringValue8(value) {
|
|
18595
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
18596
|
+
}
|
|
18597
|
+
function stringArray4(value) {
|
|
18598
|
+
if (!Array.isArray(value)) {
|
|
18599
|
+
return null;
|
|
18600
|
+
}
|
|
18601
|
+
const entries = value.filter((entry) => typeof entry === "string");
|
|
18602
|
+
return entries.length === value.length ? entries : null;
|
|
18603
|
+
}
|
|
18604
|
+
function firstNonEmptyString2(...values) {
|
|
18605
|
+
for (const value of values) {
|
|
18606
|
+
const trimmed = value?.trim();
|
|
18607
|
+
if (trimmed) {
|
|
18608
|
+
return trimmed;
|
|
18609
|
+
}
|
|
18610
|
+
}
|
|
18611
|
+
return null;
|
|
18612
|
+
}
|
|
18613
|
+
function defaultKimiCommand(env) {
|
|
18614
|
+
const override = firstNonEmptyString2(env?.KIMI_CLI_BIN, process.env.KIMI_CLI_BIN);
|
|
18615
|
+
if (override) {
|
|
18616
|
+
return override;
|
|
18617
|
+
}
|
|
18618
|
+
const installedCandidates = [
|
|
18619
|
+
join20(homedir18(), ".kimi-code", "bin", "kimi"),
|
|
18620
|
+
join20(homedir18(), ".local", "bin", "kimi")
|
|
18621
|
+
];
|
|
18622
|
+
return installedCandidates.find((candidate) => existsSync17(candidate)) ?? "kimi";
|
|
18623
|
+
}
|
|
18624
|
+
var DEFAULT_KIMI_ARGS, DEFAULT_KIMI_STARTUP_TIMEOUT_MS = 60000, KIMI_ACP_ADAPTER_TYPE = "kimi-acp", createAdapter5 = (config) => {
|
|
18625
|
+
const rawOptions = isRecord8(config.options) ? config.options : {};
|
|
18626
|
+
const command = stringValue8(rawOptions.command) ?? defaultKimiCommand(config.env);
|
|
18627
|
+
const args = stringArray4(rawOptions.args) ?? DEFAULT_KIMI_ARGS;
|
|
18628
|
+
const authMethodPreference = stringArray4(rawOptions.authMethodPreference) ?? ["login"];
|
|
18629
|
+
return new AcpAdapter({
|
|
18630
|
+
...config,
|
|
18631
|
+
options: {
|
|
18632
|
+
clientName: "openscout",
|
|
18633
|
+
clientTitle: "OpenScout",
|
|
18634
|
+
...rawOptions,
|
|
18635
|
+
adapterType: KIMI_ACP_ADAPTER_TYPE,
|
|
18636
|
+
command,
|
|
18637
|
+
args,
|
|
18638
|
+
startupTimeoutMs: typeof rawOptions.startupTimeoutMs === "number" ? rawOptions.startupTimeoutMs : DEFAULT_KIMI_STARTUP_TIMEOUT_MS,
|
|
18639
|
+
requireAuth: typeof rawOptions.requireAuth === "boolean" ? rawOptions.requireAuth : true,
|
|
18640
|
+
authMethodPreference
|
|
18641
|
+
}
|
|
18642
|
+
});
|
|
18643
|
+
};
|
|
18644
|
+
var init_adapter5 = __esm(() => {
|
|
18645
|
+
init_adapter3();
|
|
18646
|
+
DEFAULT_KIMI_ARGS = ["acp"];
|
|
18647
|
+
});
|
|
18648
|
+
|
|
18649
|
+
// ../agent-sessions/src/adapters/kimi-acp/index.ts
|
|
18650
|
+
var init_kimi_acp = __esm(() => {
|
|
18651
|
+
init_adapter5();
|
|
18652
|
+
});
|
|
18653
|
+
|
|
18466
18654
|
// ../agent-sessions/src/adapters/openai-compat/adapter.ts
|
|
18467
18655
|
function parseOptions2(raw) {
|
|
18468
18656
|
if (!raw) {
|
|
@@ -18481,8 +18669,8 @@ function parseOptions2(raw) {
|
|
|
18481
18669
|
temperature: raw["temperature"]
|
|
18482
18670
|
};
|
|
18483
18671
|
}
|
|
18484
|
-
var OpenAICompatAdapter,
|
|
18485
|
-
var
|
|
18672
|
+
var OpenAICompatAdapter, createAdapter6 = (config) => new OpenAICompatAdapter(config);
|
|
18673
|
+
var init_adapter6 = __esm(() => {
|
|
18486
18674
|
OpenAICompatAdapter = class OpenAICompatAdapter extends BaseAdapter {
|
|
18487
18675
|
type = "openai";
|
|
18488
18676
|
options;
|
|
@@ -18842,7 +19030,7 @@ Referenced files: ${prompt.files.join(", ")}`
|
|
|
18842
19030
|
|
|
18843
19031
|
// ../agent-sessions/src/adapters/openai-compat/index.ts
|
|
18844
19032
|
var init_openai_compat = __esm(() => {
|
|
18845
|
-
|
|
19033
|
+
init_adapter6();
|
|
18846
19034
|
});
|
|
18847
19035
|
|
|
18848
19036
|
// ../agent-sessions/src/adapters/opencode/adapter.ts
|
|
@@ -18871,8 +19059,8 @@ function delay(ms, signal) {
|
|
|
18871
19059
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
18872
19060
|
});
|
|
18873
19061
|
}
|
|
18874
|
-
var OpenCodeAdapter,
|
|
18875
|
-
var
|
|
19062
|
+
var OpenCodeAdapter, createAdapter7 = (config) => new OpenCodeAdapter(config);
|
|
19063
|
+
var init_adapter7 = __esm(() => {
|
|
18876
19064
|
OpenCodeAdapter = class OpenCodeAdapter extends BaseAdapter {
|
|
18877
19065
|
type = "opencode";
|
|
18878
19066
|
serverProcess = null;
|
|
@@ -19326,7 +19514,7 @@ var init_adapter6 = __esm(() => {
|
|
|
19326
19514
|
|
|
19327
19515
|
// ../agent-sessions/src/adapters/opencode/index.ts
|
|
19328
19516
|
var init_opencode = __esm(() => {
|
|
19329
|
-
|
|
19517
|
+
init_adapter7();
|
|
19330
19518
|
});
|
|
19331
19519
|
|
|
19332
19520
|
// ../agent-sessions/src/adapters/pi/adapter.ts
|
|
@@ -19423,8 +19611,8 @@ function buildPiProcessEnv(config, sourceEnv = process.env) {
|
|
|
19423
19611
|
}
|
|
19424
19612
|
return env;
|
|
19425
19613
|
}
|
|
19426
|
-
var BASE_PROCESS_ENV_KEYS, PROVIDER_CREDENTIAL_ENV, PiAdapter,
|
|
19427
|
-
var
|
|
19614
|
+
var BASE_PROCESS_ENV_KEYS, PROVIDER_CREDENTIAL_ENV, PiAdapter, createAdapter8 = (config) => new PiAdapter(config);
|
|
19615
|
+
var init_adapter8 = __esm(() => {
|
|
19428
19616
|
BASE_PROCESS_ENV_KEYS = [
|
|
19429
19617
|
"PATH",
|
|
19430
19618
|
"HOME",
|
|
@@ -20289,7 +20477,7 @@ var init_adapter7 = __esm(() => {
|
|
|
20289
20477
|
|
|
20290
20478
|
// ../agent-sessions/src/adapters/pi/index.ts
|
|
20291
20479
|
var init_pi = __esm(() => {
|
|
20292
|
-
|
|
20480
|
+
init_adapter8();
|
|
20293
20481
|
});
|
|
20294
20482
|
|
|
20295
20483
|
// ../agent-sessions/src/index.ts
|
|
@@ -20301,6 +20489,7 @@ var init_src2 = __esm(() => {
|
|
|
20301
20489
|
init_codex();
|
|
20302
20490
|
init_acp();
|
|
20303
20491
|
init_grok_acp();
|
|
20492
|
+
init_kimi_acp();
|
|
20304
20493
|
init_openai_compat();
|
|
20305
20494
|
init_opencode();
|
|
20306
20495
|
init_pi();
|
|
@@ -20323,11 +20512,21 @@ var init_requester_timeout = __esm(() => {
|
|
|
20323
20512
|
};
|
|
20324
20513
|
});
|
|
20325
20514
|
|
|
20515
|
+
// ../runtime/src/acp-agent-invocation.ts
|
|
20516
|
+
var DEFAULT_ACP_HARD_CEILING_MS;
|
|
20517
|
+
var init_acp_agent_invocation = __esm(() => {
|
|
20518
|
+
init_requester_timeout();
|
|
20519
|
+
DEFAULT_ACP_HARD_CEILING_MS = 30 * 60000;
|
|
20520
|
+
});
|
|
20521
|
+
|
|
20326
20522
|
// ../runtime/src/grok-acp-invocation.ts
|
|
20327
|
-
var GROK_ACP_HARD_CEILING_MS;
|
|
20328
20523
|
var init_grok_acp_invocation = __esm(() => {
|
|
20329
|
-
|
|
20330
|
-
|
|
20524
|
+
init_acp_agent_invocation();
|
|
20525
|
+
});
|
|
20526
|
+
|
|
20527
|
+
// ../runtime/src/kimi-acp-invocation.ts
|
|
20528
|
+
var init_kimi_acp_invocation = __esm(() => {
|
|
20529
|
+
init_acp_agent_invocation();
|
|
20331
20530
|
});
|
|
20332
20531
|
|
|
20333
20532
|
// ../runtime/src/managed-agent-environment.ts
|
|
@@ -20358,8 +20557,8 @@ function buildManagedAgentShellExports(options) {
|
|
|
20358
20557
|
import { randomUUID } from "crypto";
|
|
20359
20558
|
import { spawn as spawn5 } from "child_process";
|
|
20360
20559
|
import { appendFile as appendFile3, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile7 } from "fs/promises";
|
|
20361
|
-
import { existsSync as
|
|
20362
|
-
import { join as
|
|
20560
|
+
import { existsSync as existsSync18, readFileSync as readFileSync8 } from "fs";
|
|
20561
|
+
import { join as join21 } from "path";
|
|
20363
20562
|
function resolveRequesterTimeoutMs2(timeoutMs) {
|
|
20364
20563
|
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
|
20365
20564
|
return timeoutMs;
|
|
@@ -20410,11 +20609,11 @@ function errorMessage5(error) {
|
|
|
20410
20609
|
return error instanceof Error ? error.message : String(error);
|
|
20411
20610
|
}
|
|
20412
20611
|
function readSessionCatalogSync(runtimeDirectory) {
|
|
20413
|
-
const catalogPath =
|
|
20612
|
+
const catalogPath = join21(runtimeDirectory, SESSION_CATALOG_FILENAME2);
|
|
20414
20613
|
try {
|
|
20415
|
-
if (!
|
|
20416
|
-
const legacyPath =
|
|
20417
|
-
if (
|
|
20614
|
+
if (!existsSync18(catalogPath)) {
|
|
20615
|
+
const legacyPath = join21(runtimeDirectory, "claude-session-id.txt");
|
|
20616
|
+
if (existsSync18(legacyPath)) {
|
|
20418
20617
|
const legacyId = readFileSync8(legacyPath, "utf8").trim();
|
|
20419
20618
|
if (legacyId) {
|
|
20420
20619
|
return {
|
|
@@ -20441,7 +20640,7 @@ async function readSessionCatalog(runtimeDirectory) {
|
|
|
20441
20640
|
return readSessionCatalogSync(runtimeDirectory);
|
|
20442
20641
|
}
|
|
20443
20642
|
async function writeSessionCatalog(runtimeDirectory, catalog) {
|
|
20444
|
-
const catalogPath =
|
|
20643
|
+
const catalogPath = join21(runtimeDirectory, SESSION_CATALOG_FILENAME2);
|
|
20445
20644
|
await mkdir7(runtimeDirectory, { recursive: true });
|
|
20446
20645
|
await writeFile7(catalogPath, JSON.stringify(catalog, null, 2) + `
|
|
20447
20646
|
`);
|
|
@@ -20474,8 +20673,8 @@ class ClaudeStreamJsonSession {
|
|
|
20474
20673
|
constructor(options) {
|
|
20475
20674
|
this.options = options;
|
|
20476
20675
|
this.catalogDirectory = options.runtimeDirectory;
|
|
20477
|
-
this.stdoutLogPath =
|
|
20478
|
-
this.stderrLogPath =
|
|
20676
|
+
this.stdoutLogPath = join21(options.logsDirectory, "stdout.log");
|
|
20677
|
+
this.stderrLogPath = join21(options.logsDirectory, "stderr.log");
|
|
20479
20678
|
this.lastConfigSignature = this.configSignature(options);
|
|
20480
20679
|
}
|
|
20481
20680
|
matches(options) {
|
|
@@ -20631,7 +20830,7 @@ class ClaudeStreamJsonSession {
|
|
|
20631
20830
|
async startSession() {
|
|
20632
20831
|
await mkdir7(this.options.runtimeDirectory, { recursive: true });
|
|
20633
20832
|
await mkdir7(this.options.logsDirectory, { recursive: true });
|
|
20634
|
-
await writeFile7(
|
|
20833
|
+
await writeFile7(join21(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
|
|
20635
20834
|
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
20636
20835
|
this.claudeSessionId = catalog.activeSessionId;
|
|
20637
20836
|
this.resumedSessionId = this.claudeSessionId;
|
|
@@ -20881,11 +21080,11 @@ function buildCollaborationContractPrompt(agentId) {
|
|
|
20881
21080
|
}
|
|
20882
21081
|
|
|
20883
21082
|
// ../runtime/src/pi-rpc.ts
|
|
20884
|
-
import { existsSync as
|
|
21083
|
+
import { existsSync as existsSync19 } from "fs";
|
|
20885
21084
|
import { mkdir as mkdir8, writeFile as writeFile8 } from "fs/promises";
|
|
20886
21085
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
20887
|
-
import { homedir as
|
|
20888
|
-
import { join as
|
|
21086
|
+
import { homedir as homedir19 } from "os";
|
|
21087
|
+
import { join as join22 } from "path";
|
|
20889
21088
|
function normalizeOptionalString2(value) {
|
|
20890
21089
|
const trimmed = value?.trim();
|
|
20891
21090
|
return trimmed ? trimmed : undefined;
|
|
@@ -20906,7 +21105,7 @@ function resolveDefaultPiScoutExtension() {
|
|
|
20906
21105
|
return null;
|
|
20907
21106
|
}
|
|
20908
21107
|
for (const candidate of PI_SCOUT_EXTENSION_CANDIDATES) {
|
|
20909
|
-
if (
|
|
21108
|
+
if (existsSync19(candidate)) {
|
|
20910
21109
|
return candidate;
|
|
20911
21110
|
}
|
|
20912
21111
|
}
|
|
@@ -20986,7 +21185,7 @@ function parsePiRpcLaunchArgs(launchArgs, options) {
|
|
|
20986
21185
|
const parsed = {
|
|
20987
21186
|
extensions: [],
|
|
20988
21187
|
extraArgs: [],
|
|
20989
|
-
sessionDir:
|
|
21188
|
+
sessionDir: join22(options.runtimeDirectory, "pi-sessions")
|
|
20990
21189
|
};
|
|
20991
21190
|
for (let index = 0;index < launchArgs.length; index += 1) {
|
|
20992
21191
|
const current = launchArgs[index] ?? "";
|
|
@@ -21098,11 +21297,11 @@ class PiRpcAgentSession {
|
|
|
21098
21297
|
}
|
|
21099
21298
|
await mkdir8(this.options.runtimeDirectory, { recursive: true });
|
|
21100
21299
|
await mkdir8(this.options.logsDirectory, { recursive: true });
|
|
21101
|
-
await writeFile8(
|
|
21300
|
+
await writeFile8(join22(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
|
|
21102
21301
|
const launch = parsePiRpcLaunchArgs(this.options.launchArgs, {
|
|
21103
21302
|
runtimeDirectory: this.options.runtimeDirectory
|
|
21104
21303
|
});
|
|
21105
|
-
const adapter2 =
|
|
21304
|
+
const adapter2 = createAdapter8({
|
|
21106
21305
|
sessionId: this.options.sessionId,
|
|
21107
21306
|
name: `${this.options.agentName} Pi RPC`,
|
|
21108
21307
|
cwd: this.options.cwd,
|
|
@@ -21258,8 +21457,8 @@ var init_pi_rpc = __esm(() => {
|
|
|
21258
21457
|
init_src2();
|
|
21259
21458
|
PI_SCOUT_EXTENSION_CANDIDATES = [
|
|
21260
21459
|
process.env.OPENSCOUT_PI_SCOUT_EXTENSION_PATH,
|
|
21261
|
-
|
|
21262
|
-
|
|
21460
|
+
join22(homedir19(), ".pi", "agent", "extensions", "pi-scout"),
|
|
21461
|
+
join22(homedir19(), "dev", "pi-scout")
|
|
21263
21462
|
].filter((candidate) => Boolean(candidate));
|
|
21264
21463
|
PI_RPC_FLAGS_WITH_VALUES = new Set([
|
|
21265
21464
|
"--model",
|
|
@@ -21360,15 +21559,15 @@ var init_permission_policy2 = __esm(() => {
|
|
|
21360
21559
|
});
|
|
21361
21560
|
|
|
21362
21561
|
// ../runtime/src/user-config.ts
|
|
21363
|
-
import { existsSync as
|
|
21364
|
-
import { homedir as
|
|
21365
|
-
import { dirname as dirname14, join as
|
|
21562
|
+
import { existsSync as existsSync20, readFileSync as readFileSync9, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
21563
|
+
import { homedir as homedir20 } from "os";
|
|
21564
|
+
import { dirname as dirname14, join as join23 } from "path";
|
|
21366
21565
|
function userConfigPath() {
|
|
21367
|
-
return
|
|
21566
|
+
return join23(process.env.OPENSCOUT_HOME ?? join23(homedir20(), ".openscout"), "user.json");
|
|
21368
21567
|
}
|
|
21369
21568
|
function loadUserConfig() {
|
|
21370
21569
|
const configPath = userConfigPath();
|
|
21371
|
-
if (!
|
|
21570
|
+
if (!existsSync20(configPath))
|
|
21372
21571
|
return {};
|
|
21373
21572
|
try {
|
|
21374
21573
|
return JSON.parse(readFileSync9(configPath, "utf8"));
|
|
@@ -21384,7 +21583,7 @@ function saveUserConfig(config) {
|
|
|
21384
21583
|
}
|
|
21385
21584
|
function readSettingsOperatorName() {
|
|
21386
21585
|
const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
|
|
21387
|
-
if (!
|
|
21586
|
+
if (!existsSync20(settingsPath))
|
|
21388
21587
|
return "";
|
|
21389
21588
|
try {
|
|
21390
21589
|
const settings = JSON.parse(readFileSync9(settingsPath, "utf8"));
|
|
@@ -21410,9 +21609,9 @@ var init_user_config = __esm(() => {
|
|
|
21410
21609
|
});
|
|
21411
21610
|
|
|
21412
21611
|
// ../runtime/src/local-agents.ts
|
|
21413
|
-
import { existsSync as
|
|
21612
|
+
import { existsSync as existsSync21, readFileSync as readFileSync10 } from "fs";
|
|
21414
21613
|
import { mkdir as mkdir9, rm as rm4, stat as stat5, writeFile as writeFile9 } from "fs/promises";
|
|
21415
|
-
import { basename as basename8, dirname as dirname15, join as
|
|
21614
|
+
import { basename as basename8, dirname as dirname15, join as join24, resolve as resolve13 } from "path";
|
|
21416
21615
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
21417
21616
|
function resolveRelayHub() {
|
|
21418
21617
|
return resolveOpenScoutSupportPaths().relayHubDirectory;
|
|
@@ -21423,7 +21622,7 @@ function resolveProjectsRoot(projectPath) {
|
|
|
21423
21622
|
}
|
|
21424
21623
|
try {
|
|
21425
21624
|
const supportPaths = resolveOpenScoutSupportPaths();
|
|
21426
|
-
if (!
|
|
21625
|
+
if (!existsSync21(supportPaths.settingsPath)) {
|
|
21427
21626
|
return dirname15(projectPath);
|
|
21428
21627
|
}
|
|
21429
21628
|
const raw = JSON.parse(readFileSync10(supportPaths.settingsPath, "utf8"));
|
|
@@ -21444,7 +21643,7 @@ function parsePositiveInteger2(value, fallback) {
|
|
|
21444
21643
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
21445
21644
|
}
|
|
21446
21645
|
function scoutCliPath() {
|
|
21447
|
-
return
|
|
21646
|
+
return join24(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
|
|
21448
21647
|
}
|
|
21449
21648
|
function legacyNodeBrokerRelayCommand() {
|
|
21450
21649
|
return `node ${JSON.stringify(scoutCliPath())}`;
|
|
@@ -21457,13 +21656,13 @@ function titleCaseLocalAgentName(value) {
|
|
|
21457
21656
|
}
|
|
21458
21657
|
function resolveScoutSkillPath() {
|
|
21459
21658
|
const candidatePaths = [
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21463
|
-
|
|
21659
|
+
join24(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
|
|
21660
|
+
join24(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
|
|
21661
|
+
join24(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
|
|
21662
|
+
join24(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
|
|
21464
21663
|
];
|
|
21465
21664
|
for (const path of candidatePaths) {
|
|
21466
|
-
if (
|
|
21665
|
+
if (existsSync21(path)) {
|
|
21467
21666
|
return path;
|
|
21468
21667
|
}
|
|
21469
21668
|
}
|
|
@@ -21801,7 +22000,7 @@ function expandHomePath4(value) {
|
|
|
21801
22000
|
return process.env.HOME ?? process.cwd();
|
|
21802
22001
|
}
|
|
21803
22002
|
if (value.startsWith("~/")) {
|
|
21804
|
-
return
|
|
22003
|
+
return join24(process.env.HOME ?? process.cwd(), value.slice(2));
|
|
21805
22004
|
}
|
|
21806
22005
|
return value;
|
|
21807
22006
|
}
|
|
@@ -22076,6 +22275,23 @@ function stripLaunchReasoningEffortForHarness(harness, launchArgs) {
|
|
|
22076
22275
|
}
|
|
22077
22276
|
return next2;
|
|
22078
22277
|
}
|
|
22278
|
+
if (harness === "claude" || harness === "grok") {
|
|
22279
|
+
const next2 = [];
|
|
22280
|
+
const normalized2 = normalizeLocalAgentLaunchArgs(launchArgs);
|
|
22281
|
+
const flags = ["--effort", "--reasoning-effort"];
|
|
22282
|
+
for (let index = 0;index < normalized2.length; index += 1) {
|
|
22283
|
+
const current = normalized2[index] ?? "";
|
|
22284
|
+
if (flags.includes(current)) {
|
|
22285
|
+
index += 1;
|
|
22286
|
+
continue;
|
|
22287
|
+
}
|
|
22288
|
+
if (flags.some((flag) => current.startsWith(`${flag}=`))) {
|
|
22289
|
+
continue;
|
|
22290
|
+
}
|
|
22291
|
+
next2.push(current);
|
|
22292
|
+
}
|
|
22293
|
+
return next2;
|
|
22294
|
+
}
|
|
22079
22295
|
if (harness !== "codex") {
|
|
22080
22296
|
return normalizeLaunchArgsForHarness(harness, launchArgs);
|
|
22081
22297
|
}
|
|
@@ -22109,6 +22325,9 @@ function buildLaunchArgsForRequestedReasoningEffort(harness, reasoningEffort) {
|
|
|
22109
22325
|
if (harness === "codex") {
|
|
22110
22326
|
return normalizeCodexAppServerLaunchArgs(["--reasoning-effort", reasoningEffort]);
|
|
22111
22327
|
}
|
|
22328
|
+
if (harness === "claude") {
|
|
22329
|
+
return ["--effort", reasoningEffort];
|
|
22330
|
+
}
|
|
22112
22331
|
if (harness === "pi") {
|
|
22113
22332
|
return ["--thinking", reasoningEffort.trim().toLowerCase() === "none" ? "off" : reasoningEffort];
|
|
22114
22333
|
}
|
|
@@ -22714,6 +22933,9 @@ function isLocalAgentRecordOnline(agentName, record2) {
|
|
|
22714
22933
|
function isLocalAgentSessionAlive(sessionName) {
|
|
22715
22934
|
return readTmuxSessionExistsSnapshot(sessionName);
|
|
22716
22935
|
}
|
|
22936
|
+
async function isLocalAgentSessionAliveAsync(sessionName) {
|
|
22937
|
+
return readTmuxSessionExists(sessionName, { maxAgeMs: 0 });
|
|
22938
|
+
}
|
|
22717
22939
|
function buildLocalAgentSystemPrompt(agentName, projectName, projectPath, options = {}) {
|
|
22718
22940
|
return renderLocalAgentSystemPromptTemplate(buildLocalAgentSystemPromptTemplate(), buildLocalAgentTemplateContext(agentName, projectName, projectPath), options);
|
|
22719
22941
|
}
|
|
@@ -22721,7 +22943,7 @@ function buildLocalAgentInitialMessage(projectName, agentName) {
|
|
|
22721
22943
|
return `You are now online as the ${agentName} relay agent for ${projectName}. Announce yourself on the relay with: ${brokerRelayCommand()} send --as ${agentName} "relay agent online \u2014 ready to assist with ${projectName}"`;
|
|
22722
22944
|
}
|
|
22723
22945
|
function scoutReplyContextPath(runtimeDirectory) {
|
|
22724
|
-
return
|
|
22946
|
+
return join24(runtimeDirectory, "scout-reply-context.json");
|
|
22725
22947
|
}
|
|
22726
22948
|
function withScoutReplyContextEnvironment(options) {
|
|
22727
22949
|
return {
|
|
@@ -22829,10 +23051,10 @@ function buildLocalAgentLaunchCommand(agentName, record2, projectPath, promptFil
|
|
|
22829
23051
|
const harness = normalizeLocalAgentHarness(record2.harness);
|
|
22830
23052
|
const extraArgs = shellQuoteArguments(harness === "claude" ? normalizeClaudeRuntimeLaunchArgs(record2.launchArgs) : harness === "grok" ? normalizeGrokRuntimeLaunchArgs(record2.launchArgs) : normalizeLaunchArgsForHarness(harness, record2.launchArgs));
|
|
22831
23053
|
if (harness === "codex") {
|
|
22832
|
-
return `exec bash ${JSON.stringify(workerScript ??
|
|
23054
|
+
return `exec bash ${JSON.stringify(workerScript ?? join24(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
|
|
22833
23055
|
}
|
|
22834
23056
|
if (harness === "pi") {
|
|
22835
|
-
const sessionDir =
|
|
23057
|
+
const sessionDir = join24(relayAgentRuntimeDirectory(agentName), "pi-sessions");
|
|
22836
23058
|
return [
|
|
22837
23059
|
"pi",
|
|
22838
23060
|
`--append-system-prompt "$(cat ${JSON.stringify(promptFile)})"`,
|
|
@@ -22871,12 +23093,12 @@ function isShellCommandAvailable(binary) {
|
|
|
22871
23093
|
if (!binary.trim())
|
|
22872
23094
|
return false;
|
|
22873
23095
|
if (binary.includes("/"))
|
|
22874
|
-
return
|
|
23096
|
+
return existsSync21(binary);
|
|
22875
23097
|
const pathValue = process.env.PATH ?? "";
|
|
22876
23098
|
for (const directory of pathValue.split(":")) {
|
|
22877
23099
|
if (!directory)
|
|
22878
23100
|
continue;
|
|
22879
|
-
if (
|
|
23101
|
+
if (existsSync21(join24(directory, binary)))
|
|
22880
23102
|
return true;
|
|
22881
23103
|
}
|
|
22882
23104
|
return false;
|
|
@@ -22936,7 +23158,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
|
|
|
22936
23158
|
await mkdir9(agentRuntimeDir, { recursive: true });
|
|
22937
23159
|
await mkdir9(logsDir, { recursive: true });
|
|
22938
23160
|
if (normalizedRecord.transport === "codex_app_server") {
|
|
22939
|
-
await writeFile9(
|
|
23161
|
+
await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
|
|
22940
23162
|
await ensureCodexAppServerAgentOnline(buildCodexAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
|
|
22941
23163
|
const registry3 = await readLocalAgentRegistry();
|
|
22942
23164
|
registry3[agentName] = {
|
|
@@ -22948,7 +23170,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
|
|
|
22948
23170
|
return registry3[agentName];
|
|
22949
23171
|
}
|
|
22950
23172
|
if (normalizedRecord.transport === "claude_stream_json") {
|
|
22951
|
-
await writeFile9(
|
|
23173
|
+
await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
|
|
22952
23174
|
await ensureClaudeStreamJsonAgentOnline(buildClaudeAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
|
|
22953
23175
|
const registry3 = await readLocalAgentRegistry();
|
|
22954
23176
|
registry3[agentName] = {
|
|
@@ -22960,7 +23182,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
|
|
|
22960
23182
|
return registry3[agentName];
|
|
22961
23183
|
}
|
|
22962
23184
|
if (normalizedRecord.transport === "pi_rpc") {
|
|
22963
|
-
await writeFile9(
|
|
23185
|
+
await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
|
|
22964
23186
|
await ensurePiRpcAgentOnline(buildPiAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
|
|
22965
23187
|
const registry3 = await readLocalAgentRegistry();
|
|
22966
23188
|
registry3[agentName] = {
|
|
@@ -22973,17 +23195,17 @@ async function ensureLocalAgentOnline(agentName, record2) {
|
|
|
22973
23195
|
}
|
|
22974
23196
|
const initialMessage = buildLocalAgentInitialMessage(projectName, agentName);
|
|
22975
23197
|
const bootstrapPrompt = buildLocalAgentBootstrapPrompt(normalizeLocalAgentHarness(normalizedRecord.harness), systemPrompt, initialMessage);
|
|
22976
|
-
const queueDirectory =
|
|
22977
|
-
const processingDirectory =
|
|
22978
|
-
const processedDirectory =
|
|
22979
|
-
const promptFile =
|
|
22980
|
-
const initialFile =
|
|
22981
|
-
const launchScript =
|
|
22982
|
-
const workerScript =
|
|
22983
|
-
const codexSessionIdFile =
|
|
22984
|
-
const stateFile =
|
|
22985
|
-
const stdoutLogFile =
|
|
22986
|
-
const stderrLogFile =
|
|
23198
|
+
const queueDirectory = join24(agentRuntimeDir, "queue");
|
|
23199
|
+
const processingDirectory = join24(queueDirectory, "processing");
|
|
23200
|
+
const processedDirectory = join24(queueDirectory, "processed");
|
|
23201
|
+
const promptFile = join24(agentRuntimeDir, "prompt.txt");
|
|
23202
|
+
const initialFile = join24(agentRuntimeDir, "initial.txt");
|
|
23203
|
+
const launchScript = join24(agentRuntimeDir, "launch.sh");
|
|
23204
|
+
const workerScript = join24(agentRuntimeDir, "codex-worker.sh");
|
|
23205
|
+
const codexSessionIdFile = join24(agentRuntimeDir, "codex-session-id.txt");
|
|
23206
|
+
const stateFile = join24(agentRuntimeDir, "state.json");
|
|
23207
|
+
const stdoutLogFile = join24(logsDir, "stdout.log");
|
|
23208
|
+
const stderrLogFile = join24(logsDir, "stderr.log");
|
|
22987
23209
|
await writeFile9(promptFile, systemPrompt);
|
|
22988
23210
|
await writeFile9(initialFile, bootstrapPrompt);
|
|
22989
23211
|
await writeFile9(stderrLogFile, "");
|
|
@@ -23047,14 +23269,15 @@ async function ensureLocalAgentOnline(agentName, record2) {
|
|
|
23047
23269
|
updatedAt: new Date().toISOString()
|
|
23048
23270
|
}, null, 2) + `
|
|
23049
23271
|
`);
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
|
|
23272
|
+
let sessionOnline = false;
|
|
23273
|
+
for (let attempt = 0;attempt < 20 && !sessionOnline; attempt += 1) {
|
|
23274
|
+
sessionOnline = await isLocalAgentSessionAliveAsync(normalizedRecord.tmuxSession);
|
|
23275
|
+
if (!sessionOnline) {
|
|
23276
|
+
await new Promise((resolve14) => setTimeout(resolve14, 100));
|
|
23053
23277
|
}
|
|
23054
|
-
await new Promise((resolve14) => setTimeout(resolve14, 100));
|
|
23055
23278
|
}
|
|
23056
|
-
if (!
|
|
23057
|
-
const stderrTail =
|
|
23279
|
+
if (!sessionOnline) {
|
|
23280
|
+
const stderrTail = existsSync21(stderrLogFile) ? readFileSync10(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
|
|
23058
23281
|
`).trim() : "";
|
|
23059
23282
|
throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
|
|
23060
23283
|
${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
|
|
@@ -23546,8 +23769,8 @@ async function restartAllLocalAgents(options = {}) {
|
|
|
23546
23769
|
}
|
|
23547
23770
|
function readPersistedSessionCatalogId(runtimeDir) {
|
|
23548
23771
|
try {
|
|
23549
|
-
const catalogPath =
|
|
23550
|
-
if (
|
|
23772
|
+
const catalogPath = join24(runtimeDir, "session-catalog.json");
|
|
23773
|
+
if (existsSync21(catalogPath)) {
|
|
23551
23774
|
const raw = readFileSync10(catalogPath, "utf8").trim();
|
|
23552
23775
|
if (raw) {
|
|
23553
23776
|
const catalog = JSON.parse(raw);
|
|
@@ -23563,8 +23786,8 @@ function readPersistedSessionCatalogId(runtimeDir) {
|
|
|
23563
23786
|
}
|
|
23564
23787
|
function readPersistedLegacySessionId(runtimeDir, filename) {
|
|
23565
23788
|
try {
|
|
23566
|
-
const legacyPath =
|
|
23567
|
-
if (
|
|
23789
|
+
const legacyPath = join24(runtimeDir, filename);
|
|
23790
|
+
if (existsSync21(legacyPath)) {
|
|
23568
23791
|
const value = readFileSync10(legacyPath, "utf8").trim();
|
|
23569
23792
|
return value || null;
|
|
23570
23793
|
}
|
|
@@ -23822,6 +24045,7 @@ var init_local_agents = __esm(() => {
|
|
|
23822
24045
|
init_dispatch_stalled();
|
|
23823
24046
|
init_system_probes();
|
|
23824
24047
|
init_grok_acp_invocation();
|
|
24048
|
+
init_kimi_acp_invocation();
|
|
23825
24049
|
init_claude_stream_json();
|
|
23826
24050
|
init_codex_app_server2();
|
|
23827
24051
|
init_pi_rpc();
|
|
@@ -23841,6 +24065,7 @@ var init_local_agents = __esm(() => {
|
|
|
23841
24065
|
SUPPORTED_SCOUT_HARNESSES = [
|
|
23842
24066
|
...SUPPORTED_LOCAL_AGENT_HARNESSES,
|
|
23843
24067
|
"grok-acp",
|
|
24068
|
+
"kimi",
|
|
23844
24069
|
"flue"
|
|
23845
24070
|
];
|
|
23846
24071
|
DEFAULT_CLAUDE_SCOUT_ALLOWED_TOOLS = [
|
|
@@ -25945,7 +26170,7 @@ var init_sql = __esm(() => {
|
|
|
25945
26170
|
return new SQL([new StringChunk(str)]);
|
|
25946
26171
|
}
|
|
25947
26172
|
sql2.raw = raw;
|
|
25948
|
-
function
|
|
26173
|
+
function join25(chunks, separator) {
|
|
25949
26174
|
const result = [];
|
|
25950
26175
|
for (const [i, chunk] of chunks.entries()) {
|
|
25951
26176
|
if (i > 0 && separator !== undefined) {
|
|
@@ -25955,7 +26180,7 @@ var init_sql = __esm(() => {
|
|
|
25955
26180
|
}
|
|
25956
26181
|
return new SQL(result);
|
|
25957
26182
|
}
|
|
25958
|
-
sql2.join =
|
|
26183
|
+
sql2.join = join25;
|
|
25959
26184
|
function identifier(value) {
|
|
25960
26185
|
return new Name(value);
|
|
25961
26186
|
}
|
|
@@ -28471,7 +28696,7 @@ var init_select2 = __esm(() => {
|
|
|
28471
28696
|
const tableName = getTableLikeName(table2);
|
|
28472
28697
|
for (const item of extractUsedTable(table2))
|
|
28473
28698
|
this.usedTables.add(item);
|
|
28474
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
28699
|
+
if (typeof tableName === "string" && this.config.joins?.some((join25) => join25.alias === tableName)) {
|
|
28475
28700
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
28476
28701
|
}
|
|
28477
28702
|
if (!this.isPartialSelect) {
|
|
@@ -28893,7 +29118,7 @@ var init_update = __esm(() => {
|
|
|
28893
29118
|
createJoin(joinType) {
|
|
28894
29119
|
return (table2, on) => {
|
|
28895
29120
|
const tableName = getTableLikeName(table2);
|
|
28896
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
29121
|
+
if (typeof tableName === "string" && this.config.joins.some((join25) => join25.alias === tableName)) {
|
|
28897
29122
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
28898
29123
|
}
|
|
28899
29124
|
if (typeof on === "function") {
|
|
@@ -30411,8 +30636,8 @@ function readMigrationFiles(config) {
|
|
|
30411
30636
|
var init_migrator = () => {};
|
|
30412
30637
|
|
|
30413
30638
|
// ../runtime/src/control-plane-migrations.ts
|
|
30414
|
-
import { existsSync as
|
|
30415
|
-
import { join as
|
|
30639
|
+
import { existsSync as existsSync22 } from "fs";
|
|
30640
|
+
import { join as join25 } from "path";
|
|
30416
30641
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
30417
30642
|
function hasColumn(database, tableName, columnName) {
|
|
30418
30643
|
const escapedTableName = tableName.replaceAll("'", "''");
|
|
@@ -30429,7 +30654,7 @@ function resolveControlPlaneDrizzleMigrationsFolder() {
|
|
|
30429
30654
|
const candidates = ["../drizzle", "./drizzle"];
|
|
30430
30655
|
for (const candidate of candidates) {
|
|
30431
30656
|
const folder = fileURLToPath7(new URL(candidate, import.meta.url));
|
|
30432
|
-
if (
|
|
30657
|
+
if (existsSync22(join25(folder, "meta", "_journal.json"))) {
|
|
30433
30658
|
return folder;
|
|
30434
30659
|
}
|
|
30435
30660
|
}
|
|
@@ -30464,8 +30689,8 @@ function controlPlaneDatabaseFilename(database) {
|
|
|
30464
30689
|
}
|
|
30465
30690
|
function applyControlPlaneDrizzleMigrations(database) {
|
|
30466
30691
|
const migrationsFolder = resolveControlPlaneDrizzleMigrationsFolder();
|
|
30467
|
-
const journalPath =
|
|
30468
|
-
if (!
|
|
30692
|
+
const journalPath = join25(migrationsFolder, "meta", "_journal.json");
|
|
30693
|
+
if (!existsSync22(journalPath)) {
|
|
30469
30694
|
return false;
|
|
30470
30695
|
}
|
|
30471
30696
|
const migrations = readMigrationFiles({ migrationsFolder });
|
|
@@ -30782,7 +31007,7 @@ function stableHash(value) {
|
|
|
30782
31007
|
function metadataRecord3(value) {
|
|
30783
31008
|
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
30784
31009
|
}
|
|
30785
|
-
function
|
|
31010
|
+
function stringValue9(value) {
|
|
30786
31011
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
30787
31012
|
}
|
|
30788
31013
|
function numberValue6(value) {
|
|
@@ -30832,7 +31057,7 @@ function budgetObservationsFromEndpoint(endpoint, now = Date.now()) {
|
|
|
30832
31057
|
harness: endpoint.harness,
|
|
30833
31058
|
transport: endpoint.transport,
|
|
30834
31059
|
adapterType: endpoint.transport,
|
|
30835
|
-
model:
|
|
31060
|
+
model: stringValue9(metadata?.model),
|
|
30836
31061
|
sessionId: endpoint.sessionId,
|
|
30837
31062
|
projectRoot: endpoint.projectRoot,
|
|
30838
31063
|
cwd: endpoint.cwd,
|
|
@@ -30961,29 +31186,29 @@ function isSqliteConstraintError(error) {
|
|
|
30961
31186
|
function metadataValue(metadata, key) {
|
|
30962
31187
|
return metadata?.[key];
|
|
30963
31188
|
}
|
|
30964
|
-
function
|
|
31189
|
+
function stringValue10(metadata, key) {
|
|
30965
31190
|
const value = metadataValue(metadata, key);
|
|
30966
31191
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
30967
31192
|
}
|
|
30968
31193
|
function invocationStringValue(invocation, key) {
|
|
30969
|
-
const contextValue =
|
|
31194
|
+
const contextValue = stringValue10(invocation.context, key);
|
|
30970
31195
|
if (contextValue) {
|
|
30971
31196
|
return contextValue;
|
|
30972
31197
|
}
|
|
30973
31198
|
const nestedContext = metadataValue(invocation.context, "collaboration");
|
|
30974
31199
|
if (nestedContext && typeof nestedContext === "object" && !Array.isArray(nestedContext)) {
|
|
30975
|
-
const nestedValue =
|
|
31200
|
+
const nestedValue = stringValue10(nestedContext, key);
|
|
30976
31201
|
if (nestedValue) {
|
|
30977
31202
|
return nestedValue;
|
|
30978
31203
|
}
|
|
30979
31204
|
}
|
|
30980
|
-
const metadataEntry =
|
|
31205
|
+
const metadataEntry = stringValue10(invocation.metadata, key);
|
|
30981
31206
|
if (metadataEntry) {
|
|
30982
31207
|
return metadataEntry;
|
|
30983
31208
|
}
|
|
30984
31209
|
const nestedMetadata = metadataValue(invocation.metadata, "collaboration");
|
|
30985
31210
|
if (nestedMetadata && typeof nestedMetadata === "object" && !Array.isArray(nestedMetadata)) {
|
|
30986
|
-
return
|
|
31211
|
+
return stringValue10(nestedMetadata, key);
|
|
30987
31212
|
}
|
|
30988
31213
|
return;
|
|
30989
31214
|
}
|
|
@@ -33263,14 +33488,14 @@ var init_broker_core_service = __esm(() => {
|
|
|
33263
33488
|
});
|
|
33264
33489
|
|
|
33265
33490
|
// ../runtime/src/provisional-agent-names-config.ts
|
|
33266
|
-
import { existsSync as
|
|
33267
|
-
import { homedir as
|
|
33268
|
-
import { isAbsolute as isAbsolute3, join as
|
|
33491
|
+
import { existsSync as existsSync23, readFileSync as readFileSync11, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
|
|
33492
|
+
import { homedir as homedir21 } from "os";
|
|
33493
|
+
import { isAbsolute as isAbsolute3, join as join26, resolve as resolve14 } from "path";
|
|
33269
33494
|
function openScoutHome() {
|
|
33270
|
-
return process.env.OPENSCOUT_HOME ??
|
|
33495
|
+
return process.env.OPENSCOUT_HOME ?? join26(homedir21(), ".openscout");
|
|
33271
33496
|
}
|
|
33272
33497
|
function defaultProvisionalAgentNamesPath() {
|
|
33273
|
-
return
|
|
33498
|
+
return join26(openScoutHome(), "provisional-agent-names.json");
|
|
33274
33499
|
}
|
|
33275
33500
|
function resolveProvisionalAgentNamesMode(config) {
|
|
33276
33501
|
return config.provisionalAgentNamesMode === "extend" ? "extend" : "replace";
|
|
@@ -33315,7 +33540,7 @@ function loadInlineProvisionalAgentNames(config) {
|
|
|
33315
33540
|
}
|
|
33316
33541
|
function loadFileProvisionalAgentNames(config = loadUserConfig()) {
|
|
33317
33542
|
const envFile = process.env.OPENSCOUT_PROVISIONAL_AGENT_NAMES_FILE?.trim();
|
|
33318
|
-
if (envFile &&
|
|
33543
|
+
if (envFile && existsSync23(envFile)) {
|
|
33319
33544
|
const names = readProvisionalAgentNamesJsonFile(envFile);
|
|
33320
33545
|
if (names.length > 0) {
|
|
33321
33546
|
return { names, source: "env-file", sourcePath: envFile };
|
|
@@ -33323,7 +33548,7 @@ function loadFileProvisionalAgentNames(config = loadUserConfig()) {
|
|
|
33323
33548
|
}
|
|
33324
33549
|
if (config.provisionalAgentNamesFile?.trim()) {
|
|
33325
33550
|
const filePath = resolvePoolFilePath(config.provisionalAgentNamesFile);
|
|
33326
|
-
if (
|
|
33551
|
+
if (existsSync23(filePath)) {
|
|
33327
33552
|
const names = readProvisionalAgentNamesJsonFile(filePath);
|
|
33328
33553
|
if (names.length > 0) {
|
|
33329
33554
|
return { names, source: "user-config-file", sourcePath: filePath };
|
|
@@ -33331,7 +33556,7 @@ function loadFileProvisionalAgentNames(config = loadUserConfig()) {
|
|
|
33331
33556
|
}
|
|
33332
33557
|
}
|
|
33333
33558
|
const homeJson = defaultProvisionalAgentNamesPath();
|
|
33334
|
-
if (
|
|
33559
|
+
if (existsSync23(homeJson)) {
|
|
33335
33560
|
const names = readProvisionalAgentNamesJsonFile(homeJson);
|
|
33336
33561
|
if (names.length > 0) {
|
|
33337
33562
|
return { names, source: "home-json", sourcePath: homeJson };
|
|
@@ -33796,7 +34021,8 @@ var init_local_agent_transports = __esm(() => {
|
|
|
33796
34021
|
"codex_app_server",
|
|
33797
34022
|
"claude_stream_json",
|
|
33798
34023
|
"pi_rpc",
|
|
33799
|
-
"grok_acp"
|
|
34024
|
+
"grok_acp",
|
|
34025
|
+
"kimi_acp"
|
|
33800
34026
|
]);
|
|
33801
34027
|
});
|
|
33802
34028
|
|
|
@@ -33955,20 +34181,20 @@ var init_openscout_discovery = __esm(() => {
|
|
|
33955
34181
|
});
|
|
33956
34182
|
|
|
33957
34183
|
// ../runtime/src/provider-telemetry-bootstrap.ts
|
|
33958
|
-
import { existsSync as
|
|
34184
|
+
import { existsSync as existsSync24 } from "fs";
|
|
33959
34185
|
import { readFile as readFile11 } from "fs/promises";
|
|
33960
|
-
import { homedir as
|
|
33961
|
-
import { join as
|
|
34186
|
+
import { homedir as homedir22 } from "os";
|
|
34187
|
+
import { join as join27 } from "path";
|
|
33962
34188
|
function resolveHomeDirectory(env) {
|
|
33963
|
-
return env.HOME?.trim() ||
|
|
34189
|
+
return env.HOME?.trim() || homedir22();
|
|
33964
34190
|
}
|
|
33965
34191
|
function resolveClaudeSettingsPath2(env) {
|
|
33966
|
-
return
|
|
34192
|
+
return join27(resolveHomeDirectory(env), ".claude", "settings.json");
|
|
33967
34193
|
}
|
|
33968
|
-
function
|
|
34194
|
+
function isRecord9(value) {
|
|
33969
34195
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
33970
34196
|
}
|
|
33971
|
-
function
|
|
34197
|
+
function stringValue11(value) {
|
|
33972
34198
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
33973
34199
|
}
|
|
33974
34200
|
function numberValue7(value) {
|
|
@@ -33979,7 +34205,7 @@ function timestampMs(value) {
|
|
|
33979
34205
|
if (numeric3 !== undefined) {
|
|
33980
34206
|
return numeric3 < 10000000000 ? numeric3 * 1000 : numeric3;
|
|
33981
34207
|
}
|
|
33982
|
-
const text3 =
|
|
34208
|
+
const text3 = stringValue11(value);
|
|
33983
34209
|
if (!text3)
|
|
33984
34210
|
return;
|
|
33985
34211
|
const parsed = Date.parse(text3);
|
|
@@ -33988,36 +34214,36 @@ function timestampMs(value) {
|
|
|
33988
34214
|
async function readJsonRecord(path) {
|
|
33989
34215
|
try {
|
|
33990
34216
|
const parsed = JSON.parse(await readFile11(path, "utf8"));
|
|
33991
|
-
return
|
|
34217
|
+
return isRecord9(parsed) ? parsed : null;
|
|
33992
34218
|
} catch {
|
|
33993
34219
|
return null;
|
|
33994
34220
|
}
|
|
33995
34221
|
}
|
|
33996
34222
|
async function readClaudeStatuslineCommand(settingsPath) {
|
|
33997
34223
|
const settings = await readJsonRecord(settingsPath);
|
|
33998
|
-
const statusLine =
|
|
33999
|
-
return
|
|
34224
|
+
const statusLine = isRecord9(settings?.statusLine) ? settings.statusLine : null;
|
|
34225
|
+
return stringValue11(statusLine?.command);
|
|
34000
34226
|
}
|
|
34001
34227
|
async function readStatuslineLatest(freshnessMs) {
|
|
34002
34228
|
const path = resolveClaudeStatuslineLatestPath();
|
|
34003
|
-
if (!
|
|
34229
|
+
if (!existsSync24(path)) {
|
|
34004
34230
|
return { path, status: "missing" };
|
|
34005
34231
|
}
|
|
34006
34232
|
const latest = await readJsonRecord(path);
|
|
34007
34233
|
if (!latest) {
|
|
34008
34234
|
return { path, status: "unreadable" };
|
|
34009
34235
|
}
|
|
34010
|
-
const workspace =
|
|
34236
|
+
const workspace = isRecord9(latest.workspace) ? latest.workspace : null;
|
|
34011
34237
|
const capturedAt = timestampMs(latest.openscoutCapturedAt) ?? timestampMs(latest.capturedAt) ?? timestampMs(latest.timestamp);
|
|
34012
34238
|
const ageMs = capturedAt === undefined ? undefined : Math.max(0, Date.now() - capturedAt);
|
|
34013
34239
|
const status = ageMs !== undefined && ageMs <= freshnessMs ? "fresh" : "stale";
|
|
34014
|
-
const cwd =
|
|
34240
|
+
const cwd = stringValue11(latest.cwd) ?? stringValue11(workspace?.current_dir);
|
|
34015
34241
|
return {
|
|
34016
34242
|
path,
|
|
34017
34243
|
status,
|
|
34018
34244
|
...capturedAt === undefined ? {} : { capturedAt },
|
|
34019
34245
|
...ageMs === undefined ? {} : { ageMs },
|
|
34020
|
-
...
|
|
34246
|
+
...stringValue11(latest.session_id) ? { sessionId: stringValue11(latest.session_id) } : {},
|
|
34021
34247
|
...cwd ? { cwd } : {}
|
|
34022
34248
|
};
|
|
34023
34249
|
}
|
|
@@ -34049,7 +34275,7 @@ async function ensureProviderTelemetryBootstrap(options = {}) {
|
|
|
34049
34275
|
statuslineLatest: await readStatuslineLatest(freshnessMs)
|
|
34050
34276
|
};
|
|
34051
34277
|
}
|
|
34052
|
-
if (!
|
|
34278
|
+
if (!existsSync24(settingsPath)) {
|
|
34053
34279
|
return {
|
|
34054
34280
|
skipped: false,
|
|
34055
34281
|
claude: {
|
|
@@ -34062,7 +34288,7 @@ async function ensureProviderTelemetryBootstrap(options = {}) {
|
|
|
34062
34288
|
};
|
|
34063
34289
|
}
|
|
34064
34290
|
const command = await readClaudeStatuslineCommand(settingsPath);
|
|
34065
|
-
const alreadyInstalled = command ? isOpenScoutClaudeStatuslineCommand(command, wrapperPath) &&
|
|
34291
|
+
const alreadyInstalled = command ? isOpenScoutClaudeStatuslineCommand(command, wrapperPath) && existsSync24(wrapperPath) : false;
|
|
34066
34292
|
const claude = alreadyInstalled ? {
|
|
34067
34293
|
settingsPath,
|
|
34068
34294
|
wrapperPath,
|
|
@@ -34083,18 +34309,18 @@ var init_provider_telemetry_bootstrap = __esm(() => {
|
|
|
34083
34309
|
});
|
|
34084
34310
|
|
|
34085
34311
|
// ../runtime/src/onboarding.ts
|
|
34086
|
-
import { existsSync as
|
|
34087
|
-
import { homedir as
|
|
34088
|
-
import { dirname as dirname17, join as
|
|
34312
|
+
import { existsSync as existsSync25 } from "fs";
|
|
34313
|
+
import { homedir as homedir23 } from "os";
|
|
34314
|
+
import { dirname as dirname17, join as join28, resolve as resolve15 } from "path";
|
|
34089
34315
|
function nowMs2() {
|
|
34090
34316
|
return Date.now();
|
|
34091
34317
|
}
|
|
34092
34318
|
function expandHomePath5(value) {
|
|
34093
34319
|
if (value === "~") {
|
|
34094
|
-
return
|
|
34320
|
+
return homedir23();
|
|
34095
34321
|
}
|
|
34096
34322
|
if (value.startsWith("~/")) {
|
|
34097
|
-
return
|
|
34323
|
+
return join28(homedir23(), value.slice(2));
|
|
34098
34324
|
}
|
|
34099
34325
|
return value;
|
|
34100
34326
|
}
|
|
@@ -34102,7 +34328,7 @@ function normalizePath2(value) {
|
|
|
34102
34328
|
return resolve15(expandHomePath5(value.trim() || "."));
|
|
34103
34329
|
}
|
|
34104
34330
|
function projectConfigPath2(projectRoot) {
|
|
34105
|
-
return
|
|
34331
|
+
return join28(projectRoot, ".openscout", "project.json");
|
|
34106
34332
|
}
|
|
34107
34333
|
function normalizeDefaultHarness(value) {
|
|
34108
34334
|
return value === "codex" ? "codex" : value === "cursor" ? "cursor" : value === "pi" ? "pi" : "claude";
|
|
@@ -34123,7 +34349,7 @@ async function nearestProjectConfig(startDirectory) {
|
|
|
34123
34349
|
let current = normalizePath2(trimmed);
|
|
34124
34350
|
while (true) {
|
|
34125
34351
|
const candidate = projectConfigPath2(current);
|
|
34126
|
-
if (
|
|
34352
|
+
if (existsSync25(candidate)) {
|
|
34127
34353
|
return {
|
|
34128
34354
|
projectRoot: current,
|
|
34129
34355
|
projectConfigPath: candidate
|
|
@@ -35039,9 +35265,9 @@ import { Database as Database2 } from "bun:sqlite";
|
|
|
35039
35265
|
import { mkdirSync as mkdirSync6, readFileSync as readFileSync12 } from "fs";
|
|
35040
35266
|
import { connect as connectHttp2 } from "http2";
|
|
35041
35267
|
import { createPrivateKey, sign as signWithKey } from "crypto";
|
|
35042
|
-
import { dirname as dirname18, join as
|
|
35268
|
+
import { dirname as dirname18, join as join29 } from "path";
|
|
35043
35269
|
function resolveControlPlaneDbPath() {
|
|
35044
|
-
return
|
|
35270
|
+
return join29(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
|
|
35045
35271
|
}
|
|
35046
35272
|
function ensureMobilePushSchema(database) {
|
|
35047
35273
|
database.exec("PRAGMA busy_timeout = 5000;");
|
|
@@ -36264,7 +36490,7 @@ function endpointTmuxTarget(endpoint) {
|
|
|
36264
36490
|
}
|
|
36265
36491
|
function endpointDebugTransport(endpoint) {
|
|
36266
36492
|
const value = endpoint.metadata?.debugTransport;
|
|
36267
|
-
if (!
|
|
36493
|
+
if (!isRecord10(value) || value.kind !== "tmux" || typeof value.sessionName !== "string" || value.sessionName.length === 0) {
|
|
36268
36494
|
return null;
|
|
36269
36495
|
}
|
|
36270
36496
|
return {
|
|
@@ -36427,7 +36653,7 @@ function nativeSessionTitle(nativeSession) {
|
|
|
36427
36653
|
function titleCase2(value) {
|
|
36428
36654
|
return value ? `${value[0]?.toUpperCase()}${value.slice(1)}` : "Native";
|
|
36429
36655
|
}
|
|
36430
|
-
function
|
|
36656
|
+
function isRecord10(value) {
|
|
36431
36657
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
36432
36658
|
}
|
|
36433
36659
|
var SCOUT_VANTAGE_PLAN_SCHEMA = "scout.vantage.plan.v1", HUDSON_VANTAGE_SETUP_KIND = "hudson.vantage.setup", HUDSON_VANTAGE_SCHEMA_VERSION = 1, NODE_WIDTH = 560, NODE_HEIGHT = 360, NODE_GAP_X = 40, NODE_GAP_Y = 40, NODES_PER_ROW = 2;
|
|
@@ -36611,7 +36837,7 @@ var init_sender = __esm(() => {
|
|
|
36611
36837
|
|
|
36612
36838
|
// ../../apps/desktop/src/core/broker/service.ts
|
|
36613
36839
|
import { mkdir as mkdir10, readFile as readFile12, unlink, writeFile as writeFile10 } from "fs/promises";
|
|
36614
|
-
import { basename as basename10, join as
|
|
36840
|
+
import { basename as basename10, join as join30, resolve as resolve16 } from "path";
|
|
36615
36841
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
36616
36842
|
function relayHubDirectory() {
|
|
36617
36843
|
return resolveOpenScoutSupportPaths().relayHubDirectory;
|
|
@@ -39431,7 +39657,7 @@ async function listScoutAgents(options = {}) {
|
|
|
39431
39657
|
}
|
|
39432
39658
|
async function loadScoutRelayConfig() {
|
|
39433
39659
|
try {
|
|
39434
|
-
const raw = await readFile12(
|
|
39660
|
+
const raw = await readFile12(join30(relayHubDirectory(), "config.json"), "utf8");
|
|
39435
39661
|
return JSON.parse(raw);
|
|
39436
39662
|
} catch {
|
|
39437
39663
|
return {};
|
|
@@ -39453,7 +39679,7 @@ function applyPronunciations(text3, pronunciations) {
|
|
|
39453
39679
|
async function acquireScoutOnAir(agent, timeoutMs = 30000) {
|
|
39454
39680
|
const hub = relayHubDirectory();
|
|
39455
39681
|
await mkdir10(hub, { recursive: true });
|
|
39456
|
-
const lockPath =
|
|
39682
|
+
const lockPath = join30(hub, "on-air.lock");
|
|
39457
39683
|
const deadline = Date.now() + timeoutMs;
|
|
39458
39684
|
while (Date.now() < deadline) {
|
|
39459
39685
|
try {
|
|
@@ -39471,7 +39697,7 @@ async function acquireScoutOnAir(agent, timeoutMs = 30000) {
|
|
|
39471
39697
|
}
|
|
39472
39698
|
async function releaseScoutOnAir() {
|
|
39473
39699
|
try {
|
|
39474
|
-
await unlink(
|
|
39700
|
+
await unlink(join30(relayHubDirectory(), "on-air.lock"));
|
|
39475
39701
|
} catch {}
|
|
39476
39702
|
}
|
|
39477
39703
|
async function speakScoutText(text3, voice) {
|
|
@@ -40116,7 +40342,7 @@ var init_ask2 = __esm(() => {
|
|
|
40116
40342
|
});
|
|
40117
40343
|
|
|
40118
40344
|
// ../../apps/desktop/src/core/broker/attention.ts
|
|
40119
|
-
import { existsSync as
|
|
40345
|
+
import { existsSync as existsSync26 } from "fs";
|
|
40120
40346
|
import { basename as basename12, resolve as resolve18 } from "path";
|
|
40121
40347
|
async function loadScoutAttentionReport(options) {
|
|
40122
40348
|
const brokerUrl = options.brokerUrl ?? resolveScoutBrokerUrl();
|
|
@@ -40333,7 +40559,7 @@ async function findGitRoot(cwd) {
|
|
|
40333
40559
|
}
|
|
40334
40560
|
async function readGitAttentionState(projectRoot) {
|
|
40335
40561
|
const normalizedRoot = resolve18(projectRoot);
|
|
40336
|
-
if (!
|
|
40562
|
+
if (!existsSync26(normalizedRoot)) {
|
|
40337
40563
|
return emptyGitState(normalizedRoot, "path does not exist");
|
|
40338
40564
|
}
|
|
40339
40565
|
const inside = await gitRevParse({ repoRoot: normalizedRoot, kind: "isInsideWorkTree" });
|
|
@@ -71138,9 +71364,9 @@ var init_runtime_service_client = __esm(() => {
|
|
|
71138
71364
|
// ../../apps/desktop/src/core/setup/command-lock.ts
|
|
71139
71365
|
import { mkdir as mkdir11, open, readFile as readFile13, rm as rm5 } from "fs/promises";
|
|
71140
71366
|
import { hostname as hostname4 } from "os";
|
|
71141
|
-
import { dirname as dirname20, join as
|
|
71367
|
+
import { dirname as dirname20, join as join31 } from "path";
|
|
71142
71368
|
function scoutCoreCommandLockPath() {
|
|
71143
|
-
return
|
|
71369
|
+
return join31(resolveOpenScoutSupportPaths().runtimeDirectory, "locks", SCOUT_CORE_COMMAND_LOCK_FILE);
|
|
71144
71370
|
}
|
|
71145
71371
|
function isProcessAlive(pid) {
|
|
71146
71372
|
if (!Number.isInteger(pid) || pid <= 0) {
|
|
@@ -71245,9 +71471,9 @@ var init_command_lock = __esm(() => {
|
|
|
71245
71471
|
|
|
71246
71472
|
// ../../apps/desktop/src/core/setup/local-edge-dependencies.ts
|
|
71247
71473
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
71248
|
-
import { existsSync as
|
|
71249
|
-
import { homedir as
|
|
71250
|
-
import { join as
|
|
71474
|
+
import { existsSync as existsSync27 } from "fs";
|
|
71475
|
+
import { homedir as homedir24 } from "os";
|
|
71476
|
+
import { join as join32 } from "path";
|
|
71251
71477
|
function defaultRunCommand2(command, args, options) {
|
|
71252
71478
|
const result = spawnSync3(command, args, options);
|
|
71253
71479
|
return {
|
|
@@ -71286,7 +71512,7 @@ function readCaddyVersion(caddyPath, runCommand) {
|
|
|
71286
71512
|
return firstNonEmptyLine(result.stdout) ?? firstNonEmptyLine(result.stderr);
|
|
71287
71513
|
}
|
|
71288
71514
|
function resolveCaddyLocalRootCertificatePath(env) {
|
|
71289
|
-
return
|
|
71515
|
+
return join32(env.HOME?.trim() || homedir24(), "Library", "Application Support", "Caddy", "pki", "authorities", "local", "root.crt");
|
|
71290
71516
|
}
|
|
71291
71517
|
function shellQuote2(value) {
|
|
71292
71518
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
@@ -71307,7 +71533,7 @@ function renderMacosTrustScript(rootCertificatePath) {
|
|
|
71307
71533
|
function inspectScoutLocalEdgeTrust(input) {
|
|
71308
71534
|
const rootCertificatePath = resolveCaddyLocalRootCertificatePath(input.env);
|
|
71309
71535
|
const trustCommand = input.platform === "darwin" ? MACOS_TRUST_COMMAND_LABEL : "caddy trust";
|
|
71310
|
-
if (!
|
|
71536
|
+
if (!existsSync27(rootCertificatePath)) {
|
|
71311
71537
|
return {
|
|
71312
71538
|
status: "unavailable",
|
|
71313
71539
|
rootCertificatePath,
|
|
@@ -71477,7 +71703,7 @@ var init_local_edge_dependencies = __esm(() => {
|
|
|
71477
71703
|
// ../../apps/desktop/src/core/setup/terminal-pty-dependencies.ts
|
|
71478
71704
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
71479
71705
|
import { createRequire as createRequire2 } from "module";
|
|
71480
|
-
import { dirname as dirname21, join as
|
|
71706
|
+
import { dirname as dirname21, join as join33 } from "path";
|
|
71481
71707
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
71482
71708
|
function renderMissingBindingDetail(bindingPackage) {
|
|
71483
71709
|
return `${bindingPackage} is not installed. Reinstall @openscout/scout and ensure optional dependencies are not disabled.`;
|
|
@@ -71504,7 +71730,7 @@ function defaultResolveModule(specifier, fromPath) {
|
|
|
71504
71730
|
}
|
|
71505
71731
|
function defaultRelayBundlePath() {
|
|
71506
71732
|
const selfDir = dirname21(fileURLToPath9(import.meta.url));
|
|
71507
|
-
return
|
|
71733
|
+
return join33(selfDir, "openscout-terminal-relay.mjs");
|
|
71508
71734
|
}
|
|
71509
71735
|
function firstNonEmptyLine2(value) {
|
|
71510
71736
|
return value.split(/\r?\n/g).map((line) => line.trim()).find(Boolean) ?? null;
|
|
@@ -71638,8 +71864,8 @@ var init_terminal_pty_dependencies = __esm(() => {
|
|
|
71638
71864
|
|
|
71639
71865
|
// ../../apps/desktop/src/core/setup/service.ts
|
|
71640
71866
|
import { lookup } from "dns/promises";
|
|
71641
|
-
import { homedir as
|
|
71642
|
-
import { join as
|
|
71867
|
+
import { homedir as homedir25 } from "os";
|
|
71868
|
+
import { join as join34 } from "path";
|
|
71643
71869
|
import { Socket as Socket3 } from "net";
|
|
71644
71870
|
async function loadScoutDoctorReport(input) {
|
|
71645
71871
|
return withScoutCoreCommandLock("doctor", async () => {
|
|
@@ -71700,7 +71926,7 @@ async function loadScoutLocalEdgeDoctorReport(env) {
|
|
|
71700
71926
|
state,
|
|
71701
71927
|
portalHost,
|
|
71702
71928
|
nodeHost: localEdgeConfig.nodeHost,
|
|
71703
|
-
caddyfilePath:
|
|
71929
|
+
caddyfilePath: join34(homedir25(), ".scout", "local-edge", "Caddyfile"),
|
|
71704
71930
|
dependency,
|
|
71705
71931
|
dns: {
|
|
71706
71932
|
portal: portalDns,
|
|
@@ -71810,12 +72036,12 @@ var init_service3 = __esm(() => {
|
|
|
71810
72036
|
});
|
|
71811
72037
|
|
|
71812
72038
|
// ../../apps/desktop/src/shared/paths.ts
|
|
71813
|
-
import { existsSync as
|
|
71814
|
-
import { dirname as dirname22, join as
|
|
72039
|
+
import { existsSync as existsSync28, readFileSync as readFileSync13 } from "fs";
|
|
72040
|
+
import { dirname as dirname22, join as join35, resolve as resolve22 } from "path";
|
|
71815
72041
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
71816
72042
|
function looksLikeWorkspaceRoot(candidate) {
|
|
71817
|
-
const packageJsonPath =
|
|
71818
|
-
if (!
|
|
72043
|
+
const packageJsonPath = join35(candidate, "package.json");
|
|
72044
|
+
if (!existsSync28(packageJsonPath)) {
|
|
71819
72045
|
return false;
|
|
71820
72046
|
}
|
|
71821
72047
|
try {
|
|
@@ -71826,8 +72052,8 @@ function looksLikeWorkspaceRoot(candidate) {
|
|
|
71826
72052
|
}
|
|
71827
72053
|
}
|
|
71828
72054
|
function looksLikePackagedAppRoot(candidate) {
|
|
71829
|
-
const packageJsonPath =
|
|
71830
|
-
if (!
|
|
72055
|
+
const packageJsonPath = join35(candidate, "package.json");
|
|
72056
|
+
if (!existsSync28(packageJsonPath)) {
|
|
71831
72057
|
return false;
|
|
71832
72058
|
}
|
|
71833
72059
|
try {
|
|
@@ -71838,7 +72064,7 @@ function looksLikePackagedAppRoot(candidate) {
|
|
|
71838
72064
|
}
|
|
71839
72065
|
}
|
|
71840
72066
|
function looksLikeSourceAppRoot(candidate) {
|
|
71841
|
-
return
|
|
72067
|
+
return existsSync28(join35(candidate, "bin", "scout.ts"));
|
|
71842
72068
|
}
|
|
71843
72069
|
function findMatchingAncestor(startDirectory, predicate) {
|
|
71844
72070
|
let current = resolve22(startDirectory);
|
|
@@ -71911,17 +72137,17 @@ function shouldRestartBrokerForCliMtime(currentMtimeMs, persistedMtimeMs) {
|
|
|
71911
72137
|
function shouldEnsureBrokerUptodateForCommand(command) {
|
|
71912
72138
|
return command !== "mcp" && command !== "statusline";
|
|
71913
72139
|
}
|
|
71914
|
-
function
|
|
72140
|
+
function isRecord11(value) {
|
|
71915
72141
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
71916
72142
|
}
|
|
71917
72143
|
function readNonEmptyString(value) {
|
|
71918
72144
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
71919
72145
|
}
|
|
71920
|
-
function
|
|
72146
|
+
function firstNonEmptyString3(values) {
|
|
71921
72147
|
for (const value of values) {
|
|
71922
|
-
const
|
|
71923
|
-
if (
|
|
71924
|
-
return
|
|
72148
|
+
const stringValue12 = readNonEmptyString(value);
|
|
72149
|
+
if (stringValue12) {
|
|
72150
|
+
return stringValue12;
|
|
71925
72151
|
}
|
|
71926
72152
|
}
|
|
71927
72153
|
return null;
|
|
@@ -71942,26 +72168,26 @@ function buildIdentityHasAnyValue(identity) {
|
|
|
71942
72168
|
return Boolean(identity.display || buildIdentityHasComparableValue(identity));
|
|
71943
72169
|
}
|
|
71944
72170
|
function readBuildIdentityRecord(record4) {
|
|
71945
|
-
const packageName =
|
|
71946
|
-
const version3 =
|
|
72171
|
+
const packageName = firstNonEmptyString3([record4.packageName, record4.name]);
|
|
72172
|
+
const version3 = firstNonEmptyString3([
|
|
71947
72173
|
record4.version,
|
|
71948
72174
|
record4.appVersion,
|
|
71949
72175
|
record4.runtimeVersion,
|
|
71950
72176
|
record4.cliVersion,
|
|
71951
72177
|
record4.scoutVersion
|
|
71952
72178
|
]);
|
|
71953
|
-
const commit =
|
|
72179
|
+
const commit = firstNonEmptyString3([
|
|
71954
72180
|
record4.commit,
|
|
71955
72181
|
record4.gitSha,
|
|
71956
72182
|
record4.gitSHA,
|
|
71957
72183
|
record4.sha
|
|
71958
72184
|
]);
|
|
71959
|
-
const buildId =
|
|
72185
|
+
const buildId = firstNonEmptyString3([
|
|
71960
72186
|
record4.buildId,
|
|
71961
72187
|
record4.buildID,
|
|
71962
72188
|
record4.id
|
|
71963
72189
|
]);
|
|
71964
|
-
const display =
|
|
72190
|
+
const display = firstNonEmptyString3([
|
|
71965
72191
|
record4.identity,
|
|
71966
72192
|
record4.buildIdentity,
|
|
71967
72193
|
record4.runtimeBuild,
|
|
@@ -71987,7 +72213,7 @@ function readBuildIdentity(value) {
|
|
|
71987
72213
|
version: direct
|
|
71988
72214
|
};
|
|
71989
72215
|
}
|
|
71990
|
-
if (
|
|
72216
|
+
if (isRecord11(value)) {
|
|
71991
72217
|
return readBuildIdentityRecord(value);
|
|
71992
72218
|
}
|
|
71993
72219
|
return emptyBuildIdentity();
|
|
@@ -72002,9 +72228,9 @@ function mergeBuildIdentity(primary, fallback) {
|
|
|
72002
72228
|
};
|
|
72003
72229
|
}
|
|
72004
72230
|
function extractBuildIdentityFromRecord(record4) {
|
|
72005
|
-
const healthRecord =
|
|
72006
|
-
const statusRecord =
|
|
72007
|
-
const healthBuild = healthRecord &&
|
|
72231
|
+
const healthRecord = isRecord11(record4.health) ? record4.health : null;
|
|
72232
|
+
const statusRecord = isRecord11(record4.status) ? record4.status : null;
|
|
72233
|
+
const healthBuild = healthRecord && isRecord11(healthRecord.build) ? readBuildIdentityRecord(healthRecord.build) : null;
|
|
72008
72234
|
if (healthBuild && buildIdentityHasAnyValue(healthBuild)) {
|
|
72009
72235
|
return healthBuild;
|
|
72010
72236
|
}
|
|
@@ -72020,7 +72246,7 @@ function extractBuildIdentityFromRecord(record4) {
|
|
|
72020
72246
|
return buildIdentityHasAnyValue(merged) ? merged : emptyBuildIdentity();
|
|
72021
72247
|
}
|
|
72022
72248
|
function extractBuildIdentityPartsFromScoutdPayload(payload) {
|
|
72023
|
-
if (!
|
|
72249
|
+
if (!isRecord11(payload)) {
|
|
72024
72250
|
return emptyBuildIdentity();
|
|
72025
72251
|
}
|
|
72026
72252
|
return extractBuildIdentityFromRecord(payload);
|
|
@@ -72029,14 +72255,14 @@ function extractBuildIdentityFromScoutdPayload(payload) {
|
|
|
72029
72255
|
return extractBuildIdentityPartsFromScoutdPayload(payload).display;
|
|
72030
72256
|
}
|
|
72031
72257
|
function resolveCurrentCliBuildIdentityParts(env, fallbackVersion) {
|
|
72032
|
-
const buildId =
|
|
72033
|
-
const commit =
|
|
72258
|
+
const buildId = firstNonEmptyString3([env.OPENSCOUT_BUILD_ID, env.SCOUT_BUILD_ID]);
|
|
72259
|
+
const commit = firstNonEmptyString3([
|
|
72034
72260
|
env.OPENSCOUT_BUILD_COMMIT,
|
|
72035
72261
|
env.OPENSCOUT_BUILD_SHA,
|
|
72036
72262
|
env.GIT_COMMIT,
|
|
72037
72263
|
env.GIT_SHA
|
|
72038
72264
|
]);
|
|
72039
|
-
const version3 =
|
|
72265
|
+
const version3 = firstNonEmptyString3([
|
|
72040
72266
|
env.SCOUT_APP_VERSION,
|
|
72041
72267
|
env.OPENSCOUT_VERSION,
|
|
72042
72268
|
env.npm_package_version,
|
|
@@ -72218,7 +72444,7 @@ async function runNativeScoutdJson(command, options = {}) {
|
|
|
72218
72444
|
});
|
|
72219
72445
|
});
|
|
72220
72446
|
}
|
|
72221
|
-
function
|
|
72447
|
+
function isRecord12(value) {
|
|
72222
72448
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
72223
72449
|
}
|
|
72224
72450
|
function hasOwn(record4, key) {
|
|
@@ -72237,7 +72463,7 @@ function diagnosticText(value) {
|
|
|
72237
72463
|
const direct = readString5(value);
|
|
72238
72464
|
if (direct)
|
|
72239
72465
|
return direct;
|
|
72240
|
-
if (
|
|
72466
|
+
if (isRecord12(value)) {
|
|
72241
72467
|
const message = readString5(value.message) ?? readString5(value.detail) ?? readString5(value.title) ?? readString5(value.id);
|
|
72242
72468
|
if (message)
|
|
72243
72469
|
return message;
|
|
@@ -72259,7 +72485,7 @@ function readProcesses(value) {
|
|
|
72259
72485
|
return [];
|
|
72260
72486
|
}
|
|
72261
72487
|
return value.flatMap((entry) => {
|
|
72262
|
-
if (!
|
|
72488
|
+
if (!isRecord12(entry)) {
|
|
72263
72489
|
return [];
|
|
72264
72490
|
}
|
|
72265
72491
|
const command = readString5(entry.command);
|
|
@@ -72287,7 +72513,7 @@ function normalizeFixEntry(value, fallbackId = null) {
|
|
|
72287
72513
|
changed: null
|
|
72288
72514
|
};
|
|
72289
72515
|
}
|
|
72290
|
-
if (!
|
|
72516
|
+
if (!isRecord12(value)) {
|
|
72291
72517
|
return null;
|
|
72292
72518
|
}
|
|
72293
72519
|
const id = readString5(value.id) ?? fallbackId;
|
|
@@ -72306,13 +72532,13 @@ function readFixEntries(value) {
|
|
|
72306
72532
|
if (Array.isArray(value)) {
|
|
72307
72533
|
return value.map((entry) => normalizeFixEntry(entry)).filter((entry) => Boolean(entry));
|
|
72308
72534
|
}
|
|
72309
|
-
if (!
|
|
72535
|
+
if (!isRecord12(value)) {
|
|
72310
72536
|
return [];
|
|
72311
72537
|
}
|
|
72312
72538
|
return Object.entries(value).map(([key, entry]) => normalizeFixEntry(entry, key)).filter((entry) => Boolean(entry));
|
|
72313
72539
|
}
|
|
72314
72540
|
function readFixReport(raw) {
|
|
72315
|
-
if (!
|
|
72541
|
+
if (!isRecord12(raw)) {
|
|
72316
72542
|
return { supported: false, entries: [], raw: null };
|
|
72317
72543
|
}
|
|
72318
72544
|
for (const key of ["fixes", "repairs", "repairActions", "actions"]) {
|
|
@@ -72326,7 +72552,7 @@ function readFixReport(raw) {
|
|
|
72326
72552
|
}
|
|
72327
72553
|
if (hasOwn(raw, "fix")) {
|
|
72328
72554
|
const fix = raw.fix;
|
|
72329
|
-
if (
|
|
72555
|
+
if (isRecord12(fix)) {
|
|
72330
72556
|
const entries = readFixEntries(fix.actions).concat(readFixEntries(fix.fixes)).concat(readFixEntries(fix.repairs));
|
|
72331
72557
|
return {
|
|
72332
72558
|
supported: readBoolean2(fix.supported) ?? true,
|
|
@@ -72343,11 +72569,12 @@ function readFixReport(raw) {
|
|
|
72343
72569
|
return { supported: false, entries: [], raw: null };
|
|
72344
72570
|
}
|
|
72345
72571
|
function readStatus(raw) {
|
|
72346
|
-
if (!
|
|
72572
|
+
if (!isRecord12(raw)) {
|
|
72347
72573
|
return null;
|
|
72348
72574
|
}
|
|
72349
|
-
const status =
|
|
72350
|
-
const health =
|
|
72575
|
+
const status = isRecord12(raw.status) ? raw.status : raw;
|
|
72576
|
+
const health = isRecord12(status.health) ? status.health : {};
|
|
72577
|
+
const runtimeFreshness = isRecord12(status.runtimeFreshness) ? status.runtimeFreshness : null;
|
|
72351
72578
|
return {
|
|
72352
72579
|
label: readString5(status.label),
|
|
72353
72580
|
loaded: readBoolean2(status.loaded),
|
|
@@ -72360,20 +72587,26 @@ function readStatus(raw) {
|
|
|
72360
72587
|
healthError: readString5(health.error),
|
|
72361
72588
|
brokerUrl: readString5(status.brokerUrl),
|
|
72362
72589
|
brokerSocketPath: readString5(status.brokerSocketPath),
|
|
72363
|
-
scoutdStatePath: readString5(status.scoutdStatePath)
|
|
72590
|
+
scoutdStatePath: readString5(status.scoutdStatePath),
|
|
72591
|
+
runtimeFreshness: runtimeFreshness && readString5(runtimeFreshness.state) ? {
|
|
72592
|
+
state: readString5(runtimeFreshness.state),
|
|
72593
|
+
intentional: readBoolean2(runtimeFreshness.intentional),
|
|
72594
|
+
basis: readString5(runtimeFreshness.basis),
|
|
72595
|
+
detail: readString5(runtimeFreshness.detail)
|
|
72596
|
+
} : null
|
|
72364
72597
|
};
|
|
72365
72598
|
}
|
|
72366
72599
|
function readProbeStatus(raw) {
|
|
72367
|
-
if (!
|
|
72600
|
+
if (!isRecord12(raw)) {
|
|
72368
72601
|
return null;
|
|
72369
72602
|
}
|
|
72370
|
-
const status =
|
|
72371
|
-
const probes =
|
|
72603
|
+
const status = isRecord12(raw.status) ? raw.status : raw;
|
|
72604
|
+
const probes = isRecord12(status.probes) ? status.probes : isRecord12(raw.probes) ? raw.probes : null;
|
|
72372
72605
|
if (!probes) {
|
|
72373
72606
|
return null;
|
|
72374
72607
|
}
|
|
72375
72608
|
const families = Array.isArray(probes.families) ? probes.families.flatMap((entry) => {
|
|
72376
|
-
if (!
|
|
72609
|
+
if (!isRecord12(entry))
|
|
72377
72610
|
return [];
|
|
72378
72611
|
const probeId = readString5(entry.probeId);
|
|
72379
72612
|
if (!probeId)
|
|
@@ -72395,7 +72628,7 @@ function readProbeStatus(raw) {
|
|
|
72395
72628
|
}
|
|
72396
72629
|
function normalizeNativeScoutdDoctorReport(input) {
|
|
72397
72630
|
const raw = input.raw;
|
|
72398
|
-
const record4 =
|
|
72631
|
+
const record4 = isRecord12(raw) ? raw : {};
|
|
72399
72632
|
return {
|
|
72400
72633
|
available: input.available ?? true,
|
|
72401
72634
|
scoutdPath: input.scoutdPath,
|
|
@@ -72506,6 +72739,12 @@ function renderNativeScoutdDoctorSection(report) {
|
|
|
72506
72739
|
if (status.scoutdStatePath) {
|
|
72507
72740
|
lines.push(` State file: ${status.scoutdStatePath}`);
|
|
72508
72741
|
}
|
|
72742
|
+
if (status.runtimeFreshness) {
|
|
72743
|
+
lines.push(` Runtime freshness: ${status.runtimeFreshness.state}${status.runtimeFreshness.intentional ? " (intentional)" : ""}`);
|
|
72744
|
+
if (status.runtimeFreshness.detail) {
|
|
72745
|
+
lines.push(` Runtime detail: ${status.runtimeFreshness.detail}`);
|
|
72746
|
+
}
|
|
72747
|
+
}
|
|
72509
72748
|
}
|
|
72510
72749
|
if (report.probes) {
|
|
72511
72750
|
lines.push(" Probes:", ` Socket: ${report.probes.socketPath ?? "-"}`, ` Reachable: ${yesNo(report.probes.reachable)}`, ` Daemon version: ${report.probes.daemonVersion ?? "-"}`);
|
|
@@ -72972,8 +73211,8 @@ var exports_env = {};
|
|
|
72972
73211
|
__export(exports_env, {
|
|
72973
73212
|
runEnvCommand: () => runEnvCommand
|
|
72974
73213
|
});
|
|
72975
|
-
import { existsSync as
|
|
72976
|
-
import { join as
|
|
73214
|
+
import { existsSync as existsSync29 } from "fs";
|
|
73215
|
+
import { join as join36 } from "path";
|
|
72977
73216
|
function resolveCommandOnPath(command, env) {
|
|
72978
73217
|
const pathValue = env.PATH ?? "";
|
|
72979
73218
|
for (const directory of pathValue.split(":")) {
|
|
@@ -72981,8 +73220,8 @@ function resolveCommandOnPath(command, env) {
|
|
|
72981
73220
|
if (!trimmed) {
|
|
72982
73221
|
continue;
|
|
72983
73222
|
}
|
|
72984
|
-
const candidate =
|
|
72985
|
-
if (
|
|
73223
|
+
const candidate = join36(trimmed, command);
|
|
73224
|
+
if (existsSync29(candidate)) {
|
|
72986
73225
|
return candidate;
|
|
72987
73226
|
}
|
|
72988
73227
|
}
|
|
@@ -72990,11 +73229,11 @@ function resolveCommandOnPath(command, env) {
|
|
|
72990
73229
|
}
|
|
72991
73230
|
function resolveScoutBinPath(appRoot) {
|
|
72992
73231
|
const candidates = [
|
|
72993
|
-
|
|
72994
|
-
|
|
73232
|
+
join36(appRoot, "bin", "scout.ts"),
|
|
73233
|
+
join36(appRoot, "bin", "scout.mjs")
|
|
72995
73234
|
];
|
|
72996
73235
|
for (const candidate of candidates) {
|
|
72997
|
-
if (
|
|
73236
|
+
if (existsSync29(candidate)) {
|
|
72998
73237
|
return candidate;
|
|
72999
73238
|
}
|
|
73000
73239
|
}
|
|
@@ -73531,9 +73770,9 @@ __export(exports_install, {
|
|
|
73531
73770
|
findAppDmgAsset: () => findAppDmgAsset
|
|
73532
73771
|
});
|
|
73533
73772
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
73534
|
-
import { existsSync as
|
|
73773
|
+
import { existsSync as existsSync30, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
73535
73774
|
import { tmpdir } from "os";
|
|
73536
|
-
import { join as
|
|
73775
|
+
import { join as join37 } from "path";
|
|
73537
73776
|
function renderInstallCommandHelp() {
|
|
73538
73777
|
return [
|
|
73539
73778
|
"scout install \u2014 download and install the OpenScout macOS app",
|
|
@@ -73612,7 +73851,7 @@ function formatBytes(bytes) {
|
|
|
73612
73851
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
73613
73852
|
}
|
|
73614
73853
|
function getInstalledVersion() {
|
|
73615
|
-
if (!
|
|
73854
|
+
if (!existsSync30(INFO_PLIST_PATH))
|
|
73616
73855
|
return null;
|
|
73617
73856
|
const result = spawnSync5("defaults", ["read", INFO_PLIST_PATH, "CFBundleShortVersionString"], { encoding: "utf8" });
|
|
73618
73857
|
if ((result.status ?? 1) !== 0)
|
|
@@ -73690,8 +73929,8 @@ function copyAppFromMount(mountPoint) {
|
|
|
73690
73929
|
if (!appEntry) {
|
|
73691
73930
|
throw new ScoutCliError(`no ${APP_NAME} found in the mounted DMG at ${mountPoint}`);
|
|
73692
73931
|
}
|
|
73693
|
-
const source =
|
|
73694
|
-
if (
|
|
73932
|
+
const source = join37(mountPoint, appEntry);
|
|
73933
|
+
if (existsSync30(APP_PATH)) {
|
|
73695
73934
|
const removed = spawnSync5("rm", ["-rf", APP_PATH], { encoding: "utf8" });
|
|
73696
73935
|
if ((removed.status ?? 1) !== 0) {
|
|
73697
73936
|
throw new ScoutCliError(`could not replace ${APP_PATH} (permission denied?). Try: sudo scout install`);
|
|
@@ -73779,8 +74018,8 @@ async function runInstallCommand(context, args) {
|
|
|
73779
74018
|
}
|
|
73780
74019
|
const asset = findAppDmgAsset(release);
|
|
73781
74020
|
const wasRunning = isAppRunning();
|
|
73782
|
-
const workDir = mkdtempSync(
|
|
73783
|
-
const dmgPath =
|
|
74021
|
+
const workDir = mkdtempSync(join37(tmpdir(), "scout-install-"));
|
|
74022
|
+
const dmgPath = join37(workDir, asset.name);
|
|
73784
74023
|
let mountPoint = null;
|
|
73785
74024
|
try {
|
|
73786
74025
|
await downloadDmg(asset, dmgPath, context);
|
|
@@ -81074,9 +81313,9 @@ var init_scout_mcp = __esm(() => {
|
|
|
81074
81313
|
|
|
81075
81314
|
// ../../apps/desktop/src/cli/commands/mcp-install.ts
|
|
81076
81315
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
81077
|
-
import { accessSync as accessSync4, constants as constants4, existsSync as
|
|
81078
|
-
import { homedir as
|
|
81079
|
-
import { delimiter as delimiter4, join as
|
|
81316
|
+
import { accessSync as accessSync4, constants as constants4, existsSync as existsSync31 } from "fs";
|
|
81317
|
+
import { homedir as homedir26 } from "os";
|
|
81318
|
+
import { delimiter as delimiter4, join as join38, resolve as resolve24 } from "path";
|
|
81080
81319
|
function isExecutable3(filePath) {
|
|
81081
81320
|
if (!filePath) {
|
|
81082
81321
|
return false;
|
|
@@ -81091,15 +81330,15 @@ function isExecutable3(filePath) {
|
|
|
81091
81330
|
function resolveExecutableFromSearchPath2(names, env) {
|
|
81092
81331
|
const pathEntries = (env.PATH ?? "").split(delimiter4).filter(Boolean);
|
|
81093
81332
|
const commonDirectories = [
|
|
81094
|
-
|
|
81095
|
-
|
|
81333
|
+
join38(homedir26(), ".local", "bin"),
|
|
81334
|
+
join38(homedir26(), ".bun", "bin"),
|
|
81096
81335
|
"/opt/homebrew/bin",
|
|
81097
81336
|
"/usr/local/bin",
|
|
81098
81337
|
"/Applications/Codex.app/Contents/Resources"
|
|
81099
81338
|
];
|
|
81100
81339
|
for (const directory of [...pathEntries, ...commonDirectories]) {
|
|
81101
81340
|
for (const name of names) {
|
|
81102
|
-
const candidate =
|
|
81341
|
+
const candidate = join38(directory, name);
|
|
81103
81342
|
if (isExecutable3(candidate)) {
|
|
81104
81343
|
return candidate;
|
|
81105
81344
|
}
|
|
@@ -81115,7 +81354,7 @@ function resolveHostExecutable(host, env) {
|
|
|
81115
81354
|
}
|
|
81116
81355
|
function resolveCurrentScoutMcpLaunchCommand(env) {
|
|
81117
81356
|
const currentScript = process.argv[1];
|
|
81118
|
-
if (currentScript &&
|
|
81357
|
+
if (currentScript && existsSync31(currentScript) && isExecutable3(process.execPath)) {
|
|
81119
81358
|
return {
|
|
81120
81359
|
command: process.execPath,
|
|
81121
81360
|
args: [resolve24(currentScript), "mcp"]
|
|
@@ -81486,9 +81725,9 @@ __export(exports_menu, {
|
|
|
81486
81725
|
parseMenuCommand: () => parseMenuCommand
|
|
81487
81726
|
});
|
|
81488
81727
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
81489
|
-
import { existsSync as
|
|
81490
|
-
import { homedir as
|
|
81491
|
-
import { dirname as dirname23, join as
|
|
81728
|
+
import { existsSync as existsSync32 } from "fs";
|
|
81729
|
+
import { homedir as homedir27 } from "os";
|
|
81730
|
+
import { dirname as dirname23, join as join39, resolve as resolve25 } from "path";
|
|
81492
81731
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
81493
81732
|
function renderMenuCommandHelp() {
|
|
81494
81733
|
return [
|
|
@@ -81575,8 +81814,8 @@ function runProcess(command, args, options) {
|
|
|
81575
81814
|
function findRepoMenuHelper(startDirectory) {
|
|
81576
81815
|
let current = resolve25(startDirectory);
|
|
81577
81816
|
while (true) {
|
|
81578
|
-
const candidate =
|
|
81579
|
-
if (
|
|
81817
|
+
const candidate = join39(current, "apps", "macos", "bin", "openscout-menu.ts");
|
|
81818
|
+
if (existsSync32(candidate)) {
|
|
81580
81819
|
return candidate;
|
|
81581
81820
|
}
|
|
81582
81821
|
const parent = dirname23(current);
|
|
@@ -81586,7 +81825,7 @@ function findRepoMenuHelper(startDirectory) {
|
|
|
81586
81825
|
current = parent;
|
|
81587
81826
|
}
|
|
81588
81827
|
const sourceRelativeCandidate = fileURLToPath11(new URL("../../../../macos/bin/openscout-menu.ts", import.meta.url).toString());
|
|
81589
|
-
return
|
|
81828
|
+
return existsSync32(sourceRelativeCandidate) ? sourceRelativeCandidate : null;
|
|
81590
81829
|
}
|
|
81591
81830
|
function resolveRepoBundlePath(helperPath) {
|
|
81592
81831
|
return resolve25(dirname23(helperPath), "..", "dist", MENU_BUNDLE_NAME);
|
|
@@ -81605,14 +81844,14 @@ function resolveInstalledAppBundlePath(env) {
|
|
|
81605
81844
|
return indexedPath;
|
|
81606
81845
|
}
|
|
81607
81846
|
for (const candidate of COMMON_APP_BUNDLE_PATHS) {
|
|
81608
|
-
if (
|
|
81847
|
+
if (existsSync32(candidate)) {
|
|
81609
81848
|
return candidate;
|
|
81610
81849
|
}
|
|
81611
81850
|
}
|
|
81612
81851
|
return null;
|
|
81613
81852
|
}
|
|
81614
81853
|
function resolveEmbeddedMenuBundlePath(appBundlePath) {
|
|
81615
|
-
return
|
|
81854
|
+
return join39(appBundlePath, EMBEDDED_MENU_RELATIVE_PATH);
|
|
81616
81855
|
}
|
|
81617
81856
|
function openInstalledMenuApp(helperPath, env) {
|
|
81618
81857
|
const bundleAttempts = [
|
|
@@ -81688,7 +81927,7 @@ function runWithRepoHelper(context, helperPath, command) {
|
|
|
81688
81927
|
});
|
|
81689
81928
|
const bundlePath = resolveRepoBundlePath(helperPath);
|
|
81690
81929
|
const running = command.action === "quit" ? false : isMenuRunning(context.env);
|
|
81691
|
-
const installed =
|
|
81930
|
+
const installed = existsSync32(bundlePath) || running;
|
|
81692
81931
|
return {
|
|
81693
81932
|
action: command.action,
|
|
81694
81933
|
mode: "repo-helper",
|
|
@@ -81759,11 +81998,11 @@ var init_menu = __esm(() => {
|
|
|
81759
81998
|
init_src3();
|
|
81760
81999
|
init_context();
|
|
81761
82000
|
init_errors();
|
|
81762
|
-
EMBEDDED_MENU_RELATIVE_PATH =
|
|
82001
|
+
EMBEDDED_MENU_RELATIVE_PATH = join39("Contents", "Library", "LoginItems", "ScoutMenu.app");
|
|
81763
82002
|
HELP_FLAGS11 = new Set(["help", "--help", "-h"]);
|
|
81764
82003
|
COMMON_APP_BUNDLE_PATHS = [
|
|
81765
|
-
|
|
81766
|
-
|
|
82004
|
+
join39("/Applications", APP_BUNDLE_NAME),
|
|
82005
|
+
join39(homedir27(), "Applications", APP_BUNDLE_NAME)
|
|
81767
82006
|
];
|
|
81768
82007
|
});
|
|
81769
82008
|
|
|
@@ -82201,11 +82440,11 @@ var init_mesh = __esm(() => {
|
|
|
82201
82440
|
});
|
|
82202
82441
|
|
|
82203
82442
|
// ../../apps/desktop/src/core/pairing/runtime/config.ts
|
|
82204
|
-
import { existsSync as
|
|
82205
|
-
import { homedir as
|
|
82443
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
|
|
82444
|
+
import { homedir as homedir28 } from "os";
|
|
82206
82445
|
import path from "path";
|
|
82207
82446
|
function pairingPaths() {
|
|
82208
|
-
const rootDir = path.join(
|
|
82447
|
+
const rootDir = path.join(homedir28(), ".scout/pairing");
|
|
82209
82448
|
return {
|
|
82210
82449
|
rootDir,
|
|
82211
82450
|
configPath: path.join(rootDir, "config.json"),
|
|
@@ -82218,7 +82457,7 @@ function pairingPaths() {
|
|
|
82218
82457
|
}
|
|
82219
82458
|
function loadPairingConfig() {
|
|
82220
82459
|
const { configPath } = pairingPaths();
|
|
82221
|
-
if (!
|
|
82460
|
+
if (!existsSync33(configPath)) {
|
|
82222
82461
|
return {};
|
|
82223
82462
|
}
|
|
82224
82463
|
try {
|
|
@@ -84322,11 +84561,11 @@ var init_noise = __esm(() => {
|
|
|
84322
84561
|
});
|
|
84323
84562
|
|
|
84324
84563
|
// ../../apps/desktop/src/core/pairing/runtime/security/identity.ts
|
|
84325
|
-
import { existsSync as
|
|
84326
|
-
import { join as
|
|
84327
|
-
import { homedir as
|
|
84564
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
|
|
84565
|
+
import { join as join40 } from "path";
|
|
84566
|
+
import { homedir as homedir29 } from "os";
|
|
84328
84567
|
function loadOrCreateIdentity() {
|
|
84329
|
-
if (
|
|
84568
|
+
if (existsSync34(IDENTITY_FILE)) {
|
|
84330
84569
|
return loadIdentity();
|
|
84331
84570
|
}
|
|
84332
84571
|
return createAndSaveIdentity();
|
|
@@ -84350,7 +84589,7 @@ function createAndSaveIdentity() {
|
|
|
84350
84589
|
return keyPair;
|
|
84351
84590
|
}
|
|
84352
84591
|
function loadTrustedPeers() {
|
|
84353
|
-
if (!
|
|
84592
|
+
if (!existsSync34(TRUSTED_PEERS_FILE))
|
|
84354
84593
|
return new Map;
|
|
84355
84594
|
const data = JSON.parse(readFileSync16(TRUSTED_PEERS_FILE, "utf8"));
|
|
84356
84595
|
return new Map(data.map((p) => [p.publicKey, p]));
|
|
@@ -84401,9 +84640,9 @@ function hexToBytes2(hex3) {
|
|
|
84401
84640
|
var PAIRING_DIR, IDENTITY_FILE, TRUSTED_PEERS_FILE, QR_VERSION = 1, QR_EXPIRY_MS;
|
|
84402
84641
|
var init_identity = __esm(() => {
|
|
84403
84642
|
init_noise();
|
|
84404
|
-
PAIRING_DIR =
|
|
84405
|
-
IDENTITY_FILE =
|
|
84406
|
-
TRUSTED_PEERS_FILE =
|
|
84643
|
+
PAIRING_DIR = join40(homedir29(), ".scout/pairing");
|
|
84644
|
+
IDENTITY_FILE = join40(PAIRING_DIR, "identity.json");
|
|
84645
|
+
TRUSTED_PEERS_FILE = join40(PAIRING_DIR, "trusted-peers.json");
|
|
84407
84646
|
QR_EXPIRY_MS = 5 * 60 * 1000;
|
|
84408
84647
|
});
|
|
84409
84648
|
|
|
@@ -84564,10 +84803,10 @@ var init_security2 = __esm(() => {
|
|
|
84564
84803
|
});
|
|
84565
84804
|
|
|
84566
84805
|
// ../../apps/desktop/src/core/pairing/runtime/runtime-state.ts
|
|
84567
|
-
import { existsSync as
|
|
84806
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync17, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync8 } from "fs";
|
|
84568
84807
|
function readPairingRuntimeSnapshot() {
|
|
84569
84808
|
const { runtimeStatePath } = pairingPaths();
|
|
84570
|
-
if (!
|
|
84809
|
+
if (!existsSync35(runtimeStatePath)) {
|
|
84571
84810
|
return null;
|
|
84572
84811
|
}
|
|
84573
84812
|
try {
|
|
@@ -84595,8 +84834,8 @@ var init_runtime_state = __esm(() => {
|
|
|
84595
84834
|
|
|
84596
84835
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/log.ts
|
|
84597
84836
|
import { appendFileSync, mkdirSync as mkdirSync10 } from "fs";
|
|
84598
|
-
import { join as
|
|
84599
|
-
import { homedir as
|
|
84837
|
+
import { join as join41 } from "path";
|
|
84838
|
+
import { homedir as homedir30 } from "os";
|
|
84600
84839
|
function write(level, category, message, data) {
|
|
84601
84840
|
const ts = new Date().toISOString().slice(11, 23);
|
|
84602
84841
|
const lvl = level.toUpperCase().padEnd(5);
|
|
@@ -84612,8 +84851,8 @@ function write(level, category, message, data) {
|
|
|
84612
84851
|
}
|
|
84613
84852
|
var LOG_DIR, LOG_FILE, log;
|
|
84614
84853
|
var init_log = __esm(() => {
|
|
84615
|
-
LOG_DIR =
|
|
84616
|
-
LOG_FILE =
|
|
84854
|
+
LOG_DIR = join41(homedir30(), ".scout/pairing");
|
|
84855
|
+
LOG_FILE = join41(LOG_DIR, "bridge.log");
|
|
84617
84856
|
mkdirSync10(LOG_DIR, { recursive: true });
|
|
84618
84857
|
log = {
|
|
84619
84858
|
debug: (cat, msg, data) => write("debug", cat, msg, data),
|
|
@@ -84689,11 +84928,11 @@ var init_bridge = __esm(() => {
|
|
|
84689
84928
|
});
|
|
84690
84929
|
|
|
84691
84930
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/config.ts
|
|
84692
|
-
import { existsSync as
|
|
84693
|
-
import { join as
|
|
84694
|
-
import { homedir as
|
|
84931
|
+
import { existsSync as existsSync36, readFileSync as readFileSync18 } from "fs";
|
|
84932
|
+
import { join as join42 } from "path";
|
|
84933
|
+
import { homedir as homedir31 } from "os";
|
|
84695
84934
|
function loadConfigFile() {
|
|
84696
|
-
if (!
|
|
84935
|
+
if (!existsSync36(CONFIG_FILE)) {
|
|
84697
84936
|
return {};
|
|
84698
84937
|
}
|
|
84699
84938
|
try {
|
|
@@ -84767,8 +85006,8 @@ var init_config3 = __esm(() => {
|
|
|
84767
85006
|
port: 43130,
|
|
84768
85007
|
secure: true
|
|
84769
85008
|
};
|
|
84770
|
-
CONFIG_DIR =
|
|
84771
|
-
CONFIG_FILE =
|
|
85009
|
+
CONFIG_DIR = join42(homedir31(), ".scout/pairing");
|
|
85010
|
+
CONFIG_FILE = join42(CONFIG_DIR, "config.json");
|
|
84772
85011
|
});
|
|
84773
85012
|
|
|
84774
85013
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/web-handoff.ts
|
|
@@ -84836,9 +85075,9 @@ var init_web_handoff = __esm(() => {
|
|
|
84836
85075
|
|
|
84837
85076
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/fileserver.ts
|
|
84838
85077
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
84839
|
-
import { existsSync as
|
|
84840
|
-
import { isAbsolute as isAbsolute4, join as
|
|
84841
|
-
import { homedir as
|
|
85078
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
85079
|
+
import { isAbsolute as isAbsolute4, join as join43 } from "path";
|
|
85080
|
+
import { homedir as homedir32 } from "os";
|
|
84842
85081
|
function pairingFileServerOrigin(port, host = "127.0.0.1") {
|
|
84843
85082
|
return `http://${host}:${port}`;
|
|
84844
85083
|
}
|
|
@@ -84857,7 +85096,7 @@ function storePairingAttachmentBlob(input, options) {
|
|
|
84857
85096
|
mkdirSync11(PAIRING_ATTACHMENT_ROOT, { recursive: true, mode: 448 });
|
|
84858
85097
|
purgeExpiredPairingAttachments(options.now);
|
|
84859
85098
|
const id = `att-${randomUUID4()}`;
|
|
84860
|
-
const path2 =
|
|
85099
|
+
const path2 = join43(PAIRING_ATTACHMENT_ROOT, id);
|
|
84861
85100
|
writeFileSync9(path2, data, { mode: 384 });
|
|
84862
85101
|
const now = options.now ?? Date.now();
|
|
84863
85102
|
const entry = {
|
|
@@ -84886,7 +85125,7 @@ function isTrustedLoopbackHostname(hostname5) {
|
|
|
84886
85125
|
function isAllowedPath(filePath) {
|
|
84887
85126
|
if (!isAbsolute4(filePath))
|
|
84888
85127
|
return false;
|
|
84889
|
-
const relToHome = filePath.slice(
|
|
85128
|
+
const relToHome = filePath.slice(homedir32().length + 1);
|
|
84890
85129
|
if (relToHome.startsWith(".") && !relToHome.startsWith(".claude") && !relToHome.startsWith(".scout/pairing")) {
|
|
84891
85130
|
return false;
|
|
84892
85131
|
}
|
|
@@ -84960,7 +85199,7 @@ function servePairingAttachment(url2) {
|
|
|
84960
85199
|
return new Response("Missing attachment id", { status: 400 });
|
|
84961
85200
|
}
|
|
84962
85201
|
const entry = attachmentBlobs.get(id);
|
|
84963
|
-
if (!entry || entry.expiresAt <= Date.now() || !
|
|
85202
|
+
if (!entry || entry.expiresAt <= Date.now() || !existsSync37(entry.path)) {
|
|
84964
85203
|
if (entry) {
|
|
84965
85204
|
attachmentBlobs.delete(entry.id);
|
|
84966
85205
|
}
|
|
@@ -85519,18 +85758,18 @@ function formatTimestamp(value) {
|
|
|
85519
85758
|
var ALLOWED_ROOTS, LOOPBACK_IPV4_HOST_PATTERN, PAIRING_ATTACHMENT_ROOT, PAIRING_ATTACHMENT_TTL_MS, PAIRING_ATTACHMENT_MAX_BYTES, PAIRING_ATTACHMENT_PATH_PREFIX = "/attachments/", attachmentBlobs;
|
|
85520
85759
|
var init_fileserver = __esm(() => {
|
|
85521
85760
|
init_web_handoff();
|
|
85522
|
-
ALLOWED_ROOTS = [
|
|
85761
|
+
ALLOWED_ROOTS = [homedir32(), "/tmp"];
|
|
85523
85762
|
LOOPBACK_IPV4_HOST_PATTERN = /^127(?:\.\d{1,3}){3}$/;
|
|
85524
|
-
PAIRING_ATTACHMENT_ROOT =
|
|
85763
|
+
PAIRING_ATTACHMENT_ROOT = join43(homedir32(), ".scout", "pairing", "attachments");
|
|
85525
85764
|
PAIRING_ATTACHMENT_TTL_MS = 6 * 60 * 60 * 1000;
|
|
85526
85765
|
PAIRING_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
|
|
85527
85766
|
attachmentBlobs = new Map;
|
|
85528
85767
|
});
|
|
85529
85768
|
|
|
85530
85769
|
// ../runtime/src/agent-workspace.ts
|
|
85531
|
-
import { existsSync as
|
|
85770
|
+
import { existsSync as existsSync38 } from "fs";
|
|
85532
85771
|
import { mkdir as mkdir12 } from "fs/promises";
|
|
85533
|
-
import { join as
|
|
85772
|
+
import { join as join44 } from "path";
|
|
85534
85773
|
async function isGitRepo(projectRoot) {
|
|
85535
85774
|
try {
|
|
85536
85775
|
await execSystemFile("git", ["rev-parse", "--git-dir"], { cwd: projectRoot, timeoutMs: 2000 });
|
|
@@ -85550,9 +85789,9 @@ async function createAgentWorkspace(projectRoot, agentName, requestedBranch) {
|
|
|
85550
85789
|
}
|
|
85551
85790
|
const branch = requestedBranch?.trim() || `scout/${agentName}`;
|
|
85552
85791
|
validateWorktreeBranch(branch);
|
|
85553
|
-
const workspaceDir =
|
|
85554
|
-
const workspacePath =
|
|
85555
|
-
if (
|
|
85792
|
+
const workspaceDir = join44(projectRoot, SCOUT_WORKSPACES_DIRNAME);
|
|
85793
|
+
const workspacePath = join44(workspaceDir, agentName);
|
|
85794
|
+
if (existsSync38(workspacePath)) {
|
|
85556
85795
|
return { path: workspacePath, branch };
|
|
85557
85796
|
}
|
|
85558
85797
|
await mkdir12(workspaceDir, { recursive: true });
|
|
@@ -85575,11 +85814,11 @@ var init_agent_workspace = __esm(() => {
|
|
|
85575
85814
|
|
|
85576
85815
|
// ../../apps/desktop/src/server/db-queries.ts
|
|
85577
85816
|
import { Database as Database3 } from "bun:sqlite";
|
|
85578
|
-
import { homedir as
|
|
85579
|
-
import { join as
|
|
85817
|
+
import { homedir as homedir33 } from "os";
|
|
85818
|
+
import { join as join45 } from "path";
|
|
85580
85819
|
function resolveDbPath() {
|
|
85581
|
-
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ??
|
|
85582
|
-
return
|
|
85820
|
+
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join45(homedir33(), ".openscout", "control-plane");
|
|
85821
|
+
return join45(controlHome, "control-plane.sqlite");
|
|
85583
85822
|
}
|
|
85584
85823
|
function db2() {
|
|
85585
85824
|
if (!_db) {
|
|
@@ -85600,14 +85839,6 @@ function sqlQuoteLiteral(value) {
|
|
|
85600
85839
|
function sqlStringList(values) {
|
|
85601
85840
|
return `(${values.map(sqlQuoteLiteral).join(",")})`;
|
|
85602
85841
|
}
|
|
85603
|
-
function sqlTimestampMsExpression(valueExpression) {
|
|
85604
|
-
return `CASE
|
|
85605
|
-
WHEN ${valueExpression} IS NULL THEN NULL
|
|
85606
|
-
WHEN CAST(${valueExpression} AS REAL) < ${EPOCH_MILLISECONDS_FLOOR}
|
|
85607
|
-
THEN CAST(CAST(${valueExpression} AS REAL) * 1000 AS INTEGER)
|
|
85608
|
-
ELSE CAST(${valueExpression} AS INTEGER)
|
|
85609
|
-
END`;
|
|
85610
|
-
}
|
|
85611
85842
|
function queryExecutingAgentIds() {
|
|
85612
85843
|
return new Set(db2().prepare(`SELECT DISTINCT target_agent_id FROM flights
|
|
85613
85844
|
WHERE state = 'running'`).all().map((row) => row.target_agent_id));
|
|
@@ -85631,155 +85862,6 @@ function summarizeAgentStatusLabel(rawState, isWorking) {
|
|
|
85631
85862
|
function conversationIdForAgent(agentId) {
|
|
85632
85863
|
return `dm.operator.${agentId}`;
|
|
85633
85864
|
}
|
|
85634
|
-
function queryMobileAgents(limit = 50) {
|
|
85635
|
-
const executingAgentIds = queryExecutingAgentIds();
|
|
85636
|
-
const lastMessageAt = new Map(db2().prepare(`SELECT actor_id, MAX(created_at) AS last_at FROM messages GROUP BY actor_id`).all().map((r) => [r.actor_id, r.last_at]));
|
|
85637
|
-
const rows = db2().prepare(`SELECT
|
|
85638
|
-
a.id,
|
|
85639
|
-
ac.display_name,
|
|
85640
|
-
a.default_selector,
|
|
85641
|
-
a.metadata_json,
|
|
85642
|
-
ep.harness,
|
|
85643
|
-
ep.transport,
|
|
85644
|
-
ep.state,
|
|
85645
|
-
ep.project_root,
|
|
85646
|
-
ep.session_id,
|
|
85647
|
-
ep.updated_at,
|
|
85648
|
-
COALESCE(ep.node_id, a.authority_node_id, a.home_node_id) AS node_id,
|
|
85649
|
-
n.name AS node_name
|
|
85650
|
-
FROM agents a
|
|
85651
|
-
JOIN actors ac ON ac.id = a.id
|
|
85652
|
-
${LATEST_AGENT_ENDPOINT_JOIN}
|
|
85653
|
-
LEFT JOIN nodes n ON n.id = COALESCE(ep.node_id, a.authority_node_id, a.home_node_id)
|
|
85654
|
-
ORDER BY COALESCE(ep.updated_at, 0) DESC, ac.display_name ASC
|
|
85655
|
-
LIMIT ?`).all(limit);
|
|
85656
|
-
return rows.map((r) => {
|
|
85657
|
-
let meta3 = {};
|
|
85658
|
-
try {
|
|
85659
|
-
meta3 = r.metadata_json ? JSON.parse(r.metadata_json) : {};
|
|
85660
|
-
} catch {}
|
|
85661
|
-
const isWorking = executingAgentIds.has(r.id);
|
|
85662
|
-
const state = summarizeAgentState(r.state, isWorking);
|
|
85663
|
-
const statusLabel = summarizeAgentStatusLabel(r.state, isWorking);
|
|
85664
|
-
return {
|
|
85665
|
-
id: r.id,
|
|
85666
|
-
title: r.display_name,
|
|
85667
|
-
selector: meta3.selector ?? null,
|
|
85668
|
-
defaultSelector: r.default_selector,
|
|
85669
|
-
nodeId: compact(r.node_id),
|
|
85670
|
-
nodeName: compact(r.node_name),
|
|
85671
|
-
workspaceRoot: compact(r.project_root),
|
|
85672
|
-
harness: r.harness,
|
|
85673
|
-
transport: r.transport,
|
|
85674
|
-
state,
|
|
85675
|
-
statusLabel,
|
|
85676
|
-
sessionId: conversationIdForAgent(r.id),
|
|
85677
|
-
lastActiveAt: lastMessageAt.get(r.id) ?? null
|
|
85678
|
-
};
|
|
85679
|
-
});
|
|
85680
|
-
}
|
|
85681
|
-
function queryMobileSessions(limit = 50) {
|
|
85682
|
-
const conversationCreatedAtExpression = sqlTimestampMsExpression("c.created_at");
|
|
85683
|
-
const messageCreatedAtExpression = sqlTimestampMsExpression("created_at");
|
|
85684
|
-
const previewMessageCreatedAtExpression = sqlTimestampMsExpression("created_at");
|
|
85685
|
-
const rows = db2().prepare(`SELECT
|
|
85686
|
-
c.id,
|
|
85687
|
-
c.kind,
|
|
85688
|
-
c.title,
|
|
85689
|
-
c.metadata_json
|
|
85690
|
-
FROM conversations c
|
|
85691
|
-
WHERE c.kind = 'direct'
|
|
85692
|
-
ORDER BY ${conversationCreatedAtExpression} DESC
|
|
85693
|
-
LIMIT ?`).all(limit);
|
|
85694
|
-
const memberStmt = db2().prepare(`SELECT actor_id FROM conversation_members WHERE conversation_id = ?`);
|
|
85695
|
-
const statsStmt = db2().prepare(`SELECT COUNT(*) AS cnt, MAX(${messageCreatedAtExpression}) AS last_at FROM messages WHERE conversation_id = ?`);
|
|
85696
|
-
const previewStmt = db2().prepare(`SELECT body FROM messages WHERE conversation_id = ? AND actor_id != 'operator'
|
|
85697
|
-
ORDER BY ${previewMessageCreatedAtExpression} DESC LIMIT 1`);
|
|
85698
|
-
return rows.map((r) => {
|
|
85699
|
-
const participants = memberStmt.all(r.id).map((m) => m.actor_id);
|
|
85700
|
-
const agentId = participants.find((p) => p !== "operator") ?? null;
|
|
85701
|
-
const stats = statsStmt.get(r.id);
|
|
85702
|
-
let agentName = null;
|
|
85703
|
-
let harness = null;
|
|
85704
|
-
let branch = null;
|
|
85705
|
-
let workspaceRoot = null;
|
|
85706
|
-
if (agentId) {
|
|
85707
|
-
const agentRow = db2().prepare(`SELECT ac.display_name, ep.harness, ep.project_root, a.metadata_json
|
|
85708
|
-
FROM agents a
|
|
85709
|
-
JOIN actors ac ON ac.id = a.id
|
|
85710
|
-
LEFT JOIN agent_endpoints ep ON ep.agent_id = a.id
|
|
85711
|
-
WHERE a.id = ?`).get(agentId);
|
|
85712
|
-
if (agentRow) {
|
|
85713
|
-
agentName = agentRow.display_name;
|
|
85714
|
-
harness = agentRow.harness;
|
|
85715
|
-
workspaceRoot = compact(agentRow.project_root);
|
|
85716
|
-
try {
|
|
85717
|
-
const meta3 = agentRow.metadata_json ? JSON.parse(agentRow.metadata_json) : {};
|
|
85718
|
-
branch = meta3.branch ?? meta3.workspaceQualifier ?? null;
|
|
85719
|
-
} catch {}
|
|
85720
|
-
}
|
|
85721
|
-
}
|
|
85722
|
-
const preview = previewStmt.get(r.id)?.body ?? null;
|
|
85723
|
-
return {
|
|
85724
|
-
id: r.id,
|
|
85725
|
-
kind: r.kind,
|
|
85726
|
-
title: agentName ?? r.title,
|
|
85727
|
-
participantIds: participants,
|
|
85728
|
-
agentId,
|
|
85729
|
-
agentName,
|
|
85730
|
-
harness,
|
|
85731
|
-
currentBranch: branch,
|
|
85732
|
-
preview: preview ? preview.slice(0, 200) : null,
|
|
85733
|
-
messageCount: stats?.cnt ?? 0,
|
|
85734
|
-
lastMessageAt: stats?.last_at ?? null,
|
|
85735
|
-
workspaceRoot
|
|
85736
|
-
};
|
|
85737
|
-
});
|
|
85738
|
-
}
|
|
85739
|
-
function queryMobileWorkspaces(limit = 50) {
|
|
85740
|
-
const rows = db2().prepare(`SELECT DISTINCT
|
|
85741
|
-
ep.project_root,
|
|
85742
|
-
ac.display_name,
|
|
85743
|
-
a.metadata_json,
|
|
85744
|
-
ep.harness
|
|
85745
|
-
FROM agents a
|
|
85746
|
-
JOIN actors ac ON ac.id = a.id
|
|
85747
|
-
LEFT JOIN agent_endpoints ep ON ep.agent_id = a.id
|
|
85748
|
-
WHERE ep.project_root IS NOT NULL
|
|
85749
|
-
ORDER BY ep.updated_at DESC NULLS LAST
|
|
85750
|
-
LIMIT ?`).all(limit);
|
|
85751
|
-
const seen = new Set;
|
|
85752
|
-
const results = [];
|
|
85753
|
-
for (const r of rows) {
|
|
85754
|
-
if (seen.has(r.project_root))
|
|
85755
|
-
continue;
|
|
85756
|
-
seen.add(r.project_root);
|
|
85757
|
-
let meta3 = {};
|
|
85758
|
-
try {
|
|
85759
|
-
meta3 = r.metadata_json ? JSON.parse(r.metadata_json) : {};
|
|
85760
|
-
} catch {}
|
|
85761
|
-
const projectName = meta3.project ?? r.project_root.split("/").pop() ?? "unknown";
|
|
85762
|
-
const relativePath = r.project_root.replace(HOME + "/", "");
|
|
85763
|
-
results.push({
|
|
85764
|
-
id: r.project_root,
|
|
85765
|
-
title: projectName,
|
|
85766
|
-
projectName,
|
|
85767
|
-
root: r.project_root,
|
|
85768
|
-
sourceRoot: r.project_root,
|
|
85769
|
-
relativePath,
|
|
85770
|
-
registrationKind: "agent",
|
|
85771
|
-
defaultHarness: r.harness ?? "claude",
|
|
85772
|
-
harnesses: r.harness ? [{
|
|
85773
|
-
harness: r.harness,
|
|
85774
|
-
source: "default",
|
|
85775
|
-
detail: "Current endpoint",
|
|
85776
|
-
readinessState: "ready",
|
|
85777
|
-
readinessDetail: null
|
|
85778
|
-
}] : []
|
|
85779
|
-
});
|
|
85780
|
-
}
|
|
85781
|
-
return results;
|
|
85782
|
-
}
|
|
85783
85865
|
function queryMobileAgentDetail(agentId) {
|
|
85784
85866
|
const row = db2().prepare(`SELECT
|
|
85785
85867
|
a.id,
|
|
@@ -85872,8 +85954,7 @@ var _db = null, HOME, LATEST_AGENT_ENDPOINT_JOIN = `LEFT JOIN agent_endpoints ep
|
|
|
85872
85954
|
LIMIT 1
|
|
85873
85955
|
)`, ACTIVE_FLIGHT_STATES_SQL, ACTIVE_FLIGHT_MAX_AGE_MS, ACTIVE_WORK_STATES_SQL;
|
|
85874
85956
|
var init_db_queries = __esm(() => {
|
|
85875
|
-
|
|
85876
|
-
HOME = homedir32();
|
|
85957
|
+
HOME = homedir33();
|
|
85877
85958
|
ACTIVE_FLIGHT_STATES_SQL = sqlStringList(["running", "waking", "waiting", "queued"]);
|
|
85878
85959
|
ACTIVE_FLIGHT_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
85879
85960
|
ACTIVE_WORK_STATES_SQL = sqlStringList(["open", "working", "waiting", "review"]);
|
|
@@ -85881,6 +85962,7 @@ var init_db_queries = __esm(() => {
|
|
|
85881
85962
|
|
|
85882
85963
|
// ../../apps/desktop/src/core/mobile/service.ts
|
|
85883
85964
|
import { basename as basename14, resolve as resolve26 } from "path";
|
|
85965
|
+
import { statSync as statSync6 } from "fs";
|
|
85884
85966
|
function mobileLifecycleStateForFlight(flight) {
|
|
85885
85967
|
switch (flight?.state) {
|
|
85886
85968
|
case "queued":
|
|
@@ -85920,10 +86002,16 @@ function normalizeTimestamp(value) {
|
|
|
85920
86002
|
function normalizeTimestampMs2(value) {
|
|
85921
86003
|
return epochMs(value);
|
|
85922
86004
|
}
|
|
86005
|
+
function requireTimestampMs(value) {
|
|
86006
|
+
return normalizeTimestampMs2(value) ?? 0;
|
|
86007
|
+
}
|
|
85923
86008
|
function metadataString7(metadata, key) {
|
|
85924
86009
|
const value = metadata?.[key];
|
|
85925
86010
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
85926
86011
|
}
|
|
86012
|
+
function metadataTimestampMs(metadata, key) {
|
|
86013
|
+
return normalizeTimestampMs2(metadata?.[key]);
|
|
86014
|
+
}
|
|
85927
86015
|
function metadataBoolean2(metadata, key) {
|
|
85928
86016
|
return metadata?.[key] === true;
|
|
85929
86017
|
}
|
|
@@ -85996,6 +86084,37 @@ async function loadMobileWorkspaceInventory(currentDirectory) {
|
|
|
85996
86084
|
})
|
|
85997
86085
|
})).sort((left, right) => left.relativePath.localeCompare(right.relativePath) || left.title.localeCompare(right.title));
|
|
85998
86086
|
}
|
|
86087
|
+
function isDirectory2(path2) {
|
|
86088
|
+
try {
|
|
86089
|
+
return statSync6(path2).isDirectory();
|
|
86090
|
+
} catch {
|
|
86091
|
+
return false;
|
|
86092
|
+
}
|
|
86093
|
+
}
|
|
86094
|
+
function rehomeScoutMobileWorkspacePath(requestedPath, currentHome) {
|
|
86095
|
+
const requested = resolve26(requestedPath);
|
|
86096
|
+
const home = resolve26(currentHome);
|
|
86097
|
+
const requestedMatch = requested.match(/^\/Users\/[^/]+(\/.*)?$/);
|
|
86098
|
+
if (!requestedMatch || !/^\/Users\/[^/]+$/.test(home))
|
|
86099
|
+
return null;
|
|
86100
|
+
const suffix = requestedMatch[1] ?? "";
|
|
86101
|
+
return resolve26(home, `.${suffix || "/"}`);
|
|
86102
|
+
}
|
|
86103
|
+
async function resolveMobileWorkspaceRoot(rawWorkspaceId, currentDirectory) {
|
|
86104
|
+
const requested = resolve26(rawWorkspaceId);
|
|
86105
|
+
if (isDirectory2(requested))
|
|
86106
|
+
return requested;
|
|
86107
|
+
const currentHome = process.env.HOME?.trim();
|
|
86108
|
+
const rehomed = currentHome ? rehomeScoutMobileWorkspacePath(requested, currentHome) : null;
|
|
86109
|
+
if (rehomed && isDirectory2(rehomed))
|
|
86110
|
+
return rehomed;
|
|
86111
|
+
const requestedName = basename14(requested).toLowerCase();
|
|
86112
|
+
const inventory = await loadMobileWorkspaceInventory(currentDirectory);
|
|
86113
|
+
const matches = inventory.filter((workspace) => isDirectory2(workspace.root) && [basename14(workspace.root), workspace.projectName, workspace.title].some((value) => value.toLowerCase() === requestedName));
|
|
86114
|
+
if (matches.length === 1)
|
|
86115
|
+
return resolve26(matches[0].root);
|
|
86116
|
+
throw new Error(`Workspace is not available on this Mac: ${rawWorkspaceId}. Choose a project from the current workspace list.`);
|
|
86117
|
+
}
|
|
85999
86118
|
function latestMessageByConversation(snapshot) {
|
|
86000
86119
|
const buckets = new Map;
|
|
86001
86120
|
for (const message of Object.values(snapshot.messages)) {
|
|
@@ -86039,18 +86158,66 @@ function mobileConversationTitle(snapshot, conversation, directAgentId = null) {
|
|
|
86039
86158
|
const title = rawConversationTitle(conversation) ?? conversationIdTitle(conversation.id);
|
|
86040
86159
|
return conversation.kind === "channel" && title.startsWith("channel.") ? title.slice("channel.".length) : title;
|
|
86041
86160
|
}
|
|
86161
|
+
function endpointsForAgent(snapshot, agentId) {
|
|
86162
|
+
const stateRank = (state) => {
|
|
86163
|
+
switch (state) {
|
|
86164
|
+
case "active":
|
|
86165
|
+
return 0;
|
|
86166
|
+
case "idle":
|
|
86167
|
+
return 1;
|
|
86168
|
+
case "waiting":
|
|
86169
|
+
return 2;
|
|
86170
|
+
case "offline":
|
|
86171
|
+
return 4;
|
|
86172
|
+
default:
|
|
86173
|
+
return 3;
|
|
86174
|
+
}
|
|
86175
|
+
};
|
|
86176
|
+
return Object.values(snapshot.endpoints).filter((endpoint) => endpoint.agentId === agentId && !isInactiveEndpoint(snapshot, endpoint)).sort((left, right) => Number(right.preferred === true) - Number(left.preferred === true) || stateRank(left.state) - stateRank(right.state) || (endpointActivityAt(right) ?? 0) - (endpointActivityAt(left) ?? 0) || left.id.localeCompare(right.id));
|
|
86177
|
+
}
|
|
86042
86178
|
function endpointForAgent(snapshot, agentId) {
|
|
86043
|
-
return
|
|
86179
|
+
return endpointsForAgent(snapshot, agentId)[0] ?? null;
|
|
86180
|
+
}
|
|
86181
|
+
function maxTimestampMs(values) {
|
|
86182
|
+
const timestamps = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
86183
|
+
return timestamps.length > 0 ? Math.max(...timestamps) : null;
|
|
86184
|
+
}
|
|
86185
|
+
function endpointActivityAt(endpoint) {
|
|
86186
|
+
if (!endpoint)
|
|
86187
|
+
return null;
|
|
86188
|
+
return maxTimestampMs([
|
|
86189
|
+
metadataTimestampMs(endpoint.metadata, "lastSeenAt"),
|
|
86190
|
+
metadataTimestampMs(endpoint.metadata, "lastEnsuredAt"),
|
|
86191
|
+
metadataTimestampMs(endpoint.metadata, "lastStartedAt"),
|
|
86192
|
+
metadataTimestampMs(endpoint.metadata, "lastCompletedAt"),
|
|
86193
|
+
metadataTimestampMs(endpoint.metadata, "lastFailedAt"),
|
|
86194
|
+
metadataTimestampMs(endpoint.metadata, "startedAt")
|
|
86195
|
+
]);
|
|
86196
|
+
}
|
|
86197
|
+
function flightActivityAt2(flight) {
|
|
86198
|
+
return maxTimestampMs([
|
|
86199
|
+
normalizeTimestampMs2(flight.completedAt),
|
|
86200
|
+
normalizeTimestampMs2(flight.startedAt)
|
|
86201
|
+
]);
|
|
86202
|
+
}
|
|
86203
|
+
function isActiveMobileFlight(flight) {
|
|
86204
|
+
return flight.state === "running" || flight.state === "waiting" || flight.state === "queued" || flight.state === "waking";
|
|
86044
86205
|
}
|
|
86045
86206
|
function buildMobileAgentSummary(snapshot, agent) {
|
|
86046
|
-
const
|
|
86207
|
+
const endpoints = endpointsForAgent(snapshot, agent.id);
|
|
86208
|
+
const endpoint = endpoints[0] ?? null;
|
|
86047
86209
|
const flights = Object.values(snapshot.flights).filter((flight) => flight.targetAgentId === agent.id);
|
|
86048
|
-
const
|
|
86210
|
+
const hasActiveFlight = flights.some(isActiveMobileFlight);
|
|
86049
86211
|
const lastAuthoredMessageAt = Object.values(snapshot.messages).filter((message) => message.actorId === agent.id).reduce((latest, message) => {
|
|
86050
86212
|
const createdAt = normalizeTimestampMs2(message.createdAt);
|
|
86051
86213
|
return typeof createdAt === "number" && (!latest || createdAt > latest) ? createdAt : latest;
|
|
86052
86214
|
}, null);
|
|
86053
|
-
const
|
|
86215
|
+
const lastActiveAt = maxTimestampMs([
|
|
86216
|
+
lastAuthoredMessageAt,
|
|
86217
|
+
...endpoints.map(endpointActivityAt),
|
|
86218
|
+
...flights.map(flightActivityAt2)
|
|
86219
|
+
]);
|
|
86220
|
+
const state = hasActiveFlight ? "working" : endpoints.some((candidate) => candidate.state !== "offline") ? "available" : agent.wakePolicy !== "manual" ? "available" : "offline";
|
|
86054
86221
|
return {
|
|
86055
86222
|
id: agent.id,
|
|
86056
86223
|
title: agent.displayName,
|
|
@@ -86064,7 +86231,7 @@ function buildMobileAgentSummary(snapshot, agent) {
|
|
|
86064
86231
|
state,
|
|
86065
86232
|
statusLabel: state === "working" ? "Working" : state === "available" ? "Available" : "Offline",
|
|
86066
86233
|
sessionId: endpoint?.sessionId ?? null,
|
|
86067
|
-
lastActiveAt
|
|
86234
|
+
lastActiveAt
|
|
86068
86235
|
};
|
|
86069
86236
|
}
|
|
86070
86237
|
function buildMobileSessionSummaries(snapshot) {
|
|
@@ -86378,7 +86545,7 @@ async function createScoutSession(input, currentDirectory, deviceId) {
|
|
|
86378
86545
|
if (!rawWorkspaceId) {
|
|
86379
86546
|
throw new Error(`Invalid workspaceId.`);
|
|
86380
86547
|
}
|
|
86381
|
-
const workspaceRoot =
|
|
86548
|
+
const workspaceRoot = await resolveMobileWorkspaceRoot(rawWorkspaceId, currentDirectory);
|
|
86382
86549
|
const projectName = basename14(workspaceRoot) || workspaceRoot;
|
|
86383
86550
|
const workspace = {
|
|
86384
86551
|
id: workspaceRoot,
|
|
@@ -86595,8 +86762,49 @@ async function requireMobileRelayContext() {
|
|
|
86595
86762
|
return broker2;
|
|
86596
86763
|
}
|
|
86597
86764
|
async function getScoutMobileActivity(filters = {}) {
|
|
86598
|
-
const
|
|
86599
|
-
|
|
86765
|
+
const broker2 = await loadScoutBrokerContext();
|
|
86766
|
+
if (!broker2) {
|
|
86767
|
+
const home = await readScoutBrokerHome();
|
|
86768
|
+
return (home?.activity ?? []).slice(0, filters.limit ?? 100);
|
|
86769
|
+
}
|
|
86770
|
+
const { snapshot } = broker2;
|
|
86771
|
+
const selfIds = operatorActorIds();
|
|
86772
|
+
const mediatedKinds = new Set(["channel", "direct", "group_direct", "thread"]);
|
|
86773
|
+
const rows = Object.values(snapshot.messages ?? {}).filter((message) => {
|
|
86774
|
+
const conversation = snapshot.conversations?.[message.conversationId];
|
|
86775
|
+
if (!conversation || !mediatedKinds.has(conversation.kind))
|
|
86776
|
+
return false;
|
|
86777
|
+
if (filters.agentId && message.actorId !== filters.agentId)
|
|
86778
|
+
return false;
|
|
86779
|
+
if (filters.actorId && message.actorId !== filters.actorId)
|
|
86780
|
+
return false;
|
|
86781
|
+
if (filters.conversationId && message.conversationId !== filters.conversationId)
|
|
86782
|
+
return false;
|
|
86783
|
+
return true;
|
|
86784
|
+
}).sort((left, right) => requireTimestampMs(right.createdAt) - requireTimestampMs(left.createdAt)).map((message) => {
|
|
86785
|
+
const conversation = snapshot.conversations[message.conversationId];
|
|
86786
|
+
const actorName = commsActorLabel(snapshot, message.actorId, selfIds);
|
|
86787
|
+
const channel = conversation.kind === "channel" ? channelNaturalKeyFromMetadata(conversation.metadata) ?? conversation.title ?? null : null;
|
|
86788
|
+
return {
|
|
86789
|
+
id: message.id,
|
|
86790
|
+
kind: message.class === "status" || message.actorId === "system" ? "system" : "message",
|
|
86791
|
+
actorId: message.actorId,
|
|
86792
|
+
actorName,
|
|
86793
|
+
title: actorName,
|
|
86794
|
+
detail: message.body,
|
|
86795
|
+
conversationId: message.conversationId,
|
|
86796
|
+
channel,
|
|
86797
|
+
timestamp: requireTimestampMs(message.createdAt)
|
|
86798
|
+
};
|
|
86799
|
+
});
|
|
86800
|
+
const limit = filters.limit && filters.limit > 0 ? Math.floor(filters.limit) : 100;
|
|
86801
|
+
return rows.slice(0, limit);
|
|
86802
|
+
}
|
|
86803
|
+
async function getScoutMobileServiceBudgets() {
|
|
86804
|
+
return { budgets: [] };
|
|
86805
|
+
}
|
|
86806
|
+
async function getScoutMobileTerminals() {
|
|
86807
|
+
return { terminals: [] };
|
|
86600
86808
|
}
|
|
86601
86809
|
function operatorActorIds() {
|
|
86602
86810
|
const ids = new Set([MOBILE_OPERATOR_ID]);
|
|
@@ -86970,7 +87178,7 @@ import { createHash as createHash5 } from "crypto";
|
|
|
86970
87178
|
import {
|
|
86971
87179
|
chmodSync,
|
|
86972
87180
|
closeSync,
|
|
86973
|
-
existsSync as
|
|
87181
|
+
existsSync as existsSync39,
|
|
86974
87182
|
mkdirSync as mkdirSync12,
|
|
86975
87183
|
openSync,
|
|
86976
87184
|
readFileSync as readFileSync19,
|
|
@@ -86978,8 +87186,8 @@ import {
|
|
|
86978
87186
|
unlinkSync as unlinkSync3,
|
|
86979
87187
|
writeFileSync as writeFileSync10
|
|
86980
87188
|
} from "fs";
|
|
86981
|
-
import { homedir as
|
|
86982
|
-
import { join as
|
|
87189
|
+
import { homedir as homedir34, hostname as hostname5, userInfo as userInfo2 } from "os";
|
|
87190
|
+
import { join as join46 } from "path";
|
|
86983
87191
|
async function readMobileTerminalStatus() {
|
|
86984
87192
|
const base = {
|
|
86985
87193
|
shellExecutable: process.env.SHELL?.trim() || "/bin/zsh",
|
|
@@ -87049,17 +87257,17 @@ async function readMobileTerminalStatus() {
|
|
|
87049
87257
|
}
|
|
87050
87258
|
async function provisionMobileTerminalAccess(sshPublicKey, deviceId) {
|
|
87051
87259
|
const id = deviceId?.trim() || "scout-ios-device";
|
|
87052
|
-
const sshDir =
|
|
87053
|
-
const authorizedKeysPath =
|
|
87260
|
+
const sshDir = join46(homedir34(), ".ssh");
|
|
87261
|
+
const authorizedKeysPath = join46(sshDir, "authorized_keys");
|
|
87054
87262
|
const hostKeyFingerprint = readRequiredHostKeyFingerprint();
|
|
87055
87263
|
const result = withAuthorizedKeysLock(sshDir, () => {
|
|
87056
|
-
if (!
|
|
87264
|
+
if (!existsSync39(sshDir)) {
|
|
87057
87265
|
mkdirSync12(sshDir, { recursive: true, mode: 448 });
|
|
87058
87266
|
}
|
|
87059
87267
|
try {
|
|
87060
87268
|
chmodSync(sshDir, 448);
|
|
87061
87269
|
} catch {}
|
|
87062
|
-
const existing =
|
|
87270
|
+
const existing = existsSync39(authorizedKeysPath) ? readFileSync19(authorizedKeysPath, "utf8") : "";
|
|
87063
87271
|
const result2 = provisionSshTerminalAccess({
|
|
87064
87272
|
authorizedKeys: existing,
|
|
87065
87273
|
deviceId: id,
|
|
@@ -87113,10 +87321,10 @@ function writeAuthorizedKeysAtomically(path2, contents) {
|
|
|
87113
87321
|
}
|
|
87114
87322
|
}
|
|
87115
87323
|
function withAuthorizedKeysLock(sshDir, action) {
|
|
87116
|
-
if (!
|
|
87324
|
+
if (!existsSync39(sshDir)) {
|
|
87117
87325
|
mkdirSync12(sshDir, { recursive: true, mode: 448 });
|
|
87118
87326
|
}
|
|
87119
|
-
const lockPath =
|
|
87327
|
+
const lockPath = join46(sshDir, ".scout-authorized-keys.lock");
|
|
87120
87328
|
const deadline = Date.now() + 5000;
|
|
87121
87329
|
let fd = null;
|
|
87122
87330
|
while (fd === null) {
|
|
@@ -87157,9 +87365,9 @@ var init_mobile_terminal_provision = __esm(() => {
|
|
|
87157
87365
|
});
|
|
87158
87366
|
|
|
87159
87367
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
|
|
87160
|
-
import { readdirSync as readdirSync4, readFileSync as readFileSync20, realpathSync as realpathSync3, statSync as
|
|
87161
|
-
import { basename as basename15, isAbsolute as isAbsolute5, join as
|
|
87162
|
-
import { homedir as
|
|
87368
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync20, realpathSync as realpathSync3, statSync as statSync7 } from "fs";
|
|
87369
|
+
import { basename as basename15, isAbsolute as isAbsolute5, join as join47, relative as relative4 } from "path";
|
|
87370
|
+
import { homedir as homedir35 } from "os";
|
|
87163
87371
|
function replaySyncEvents(bridge, sessionId, lastSeq) {
|
|
87164
87372
|
return bridge.replay(sessionId, lastSeq);
|
|
87165
87373
|
}
|
|
@@ -87346,7 +87554,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
|
|
|
87346
87554
|
if (dirName.startsWith("-")) {
|
|
87347
87555
|
const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
|
|
87348
87556
|
try {
|
|
87349
|
-
|
|
87557
|
+
statSync7(candidate);
|
|
87350
87558
|
cwd = candidate;
|
|
87351
87559
|
} catch {
|
|
87352
87560
|
const config2 = resolveConfig();
|
|
@@ -87403,7 +87611,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
|
|
|
87403
87611
|
}
|
|
87404
87612
|
const root = resolveWorkspaceRoot(configuredRoot);
|
|
87405
87613
|
const projectPath = resolveWorkspacePath(root, p.path);
|
|
87406
|
-
const stat6 =
|
|
87614
|
+
const stat6 = statSync7(projectPath);
|
|
87407
87615
|
if (!stat6.isDirectory()) {
|
|
87408
87616
|
return { id: req.id, error: { code: -32000, message: "Workspace target is not a directory" } };
|
|
87409
87617
|
}
|
|
@@ -87483,6 +87691,18 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
|
|
|
87483
87691
|
result: await getScoutMobileActivity(p)
|
|
87484
87692
|
};
|
|
87485
87693
|
}
|
|
87694
|
+
case "mobile/service-budgets": {
|
|
87695
|
+
return {
|
|
87696
|
+
id: req.id,
|
|
87697
|
+
result: await getScoutMobileServiceBudgets()
|
|
87698
|
+
};
|
|
87699
|
+
}
|
|
87700
|
+
case "mobile/terminal-sessions": {
|
|
87701
|
+
return {
|
|
87702
|
+
id: req.id,
|
|
87703
|
+
result: await getScoutMobileTerminals()
|
|
87704
|
+
};
|
|
87705
|
+
}
|
|
87486
87706
|
case "mobile/comms/conversations": {
|
|
87487
87707
|
const p = req.params;
|
|
87488
87708
|
return {
|
|
@@ -87591,7 +87811,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
|
|
|
87591
87811
|
const config2 = resolveConfig();
|
|
87592
87812
|
const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot(config2.workspace.root) : null;
|
|
87593
87813
|
const matches = await readSessionSearch({
|
|
87594
|
-
home:
|
|
87814
|
+
home: homedir35(),
|
|
87595
87815
|
workspaceRoot,
|
|
87596
87816
|
maxAgeDays: maxAge,
|
|
87597
87817
|
limit,
|
|
@@ -87724,13 +87944,13 @@ function resolveMobileCurrentDirectory() {
|
|
|
87724
87944
|
}
|
|
87725
87945
|
}
|
|
87726
87946
|
function resolveWorkspaceRoot(root) {
|
|
87727
|
-
const expandedRoot = root.replace(/^~/,
|
|
87947
|
+
const expandedRoot = root.replace(/^~/, homedir35());
|
|
87728
87948
|
return realpathSync3(expandedRoot);
|
|
87729
87949
|
}
|
|
87730
87950
|
function resolveWorkspacePath(root, requestedPath) {
|
|
87731
87951
|
const normalizedRoot = resolveWorkspaceRoot(root);
|
|
87732
|
-
const expandedPath = requestedPath?.replace(/^~/,
|
|
87733
|
-
const candidate = expandedPath ? isAbsolute5(expandedPath) ? expandedPath :
|
|
87952
|
+
const expandedPath = requestedPath?.replace(/^~/, homedir35());
|
|
87953
|
+
const candidate = expandedPath ? isAbsolute5(expandedPath) ? expandedPath : join47(normalizedRoot, expandedPath) : normalizedRoot;
|
|
87734
87954
|
const resolvedCandidate = realpathSync3(candidate);
|
|
87735
87955
|
const rel = relative4(normalizedRoot, resolvedCandidate);
|
|
87736
87956
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute5(rel)) {
|
|
@@ -87745,9 +87965,9 @@ function listDirectories(dirPath) {
|
|
|
87745
87965
|
continue;
|
|
87746
87966
|
if (name === "node_modules" || name === ".build" || name === "target")
|
|
87747
87967
|
continue;
|
|
87748
|
-
const fullPath =
|
|
87968
|
+
const fullPath = join47(dirPath, name);
|
|
87749
87969
|
try {
|
|
87750
|
-
const stat6 =
|
|
87970
|
+
const stat6 = statSync7(fullPath);
|
|
87751
87971
|
if (!stat6.isDirectory())
|
|
87752
87972
|
continue;
|
|
87753
87973
|
const children = new Set(readdirSync4(fullPath));
|
|
@@ -87771,7 +87991,7 @@ async function discoverSessionFiles(maxAgeDays, limit) {
|
|
|
87771
87991
|
const config2 = resolveConfig();
|
|
87772
87992
|
const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot(config2.workspace.root) : null;
|
|
87773
87993
|
const sessions4 = await readSessionFileScan({
|
|
87774
|
-
home:
|
|
87994
|
+
home: homedir35(),
|
|
87775
87995
|
workspaceRoot,
|
|
87776
87996
|
maxAgeDays,
|
|
87777
87997
|
limit
|
|
@@ -87883,9 +88103,9 @@ var init_tail_fanout = __esm(() => {
|
|
|
87883
88103
|
});
|
|
87884
88104
|
|
|
87885
88105
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
|
|
87886
|
-
import { readFileSync as readFileSync21, readdirSync as readdirSync5, realpathSync as realpathSync4, statSync as
|
|
87887
|
-
import { basename as basename16, isAbsolute as isAbsolute6, join as
|
|
87888
|
-
import { homedir as
|
|
88106
|
+
import { readFileSync as readFileSync21, readdirSync as readdirSync5, realpathSync as realpathSync4, statSync as statSync8 } from "fs";
|
|
88107
|
+
import { basename as basename16, isAbsolute as isAbsolute6, join as join48, relative as relative5 } from "path";
|
|
88108
|
+
import { homedir as homedir36 } from "os";
|
|
87889
88109
|
function resolveMobileCurrentDirectory2() {
|
|
87890
88110
|
const config2 = resolveConfig();
|
|
87891
88111
|
const configuredRoot = config2.workspace?.root;
|
|
@@ -87898,13 +88118,13 @@ function resolveMobileCurrentDirectory2() {
|
|
|
87898
88118
|
}
|
|
87899
88119
|
}
|
|
87900
88120
|
function resolveWorkspaceRoot2(root) {
|
|
87901
|
-
const expandedRoot = root.replace(/^~/,
|
|
88121
|
+
const expandedRoot = root.replace(/^~/, homedir36());
|
|
87902
88122
|
return realpathSync4(expandedRoot);
|
|
87903
88123
|
}
|
|
87904
88124
|
function resolveWorkspacePath2(root, requestedPath) {
|
|
87905
88125
|
const normalizedRoot = resolveWorkspaceRoot2(root);
|
|
87906
|
-
const expandedPath = requestedPath?.replace(/^~/,
|
|
87907
|
-
const candidate = expandedPath ? isAbsolute6(expandedPath) ? expandedPath :
|
|
88126
|
+
const expandedPath = requestedPath?.replace(/^~/, homedir36());
|
|
88127
|
+
const candidate = expandedPath ? isAbsolute6(expandedPath) ? expandedPath : join48(normalizedRoot, expandedPath) : normalizedRoot;
|
|
87908
88128
|
const resolvedCandidate = realpathSync4(candidate);
|
|
87909
88129
|
const rel = relative5(normalizedRoot, resolvedCandidate);
|
|
87910
88130
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute6(rel)) {
|
|
@@ -87919,9 +88139,9 @@ function listDirectories2(dirPath) {
|
|
|
87919
88139
|
continue;
|
|
87920
88140
|
if (name === "node_modules" || name === ".build" || name === "target")
|
|
87921
88141
|
continue;
|
|
87922
|
-
const fullPath =
|
|
88142
|
+
const fullPath = join48(dirPath, name);
|
|
87923
88143
|
try {
|
|
87924
|
-
const stat6 =
|
|
88144
|
+
const stat6 = statSync8(fullPath);
|
|
87925
88145
|
if (!stat6.isDirectory())
|
|
87926
88146
|
continue;
|
|
87927
88147
|
const children = new Set(readdirSync5(fullPath));
|
|
@@ -87952,7 +88172,7 @@ async function discoverSessionFiles2(maxAgeDays, limit) {
|
|
|
87952
88172
|
const config2 = resolveConfig();
|
|
87953
88173
|
const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot2(config2.workspace.root) : null;
|
|
87954
88174
|
const sessions4 = await readSessionFileScan({
|
|
87955
|
-
home:
|
|
88175
|
+
home: homedir36(),
|
|
87956
88176
|
workspaceRoot,
|
|
87957
88177
|
maxAgeDays,
|
|
87958
88178
|
limit
|
|
@@ -88297,7 +88517,7 @@ var init_router = __esm(() => {
|
|
|
88297
88517
|
if (dirName.startsWith("-")) {
|
|
88298
88518
|
const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
|
|
88299
88519
|
try {
|
|
88300
|
-
|
|
88520
|
+
statSync8(candidate);
|
|
88301
88521
|
cwd = candidate;
|
|
88302
88522
|
} catch {
|
|
88303
88523
|
const config2 = resolveConfig();
|
|
@@ -88358,56 +88578,31 @@ var init_router = __esm(() => {
|
|
|
88358
88578
|
workspaceLimit: exports_external.number().optional(),
|
|
88359
88579
|
agentLimit: exports_external.number().optional(),
|
|
88360
88580
|
sessionLimit: exports_external.number().optional()
|
|
88361
|
-
}).optional()).query(({ input }) => {
|
|
88362
|
-
|
|
88363
|
-
|
|
88364
|
-
|
|
88365
|
-
|
|
88366
|
-
|
|
88367
|
-
|
|
88368
|
-
return {
|
|
88369
|
-
workspaces,
|
|
88370
|
-
agents,
|
|
88371
|
-
sessions: sessions4,
|
|
88372
|
-
totals: {
|
|
88373
|
-
workspaces: workspaces.length,
|
|
88374
|
-
agents: agents.length,
|
|
88375
|
-
sessions: sessions4.length
|
|
88376
|
-
}
|
|
88377
|
-
};
|
|
88581
|
+
}).optional()).query(async ({ input }) => {
|
|
88582
|
+
return getScoutMobileHome({
|
|
88583
|
+
currentDirectory: resolveMobileCurrentDirectory2(),
|
|
88584
|
+
workspaceLimit: input?.workspaceLimit,
|
|
88585
|
+
agentLimit: input?.agentLimit,
|
|
88586
|
+
sessionLimit: input?.sessionLimit
|
|
88587
|
+
});
|
|
88378
88588
|
}),
|
|
88379
88589
|
workspaces: procedure.input(exports_external.object({
|
|
88380
88590
|
query: exports_external.string().optional(),
|
|
88381
88591
|
limit: exports_external.number().optional()
|
|
88382
|
-
}).optional()).query(({ input }) => {
|
|
88383
|
-
|
|
88384
|
-
if (input?.query) {
|
|
88385
|
-
const q = input.query.toLowerCase();
|
|
88386
|
-
results = results.filter((w) => w.title.toLowerCase().includes(q) || w.root.toLowerCase().includes(q));
|
|
88387
|
-
}
|
|
88388
|
-
return results;
|
|
88592
|
+
}).optional()).query(async ({ input }) => {
|
|
88593
|
+
return getScoutMobileWorkspaces(input, resolveMobileCurrentDirectory2());
|
|
88389
88594
|
}),
|
|
88390
88595
|
agents: procedure.input(exports_external.object({
|
|
88391
88596
|
query: exports_external.string().optional(),
|
|
88392
88597
|
limit: exports_external.number().optional()
|
|
88393
|
-
}).optional()).query(({ input }) => {
|
|
88394
|
-
|
|
88395
|
-
if (input?.query) {
|
|
88396
|
-
const q = input.query.toLowerCase();
|
|
88397
|
-
results = results.filter((a) => a.title.toLowerCase().includes(q) || a.id.toLowerCase().includes(q) || (a.workspaceRoot ?? "").toLowerCase().includes(q));
|
|
88398
|
-
}
|
|
88399
|
-
return results;
|
|
88598
|
+
}).optional()).query(async ({ input }) => {
|
|
88599
|
+
return getScoutMobileAgents(input, resolveMobileCurrentDirectory2());
|
|
88400
88600
|
}),
|
|
88401
88601
|
sessions: procedure.input(exports_external.object({
|
|
88402
88602
|
query: exports_external.string().optional(),
|
|
88403
88603
|
limit: exports_external.number().optional()
|
|
88404
|
-
}).optional()).query(({ input }) => {
|
|
88405
|
-
|
|
88406
|
-
if (input?.query) {
|
|
88407
|
-
const q = input.query.toLowerCase();
|
|
88408
|
-
results = results.filter((s) => s.title.toLowerCase().includes(q) || (s.agentName ?? "").toLowerCase().includes(q) || (s.preview ?? "").toLowerCase().includes(q));
|
|
88409
|
-
}
|
|
88410
|
-
return results;
|
|
88604
|
+
}).optional()).query(async ({ input }) => {
|
|
88605
|
+
return getScoutMobileSessions(input, resolveMobileCurrentDirectory2());
|
|
88411
88606
|
}),
|
|
88412
88607
|
sessionSnapshot: procedure.input(exports_external.object({
|
|
88413
88608
|
conversationId: exports_external.string().optional(),
|
|
@@ -88527,6 +88722,8 @@ var init_router = __esm(() => {
|
|
|
88527
88722
|
}).optional()).query(async ({ input }) => {
|
|
88528
88723
|
return getScoutMobileActivity(input);
|
|
88529
88724
|
}),
|
|
88725
|
+
serviceBudgets: procedure.input(exports_external.object({}).optional()).query(async () => getScoutMobileServiceBudgets()),
|
|
88726
|
+
terminalSessions: procedure.input(exports_external.object({}).optional()).query(async () => getScoutMobileTerminals()),
|
|
88530
88727
|
agentDetail: procedure.input(exports_external.object({ agentId: exports_external.string() })).query(async ({ input }) => {
|
|
88531
88728
|
return queryMobileAgentDetail(input.agentId);
|
|
88532
88729
|
}),
|
|
@@ -88656,7 +88853,7 @@ var init_router = __esm(() => {
|
|
|
88656
88853
|
}
|
|
88657
88854
|
const root = resolveWorkspaceRoot2(configuredRoot);
|
|
88658
88855
|
const projectPath = resolveWorkspacePath2(root, input.path);
|
|
88659
|
-
const stat6 =
|
|
88856
|
+
const stat6 = statSync8(projectPath);
|
|
88660
88857
|
if (!stat6.isDirectory()) {
|
|
88661
88858
|
throw new TRPCError({
|
|
88662
88859
|
code: "BAD_REQUEST",
|
|
@@ -88698,7 +88895,7 @@ var init_router = __esm(() => {
|
|
|
88698
88895
|
const config2 = resolveConfig();
|
|
88699
88896
|
const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot2(config2.workspace.root) : null;
|
|
88700
88897
|
const matches = await readSessionSearch({
|
|
88701
|
-
home:
|
|
88898
|
+
home: homedir36(),
|
|
88702
88899
|
workspaceRoot,
|
|
88703
88900
|
maxAgeDays: maxAge,
|
|
88704
88901
|
limit,
|
|
@@ -88902,8 +89099,8 @@ function mobileConversationLifecycleEvent(lifecycle) {
|
|
|
88902
89099
|
}
|
|
88903
89100
|
function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
88904
89101
|
const { secure = true, events: events2 } = options;
|
|
88905
|
-
const
|
|
88906
|
-
const qrPayload = createQRPayload(identity2.publicKey,
|
|
89102
|
+
const eventRelayUrl = options.publicRelayUrl?.trim() || relayUrl;
|
|
89103
|
+
const qrPayload = options.qrPayload ?? createQRPayload(identity2.publicKey, eventRelayUrl, options.fallbackRelayUrls);
|
|
88907
89104
|
let ws = null;
|
|
88908
89105
|
let eventUnsub = null;
|
|
88909
89106
|
let brokerWatchAbort = null;
|
|
@@ -88918,12 +89115,12 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
88918
89115
|
const bridgeKeyHex = bytesToHex2(identity2.publicKey);
|
|
88919
89116
|
const url2 = buildRelayUrl(relayUrl, qrPayload.room, bridgeKeyHex);
|
|
88920
89117
|
console.log(`[relay-client] connecting to relay (room: ${qrPayload.room})`);
|
|
88921
|
-
events2?.onConnecting?.({ relayUrl:
|
|
89118
|
+
events2?.onConnecting?.({ relayUrl: eventRelayUrl, room: qrPayload.room });
|
|
88922
89119
|
ws = new WebSocket(url2, relayWebSocketOptions(relayUrl));
|
|
88923
89120
|
ws.addEventListener("open", () => {
|
|
88924
89121
|
console.log(`[relay-client] connected to relay (room: ${qrPayload.room})`);
|
|
88925
89122
|
backoff = INITIAL_BACKOFF_MS;
|
|
88926
|
-
events2?.onConnected?.({ relayUrl:
|
|
89123
|
+
events2?.onConnected?.({ relayUrl: eventRelayUrl, room: qrPayload.room });
|
|
88927
89124
|
});
|
|
88928
89125
|
ws.addEventListener("message", (event) => {
|
|
88929
89126
|
handleRelaySocketMessage(event.data);
|
|
@@ -88931,7 +89128,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
88931
89128
|
ws.addEventListener("close", (event) => {
|
|
88932
89129
|
console.log(`[relay-client] disconnected (code: ${event.code}, reason: ${event.reason})`);
|
|
88933
89130
|
events2?.onClosed?.({
|
|
88934
|
-
relayUrl:
|
|
89131
|
+
relayUrl: eventRelayUrl,
|
|
88935
89132
|
room: qrPayload.room,
|
|
88936
89133
|
code: event.code,
|
|
88937
89134
|
reason: event.reason
|
|
@@ -88942,7 +89139,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
88942
89139
|
ws.addEventListener("error", () => {
|
|
88943
89140
|
const error48 = new Error("Relay websocket error");
|
|
88944
89141
|
console.error("[relay-client] connection error");
|
|
88945
|
-
events2?.onError?.({ relayUrl:
|
|
89142
|
+
events2?.onError?.({ relayUrl: eventRelayUrl, room: qrPayload.room, error: error48 });
|
|
88946
89143
|
});
|
|
88947
89144
|
}
|
|
88948
89145
|
function handleRelaySocketMessage(raw) {
|
|
@@ -88999,7 +89196,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
88999
89196
|
ensureBridgeEventSubscription();
|
|
89000
89197
|
ensureBrokerMessageSubscription();
|
|
89001
89198
|
console.log(`[relay-client] secure handshake complete (peer: ${pubHex.slice(0, 12)}..., trusted: ${peer.trustedPeer}, device: ${peer.deviceId}, client: ${clientId})`);
|
|
89002
|
-
events2?.onPaired?.({ relayUrl:
|
|
89199
|
+
events2?.onPaired?.({ relayUrl: eventRelayUrl, room: qrPayload.room, remotePublicKey });
|
|
89003
89200
|
sendExistingSessions((json2) => {
|
|
89004
89201
|
if (peer.transport.isReady()) {
|
|
89005
89202
|
peer.transport.send(json2);
|
|
@@ -89012,7 +89209,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
89012
89209
|
onError: (err) => {
|
|
89013
89210
|
console.error("[relay-client] secure transport error:", err.message);
|
|
89014
89211
|
log.error("trns:cry", `decrypt failed for ${clientId} \u2014 resetting handshake: ${err.message}`);
|
|
89015
|
-
events2?.onError?.({ relayUrl:
|
|
89212
|
+
events2?.onError?.({ relayUrl: eventRelayUrl, room: qrPayload.room, error: err });
|
|
89016
89213
|
sendRelayClose(clientId, 4002, "Transport reset");
|
|
89017
89214
|
teardownSecurePeer(clientId);
|
|
89018
89215
|
},
|
|
@@ -89249,7 +89446,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
89249
89446
|
if (stopped)
|
|
89250
89447
|
return;
|
|
89251
89448
|
console.log(`[relay-client] reconnecting in ${backoff}ms...`);
|
|
89252
|
-
events2?.onReconnectScheduled?.({ relayUrl:
|
|
89449
|
+
events2?.onReconnectScheduled?.({ relayUrl: eventRelayUrl, room: qrPayload.room, delayMs: backoff });
|
|
89253
89450
|
reconnectTimer = setTimeout(() => {
|
|
89254
89451
|
reconnectTimer = null;
|
|
89255
89452
|
connect();
|
|
@@ -90954,14 +91151,14 @@ var init_dist4 = __esm(() => {
|
|
|
90954
91151
|
|
|
90955
91152
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server-trpc.ts
|
|
90956
91153
|
import { realpathSync as realpathSync5 } from "fs";
|
|
90957
|
-
import { homedir as
|
|
91154
|
+
import { homedir as homedir37 } from "os";
|
|
90958
91155
|
function resolveCurrentDirectory() {
|
|
90959
91156
|
try {
|
|
90960
91157
|
const config2 = resolveConfig();
|
|
90961
91158
|
const configuredRoot = config2.workspace?.root;
|
|
90962
91159
|
if (!configuredRoot)
|
|
90963
91160
|
return process.cwd();
|
|
90964
|
-
const expanded = configuredRoot.replace(/^~/,
|
|
91161
|
+
const expanded = configuredRoot.replace(/^~/, homedir37());
|
|
90965
91162
|
return realpathSync5(expanded);
|
|
90966
91163
|
} catch {
|
|
90967
91164
|
return process.cwd();
|
|
@@ -91469,16 +91666,17 @@ var init_server_trpc = __esm(() => {
|
|
|
91469
91666
|
});
|
|
91470
91667
|
|
|
91471
91668
|
// ../../apps/desktop/src/core/pairing/runtime/runtime.ts
|
|
91472
|
-
import { homedir as
|
|
91669
|
+
import { homedir as homedir38 } from "os";
|
|
91473
91670
|
function createPairingAdapterRegistry(configAdapters) {
|
|
91474
91671
|
const adapters = {
|
|
91475
91672
|
"claude-code": createAdapter,
|
|
91476
91673
|
acp: createAdapter3,
|
|
91477
91674
|
codex: createAdapter2,
|
|
91478
91675
|
"grok-acp": createAdapter4,
|
|
91479
|
-
|
|
91480
|
-
|
|
91481
|
-
|
|
91676
|
+
"kimi-acp": createAdapter5,
|
|
91677
|
+
pi: createAdapter8,
|
|
91678
|
+
opencode: createAdapter7,
|
|
91679
|
+
openai: createAdapter6
|
|
91482
91680
|
};
|
|
91483
91681
|
if (configAdapters) {
|
|
91484
91682
|
for (const [name, entry] of Object.entries(configAdapters)) {
|
|
@@ -91513,34 +91711,105 @@ async function startPairingRuntime(options) {
|
|
|
91513
91711
|
identity: config2.secure ? identity2 : undefined
|
|
91514
91712
|
});
|
|
91515
91713
|
const fileServer = startFileServer({ port: config2.port + 2, bridge });
|
|
91516
|
-
const
|
|
91517
|
-
|
|
91714
|
+
const relayEndpoints = resolveRelayEndpoints(config2, options);
|
|
91715
|
+
const advertisedRelayUrls = dedupeRelayUrls(relayEndpoints.flatMap((endpoint) => [
|
|
91716
|
+
advertisedRelayUrl(endpoint),
|
|
91717
|
+
...endpoint.fallbackRelayUrls ?? []
|
|
91718
|
+
]));
|
|
91719
|
+
const primaryRelayUrl = advertisedRelayUrls[0] ?? null;
|
|
91720
|
+
if (!primaryRelayUrl) {
|
|
91518
91721
|
fileServer.stop();
|
|
91519
91722
|
server.stop();
|
|
91520
91723
|
throw new Error("Pairing relay URL is not configured.");
|
|
91521
91724
|
}
|
|
91522
|
-
const
|
|
91523
|
-
|
|
91524
|
-
|
|
91525
|
-
|
|
91526
|
-
|
|
91527
|
-
|
|
91725
|
+
const qrPayload = createQRPayload(identity2.publicKey, primaryRelayUrl, advertisedRelayUrls.slice(1));
|
|
91726
|
+
let relayConnections = [];
|
|
91727
|
+
try {
|
|
91728
|
+
relayConnections = relayEndpoints.map((endpoint) => connectToRelay(endpoint.relayUrl.trim(), identity2, bridge, {
|
|
91729
|
+
secure: true,
|
|
91730
|
+
publicRelayUrl: advertisedRelayUrl(endpoint),
|
|
91731
|
+
qrPayload,
|
|
91732
|
+
events: options?.relayEvents
|
|
91733
|
+
}));
|
|
91734
|
+
} catch (error48) {
|
|
91735
|
+
for (const relayConnection of relayConnections) {
|
|
91736
|
+
relayConnection.disconnect();
|
|
91737
|
+
}
|
|
91738
|
+
fileServer.stop();
|
|
91739
|
+
server.stop();
|
|
91740
|
+
throw error48;
|
|
91741
|
+
}
|
|
91528
91742
|
await autoStartConfiguredSessions(bridge, config2.sessions);
|
|
91529
91743
|
return {
|
|
91530
91744
|
bridge,
|
|
91531
91745
|
fileServer,
|
|
91532
91746
|
identity: identity2,
|
|
91533
91747
|
config: config2,
|
|
91534
|
-
relayConnection,
|
|
91535
|
-
|
|
91748
|
+
relayConnection: relayConnections[0] ?? null,
|
|
91749
|
+
relayConnections,
|
|
91750
|
+
qrPayload,
|
|
91536
91751
|
async stop() {
|
|
91537
|
-
relayConnection
|
|
91752
|
+
for (const relayConnection of relayConnections) {
|
|
91753
|
+
relayConnection.disconnect();
|
|
91754
|
+
}
|
|
91538
91755
|
fileServer.stop();
|
|
91539
91756
|
await bridge.shutdown();
|
|
91540
91757
|
server.stop();
|
|
91541
91758
|
}
|
|
91542
91759
|
};
|
|
91543
91760
|
}
|
|
91761
|
+
function resolveRelayEndpoints(config2, options) {
|
|
91762
|
+
const explicit = options?.relayEndpoints?.map((endpoint) => ({
|
|
91763
|
+
relayUrl: endpoint.relayUrl.trim(),
|
|
91764
|
+
advertisedRelayUrl: endpoint.advertisedRelayUrl?.trim() || endpoint.relayUrl.trim(),
|
|
91765
|
+
fallbackRelayUrls: endpoint.fallbackRelayUrls
|
|
91766
|
+
})).filter((endpoint) => endpoint.relayUrl.length > 0) ?? [];
|
|
91767
|
+
if (explicit.length > 0) {
|
|
91768
|
+
return dedupeRelayEndpoints(explicit);
|
|
91769
|
+
}
|
|
91770
|
+
const relayUrl = options?.relayUrl?.trim() || config2.relay || null;
|
|
91771
|
+
if (!relayUrl) {
|
|
91772
|
+
return [];
|
|
91773
|
+
}
|
|
91774
|
+
return [{
|
|
91775
|
+
relayUrl,
|
|
91776
|
+
advertisedRelayUrl: options?.advertisedRelayUrl?.trim() || relayUrl,
|
|
91777
|
+
fallbackRelayUrls: options?.fallbackRelayUrls
|
|
91778
|
+
}];
|
|
91779
|
+
}
|
|
91780
|
+
function advertisedRelayUrl(endpoint) {
|
|
91781
|
+
return endpoint.advertisedRelayUrl?.trim() || endpoint.relayUrl.trim();
|
|
91782
|
+
}
|
|
91783
|
+
function dedupeRelayEndpoints(endpoints) {
|
|
91784
|
+
const seen = new Set;
|
|
91785
|
+
const out = [];
|
|
91786
|
+
for (const endpoint of endpoints) {
|
|
91787
|
+
const relayUrl = endpoint.relayUrl.trim();
|
|
91788
|
+
if (!relayUrl || seen.has(relayUrl)) {
|
|
91789
|
+
continue;
|
|
91790
|
+
}
|
|
91791
|
+
seen.add(relayUrl);
|
|
91792
|
+
out.push({
|
|
91793
|
+
relayUrl,
|
|
91794
|
+
advertisedRelayUrl: advertisedRelayUrl(endpoint),
|
|
91795
|
+
fallbackRelayUrls: dedupeRelayUrls(endpoint.fallbackRelayUrls ?? [])
|
|
91796
|
+
});
|
|
91797
|
+
}
|
|
91798
|
+
return out;
|
|
91799
|
+
}
|
|
91800
|
+
function dedupeRelayUrls(urls) {
|
|
91801
|
+
const seen = new Set;
|
|
91802
|
+
const out = [];
|
|
91803
|
+
for (const url2 of urls) {
|
|
91804
|
+
const trimmed = url2.trim();
|
|
91805
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
91806
|
+
continue;
|
|
91807
|
+
}
|
|
91808
|
+
seen.add(trimmed);
|
|
91809
|
+
out.push(trimmed);
|
|
91810
|
+
}
|
|
91811
|
+
return out;
|
|
91812
|
+
}
|
|
91544
91813
|
async function autoStartConfiguredSessions(bridge, sessions4) {
|
|
91545
91814
|
if (!sessions4?.length) {
|
|
91546
91815
|
return;
|
|
@@ -91550,7 +91819,7 @@ async function autoStartConfiguredSessions(bridge, sessions4) {
|
|
|
91550
91819
|
try {
|
|
91551
91820
|
const session3 = await bridge.createSession(entry.adapter, {
|
|
91552
91821
|
name: entry.name,
|
|
91553
|
-
cwd: entry.cwd?.replace(/^~/,
|
|
91822
|
+
cwd: entry.cwd?.replace(/^~/, homedir38()),
|
|
91554
91823
|
options: entry.options
|
|
91555
91824
|
});
|
|
91556
91825
|
console.log(`[bridge] session started: ${session3.name} (${entry.adapter})`);
|
|
@@ -91819,16 +92088,16 @@ function parseRelayEnvelope2(data) {
|
|
|
91819
92088
|
var BRIDGE_ABSENCE_GRACE_MS = 30000, ROOM_IDLE_TIMEOUT_MS = 60000;
|
|
91820
92089
|
|
|
91821
92090
|
// ../../apps/desktop/src/core/pairing/runtime/relay-runtime.ts
|
|
91822
|
-
import { existsSync as
|
|
91823
|
-
import { homedir as
|
|
91824
|
-
import { join as
|
|
92091
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync14 } from "fs";
|
|
92092
|
+
import { homedir as homedir39, networkInterfaces } from "os";
|
|
92093
|
+
import { join as join49 } from "path";
|
|
91825
92094
|
async function findStoredTailscaleCert(hostname6) {
|
|
91826
|
-
if (!
|
|
92095
|
+
if (!existsSync40(PAIRING_DIR2)) {
|
|
91827
92096
|
return null;
|
|
91828
92097
|
}
|
|
91829
|
-
const certPath =
|
|
91830
|
-
const keyPath =
|
|
91831
|
-
if (!
|
|
92098
|
+
const certPath = join49(PAIRING_DIR2, `${hostname6}.crt`);
|
|
92099
|
+
const keyPath = join49(PAIRING_DIR2, `${hostname6}.key`);
|
|
92100
|
+
if (!existsSync40(certPath) || !existsSync40(keyPath)) {
|
|
91832
92101
|
return null;
|
|
91833
92102
|
}
|
|
91834
92103
|
if (!await storedCertificateLooksPubliclyTrusted(certPath)) {
|
|
@@ -91912,8 +92181,8 @@ function resolveRelayEndpointForTailscaleStatus(port, tailscale2, options = {})
|
|
|
91912
92181
|
}
|
|
91913
92182
|
async function generateTailscaleCerts(hostname6) {
|
|
91914
92183
|
mkdirSync14(PAIRING_DIR2, { recursive: true });
|
|
91915
|
-
const certPath =
|
|
91916
|
-
const keyPath =
|
|
92184
|
+
const certPath = join49(PAIRING_DIR2, `${hostname6}.crt`);
|
|
92185
|
+
const keyPath = join49(PAIRING_DIR2, `${hostname6}.key`);
|
|
91917
92186
|
try {
|
|
91918
92187
|
pairingLog.info("relay", "generating tailscale TLS cert", { hostname: hostname6 });
|
|
91919
92188
|
await execSystemFile("tailscale", ["cert", "--cert-file", certPath, "--key-file", keyPath, hostname6], {
|
|
@@ -92040,7 +92309,7 @@ var PAIRING_DIR2;
|
|
|
92040
92309
|
var init_relay_runtime = __esm(() => {
|
|
92041
92310
|
init_system_probes();
|
|
92042
92311
|
init_log2();
|
|
92043
|
-
PAIRING_DIR2 =
|
|
92312
|
+
PAIRING_DIR2 = join49(homedir39(), ".scout/pairing");
|
|
92044
92313
|
});
|
|
92045
92314
|
|
|
92046
92315
|
// ../../node_modules/.bun/uqr@0.1.3/node_modules/uqr/dist/index.mjs
|
|
@@ -92740,20 +93009,41 @@ async function startScoutPairingSession(input) {
|
|
|
92740
93009
|
};
|
|
92741
93010
|
const resolvedRelayUrl = input.forceManagedRelay ? null : input.relayUrl?.trim() || config3.relay;
|
|
92742
93011
|
try {
|
|
92743
|
-
|
|
93012
|
+
let managedRelay = null;
|
|
93013
|
+
try {
|
|
93014
|
+
managedRelay = await startManagedRelay(config3.port + 1);
|
|
93015
|
+
} catch (error48) {
|
|
93016
|
+
if (!resolvedRelayUrl) {
|
|
93017
|
+
throw error48;
|
|
93018
|
+
}
|
|
93019
|
+
const detail = error48 instanceof Error ? error48.message : String(error48);
|
|
93020
|
+
console.warn(`[pairing] managed relay unavailable; continuing with configured relay: ${detail}`);
|
|
93021
|
+
}
|
|
92744
93022
|
relay = managedRelay;
|
|
92745
|
-
const
|
|
92746
|
-
|
|
92747
|
-
|
|
93023
|
+
const relayEndpoints = [
|
|
93024
|
+
...resolvedRelayUrl ? [{
|
|
93025
|
+
relayUrl: resolvedRelayUrl,
|
|
93026
|
+
advertisedRelayUrl: resolvedRelayUrl
|
|
93027
|
+
}] : [],
|
|
93028
|
+
...managedRelay ? [{
|
|
93029
|
+
relayUrl: managedRelay.connectUrl ?? managedRelay.relayUrl,
|
|
93030
|
+
advertisedRelayUrl: managedRelay.relayUrl,
|
|
93031
|
+
fallbackRelayUrls: managedRelay.fallbackRelayUrls
|
|
93032
|
+
}] : []
|
|
93033
|
+
];
|
|
93034
|
+
const advertisedRelayUrls = dedupeRelayUrls2(relayEndpoints.flatMap((endpoint) => [
|
|
93035
|
+
endpoint.advertisedRelayUrl ?? endpoint.relayUrl,
|
|
93036
|
+
...endpoint.fallbackRelayUrls ?? []
|
|
93037
|
+
]));
|
|
93038
|
+
const activeRelayUrl = advertisedRelayUrls[0] ?? null;
|
|
93039
|
+
if (!activeRelayUrl || relayEndpoints.length === 0) {
|
|
92748
93040
|
throw new Error("Scout pairing relay URL is not configured.");
|
|
92749
93041
|
}
|
|
92750
93042
|
runtime2 = await startPairingRuntime({
|
|
92751
|
-
|
|
92752
|
-
advertisedRelayUrl: activeRelayUrl,
|
|
92753
|
-
fallbackRelayUrls: managedRelay?.fallbackRelayUrls,
|
|
93043
|
+
relayEndpoints,
|
|
92754
93044
|
relayEvents: {
|
|
92755
|
-
onConnecting() {
|
|
92756
|
-
emitOrQueue(createStatusEvent("connecting", `Connecting to ${activeRelayUrl}`));
|
|
93045
|
+
onConnecting(detail) {
|
|
93046
|
+
emitOrQueue(createStatusEvent("connecting", `Connecting to ${detail?.relayUrl ?? activeRelayUrl}`));
|
|
92757
93047
|
},
|
|
92758
93048
|
onConnected({ room }) {
|
|
92759
93049
|
emitOrQueue(createStatusEvent("connected", `Relay room ${room} is ready`));
|
|
@@ -92818,6 +93108,19 @@ function freshPairingPayload(pairing) {
|
|
|
92818
93108
|
expiresAt: Date.now() + PAIRING_QR_TTL_MS
|
|
92819
93109
|
};
|
|
92820
93110
|
}
|
|
93111
|
+
function dedupeRelayUrls2(relayUrls) {
|
|
93112
|
+
const seen = new Set;
|
|
93113
|
+
const result = [];
|
|
93114
|
+
for (const relayUrl of relayUrls) {
|
|
93115
|
+
const trimmed = relayUrl.trim();
|
|
93116
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
93117
|
+
continue;
|
|
93118
|
+
}
|
|
93119
|
+
seen.add(trimmed);
|
|
93120
|
+
result.push(trimmed);
|
|
93121
|
+
}
|
|
93122
|
+
return result;
|
|
93123
|
+
}
|
|
92821
93124
|
var init_service7 = __esm(() => {
|
|
92822
93125
|
init_runtime2();
|
|
92823
93126
|
});
|
|
@@ -92989,8 +93292,8 @@ __export(exports_session, {
|
|
|
92989
93292
|
import { spawnSync as spawnSync8 } from "child_process";
|
|
92990
93293
|
import { createHash as createHash6 } from "crypto";
|
|
92991
93294
|
import { mkdirSync as mkdirSync15 } from "fs";
|
|
92992
|
-
import { homedir as
|
|
92993
|
-
import { basename as basename17, join as
|
|
93295
|
+
import { homedir as homedir40 } from "os";
|
|
93296
|
+
import { basename as basename17, join as join50, resolve as resolve27 } from "path";
|
|
92994
93297
|
async function runSessionCommand(context, args) {
|
|
92995
93298
|
const action = args[0];
|
|
92996
93299
|
if (!action || action === "help" || action === "--help" || action === "-h") {
|
|
@@ -93282,7 +93585,7 @@ function readOptionValue(args, index2, flag) {
|
|
|
93282
93585
|
}
|
|
93283
93586
|
function resolveProjectPath2(context, projectPath) {
|
|
93284
93587
|
const rawPath = projectPath?.trim() || context.cwd;
|
|
93285
|
-
const expanded = rawPath === "~" ? context.env.HOME?.trim() ||
|
|
93588
|
+
const expanded = rawPath === "~" ? context.env.HOME?.trim() || homedir40() : rawPath.startsWith("~/") ? resolve27(context.env.HOME?.trim() || homedir40(), rawPath.slice(2)) : rawPath;
|
|
93286
93589
|
return resolve27(context.cwd, expanded);
|
|
93287
93590
|
}
|
|
93288
93591
|
function resolveControlPlaneDbPath2(context) {
|
|
@@ -93290,8 +93593,8 @@ function resolveControlPlaneDbPath2(context) {
|
|
|
93290
93593
|
if (explicitPath) {
|
|
93291
93594
|
return explicitPath;
|
|
93292
93595
|
}
|
|
93293
|
-
const controlHome = context.env.OPENSCOUT_CONTROL_HOME?.trim() ||
|
|
93294
|
-
return
|
|
93596
|
+
const controlHome = context.env.OPENSCOUT_CONTROL_HOME?.trim() || join50(context.env.HOME?.trim() || homedir40(), ".openscout", "control-plane");
|
|
93597
|
+
return join50(controlHome, "control-plane.sqlite");
|
|
93295
93598
|
}
|
|
93296
93599
|
function openTerminalSessionStore(context) {
|
|
93297
93600
|
return new SQLiteControlPlaneStore(resolveControlPlaneDbPath2(context));
|
|
@@ -93415,7 +93718,7 @@ function assertZellijAvailable(context) {
|
|
|
93415
93718
|
}
|
|
93416
93719
|
function resolveZellijSocketDir(context) {
|
|
93417
93720
|
const configured = context.env.ZELLIJ_SOCKET_DIR?.trim() || context.env.OPENSCOUT_ZELLIJ_SOCKET_DIR?.trim();
|
|
93418
|
-
return configured ||
|
|
93721
|
+
return configured || join50(context.env.HOME?.trim() || homedir40(), ".openscout", "zellij-sockets");
|
|
93419
93722
|
}
|
|
93420
93723
|
function zellijEnv(context) {
|
|
93421
93724
|
const socketDir = resolveZellijSocketDir(context);
|
|
@@ -93720,9 +94023,9 @@ __export(exports_server, {
|
|
|
93720
94023
|
normalizeServerOpenPath: () => normalizeServerOpenPath
|
|
93721
94024
|
});
|
|
93722
94025
|
import { spawn as spawn8 } from "child_process";
|
|
93723
|
-
import { existsSync as
|
|
93724
|
-
import { homedir as
|
|
93725
|
-
import { dirname as dirname24, join as
|
|
94026
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync16, openSync as openSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
94027
|
+
import { homedir as homedir41 } from "os";
|
|
94028
|
+
import { dirname as dirname24, join as join51, resolve as resolve28 } from "path";
|
|
93726
94029
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
93727
94030
|
function renderServerCommandHelp() {
|
|
93728
94031
|
return [
|
|
@@ -93966,17 +94269,17 @@ function appendEnvListValues(input, values) {
|
|
|
93966
94269
|
}
|
|
93967
94270
|
function resolveBundledStaticClientRoot(entry, _mode) {
|
|
93968
94271
|
const entryDir = dirname24(entry);
|
|
93969
|
-
const clientDirectory =
|
|
93970
|
-
const indexPath =
|
|
93971
|
-
return
|
|
94272
|
+
const clientDirectory = join51(entryDir, "client");
|
|
94273
|
+
const indexPath = join51(clientDirectory, "index.html");
|
|
94274
|
+
return existsSync41(indexPath) ? clientDirectory : null;
|
|
93972
94275
|
}
|
|
93973
94276
|
function resolveDevCheckoutWebClientRoot(env) {
|
|
93974
94277
|
const setupCwd = env.OPENSCOUT_SETUP_CWD?.trim();
|
|
93975
94278
|
if (!setupCwd)
|
|
93976
94279
|
return null;
|
|
93977
|
-
const clientDirectory =
|
|
93978
|
-
const indexPath =
|
|
93979
|
-
return
|
|
94280
|
+
const clientDirectory = join51(setupCwd, "packages/web/dist/client");
|
|
94281
|
+
const indexPath = join51(clientDirectory, "index.html");
|
|
94282
|
+
return existsSync41(indexPath) ? clientDirectory : null;
|
|
93980
94283
|
}
|
|
93981
94284
|
function resolveBunExecutable4(env) {
|
|
93982
94285
|
const bun = resolveBunExecutable(env);
|
|
@@ -94273,14 +94576,14 @@ async function openBrowser(url2) {
|
|
|
94273
94576
|
});
|
|
94274
94577
|
}
|
|
94275
94578
|
function resolveScoutWebServerLogPath() {
|
|
94276
|
-
const dir =
|
|
94579
|
+
const dir = join51(homedir41(), ".scout", "logs");
|
|
94277
94580
|
mkdirSync16(dir, { recursive: true });
|
|
94278
|
-
return
|
|
94581
|
+
return join51(dir, "web-server.log");
|
|
94279
94582
|
}
|
|
94280
94583
|
function resolveScoutLocalEdgeCaddyfilePath() {
|
|
94281
|
-
const dir =
|
|
94584
|
+
const dir = join51(homedir41(), ".scout", "local-edge");
|
|
94282
94585
|
mkdirSync16(dir, { recursive: true });
|
|
94283
|
-
return
|
|
94586
|
+
return join51(dir, "Caddyfile");
|
|
94284
94587
|
}
|
|
94285
94588
|
function resolveCaddyExecutable2(env) {
|
|
94286
94589
|
return env.OPENSCOUT_CADDY_BIN?.trim() || "caddy";
|
|
@@ -95120,8 +95423,8 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
95120
95423
|
import { resolve as resolve29, dirname as dirname25 } from "path";
|
|
95121
95424
|
import { fileURLToPath as fileURLToPath13 } from "url";
|
|
95122
95425
|
import { resolve as resolve210, isAbsolute as isAbsolute7, parse as parse7 } from "path";
|
|
95123
|
-
import { existsSync as
|
|
95124
|
-
import { basename as basename18, join as
|
|
95426
|
+
import { existsSync as existsSync42 } from "fs";
|
|
95427
|
+
import { basename as basename18, join as join52 } from "path";
|
|
95125
95428
|
import os from "os";
|
|
95126
95429
|
import path2 from "path";
|
|
95127
95430
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
@@ -98412,7 +98715,7 @@ function getBunfsRootPath() {
|
|
|
98412
98715
|
return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
|
|
98413
98716
|
}
|
|
98414
98717
|
function normalizeBunfsPath(fileName) {
|
|
98415
|
-
return
|
|
98718
|
+
return join52(getBunfsRootPath(), basename18(fileName));
|
|
98416
98719
|
}
|
|
98417
98720
|
function addDefaultParsers(parsers) {
|
|
98418
98721
|
for (const parser of parsers) {
|
|
@@ -109334,7 +109637,7 @@ var init_index_vy1rm1x3 = __esm(async () => {
|
|
|
109334
109637
|
worker_path = this.options.workerPath;
|
|
109335
109638
|
} else {
|
|
109336
109639
|
worker_path = new URL("./parser.worker.js", import.meta.url).href;
|
|
109337
|
-
if (!
|
|
109640
|
+
if (!existsSync42(resolve210(import.meta.dirname, "parser.worker.js"))) {
|
|
109338
109641
|
worker_path = new URL("./parser.worker.ts", import.meta.url).href;
|
|
109339
109642
|
}
|
|
109340
109643
|
}
|
|
@@ -156626,7 +156929,7 @@ var exports_up = {};
|
|
|
156626
156929
|
__export(exports_up, {
|
|
156627
156930
|
runUpCommand: () => runUpCommand
|
|
156628
156931
|
});
|
|
156629
|
-
import { existsSync as
|
|
156932
|
+
import { existsSync as existsSync43 } from "fs";
|
|
156630
156933
|
import { resolve as resolve31 } from "path";
|
|
156631
156934
|
function looksLikePath(value) {
|
|
156632
156935
|
return value.includes("/") || value.startsWith(".") || value.startsWith("~");
|
|
@@ -156735,7 +157038,7 @@ async function runUpCommand(context, args) {
|
|
|
156735
157038
|
throw new ScoutCliError(`usage: scout up <name|path> [--name <alias>] [--harness <claude|codex|grok|pi>] [--provider <provider>] [--model <model>] [--reasoning-effort <effort>] [--permission-profile <${formatScoutPermissionProfiles()}>]`);
|
|
156736
157039
|
}
|
|
156737
157040
|
let projectPath;
|
|
156738
|
-
if (looksLikePath(target) ||
|
|
157041
|
+
if (looksLikePath(target) || existsSync43(resolve31(target))) {
|
|
156739
157042
|
projectPath = resolve31(target);
|
|
156740
157043
|
} else {
|
|
156741
157044
|
const resolved = await resolveLocalAgentByName(target);
|
|
@@ -157193,13 +157496,13 @@ __export(exports_whoami, {
|
|
|
157193
157496
|
renderWhoAmICommandHelp: () => renderWhoAmICommandHelp
|
|
157194
157497
|
});
|
|
157195
157498
|
import { access as access2 } from "fs/promises";
|
|
157196
|
-
import { join as
|
|
157499
|
+
import { join as join55 } from "path";
|
|
157197
157500
|
async function resolveProjectAgentsMd(projectRoot) {
|
|
157198
157501
|
if (!projectRoot) {
|
|
157199
157502
|
return null;
|
|
157200
157503
|
}
|
|
157201
157504
|
for (const candidate of PROJECT_AGENT_INSTRUCTION_CANDIDATES) {
|
|
157202
|
-
const path6 =
|
|
157505
|
+
const path6 = join55(projectRoot, candidate);
|
|
157203
157506
|
try {
|
|
157204
157507
|
await access2(path6);
|
|
157205
157508
|
return path6;
|
|
@@ -157279,10 +157582,10 @@ var init_whoami = __esm(() => {
|
|
|
157279
157582
|
});
|
|
157280
157583
|
|
|
157281
157584
|
// ../../apps/desktop/src/cli/main.ts
|
|
157282
|
-
import { existsSync as
|
|
157283
|
-
import { join as
|
|
157585
|
+
import { existsSync as existsSync44, readFileSync as readFileSync22, writeFileSync as writeFileSync13, statSync as statSync9, mkdirSync as mkdirSync17, unlinkSync as unlinkSync4 } from "fs";
|
|
157586
|
+
import { join as join56 } from "path";
|
|
157284
157587
|
import { spawnSync as spawnSync9 } from "child_process";
|
|
157285
|
-
import { homedir as
|
|
157588
|
+
import { homedir as homedir42 } from "os";
|
|
157286
157589
|
|
|
157287
157590
|
// ../../apps/desktop/src/cli/argv.ts
|
|
157288
157591
|
function parseScoutArgv(argv) {
|
|
@@ -157648,8 +157951,8 @@ var _scoutBinPath = null;
|
|
|
157648
157951
|
function getScoutBinPath() {
|
|
157649
157952
|
if (_scoutBinPath)
|
|
157650
157953
|
return _scoutBinPath;
|
|
157651
|
-
_scoutBinPath =
|
|
157652
|
-
if (!
|
|
157954
|
+
_scoutBinPath = join56(homedir42(), ".bun", "bin", "scout");
|
|
157955
|
+
if (!existsSync44(_scoutBinPath)) {
|
|
157653
157956
|
_scoutBinPath = spawnSync9("which", ["scout"], { encoding: "utf8" }).stdout.trim();
|
|
157654
157957
|
}
|
|
157655
157958
|
return _scoutBinPath;
|
|
@@ -157692,7 +157995,7 @@ async function ensureBrokerUptodate(report = () => {
|
|
|
157692
157995
|
return;
|
|
157693
157996
|
}
|
|
157694
157997
|
const mtimePath = cliMtimeCheckpointPath();
|
|
157695
|
-
const lastMtime =
|
|
157998
|
+
const lastMtime = existsSync44(mtimePath) ? Number(readFileSync22(mtimePath, "utf8").trim()) : 0;
|
|
157696
157999
|
if (shouldRestartBrokerForCliMtime(mtime, lastMtime)) {
|
|
157697
158000
|
report("Scout CLI changed on disk; restarting the broker service to load the updated runtime.");
|
|
157698
158001
|
await restartBrokerServiceWithLaunchctl();
|
|
@@ -157702,17 +158005,17 @@ async function ensureBrokerUptodate(report = () => {
|
|
|
157702
158005
|
}
|
|
157703
158006
|
function readCurrentCliMtime() {
|
|
157704
158007
|
try {
|
|
157705
|
-
return normalizeCliBinaryMtimeMs(
|
|
158008
|
+
return normalizeCliBinaryMtimeMs(statSync9(getScoutBinPath()).mtimeMs);
|
|
157706
158009
|
} catch {
|
|
157707
158010
|
return null;
|
|
157708
158011
|
}
|
|
157709
158012
|
}
|
|
157710
158013
|
function cliMtimeCheckpointPath() {
|
|
157711
|
-
return
|
|
158014
|
+
return join56(homedir42(), ".scout", "cli-mtime");
|
|
157712
158015
|
}
|
|
157713
158016
|
function writeCliMtimeCheckpoint(mtime) {
|
|
157714
|
-
const checkpointDir =
|
|
157715
|
-
if (!
|
|
158017
|
+
const checkpointDir = join56(homedir42(), ".scout");
|
|
158018
|
+
if (!existsSync44(checkpointDir)) {
|
|
157716
158019
|
mkdirSync17(checkpointDir, { recursive: true });
|
|
157717
158020
|
}
|
|
157718
158021
|
writeFileSync13(cliMtimeCheckpointPath(), String(mtime), { encoding: "utf8", flag: "w" });
|
|
@@ -157735,7 +158038,7 @@ async function restartBrokerServiceWithLaunchctl() {
|
|
|
157735
158038
|
for (const legacyLabel of legacyBrokerServiceLabels(config3.mode)) {
|
|
157736
158039
|
spawnSync9("launchctl", ["bootout", `gui/${uid}/${legacyLabel}`], { stdio: "ignore" });
|
|
157737
158040
|
try {
|
|
157738
|
-
unlinkSync4(
|
|
158041
|
+
unlinkSync4(join56(homedir42(), "Library", "LaunchAgents", `${legacyLabel}.plist`));
|
|
157739
158042
|
} catch {}
|
|
157740
158043
|
}
|
|
157741
158044
|
spawnSync9("launchctl", ["bootout", `gui/${uid}/${config3.label}`], { stdio: "ignore" });
|