@agentproto/runtime 3.4.0 → 3.6.1
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/dist/catalog-models.d.ts +1 -1
- package/dist/catalog-models.mjs.map +1 -1
- package/dist/config.d.ts +24 -2
- package/dist/config.mjs.map +1 -1
- package/dist/index.d.ts +45 -6
- package/dist/index.mjs +868 -269
- package/dist/index.mjs.map +1 -1
- package/dist/resume-strategies.d.ts +33 -4
- package/dist/resume-strategies.mjs +38 -9
- package/dist/resume-strategies.mjs.map +1 -1
- package/dist/session-presence.mjs.map +1 -1
- package/dist/{spawn-defaults-D4W661ui.d.ts → spawn-defaults-CwI9Puwy.d.ts} +8 -0
- package/package.json +11 -11
|
@@ -78,6 +78,10 @@ interface ResumeStrategy {
|
|
|
78
78
|
* why this exists and what silently omitting it breaks. Undefined for
|
|
79
79
|
* a provider with no config-dir-isolated store. */
|
|
80
80
|
configDirEnvVar?: string;
|
|
81
|
+
/** Absolute transcript path for a conversation id — see
|
|
82
|
+
* `ConversationStore.transcriptPath`. Present only when the provider's
|
|
83
|
+
* resume command also accepts a path in place of a bare id. */
|
|
84
|
+
transcriptPath?(cwd: string, conversationId: string, configDir?: string): string;
|
|
81
85
|
}
|
|
82
86
|
declare const RESUME_STRATEGIES: Record<string, ResumeStrategy>;
|
|
83
87
|
/**
|
|
@@ -101,9 +105,10 @@ interface RestartCandidate {
|
|
|
101
105
|
resumable?: boolean;
|
|
102
106
|
/**
|
|
103
107
|
* Manifest-declared `capabilities.nativeTerminalResume` for `adapterSlug`.
|
|
104
|
-
* The `pty-native`
|
|
105
|
-
*
|
|
106
|
-
*
|
|
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.
|
|
107
112
|
*/
|
|
108
113
|
nativeTerminalResume?: boolean;
|
|
109
114
|
}
|
|
@@ -197,6 +202,30 @@ declare const RESUME_ID_REJECTED_RE: RegExp;
|
|
|
197
202
|
* "not found", triggering the fresh-spawn fallback + digest injection.
|
|
198
203
|
*/
|
|
199
204
|
declare function augmentWithFsResume<T extends FsProbeCandidate>(prev: T): Promise<T>;
|
|
205
|
+
/** What `probeNativeTranscript` found for a candidate's own transcript. */
|
|
206
|
+
interface NativeTranscriptProbe {
|
|
207
|
+
/** Directory that was (or would be) probed for the transcript. */
|
|
208
|
+
dir: string;
|
|
209
|
+
/** Absolute path of the transcript file the id maps to. */
|
|
210
|
+
path: string;
|
|
211
|
+
/** Whether that exact file exists on disk right now. */
|
|
212
|
+
exists: boolean;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Locate the candidate's own on-disk transcript for a provider whose native
|
|
216
|
+
* resume command accepts an absolute path (`ResumeStrategy.transcriptPath`).
|
|
217
|
+
* Returns `undefined` when the adapter declares no `transcriptPath`, or the
|
|
218
|
+
* candidate has no cwd / no conversation id to map — callers treat that as
|
|
219
|
+
* "nothing to upgrade, and no directory worth naming in diagnostics".
|
|
220
|
+
*
|
|
221
|
+
* The id lookup mirrors `decideRestartStrategy`'s (`resumeMetadata[storeAs]`),
|
|
222
|
+
* falling back to `adapterSessionId` (for claude-code the ACP session id IS
|
|
223
|
+
* the on-disk `.jsonl` uuid — acp-host.ts pins them equal) so a probe can
|
|
224
|
+
* still name the transcript it looked for when the sniffer never fired.
|
|
225
|
+
* `exists: false` is the honest "transcript not found" answer — never fall
|
|
226
|
+
* through to a sibling file (cross-session contamination, see fsProbe's doc).
|
|
227
|
+
*/
|
|
228
|
+
declare function probeNativeTranscript(prev: FsProbeCandidate): Promise<NativeTranscriptProbe | undefined>;
|
|
200
229
|
/**
|
|
201
230
|
* Describe which resume path a restart used, for CLI banners / MCP
|
|
202
231
|
* responses. Returns a short phrase like "resumed via claude --resume",
|
|
@@ -226,4 +255,4 @@ declare function describeResumePath(prev: RestartCandidate, opts?: DecideRestart
|
|
|
226
255
|
*/
|
|
227
256
|
declare function tokenizeCommand(s: string): string[];
|
|
228
257
|
|
|
229
|
-
export { type DecideRestartStrategyOptions, type FsProbeCandidate, RESUME_ID_REJECTED_RE, RESUME_STRATEGIES, type RestartCandidate, type RestartStrategy, type ResumeMetadataKey, type ResumeStrategy, augmentWithFsResume, decideRestartStrategy, describeResumePath, hasResumeStrategy, tokenizeCommand };
|
|
258
|
+
export { type DecideRestartStrategyOptions, type FsProbeCandidate, type NativeTranscriptProbe, RESUME_ID_REJECTED_RE, RESUME_STRATEGIES, type RestartCandidate, type RestartStrategy, type ResumeMetadataKey, type ResumeStrategy, augmentWithFsResume, decideRestartStrategy, describeResumePath, hasResumeStrategy, probeNativeTranscript, tokenizeCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { join, resolve } from 'path';
|
|
1
|
+
import { join, resolve, dirname } from 'path';
|
|
2
2
|
import { createReadStream, promises } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { createInterface } from 'readline';
|
|
@@ -1063,8 +1063,8 @@ async function discoverOpenCodeSessions(cwd, since, expectedId) {
|
|
|
1063
1063
|
const sinceMs = since ? Date.parse(since) : NaN;
|
|
1064
1064
|
return rows.filter((r) => {
|
|
1065
1065
|
if (!Number.isFinite(sinceMs)) return true;
|
|
1066
|
-
|
|
1067
|
-
return
|
|
1066
|
+
if (r.time_created === void 0) return false;
|
|
1067
|
+
return r.time_created >= sinceMs - 1e3;
|
|
1068
1068
|
}).map(openCodeRowToCandidate);
|
|
1069
1069
|
} finally {
|
|
1070
1070
|
db.close();
|
|
@@ -1495,6 +1495,9 @@ function extractFirstText(content) {
|
|
|
1495
1495
|
}
|
|
1496
1496
|
return void 0;
|
|
1497
1497
|
}
|
|
1498
|
+
function isClaudeControlText(text) {
|
|
1499
|
+
return /^<(?:local-command-caveat|local-command-stdout|command-name|task-notification)>/i.test(text);
|
|
1500
|
+
}
|
|
1498
1501
|
async function scanClaudeJsonl(filePath) {
|
|
1499
1502
|
const stream = createReadStream(filePath, { encoding: "utf8" });
|
|
1500
1503
|
const rl = createInterface({ input: stream, crlfDelay: Infinity });
|
|
@@ -1523,7 +1526,7 @@ async function scanClaudeJsonl(filePath) {
|
|
|
1523
1526
|
messageCount += 1;
|
|
1524
1527
|
if (preview === void 0 && entry.type === "user") {
|
|
1525
1528
|
const text = extractFirstText(entry.message?.content);
|
|
1526
|
-
if (text !== void 0) {
|
|
1529
|
+
if (text !== void 0 && !isClaudeControlText(text)) {
|
|
1527
1530
|
preview = text.length > 120 ? text.slice(0, 120) : text;
|
|
1528
1531
|
}
|
|
1529
1532
|
}
|
|
@@ -1639,6 +1642,7 @@ var init_conversation_store = __esm({
|
|
|
1639
1642
|
// (default). Example: `claude --resume 0e483f81-1a44-4bec-9667-b37158450296`
|
|
1640
1643
|
outputHint: /claude\s+--resume\s+([0-9a-f-]{8,})/i,
|
|
1641
1644
|
attachArgv: (conversationId) => ["claude", "--resume", conversationId],
|
|
1645
|
+
transcriptPath: (cwd, conversationId, configDir) => join(claudeCodeProjectDir(cwd, configDir), `${conversationId}.jsonl`),
|
|
1642
1646
|
configDirEnvVar: "CLAUDE_CONFIG_DIR",
|
|
1643
1647
|
discover: discoverClaudeCode,
|
|
1644
1648
|
read: readClaudeCode
|
|
@@ -1663,6 +1667,9 @@ var init_conversation_store = __esm({
|
|
|
1663
1667
|
},
|
|
1664
1668
|
opencode: {
|
|
1665
1669
|
storeAs: "openCodeResumeId",
|
|
1670
|
+
// Match the adapter's portable npx installation: a direct `opencode`
|
|
1671
|
+
// binary is not guaranteed to be on the daemon's PATH on every host.
|
|
1672
|
+
attachArgv: (conversationId) => ["npx", "-y", "opencode-ai", "-s", conversationId],
|
|
1666
1673
|
discover: discoverOpenCode,
|
|
1667
1674
|
read: readOpenCode
|
|
1668
1675
|
},
|
|
@@ -1677,6 +1684,9 @@ var init_conversation_store = __esm({
|
|
|
1677
1684
|
read: readPi
|
|
1678
1685
|
}
|
|
1679
1686
|
};
|
|
1687
|
+
new Set(
|
|
1688
|
+
Object.values(CONVERSATION_STORES).map((s) => s.storeAs)
|
|
1689
|
+
);
|
|
1680
1690
|
}
|
|
1681
1691
|
});
|
|
1682
1692
|
|
|
@@ -1691,6 +1701,7 @@ var RESUME_STRATEGIES = Object.fromEntries(
|
|
|
1691
1701
|
outputHint: store.outputHint,
|
|
1692
1702
|
storeAs: store.storeAs,
|
|
1693
1703
|
...store.configDirEnvVar ? { configDirEnvVar: store.configDirEnvVar } : {},
|
|
1704
|
+
...store.transcriptPath ? { transcriptPath: store.transcriptPath } : {},
|
|
1694
1705
|
fsProbe: async (cwd, prevStartedAt, expectedId, configDir) => {
|
|
1695
1706
|
const candidates = await s.discover({
|
|
1696
1707
|
cwd,
|
|
@@ -1712,7 +1723,8 @@ function hasResumeStrategy(adapterSlug) {
|
|
|
1712
1723
|
}
|
|
1713
1724
|
function decideRestartStrategy(prev, opts = {}) {
|
|
1714
1725
|
const mayPreferNative = prev.pty === true || opts.preferNativeTerminal === true;
|
|
1715
|
-
|
|
1726
|
+
const hasNativeCapability = prev.nativeTerminalResume === true || prev.pty === true && prev.nativeTerminalResume === void 0;
|
|
1727
|
+
if (prev.adapterSlug && hasNativeCapability && mayPreferNative) {
|
|
1716
1728
|
const strategy = RESUME_STRATEGIES[prev.adapterSlug];
|
|
1717
1729
|
const id = strategy?.storeAs ? prev.resumeMetadata?.[strategy.storeAs] : void 0;
|
|
1718
1730
|
if (strategy?.spawnArgs && id) {
|
|
@@ -1767,13 +1779,30 @@ async function augmentWithFsResume(prev) {
|
|
|
1767
1779
|
}
|
|
1768
1780
|
};
|
|
1769
1781
|
}
|
|
1782
|
+
async function probeNativeTranscript(prev) {
|
|
1783
|
+
if (!prev.adapterSlug || !prev.cwd) return void 0;
|
|
1784
|
+
const strategy = RESUME_STRATEGIES[prev.adapterSlug];
|
|
1785
|
+
if (!strategy?.transcriptPath) return void 0;
|
|
1786
|
+
const id = prev.resumeMetadata?.[strategy.storeAs] ?? prev.adapterSessionId;
|
|
1787
|
+
if (!id) return void 0;
|
|
1788
|
+
const path = strategy.transcriptPath(prev.cwd, id, prev.adapterConfigDir);
|
|
1789
|
+
let exists = false;
|
|
1790
|
+
try {
|
|
1791
|
+
exists = (await promises.stat(path)).isFile();
|
|
1792
|
+
} catch {
|
|
1793
|
+
exists = false;
|
|
1794
|
+
}
|
|
1795
|
+
return { dir: dirname(path), path, exists };
|
|
1796
|
+
}
|
|
1770
1797
|
function describeResumePath(prev, opts = {}) {
|
|
1771
1798
|
const mayPreferNative = prev.pty === true || opts.preferNativeTerminal === true;
|
|
1772
|
-
|
|
1799
|
+
const hasNativeCapability = prev.nativeTerminalResume === true || prev.pty === true && prev.nativeTerminalResume === void 0;
|
|
1800
|
+
if (prev.adapterSlug && hasNativeCapability && mayPreferNative) {
|
|
1773
1801
|
const s = RESUME_STRATEGIES[prev.adapterSlug];
|
|
1774
1802
|
if (s?.spawnArgs && s.storeAs && prev.resumeMetadata?.[s.storeAs]) {
|
|
1775
|
-
const sample = s.spawnArgs("\u2026")
|
|
1776
|
-
|
|
1803
|
+
const sample = s.spawnArgs("\u2026");
|
|
1804
|
+
const idIndex = sample.indexOf("\u2026");
|
|
1805
|
+
return `resumed via ${idIndex > 0 ? sample.slice(0, idIndex).join(" ") : sample[0] ?? prev.adapterSlug}`;
|
|
1777
1806
|
}
|
|
1778
1807
|
}
|
|
1779
1808
|
if (prev.adapterSlug && prev.adapterSessionId) {
|
|
@@ -1812,6 +1841,6 @@ function tokenizeCommand(s) {
|
|
|
1812
1841
|
return out;
|
|
1813
1842
|
}
|
|
1814
1843
|
|
|
1815
|
-
export { RESUME_ID_REJECTED_RE, RESUME_STRATEGIES, augmentWithFsResume, decideRestartStrategy, describeResumePath, hasResumeStrategy, tokenizeCommand };
|
|
1844
|
+
export { RESUME_ID_REJECTED_RE, RESUME_STRATEGIES, augmentWithFsResume, decideRestartStrategy, describeResumePath, hasResumeStrategy, probeNativeTranscript, tokenizeCommand };
|
|
1816
1845
|
//# sourceMappingURL=resume-strategies.mjs.map
|
|
1817
1846
|
//# sourceMappingURL=resume-strategies.mjs.map
|