@openscout/scout 0.2.57 → 0.2.58
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/README.md +2 -2
- package/dist/client/assets/{arc.es-Ccqmb9Pq.js → arc.es-Bkj9Bkvx.js} +1 -1
- package/dist/client/assets/index-BDyu05Hi.js +140 -0
- package/dist/client/assets/index-pbcZpgCR.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/main.mjs +286 -130
- package/dist/pair-supervisor.mjs +151 -42
- package/dist/scout-control-plane-web.mjs +1085 -889
- package/package.json +2 -2
- package/dist/client/assets/index-CN8PCsrs.css +0 -1
- package/dist/client/assets/index-X8QwrbtL.js +0 -140
package/dist/main.mjs
CHANGED
|
@@ -2277,6 +2277,7 @@ function createBuiltInHarnessCatalog() {
|
|
|
2277
2277
|
anyOf: entry.readiness.anyOf ? [...entry.readiness.anyOf] : undefined
|
|
2278
2278
|
} : undefined,
|
|
2279
2279
|
launch: entry.launch ? { ...entry.launch, args: [...entry.launch.args] } : undefined,
|
|
2280
|
+
resume: entry.resume ? { ...entry.resume } : undefined,
|
|
2280
2281
|
resolveEnv: entry.resolveEnv ? [...entry.resolveEnv] : undefined,
|
|
2281
2282
|
capabilities: [...entry.capabilities],
|
|
2282
2283
|
metadata: entry.metadata ? { ...entry.metadata } : undefined
|
|
@@ -2294,6 +2295,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
2294
2295
|
install: mergeInstall(entry.install, override.install),
|
|
2295
2296
|
readiness: mergeReadiness(entry.readiness, override.readiness),
|
|
2296
2297
|
launch: mergeLaunch(entry.launch, override.launch),
|
|
2298
|
+
resume: override.resume && entry.resume ? { ...entry.resume, ...override.resume } : entry.resume,
|
|
2297
2299
|
tags: override.tags ? [...override.tags] : entry.tags,
|
|
2298
2300
|
capabilities: override.capabilities ? [...override.capabilities] : entry.capabilities,
|
|
2299
2301
|
resolveEnv: override.resolveEnv ? [...override.resolveEnv] : entry.resolveEnv,
|
|
@@ -2322,6 +2324,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
2322
2324
|
install: mergeInstall(undefined, override.install),
|
|
2323
2325
|
readiness: mergeReadiness(undefined, override.readiness),
|
|
2324
2326
|
launch: mergeLaunch(undefined, override.launch),
|
|
2327
|
+
resume: override.resume?.command && override.resume?.sessionFlag ? { command: override.resume.command, sessionFlag: override.resume.sessionFlag, cwdFlag: override.resume.cwdFlag } : undefined,
|
|
2325
2328
|
resolveEnv: override.resolveEnv ? [...override.resolveEnv] : undefined,
|
|
2326
2329
|
capabilities: [...override.capabilities],
|
|
2327
2330
|
metadata: override.metadata ? { ...override.metadata } : undefined
|
|
@@ -2474,6 +2477,11 @@ var init_harness_catalog = __esm(() => {
|
|
|
2474
2477
|
loginCommand: "claude login",
|
|
2475
2478
|
notReadyMessage: "Claude is installed but not authenticated yet."
|
|
2476
2479
|
},
|
|
2480
|
+
resume: {
|
|
2481
|
+
command: "claude",
|
|
2482
|
+
sessionFlag: "--resume",
|
|
2483
|
+
cwdFlag: "--cwd"
|
|
2484
|
+
},
|
|
2477
2485
|
capabilities: ["chat", "invoke", "deliver", "summarize", "review"]
|
|
2478
2486
|
},
|
|
2479
2487
|
{
|
|
@@ -2505,6 +2513,11 @@ var init_harness_catalog = __esm(() => {
|
|
|
2505
2513
|
loginCommand: "codex login",
|
|
2506
2514
|
notReadyMessage: "Codex is installed but not authenticated yet."
|
|
2507
2515
|
},
|
|
2516
|
+
resume: {
|
|
2517
|
+
command: "codex",
|
|
2518
|
+
sessionFlag: "--thread",
|
|
2519
|
+
cwdFlag: "--cwd"
|
|
2520
|
+
},
|
|
2508
2521
|
capabilities: ["chat", "invoke", "deliver", "review", "execute"]
|
|
2509
2522
|
}
|
|
2510
2523
|
];
|
|
@@ -4684,7 +4697,8 @@ function buildManagedAgentShellExports(options) {
|
|
|
4684
4697
|
// ../runtime/src/claude-stream-json.ts
|
|
4685
4698
|
import { randomUUID } from "crypto";
|
|
4686
4699
|
import { spawn } from "child_process";
|
|
4687
|
-
import { appendFile, mkdir as mkdir3, readFile as readFile4,
|
|
4700
|
+
import { appendFile, mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
4701
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
4688
4702
|
import { join as join5 } from "path";
|
|
4689
4703
|
function resolveClaudeStreamJsonOutput(result, fallbackParts) {
|
|
4690
4704
|
const trimmedResult = result?.trim();
|
|
@@ -4699,19 +4713,57 @@ function sessionKey(options) {
|
|
|
4699
4713
|
function errorMessage(error) {
|
|
4700
4714
|
return error instanceof Error ? error.message : String(error);
|
|
4701
4715
|
}
|
|
4702
|
-
|
|
4716
|
+
function readSessionCatalogSync(runtimeDirectory) {
|
|
4717
|
+
const catalogPath = join5(runtimeDirectory, SESSION_CATALOG_FILENAME);
|
|
4703
4718
|
try {
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4719
|
+
if (!existsSync4(catalogPath)) {
|
|
4720
|
+
const legacyPath = join5(runtimeDirectory, "claude-session-id.txt");
|
|
4721
|
+
if (existsSync4(legacyPath)) {
|
|
4722
|
+
const legacyId = readFileSync2(legacyPath, "utf8").trim();
|
|
4723
|
+
if (legacyId) {
|
|
4724
|
+
return {
|
|
4725
|
+
activeSessionId: legacyId,
|
|
4726
|
+
sessions: [{ id: legacyId, startedAt: Date.now(), cwd: "" }]
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
return { activeSessionId: null, sessions: [] };
|
|
4731
|
+
}
|
|
4732
|
+
const raw = readFileSync2(catalogPath, "utf8").trim();
|
|
4733
|
+
if (!raw)
|
|
4734
|
+
return { activeSessionId: null, sessions: [] };
|
|
4735
|
+
const parsed = JSON.parse(raw);
|
|
4736
|
+
return {
|
|
4737
|
+
activeSessionId: parsed.activeSessionId ?? null,
|
|
4738
|
+
sessions: Array.isArray(parsed.sessions) ? parsed.sessions : []
|
|
4739
|
+
};
|
|
4707
4740
|
} catch {
|
|
4708
|
-
return null;
|
|
4741
|
+
return { activeSessionId: null, sessions: [] };
|
|
4709
4742
|
}
|
|
4710
4743
|
}
|
|
4744
|
+
async function readSessionCatalog(runtimeDirectory) {
|
|
4745
|
+
return readSessionCatalogSync(runtimeDirectory);
|
|
4746
|
+
}
|
|
4747
|
+
async function writeSessionCatalog(runtimeDirectory, catalog) {
|
|
4748
|
+
const catalogPath = join5(runtimeDirectory, SESSION_CATALOG_FILENAME);
|
|
4749
|
+
await writeFile3(catalogPath, JSON.stringify(catalog, null, 2) + `
|
|
4750
|
+
`);
|
|
4751
|
+
}
|
|
4752
|
+
function catalogRecordSession(catalog, sessionId, cwd) {
|
|
4753
|
+
const now = Date.now();
|
|
4754
|
+
const sessions = catalog.sessions.map((s) => s.id === catalog.activeSessionId && !s.endedAt ? { ...s, endedAt: now } : s);
|
|
4755
|
+
if (!sessions.some((s) => s.id === sessionId)) {
|
|
4756
|
+
sessions.push({ id: sessionId, startedAt: now, cwd });
|
|
4757
|
+
}
|
|
4758
|
+
while (sessions.length > SESSION_CATALOG_MAX_ENTRIES) {
|
|
4759
|
+
sessions.shift();
|
|
4760
|
+
}
|
|
4761
|
+
return { activeSessionId: sessionId, sessions };
|
|
4762
|
+
}
|
|
4711
4763
|
|
|
4712
4764
|
class ClaudeStreamJsonSession {
|
|
4713
4765
|
options;
|
|
4714
|
-
|
|
4766
|
+
catalogDirectory;
|
|
4715
4767
|
stdoutLogPath;
|
|
4716
4768
|
stderrLogPath;
|
|
4717
4769
|
process = null;
|
|
@@ -4722,7 +4774,7 @@ class ClaudeStreamJsonSession {
|
|
|
4722
4774
|
lastConfigSignature;
|
|
4723
4775
|
constructor(options) {
|
|
4724
4776
|
this.options = options;
|
|
4725
|
-
this.
|
|
4777
|
+
this.catalogDirectory = options.runtimeDirectory;
|
|
4726
4778
|
this.stdoutLogPath = join5(options.logsDirectory, "stdout.log");
|
|
4727
4779
|
this.stderrLogPath = join5(options.logsDirectory, "stderr.log");
|
|
4728
4780
|
this.lastConfigSignature = this.configSignature(options);
|
|
@@ -4828,7 +4880,9 @@ class ClaudeStreamJsonSession {
|
|
|
4828
4880
|
}
|
|
4829
4881
|
if (options.resetSession) {
|
|
4830
4882
|
this.claudeSessionId = null;
|
|
4831
|
-
await
|
|
4883
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
4884
|
+
catalog.activeSessionId = null;
|
|
4885
|
+
await writeSessionCatalog(this.catalogDirectory, catalog);
|
|
4832
4886
|
}
|
|
4833
4887
|
}
|
|
4834
4888
|
configSignature(options) {
|
|
@@ -4857,7 +4911,8 @@ class ClaudeStreamJsonSession {
|
|
|
4857
4911
|
await mkdir3(this.options.runtimeDirectory, { recursive: true });
|
|
4858
4912
|
await mkdir3(this.options.logsDirectory, { recursive: true });
|
|
4859
4913
|
await writeFile3(join5(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
|
|
4860
|
-
|
|
4914
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
4915
|
+
this.claudeSessionId = catalog.activeSessionId;
|
|
4861
4916
|
const args = [
|
|
4862
4917
|
"--verbose",
|
|
4863
4918
|
"--print",
|
|
@@ -4936,8 +4991,11 @@ class ClaudeStreamJsonSession {
|
|
|
4936
4991
|
const nextSessionId = event.session_id ?? event.sessionId ?? null;
|
|
4937
4992
|
if (nextSessionId && nextSessionId !== this.claudeSessionId) {
|
|
4938
4993
|
this.claudeSessionId = nextSessionId;
|
|
4939
|
-
|
|
4940
|
-
|
|
4994
|
+
(async () => {
|
|
4995
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
4996
|
+
const updated = catalogRecordSession(catalog, nextSessionId, this.options.cwd);
|
|
4997
|
+
await writeSessionCatalog(this.catalogDirectory, updated);
|
|
4998
|
+
})();
|
|
4941
4999
|
}
|
|
4942
5000
|
return;
|
|
4943
5001
|
}
|
|
@@ -5000,14 +5058,16 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
|
|
|
5000
5058
|
const session = sessions.get(key);
|
|
5001
5059
|
if (!session) {
|
|
5002
5060
|
if (shutdownOptions.resetSession) {
|
|
5003
|
-
await
|
|
5061
|
+
const catalog = await readSessionCatalog(options.runtimeDirectory);
|
|
5062
|
+
catalog.activeSessionId = null;
|
|
5063
|
+
await writeSessionCatalog(options.runtimeDirectory, catalog);
|
|
5004
5064
|
}
|
|
5005
5065
|
return;
|
|
5006
5066
|
}
|
|
5007
5067
|
sessions.delete(key);
|
|
5008
5068
|
await session.shutdown(shutdownOptions);
|
|
5009
5069
|
}
|
|
5010
|
-
var sessions;
|
|
5070
|
+
var SESSION_CATALOG_FILENAME = "session-catalog.json", SESSION_CATALOG_MAX_ENTRIES = 64, sessions;
|
|
5011
5071
|
var init_claude_stream_json = __esm(() => {
|
|
5012
5072
|
sessions = new Map;
|
|
5013
5073
|
});
|
|
@@ -6184,7 +6244,7 @@ class ClaudeCodeHistoryParser {
|
|
|
6184
6244
|
var init_history = () => {};
|
|
6185
6245
|
|
|
6186
6246
|
// ../agent-sessions/src/adapters/claude-code.ts
|
|
6187
|
-
import { existsSync as
|
|
6247
|
+
import { existsSync as existsSync5, readdirSync, statSync as statSync2 } from "fs";
|
|
6188
6248
|
import { homedir as homedir4 } from "os";
|
|
6189
6249
|
import { join as join6 } from "path";
|
|
6190
6250
|
function resolveClaudeResumeContext(config) {
|
|
@@ -6194,7 +6254,7 @@ function resolveClaudeResumeContext(config) {
|
|
|
6194
6254
|
return null;
|
|
6195
6255
|
}
|
|
6196
6256
|
const projectsRoot = join6(homedir4(), ".claude", "projects");
|
|
6197
|
-
if (!
|
|
6257
|
+
if (!existsSync5(projectsRoot)) {
|
|
6198
6258
|
return null;
|
|
6199
6259
|
}
|
|
6200
6260
|
let projectSlugs;
|
|
@@ -6205,7 +6265,7 @@ function resolveClaudeResumeContext(config) {
|
|
|
6205
6265
|
}
|
|
6206
6266
|
for (const slug of projectSlugs) {
|
|
6207
6267
|
const sessionPath = join6(projectsRoot, slug, `${resumeId}.jsonl`);
|
|
6208
|
-
if (!
|
|
6268
|
+
if (!existsSync5(sessionPath)) {
|
|
6209
6269
|
continue;
|
|
6210
6270
|
}
|
|
6211
6271
|
const cwd = decodeClaudeProjectsSlug2(slug);
|
|
@@ -6746,7 +6806,7 @@ Referenced files: ${prompt.files.join(", ")}` });
|
|
|
6746
6806
|
});
|
|
6747
6807
|
|
|
6748
6808
|
// ../agent-sessions/src/codex-launch-config.ts
|
|
6749
|
-
import { accessSync, constants, existsSync as
|
|
6809
|
+
import { accessSync, constants, existsSync as existsSync6 } from "fs";
|
|
6750
6810
|
import { homedir as homedir5 } from "os";
|
|
6751
6811
|
import { basename as basename2, delimiter, dirname as dirname4, join as join7, resolve as resolve5 } from "path";
|
|
6752
6812
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -6830,7 +6890,7 @@ function resolveRepoScoutScript(currentDirectory) {
|
|
|
6830
6890
|
for (const start of starts) {
|
|
6831
6891
|
for (const candidate of ancestorChain(start)) {
|
|
6832
6892
|
const scriptPath = join7(candidate, "apps", "desktop", "bin", "scout.ts");
|
|
6833
|
-
if (
|
|
6893
|
+
if (existsSync6(scriptPath)) {
|
|
6834
6894
|
return scriptPath;
|
|
6835
6895
|
}
|
|
6836
6896
|
}
|
|
@@ -6920,7 +6980,7 @@ function errorMessage2(error) {
|
|
|
6920
6980
|
}
|
|
6921
6981
|
return String(error);
|
|
6922
6982
|
}
|
|
6923
|
-
async function
|
|
6983
|
+
async function readOptionalFile(filePath) {
|
|
6924
6984
|
try {
|
|
6925
6985
|
const raw = await readFile5(filePath, "utf8");
|
|
6926
6986
|
const trimmed = raw.trim();
|
|
@@ -7267,7 +7327,7 @@ var init_codex = __esm(() => {
|
|
|
7267
7327
|
async resumeOrStartThread() {
|
|
7268
7328
|
const options = this.codexOptions;
|
|
7269
7329
|
const requestedThreadId = options.threadId?.trim() || null;
|
|
7270
|
-
const storedThreadId = requestedThreadId ?? await
|
|
7330
|
+
const storedThreadId = requestedThreadId ?? await readOptionalFile(this.threadIdPath);
|
|
7271
7331
|
if (storedThreadId) {
|
|
7272
7332
|
try {
|
|
7273
7333
|
const resumed = await this.request("thread/resume", {
|
|
@@ -9483,7 +9543,7 @@ function isServerRequest2(message) {
|
|
|
9483
9543
|
function isNotification2(message) {
|
|
9484
9544
|
return Boolean(message && typeof message === "object" && "method" in message && !("id" in message));
|
|
9485
9545
|
}
|
|
9486
|
-
async function
|
|
9546
|
+
async function readOptionalFile2(filePath) {
|
|
9487
9547
|
try {
|
|
9488
9548
|
const raw = await readFile6(filePath, "utf8");
|
|
9489
9549
|
const trimmed = raw.trim();
|
|
@@ -9760,7 +9820,7 @@ class CodexAppServerSession {
|
|
|
9760
9820
|
}
|
|
9761
9821
|
async resumeOrStartThread() {
|
|
9762
9822
|
const requestedThreadId = this.options.threadId?.trim() || null;
|
|
9763
|
-
const storedThreadId = requestedThreadId ?? await
|
|
9823
|
+
const storedThreadId = requestedThreadId ?? await readOptionalFile2(this.threadIdPath);
|
|
9764
9824
|
if (storedThreadId) {
|
|
9765
9825
|
try {
|
|
9766
9826
|
const resumed = await this.request("thread/resume", {
|
|
@@ -10191,7 +10251,7 @@ function buildCollaborationContractPrompt(agentId) {
|
|
|
10191
10251
|
|
|
10192
10252
|
// ../runtime/src/broker-service.ts
|
|
10193
10253
|
import { spawnSync } from "child_process";
|
|
10194
|
-
import { existsSync as
|
|
10254
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
10195
10255
|
import { homedir as homedir7 } from "os";
|
|
10196
10256
|
import { basename as basename3, dirname as dirname5, join as join10, resolve as resolve6 } from "path";
|
|
10197
10257
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -10230,7 +10290,7 @@ function runtimePackageDir() {
|
|
|
10230
10290
|
return resolve6(moduleDir, "..");
|
|
10231
10291
|
}
|
|
10232
10292
|
function isInstalledRuntimePackageDir(candidate) {
|
|
10233
|
-
return
|
|
10293
|
+
return existsSync7(join10(candidate, "package.json")) && existsSync7(join10(candidate, "bin", "openscout-runtime.mjs"));
|
|
10234
10294
|
}
|
|
10235
10295
|
function findGlobalRuntimeDir() {
|
|
10236
10296
|
const candidates = [
|
|
@@ -10261,7 +10321,7 @@ function findWorkspaceRuntimeDir(startDir) {
|
|
|
10261
10321
|
let current = resolve6(startDir);
|
|
10262
10322
|
while (true) {
|
|
10263
10323
|
const candidate = join10(current, "packages", "runtime");
|
|
10264
|
-
if (
|
|
10324
|
+
if (existsSync7(join10(candidate, "package.json")) && existsSync7(join10(candidate, "src"))) {
|
|
10265
10325
|
return candidate;
|
|
10266
10326
|
}
|
|
10267
10327
|
const parent = dirname5(current);
|
|
@@ -10275,18 +10335,18 @@ function resolveBunExecutable2() {
|
|
|
10275
10335
|
if (explicit && explicit.trim().length > 0) {
|
|
10276
10336
|
return explicit;
|
|
10277
10337
|
}
|
|
10278
|
-
if (basename3(process.execPath).startsWith("bun") &&
|
|
10338
|
+
if (basename3(process.execPath).startsWith("bun") && existsSync7(process.execPath)) {
|
|
10279
10339
|
return process.execPath;
|
|
10280
10340
|
}
|
|
10281
10341
|
const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
|
|
10282
10342
|
for (const entry of pathEntries) {
|
|
10283
10343
|
const candidate = join10(entry, "bun");
|
|
10284
|
-
if (
|
|
10344
|
+
if (existsSync7(candidate)) {
|
|
10285
10345
|
return candidate;
|
|
10286
10346
|
}
|
|
10287
10347
|
}
|
|
10288
10348
|
const homeBun = join10(homedir7(), ".bun", "bin", "bun");
|
|
10289
|
-
if (
|
|
10349
|
+
if (existsSync7(homeBun)) {
|
|
10290
10350
|
return homeBun;
|
|
10291
10351
|
}
|
|
10292
10352
|
return "bun";
|
|
@@ -10476,10 +10536,10 @@ function launchctlPath() {
|
|
|
10476
10536
|
return "/bin/launchctl";
|
|
10477
10537
|
}
|
|
10478
10538
|
function readLogLines(path) {
|
|
10479
|
-
if (!
|
|
10539
|
+
if (!existsSync7(path)) {
|
|
10480
10540
|
return [];
|
|
10481
10541
|
}
|
|
10482
|
-
return
|
|
10542
|
+
return readFileSync3(path, "utf8").split(`
|
|
10483
10543
|
`).map((line) => line.trim()).filter(Boolean);
|
|
10484
10544
|
}
|
|
10485
10545
|
function isPackageScriptBanner(line) {
|
|
@@ -10576,7 +10636,7 @@ async function brokerServiceStatus(config = resolveBrokerServiceConfig()) {
|
|
|
10576
10636
|
ensureServiceDirectories(config);
|
|
10577
10637
|
const launchctl = inspectLaunchctl(config);
|
|
10578
10638
|
const health = await fetchHealthSnapshot(config);
|
|
10579
|
-
const installed =
|
|
10639
|
+
const installed = existsSync7(config.launchAgentPath);
|
|
10580
10640
|
const lastLogLine = health.reachable ? readLastLogLine([config.stdoutLogPath, config.stderrLogPath]) : readLastLogLine([config.stderrLogPath, config.stdoutLogPath]);
|
|
10581
10641
|
return {
|
|
10582
10642
|
label: config.label,
|
|
@@ -10638,7 +10698,7 @@ async function restartBrokerService(config = resolveBrokerServiceConfig()) {
|
|
|
10638
10698
|
}
|
|
10639
10699
|
async function uninstallBrokerService(config = resolveBrokerServiceConfig()) {
|
|
10640
10700
|
await stopBrokerService(config);
|
|
10641
|
-
if (
|
|
10701
|
+
if (existsSync7(config.launchAgentPath)) {
|
|
10642
10702
|
rmSync2(config.launchAgentPath, { force: true });
|
|
10643
10703
|
}
|
|
10644
10704
|
return brokerServiceStatus(config);
|
|
@@ -10717,7 +10777,7 @@ var init_local_agent_template = __esm(() => {
|
|
|
10717
10777
|
|
|
10718
10778
|
// ../runtime/src/local-agents.ts
|
|
10719
10779
|
import { execFileSync as execFileSync3, execSync } from "child_process";
|
|
10720
|
-
import { existsSync as
|
|
10780
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
|
|
10721
10781
|
import { mkdir as mkdir6, rm as rm5, stat as stat3, writeFile as writeFile6 } from "fs/promises";
|
|
10722
10782
|
import { basename as basename4, dirname as dirname6, join as join11, resolve as resolve7 } from "path";
|
|
10723
10783
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
@@ -10730,10 +10790,10 @@ function resolveProjectsRoot(projectPath) {
|
|
|
10730
10790
|
}
|
|
10731
10791
|
try {
|
|
10732
10792
|
const supportPaths = resolveOpenScoutSupportPaths();
|
|
10733
|
-
if (!
|
|
10793
|
+
if (!existsSync8(supportPaths.settingsPath)) {
|
|
10734
10794
|
return dirname6(projectPath);
|
|
10735
10795
|
}
|
|
10736
|
-
const raw = JSON.parse(
|
|
10796
|
+
const raw = JSON.parse(readFileSync4(supportPaths.settingsPath, "utf8"));
|
|
10737
10797
|
const workspaceRoot = raw.discovery?.workspaceRoots?.find((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
10738
10798
|
return workspaceRoot ? resolve7(workspaceRoot) : dirname6(projectPath);
|
|
10739
10799
|
} catch {
|
|
@@ -10746,8 +10806,14 @@ function resolveBrokerUrl() {
|
|
|
10746
10806
|
function nowSeconds2() {
|
|
10747
10807
|
return Math.floor(Date.now() / 1000);
|
|
10748
10808
|
}
|
|
10809
|
+
function scoutCliPath() {
|
|
10810
|
+
return join11(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
|
|
10811
|
+
}
|
|
10812
|
+
function legacyNodeBrokerRelayCommand() {
|
|
10813
|
+
return `node ${JSON.stringify(scoutCliPath())}`;
|
|
10814
|
+
}
|
|
10749
10815
|
function brokerRelayCommand() {
|
|
10750
|
-
return `
|
|
10816
|
+
return `bun ${JSON.stringify(scoutCliPath())}`;
|
|
10751
10817
|
}
|
|
10752
10818
|
function titleCaseLocalAgentName(value) {
|
|
10753
10819
|
return value.split(/[-_.\s]+/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
|
|
@@ -10760,7 +10826,7 @@ function resolveScoutSkillPath() {
|
|
|
10760
10826
|
join11(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
|
|
10761
10827
|
];
|
|
10762
10828
|
for (const path of candidatePaths) {
|
|
10763
|
-
if (
|
|
10829
|
+
if (existsSync8(path)) {
|
|
10764
10830
|
return path;
|
|
10765
10831
|
}
|
|
10766
10832
|
}
|
|
@@ -10956,7 +11022,7 @@ function buildLegacyBrokerBackedRelayPrompt(agentId, projectName, projectPath, r
|
|
|
10956
11022
|
function legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath) {
|
|
10957
11023
|
const relayHub = resolveRelayHub();
|
|
10958
11024
|
const brokerUrl = resolveBrokerUrl();
|
|
10959
|
-
const relayCommandBases = ["openscout relay", brokerRelayCommand()];
|
|
11025
|
+
const relayCommandBases = ["openscout relay", brokerRelayCommand(), legacyNodeBrokerRelayCommand()];
|
|
10960
11026
|
const projectPathCandidates = projectPath.endsWith("/") ? [projectPath, projectPath.slice(0, -1)] : [projectPath, `${projectPath}/`];
|
|
10961
11027
|
const candidates = new Set;
|
|
10962
11028
|
for (const pathCandidate of projectPathCandidates) {
|
|
@@ -10967,12 +11033,28 @@ function legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPat
|
|
|
10967
11033
|
}
|
|
10968
11034
|
return Array.from(candidates);
|
|
10969
11035
|
}
|
|
11036
|
+
function generatedLocalAgentSystemPromptCandidates(agentId, projectName, projectPath) {
|
|
11037
|
+
const baseContext = buildLocalAgentTemplateContext(agentId, projectName, projectPath);
|
|
11038
|
+
const relayCommands = [brokerRelayCommand(), legacyNodeBrokerRelayCommand()];
|
|
11039
|
+
const transportModes = [undefined, "codex_app_server", "claude_stream_json"];
|
|
11040
|
+
const candidates = new Set;
|
|
11041
|
+
for (const relayCommand of relayCommands) {
|
|
11042
|
+
const context = {
|
|
11043
|
+
...baseContext,
|
|
11044
|
+
relayCommand
|
|
11045
|
+
};
|
|
11046
|
+
for (const transport of transportModes) {
|
|
11047
|
+
candidates.add(renderLocalAgentSystemPromptTemplate(buildLocalAgentSystemPromptTemplate(), context, transport ? { transport } : {}));
|
|
11048
|
+
}
|
|
11049
|
+
}
|
|
11050
|
+
return Array.from(candidates);
|
|
11051
|
+
}
|
|
10970
11052
|
function normalizeLocalAgentSystemPrompt(agentId, projectName, projectPath, systemPrompt) {
|
|
10971
11053
|
const trimmed = systemPrompt?.trim();
|
|
10972
11054
|
if (!trimmed) {
|
|
10973
11055
|
return;
|
|
10974
11056
|
}
|
|
10975
|
-
if (legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed)) {
|
|
11057
|
+
if (legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed) || generatedLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed)) {
|
|
10976
11058
|
return;
|
|
10977
11059
|
}
|
|
10978
11060
|
return trimmed;
|
|
@@ -11460,7 +11542,7 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
11460
11542
|
await new Promise((resolve8) => setTimeout(resolve8, 100));
|
|
11461
11543
|
}
|
|
11462
11544
|
if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
|
|
11463
|
-
const stderrTail =
|
|
11545
|
+
const stderrTail = existsSync8(stderrLogFile) ? readFileSync4(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
|
|
11464
11546
|
`).trim() : "";
|
|
11465
11547
|
throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
|
|
11466
11548
|
${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
|
|
@@ -11828,6 +11910,29 @@ async function restartAllLocalAgents(options = {}) {
|
|
|
11828
11910
|
}));
|
|
11829
11911
|
return restarted.filter((agent) => Boolean(agent));
|
|
11830
11912
|
}
|
|
11913
|
+
function readPersistedClaudeSessionId(agentName) {
|
|
11914
|
+
try {
|
|
11915
|
+
const runtimeDir = relayAgentRuntimeDirectory(agentName);
|
|
11916
|
+
const catalogPath = join11(runtimeDir, "session-catalog.json");
|
|
11917
|
+
if (existsSync8(catalogPath)) {
|
|
11918
|
+
const raw = readFileSync4(catalogPath, "utf8").trim();
|
|
11919
|
+
if (raw) {
|
|
11920
|
+
const catalog = JSON.parse(raw);
|
|
11921
|
+
if (typeof catalog.activeSessionId === "string" && catalog.activeSessionId.trim()) {
|
|
11922
|
+
return catalog.activeSessionId.trim();
|
|
11923
|
+
}
|
|
11924
|
+
}
|
|
11925
|
+
}
|
|
11926
|
+
const legacyPath = join11(runtimeDir, "claude-session-id.txt");
|
|
11927
|
+
if (existsSync8(legacyPath)) {
|
|
11928
|
+
const value = readFileSync4(legacyPath, "utf8").trim();
|
|
11929
|
+
return value || null;
|
|
11930
|
+
}
|
|
11931
|
+
return null;
|
|
11932
|
+
} catch {
|
|
11933
|
+
return null;
|
|
11934
|
+
}
|
|
11935
|
+
}
|
|
11831
11936
|
function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
11832
11937
|
const normalizedRecord = normalizeLocalAgentRecord(agentId, record);
|
|
11833
11938
|
const definitionId = normalizedRecord.definitionId ?? agentId;
|
|
@@ -11835,6 +11940,7 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
|
11835
11940
|
const projectRoot = normalizedRecord.projectRoot ?? normalizedRecord.cwd;
|
|
11836
11941
|
const instance = buildRelayAgentInstance(definitionId, projectRoot);
|
|
11837
11942
|
const actorId = instance.id;
|
|
11943
|
+
const externalSessionId = normalizedRecord.transport === "claude_stream_json" ? readPersistedClaudeSessionId(definitionId) : null;
|
|
11838
11944
|
return {
|
|
11839
11945
|
actor: {
|
|
11840
11946
|
id: actorId,
|
|
@@ -11912,7 +12018,8 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
|
11912
12018
|
selector: instance.selector,
|
|
11913
12019
|
nodeQualifier: instance.nodeQualifier,
|
|
11914
12020
|
workspaceQualifier: instance.workspaceQualifier,
|
|
11915
|
-
branch: instance.branch
|
|
12021
|
+
branch: instance.branch,
|
|
12022
|
+
...externalSessionId ? { externalSessionId } : {}
|
|
11916
12023
|
}
|
|
11917
12024
|
}
|
|
11918
12025
|
};
|
|
@@ -12008,7 +12115,7 @@ var init_local_agents = __esm(async () => {
|
|
|
12008
12115
|
});
|
|
12009
12116
|
|
|
12010
12117
|
// ../runtime/src/user-config.ts
|
|
12011
|
-
import { existsSync as
|
|
12118
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
12012
12119
|
import { homedir as homedir8 } from "os";
|
|
12013
12120
|
import { dirname as dirname7, join as join12 } from "path";
|
|
12014
12121
|
function userConfigPath() {
|
|
@@ -12016,10 +12123,10 @@ function userConfigPath() {
|
|
|
12016
12123
|
}
|
|
12017
12124
|
function loadUserConfig() {
|
|
12018
12125
|
const configPath = userConfigPath();
|
|
12019
|
-
if (!
|
|
12126
|
+
if (!existsSync9(configPath))
|
|
12020
12127
|
return {};
|
|
12021
12128
|
try {
|
|
12022
|
-
return JSON.parse(
|
|
12129
|
+
return JSON.parse(readFileSync5(configPath, "utf8"));
|
|
12023
12130
|
} catch {
|
|
12024
12131
|
return {};
|
|
12025
12132
|
}
|
|
@@ -43090,7 +43197,7 @@ var init_down = __esm(async () => {
|
|
|
43090
43197
|
// ../../apps/desktop/src/app/host/runtime-service-client.ts
|
|
43091
43198
|
import { spawn as spawn4 } from "child_process";
|
|
43092
43199
|
import { basename as basename6, dirname as dirname8, join as join14 } from "path";
|
|
43093
|
-
import { existsSync as
|
|
43200
|
+
import { existsSync as existsSync10 } from "fs";
|
|
43094
43201
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
43095
43202
|
import { homedir as homedir9 } from "os";
|
|
43096
43203
|
function tryWhich(executableName) {
|
|
@@ -43100,13 +43207,13 @@ function tryWhich(executableName) {
|
|
|
43100
43207
|
if (!dir)
|
|
43101
43208
|
continue;
|
|
43102
43209
|
const candidate = join14(dir, executableName);
|
|
43103
|
-
if (
|
|
43210
|
+
if (existsSync10(candidate)) {
|
|
43104
43211
|
return candidate;
|
|
43105
43212
|
}
|
|
43106
43213
|
if (process.platform === "win32") {
|
|
43107
43214
|
for (const ext of [".cmd", ".exe", ".bat"]) {
|
|
43108
43215
|
const withExt = candidate + ext;
|
|
43109
|
-
if (
|
|
43216
|
+
if (existsSync10(withExt))
|
|
43110
43217
|
return withExt;
|
|
43111
43218
|
}
|
|
43112
43219
|
}
|
|
@@ -43118,7 +43225,7 @@ function findNodeModulesRuntimeBin() {
|
|
|
43118
43225
|
let dir = dirname8(fileURLToPath6(import.meta.url));
|
|
43119
43226
|
for (let i = 0;i < 24; i++) {
|
|
43120
43227
|
const candidate = join14(dir, runtimeBinRel);
|
|
43121
|
-
if (
|
|
43228
|
+
if (existsSync10(candidate))
|
|
43122
43229
|
return candidate;
|
|
43123
43230
|
const parent = dirname8(dir);
|
|
43124
43231
|
if (parent === dir)
|
|
@@ -43126,7 +43233,7 @@ function findNodeModulesRuntimeBin() {
|
|
|
43126
43233
|
dir = parent;
|
|
43127
43234
|
}
|
|
43128
43235
|
const bunGlobal = join14(homedir9(), ".bun", "install", "global", "node_modules", "@openscout", "runtime", "bin", "openscout-runtime.mjs");
|
|
43129
|
-
if (
|
|
43236
|
+
if (existsSync10(bunGlobal))
|
|
43130
43237
|
return bunGlobal;
|
|
43131
43238
|
return null;
|
|
43132
43239
|
}
|
|
@@ -43134,7 +43241,7 @@ function findMonorepoOpenscoutRuntimeBin() {
|
|
|
43134
43241
|
let dir = process.cwd();
|
|
43135
43242
|
for (let i = 0;i < 24; i++) {
|
|
43136
43243
|
const candidate = join14(dir, "packages", "runtime", "bin", "openscout-runtime.mjs");
|
|
43137
|
-
if (
|
|
43244
|
+
if (existsSync10(candidate)) {
|
|
43138
43245
|
return candidate;
|
|
43139
43246
|
}
|
|
43140
43247
|
const parent = dirname8(dir);
|
|
@@ -43147,7 +43254,7 @@ function findMonorepoOpenscoutRuntimeBin() {
|
|
|
43147
43254
|
function resolveJavaScriptRuntimeExecutable() {
|
|
43148
43255
|
const explicit = process.env.OPENSCOUT_RUNTIME_NODE_BIN?.trim();
|
|
43149
43256
|
if (explicit) {
|
|
43150
|
-
if (
|
|
43257
|
+
if (existsSync10(explicit)) {
|
|
43151
43258
|
return explicit;
|
|
43152
43259
|
}
|
|
43153
43260
|
const found = tryWhich(explicit);
|
|
@@ -43173,7 +43280,7 @@ function resolveJavaScriptRuntimeExecutable() {
|
|
|
43173
43280
|
function resolveRuntimeServiceEntrypoint() {
|
|
43174
43281
|
const explicit = process.env.OPENSCOUT_RUNTIME_BIN?.trim();
|
|
43175
43282
|
if (explicit) {
|
|
43176
|
-
if (
|
|
43283
|
+
if (existsSync10(explicit)) {
|
|
43177
43284
|
return explicit;
|
|
43178
43285
|
}
|
|
43179
43286
|
const found = tryWhich(explicit);
|
|
@@ -43450,16 +43557,16 @@ var init_service3 = __esm(() => {
|
|
|
43450
43557
|
});
|
|
43451
43558
|
|
|
43452
43559
|
// ../../apps/desktop/src/shared/paths.ts
|
|
43453
|
-
import { existsSync as
|
|
43560
|
+
import { existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
|
|
43454
43561
|
import { dirname as dirname10, join as join16, resolve as resolve10 } from "path";
|
|
43455
43562
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
43456
43563
|
function looksLikeWorkspaceRoot(candidate) {
|
|
43457
43564
|
const packageJsonPath = join16(candidate, "package.json");
|
|
43458
|
-
if (!
|
|
43565
|
+
if (!existsSync11(packageJsonPath)) {
|
|
43459
43566
|
return false;
|
|
43460
43567
|
}
|
|
43461
43568
|
try {
|
|
43462
|
-
const parsed = JSON.parse(
|
|
43569
|
+
const parsed = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
43463
43570
|
return Array.isArray(parsed.workspaces);
|
|
43464
43571
|
} catch {
|
|
43465
43572
|
return false;
|
|
@@ -43467,18 +43574,18 @@ function looksLikeWorkspaceRoot(candidate) {
|
|
|
43467
43574
|
}
|
|
43468
43575
|
function looksLikePackagedAppRoot(candidate) {
|
|
43469
43576
|
const packageJsonPath = join16(candidate, "package.json");
|
|
43470
|
-
if (!
|
|
43577
|
+
if (!existsSync11(packageJsonPath)) {
|
|
43471
43578
|
return false;
|
|
43472
43579
|
}
|
|
43473
43580
|
try {
|
|
43474
|
-
const parsed = JSON.parse(
|
|
43581
|
+
const parsed = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
43475
43582
|
return parsed.name === "@openscout/scout" || parsed.name === "@openscout/cli";
|
|
43476
43583
|
} catch {
|
|
43477
43584
|
return false;
|
|
43478
43585
|
}
|
|
43479
43586
|
}
|
|
43480
43587
|
function looksLikeSourceAppRoot(candidate) {
|
|
43481
|
-
return
|
|
43588
|
+
return existsSync11(join16(candidate, "bin", "scout.ts"));
|
|
43482
43589
|
}
|
|
43483
43590
|
function findMatchingAncestor(startDirectory, predicate) {
|
|
43484
43591
|
let current = resolve10(startDirectory);
|
|
@@ -43798,7 +43905,7 @@ var exports_env = {};
|
|
|
43798
43905
|
__export(exports_env, {
|
|
43799
43906
|
runEnvCommand: () => runEnvCommand
|
|
43800
43907
|
});
|
|
43801
|
-
import { existsSync as
|
|
43908
|
+
import { existsSync as existsSync12 } from "fs";
|
|
43802
43909
|
import { join as join17 } from "path";
|
|
43803
43910
|
function resolveCommandOnPath(command, env) {
|
|
43804
43911
|
const pathValue = env.PATH ?? "";
|
|
@@ -43808,7 +43915,7 @@ function resolveCommandOnPath(command, env) {
|
|
|
43808
43915
|
continue;
|
|
43809
43916
|
}
|
|
43810
43917
|
const candidate = join17(trimmed, command);
|
|
43811
|
-
if (
|
|
43918
|
+
if (existsSync12(candidate)) {
|
|
43812
43919
|
return candidate;
|
|
43813
43920
|
}
|
|
43814
43921
|
}
|
|
@@ -43820,7 +43927,7 @@ function resolveScoutBinPath(appRoot) {
|
|
|
43820
43927
|
join17(appRoot, "bin", "scout.mjs")
|
|
43821
43928
|
];
|
|
43822
43929
|
for (const candidate of candidates) {
|
|
43823
|
-
if (
|
|
43930
|
+
if (existsSync12(candidate)) {
|
|
43824
43931
|
return candidate;
|
|
43825
43932
|
}
|
|
43826
43933
|
}
|
|
@@ -43895,9 +44002,9 @@ var init_env = __esm(async () => {
|
|
|
43895
44002
|
|
|
43896
44003
|
// ../runtime/src/local-config.ts
|
|
43897
44004
|
import {
|
|
43898
|
-
existsSync as
|
|
44005
|
+
existsSync as existsSync13,
|
|
43899
44006
|
mkdirSync as mkdirSync4,
|
|
43900
|
-
readFileSync as
|
|
44007
|
+
readFileSync as readFileSync7,
|
|
43901
44008
|
renameSync,
|
|
43902
44009
|
writeFileSync as writeFileSync4
|
|
43903
44010
|
} from "fs";
|
|
@@ -43911,10 +44018,10 @@ function localConfigPath() {
|
|
|
43911
44018
|
}
|
|
43912
44019
|
function loadLocalConfig() {
|
|
43913
44020
|
const configPath = localConfigPath();
|
|
43914
|
-
if (!
|
|
44021
|
+
if (!existsSync13(configPath))
|
|
43915
44022
|
return { version: LOCAL_CONFIG_VERSION };
|
|
43916
44023
|
try {
|
|
43917
|
-
return validateLocalConfig(JSON.parse(
|
|
44024
|
+
return validateLocalConfig(JSON.parse(readFileSync7(configPath, "utf8")));
|
|
43918
44025
|
} catch {
|
|
43919
44026
|
return { version: LOCAL_CONFIG_VERSION };
|
|
43920
44027
|
}
|
|
@@ -43954,7 +44061,7 @@ function writeLocalConfig(config2) {
|
|
|
43954
44061
|
renameSync(tmp, configPath);
|
|
43955
44062
|
}
|
|
43956
44063
|
function localConfigExists() {
|
|
43957
|
-
return
|
|
44064
|
+
return existsSync13(localConfigPath());
|
|
43958
44065
|
}
|
|
43959
44066
|
var LOCAL_CONFIG_VERSION = 1, DEFAULT_LOCAL_CONFIG;
|
|
43960
44067
|
var init_local_config = __esm(() => {
|
|
@@ -46011,7 +46118,7 @@ __export(exports_menu, {
|
|
|
46011
46118
|
parseMenuCommand: () => parseMenuCommand
|
|
46012
46119
|
});
|
|
46013
46120
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
46014
|
-
import { existsSync as
|
|
46121
|
+
import { existsSync as existsSync14 } from "fs";
|
|
46015
46122
|
import { homedir as homedir11 } from "os";
|
|
46016
46123
|
import { dirname as dirname12, join as join19, resolve as resolve12 } from "path";
|
|
46017
46124
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
@@ -46100,7 +46207,7 @@ function findRepoMenuHelper(startDirectory) {
|
|
|
46100
46207
|
let current = resolve12(startDirectory);
|
|
46101
46208
|
while (true) {
|
|
46102
46209
|
const candidate = join19(current, "apps", "macos", "bin", "openscout-menu.ts");
|
|
46103
|
-
if (
|
|
46210
|
+
if (existsSync14(candidate)) {
|
|
46104
46211
|
return candidate;
|
|
46105
46212
|
}
|
|
46106
46213
|
const parent = dirname12(current);
|
|
@@ -46110,7 +46217,7 @@ function findRepoMenuHelper(startDirectory) {
|
|
|
46110
46217
|
current = parent;
|
|
46111
46218
|
}
|
|
46112
46219
|
const sourceRelativeCandidate = fileURLToPath8(new URL("../../../../macos/bin/openscout-menu.ts", import.meta.url));
|
|
46113
|
-
return
|
|
46220
|
+
return existsSync14(sourceRelativeCandidate) ? sourceRelativeCandidate : null;
|
|
46114
46221
|
}
|
|
46115
46222
|
function resolveRepoBundlePath(helperPath) {
|
|
46116
46223
|
return resolve12(dirname12(helperPath), "..", "dist", MENU_BUNDLE_NAME);
|
|
@@ -46129,7 +46236,7 @@ function resolveInstalledMenuBundlePath(env) {
|
|
|
46129
46236
|
return indexedPath;
|
|
46130
46237
|
}
|
|
46131
46238
|
for (const candidate of COMMON_MENU_BUNDLE_PATHS) {
|
|
46132
|
-
if (
|
|
46239
|
+
if (existsSync14(candidate)) {
|
|
46133
46240
|
return candidate;
|
|
46134
46241
|
}
|
|
46135
46242
|
}
|
|
@@ -46198,7 +46305,7 @@ function runWithRepoHelper(context, helperPath, command) {
|
|
|
46198
46305
|
});
|
|
46199
46306
|
const bundlePath = resolveRepoBundlePath(helperPath);
|
|
46200
46307
|
const running = command.action === "quit" ? false : isMenuRunning(context.env);
|
|
46201
|
-
const installed =
|
|
46308
|
+
const installed = existsSync14(bundlePath) || running;
|
|
46202
46309
|
return {
|
|
46203
46310
|
action: command.action,
|
|
46204
46311
|
mode: "repo-helper",
|
|
@@ -46290,6 +46397,26 @@ function parsePeers(status) {
|
|
|
46290
46397
|
tags: peer.Tags ?? []
|
|
46291
46398
|
}));
|
|
46292
46399
|
}
|
|
46400
|
+
function parseSelf(status) {
|
|
46401
|
+
const self2 = status.Self;
|
|
46402
|
+
if (!self2) {
|
|
46403
|
+
return null;
|
|
46404
|
+
}
|
|
46405
|
+
return {
|
|
46406
|
+
id: self2.ID ?? self2.DNSName ?? self2.HostName ?? "self",
|
|
46407
|
+
name: self2.HostName ?? self2.DNSName ?? "self",
|
|
46408
|
+
dnsName: self2.DNSName,
|
|
46409
|
+
addresses: self2.TailscaleIPs ?? [],
|
|
46410
|
+
online: self2.Online ?? true,
|
|
46411
|
+
hostName: self2.HostName,
|
|
46412
|
+
os: self2.OS,
|
|
46413
|
+
tailnetName: status.CurrentTailnet?.Name,
|
|
46414
|
+
magicDnsSuffix: status.CurrentTailnet?.MagicDNSSuffix
|
|
46415
|
+
};
|
|
46416
|
+
}
|
|
46417
|
+
function isBackendRunning(status) {
|
|
46418
|
+
return (status.BackendState ?? "").trim().toLowerCase() === "running";
|
|
46419
|
+
}
|
|
46293
46420
|
async function readStatusJsonFromFile(filePath) {
|
|
46294
46421
|
const raw = await readFile9(filePath, "utf8");
|
|
46295
46422
|
return parseStatusJson(raw);
|
|
@@ -46308,11 +46435,24 @@ async function readStatusJson() {
|
|
|
46308
46435
|
}
|
|
46309
46436
|
}
|
|
46310
46437
|
async function readTailscalePeers() {
|
|
46438
|
+
const summary = await readTailscaleStatusSummary();
|
|
46439
|
+
if (!summary) {
|
|
46440
|
+
return [];
|
|
46441
|
+
}
|
|
46442
|
+
return summary.peers;
|
|
46443
|
+
}
|
|
46444
|
+
async function readTailscaleStatusSummary() {
|
|
46311
46445
|
const status = await readStatusJson();
|
|
46312
46446
|
if (!status) {
|
|
46313
|
-
return
|
|
46447
|
+
return null;
|
|
46314
46448
|
}
|
|
46315
|
-
return
|
|
46449
|
+
return {
|
|
46450
|
+
backendState: status.BackendState ?? null,
|
|
46451
|
+
running: isBackendRunning(status),
|
|
46452
|
+
health: status.Health ?? [],
|
|
46453
|
+
peers: parsePeers(status),
|
|
46454
|
+
self: parseSelf(status)
|
|
46455
|
+
};
|
|
46316
46456
|
}
|
|
46317
46457
|
var execFileAsync;
|
|
46318
46458
|
var init_tailscale = __esm(() => {
|
|
@@ -46342,9 +46482,13 @@ function readMeshEnvVars() {
|
|
|
46342
46482
|
};
|
|
46343
46483
|
}
|
|
46344
46484
|
async function readTailscaleStatus() {
|
|
46345
|
-
const
|
|
46485
|
+
const summary = await readTailscaleStatusSummary();
|
|
46486
|
+
const peers = summary?.peers ?? [];
|
|
46346
46487
|
return {
|
|
46347
|
-
available:
|
|
46488
|
+
available: summary !== null,
|
|
46489
|
+
running: summary?.running ?? false,
|
|
46490
|
+
backendState: summary?.backendState ?? null,
|
|
46491
|
+
health: summary?.health ?? [],
|
|
46348
46492
|
peers,
|
|
46349
46493
|
onlineCount: peers.filter((p) => p.online).length
|
|
46350
46494
|
};
|
|
@@ -46360,6 +46504,9 @@ function computeWarnings(health, localNode, nodes, tailscale) {
|
|
|
46360
46504
|
} else if (localNode?.advertiseScope === "mesh" && localNode.brokerUrl && isLoopbackBrokerUrl(localNode.brokerUrl)) {
|
|
46361
46505
|
warnings.push("Broker advertises mesh scope but is bound to loopback \u2014 peers cannot reach it. " + "Unset OPENSCOUT_BROKER_HOST (mesh default is 0.0.0.0) or use your Tailscale IP.");
|
|
46362
46506
|
}
|
|
46507
|
+
if (tailscale.available && !tailscale.running) {
|
|
46508
|
+
warnings.push("Tailscale is installed but currently stopped on this machine. " + "Cached peers may appear, but the broker cannot reach them until Tailscale is running.");
|
|
46509
|
+
}
|
|
46363
46510
|
const remoteNodes = Object.values(nodes).filter((n) => n.id !== localNode?.id);
|
|
46364
46511
|
if (!tailscale.available && remoteNodes.length === 0) {
|
|
46365
46512
|
warnings.push("No Tailscale peers found and no mesh seeds configured. " + "Install Tailscale or set OPENSCOUT_MESH_SEEDS.");
|
|
@@ -46525,7 +46672,7 @@ function renderMeshStatus(report) {
|
|
|
46525
46672
|
}
|
|
46526
46673
|
lines.push(` Broker: ${report.brokerUrl}`);
|
|
46527
46674
|
lines.push(` Scope: ${report.localNode?.advertiseScope === "mesh" ? "mesh-reachable" : "local-only"}`);
|
|
46528
|
-
const tsLabel = report.tailscale.available ?
|
|
46675
|
+
const tsLabel = !report.tailscale.available ? "not available" : report.tailscale.running ? `running (${report.tailscale.onlineCount} peer${report.tailscale.onlineCount === 1 ? "" : "s"} online)` : `not running (${report.tailscale.backendState ?? "unknown"})`;
|
|
46529
46676
|
lines.push(` Tailscale: ${tsLabel}`);
|
|
46530
46677
|
const allNodes = Object.values(report.nodes);
|
|
46531
46678
|
const remoteNodes = allNodes.filter((n) => n.id !== report.localNode?.id);
|
|
@@ -46559,7 +46706,8 @@ function renderMeshDoctor(report) {
|
|
|
46559
46706
|
lines.push(` ID: ${report.localNode.id}`);
|
|
46560
46707
|
lines.push(` Name: ${report.localNode.name}`);
|
|
46561
46708
|
lines.push(` Mesh: ${report.localNode.meshId}`);
|
|
46562
|
-
lines.push(`
|
|
46709
|
+
lines.push(` Control URL: ${report.brokerUrl}`);
|
|
46710
|
+
lines.push(` Announced URL: ${report.localNode.brokerUrl ?? report.brokerUrl}`);
|
|
46563
46711
|
lines.push(` Advertise scope: ${report.localNode.advertiseScope}`);
|
|
46564
46712
|
if (report.localNode.hostName) {
|
|
46565
46713
|
lines.push(` Hostname: ${report.localNode.hostName}`);
|
|
@@ -46570,7 +46718,11 @@ function renderMeshDoctor(report) {
|
|
|
46570
46718
|
lines.push("");
|
|
46571
46719
|
lines.push("Tailscale:");
|
|
46572
46720
|
if (report.tailscale.available) {
|
|
46573
|
-
|
|
46721
|
+
const state = report.tailscale.backendState ?? "unknown";
|
|
46722
|
+
lines.push(` Status: ${report.tailscale.running ? `running (${state})` : `not running (${state})`} (${report.tailscale.peers.length} peer${report.tailscale.peers.length === 1 ? "" : "s"})`);
|
|
46723
|
+
for (const detail of report.tailscale.health) {
|
|
46724
|
+
lines.push(` ! ${detail}`);
|
|
46725
|
+
}
|
|
46574
46726
|
for (const peer of report.tailscale.peers) {
|
|
46575
46727
|
const ips = peer.addresses.join(", ");
|
|
46576
46728
|
const status = peer.online ? "online" : "offline";
|
|
@@ -46598,7 +46750,7 @@ function renderMeshDoctor(report) {
|
|
|
46598
46750
|
}
|
|
46599
46751
|
}
|
|
46600
46752
|
lines.push("");
|
|
46601
|
-
lines.push("
|
|
46753
|
+
lines.push("Client environment (this shell):");
|
|
46602
46754
|
const env = report.envVars;
|
|
46603
46755
|
lines.push(` OPENSCOUT_MESH_ID: ${env.meshId ?? "(default: openscout)"}`);
|
|
46604
46756
|
lines.push(` OPENSCOUT_MESH_SEEDS: ${env.meshSeeds || "(not set)"}`);
|
|
@@ -46741,7 +46893,7 @@ var init_mesh2 = __esm(async () => {
|
|
|
46741
46893
|
});
|
|
46742
46894
|
|
|
46743
46895
|
// ../../apps/desktop/src/core/pairing/runtime/config.ts
|
|
46744
|
-
import { existsSync as
|
|
46896
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
46745
46897
|
import { homedir as homedir12 } from "os";
|
|
46746
46898
|
import path from "path";
|
|
46747
46899
|
function pairingPaths() {
|
|
@@ -46758,11 +46910,11 @@ function pairingPaths() {
|
|
|
46758
46910
|
}
|
|
46759
46911
|
function loadPairingConfig() {
|
|
46760
46912
|
const { configPath } = pairingPaths();
|
|
46761
|
-
if (!
|
|
46913
|
+
if (!existsSync15(configPath)) {
|
|
46762
46914
|
return {};
|
|
46763
46915
|
}
|
|
46764
46916
|
try {
|
|
46765
|
-
const payload = JSON.parse(
|
|
46917
|
+
const payload = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
46766
46918
|
return typeof payload === "object" && payload ? payload : {};
|
|
46767
46919
|
} catch {
|
|
46768
46920
|
return {};
|
|
@@ -48845,17 +48997,17 @@ var init_noise = __esm(() => {
|
|
|
48845
48997
|
});
|
|
48846
48998
|
|
|
48847
48999
|
// ../../apps/desktop/src/core/pairing/runtime/security/identity.ts
|
|
48848
|
-
import { existsSync as
|
|
49000
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
48849
49001
|
import { join as join20 } from "path";
|
|
48850
49002
|
import { homedir as homedir13 } from "os";
|
|
48851
49003
|
function loadOrCreateIdentity() {
|
|
48852
|
-
if (
|
|
49004
|
+
if (existsSync16(IDENTITY_FILE)) {
|
|
48853
49005
|
return loadIdentity();
|
|
48854
49006
|
}
|
|
48855
49007
|
return createAndSaveIdentity();
|
|
48856
49008
|
}
|
|
48857
49009
|
function loadIdentity() {
|
|
48858
|
-
const data = JSON.parse(
|
|
49010
|
+
const data = JSON.parse(readFileSync9(IDENTITY_FILE, "utf8"));
|
|
48859
49011
|
return {
|
|
48860
49012
|
publicKey: hexToBytes2(data.publicKey),
|
|
48861
49013
|
privateKey: hexToBytes2(data.privateKey)
|
|
@@ -48873,9 +49025,9 @@ function createAndSaveIdentity() {
|
|
|
48873
49025
|
return keyPair;
|
|
48874
49026
|
}
|
|
48875
49027
|
function loadTrustedPeers() {
|
|
48876
|
-
if (!
|
|
49028
|
+
if (!existsSync16(TRUSTED_PEERS_FILE))
|
|
48877
49029
|
return new Map;
|
|
48878
|
-
const data = JSON.parse(
|
|
49030
|
+
const data = JSON.parse(readFileSync9(TRUSTED_PEERS_FILE, "utf8"));
|
|
48879
49031
|
return new Map(data.map((p) => [p.publicKey, p]));
|
|
48880
49032
|
}
|
|
48881
49033
|
function saveTrustedPeer(peer) {
|
|
@@ -49056,14 +49208,14 @@ var init_security2 = __esm(() => {
|
|
|
49056
49208
|
});
|
|
49057
49209
|
|
|
49058
49210
|
// ../../apps/desktop/src/core/pairing/runtime/runtime-state.ts
|
|
49059
|
-
import { existsSync as
|
|
49211
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync10, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync7 } from "fs";
|
|
49060
49212
|
function readPairingRuntimeSnapshot() {
|
|
49061
49213
|
const { runtimeStatePath } = pairingPaths();
|
|
49062
|
-
if (!
|
|
49214
|
+
if (!existsSync17(runtimeStatePath)) {
|
|
49063
49215
|
return null;
|
|
49064
49216
|
}
|
|
49065
49217
|
try {
|
|
49066
|
-
const parsed = JSON.parse(
|
|
49218
|
+
const parsed = JSON.parse(readFileSync10(runtimeStatePath, "utf8"));
|
|
49067
49219
|
return parsed?.version === 1 ? parsed : null;
|
|
49068
49220
|
} catch {
|
|
49069
49221
|
return null;
|
|
@@ -49181,15 +49333,15 @@ var init_bridge = __esm(() => {
|
|
|
49181
49333
|
});
|
|
49182
49334
|
|
|
49183
49335
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/config.ts
|
|
49184
|
-
import { existsSync as
|
|
49336
|
+
import { existsSync as existsSync18, readFileSync as readFileSync11 } from "fs";
|
|
49185
49337
|
import { join as join22 } from "path";
|
|
49186
49338
|
import { homedir as homedir15 } from "os";
|
|
49187
49339
|
function loadConfigFile() {
|
|
49188
|
-
if (!
|
|
49340
|
+
if (!existsSync18(CONFIG_FILE)) {
|
|
49189
49341
|
return {};
|
|
49190
49342
|
}
|
|
49191
49343
|
try {
|
|
49192
|
-
const raw =
|
|
49344
|
+
const raw = readFileSync11(CONFIG_FILE, "utf8");
|
|
49193
49345
|
const parsed = JSON.parse(raw);
|
|
49194
49346
|
return parsed;
|
|
49195
49347
|
} catch (err) {
|
|
@@ -50102,7 +50254,7 @@ async function deriveNewAgentName(projectName, branch, harness) {
|
|
|
50102
50254
|
async function createGitWorktree(projectRoot, agentName) {
|
|
50103
50255
|
const { execSync: execSync2 } = await import("child_process");
|
|
50104
50256
|
const { join: join24 } = await import("path");
|
|
50105
|
-
const { mkdirSync: mkdirSync9, existsSync:
|
|
50257
|
+
const { mkdirSync: mkdirSync9, existsSync: existsSync19 } = await import("fs");
|
|
50106
50258
|
try {
|
|
50107
50259
|
execSync2("git rev-parse --git-dir", { cwd: projectRoot, stdio: "pipe" });
|
|
50108
50260
|
} catch {
|
|
@@ -50111,7 +50263,7 @@ async function createGitWorktree(projectRoot, agentName) {
|
|
|
50111
50263
|
const branchName = `scout/${agentName}`;
|
|
50112
50264
|
const worktreeDir = join24(projectRoot, ".scout-worktrees");
|
|
50113
50265
|
const worktreePath = join24(worktreeDir, agentName);
|
|
50114
|
-
if (
|
|
50266
|
+
if (existsSync19(worktreePath)) {
|
|
50115
50267
|
return { path: worktreePath, branch: branchName };
|
|
50116
50268
|
}
|
|
50117
50269
|
mkdirSync9(worktreeDir, { recursive: true });
|
|
@@ -50154,7 +50306,7 @@ var init_service5 = __esm(async () => {
|
|
|
50154
50306
|
});
|
|
50155
50307
|
|
|
50156
50308
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
|
|
50157
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
50309
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync12, realpathSync, statSync as statSync3 } from "fs";
|
|
50158
50310
|
import { execSync as execSync2 } from "child_process";
|
|
50159
50311
|
import { basename as basename9, isAbsolute as isAbsolute3, join as join24, relative as relative2 } from "path";
|
|
50160
50312
|
import { homedir as homedir18 } from "os";
|
|
@@ -50493,7 +50645,7 @@ async function handleRPCInner(bridge, req, deviceId) {
|
|
|
50493
50645
|
return { id: req.id, error: { code: -32000, message: "Only .jsonl files can be read" } };
|
|
50494
50646
|
}
|
|
50495
50647
|
try {
|
|
50496
|
-
const content =
|
|
50648
|
+
const content = readFileSync12(p.path, "utf-8");
|
|
50497
50649
|
const lines = content.split(`
|
|
50498
50650
|
`).filter((l) => l.trim().length > 0);
|
|
50499
50651
|
const trimmed = lines.length > 500 ? lines.slice(-500) : lines;
|
|
@@ -54747,7 +54899,7 @@ var init_thread_events2 = __esm(() => {
|
|
|
54747
54899
|
|
|
54748
54900
|
// ../runtime/src/mobile-push.ts
|
|
54749
54901
|
import { Database as Database2 } from "bun:sqlite";
|
|
54750
|
-
import { mkdirSync as mkdirSync9, readFileSync as
|
|
54902
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync13 } from "fs";
|
|
54751
54903
|
import { connect as connectHttp2 } from "http2";
|
|
54752
54904
|
import { createPrivateKey, sign as signWithKey } from "crypto";
|
|
54753
54905
|
import { dirname as dirname13, join as join25 } from "path";
|
|
@@ -54918,7 +55070,7 @@ function loadApnsCredentials() {
|
|
|
54918
55070
|
privateKeyPem = Buffer.from(inlineBase64, "base64").toString("utf8");
|
|
54919
55071
|
}
|
|
54920
55072
|
if (!privateKeyPem && path2) {
|
|
54921
|
-
privateKeyPem =
|
|
55073
|
+
privateKeyPem = readFileSync13(path2, "utf8");
|
|
54922
55074
|
}
|
|
54923
55075
|
if (!teamId || !keyId || !privateKeyPem) {
|
|
54924
55076
|
return null;
|
|
@@ -55142,7 +55294,7 @@ var init_src2 = __esm(async () => {
|
|
|
55142
55294
|
});
|
|
55143
55295
|
|
|
55144
55296
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
|
|
55145
|
-
import { readFileSync as
|
|
55297
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync3, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
|
|
55146
55298
|
import { execSync as execSync3 } from "child_process";
|
|
55147
55299
|
import { basename as basename10, isAbsolute as isAbsolute4, join as join26, relative as relative3 } from "path";
|
|
55148
55300
|
import { homedir as homedir19 } from "os";
|
|
@@ -55822,7 +55974,7 @@ var init_router = __esm(async () => {
|
|
|
55822
55974
|
});
|
|
55823
55975
|
}
|
|
55824
55976
|
try {
|
|
55825
|
-
const content =
|
|
55977
|
+
const content = readFileSync14(input.path, "utf-8");
|
|
55826
55978
|
const lines = content.split(`
|
|
55827
55979
|
`).filter((l) => l.trim().length > 0);
|
|
55828
55980
|
const trimmed = lines.length > 500 ? lines.slice(-500) : lines;
|
|
@@ -60775,11 +60927,11 @@ var BRIDGE_ABSENCE_GRACE_MS = 30000, ROOM_IDLE_TIMEOUT_MS = 60000;
|
|
|
60775
60927
|
|
|
60776
60928
|
// ../../apps/desktop/src/core/pairing/runtime/relay-runtime.ts
|
|
60777
60929
|
import { execSync as execSync4 } from "child_process";
|
|
60778
|
-
import { existsSync as
|
|
60930
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync11, readdirSync as readdirSync4 } from "fs";
|
|
60779
60931
|
import { homedir as homedir22 } from "os";
|
|
60780
60932
|
import { join as join27 } from "path";
|
|
60781
60933
|
function findStoredCerts() {
|
|
60782
|
-
if (!
|
|
60934
|
+
if (!existsSync19(PAIRING_DIR2)) {
|
|
60783
60935
|
return null;
|
|
60784
60936
|
}
|
|
60785
60937
|
try {
|
|
@@ -61835,7 +61987,7 @@ __export(exports_server, {
|
|
|
61835
61987
|
normalizeServerOpenPath: () => normalizeServerOpenPath
|
|
61836
61988
|
});
|
|
61837
61989
|
import { spawn as spawn5 } from "child_process";
|
|
61838
|
-
import { existsSync as
|
|
61990
|
+
import { existsSync as existsSync20 } from "fs";
|
|
61839
61991
|
import { dirname as dirname14, join as join28, resolve as resolve14 } from "path";
|
|
61840
61992
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
61841
61993
|
function renderServerCommandHelp() {
|
|
@@ -61845,6 +61997,7 @@ function renderServerCommandHelp() {
|
|
|
61845
61997
|
"Usage:",
|
|
61846
61998
|
" scout server start [options]",
|
|
61847
61999
|
" scout server open [options]",
|
|
62000
|
+
" scout server control-plane open [options] # legacy alias",
|
|
61848
62001
|
"",
|
|
61849
62002
|
"Subcommands:",
|
|
61850
62003
|
" start Start the Scout web UI server.",
|
|
@@ -61868,14 +62021,18 @@ function resolveScoutWebServerEntry() {
|
|
|
61868
62021
|
function resolveScoutControlPlaneWebServerEntry() {
|
|
61869
62022
|
const mainDir = dirname14(fileURLToPath9(import.meta.url));
|
|
61870
62023
|
const bundled = join28(mainDir, "scout-control-plane-web.mjs");
|
|
61871
|
-
if (
|
|
62024
|
+
if (existsSync20(bundled)) {
|
|
61872
62025
|
return bundled;
|
|
61873
62026
|
}
|
|
61874
|
-
const source = fileURLToPath9(new URL("
|
|
61875
|
-
if (
|
|
62027
|
+
const source = fileURLToPath9(new URL("../../../../../packages/web/server/index.ts", import.meta.url).href);
|
|
62028
|
+
if (existsSync20(source)) {
|
|
61876
62029
|
return source;
|
|
61877
62030
|
}
|
|
61878
|
-
|
|
62031
|
+
const legacySource = fileURLToPath9(new URL("../../server/control-plane-index.ts", import.meta.url).href);
|
|
62032
|
+
if (existsSync20(legacySource)) {
|
|
62033
|
+
return legacySource;
|
|
62034
|
+
}
|
|
62035
|
+
throw new ScoutCliError("Could not find Scout web server entry. Rebuild @openscout/scout or run from the OpenScout repository.");
|
|
61879
62036
|
}
|
|
61880
62037
|
function parseServerFlags(args) {
|
|
61881
62038
|
const env = {};
|
|
@@ -61949,7 +62106,7 @@ function resolveBundledStaticClientRoot(entry, _mode) {
|
|
|
61949
62106
|
const entryDir = dirname14(entry);
|
|
61950
62107
|
const clientDirectory = join28(entryDir, "client");
|
|
61951
62108
|
const indexPath = join28(clientDirectory, "index.html");
|
|
61952
|
-
return
|
|
62109
|
+
return existsSync20(indexPath) ? clientDirectory : null;
|
|
61953
62110
|
}
|
|
61954
62111
|
function buildMergedServerEnv(entry, mode, flagEnv) {
|
|
61955
62112
|
const bundledStaticClientRoot = resolveBundledStaticClientRoot(entry, mode);
|
|
@@ -61975,7 +62132,7 @@ function parseServerSelection(args) {
|
|
|
61975
62132
|
action: "start",
|
|
61976
62133
|
flagArgs: args.slice(1),
|
|
61977
62134
|
entry: resolveScoutControlPlaneWebServerEntry(),
|
|
61978
|
-
mode: "
|
|
62135
|
+
mode: "openscout-web"
|
|
61979
62136
|
};
|
|
61980
62137
|
}
|
|
61981
62138
|
if (args[0] === "open") {
|
|
@@ -61983,7 +62140,7 @@ function parseServerSelection(args) {
|
|
|
61983
62140
|
action: "open",
|
|
61984
62141
|
flagArgs: args.slice(1),
|
|
61985
62142
|
entry: resolveScoutControlPlaneWebServerEntry(),
|
|
61986
|
-
mode: "
|
|
62143
|
+
mode: "openscout-web"
|
|
61987
62144
|
};
|
|
61988
62145
|
}
|
|
61989
62146
|
if (args[0] === "control-plane") {
|
|
@@ -61992,7 +62149,7 @@ function parseServerSelection(args) {
|
|
|
61992
62149
|
action: sub,
|
|
61993
62150
|
flagArgs: args.slice(2),
|
|
61994
62151
|
entry: resolveScoutControlPlaneWebServerEntry(),
|
|
61995
|
-
mode: "
|
|
62152
|
+
mode: "openscout-web"
|
|
61996
62153
|
};
|
|
61997
62154
|
}
|
|
61998
62155
|
throw new ScoutCliError(`unknown subcommand: ${args[0]} (try: scout server open)`);
|
|
@@ -62028,7 +62185,7 @@ function resolveExpectedCurrentDirectory(env) {
|
|
|
62028
62185
|
return resolve14(env.OPENSCOUT_SETUP_CWD?.trim() || process.cwd());
|
|
62029
62186
|
}
|
|
62030
62187
|
function renderModeLabel(mode) {
|
|
62031
|
-
return
|
|
62188
|
+
return "Scout web";
|
|
62032
62189
|
}
|
|
62033
62190
|
function renderSurfaceLabel(surface) {
|
|
62034
62191
|
switch (surface) {
|
|
@@ -62036,14 +62193,13 @@ function renderSurfaceLabel(surface) {
|
|
|
62036
62193
|
return "control-plane";
|
|
62037
62194
|
case "openscout-web":
|
|
62038
62195
|
return "@openscout/web";
|
|
62039
|
-
case "full":
|
|
62040
|
-
default:
|
|
62041
|
-
return "full";
|
|
62042
62196
|
}
|
|
62043
62197
|
}
|
|
62044
62198
|
function renderServerOpenResult(result) {
|
|
62045
|
-
|
|
62046
|
-
|
|
62199
|
+
return `Opened Scout web at ${result.url}${result.reusedExistingServer ? "" : " (started server)"}`;
|
|
62200
|
+
}
|
|
62201
|
+
function isCurrentScoutWebSurface(surface) {
|
|
62202
|
+
return surface === "openscout-web" || surface === "control-plane";
|
|
62047
62203
|
}
|
|
62048
62204
|
function healthUrlForPort(port) {
|
|
62049
62205
|
return new URL(`/api/health`, `http://127.0.0.1:${port}`);
|
|
@@ -62071,7 +62227,7 @@ async function probeScoutServer(port) {
|
|
|
62071
62227
|
statusCode: response.status
|
|
62072
62228
|
};
|
|
62073
62229
|
}
|
|
62074
|
-
if (body.ok === true && (body.surface === "
|
|
62230
|
+
if (body.ok === true && (body.surface === "control-plane" || body.surface === "openscout-web") && typeof body.currentDirectory === "string") {
|
|
62075
62231
|
return {
|
|
62076
62232
|
status: "healthy",
|
|
62077
62233
|
health: {
|
|
@@ -62150,7 +62306,7 @@ async function waitForScoutServer(port, mode, expectedCurrentDirectory) {
|
|
|
62150
62306
|
const probe = await probeScoutServer(port);
|
|
62151
62307
|
if (probe.status === "healthy") {
|
|
62152
62308
|
const actualCurrentDirectory = resolve14(probe.health.currentDirectory);
|
|
62153
|
-
if (probe.health.surface
|
|
62309
|
+
if (!isCurrentScoutWebSurface(probe.health.surface)) {
|
|
62154
62310
|
throw new ScoutCliError(`port ${port} is serving Scout ${renderSurfaceLabel(probe.health.surface)}, not ${renderModeLabel(mode)}.`);
|
|
62155
62311
|
}
|
|
62156
62312
|
if (actualCurrentDirectory !== expectedCurrentDirectory) {
|
|
@@ -62172,7 +62328,7 @@ async function openScoutServer(options) {
|
|
|
62172
62328
|
const probe = await probeScoutServer(port);
|
|
62173
62329
|
if (probe.status === "healthy") {
|
|
62174
62330
|
const actualCurrentDirectory = resolve14(probe.health.currentDirectory);
|
|
62175
|
-
if (probe.health.surface
|
|
62331
|
+
if (!isCurrentScoutWebSurface(probe.health.surface)) {
|
|
62176
62332
|
throw new ScoutCliError(`port ${port} is already serving Scout ${renderSurfaceLabel(probe.health.surface)}, not ${renderModeLabel(options.mode)}.`);
|
|
62177
62333
|
}
|
|
62178
62334
|
if (actualCurrentDirectory !== expectedCurrentDirectory) {
|
|
@@ -62370,7 +62526,7 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
62370
62526
|
import { resolve as resolve15, dirname as dirname15 } from "path";
|
|
62371
62527
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
62372
62528
|
import { resolve as resolve22, isAbsolute as isAbsolute5, parse as parse7 } from "path";
|
|
62373
|
-
import { existsSync as
|
|
62529
|
+
import { existsSync as existsSync21 } from "fs";
|
|
62374
62530
|
import { basename as basename11, join as join29 } from "path";
|
|
62375
62531
|
import os from "os";
|
|
62376
62532
|
import path2 from "path";
|
|
@@ -76584,7 +76740,7 @@ var init_index_vy1rm1x3 = __esm(async () => {
|
|
|
76584
76740
|
worker_path = this.options.workerPath;
|
|
76585
76741
|
} else {
|
|
76586
76742
|
worker_path = new URL("./parser.worker.js", import.meta.url).href;
|
|
76587
|
-
if (!
|
|
76743
|
+
if (!existsSync21(resolve22(import.meta.dirname, "parser.worker.js"))) {
|
|
76588
76744
|
worker_path = new URL("./parser.worker.ts", import.meta.url).href;
|
|
76589
76745
|
}
|
|
76590
76746
|
}
|
|
@@ -123658,7 +123814,7 @@ var exports_up = {};
|
|
|
123658
123814
|
__export(exports_up, {
|
|
123659
123815
|
runUpCommand: () => runUpCommand
|
|
123660
123816
|
});
|
|
123661
|
-
import { existsSync as
|
|
123817
|
+
import { existsSync as existsSync23 } from "fs";
|
|
123662
123818
|
import { resolve as resolve17 } from "path";
|
|
123663
123819
|
function looksLikePath(value) {
|
|
123664
123820
|
return value.includes("/") || value.startsWith(".") || value.startsWith("~");
|
|
@@ -123707,7 +123863,7 @@ async function runUpCommand(context, args) {
|
|
|
123707
123863
|
throw new ScoutCliError("usage: scout up <name|path> [--name <alias>] [--harness <claude|codex>]");
|
|
123708
123864
|
}
|
|
123709
123865
|
let projectPath;
|
|
123710
|
-
if (looksLikePath(target) ||
|
|
123866
|
+
if (looksLikePath(target) || existsSync23(resolve17(target))) {
|
|
123711
123867
|
projectPath = resolve17(target);
|
|
123712
123868
|
} else {
|
|
123713
123869
|
const resolved = await resolveLocalAgentByName(target);
|
|
@@ -123827,7 +123983,7 @@ var init_whoami = __esm(async () => {
|
|
|
123827
123983
|
});
|
|
123828
123984
|
|
|
123829
123985
|
// ../../apps/desktop/src/cli/main.ts
|
|
123830
|
-
import { existsSync as
|
|
123986
|
+
import { existsSync as existsSync25, readFileSync as readFileSync15, writeFileSync as writeFileSync9, statSync as statSync5, mkdirSync as mkdirSync12 } from "fs";
|
|
123831
123987
|
import { join as join32 } from "path";
|
|
123832
123988
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
123833
123989
|
import { homedir as homedir23 } from "os";
|
|
@@ -124091,7 +124247,7 @@ function getScoutBinPath() {
|
|
|
124091
124247
|
if (_scoutBinPath)
|
|
124092
124248
|
return _scoutBinPath;
|
|
124093
124249
|
_scoutBinPath = join32(homedir23(), ".bun", "bin", "scout");
|
|
124094
|
-
if (!
|
|
124250
|
+
if (!existsSync25(_scoutBinPath)) {
|
|
124095
124251
|
_scoutBinPath = spawnSync3("which", ["scout"], { encoding: "utf8" }).stdout.trim();
|
|
124096
124252
|
}
|
|
124097
124253
|
return _scoutBinPath;
|
|
@@ -124101,7 +124257,7 @@ async function ensureBrokerUptodate() {
|
|
|
124101
124257
|
const mtime = statSync5(getScoutBinPath()).mtimeMs;
|
|
124102
124258
|
const checkpointDir = join32(homedir23(), ".scout");
|
|
124103
124259
|
const mtimePath = join32(checkpointDir, "cli-mtime");
|
|
124104
|
-
const lastMtime =
|
|
124260
|
+
const lastMtime = existsSync25(mtimePath) ? Number(readFileSync15(mtimePath, "utf8").trim()) : 0;
|
|
124105
124261
|
if (mtime > lastMtime) {
|
|
124106
124262
|
const uid = process.getuid();
|
|
124107
124263
|
const plistPath = join32(homedir23(), "Library", "LaunchAgents", "dev.openscout.broker.plist");
|
|
@@ -124110,7 +124266,7 @@ async function ensureBrokerUptodate() {
|
|
|
124110
124266
|
spawnSync3("launchctl", ["bootstrap", `gui/${uid}`, plistPath], { stdio: "ignore" });
|
|
124111
124267
|
await new Promise((resolve18) => setTimeout(resolve18, 2000));
|
|
124112
124268
|
}
|
|
124113
|
-
if (!
|
|
124269
|
+
if (!existsSync25(checkpointDir)) {
|
|
124114
124270
|
mkdirSync12(checkpointDir, { recursive: true });
|
|
124115
124271
|
}
|
|
124116
124272
|
writeFileSync9(mtimePath, String(Math.floor(mtime)), { encoding: "utf8", flag: "w" });
|