@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.
@@ -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 readFileSync8, realpathSync, statSync as statSync3 } from "fs";
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 existsSync12, readFileSync as readFileSync7 } from "fs";
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, rm as rm3, writeFile as writeFile4 } from "fs/promises";
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
- async function readOptionalFile2(filePath) {
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
- const raw = await readFile5(filePath, "utf8");
11784
- const trimmed = raw.trim();
11785
- return trimmed || null;
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
- sessionStatePath;
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.sessionStatePath = join12(options.runtimeDirectory, "claude-session-id.txt");
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 rm3(this.sessionStatePath, { force: true });
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
- this.claudeSessionId = await readOptionalFile2(this.sessionStatePath);
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
- writeFile4(this.sessionStatePath, `${nextSessionId}
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 rm3(join12(options.runtimeDirectory, "claude-session-id.txt"), { force: true });
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 readOptionalFile3(filePath) {
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 readOptionalFile3(this.threadIdPath);
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 existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
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 existsSync11(join14(candidate, "package.json")) && existsSync11(join14(candidate, "bin", "openscout-runtime.mjs"));
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 (existsSync11(join14(candidate, "package.json")) && existsSync11(join14(candidate, "src"))) {
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") && existsSync11(process.execPath)) {
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 (existsSync11(candidate)) {
13052
+ if (existsSync12(candidate)) {
12991
13053
  return candidate;
12992
13054
  }
12993
13055
  }
12994
13056
  const homeBun = join14(homedir13(), ".bun", "bin", "bun");
12995
- if (existsSync11(homeBun)) {
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 (!existsSync11(path2)) {
13247
+ if (!existsSync12(path2)) {
13186
13248
  return [];
13187
13249
  }
13188
- return readFileSync6(path2, "utf8").split(`
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 = existsSync11(config.launchAgentPath);
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 (existsSync11(config.launchAgentPath)) {
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 (!existsSync12(supportPaths.settingsPath)) {
13492
+ if (!existsSync13(supportPaths.settingsPath)) {
13431
13493
  return dirname6(projectPath);
13432
13494
  }
13433
- const raw = JSON.parse(readFileSync7(supportPaths.settingsPath, "utf8"));
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 `node ${JSON.stringify(join15(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs"))}`;
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 (existsSync12(path2)) {
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 = existsSync12(stderrLogFile) ? readFileSync7(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
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: existsSync13 } = await import("fs");
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 (existsSync13(worktreePath)) {
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 = readFileSync8(p.path, "utf-8");
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 readFileSync9 } from "fs";
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 = readFileSync9(path2, "utf8");
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 readFileSync10, readdirSync as readdirSync4, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
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 = readFileSync10(input.path, "utf-8");
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;