@koda-sl/baker-bridge 0.142.0-dev.c547ce62b → 0.142.0-dev.fe5f5a0fa
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 +7 -15
- package/dist/hono/agent.d.ts.map +1 -1
- package/dist/hono/agent.js +0 -2
- package/dist/hono/agent.js.map +1 -1
- package/dist/hono/bridge-job.d.ts +0 -13
- package/dist/hono/bridge-job.d.ts.map +1 -1
- package/dist/hono/bridge-job.js +13 -59
- package/dist/hono/bridge-job.js.map +1 -1
- package/dist/hono/bridge-job.test.js +33 -64
- package/dist/hono/bridge-job.test.js.map +1 -1
- package/dist/hono/runtime-files.d.ts +0 -1
- package/dist/hono/runtime-files.d.ts.map +1 -1
- package/dist/hono/runtime-files.js +0 -1
- package/dist/hono/runtime-files.js.map +1 -1
- package/dist/hono/session-continuity.d.ts.map +1 -1
- package/dist/hono/session-continuity.js +2 -5
- package/dist/hono/session-continuity.js.map +1 -1
- package/dist/hono/turn-events.d.ts +1 -1
- package/dist/hono/turn-events.d.ts.map +1 -1
- package/dist/hono/turn-events.js.map +1 -1
- package/dist/review/evidence-block.d.ts.map +1 -1
- package/dist/review/evidence-block.js +3 -1
- package/dist/review/evidence-block.js.map +1 -1
- package/dist/review/evidence-block.test.js +33 -1
- package/dist/review/evidence-block.test.js.map +1 -1
- package/dist/review/evidence.d.ts +4 -0
- package/dist/review/evidence.d.ts.map +1 -1
- package/dist/review/evidence.js +18 -5
- package/dist/review/evidence.js.map +1 -1
- package/dist/review/evidence.test.d.ts +2 -0
- package/dist/review/evidence.test.d.ts.map +1 -0
- package/dist/review/evidence.test.js +92 -0
- package/dist/review/evidence.test.js.map +1 -0
- package/dist/review/transcripts.d.ts +17 -6
- package/dist/review/transcripts.d.ts.map +1 -1
- package/dist/review/transcripts.js +100 -19
- package/dist/review/transcripts.js.map +1 -1
- package/dist/review/transcripts.test.js +37 -0
- package/dist/review/transcripts.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/hono/publish-handoff.d.ts +0 -45
- package/dist/hono/publish-handoff.d.ts.map +0 -1
- package/dist/hono/publish-handoff.js +0 -176
- package/dist/hono/publish-handoff.js.map +0 -1
|
@@ -10,11 +10,20 @@ import { bridgeRuntimeFiles, runtimeFileStore } from "../hono/runtime-files.js";
|
|
|
10
10
|
* this sandbox. That file is append-only, so it survives compaction: a
|
|
11
11
|
* compaction adds a summary line, it never removes one.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* A thread is not one SDK session. Every message resumes the last one as a
|
|
14
|
+
* fork, a stall or a restart forks again, and `/publish` runs in a session of
|
|
15
|
+
* its own the thread never adopts. The bridge records each id a turn runs under
|
|
16
|
+
* as a `session` line in `~/.baker/turn-events.jsonl`; the thread's session file
|
|
17
|
+
* (`~/.baker/sessions/<threadId>.json`) names only the latest. Both are read,
|
|
18
|
+
* and each id maps to `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl` plus the
|
|
19
|
+
* subagent directory beside it — a subagent lives under the id it was spawned
|
|
20
|
+
* in, so reading the latest alone drops every earlier turn's fan-out.
|
|
21
|
+
*
|
|
22
|
+
* A fork copies the conversation so far into its new file under the same line
|
|
23
|
+
* uuids, so the files overlap; the reader dedupes by uuid.
|
|
24
|
+
*
|
|
25
|
+
* Whatever cannot be read is reported rather than skipped: "we could not read
|
|
26
|
+
* this" and "this had no tool calls" must never look the same to the reviewer.
|
|
18
27
|
*/
|
|
19
28
|
/** Claude Code names a project directory after its cwd, with every separator folded to `-`. */
|
|
20
29
|
export function projectSlug(cwd) {
|
|
@@ -36,6 +45,53 @@ async function readSessionId(threadId) {
|
|
|
36
45
|
return undefined;
|
|
37
46
|
}
|
|
38
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Session ids per thread, in the order the bridge first saw each one.
|
|
50
|
+
*
|
|
51
|
+
* Absent or unreadable is an empty map: a Runtime whose bridge predates the
|
|
52
|
+
* `session` event still has the session file, which is what it had before.
|
|
53
|
+
*/
|
|
54
|
+
async function readTurnSessionIds() {
|
|
55
|
+
const byThread = new Map();
|
|
56
|
+
const result = await runtimeFileStore.readText(bridgeRuntimeFiles.turnEventsFile());
|
|
57
|
+
if (!result.ok) {
|
|
58
|
+
return byThread;
|
|
59
|
+
}
|
|
60
|
+
for (const line of result.value.split("\n")) {
|
|
61
|
+
const sessionId = sessionEventId(line);
|
|
62
|
+
if (!sessionId) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const ids = byThread.get(sessionId.threadId) ?? [];
|
|
66
|
+
if (!ids.includes(sessionId.sessionId)) {
|
|
67
|
+
ids.push(sessionId.sessionId);
|
|
68
|
+
}
|
|
69
|
+
byThread.set(sessionId.threadId, ids);
|
|
70
|
+
}
|
|
71
|
+
return byThread;
|
|
72
|
+
}
|
|
73
|
+
function sessionEventId(line) {
|
|
74
|
+
if (line.trim().length === 0) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
let parsed;
|
|
78
|
+
try {
|
|
79
|
+
parsed = JSON.parse(line);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// A truncated final line is normal on a file still being appended to.
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const event = parsed;
|
|
89
|
+
if (event.event !== "session" || typeof event.threadId !== "string") {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const sessionId = event.detail?.sessionId;
|
|
93
|
+
return typeof sessionId === "string" && sessionId.length > 0 ? { threadId: event.threadId, sessionId } : undefined;
|
|
94
|
+
}
|
|
39
95
|
async function listJsonl(dir) {
|
|
40
96
|
try {
|
|
41
97
|
const entries = await readdir(dir);
|
|
@@ -57,24 +113,49 @@ export async function resolveThreadTranscripts(threadIds, options = {}) {
|
|
|
57
113
|
const projectsRoot = options.projectsRoot ?? join(homedir(), ".claude", "projects");
|
|
58
114
|
const projectDir = join(projectsRoot, projectSlug(projectRoot));
|
|
59
115
|
const onDisk = new Set(await listJsonl(projectDir));
|
|
116
|
+
const turnSessionIds = await readTurnSessionIds();
|
|
60
117
|
const out = [];
|
|
61
118
|
for (const threadId of threadIds) {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
119
|
+
const sessionIds = [...(turnSessionIds.get(threadId) ?? [])];
|
|
120
|
+
const latest = await readSessionId(threadId);
|
|
121
|
+
if (latest && !sessionIds.includes(latest)) {
|
|
122
|
+
sessionIds.push(latest);
|
|
66
123
|
}
|
|
67
|
-
|
|
68
|
-
const files = onDisk.has(file) ? [file] : [];
|
|
69
|
-
const subagentFiles = await listJsonl(join(projectDir, sessionId, "subagents"));
|
|
70
|
-
out.push({
|
|
71
|
-
threadId,
|
|
72
|
-
sessionIds: [sessionId],
|
|
73
|
-
files,
|
|
74
|
-
subagentFiles,
|
|
75
|
-
...(files.length === 0 ? { missing: "no_transcript" } : {}),
|
|
76
|
-
});
|
|
124
|
+
out.push(await threadTranscripts(threadId, sessionIds, projectDir, onDisk));
|
|
77
125
|
}
|
|
78
126
|
return out;
|
|
79
127
|
}
|
|
128
|
+
async function threadTranscripts(threadId, sessionIds, projectDir, onDisk) {
|
|
129
|
+
if (sessionIds.length === 0) {
|
|
130
|
+
return {
|
|
131
|
+
threadId,
|
|
132
|
+
sessionIds: [],
|
|
133
|
+
sessionIdsWithoutTranscript: [],
|
|
134
|
+
files: [],
|
|
135
|
+
subagentFiles: [],
|
|
136
|
+
missing: "no_session_file",
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const files = [];
|
|
140
|
+
const sessionIdsWithoutTranscript = [];
|
|
141
|
+
const subagentFiles = [];
|
|
142
|
+
for (const sessionId of sessionIds) {
|
|
143
|
+
const file = join(projectDir, `${sessionId}.jsonl`);
|
|
144
|
+
if (onDisk.has(file)) {
|
|
145
|
+
files.push(file);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
sessionIdsWithoutTranscript.push(sessionId);
|
|
149
|
+
}
|
|
150
|
+
subagentFiles.push(...(await listJsonl(join(projectDir, sessionId, "subagents"))));
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
threadId,
|
|
154
|
+
sessionIds,
|
|
155
|
+
sessionIdsWithoutTranscript,
|
|
156
|
+
files,
|
|
157
|
+
subagentFiles,
|
|
158
|
+
...(files.length === 0 ? { missing: "no_transcript" } : {}),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
80
161
|
//# sourceMappingURL=transcripts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEhF
|
|
1
|
+
{"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ vi.mock("../hono/runtime-files.ts", async () => {
|
|
|
10
10
|
bridgeRuntimeFiles: {
|
|
11
11
|
...actual.bridgeRuntimeFiles,
|
|
12
12
|
sessionFile: (threadId) => join(bakerHome, "sessions", `${threadId}.json`),
|
|
13
|
+
turnEventsFile: () => join(bakerHome, "turn-events.jsonl"),
|
|
13
14
|
},
|
|
14
15
|
};
|
|
15
16
|
});
|
|
@@ -25,6 +26,9 @@ function writeSession(threadId, body) {
|
|
|
25
26
|
mkdirSync(join(bakerHome, "sessions"), { recursive: true });
|
|
26
27
|
writeFileSync(join(bakerHome, "sessions", `${threadId}.json`), body);
|
|
27
28
|
}
|
|
29
|
+
function writeTurnEvents(events) {
|
|
30
|
+
writeFileSync(join(bakerHome, "turn-events.jsonl"), events.map((event) => `${JSON.stringify(event)}\n`).join(""));
|
|
31
|
+
}
|
|
28
32
|
describe("projectSlug", () => {
|
|
29
33
|
it("folds every path separator and dot, the way Claude Code names its project directory", () => {
|
|
30
34
|
expect(projectSlug("/home/user/my.repo")).toBe("-home-user-my-repo");
|
|
@@ -78,5 +82,38 @@ describe("resolveThreadTranscripts", () => {
|
|
|
78
82
|
const result = await resolveThreadTranscripts(["thread-reaped"], { projectRoot, projectsRoot });
|
|
79
83
|
expect(result[0]?.missing).toBe("no_transcript");
|
|
80
84
|
});
|
|
85
|
+
it("joins every session a resumed thread ran under, with each one's subagents", async () => {
|
|
86
|
+
// Every message forks the SDK session: the thread's session file names only
|
|
87
|
+
// the last id, while the visual checks of turn 2 sit under the id turn 2 ran in.
|
|
88
|
+
const projectsRoot = mkdtempSync(join(tmpdir(), "projects-"));
|
|
89
|
+
created.push(projectsRoot);
|
|
90
|
+
const projectRoot = "/work/resumed";
|
|
91
|
+
const dir = join(projectsRoot, projectSlug(projectRoot));
|
|
92
|
+
mkdirSync(dir, { recursive: true });
|
|
93
|
+
for (const sessionId of ["s-turn1", "s-turn2", "s-turn3"]) {
|
|
94
|
+
writeFileSync(join(dir, `${sessionId}.jsonl`), "{}\n");
|
|
95
|
+
}
|
|
96
|
+
mkdirSync(join(dir, "s-turn2", "subagents"), { recursive: true });
|
|
97
|
+
writeFileSync(join(dir, "s-turn2", "subagents", "agent-v4.jsonl"), "{}\n");
|
|
98
|
+
writeFileSync(join(dir, "s-turn2", "subagents", "agent-v1.jsonl"), "{}\n");
|
|
99
|
+
mkdirSync(join(dir, "s-turn3", "subagents"), { recursive: true });
|
|
100
|
+
writeFileSync(join(dir, "s-turn3", "subagents", "agent-last.jsonl"), "{}\n");
|
|
101
|
+
writeSession("thread-resumed", JSON.stringify({ version: 2, sessionId: "s-turn3", updatedAtMs: 3 }));
|
|
102
|
+
writeTurnEvents([
|
|
103
|
+
{ threadId: "thread-resumed", turnId: "t1", event: "session", detail: { sessionId: "s-turn1" } },
|
|
104
|
+
{ threadId: "thread-other", turnId: "o1", event: "session", detail: { sessionId: "s-other" } },
|
|
105
|
+
{ threadId: "thread-resumed", turnId: "t2", event: "session", detail: { sessionId: "s-turn2" } },
|
|
106
|
+
{ threadId: "thread-resumed", turnId: "t2", event: "turn_end" },
|
|
107
|
+
{ threadId: "thread-resumed", turnId: "t3", event: "session", detail: { sessionId: "s-turn3" } },
|
|
108
|
+
]);
|
|
109
|
+
const [thread] = await resolveThreadTranscripts(["thread-resumed"], { projectRoot, projectsRoot });
|
|
110
|
+
expect(thread?.sessionIds).toEqual(["s-turn1", "s-turn2", "s-turn3"]);
|
|
111
|
+
expect(thread?.files).toEqual(["s-turn1", "s-turn2", "s-turn3"].map((id) => join(dir, `${id}.jsonl`)));
|
|
112
|
+
expect([...(thread?.subagentFiles ?? [])].sort()).toEqual([
|
|
113
|
+
join(dir, "s-turn2", "subagents", "agent-v1.jsonl"),
|
|
114
|
+
join(dir, "s-turn2", "subagents", "agent-v4.jsonl"),
|
|
115
|
+
join(dir, "s-turn3", "subagents", "agent-last.jsonl"),
|
|
116
|
+
].sort());
|
|
117
|
+
});
|
|
81
118
|
});
|
|
82
119
|
//# sourceMappingURL=transcripts.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcripts.test.js","sourceRoot":"","sources":["../../src/review/transcripts.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE7D,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;AAE7D,EAAE,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC7C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAA4C,0BAA0B,CAAC,CAAC;IAC5G,OAAO;QACL,GAAG,MAAM;QACT,kBAAkB,EAAE;YAClB,GAAG,MAAM,CAAC,kBAAkB;YAC5B,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,QAAQ,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"transcripts.test.js","sourceRoot":"","sources":["../../src/review/transcripts.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koda-sl/baker-bridge",
|
|
3
|
-
"version": "0.142.0-dev.
|
|
3
|
+
"version": "0.142.0-dev.fe5f5a0fa",
|
|
4
4
|
"description": "HTTP server wrapping the Claude Agent SDK. Persists chat events to Convex; the dashboard subscribes via Convex realtime",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
import { type BridgeRuntimeFiles } from "./runtime-files.ts";
|
|
3
|
-
import type { DispatchHistorySnapshot } from "./types.ts";
|
|
4
|
-
/**
|
|
5
|
-
* The language a publish run reports in. CLAUDE.md says to write in the language
|
|
6
|
-
* of the last message the marketer typed, and a run whose only user message is
|
|
7
|
-
* `/publish` has none in view — so it guessed, often English to a Spanish chat.
|
|
8
|
-
*/
|
|
9
|
-
export declare function publishLanguageReminder(history: DispatchHistorySnapshot | undefined): string | undefined;
|
|
10
|
-
export type PublishRunEnding = "completed" | "errored" | "cancelled";
|
|
11
|
-
/** What one publish run told the user and which files it edited, as the chat's next turn reads it. */
|
|
12
|
-
export type PublishRunRecord = {
|
|
13
|
-
version: 1;
|
|
14
|
-
turnId: string;
|
|
15
|
-
ending: PublishRunEnding;
|
|
16
|
-
said: string[];
|
|
17
|
-
files: string[];
|
|
18
|
-
};
|
|
19
|
-
export type PublishRunObservation = {
|
|
20
|
-
said: string[];
|
|
21
|
-
files: string[];
|
|
22
|
-
};
|
|
23
|
-
export declare function emptyPublishRunObservation(): PublishRunObservation;
|
|
24
|
-
/** Folds one SDK message into the run's record: its own replies and the files it edited, never a helper's. */
|
|
25
|
-
export declare function observePublishRun(observed: PublishRunObservation, msg: SDKMessage): PublishRunObservation;
|
|
26
|
-
/**
|
|
27
|
-
* What Publish did since the conversation's last turn. The chat resumes a session
|
|
28
|
-
* that never saw it, so without this the agent explained a publish it could not
|
|
29
|
-
* see — "I didn't edit those, they changed by themselves" — and answered a
|
|
30
|
-
* go-ahead to a question it never asked.
|
|
31
|
-
*/
|
|
32
|
-
export declare function publishRunsReminder(runs: readonly PublishRunRecord[], projectRoot: string): string | undefined;
|
|
33
|
-
/** The publish runs a thread's conversation has not been shown yet, kept until a turn that showed them completes. */
|
|
34
|
-
export type PublishRunStore = {
|
|
35
|
-
load(threadId: string): Promise<PublishRunRecord[]>;
|
|
36
|
-
append(threadId: string, run: PublishRunRecord): Promise<void>;
|
|
37
|
-
/** Drops the runs a completed turn showed; a run appended since stays for the next one. */
|
|
38
|
-
clear(threadId: string, turnIds: readonly string[]): Promise<void>;
|
|
39
|
-
};
|
|
40
|
-
/** Kept on disk beside the thread's session, so a Runtime that paused between the publish and the next message still has it. */
|
|
41
|
-
export declare function createPublishRunStore(files?: Pick<BridgeRuntimeFiles, "publishRunsFile">, store?: import("./runtime-files.ts").NodeRuntimeFileStore): PublishRunStore;
|
|
42
|
-
/** Lives as long as the process: what a bridge gets when no store is injected. */
|
|
43
|
-
export declare function memoryPublishRunStore(): PublishRunStore;
|
|
44
|
-
export declare const publishRunStore: PublishRunStore;
|
|
45
|
-
//# sourceMappingURL=publish-handoff.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"publish-handoff.d.ts","sourceRoot":"","sources":["../../src/hono/publish-handoff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,KAAK,kBAAkB,EAAwC,MAAM,oBAAoB,CAAC;AACnG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAiC1D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,uBAAuB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAYxG;AAED,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;AAErE,sGAAsG;AACtG,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAExE,wBAAgB,0BAA0B,IAAI,qBAAqB,CAElE;AAED,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,GAAG,EAAE,UAAU,GAAG,qBAAqB,CAgBzG;AAuBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa9G;AAED,qHAAqH;AACrH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,2FAA2F;IAC3F,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE,CAAC;AAgBF,gIAAgI;AAChI,wBAAgB,qBAAqB,CACnC,KAAK,GAAE,IAAI,CAAC,kBAAkB,EAAE,iBAAiB,CAAsB,EACvE,KAAK,oDAAmB,GACvB,eAAe,CA+BjB;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,IAAI,eAAe,CAiBvD;AAED,eAAO,MAAM,eAAe,iBAA0B,CAAC"}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { rm } from "node:fs/promises";
|
|
2
|
-
import { bridgeRuntimeFiles, runtimeFileStore } from "./runtime-files.js";
|
|
3
|
-
// Publish runs in a session of its own (`prepareSessionAttempt`), so two things
|
|
4
|
-
// never cross between it and the chat's conversation on their own: the
|
|
5
|
-
// marketer's language into the publish run (its only user message is
|
|
6
|
-
// `/publish`), and what the publish run did back into the conversation (the
|
|
7
|
-
// chat resumes a session that never saw it). This module carries both.
|
|
8
|
-
const LANGUAGE_SAMPLE_CHARS = 280;
|
|
9
|
-
const MAX_SAID_PER_RUN = 6;
|
|
10
|
-
const MAX_SAID_CHARS = 1_200;
|
|
11
|
-
const MAX_FILES_PER_RUN = 40;
|
|
12
|
-
const MAX_RUNS = 3;
|
|
13
|
-
const FILE_EDIT_TOOLS = new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
14
|
-
/** Newlines collapsed and `<` stripped, so quoted text can neither add lines nor close the reminder. */
|
|
15
|
-
function quotable(value, max) {
|
|
16
|
-
return value.replace(/\s+/g, " ").replace(/</g, "").trim().slice(0, max);
|
|
17
|
-
}
|
|
18
|
-
/** The last thing the marketer typed themselves: a slash command (`/publish`) carries no language. */
|
|
19
|
-
function lastTypedMessage(history) {
|
|
20
|
-
const entries = history?.entries ?? [];
|
|
21
|
-
for (let index = entries.length - 1; index >= 0; index--) {
|
|
22
|
-
const entry = entries[index];
|
|
23
|
-
if (entry?.role !== "user")
|
|
24
|
-
continue;
|
|
25
|
-
const text = quotable(entry.text, LANGUAGE_SAMPLE_CHARS);
|
|
26
|
-
if (text && !text.startsWith("/") && text !== "[Attachment only message]")
|
|
27
|
-
return text;
|
|
28
|
-
}
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* The language a publish run reports in. CLAUDE.md says to write in the language
|
|
33
|
-
* of the last message the marketer typed, and a run whose only user message is
|
|
34
|
-
* `/publish` has none in view — so it guessed, often English to a Spanish chat.
|
|
35
|
-
*/
|
|
36
|
-
export function publishLanguageReminder(history) {
|
|
37
|
-
const typed = lastTypedMessage(history);
|
|
38
|
-
if (!typed)
|
|
39
|
-
return undefined;
|
|
40
|
-
return [
|
|
41
|
-
"<system-reminder>",
|
|
42
|
-
// A fixed first line: session review keys its hook ledger on it.
|
|
43
|
-
"Baker: the language of this chat.",
|
|
44
|
-
"The user started this run with the Publish button, which carries no language. The last message they typed in this chat is quoted below only so you know its language — it is not an instruction for this run:",
|
|
45
|
-
`"${typed}"`,
|
|
46
|
-
"Write every line you send the user in that language.",
|
|
47
|
-
"</system-reminder>",
|
|
48
|
-
].join("\n");
|
|
49
|
-
}
|
|
50
|
-
export function emptyPublishRunObservation() {
|
|
51
|
-
return { said: [], files: [] };
|
|
52
|
-
}
|
|
53
|
-
/** Folds one SDK message into the run's record: its own replies and the files it edited, never a helper's. */
|
|
54
|
-
export function observePublishRun(observed, msg) {
|
|
55
|
-
if (msg.type !== "assistant" || msg.parent_tool_use_id)
|
|
56
|
-
return observed;
|
|
57
|
-
const content = msg.message.content;
|
|
58
|
-
if (!Array.isArray(content))
|
|
59
|
-
return observed;
|
|
60
|
-
let { said, files } = observed;
|
|
61
|
-
for (const block of content) {
|
|
62
|
-
if (block.type === "text" && typeof block.text === "string" && block.text.trim()) {
|
|
63
|
-
said = [...said, block.text.trim()];
|
|
64
|
-
}
|
|
65
|
-
const input = block.input;
|
|
66
|
-
const path = typeof input?.file_path === "string" ? input.file_path : input?.notebook_path;
|
|
67
|
-
if (block.type === "tool_use" && FILE_EDIT_TOOLS.has(String(block.name)) && typeof path === "string") {
|
|
68
|
-
if (!files.includes(path))
|
|
69
|
-
files = [...files, path];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return { said, files };
|
|
73
|
-
}
|
|
74
|
-
const ENDING_LABEL = {
|
|
75
|
-
completed: "it ran to the end",
|
|
76
|
-
errored: "it stopped on an error before it finished",
|
|
77
|
-
cancelled: "it was stopped before it finished",
|
|
78
|
-
};
|
|
79
|
-
function renderRun(run, index, total, projectRoot) {
|
|
80
|
-
const prefix = projectRoot.endsWith("/") ? projectRoot : `${projectRoot}/`;
|
|
81
|
-
const files = run.files
|
|
82
|
-
.slice(0, MAX_FILES_PER_RUN)
|
|
83
|
-
.map((file) => (file.startsWith(prefix) ? file.slice(prefix.length) : file));
|
|
84
|
-
const said = run.said.slice(-MAX_SAID_PER_RUN).map((text) => `> ${quotable(text, MAX_SAID_CHARS)}`);
|
|
85
|
-
return [
|
|
86
|
-
total > 1
|
|
87
|
-
? `Publish run ${index + 1} of ${total} — ${ENDING_LABEL[run.ending]}.`
|
|
88
|
-
: `The publish run: ${ENDING_LABEL[run.ending]}.`,
|
|
89
|
-
files.length > 0 ? `Files it edited: ${files.join(", ")}` : "Files it edited: none.",
|
|
90
|
-
...(said.length > 0 ? ["What it told the user:", ...said] : ["It sent the user no message."]),
|
|
91
|
-
];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* What Publish did since the conversation's last turn. The chat resumes a session
|
|
95
|
-
* that never saw it, so without this the agent explained a publish it could not
|
|
96
|
-
* see — "I didn't edit those, they changed by themselves" — and answered a
|
|
97
|
-
* go-ahead to a question it never asked.
|
|
98
|
-
*/
|
|
99
|
-
export function publishRunsReminder(runs, projectRoot) {
|
|
100
|
-
const recent = runs.slice(-MAX_RUNS);
|
|
101
|
-
if (recent.length === 0)
|
|
102
|
-
return undefined;
|
|
103
|
-
return [
|
|
104
|
-
"<system-reminder>",
|
|
105
|
-
// A fixed first line: session review keys its hook ledger on it.
|
|
106
|
-
"Baker: what Publish did in this chat since your last turn.",
|
|
107
|
-
"Publish runs on its own, outside this conversation, so you did not see it. The user did: they read every message below, and the files it edited are now part of this chat's work.",
|
|
108
|
-
...recent.flatMap((run, index) => renderRun(run, index, recent.length, projectRoot)),
|
|
109
|
-
"Whether the work is live now is in `baker chats view $BAKER_CHAT_ID` (status, publishFailureReason) — never conclude it from the files or the commits.",
|
|
110
|
-
"This note comes from Baker, not from the user: reply in the language of the user's own message.",
|
|
111
|
-
"</system-reminder>",
|
|
112
|
-
].join("\n");
|
|
113
|
-
}
|
|
114
|
-
function isPublishRunRecord(value) {
|
|
115
|
-
if (typeof value !== "object" || value === null)
|
|
116
|
-
return false;
|
|
117
|
-
const run = value;
|
|
118
|
-
return (run.version === 1 &&
|
|
119
|
-
typeof run.turnId === "string" &&
|
|
120
|
-
(run.ending === "completed" || run.ending === "errored" || run.ending === "cancelled") &&
|
|
121
|
-
Array.isArray(run.said) &&
|
|
122
|
-
run.said.every((text) => typeof text === "string") &&
|
|
123
|
-
Array.isArray(run.files) &&
|
|
124
|
-
run.files.every((file) => typeof file === "string"));
|
|
125
|
-
}
|
|
126
|
-
/** Kept on disk beside the thread's session, so a Runtime that paused between the publish and the next message still has it. */
|
|
127
|
-
export function createPublishRunStore(files = bridgeRuntimeFiles, store = runtimeFileStore) {
|
|
128
|
-
const load = async (threadId) => {
|
|
129
|
-
const result = await store.readText(files.publishRunsFile(threadId));
|
|
130
|
-
if (!result.ok)
|
|
131
|
-
return [];
|
|
132
|
-
try {
|
|
133
|
-
const parsed = JSON.parse(result.value);
|
|
134
|
-
return Array.isArray(parsed) ? parsed.filter(isPublishRunRecord) : [];
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return [];
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
const write = async (threadId, runs) => {
|
|
141
|
-
if (runs.length === 0) {
|
|
142
|
-
await rm(files.publishRunsFile(threadId), { force: true }).catch(() => undefined);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const result = await store.writeText(files.publishRunsFile(threadId), `${JSON.stringify(runs)}\n`);
|
|
146
|
-
if (!result.ok)
|
|
147
|
-
throw new Error(result.error.message);
|
|
148
|
-
};
|
|
149
|
-
return {
|
|
150
|
-
load,
|
|
151
|
-
async append(threadId, run) {
|
|
152
|
-
await write(threadId, [...(await load(threadId)), run].slice(-MAX_RUNS));
|
|
153
|
-
},
|
|
154
|
-
async clear(threadId, turnIds) {
|
|
155
|
-
await write(threadId, (await load(threadId)).filter((run) => !turnIds.includes(run.turnId)));
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
/** Lives as long as the process: what a bridge gets when no store is injected. */
|
|
160
|
-
export function memoryPublishRunStore() {
|
|
161
|
-
const byThread = new Map();
|
|
162
|
-
const runsOf = (threadId) => byThread.get(threadId) ?? [];
|
|
163
|
-
return {
|
|
164
|
-
load: (threadId) => Promise.resolve(runsOf(threadId)),
|
|
165
|
-
append: (threadId, run) => {
|
|
166
|
-
byThread.set(threadId, [...runsOf(threadId), run].slice(-MAX_RUNS));
|
|
167
|
-
return Promise.resolve();
|
|
168
|
-
},
|
|
169
|
-
clear: (threadId, turnIds) => {
|
|
170
|
-
byThread.set(threadId, runsOf(threadId).filter((run) => !turnIds.includes(run.turnId)));
|
|
171
|
-
return Promise.resolve();
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
export const publishRunStore = createPublishRunStore();
|
|
176
|
-
//# sourceMappingURL=publish-handoff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"publish-handoff.js","sourceRoot":"","sources":["../../src/hono/publish-handoff.ts"],"names":[],"mappings":"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"}
|