@heyditto/cli 2.17.0 → 2.19.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.
- package/README.md +3 -2
- package/dist/agents/claude-resume.d.ts +32 -0
- package/dist/agents/claude-resume.js +152 -0
- package/dist/agents/claude-resume.js.map +1 -0
- package/dist/agents/claude-transcripts.d.ts +52 -0
- package/dist/agents/claude-transcripts.js +237 -0
- package/dist/agents/claude-transcripts.js.map +1 -0
- package/dist/agents/claude.d.ts +11 -0
- package/dist/agents/claude.js +35 -1
- package/dist/agents/claude.js.map +1 -1
- package/dist/agents/launch.js +78 -12
- package/dist/agents/launch.js.map +1 -1
- package/dist/agents/sessions.d.ts +4 -0
- package/dist/agents/sessions.js +11 -1
- package/dist/agents/sessions.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +1 -0
- package/dist/commands.js +31 -3
- package/dist/commands.js.map +1 -1
- package/dist/review-commands.d.ts +57 -0
- package/dist/review-commands.js +150 -0
- package/dist/review-commands.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -410,7 +410,8 @@ heyditto codex --yellow # Codex, auto-accept edits
|
|
|
410
410
|
heyditto claude --yolo --worktree fix-login # bypass prompts in <repo>/.worktrees/fix-login
|
|
411
411
|
heyditto codex -p "summarize this repo" --json # headless (codex exec)
|
|
412
412
|
heyditto claude -p "list TODOs" --output-format json --max-turns 3
|
|
413
|
-
heyditto claude --resume #
|
|
413
|
+
heyditto claude --resume # pick a session (type words to search every project)
|
|
414
|
+
heyditto claude --resume "Fix login bug" # resume by title, as `claude --resume` prints it
|
|
414
415
|
heyditto claude -- --verbose # anything after -- goes to the agent
|
|
415
416
|
```
|
|
416
417
|
|
|
@@ -422,7 +423,7 @@ Options shared by both commands:
|
|
|
422
423
|
| `--budget <tokens>` | spend cap for this session's key, in Ditto tokens |
|
|
423
424
|
| `--expires <1h…never>` | server-side key expiry; the key is still revoked on exit unless `--keep-key` |
|
|
424
425
|
| `--session <id>` | reuse a Ditto session id so traces land in an existing thread |
|
|
425
|
-
| `--resume [id]` / `-c, --continue` | resume a local session (`heyditto sessions`) / the agent's most recent conversation |
|
|
426
|
+
| `--resume [id]` / `-c, --continue` | resume a local session (`heyditto sessions`) / the agent's most recent conversation. Claude also takes a Claude session id or title here, including sessions started in Claude Desktop or plain `claude`, and runs in the directory that session ran in; with no value, a terminal gets a searchable picker. Claude's own `-r` / `--resume` / `-c` after `--` do the same. |
|
|
426
427
|
| `--yolo` / `--yellow` / `--plan` | bypass permissions / auto-accept edits / plan mode (Claude only) |
|
|
427
428
|
| `-p, --prompt <text>` | headless run: `claude -p` or `codex exec` |
|
|
428
429
|
| `-m, --model <id>` | model to request (default: the agent's own model id passes through and the endpoint routes it) |
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ClaudeTranscript } from "./claude-transcripts.js";
|
|
2
|
+
import { type SessionRecord } from "./sessions.js";
|
|
3
|
+
/**
|
|
4
|
+
* What `heyditto claude --resume [value]` reopens: the Claude conversation to
|
|
5
|
+
* resume (if it has one) and the Ditto record whose thread it continues (if it
|
|
6
|
+
* was launched through Ditto before).
|
|
7
|
+
*/
|
|
8
|
+
export interface ClaudeResumeTarget {
|
|
9
|
+
record?: SessionRecord;
|
|
10
|
+
/** Undefined when the session never recorded a conversation (nothing was sent). */
|
|
11
|
+
transcript?: ClaudeTranscript;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolveOptions {
|
|
14
|
+
cwd: string;
|
|
15
|
+
interactive: boolean;
|
|
16
|
+
log: (message: string) => void;
|
|
17
|
+
}
|
|
18
|
+
/** The directory `claude --resume` must run in to find a transcript, when it still exists. */
|
|
19
|
+
export declare function transcriptCwd(t: ClaudeTranscript): Promise<string | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* Numbered picker over Claude Code sessions. A number picks, Enter picks the
|
|
22
|
+
* first, and anything else is a search across every project (Claude Desktop
|
|
23
|
+
* sessions included), so "I remember what it was about" is enough to find one.
|
|
24
|
+
*/
|
|
25
|
+
export declare function pickTranscript(initial: ClaudeTranscript[], heading: string, cwd: string): Promise<ClaudeTranscript>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves `--resume [value]` for Claude Code. A value may be a Ditto session
|
|
28
|
+
* id, a Claude session id, or a title / words from one (what `claude --resume`
|
|
29
|
+
* prints for a renamed session). With no value an interactive terminal gets a
|
|
30
|
+
* picker; a script gets the most recent session, as before.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveClaudeResume(value: string | true, opts: ResolveOptions): Promise<ClaudeResumeTarget>;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { createInterface } from "node:readline/promises";
|
|
4
|
+
import { canonicalCwd } from "../teleport/harness.js";
|
|
5
|
+
import { err as c } from "../ui.js";
|
|
6
|
+
import { entrypointLabel, findTranscriptById, listAllTranscripts, listTranscriptsIn, relativeTime, searchTranscripts, } from "./claude-transcripts.js";
|
|
7
|
+
import { latestSession, listSessions, readSession, sessionForHarnessId } from "./sessions.js";
|
|
8
|
+
const PAGE = 10;
|
|
9
|
+
async function isDirectory(dir) {
|
|
10
|
+
try {
|
|
11
|
+
return (await stat(dir)).isDirectory();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** The directory `claude --resume` must run in to find a transcript, when it still exists. */
|
|
18
|
+
export async function transcriptCwd(t) {
|
|
19
|
+
return t.cwd && (await isDirectory(t.cwd)) ? t.cwd : undefined;
|
|
20
|
+
}
|
|
21
|
+
function tildify(dir) {
|
|
22
|
+
const home = os.homedir();
|
|
23
|
+
return dir === home || dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir;
|
|
24
|
+
}
|
|
25
|
+
function clip(text, width) {
|
|
26
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
27
|
+
return flat.length > width ? `${flat.slice(0, Math.max(1, width - 1))}…` : flat;
|
|
28
|
+
}
|
|
29
|
+
function describe(t) {
|
|
30
|
+
return t.title ?? (t.lastPrompt ? clip(t.lastPrompt, 60) : "(untitled)");
|
|
31
|
+
}
|
|
32
|
+
function printChoices(list, here, viaDitto) {
|
|
33
|
+
const width = Math.max(40, (process.stderr.columns ?? 100) - 8);
|
|
34
|
+
list.slice(0, PAGE).forEach((t, i) => {
|
|
35
|
+
const meta = [
|
|
36
|
+
relativeTime(t.modifiedAt),
|
|
37
|
+
entrypointLabel(t.entrypoint),
|
|
38
|
+
t.gitBranch,
|
|
39
|
+
viaDitto.has(t.id) ? "via Ditto" : undefined,
|
|
40
|
+
].filter(Boolean).join(" · ");
|
|
41
|
+
process.stderr.write(` ${c("cyan", `${String(i + 1).padStart(2)})`)} ${c("bold", clip(describe(t), width - meta.length - 3))} ${c("dim", meta)}\n`);
|
|
42
|
+
const where = t.cwd && t.cwd !== here ? `${tildify(t.cwd)} ` : "";
|
|
43
|
+
const prompt = t.title && t.lastPrompt ? `› ${t.lastPrompt}` : "";
|
|
44
|
+
const detail = `${where}${prompt}`.trim();
|
|
45
|
+
if (detail)
|
|
46
|
+
process.stderr.write(` ${c("dim", clip(detail, width))}\n`);
|
|
47
|
+
});
|
|
48
|
+
if (list.length > PAGE)
|
|
49
|
+
process.stderr.write(c("dim", ` …and ${list.length - PAGE} more; type words to narrow\n`));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Numbered picker over Claude Code sessions. A number picks, Enter picks the
|
|
53
|
+
* first, and anything else is a search across every project (Claude Desktop
|
|
54
|
+
* sessions included), so "I remember what it was about" is enough to find one.
|
|
55
|
+
*/
|
|
56
|
+
export async function pickTranscript(initial, heading, cwd) {
|
|
57
|
+
const here = canonicalCwd(cwd);
|
|
58
|
+
const viaDitto = new Set((await listSessions()).map((s) => s.harnessSessionId).filter((id) => Boolean(id)));
|
|
59
|
+
let all;
|
|
60
|
+
let list = initial;
|
|
61
|
+
process.stderr.write(`${c("bold", heading)}\n\n`);
|
|
62
|
+
if (list.length === 0) {
|
|
63
|
+
all = await listAllTranscripts();
|
|
64
|
+
list = all;
|
|
65
|
+
process.stderr.write(` ${c("dim", "none here yet — newest from every project:")}\n`);
|
|
66
|
+
}
|
|
67
|
+
printChoices(list, here, viaDitto);
|
|
68
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
69
|
+
try {
|
|
70
|
+
for (;;) {
|
|
71
|
+
const range = list.length ? `a number 1-${Math.min(list.length, PAGE)}, ` : "";
|
|
72
|
+
const answer = (await rl.question(`\nResume which? [${range}words to search, Enter = 1, q = cancel] `)).trim();
|
|
73
|
+
if (answer === "q" || answer === "quit")
|
|
74
|
+
throw new Error("no session picked");
|
|
75
|
+
if (answer === "" && list.length)
|
|
76
|
+
return list[0];
|
|
77
|
+
const idx = Number(answer);
|
|
78
|
+
if (Number.isInteger(idx) && idx >= 1 && idx <= Math.min(list.length, PAGE))
|
|
79
|
+
return list[idx - 1];
|
|
80
|
+
all ??= await listAllTranscripts();
|
|
81
|
+
const hits = searchTranscripts(all, answer, cwd);
|
|
82
|
+
if (hits.length === 0) {
|
|
83
|
+
// Keep the list on screen so the numbers still mean what they did.
|
|
84
|
+
process.stderr.write(` ${c("yellow", `no session matches "${answer}"`)} ${c("dim", "— try other words, or pick from the list above")}\n`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
list = hits;
|
|
88
|
+
process.stderr.write(`\n${c("bold", `Sessions matching "${answer}":`)}\n\n`);
|
|
89
|
+
printChoices(list, here, viaDitto);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
rl.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function listForError(matches) {
|
|
97
|
+
return matches
|
|
98
|
+
.slice(0, 5)
|
|
99
|
+
.map((t) => ` ${t.id} ${describe(t)}${t.cwd ? ` (${tildify(t.cwd)})` : ""}`)
|
|
100
|
+
.join("\n");
|
|
101
|
+
}
|
|
102
|
+
async function withRecord(transcript) {
|
|
103
|
+
return { transcript, record: await sessionForHarnessId("claude", transcript.id) };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolves `--resume [value]` for Claude Code. A value may be a Ditto session
|
|
107
|
+
* id, a Claude session id, or a title / words from one (what `claude --resume`
|
|
108
|
+
* prints for a renamed session). With no value an interactive terminal gets a
|
|
109
|
+
* picker; a script gets the most recent session, as before.
|
|
110
|
+
*/
|
|
111
|
+
export async function resolveClaudeResume(value, opts) {
|
|
112
|
+
if (value === true) {
|
|
113
|
+
if (opts.interactive) {
|
|
114
|
+
const here = await listTranscriptsIn(opts.cwd);
|
|
115
|
+
return withRecord(await pickTranscript(here, `Claude Code sessions in ${tildify(canonicalCwd(opts.cwd))} (newest first):`, opts.cwd));
|
|
116
|
+
}
|
|
117
|
+
// The most recent conversation: the newest transcript here, or the last
|
|
118
|
+
// Ditto launch's (it may have run in a worktree) if that one is newer. A
|
|
119
|
+
// launch that never sent anything only wins when there is nothing else.
|
|
120
|
+
const [newest] = await listTranscriptsIn(opts.cwd);
|
|
121
|
+
const record = await latestSession("claude", opts.cwd);
|
|
122
|
+
const recorded = record ? await findTranscriptById(record.harnessSessionId ?? record.id, record.worktree ?? record.cwd) : undefined;
|
|
123
|
+
if (record && recorded && (!newest || recorded.modifiedAt >= newest.modifiedAt))
|
|
124
|
+
return { record, transcript: recorded };
|
|
125
|
+
if (newest)
|
|
126
|
+
return withRecord(newest);
|
|
127
|
+
if (record)
|
|
128
|
+
return { record };
|
|
129
|
+
throw new Error("no previous claude session to resume here; see `heyditto sessions`");
|
|
130
|
+
}
|
|
131
|
+
const wanted = value.trim();
|
|
132
|
+
const record = (await readSession(wanted)) ?? (await sessionForHarnessId("claude", wanted));
|
|
133
|
+
if (record) {
|
|
134
|
+
if (record.harness !== "claude")
|
|
135
|
+
return { record };
|
|
136
|
+
return { record, transcript: await findTranscriptById(record.harnessSessionId ?? record.id, record.cwd) };
|
|
137
|
+
}
|
|
138
|
+
const byId = await findTranscriptById(wanted, opts.cwd);
|
|
139
|
+
if (byId)
|
|
140
|
+
return withRecord(byId);
|
|
141
|
+
const matches = searchTranscripts(await listAllTranscripts(), wanted, opts.cwd);
|
|
142
|
+
if (matches.length === 1)
|
|
143
|
+
return withRecord(matches[0]);
|
|
144
|
+
if (matches.length === 0) {
|
|
145
|
+
throw new Error(`no Claude Code session matches "${wanted}" (searched Ditto session ids, Claude session ids and titles).\n` +
|
|
146
|
+
"Run `heyditto claude --resume` with no value to pick from a list.");
|
|
147
|
+
}
|
|
148
|
+
if (opts.interactive)
|
|
149
|
+
return withRecord(await pickTranscript(matches, `Sessions matching "${wanted}":`, opts.cwd));
|
|
150
|
+
throw new Error(`"${wanted}" matches ${matches.length} sessions; pass one id:\n${listForError(matches)}`);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=claude-resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-resume.js","sourceRoot":"","sources":["../../src/agents/claude-resume.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code's own session store (`~/.claude/projects/<cwd slug>/<id>.jsonl`),
|
|
3
|
+
* read so `heyditto claude --resume` can find a conversation the way `claude
|
|
4
|
+
* --resume` does: by session id, by title, or from a picker. Sessions started
|
|
5
|
+
* in Claude Desktop live in the same store, so they resume here too.
|
|
6
|
+
*
|
|
7
|
+
* Transcripts can be tens of megabytes; only the head and tail are read. Claude
|
|
8
|
+
* re-appends its title and last-prompt lines as the session goes, so the tail
|
|
9
|
+
* carries the current ones.
|
|
10
|
+
*/
|
|
11
|
+
/** Metadata of one Claude Code transcript. */
|
|
12
|
+
export interface ClaudeTranscript {
|
|
13
|
+
/** Claude's session id (the file name). */
|
|
14
|
+
id: string;
|
|
15
|
+
file: string;
|
|
16
|
+
/** Directory the session ran in, when the transcript records it. */
|
|
17
|
+
cwd?: string;
|
|
18
|
+
/** `/rename` title, else the title Claude generated. */
|
|
19
|
+
title?: string;
|
|
20
|
+
lastPrompt?: string;
|
|
21
|
+
/** The opening prompt, when it falls in the part of the file that is read. */
|
|
22
|
+
firstPrompt?: string;
|
|
23
|
+
/** "cli", "claude-desktop", "sdk-ts", … */
|
|
24
|
+
entrypoint?: string;
|
|
25
|
+
gitBranch?: string;
|
|
26
|
+
modifiedAt: Date;
|
|
27
|
+
}
|
|
28
|
+
export declare function claudeHome(): string;
|
|
29
|
+
/** The project directory Claude Code keys sessions started in `cwd` under. */
|
|
30
|
+
export declare function claudeProjectDir(cwd: string): string;
|
|
31
|
+
export declare function isUuid(value: string): boolean;
|
|
32
|
+
/** Reads one transcript's metadata; undefined when it has no conversation in it. */
|
|
33
|
+
export declare function readTranscript(file: string): Promise<ClaudeTranscript | undefined>;
|
|
34
|
+
/** Conversations started in `cwd`, newest first. */
|
|
35
|
+
export declare function listTranscriptsIn(cwd: string): Promise<ClaudeTranscript[]>;
|
|
36
|
+
/** Every conversation Claude Code has on this machine, newest first. */
|
|
37
|
+
export declare function listAllTranscripts(): Promise<ClaudeTranscript[]>;
|
|
38
|
+
/**
|
|
39
|
+
* A transcript by Claude session id, looked up in `cwd`'s project first and
|
|
40
|
+
* then in every project (a session moved between worktrees keeps its id).
|
|
41
|
+
*/
|
|
42
|
+
export declare function findTranscriptById(id: string, cwd?: string): Promise<ClaudeTranscript | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* Transcripts matching a free-text query. An exact (case-insensitive) title
|
|
45
|
+
* match wins outright, as `claude --resume "<title>"` does; otherwise every
|
|
46
|
+
* word must appear in the title, first or last prompt, directory, branch or
|
|
47
|
+
* id. Title hits come first, and within each group ones from `cwd` lead.
|
|
48
|
+
*/
|
|
49
|
+
export declare function searchTranscripts(all: ClaudeTranscript[], query: string, cwd?: string): ClaudeTranscript[];
|
|
50
|
+
/** "3m ago", "5h ago", "2d ago", or a date for anything older than a month. */
|
|
51
|
+
export declare function relativeTime(date: Date, now?: number): string;
|
|
52
|
+
export declare function entrypointLabel(entrypoint: string | undefined): string | undefined;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { open, readFile, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { canonicalCwd } from "../teleport/harness.js";
|
|
5
|
+
import { cwdSlug } from "../teleport/types.js";
|
|
6
|
+
const HEAD_BYTES = 64 * 1024;
|
|
7
|
+
const TAIL_BYTES = 256 * 1024;
|
|
8
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9
|
+
export function claudeHome() {
|
|
10
|
+
return process.env.CLAUDE_CONFIG_DIR?.trim() || path.join(os.homedir(), ".claude");
|
|
11
|
+
}
|
|
12
|
+
function projectsDir() {
|
|
13
|
+
return path.join(claudeHome(), "projects");
|
|
14
|
+
}
|
|
15
|
+
/** The project directory Claude Code keys sessions started in `cwd` under. */
|
|
16
|
+
export function claudeProjectDir(cwd) {
|
|
17
|
+
return path.join(projectsDir(), cwdSlug(canonicalCwd(cwd)));
|
|
18
|
+
}
|
|
19
|
+
export function isUuid(value) {
|
|
20
|
+
return UUID.test(value);
|
|
21
|
+
}
|
|
22
|
+
async function readSlice(file, size) {
|
|
23
|
+
const handle = await open(file, "r");
|
|
24
|
+
try {
|
|
25
|
+
const headLen = Math.min(size, HEAD_BYTES);
|
|
26
|
+
const head = Buffer.alloc(headLen);
|
|
27
|
+
await handle.read(head, 0, headLen, 0);
|
|
28
|
+
if (size <= HEAD_BYTES)
|
|
29
|
+
return { head: head.toString("utf8"), tail: "" };
|
|
30
|
+
const tailLen = Math.min(size - headLen, TAIL_BYTES);
|
|
31
|
+
const tail = Buffer.alloc(tailLen);
|
|
32
|
+
await handle.read(tail, 0, tailLen, size - tailLen);
|
|
33
|
+
return { head: head.toString("utf8"), tail: tail.toString("utf8") };
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await handle.close();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function jsonLines(text) {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const line of text.split("\n")) {
|
|
42
|
+
if (!line.startsWith("{"))
|
|
43
|
+
continue;
|
|
44
|
+
try {
|
|
45
|
+
out.push(JSON.parse(line));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* a line cut by the head/tail window */
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/** Text the user typed in a transcript `user` message; injected context (`<system-reminder>`, tool results) is skipped. */
|
|
54
|
+
function promptText(message) {
|
|
55
|
+
const content = message?.content;
|
|
56
|
+
const parts = typeof content === "string" ? [content] : Array.isArray(content)
|
|
57
|
+
? content.map((p) => (p.type === "text" ? p.text : undefined))
|
|
58
|
+
: [];
|
|
59
|
+
for (const part of parts) {
|
|
60
|
+
if (typeof part !== "string")
|
|
61
|
+
continue;
|
|
62
|
+
const text = part.trim();
|
|
63
|
+
if (text && !text.startsWith("<"))
|
|
64
|
+
return text.slice(0, 500);
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const str = (v) => (typeof v === "string" && v.trim() ? v.trim() : undefined);
|
|
69
|
+
/** Reads one transcript's metadata; undefined when it has no conversation in it. */
|
|
70
|
+
export async function readTranscript(file) {
|
|
71
|
+
let info;
|
|
72
|
+
try {
|
|
73
|
+
info = await stat(file);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
if (!info.isFile())
|
|
79
|
+
return undefined;
|
|
80
|
+
const id = path.basename(file, ".jsonl");
|
|
81
|
+
const { head, tail } = await readSlice(file, info.size);
|
|
82
|
+
const lines = [...jsonLines(head), ...jsonLines(tail)];
|
|
83
|
+
let customTitle;
|
|
84
|
+
let aiTitle;
|
|
85
|
+
let lastPrompt;
|
|
86
|
+
let firstPrompt;
|
|
87
|
+
let cwd;
|
|
88
|
+
let entrypoint;
|
|
89
|
+
let gitBranch;
|
|
90
|
+
let spoke = false;
|
|
91
|
+
for (const l of lines) {
|
|
92
|
+
if (l.type === "custom-title")
|
|
93
|
+
customTitle = str(l.customTitle) ?? customTitle;
|
|
94
|
+
else if (l.type === "ai-title")
|
|
95
|
+
aiTitle = str(l.aiTitle) ?? aiTitle;
|
|
96
|
+
else if (l.type === "last-prompt")
|
|
97
|
+
lastPrompt = str(l.lastPrompt) ?? lastPrompt;
|
|
98
|
+
else if (l.type === "user" || l.type === "assistant") {
|
|
99
|
+
spoke = true;
|
|
100
|
+
if (l.type === "user" && !firstPrompt)
|
|
101
|
+
firstPrompt = promptText(l.message);
|
|
102
|
+
}
|
|
103
|
+
cwd ??= str(l.cwd);
|
|
104
|
+
entrypoint ??= str(l.entrypoint);
|
|
105
|
+
gitBranch = str(l.gitBranch) ?? gitBranch;
|
|
106
|
+
}
|
|
107
|
+
// Newer Claude builds also keep the /rename title beside the transcript.
|
|
108
|
+
try {
|
|
109
|
+
const sidecar = JSON.parse(await readFile(path.join(path.dirname(file), id, "custom-title.json"), "utf8"));
|
|
110
|
+
customTitle = str(sidecar.customTitle) ?? customTitle;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
/* no sidecar */
|
|
114
|
+
}
|
|
115
|
+
if (!spoke && !lastPrompt)
|
|
116
|
+
return undefined;
|
|
117
|
+
return {
|
|
118
|
+
id,
|
|
119
|
+
file,
|
|
120
|
+
cwd,
|
|
121
|
+
title: customTitle ?? aiTitle,
|
|
122
|
+
lastPrompt,
|
|
123
|
+
firstPrompt,
|
|
124
|
+
entrypoint,
|
|
125
|
+
gitBranch,
|
|
126
|
+
modifiedAt: info.mtime,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async function jsonlFiles(dir) {
|
|
130
|
+
try {
|
|
131
|
+
return (await readdir(dir)).filter((n) => n.endsWith(".jsonl")).map((n) => path.join(dir, n));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function projectDirs() {
|
|
138
|
+
try {
|
|
139
|
+
const entries = await readdir(projectsDir(), { withFileTypes: true });
|
|
140
|
+
return entries.filter((e) => e.isDirectory()).map((e) => path.join(projectsDir(), e.name));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Newest-first sort, keeping files whose metadata could not be read out. */
|
|
147
|
+
async function readAll(files) {
|
|
148
|
+
// Most-recent files first so a caller that only shows the top of the list
|
|
149
|
+
// does not wait on years of history.
|
|
150
|
+
const withTimes = await Promise.all(files.map(async (f) => ({ f, t: await stat(f).then((s) => s.mtimeMs, () => 0) })));
|
|
151
|
+
withTimes.sort((a, b) => b.t - a.t);
|
|
152
|
+
const out = [];
|
|
153
|
+
for (const { f } of withTimes) {
|
|
154
|
+
const t = await readTranscript(f);
|
|
155
|
+
if (t)
|
|
156
|
+
out.push(t);
|
|
157
|
+
}
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
/** Conversations started in `cwd`, newest first. */
|
|
161
|
+
export async function listTranscriptsIn(cwd) {
|
|
162
|
+
return readAll(await jsonlFiles(claudeProjectDir(cwd)));
|
|
163
|
+
}
|
|
164
|
+
/** Every conversation Claude Code has on this machine, newest first. */
|
|
165
|
+
export async function listAllTranscripts() {
|
|
166
|
+
const files = (await Promise.all((await projectDirs()).map(jsonlFiles))).flat();
|
|
167
|
+
return readAll(files);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A transcript by Claude session id, looked up in `cwd`'s project first and
|
|
171
|
+
* then in every project (a session moved between worktrees keeps its id).
|
|
172
|
+
*/
|
|
173
|
+
export async function findTranscriptById(id, cwd) {
|
|
174
|
+
if (!isUuid(id))
|
|
175
|
+
return undefined;
|
|
176
|
+
if (cwd) {
|
|
177
|
+
const here = await readTranscript(path.join(claudeProjectDir(cwd), `${id}.jsonl`));
|
|
178
|
+
if (here)
|
|
179
|
+
return here;
|
|
180
|
+
}
|
|
181
|
+
for (const dir of await projectDirs()) {
|
|
182
|
+
const t = await readTranscript(path.join(dir, `${id}.jsonl`));
|
|
183
|
+
if (t)
|
|
184
|
+
return t;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
function norm(s) {
|
|
189
|
+
return (s ?? "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Transcripts matching a free-text query. An exact (case-insensitive) title
|
|
193
|
+
* match wins outright, as `claude --resume "<title>"` does; otherwise every
|
|
194
|
+
* word must appear in the title, first or last prompt, directory, branch or
|
|
195
|
+
* id. Title hits come first, and within each group ones from `cwd` lead.
|
|
196
|
+
*/
|
|
197
|
+
export function searchTranscripts(all, query, cwd) {
|
|
198
|
+
const q = norm(query);
|
|
199
|
+
if (!q)
|
|
200
|
+
return all;
|
|
201
|
+
const here = cwd ? canonicalCwd(cwd) : undefined;
|
|
202
|
+
const byHere = (list) => [...list].sort((a, b) => Number(b.cwd === here) - Number(a.cwd === here));
|
|
203
|
+
const exact = all.filter((t) => norm(t.title) === q);
|
|
204
|
+
if (exact.length)
|
|
205
|
+
return byHere(exact);
|
|
206
|
+
const words = q.split(" ");
|
|
207
|
+
const has = (text) => {
|
|
208
|
+
const hay = norm(text);
|
|
209
|
+
return words.every((w) => hay.includes(w));
|
|
210
|
+
};
|
|
211
|
+
const inTitle = all.filter((t) => has(t.title));
|
|
212
|
+
const elsewhere = all.filter((t) => !has(t.title) && has([t.title, t.lastPrompt, t.firstPrompt, t.cwd, t.gitBranch, t.id].filter(Boolean).join(" ")));
|
|
213
|
+
return [...byHere(inTitle), ...byHere(elsewhere)];
|
|
214
|
+
}
|
|
215
|
+
/** "3m ago", "5h ago", "2d ago", or a date for anything older than a month. */
|
|
216
|
+
export function relativeTime(date, now = Date.now()) {
|
|
217
|
+
const s = Math.max(0, Math.round((now - date.getTime()) / 1000));
|
|
218
|
+
if (s < 60)
|
|
219
|
+
return "just now";
|
|
220
|
+
if (s < 3600)
|
|
221
|
+
return `${Math.floor(s / 60)}m ago`;
|
|
222
|
+
if (s < 86400)
|
|
223
|
+
return `${Math.floor(s / 3600)}h ago`;
|
|
224
|
+
if (s < 30 * 86400)
|
|
225
|
+
return `${Math.floor(s / 86400)}d ago`;
|
|
226
|
+
return date.toISOString().slice(0, 10);
|
|
227
|
+
}
|
|
228
|
+
export function entrypointLabel(entrypoint) {
|
|
229
|
+
if (entrypoint === "claude-desktop")
|
|
230
|
+
return "Claude Desktop";
|
|
231
|
+
if (entrypoint === "cli")
|
|
232
|
+
return "CLI";
|
|
233
|
+
if (entrypoint?.startsWith("sdk"))
|
|
234
|
+
return "SDK";
|
|
235
|
+
return entrypoint;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=claude-transcripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-transcripts.js","sourceRoot":"","sources":["../../src/agents/claude-transcripts.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/claude.d.ts
CHANGED
|
@@ -9,3 +9,14 @@ import { type HarnessPlan, type PlanInput } from "./types.js";
|
|
|
9
9
|
* prompt or add a stray x-api-key header.
|
|
10
10
|
*/
|
|
11
11
|
export declare function planClaude(input: PlanInput): HarnessPlan;
|
|
12
|
+
/**
|
|
13
|
+
* Claude's own resume flags typed after `--` (`heyditto claude -- -r`). Passed
|
|
14
|
+
* through they collide with the `--session-id` every launch sets ("--session-id
|
|
15
|
+
* can only be used with --continue or --resume if --fork-session is also
|
|
16
|
+
* specified"), so they are lifted out and handled as `--resume` / `--continue`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function liftResumeFlags(args: string[]): {
|
|
19
|
+
args: string[];
|
|
20
|
+
resume?: string | true;
|
|
21
|
+
continue?: boolean;
|
|
22
|
+
};
|
package/dist/agents/claude.js
CHANGED
|
@@ -16,11 +16,15 @@ export function planClaude(input) {
|
|
|
16
16
|
args.push("--permission-mode", "acceptEdits");
|
|
17
17
|
else if (input.plan)
|
|
18
18
|
args.push("--permission-mode", "plan");
|
|
19
|
+
// A session id of our own is only for a brand-new conversation; Claude
|
|
20
|
+
// rejects it next to its other ways of picking one (--from-pr, a forwarded
|
|
21
|
+
// --session-id).
|
|
22
|
+
const picksOwn = input.passthrough.some((a) => a === "--from-pr" || a.startsWith("--from-pr=") || a === "--session-id" || a.startsWith("--session-id="));
|
|
19
23
|
if (input.resumeId)
|
|
20
24
|
args.push("--resume", input.resumeId);
|
|
21
25
|
else if (input.resumeLast)
|
|
22
26
|
args.push("--continue");
|
|
23
|
-
else
|
|
27
|
+
else if (!picksOwn)
|
|
24
28
|
args.push("--session-id", input.sessionId);
|
|
25
29
|
if (input.model)
|
|
26
30
|
args.push("--model", input.model);
|
|
@@ -45,4 +49,34 @@ export function planClaude(input) {
|
|
|
45
49
|
installHint: "install Claude Code: npm i -g @anthropic-ai/claude-code (or see https://code.claude.com)",
|
|
46
50
|
};
|
|
47
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Claude's own resume flags typed after `--` (`heyditto claude -- -r`). Passed
|
|
54
|
+
* through they collide with the `--session-id` every launch sets ("--session-id
|
|
55
|
+
* can only be used with --continue or --resume if --fork-session is also
|
|
56
|
+
* specified"), so they are lifted out and handled as `--resume` / `--continue`.
|
|
57
|
+
*/
|
|
58
|
+
export function liftResumeFlags(args) {
|
|
59
|
+
const out = [];
|
|
60
|
+
let resume;
|
|
61
|
+
let cont = false;
|
|
62
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
63
|
+
const a = args[i];
|
|
64
|
+
if (a === "-r" || a === "--resume") {
|
|
65
|
+
const next = args[i + 1];
|
|
66
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
67
|
+
resume = next;
|
|
68
|
+
i += 1;
|
|
69
|
+
}
|
|
70
|
+
else
|
|
71
|
+
resume = true;
|
|
72
|
+
}
|
|
73
|
+
else if (a.startsWith("--resume="))
|
|
74
|
+
resume = a.slice("--resume=".length) || true;
|
|
75
|
+
else if (a === "-c" || a === "--continue")
|
|
76
|
+
cont = true;
|
|
77
|
+
else
|
|
78
|
+
out.push(a);
|
|
79
|
+
}
|
|
80
|
+
return { args: out, ...(resume !== undefined ? { resume } : {}), ...(cont ? { continue: true } : {}) };
|
|
81
|
+
}
|
|
48
82
|
//# sourceMappingURL=claude.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzF;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,KAAgB;IACzC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;SACvD,IAAI,KAAK,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;SAChE,IAAI,KAAK,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAE5D,IAAI,KAAK,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;SACrD,IAAI,KAAK,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"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"}
|