feat(story-mode): a helper's own steps, from its transcript

GET /api/sessions/:id/story/helpers/:agentId draws one helper (an Agent call)
as a page from its own transcript, <conversation>/subagents/agent-<id>.jsonl
beside the session's, with the type, description and finished flag from its
.meta.json. The file is derived from the session's own transcript path and an
id checked against [A-Za-z0-9_-]{1,64}; a helper with no file yet is page
null, not an error. The reducer gains a sidechain mode (every helper line is a
sidechain line) and keeps the agentId of Agent results, so the main page links
each helper to its steps. Same gates and ETag/304 as /story, now shared.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-18 09:41:39 +02:00
1 parent fc279f998c
commit fb71180632
5 files changed
+261 -63

No files matched your search

+11
View File
@@ -82,6 +82,8 @@ export interface StoryHelper {
result?: string;
toolUses?: number;
durationMs?: number;
/** Claude Code's id for the helper; its own steps are at `GET /api/sessions/:id/story/helpers/<agentId>`. */
agentId?: string;
}
export interface StoryTests {
@@ -164,6 +166,15 @@ export interface StoryPage extends StoryTurnSummary {
helpers: number;
}
/** `GET /api/sessions/:id/story/helpers/:agentId`: one helper's own steps, as one page. */
export type StoryHelperResponse =
| { supported: false; reason: string }
| {
supported: true;
helper: { agentId: string; type?: string; description?: string; finished?: boolean };
page: StoryPage | null;
};
export type StoryResponse =
| { supported: false; reason: string }
| { supported: true; turns: StoryTurnSummary[]; page: StoryPage | null };