@openscout/scout 0.2.56 → 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-Cs--6ecm.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 +3 -3
- package/dist/main.mjs +295 -131
- package/dist/pair-supervisor.mjs +159 -42
- package/dist/scout-control-plane-web.mjs +1123 -855
- package/package.json +2 -2
- package/dist/client/assets/index-DvJjuWtM.js +0 -146
- package/dist/client/assets/index-MaClzcbW.css +0 -1
package/dist/pair-supervisor.mjs
CHANGED
|
@@ -7932,7 +7932,7 @@ function serveFile(url) {
|
|
|
7932
7932
|
}
|
|
7933
7933
|
|
|
7934
7934
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
|
|
7935
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
7935
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync9, realpathSync, statSync as statSync3 } from "fs";
|
|
7936
7936
|
import { execSync as execSync3 } from "child_process";
|
|
7937
7937
|
import { basename as basename6, isAbsolute as isAbsolute3, join as join17, relative as relative2 } from "path";
|
|
7938
7938
|
import { homedir as homedir15 } from "os";
|
|
@@ -8036,6 +8036,11 @@ var BUILT_IN_HARNESS_CATALOG = [
|
|
|
8036
8036
|
loginCommand: "claude login",
|
|
8037
8037
|
notReadyMessage: "Claude is installed but not authenticated yet."
|
|
8038
8038
|
},
|
|
8039
|
+
resume: {
|
|
8040
|
+
command: "claude",
|
|
8041
|
+
sessionFlag: "--resume",
|
|
8042
|
+
cwdFlag: "--cwd"
|
|
8043
|
+
},
|
|
8039
8044
|
capabilities: ["chat", "invoke", "deliver", "summarize", "review"]
|
|
8040
8045
|
},
|
|
8041
8046
|
{
|
|
@@ -8067,6 +8072,11 @@ var BUILT_IN_HARNESS_CATALOG = [
|
|
|
8067
8072
|
loginCommand: "codex login",
|
|
8068
8073
|
notReadyMessage: "Codex is installed but not authenticated yet."
|
|
8069
8074
|
},
|
|
8075
|
+
resume: {
|
|
8076
|
+
command: "codex",
|
|
8077
|
+
sessionFlag: "--thread",
|
|
8078
|
+
cwdFlag: "--cwd"
|
|
8079
|
+
},
|
|
8070
8080
|
capabilities: ["chat", "invoke", "deliver", "review", "execute"]
|
|
8071
8081
|
}
|
|
8072
8082
|
];
|
|
@@ -8179,6 +8189,7 @@ function createBuiltInHarnessCatalog() {
|
|
|
8179
8189
|
anyOf: entry.readiness.anyOf ? [...entry.readiness.anyOf] : undefined
|
|
8180
8190
|
} : undefined,
|
|
8181
8191
|
launch: entry.launch ? { ...entry.launch, args: [...entry.launch.args] } : undefined,
|
|
8192
|
+
resume: entry.resume ? { ...entry.resume } : undefined,
|
|
8182
8193
|
resolveEnv: entry.resolveEnv ? [...entry.resolveEnv] : undefined,
|
|
8183
8194
|
capabilities: [...entry.capabilities],
|
|
8184
8195
|
metadata: entry.metadata ? { ...entry.metadata } : undefined
|
|
@@ -8196,6 +8207,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
8196
8207
|
install: mergeInstall(entry.install, override.install),
|
|
8197
8208
|
readiness: mergeReadiness(entry.readiness, override.readiness),
|
|
8198
8209
|
launch: mergeLaunch(entry.launch, override.launch),
|
|
8210
|
+
resume: override.resume && entry.resume ? { ...entry.resume, ...override.resume } : entry.resume,
|
|
8199
8211
|
tags: override.tags ? [...override.tags] : entry.tags,
|
|
8200
8212
|
capabilities: override.capabilities ? [...override.capabilities] : entry.capabilities,
|
|
8201
8213
|
resolveEnv: override.resolveEnv ? [...override.resolveEnv] : entry.resolveEnv,
|
|
@@ -8224,6 +8236,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
|
|
|
8224
8236
|
install: mergeInstall(undefined, override.install),
|
|
8225
8237
|
readiness: mergeReadiness(undefined, override.readiness),
|
|
8226
8238
|
launch: mergeLaunch(undefined, override.launch),
|
|
8239
|
+
resume: override.resume?.command && override.resume?.sessionFlag ? { command: override.resume.command, sessionFlag: override.resume.sessionFlag, cwdFlag: override.resume.cwdFlag } : undefined,
|
|
8227
8240
|
resolveEnv: override.resolveEnv ? [...override.resolveEnv] : undefined,
|
|
8228
8241
|
capabilities: [...override.capabilities],
|
|
8229
8242
|
metadata: override.metadata ? { ...override.metadata } : undefined
|
|
@@ -11729,7 +11742,7 @@ async function ensureRelayAgentConfigured(value, options = {}) {
|
|
|
11729
11742
|
|
|
11730
11743
|
// ../runtime/src/local-agents.ts
|
|
11731
11744
|
import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
|
|
11732
|
-
import { existsSync as
|
|
11745
|
+
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
|
|
11733
11746
|
import { mkdir as mkdir6, rm as rm5, stat as stat3, writeFile as writeFile6 } from "fs/promises";
|
|
11734
11747
|
import { basename as basename4, dirname as dirname6, join as join15, resolve as resolve5 } from "path";
|
|
11735
11748
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
@@ -11737,7 +11750,8 @@ import { fileURLToPath as fileURLToPath5 } from "url";
|
|
|
11737
11750
|
// ../runtime/src/claude-stream-json.ts
|
|
11738
11751
|
import { randomUUID } from "crypto";
|
|
11739
11752
|
import { spawn as spawn2 } from "child_process";
|
|
11740
|
-
import { appendFile as appendFile2, mkdir as mkdir4, readFile as readFile5,
|
|
11753
|
+
import { appendFile as appendFile2, mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
11754
|
+
import { existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
|
|
11741
11755
|
import { join as join12 } from "path";
|
|
11742
11756
|
|
|
11743
11757
|
// ../runtime/src/managed-agent-environment.ts
|
|
@@ -11778,18 +11792,58 @@ function sessionKey(options) {
|
|
|
11778
11792
|
function errorMessage2(error) {
|
|
11779
11793
|
return error instanceof Error ? error.message : String(error);
|
|
11780
11794
|
}
|
|
11781
|
-
|
|
11795
|
+
var SESSION_CATALOG_FILENAME = "session-catalog.json";
|
|
11796
|
+
var SESSION_CATALOG_MAX_ENTRIES = 64;
|
|
11797
|
+
function readSessionCatalogSync(runtimeDirectory) {
|
|
11798
|
+
const catalogPath = join12(runtimeDirectory, SESSION_CATALOG_FILENAME);
|
|
11782
11799
|
try {
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11800
|
+
if (!existsSync11(catalogPath)) {
|
|
11801
|
+
const legacyPath = join12(runtimeDirectory, "claude-session-id.txt");
|
|
11802
|
+
if (existsSync11(legacyPath)) {
|
|
11803
|
+
const legacyId = readFileSync6(legacyPath, "utf8").trim();
|
|
11804
|
+
if (legacyId) {
|
|
11805
|
+
return {
|
|
11806
|
+
activeSessionId: legacyId,
|
|
11807
|
+
sessions: [{ id: legacyId, startedAt: Date.now(), cwd: "" }]
|
|
11808
|
+
};
|
|
11809
|
+
}
|
|
11810
|
+
}
|
|
11811
|
+
return { activeSessionId: null, sessions: [] };
|
|
11812
|
+
}
|
|
11813
|
+
const raw = readFileSync6(catalogPath, "utf8").trim();
|
|
11814
|
+
if (!raw)
|
|
11815
|
+
return { activeSessionId: null, sessions: [] };
|
|
11816
|
+
const parsed = JSON.parse(raw);
|
|
11817
|
+
return {
|
|
11818
|
+
activeSessionId: parsed.activeSessionId ?? null,
|
|
11819
|
+
sessions: Array.isArray(parsed.sessions) ? parsed.sessions : []
|
|
11820
|
+
};
|
|
11786
11821
|
} catch {
|
|
11787
|
-
return null;
|
|
11822
|
+
return { activeSessionId: null, sessions: [] };
|
|
11788
11823
|
}
|
|
11789
11824
|
}
|
|
11825
|
+
async function readSessionCatalog(runtimeDirectory) {
|
|
11826
|
+
return readSessionCatalogSync(runtimeDirectory);
|
|
11827
|
+
}
|
|
11828
|
+
async function writeSessionCatalog(runtimeDirectory, catalog) {
|
|
11829
|
+
const catalogPath = join12(runtimeDirectory, SESSION_CATALOG_FILENAME);
|
|
11830
|
+
await writeFile4(catalogPath, JSON.stringify(catalog, null, 2) + `
|
|
11831
|
+
`);
|
|
11832
|
+
}
|
|
11833
|
+
function catalogRecordSession(catalog, sessionId, cwd) {
|
|
11834
|
+
const now = Date.now();
|
|
11835
|
+
const sessions = catalog.sessions.map((s) => s.id === catalog.activeSessionId && !s.endedAt ? { ...s, endedAt: now } : s);
|
|
11836
|
+
if (!sessions.some((s) => s.id === sessionId)) {
|
|
11837
|
+
sessions.push({ id: sessionId, startedAt: now, cwd });
|
|
11838
|
+
}
|
|
11839
|
+
while (sessions.length > SESSION_CATALOG_MAX_ENTRIES) {
|
|
11840
|
+
sessions.shift();
|
|
11841
|
+
}
|
|
11842
|
+
return { activeSessionId: sessionId, sessions };
|
|
11843
|
+
}
|
|
11790
11844
|
class ClaudeStreamJsonSession {
|
|
11791
11845
|
options;
|
|
11792
|
-
|
|
11846
|
+
catalogDirectory;
|
|
11793
11847
|
stdoutLogPath;
|
|
11794
11848
|
stderrLogPath;
|
|
11795
11849
|
process = null;
|
|
@@ -11800,7 +11854,7 @@ class ClaudeStreamJsonSession {
|
|
|
11800
11854
|
lastConfigSignature;
|
|
11801
11855
|
constructor(options) {
|
|
11802
11856
|
this.options = options;
|
|
11803
|
-
this.
|
|
11857
|
+
this.catalogDirectory = options.runtimeDirectory;
|
|
11804
11858
|
this.stdoutLogPath = join12(options.logsDirectory, "stdout.log");
|
|
11805
11859
|
this.stderrLogPath = join12(options.logsDirectory, "stderr.log");
|
|
11806
11860
|
this.lastConfigSignature = this.configSignature(options);
|
|
@@ -11906,7 +11960,9 @@ class ClaudeStreamJsonSession {
|
|
|
11906
11960
|
}
|
|
11907
11961
|
if (options.resetSession) {
|
|
11908
11962
|
this.claudeSessionId = null;
|
|
11909
|
-
await
|
|
11963
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
11964
|
+
catalog.activeSessionId = null;
|
|
11965
|
+
await writeSessionCatalog(this.catalogDirectory, catalog);
|
|
11910
11966
|
}
|
|
11911
11967
|
}
|
|
11912
11968
|
configSignature(options) {
|
|
@@ -11935,7 +11991,8 @@ class ClaudeStreamJsonSession {
|
|
|
11935
11991
|
await mkdir4(this.options.runtimeDirectory, { recursive: true });
|
|
11936
11992
|
await mkdir4(this.options.logsDirectory, { recursive: true });
|
|
11937
11993
|
await writeFile4(join12(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
|
|
11938
|
-
|
|
11994
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
11995
|
+
this.claudeSessionId = catalog.activeSessionId;
|
|
11939
11996
|
const args = [
|
|
11940
11997
|
"--verbose",
|
|
11941
11998
|
"--print",
|
|
@@ -12014,8 +12071,11 @@ class ClaudeStreamJsonSession {
|
|
|
12014
12071
|
const nextSessionId = event.session_id ?? event.sessionId ?? null;
|
|
12015
12072
|
if (nextSessionId && nextSessionId !== this.claudeSessionId) {
|
|
12016
12073
|
this.claudeSessionId = nextSessionId;
|
|
12017
|
-
|
|
12018
|
-
|
|
12074
|
+
(async () => {
|
|
12075
|
+
const catalog = await readSessionCatalog(this.catalogDirectory);
|
|
12076
|
+
const updated = catalogRecordSession(catalog, nextSessionId, this.options.cwd);
|
|
12077
|
+
await writeSessionCatalog(this.catalogDirectory, updated);
|
|
12078
|
+
})();
|
|
12019
12079
|
}
|
|
12020
12080
|
return;
|
|
12021
12081
|
}
|
|
@@ -12079,7 +12139,9 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
|
|
|
12079
12139
|
const session = sessions.get(key);
|
|
12080
12140
|
if (!session) {
|
|
12081
12141
|
if (shutdownOptions.resetSession) {
|
|
12082
|
-
await
|
|
12142
|
+
const catalog = await readSessionCatalog(options.runtimeDirectory);
|
|
12143
|
+
catalog.activeSessionId = null;
|
|
12144
|
+
await writeSessionCatalog(options.runtimeDirectory, catalog);
|
|
12083
12145
|
}
|
|
12084
12146
|
return;
|
|
12085
12147
|
}
|
|
@@ -12186,7 +12248,7 @@ function isServerRequest2(message) {
|
|
|
12186
12248
|
function isNotification2(message) {
|
|
12187
12249
|
return Boolean(message && typeof message === "object" && "method" in message && !("id" in message));
|
|
12188
12250
|
}
|
|
12189
|
-
async function
|
|
12251
|
+
async function readOptionalFile2(filePath) {
|
|
12190
12252
|
try {
|
|
12191
12253
|
const raw = await readFile6(filePath, "utf8");
|
|
12192
12254
|
const trimmed = raw.trim();
|
|
@@ -12463,7 +12525,7 @@ class CodexAppServerSession {
|
|
|
12463
12525
|
}
|
|
12464
12526
|
async resumeOrStartThread() {
|
|
12465
12527
|
const requestedThreadId = this.options.threadId?.trim() || null;
|
|
12466
|
-
const storedThreadId = requestedThreadId ?? await
|
|
12528
|
+
const storedThreadId = requestedThreadId ?? await readOptionalFile2(this.threadIdPath);
|
|
12467
12529
|
if (storedThreadId) {
|
|
12468
12530
|
try {
|
|
12469
12531
|
const resumed = await this.request("thread/resume", {
|
|
@@ -12890,7 +12952,7 @@ function buildCollaborationContractPrompt(agentId) {
|
|
|
12890
12952
|
|
|
12891
12953
|
// ../runtime/src/broker-service.ts
|
|
12892
12954
|
import { spawnSync } from "child_process";
|
|
12893
|
-
import { existsSync as
|
|
12955
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
12894
12956
|
import { homedir as homedir13 } from "os";
|
|
12895
12957
|
import { basename as basename3, dirname as dirname5, join as join14, resolve as resolve4 } from "path";
|
|
12896
12958
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -12936,7 +12998,7 @@ function runtimePackageDir() {
|
|
|
12936
12998
|
return resolve4(moduleDir, "..");
|
|
12937
12999
|
}
|
|
12938
13000
|
function isInstalledRuntimePackageDir(candidate) {
|
|
12939
|
-
return
|
|
13001
|
+
return existsSync12(join14(candidate, "package.json")) && existsSync12(join14(candidate, "bin", "openscout-runtime.mjs"));
|
|
12940
13002
|
}
|
|
12941
13003
|
function findGlobalRuntimeDir() {
|
|
12942
13004
|
const candidates = [
|
|
@@ -12967,7 +13029,7 @@ function findWorkspaceRuntimeDir(startDir) {
|
|
|
12967
13029
|
let current = resolve4(startDir);
|
|
12968
13030
|
while (true) {
|
|
12969
13031
|
const candidate = join14(current, "packages", "runtime");
|
|
12970
|
-
if (
|
|
13032
|
+
if (existsSync12(join14(candidate, "package.json")) && existsSync12(join14(candidate, "src"))) {
|
|
12971
13033
|
return candidate;
|
|
12972
13034
|
}
|
|
12973
13035
|
const parent = dirname5(current);
|
|
@@ -12981,18 +13043,18 @@ function resolveBunExecutable2() {
|
|
|
12981
13043
|
if (explicit && explicit.trim().length > 0) {
|
|
12982
13044
|
return explicit;
|
|
12983
13045
|
}
|
|
12984
|
-
if (basename3(process.execPath).startsWith("bun") &&
|
|
13046
|
+
if (basename3(process.execPath).startsWith("bun") && existsSync12(process.execPath)) {
|
|
12985
13047
|
return process.execPath;
|
|
12986
13048
|
}
|
|
12987
13049
|
const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
|
|
12988
13050
|
for (const entry of pathEntries) {
|
|
12989
13051
|
const candidate = join14(entry, "bun");
|
|
12990
|
-
if (
|
|
13052
|
+
if (existsSync12(candidate)) {
|
|
12991
13053
|
return candidate;
|
|
12992
13054
|
}
|
|
12993
13055
|
}
|
|
12994
13056
|
const homeBun = join14(homedir13(), ".bun", "bin", "bun");
|
|
12995
|
-
if (
|
|
13057
|
+
if (existsSync12(homeBun)) {
|
|
12996
13058
|
return homeBun;
|
|
12997
13059
|
}
|
|
12998
13060
|
return "bun";
|
|
@@ -13182,10 +13244,10 @@ function launchctlPath() {
|
|
|
13182
13244
|
return "/bin/launchctl";
|
|
13183
13245
|
}
|
|
13184
13246
|
function readLogLines(path2) {
|
|
13185
|
-
if (!
|
|
13247
|
+
if (!existsSync12(path2)) {
|
|
13186
13248
|
return [];
|
|
13187
13249
|
}
|
|
13188
|
-
return
|
|
13250
|
+
return readFileSync7(path2, "utf8").split(`
|
|
13189
13251
|
`).map((line) => line.trim()).filter(Boolean);
|
|
13190
13252
|
}
|
|
13191
13253
|
function isPackageScriptBanner(line) {
|
|
@@ -13282,7 +13344,7 @@ async function brokerServiceStatus(config = resolveBrokerServiceConfig()) {
|
|
|
13282
13344
|
ensureServiceDirectories(config);
|
|
13283
13345
|
const launchctl = inspectLaunchctl(config);
|
|
13284
13346
|
const health = await fetchHealthSnapshot(config);
|
|
13285
|
-
const installed =
|
|
13347
|
+
const installed = existsSync12(config.launchAgentPath);
|
|
13286
13348
|
const lastLogLine = health.reachable ? readLastLogLine([config.stdoutLogPath, config.stderrLogPath]) : readLastLogLine([config.stderrLogPath, config.stdoutLogPath]);
|
|
13287
13349
|
return {
|
|
13288
13350
|
label: config.label,
|
|
@@ -13344,7 +13406,7 @@ async function restartBrokerService(config = resolveBrokerServiceConfig()) {
|
|
|
13344
13406
|
}
|
|
13345
13407
|
async function uninstallBrokerService(config = resolveBrokerServiceConfig()) {
|
|
13346
13408
|
await stopBrokerService(config);
|
|
13347
|
-
if (
|
|
13409
|
+
if (existsSync12(config.launchAgentPath)) {
|
|
13348
13410
|
rmSync2(config.launchAgentPath, { force: true });
|
|
13349
13411
|
}
|
|
13350
13412
|
return brokerServiceStatus(config);
|
|
@@ -13427,10 +13489,10 @@ function resolveProjectsRoot(projectPath) {
|
|
|
13427
13489
|
}
|
|
13428
13490
|
try {
|
|
13429
13491
|
const supportPaths = resolveOpenScoutSupportPaths();
|
|
13430
|
-
if (!
|
|
13492
|
+
if (!existsSync13(supportPaths.settingsPath)) {
|
|
13431
13493
|
return dirname6(projectPath);
|
|
13432
13494
|
}
|
|
13433
|
-
const raw = JSON.parse(
|
|
13495
|
+
const raw = JSON.parse(readFileSync8(supportPaths.settingsPath, "utf8"));
|
|
13434
13496
|
const workspaceRoot = raw.discovery?.workspaceRoots?.find((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
13435
13497
|
return workspaceRoot ? resolve5(workspaceRoot) : dirname6(projectPath);
|
|
13436
13498
|
} catch {
|
|
@@ -13443,8 +13505,14 @@ function resolveBrokerUrl() {
|
|
|
13443
13505
|
function nowSeconds2() {
|
|
13444
13506
|
return Math.floor(Date.now() / 1000);
|
|
13445
13507
|
}
|
|
13508
|
+
function scoutCliPath() {
|
|
13509
|
+
return join15(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
|
|
13510
|
+
}
|
|
13511
|
+
function legacyNodeBrokerRelayCommand() {
|
|
13512
|
+
return `node ${JSON.stringify(scoutCliPath())}`;
|
|
13513
|
+
}
|
|
13446
13514
|
function brokerRelayCommand() {
|
|
13447
|
-
return `
|
|
13515
|
+
return `bun ${JSON.stringify(scoutCliPath())}`;
|
|
13448
13516
|
}
|
|
13449
13517
|
function titleCaseLocalAgentName(value) {
|
|
13450
13518
|
return value.split(/[-_.\s]+/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
|
|
@@ -13457,7 +13525,7 @@ function resolveScoutSkillPath() {
|
|
|
13457
13525
|
join15(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
|
|
13458
13526
|
];
|
|
13459
13527
|
for (const path2 of candidatePaths) {
|
|
13460
|
-
if (
|
|
13528
|
+
if (existsSync13(path2)) {
|
|
13461
13529
|
return path2;
|
|
13462
13530
|
}
|
|
13463
13531
|
}
|
|
@@ -13653,7 +13721,7 @@ function buildLegacyBrokerBackedRelayPrompt(agentId, projectName, projectPath, r
|
|
|
13653
13721
|
function legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath) {
|
|
13654
13722
|
const relayHub = resolveRelayHub();
|
|
13655
13723
|
const brokerUrl = resolveBrokerUrl();
|
|
13656
|
-
const relayCommandBases = ["openscout relay", brokerRelayCommand()];
|
|
13724
|
+
const relayCommandBases = ["openscout relay", brokerRelayCommand(), legacyNodeBrokerRelayCommand()];
|
|
13657
13725
|
const projectPathCandidates = projectPath.endsWith("/") ? [projectPath, projectPath.slice(0, -1)] : [projectPath, `${projectPath}/`];
|
|
13658
13726
|
const candidates = new Set;
|
|
13659
13727
|
for (const pathCandidate of projectPathCandidates) {
|
|
@@ -13664,12 +13732,28 @@ function legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPat
|
|
|
13664
13732
|
}
|
|
13665
13733
|
return Array.from(candidates);
|
|
13666
13734
|
}
|
|
13735
|
+
function generatedLocalAgentSystemPromptCandidates(agentId, projectName, projectPath) {
|
|
13736
|
+
const baseContext = buildLocalAgentTemplateContext(agentId, projectName, projectPath);
|
|
13737
|
+
const relayCommands = [brokerRelayCommand(), legacyNodeBrokerRelayCommand()];
|
|
13738
|
+
const transportModes = [undefined, "codex_app_server", "claude_stream_json"];
|
|
13739
|
+
const candidates = new Set;
|
|
13740
|
+
for (const relayCommand of relayCommands) {
|
|
13741
|
+
const context = {
|
|
13742
|
+
...baseContext,
|
|
13743
|
+
relayCommand
|
|
13744
|
+
};
|
|
13745
|
+
for (const transport of transportModes) {
|
|
13746
|
+
candidates.add(renderLocalAgentSystemPromptTemplate(buildLocalAgentSystemPromptTemplate(), context, transport ? { transport } : {}));
|
|
13747
|
+
}
|
|
13748
|
+
}
|
|
13749
|
+
return Array.from(candidates);
|
|
13750
|
+
}
|
|
13667
13751
|
function normalizeLocalAgentSystemPrompt(agentId, projectName, projectPath, systemPrompt) {
|
|
13668
13752
|
const trimmed = systemPrompt?.trim();
|
|
13669
13753
|
if (!trimmed) {
|
|
13670
13754
|
return;
|
|
13671
13755
|
}
|
|
13672
|
-
if (legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed)) {
|
|
13756
|
+
if (legacyLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed) || generatedLocalAgentSystemPromptCandidates(agentId, projectName, projectPath).includes(trimmed)) {
|
|
13673
13757
|
return;
|
|
13674
13758
|
}
|
|
13675
13759
|
return trimmed;
|
|
@@ -14157,7 +14241,7 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
14157
14241
|
await new Promise((resolve6) => setTimeout(resolve6, 100));
|
|
14158
14242
|
}
|
|
14159
14243
|
if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
|
|
14160
|
-
const stderrTail =
|
|
14244
|
+
const stderrTail = existsSync13(stderrLogFile) ? readFileSync8(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
|
|
14161
14245
|
`).trim() : "";
|
|
14162
14246
|
throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
|
|
14163
14247
|
${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
|
|
@@ -14402,6 +14486,29 @@ async function interruptLocalAgent(agentId) {
|
|
|
14402
14486
|
return { ok: false, agentId };
|
|
14403
14487
|
}
|
|
14404
14488
|
}
|
|
14489
|
+
function readPersistedClaudeSessionId(agentName) {
|
|
14490
|
+
try {
|
|
14491
|
+
const runtimeDir = relayAgentRuntimeDirectory(agentName);
|
|
14492
|
+
const catalogPath = join15(runtimeDir, "session-catalog.json");
|
|
14493
|
+
if (existsSync13(catalogPath)) {
|
|
14494
|
+
const raw = readFileSync8(catalogPath, "utf8").trim();
|
|
14495
|
+
if (raw) {
|
|
14496
|
+
const catalog = JSON.parse(raw);
|
|
14497
|
+
if (typeof catalog.activeSessionId === "string" && catalog.activeSessionId.trim()) {
|
|
14498
|
+
return catalog.activeSessionId.trim();
|
|
14499
|
+
}
|
|
14500
|
+
}
|
|
14501
|
+
}
|
|
14502
|
+
const legacyPath = join15(runtimeDir, "claude-session-id.txt");
|
|
14503
|
+
if (existsSync13(legacyPath)) {
|
|
14504
|
+
const value = readFileSync8(legacyPath, "utf8").trim();
|
|
14505
|
+
return value || null;
|
|
14506
|
+
}
|
|
14507
|
+
return null;
|
|
14508
|
+
} catch {
|
|
14509
|
+
return null;
|
|
14510
|
+
}
|
|
14511
|
+
}
|
|
14405
14512
|
function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
14406
14513
|
const normalizedRecord = normalizeLocalAgentRecord(agentId, record);
|
|
14407
14514
|
const definitionId = normalizedRecord.definitionId ?? agentId;
|
|
@@ -14409,6 +14516,7 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
|
14409
14516
|
const projectRoot = normalizedRecord.projectRoot ?? normalizedRecord.cwd;
|
|
14410
14517
|
const instance = buildRelayAgentInstance(definitionId, projectRoot);
|
|
14411
14518
|
const actorId = instance.id;
|
|
14519
|
+
const externalSessionId = normalizedRecord.transport === "claude_stream_json" ? readPersistedClaudeSessionId(definitionId) : null;
|
|
14412
14520
|
return {
|
|
14413
14521
|
actor: {
|
|
14414
14522
|
id: actorId,
|
|
@@ -14486,7 +14594,8 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
|
|
|
14486
14594
|
selector: instance.selector,
|
|
14487
14595
|
nodeQualifier: instance.nodeQualifier,
|
|
14488
14596
|
workspaceQualifier: instance.workspaceQualifier,
|
|
14489
|
-
branch: instance.branch
|
|
14597
|
+
branch: instance.branch,
|
|
14598
|
+
...externalSessionId ? { externalSessionId } : {}
|
|
14490
14599
|
}
|
|
14491
14600
|
}
|
|
14492
14601
|
};
|
|
@@ -15050,6 +15159,12 @@ function compact(p) {
|
|
|
15050
15159
|
return null;
|
|
15051
15160
|
return p.startsWith(HOME) ? `~${p.slice(HOME.length)}` : p;
|
|
15052
15161
|
}
|
|
15162
|
+
function sqlQuoteLiteral(value) {
|
|
15163
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
15164
|
+
}
|
|
15165
|
+
function sqlStringList(values) {
|
|
15166
|
+
return `(${values.map(sqlQuoteLiteral).join(",")})`;
|
|
15167
|
+
}
|
|
15053
15168
|
var LATEST_AGENT_ENDPOINT_JOIN = `LEFT JOIN agent_endpoints ep ON ep.id = (
|
|
15054
15169
|
SELECT ep2.id
|
|
15055
15170
|
FROM agent_endpoints ep2
|
|
@@ -15077,6 +15192,8 @@ function summarizeAgentStatusLabel(rawState, isWorking) {
|
|
|
15077
15192
|
return "Offline";
|
|
15078
15193
|
}
|
|
15079
15194
|
}
|
|
15195
|
+
var ACTIVE_FLIGHT_STATES_SQL = sqlStringList(["running", "waking", "waiting", "queued"]);
|
|
15196
|
+
var ACTIVE_WORK_STATES_SQL = sqlStringList(["open", "working", "waiting", "review"]);
|
|
15080
15197
|
function conversationIdForAgent(agentId) {
|
|
15081
15198
|
return `dm.operator.${agentId}`;
|
|
15082
15199
|
}
|
|
@@ -15803,7 +15920,7 @@ async function deriveNewAgentName(projectName, branch, harness) {
|
|
|
15803
15920
|
async function createGitWorktree(projectRoot, agentName) {
|
|
15804
15921
|
const { execSync: execSync3 } = await import("child_process");
|
|
15805
15922
|
const { join: join17 } = await import("path");
|
|
15806
|
-
const { mkdirSync: mkdirSync9, existsSync:
|
|
15923
|
+
const { mkdirSync: mkdirSync9, existsSync: existsSync14 } = await import("fs");
|
|
15807
15924
|
try {
|
|
15808
15925
|
execSync3("git rev-parse --git-dir", { cwd: projectRoot, stdio: "pipe" });
|
|
15809
15926
|
} catch {
|
|
@@ -15812,7 +15929,7 @@ async function createGitWorktree(projectRoot, agentName) {
|
|
|
15812
15929
|
const branchName = `scout/${agentName}`;
|
|
15813
15930
|
const worktreeDir = join17(projectRoot, ".scout-worktrees");
|
|
15814
15931
|
const worktreePath = join17(worktreeDir, agentName);
|
|
15815
|
-
if (
|
|
15932
|
+
if (existsSync14(worktreePath)) {
|
|
15816
15933
|
return { path: worktreePath, branch: branchName };
|
|
15817
15934
|
}
|
|
15818
15935
|
mkdirSync9(worktreeDir, { recursive: true });
|
|
@@ -16180,7 +16297,7 @@ async function handleRPCInner(bridge, req, deviceId) {
|
|
|
16180
16297
|
return { id: req.id, error: { code: -32000, message: "Only .jsonl files can be read" } };
|
|
16181
16298
|
}
|
|
16182
16299
|
try {
|
|
16183
|
-
const content =
|
|
16300
|
+
const content = readFileSync9(p.path, "utf-8");
|
|
16184
16301
|
const lines = content.split(`
|
|
16185
16302
|
`).filter((l) => l.trim().length > 0);
|
|
16186
16303
|
const trimmed = lines.length > 500 ? lines.slice(-500) : lines;
|
|
@@ -33073,7 +33190,7 @@ class ThreadEventPlane {
|
|
|
33073
33190
|
}
|
|
33074
33191
|
// ../runtime/src/mobile-push.ts
|
|
33075
33192
|
import { Database as Database2 } from "bun:sqlite";
|
|
33076
|
-
import { mkdirSync as mkdirSync9, readFileSync as
|
|
33193
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync10 } from "fs";
|
|
33077
33194
|
import { connect as connectHttp2 } from "http2";
|
|
33078
33195
|
import { createPrivateKey, sign as signWithKey } from "crypto";
|
|
33079
33196
|
import { dirname as dirname7, join as join18 } from "path";
|
|
@@ -33270,7 +33387,7 @@ function loadApnsCredentials() {
|
|
|
33270
33387
|
privateKeyPem = Buffer.from(inlineBase64, "base64").toString("utf8");
|
|
33271
33388
|
}
|
|
33272
33389
|
if (!privateKeyPem && path2) {
|
|
33273
|
-
privateKeyPem =
|
|
33390
|
+
privateKeyPem = readFileSync10(path2, "utf8");
|
|
33274
33391
|
}
|
|
33275
33392
|
if (!teamId || !keyId || !privateKeyPem) {
|
|
33276
33393
|
return null;
|
|
@@ -33444,7 +33561,7 @@ async function broadcastApnsAlertToActiveMobileDevices(alert) {
|
|
|
33444
33561
|
};
|
|
33445
33562
|
}
|
|
33446
33563
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
|
|
33447
|
-
import { readFileSync as
|
|
33564
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync4, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
|
|
33448
33565
|
import { execSync as execSync4 } from "child_process";
|
|
33449
33566
|
import { basename as basename7, isAbsolute as isAbsolute4, join as join19, relative as relative3 } from "path";
|
|
33450
33567
|
import { homedir as homedir16 } from "os";
|
|
@@ -34102,7 +34219,7 @@ var historyRouter = t.router({
|
|
|
34102
34219
|
});
|
|
34103
34220
|
}
|
|
34104
34221
|
try {
|
|
34105
|
-
const content =
|
|
34222
|
+
const content = readFileSync11(input.path, "utf-8");
|
|
34106
34223
|
const lines = content.split(`
|
|
34107
34224
|
`).filter((l) => l.trim().length > 0);
|
|
34108
34225
|
const trimmed = lines.length > 500 ? lines.slice(-500) : lines;
|