@agentproto/runtime 3.5.0 → 4.0.0

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.
@@ -17,6 +17,7 @@
17
17
  * - ~/.cursor/mcp.json (cursor) — flat `mcpServers` map.
18
18
  * - ~/.config/goose/config.yaml (goose) — TOML/YAML hybrid; we
19
19
  * only handle the YAML form for now.
20
+ * - ~/.codex/config.toml (codex) — `[mcp_servers.<name>]` tables.
20
21
  * - any `.mcp.json` under the user's home that follows the
21
22
  * standard mcpServers shape.
22
23
  *
@@ -29,7 +30,7 @@ interface DiscoveredMcp {
29
30
  * cross-call identity (UI treat as React key). */
30
31
  id: string;
31
32
  /** Where we found it. Lets the UI render a source badge. */
32
- source: "claude-code" | "cursor" | "goose" | "workspace";
33
+ source: "claude-code" | "cursor" | "goose" | "codex" | "workspace";
33
34
  /** "global" when the entry sits at the top level of the host's
34
35
  * config; "project:<path>" when it's scoped to a single
35
36
  * workspace. claude-code in particular nests per-project. */
@@ -105,9 +105,10 @@ interface RestartCandidate {
105
105
  resumable?: boolean;
106
106
  /**
107
107
  * Manifest-declared `capabilities.nativeTerminalResume` for `adapterSlug`.
108
- * The `pty-native` restart strategy is only chosen when this flag is true
109
- * AND a native resume id is available. ACP resumability (`resumable`)
110
- * alone does NOT imply a native TUI resume is safe or available.
108
+ * The `pty-native` strategy requires this flag for ACP-origin sessions.
109
+ * Legacy PTY rows without the flag can use a newly-added store strategy
110
+ * when they already carry an exact native resume id; explicit false blocks
111
+ * that fallback. ACP resumability (`resumable`) does not imply a TUI resume.
111
112
  */
112
113
  nativeTerminalResume?: boolean;
113
114
  }
@@ -188,7 +188,7 @@ function renderMarkdown(session, opts = {}) {
188
188
  out.push("");
189
189
  for (const m of messages) {
190
190
  const icon = ROLE_ICON[m.role] ?? m.role;
191
- const nameSuffix = m.toolName ? ` \xB7 \`${m.toolName}\`` : "";
191
+ const nameSuffix = m.toolName ? ` \xB7 \`${m.toolName}\`` : m.from ? ` \xB7 from ${m.from.relation} \`${m.from.label ?? m.from.sessionId ?? ""}\` (${m.from.kind})` : "";
192
192
  out.push(`### ${icon}${nameSuffix}`);
193
193
  if (m.reasoning?.trim()) {
194
194
  out.push("");
@@ -652,6 +652,25 @@ ${rec.stderr}`);
652
652
  flushAssistant();
653
653
  messages.push({ role: "user", text: rec.text ?? "", ...tsOrUndefined !== void 0 ? { ts: tsOrUndefined } : {} });
654
654
  break;
655
+ case "session-message": {
656
+ flushAssistant();
657
+ const m = rec.message;
658
+ if (!m) break;
659
+ const relation = m.from?.relation ?? "system";
660
+ messages.push({
661
+ role: "user",
662
+ text: m.text ?? "",
663
+ from: {
664
+ ...m.from?.sessionId ? { sessionId: m.from.sessionId } : {},
665
+ ...m.from?.label ? { label: m.from.label } : {},
666
+ relation,
667
+ kind: m.kind ?? "report",
668
+ messageId: m.id
669
+ },
670
+ ...tsOrUndefined !== void 0 ? { ts: tsOrUndefined } : {}
671
+ });
672
+ break;
673
+ }
655
674
  case "system-prompt":
656
675
  flushAssistant();
657
676
  messages.push({ role: "system", text: rec.text ?? "", ...tsOrUndefined !== void 0 ? { ts: tsOrUndefined } : {} });
@@ -1063,8 +1082,8 @@ async function discoverOpenCodeSessions(cwd, since, expectedId) {
1063
1082
  const sinceMs = since ? Date.parse(since) : NaN;
1064
1083
  return rows.filter((r) => {
1065
1084
  if (!Number.isFinite(sinceMs)) return true;
1066
- const last = r.time_updated ?? r.time_created;
1067
- return last === void 0 || last >= sinceMs - 1e3;
1085
+ if (r.time_created === void 0) return false;
1086
+ return r.time_created >= sinceMs - 1e3;
1068
1087
  }).map(openCodeRowToCandidate);
1069
1088
  } finally {
1070
1089
  db.close();
@@ -1495,6 +1514,9 @@ function extractFirstText(content) {
1495
1514
  }
1496
1515
  return void 0;
1497
1516
  }
1517
+ function isClaudeControlText(text) {
1518
+ return /^<(?:local-command-caveat|local-command-stdout|command-name|task-notification)>/i.test(text);
1519
+ }
1498
1520
  async function scanClaudeJsonl(filePath) {
1499
1521
  const stream = createReadStream(filePath, { encoding: "utf8" });
1500
1522
  const rl = createInterface({ input: stream, crlfDelay: Infinity });
@@ -1523,7 +1545,7 @@ async function scanClaudeJsonl(filePath) {
1523
1545
  messageCount += 1;
1524
1546
  if (preview === void 0 && entry.type === "user") {
1525
1547
  const text = extractFirstText(entry.message?.content);
1526
- if (text !== void 0) {
1548
+ if (text !== void 0 && !isClaudeControlText(text)) {
1527
1549
  preview = text.length > 120 ? text.slice(0, 120) : text;
1528
1550
  }
1529
1551
  }
@@ -1664,6 +1686,9 @@ var init_conversation_store = __esm({
1664
1686
  },
1665
1687
  opencode: {
1666
1688
  storeAs: "openCodeResumeId",
1689
+ // Match the adapter's portable npx installation: a direct `opencode`
1690
+ // binary is not guaranteed to be on the daemon's PATH on every host.
1691
+ attachArgv: (conversationId) => ["npx", "-y", "opencode-ai", "-s", conversationId],
1667
1692
  discover: discoverOpenCode,
1668
1693
  read: readOpenCode
1669
1694
  },
@@ -1717,7 +1742,8 @@ function hasResumeStrategy(adapterSlug) {
1717
1742
  }
1718
1743
  function decideRestartStrategy(prev, opts = {}) {
1719
1744
  const mayPreferNative = prev.pty === true || opts.preferNativeTerminal === true;
1720
- if (prev.adapterSlug && prev.nativeTerminalResume === true && mayPreferNative) {
1745
+ const hasNativeCapability = prev.nativeTerminalResume === true || prev.pty === true && prev.nativeTerminalResume === void 0;
1746
+ if (prev.adapterSlug && hasNativeCapability && mayPreferNative) {
1721
1747
  const strategy = RESUME_STRATEGIES[prev.adapterSlug];
1722
1748
  const id = strategy?.storeAs ? prev.resumeMetadata?.[strategy.storeAs] : void 0;
1723
1749
  if (strategy?.spawnArgs && id) {
@@ -1789,11 +1815,13 @@ async function probeNativeTranscript(prev) {
1789
1815
  }
1790
1816
  function describeResumePath(prev, opts = {}) {
1791
1817
  const mayPreferNative = prev.pty === true || opts.preferNativeTerminal === true;
1792
- if (prev.adapterSlug && mayPreferNative) {
1818
+ const hasNativeCapability = prev.nativeTerminalResume === true || prev.pty === true && prev.nativeTerminalResume === void 0;
1819
+ if (prev.adapterSlug && hasNativeCapability && mayPreferNative) {
1793
1820
  const s = RESUME_STRATEGIES[prev.adapterSlug];
1794
1821
  if (s?.spawnArgs && s.storeAs && prev.resumeMetadata?.[s.storeAs]) {
1795
- const sample = s.spawnArgs("\u2026")[0] ?? prev.adapterSlug;
1796
- return `resumed via ${sample} --resume`;
1822
+ const sample = s.spawnArgs("\u2026");
1823
+ const idIndex = sample.indexOf("\u2026");
1824
+ return `resumed via ${idIndex > 0 ? sample.slice(0, idIndex).join(" ") : sample[0] ?? prev.adapterSlug}`;
1797
1825
  }
1798
1826
  }
1799
1827
  if (prev.adapterSlug && prev.adapterSessionId) {