@termfleet/core 0.2.0 → 0.2.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/agent-session.d.ts +15 -0
- package/dist/agent-session.js +53 -0
- package/package.json +1 -1
package/dist/agent-session.d.ts
CHANGED
|
@@ -302,6 +302,21 @@ export declare function resolveClaudeTranscriptPath(options: {
|
|
|
302
302
|
home?: string;
|
|
303
303
|
sessionId: string;
|
|
304
304
|
}): string | undefined;
|
|
305
|
+
export declare function findLocalClaudeSession(sessionId: string, options?: {
|
|
306
|
+
home?: string;
|
|
307
|
+
}): {
|
|
308
|
+
sessionId: string;
|
|
309
|
+
cwd: string | undefined;
|
|
310
|
+
transcriptPath: string;
|
|
311
|
+
} | undefined;
|
|
312
|
+
export declare function findLocalAgentSession(agentSessionId: string, options?: {
|
|
313
|
+
home?: string;
|
|
314
|
+
}): {
|
|
315
|
+
agent: "claude" | "codex" | "gemini";
|
|
316
|
+
sessionId: string;
|
|
317
|
+
cwd: string | undefined;
|
|
318
|
+
transcriptPath: string;
|
|
319
|
+
} | undefined;
|
|
305
320
|
export declare function emptyClaudeSession(options: {
|
|
306
321
|
cwd: string;
|
|
307
322
|
home?: string;
|
package/dist/agent-session.js
CHANGED
|
@@ -74,6 +74,59 @@ export function resolveClaudeTranscriptPath(options) {
|
|
|
74
74
|
const found = findClaudeTranscriptById(join(options.home ?? agentHome(), ".claude", "projects"), assertSafeAgentSessionId(normalizeClaudeSessionId(options.sessionId)));
|
|
75
75
|
return existsSync(found) ? found : undefined;
|
|
76
76
|
}
|
|
77
|
+
// Read the working dir a Claude session ran in, straight from its transcript. The `cwd` is on the message
|
|
78
|
+
// records, not always the first header line, so scan a bounded prefix (headers are small). undefined if absent.
|
|
79
|
+
function readClaudeSessionCwd(transcriptPath, maxBytes = 65_536) {
|
|
80
|
+
let head;
|
|
81
|
+
try {
|
|
82
|
+
const fd = openSync(transcriptPath, "r");
|
|
83
|
+
try {
|
|
84
|
+
const buffer = Buffer.alloc(maxBytes);
|
|
85
|
+
const bytesRead = readSync(fd, buffer, 0, maxBytes, 0);
|
|
86
|
+
head = buffer.toString("utf8", 0, bytesRead);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
closeSync(fd);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
for (const line of head.split("\n")) {
|
|
96
|
+
if (!line)
|
|
97
|
+
continue;
|
|
98
|
+
try {
|
|
99
|
+
const row = JSON.parse(line);
|
|
100
|
+
if (typeof row.cwd === "string" && row.cwd)
|
|
101
|
+
return row.cwd;
|
|
102
|
+
}
|
|
103
|
+
catch { /* a truncated final line in the bounded read — ignore */ }
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
// Resolve a Claude session from its id ALONE (no cwd needed): find its transcript across every project dir and
|
|
108
|
+
// read the session's cwd from it. Local + provider-free — the primitive any tool needs when it has a session
|
|
109
|
+
// id but not its working dir (a session mirror, a resumer, a cross-project browser). undefined when the
|
|
110
|
+
// transcript doesn't exist yet (a just-launched session writes it only once it produces messages).
|
|
111
|
+
export function findLocalClaudeSession(sessionId, options = {}) {
|
|
112
|
+
const bareId = assertSafeAgentSessionId(normalizeClaudeSessionId(sessionId));
|
|
113
|
+
const transcriptPath = findClaudeTranscriptById(join(options.home ?? agentHome(), ".claude", "projects"), bareId);
|
|
114
|
+
if (!existsSync(transcriptPath))
|
|
115
|
+
return undefined;
|
|
116
|
+
return { sessionId: bareId, cwd: readClaudeSessionCwd(transcriptPath), transcriptPath };
|
|
117
|
+
}
|
|
118
|
+
// The agent-generic form: resolve a (prefixed or bare) agentSessionId → its provider, cwd, and transcript
|
|
119
|
+
// path, locally. A bare id is treated as Claude. (Codex/Gemini keep transcripts elsewhere; extend here when
|
|
120
|
+
// needed — non-Claude returns undefined for now.)
|
|
121
|
+
export function findLocalAgentSession(agentSessionId, options = {}) {
|
|
122
|
+
const separator = agentSessionId.indexOf(":");
|
|
123
|
+
const prefix = separator > 0 ? agentSessionId.slice(0, separator) : "";
|
|
124
|
+
const agent = prefix === "codex" ? "codex" : prefix === "gemini" ? "gemini" : "claude";
|
|
125
|
+
if (agent !== "claude")
|
|
126
|
+
return undefined;
|
|
127
|
+
const resolved = findLocalClaudeSession(agentSessionId, options);
|
|
128
|
+
return resolved ? { agent, ...resolved } : undefined;
|
|
129
|
+
}
|
|
77
130
|
// A real, openable chat for a session that has no transcript yet — just an empty
|
|
78
131
|
// conversation. Parsing empty JSONL yields a well-formed session with zero
|
|
79
132
|
// messages, so a just-launched agent displays as an empty chat instead of 500ing.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@termfleet/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Termfleet core: contracts, the provider SDK, and the agent-transcript/session library (Claude Code / Codex / Gemini). The reusable layer, usable beyond the console.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|