@peasant-labs/fairtrade 0.0.17 → 0.0.19

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.
Files changed (35) hide show
  1. package/README.md +11 -2
  2. package/THIRD_PARTY_NOTICES.md +31 -0
  3. package/dist/lib/{InUseShell-CY5Acw6t.js → GraphLegend-BB0V2w59.js} +780 -558
  4. package/dist/lib/commons.js +139 -139
  5. package/dist/lib/components.css +1 -1
  6. package/dist/lib/graph.css +1 -1
  7. package/dist/lib/graph.js +921 -359
  8. package/dist/lib/types/BrandMark.d.ts +2 -2
  9. package/dist/lib/types/commons/providers.d.ts +1 -1
  10. package/dist/lib/types/graph/index.d.ts +16 -0
  11. package/dist/lib/types/provider-policy.d.ts +2 -2
  12. package/dist/lib/types/transcript/OutcomeChip.d.ts +18 -0
  13. package/dist/lib/types/transcript/UsageDisclosure.d.ts +8 -0
  14. package/dist/lib/types/transcript/analytics.d.ts +3 -6
  15. package/dist/lib/types/transcript/graph/engine/GraphControls.d.ts +13 -0
  16. package/dist/lib/types/transcript/graph/engine/TrajectoryGraph.d.ts +18 -0
  17. package/dist/lib/types/transcript/graph/engine/TrajectoryGraphLegend.d.ts +18 -0
  18. package/dist/lib/types/transcript/graph/engine/constants.d.ts +37 -0
  19. package/dist/lib/types/transcript/graph/engine/index.d.ts +23 -0
  20. package/dist/lib/types/transcript/graph/engine/nodes/SubagentBranchNode.d.ts +11 -0
  21. package/dist/lib/types/transcript/graph/engine/nodes/ToolPillNode.d.ts +11 -0
  22. package/dist/lib/types/transcript/graph/engine/nodes/TurnCardNode.d.ts +11 -0
  23. package/dist/lib/types/transcript/graph/engine/turnsToFlow.d.ts +47 -0
  24. package/dist/lib/types/transcript/graph/engine/types.d.ts +131 -0
  25. package/dist/lib/types/transcript/graph/engine/useCanvasSync.d.ts +17 -0
  26. package/dist/lib/types/transcript/index.d.ts +5 -0
  27. package/dist/lib/types/transcript/state-capabilities.d.ts +2 -1
  28. package/dist/lib/types/transcript/time.d.ts +22 -0
  29. package/dist/lib/types/transcript/title.d.ts +48 -0
  30. package/dist/lib/types/transcript/turnNav.d.ts +9 -0
  31. package/dist/lib/types/transcript/usage.d.ts +19 -0
  32. package/dist/lib/types/transcript/view-model.d.ts +61 -0
  33. package/dist/lib/{ui-yIg-1YXY.js → ui-DkPbLhcp.js} +2872 -2731
  34. package/dist/lib/ui.js +4 -4
  35. package/package.json +29 -8
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * resolve any accepted name/alias to a canonical mark key, or null when unknown.
3
3
  * @param {string} name
4
- * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike')|null}
4
+ * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi')|null}
5
5
  */
6
- export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike") | null;
6
+ export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi") | null;
7
7
  /**
8
8
  * BrandMark - a single-color, currentColor-tinted company/provider logo.
9
9
  *
@@ -4,4 +4,4 @@
4
4
  export function formatProvider(provider: unknown): string;
5
5
  /** @param {import('@peasant-labs/schema').Harness} provider */
6
6
  export function providerLabel(provider: import("@peasant-labs/schema").Harness): string;
7
- export const PROVIDER_LABEL: Readonly<Record<"strike" | "cursor" | "claude-code" | "gemini-cli" | "codex" | "opencode" | "antigravity", string>>;
7
+ export const PROVIDER_LABEL: Readonly<Record<"strike" | "cursor" | "claude-code" | "gemini-cli" | "codex" | "opencode" | "antigravity" | "pi", string>>;
@@ -54,6 +54,20 @@ export type TimelineHighlight = import("./codeMapState.js").TimelineHighlight;
54
54
  export type RankInputNode = import("./ranking.js").RankInputNode;
55
55
  export type RankedRowData = import("./ranking.js").RankedRow;
56
56
  export type DebtState = import("./ranking.js").DebtState;
57
+ export type TrajectoryGraphProps = import("../transcript/graph/engine/index.js").TrajectoryGraphProps;
58
+ export type GraphControlsProps = import("../transcript/graph/engine/index.js").GraphControlsProps;
59
+ export type TrajectoryGraphLegendProps = import("../transcript/graph/engine/index.js").TrajectoryGraphLegendProps;
60
+ export type TurnsToFlowOptions = import("../transcript/graph/engine/index.js").TurnsToFlowOptions;
61
+ export type TrajectoryCanvasProps = import("../transcript/graph/engine/index.js").TrajectoryCanvasProps;
62
+ export type TurnNodeData = import("../transcript/graph/engine/index.js").TurnNodeData;
63
+ export type ToolCallNodeData = import("../transcript/graph/engine/index.js").ToolCallNodeData;
64
+ export type SubagentLaneData = import("../transcript/graph/engine/index.js").SubagentLaneData;
65
+ export type NavCommand = import("../transcript/graph/engine/index.js").NavCommand;
66
+ export type EdgeType = import("../transcript/graph/engine/index.js").EdgeType;
67
+ export type CanvasEdgeData = import("../transcript/graph/engine/index.js").CanvasEdgeData;
68
+ export type FlowNode = import("../transcript/graph/engine/index.js").FlowNode;
69
+ export type FlowEdge = import("../transcript/graph/engine/index.js").FlowEdge;
70
+ export type FlowGraph = import("../transcript/graph/engine/index.js").FlowGraph;
57
71
  export { default as CodeMap, codeMapPayloadToMapData } from "./CodeMap.jsx";
58
72
  export { default as CodeMapComposition, DefaultMapLegend } from "./CodeMapComposition.jsx";
59
73
  export { CODE_MAP_STATE_VERSION, CODE_MAP_VIEWPORT_SCALE, isCodeMapViewportScale, codeMapStatesEqual, createCodeMapState, reduceCodeMapState, deriveCodeMapView, deriveTimelineHighlight, resolveEscapeAction } from "./codeMapState.js";
@@ -62,3 +76,5 @@ export { buildChangesGraph, humanizeAge } from "./changeGraph.js";
62
76
  export { DOI_WEIGHTS, DEBT_VIEWED, COVERAGE_CAP, RECENCY_HALF_LIFE_DAYS, RANK_FLOOR, RANK_CAP, SCENT_TAGS, debtState, debt, coverage, hunkClears, partialReadHoverText, debtHoverText, scentTagsFor, rankMapNodesIntrinsic, deriveRankedRows, rankMapNodes, gateRankedRows } from "./ranking.js";
63
77
  export { assertChangeDetailPayloadEnums, assertChangeDiffPayloadEnums, assertCodeMapPayloadEnums, MAP_NODE_KINDS, CHANGE_BINDINGS, EDGE_VIOLATION_KINDS, FILE_CHANGE_STATUSES, DIFF_LINE_KINDS } from "./types.js";
64
78
  export { MapNodeKind, AllMapNodeKinds, isMapNodeKind, ChangeBinding, AllChangeBindings, isChangeBinding, EdgeViolationKind, AllEdgeViolationKinds, isEdgeViolationKind, FileChangeStatus, AllFileChangeStatuses, isFileChangeStatus, DiffLineKind, AllDiffLineKinds, isDiffLineKind, InsightKind, AllInsightKinds, isInsightKind, InsightProvenance, AllInsightProvenances, isInsightProvenance, ReadAttributionState, AllReadAttributionStates, isReadAttributionState, ReadStateGrade, AllReadStateGrades, isReadStateGrade } from "@peasant-labs/schema";
79
+ export { TrajectoryGraph, GraphControls, TrajectoryGraphLegend, TurnCardNode, ToolPillNode, SubagentBranchNode, useCanvasSync, turnsToFlow, computeLaneHeaders, NODE_DIMENSIONS, EDGE_DEFAULTS } from "../transcript/graph/engine/index.js";
80
+ export { GraphTurnNode, GraphToolNode, GraphSubagentBranch, GraphLegend, GRAPH_LEGEND_ITEMS } from "../transcript/graph/index.js";
@@ -12,7 +12,7 @@ export function providerBrand(harness: Harness): ProviderBrand;
12
12
  /** @param {Harness} harness @returns {ProviderAccent} */
13
13
  export function providerAccent(harness: Harness): ProviderAccent;
14
14
  /** @typedef {import('@peasant-labs/schema').Harness} Harness */
15
- /** @typedef {'claude'|'gemini'|'openai'|'opencode'|'cursor'|'strike'} ProviderBrand */
15
+ /** @typedef {'claude'|'gemini'|'openai'|'opencode'|'cursor'|'strike'|'pi'} ProviderBrand */
16
16
  /** @typedef {'amber'|'teal'|'olive'|'mauve'|'clay'} ProviderAccent */
17
17
  /** @type {readonly Harness[]} */
18
18
  export const PROVIDER_HARNESSES: readonly Harness[];
@@ -23,5 +23,5 @@ export const PROVIDER_BRANDS: Readonly<Record<Harness, ProviderBrand>>;
23
23
  /** @type {Readonly<Record<Harness, ProviderAccent>>} */
24
24
  export const PROVIDER_ACCENTS: Readonly<Record<Harness, ProviderAccent>>;
25
25
  export type Harness = import("@peasant-labs/schema").Harness;
26
- export type ProviderBrand = "claude" | "gemini" | "openai" | "opencode" | "cursor" | "strike";
26
+ export type ProviderBrand = "claude" | "gemini" | "openai" | "opencode" | "cursor" | "strike" | "pi";
27
27
  export type ProviderAccent = "amber" | "teal" | "olive" | "mauve" | "clay";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Render a session outcome as a semantically-toned chip. Renders nothing for
3
+ * an unknown / absent outcome, so a caller can gate on the element rather than
4
+ * pre-checking the value (matching the prior inline `session.outcome &&` guard).
5
+ *
6
+ * @param {object} props
7
+ * @param {string} [props.outcome] outcome / label string — see `OUTCOME_VISUALS`
8
+ * @param {string} [props.className] extra classes appended after the chip classes
9
+ */
10
+ export default function TranscriptOutcomeChip({ outcome, className }: {
11
+ outcome?: string;
12
+ className?: string;
13
+ }): import("react").JSX.Element;
14
+ export type OutcomeVisual = {
15
+ icon: React.ElementType;
16
+ chipTone: "ok" | "warn" | "err";
17
+ label: string;
18
+ };
@@ -0,0 +1,8 @@
1
+ /** @param {{usage?: import('@peasant-labs/schema').UsageDetail}} props */
2
+ export default function UsageDisclosure({ usage }: {
3
+ usage?: import("@peasant-labs/schema").UsageDetail;
4
+ }): import("react").JSX.Element;
5
+ /** @param {{scopes?: import('./view-model.js').UsageScopeVM[]}} props */
6
+ export function UsageScopes({ scopes }: {
7
+ scopes?: import("./view-model.js").UsageScopeVM[];
8
+ }): import("react").JSX.Element;
@@ -9,8 +9,7 @@
9
9
  /**
10
10
  * A "task" is the span from a top-level user prompt up to (but not including)
11
11
  * the next one — one turn of human↔agent collaboration. The shape is the
12
- * canonical `TaskGroup` the transcript-browser already exports, kept stable for
13
- * back-compat re-export.
12
+ * canonical `TaskGroup` shape, kept stable for consumer back-compat.
14
13
  * @typedef {object} TaskGroup
15
14
  * @property {number} startIndex display position of the starting prompt
16
15
  * @property {number} endIndex display position of the last turn (inclusive)
@@ -123,8 +122,7 @@ export type TranscriptAnalyticsVM = import("./view-model.js").TranscriptAnalytic
123
122
  /**
124
123
  * A "task" is the span from a top-level user prompt up to (but not including)
125
124
  * the next one — one turn of human↔agent collaboration. The shape is the
126
- * canonical `TaskGroup` the transcript-browser already exports, kept stable for
127
- * back-compat re-export.
125
+ * canonical `TaskGroup` shape, kept stable for consumer back-compat.
128
126
  */
129
127
  export type TaskGroup = {
130
128
  /**
@@ -176,8 +174,7 @@ export type PersonalMedians = {
176
174
  };
177
175
  /**
178
176
  * A session sample for personal-median computation — the QualitySession subset
179
- * the medians read. Kept structural so the transcript-browser `QualitySession`
180
- * is assignable for back-compat.
177
+ * the medians read. Kept structural for consumer back-compat.
181
178
  */
182
179
  export type PersonalMedianSession = {
183
180
  totalTokens: number;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @typedef {object} GraphControlsProps
3
+ * @property {string} [className]
4
+ */
5
+ /**
6
+ * The trajectory-graph viewport controls. Must render inside a `<ReactFlowProvider>`.
7
+ * @param {GraphControlsProps} props
8
+ * @returns {JSX.Element}
9
+ */
10
+ export function GraphControls({ className }: GraphControlsProps): JSX.Element;
11
+ export type GraphControlsProps = {
12
+ className?: string;
13
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @typedef {import('./types.js').TrajectoryCanvasProps & {
3
+ * provider?: import('@peasant-labs/schema').Harness,
4
+ * className?: string,
5
+ * }} TrajectoryGraphProps
6
+ */
7
+ /**
8
+ * The trajectory graph. Owns its own `<ReactFlowProvider>`, so a host can mount
9
+ * it directly (for example into the transcript viewer's graph slot).
10
+ * @param {TrajectoryGraphProps} props
11
+ * @returns {JSX.Element}
12
+ */
13
+ export function TrajectoryGraph(props: TrajectoryGraphProps): JSX.Element;
14
+ export type TrajectoryGraphProps = import("./types.js").TrajectoryCanvasProps & {
15
+ provider?: import("@peasant-labs/schema").Harness;
16
+ className?: string;
17
+ };
18
+ export type TurnNodeData = import("./types.js").TurnNodeData;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @typedef {object} TrajectoryGraphLegendProps
3
+ * @property {import('@peasant-labs/schema').Harness} [provider]
4
+ * canonical harness; sets the assistant swatch accent + label to match the turn cards
5
+ * @property {string} [className]
6
+ */
7
+ /**
8
+ * @param {TrajectoryGraphLegendProps} props
9
+ * @returns {JSX.Element}
10
+ */
11
+ export function TrajectoryGraphLegend({ provider, className }: TrajectoryGraphLegendProps): JSX.Element;
12
+ export type TrajectoryGraphLegendProps = {
13
+ /**
14
+ * canonical harness; sets the assistant swatch accent + label to match the turn cards
15
+ */
16
+ provider?: import("@peasant-labs/schema").Harness;
17
+ className?: string;
18
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Canvas geometry for the trajectory graph, in canvas units.
3
+ * @type {Readonly<{
4
+ * turnWidth: number, turnBaseHeight: number, toolCallWidth: number,
5
+ * toolCallHeight: number, laneGap: number, verticalGap: number,
6
+ * toolSideGap: number, subagentIndent: number, phasePadding: number,
7
+ * }>}
8
+ */
9
+ export const NODE_DIMENSIONS: Readonly<{
10
+ turnWidth: number;
11
+ turnBaseHeight: number;
12
+ toolCallWidth: number;
13
+ toolCallHeight: number;
14
+ laneGap: number;
15
+ verticalGap: number;
16
+ toolSideGap: number;
17
+ subagentIndent: number;
18
+ phasePadding: number;
19
+ }>;
20
+ /**
21
+ * Default edge stroke roles. Colours are token-backed custom properties
22
+ * (`--edge` / `--edge-error`) declared on the `.tb-graph` root.
23
+ * @type {Readonly<{
24
+ * sequentialColor: string, sequentialColorDark: string, sequentialWidth: number,
25
+ * phaseTransitionWidth: number, subagentSpawnColor: string,
26
+ * subagentReturnColor: string, errorColor: string,
27
+ * }>}
28
+ */
29
+ export const EDGE_DEFAULTS: Readonly<{
30
+ sequentialColor: string;
31
+ sequentialColorDark: string;
32
+ sequentialWidth: number;
33
+ phaseTransitionWidth: number;
34
+ subagentSpawnColor: string;
35
+ subagentReturnColor: string;
36
+ errorColor: string;
37
+ }>;
@@ -0,0 +1,23 @@
1
+ export { TrajectoryGraph } from "./TrajectoryGraph.jsx";
2
+ export { GraphControls } from "./GraphControls.jsx";
3
+ export { TrajectoryGraphLegend } from "./TrajectoryGraphLegend.jsx";
4
+ export { TurnCardNode } from "./nodes/TurnCardNode.jsx";
5
+ export { ToolPillNode } from "./nodes/ToolPillNode.jsx";
6
+ export { SubagentBranchNode } from "./nodes/SubagentBranchNode.jsx";
7
+ export { useCanvasSync } from "./useCanvasSync.js";
8
+ export type TrajectoryGraphProps = import("./TrajectoryGraph.jsx").TrajectoryGraphProps;
9
+ export type GraphControlsProps = import("./GraphControls.jsx").GraphControlsProps;
10
+ export type TrajectoryGraphLegendProps = import("./TrajectoryGraphLegend.jsx").TrajectoryGraphLegendProps;
11
+ export type TurnsToFlowOptions = import("./turnsToFlow.js").TurnsToFlowOptions;
12
+ export type TrajectoryCanvasProps = import("./types.js").TrajectoryCanvasProps;
13
+ export type TurnNodeData = import("./types.js").TurnNodeData;
14
+ export type ToolCallNodeData = import("./types.js").ToolCallNodeData;
15
+ export type SubagentLaneData = import("./types.js").SubagentLaneData;
16
+ export type NavCommand = import("./types.js").NavCommand;
17
+ export type EdgeType = import("./types.js").EdgeType;
18
+ export type CanvasEdgeData = import("./types.js").CanvasEdgeData;
19
+ export type FlowNode = import("./types.js").FlowNode;
20
+ export type FlowEdge = import("./types.js").FlowEdge;
21
+ export type FlowGraph = import("./types.js").FlowGraph;
22
+ export { turnsToFlow, computeLaneHeaders } from "./turnsToFlow.js";
23
+ export { NODE_DIMENSIONS, EDGE_DEFAULTS } from "./constants.js";
@@ -0,0 +1,11 @@
1
+ export const SubagentBranchNode: import("react").MemoExoticComponent<typeof SubagentBranchNodeImpl>;
2
+ export type SubagentLaneData = import("../types.js").SubagentLaneData;
3
+ /** @typedef {import('../types.js').SubagentLaneData} SubagentLaneData */
4
+ /**
5
+ * @param {{ data: SubagentLaneData }} props
6
+ * @returns {JSX.Element}
7
+ */
8
+ declare function SubagentBranchNodeImpl({ data }: {
9
+ data: SubagentLaneData;
10
+ }): JSX.Element;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ export const ToolPillNode: import("react").MemoExoticComponent<typeof ToolPillNodeImpl>;
2
+ export type ToolCallNodeData = import("../types.js").ToolCallNodeData;
3
+ /** @typedef {import('../types.js').ToolCallNodeData} ToolCallNodeData */
4
+ /**
5
+ * @param {{ data: ToolCallNodeData }} props
6
+ * @returns {JSX.Element}
7
+ */
8
+ declare function ToolPillNodeImpl({ data }: {
9
+ data: ToolCallNodeData;
10
+ }): JSX.Element;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ export const TurnCardNode: import("react").MemoExoticComponent<typeof TurnCardNodeImpl>;
2
+ export type TurnNodeData = import("../types.js").TurnNodeData;
3
+ /**
4
+ * @param {{ data: TurnNodeData, selected?: boolean }} props
5
+ * @returns {JSX.Element}
6
+ */
7
+ declare function TurnCardNodeImpl({ data, selected }: {
8
+ data: TurnNodeData;
9
+ selected?: boolean;
10
+ }): JSX.Element;
11
+ export {};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @typedef {object} TurnsToFlowOptions
3
+ * @property {TurnDetail[]} turns
4
+ * @property {Map<number, ToolCallVM[]>} [toolVMsByTurn] cooked tool calls by turn index; supplies each tool node's preview
5
+ * @property {Phase[]} phases
6
+ * @property {TranscriptAnnotation[]} annotations
7
+ * @property {number[]} searchMatches
8
+ * @property {Set<number>} filteredIndices
9
+ * @property {string} [searchQuery]
10
+ * @property {Set<number>} [selectedTurns]
11
+ */
12
+ /**
13
+ * Build the trajectory graph's nodes and edges from a turn list.
14
+ * @param {TurnsToFlowOptions} options
15
+ * @returns {FlowGraph}
16
+ */
17
+ export function turnsToFlow({ turns, toolVMsByTurn, phases, annotations, searchMatches, filteredIndices, searchQuery, selectedTurns, }: TurnsToFlowOptions): FlowGraph;
18
+ /**
19
+ * Compute the lane-header nodes for the subagent swimlanes. The main lane
20
+ * (depth 0) carries no header.
21
+ * @param {FlowNode[]} turnNodes
22
+ * @returns {FlowNode[]}
23
+ */
24
+ export function computeLaneHeaders(turnNodes: FlowNode[]): FlowNode[];
25
+ export type TurnsToFlowOptions = {
26
+ turns: TurnDetail[];
27
+ /**
28
+ * cooked tool calls by turn index; supplies each tool node's preview
29
+ */
30
+ toolVMsByTurn?: Map<number, ToolCallVM[]>;
31
+ phases: Phase[];
32
+ annotations: TranscriptAnnotation[];
33
+ searchMatches: number[];
34
+ filteredIndices: Set<number>;
35
+ searchQuery?: string;
36
+ selectedTurns?: Set<number>;
37
+ };
38
+ export type TurnDetail = import("./types.js").TurnDetail;
39
+ export type Phase = import("./types.js").Phase;
40
+ export type PhaseType = import("./types.js").PhaseType;
41
+ export type TranscriptAnnotation = import("./types.js").TranscriptAnnotation;
42
+ export type ToolCallVM = import("./types.js").ToolCallVM;
43
+ export type TurnNodeData = import("./types.js").TurnNodeData;
44
+ export type ToolCallNodeData = import("./types.js").ToolCallNodeData;
45
+ export type FlowNode = import("./types.js").FlowNode;
46
+ export type FlowEdge = import("./types.js").FlowEdge;
47
+ export type FlowGraph = import("./types.js").FlowGraph;
@@ -0,0 +1,131 @@
1
+ export type TurnDetail = import("@peasant-labs/schema").TurnDetail;
2
+ export type ToolCallDetail = import("@peasant-labs/schema").ToolCallDetail;
3
+ export type Harness = import("@peasant-labs/schema").Harness;
4
+ export type TranscriptAnnotation = import("../../analytics.js").TranscriptAnnotation;
5
+ export type Phase = import("../../analytics.js").PhaseSegment;
6
+ export type PhaseType = import("../../analytics.js").PhaseType;
7
+ export type ToolCallVM = import("../../view-model.js").ToolCallVM;
8
+ /**
9
+ * A positioned graph node in canvas coordinates.
10
+ */
11
+ export type FlowNode = {
12
+ id: string;
13
+ /**
14
+ * custom node type key ('turn' | 'toolCall' | 'subagentLane')
15
+ */
16
+ type?: string;
17
+ /**
18
+ * canvas coordinates
19
+ */
20
+ position: {
21
+ x: number;
22
+ y: number;
23
+ };
24
+ /**
25
+ * the node's cooked payload
26
+ */
27
+ data: Record<string, unknown>;
28
+ style?: Record<string, unknown>;
29
+ selectable?: boolean;
30
+ draggable?: boolean;
31
+ };
32
+ /**
33
+ * A connector between two `FlowNode`s.
34
+ */
35
+ export type FlowEdge = {
36
+ id: string;
37
+ source: string;
38
+ target: string;
39
+ sourceHandle?: string;
40
+ targetHandle?: string;
41
+ type?: string;
42
+ animated?: boolean;
43
+ style?: Record<string, unknown>;
44
+ data?: CanvasEdgeData;
45
+ };
46
+ /**
47
+ * How an edge came about. Drives stroke colour, width, and dash pattern.
48
+ */
49
+ export type EdgeType = "sequential" | "phase-transition" | "spawn" | "return" | "turn-to-tool" | "error";
50
+ export type CanvasEdgeData = {
51
+ edgeType: EdgeType;
52
+ phaseColor?: string;
53
+ };
54
+ /**
55
+ * The mapper's output: a complete node-link graph.
56
+ */
57
+ export type FlowGraph = {
58
+ nodes: FlowNode[];
59
+ edges: FlowEdge[];
60
+ };
61
+ export type TurnNodeData = {
62
+ turn: TurnDetail;
63
+ annotations: TranscriptAnnotation[];
64
+ phaseType: PhaseType | undefined;
65
+ isSearchMatch: boolean;
66
+ isFilteredOut: boolean;
67
+ isSelected: boolean;
68
+ turnNumber: number;
69
+ tokensCumulative: number;
70
+ searchQuery?: string;
71
+ /**
72
+ * threaded in by the graph so the card accent matches the host
73
+ */
74
+ provider?: Harness;
75
+ };
76
+ export type ToolCallNodeData = {
77
+ turnIndex: number;
78
+ toolCalls: ToolCallDetail[];
79
+ /**
80
+ * cooked one-line previews keyed by tool-call id (the adapter's `ToolCallVM.preview`),
81
+ * threaded in so the node renders the same arg summary as the list view WITHOUT
82
+ * parsing wire (`ToolCallDetail.arguments`) in the node
83
+ */
84
+ previewById: Record<string, string>;
85
+ totalDurationMs: number;
86
+ hasError: boolean;
87
+ isFilteredOut: boolean;
88
+ phaseType: PhaseType | undefined;
89
+ };
90
+ export type SubagentLaneData = {
91
+ depth: number;
92
+ agentName: string;
93
+ };
94
+ /**
95
+ * A navigation command carrying a nonce, so the same target can be re-triggered.
96
+ */
97
+ export type NavCommand = {
98
+ target: number;
99
+ seq: number;
100
+ };
101
+ export type TrajectoryCanvasProps = {
102
+ turns: TurnDetail[];
103
+ /**
104
+ * cooked tool calls keyed by turn index; absent means tool nodes render without arg previews
105
+ */
106
+ toolVMsByTurn?: Map<number, ToolCallVM[]>;
107
+ filteredTurns: TurnDetail[];
108
+ phases: Phase[];
109
+ annotations: TranscriptAnnotation[];
110
+ searchMatches: number[];
111
+ searchQuery?: string;
112
+ activeMatchIndex?: number;
113
+ /**
114
+ * external command to pan the canvas to a turn index
115
+ */
116
+ focusTurn?: NavCommand;
117
+ /**
118
+ * external command to fit the canvas to a phase index
119
+ */
120
+ focusPhase?: NavCommand;
121
+ onPhaseActivate?: (phaseIndex: number) => void;
122
+ onViewportChange?: (range: {
123
+ start: number;
124
+ end: number;
125
+ }) => void;
126
+ /**
127
+ * selected turn indices, for marquee highlighting
128
+ */
129
+ selectedTurns?: Set<number>;
130
+ onMarqueeSelect?: (indices: number[]) => void;
131
+ };
@@ -0,0 +1,17 @@
1
+ /** @typedef {import('./types.js').TurnDetail} TurnDetail */
2
+ /** @typedef {import('./types.js').Phase} Phase */
3
+ /** @typedef {import('./types.js').TurnNodeData} TurnNodeData */
4
+ /**
5
+ * Focus helpers bound to the enclosing `<ReactFlowProvider>`.
6
+ * @param {Phase[]} phases
7
+ * @param {TurnDetail[]} turns
8
+ * @param {(phaseIndex: number) => void} [onPhaseActivate]
9
+ * @returns {{ focusPhase: (phaseIndex: number) => void, focusTurn: (turnIndex: number) => void }}
10
+ */
11
+ export function useCanvasSync(phases: Phase[], turns: TurnDetail[], onPhaseActivate?: (phaseIndex: number) => void): {
12
+ focusPhase: (phaseIndex: number) => void;
13
+ focusTurn: (turnIndex: number) => void;
14
+ };
15
+ export type TurnDetail = import("./types.js").TurnDetail;
16
+ export type Phase = import("./types.js").Phase;
17
+ export type TurnNodeData = import("./types.js").TurnNodeData;
@@ -1,10 +1,12 @@
1
1
  export { TOOL_GROUPS } from "./view-model.js";
2
+ export { nextNavTurn } from "./turnNav.js";
2
3
  export { default as TranscriptTurnCard } from "./TurnCard.jsx";
3
4
  export { default as TranscriptThinking } from "./Thinking.jsx";
4
5
  export { default as TranscriptMarkdown } from "./Markdown.jsx";
5
6
  export { default as TranscriptToolCall } from "./ToolCall.jsx";
6
7
  export { default as TranscriptToolBody } from "./ToolBody.jsx";
7
8
  export { default as TranscriptTaskBody } from "./TaskBody.jsx";
9
+ export { default as TranscriptOutcomeChip } from "./OutcomeChip.jsx";
8
10
  export { default as TranscriptViewer } from "./TranscriptViewer.jsx";
9
11
  export { default as TranscriptOutlineRail } from "./OutlineRail.jsx";
10
12
  export { default as TranscriptFiltersRail } from "./FiltersRail.jsx";
@@ -61,6 +63,7 @@ export type FileEntryVM = import("./view-model.js").FileEntryVM;
61
63
  export type TaskGroupVM = import("./view-model.js").TaskGroupVM;
62
64
  export type HighlightVM = import("./view-model.js").HighlightVM;
63
65
  export type AnnotationVM = import("./view-model.js").AnnotationVM;
66
+ export type TurnLabel = import("./view-model.js").TurnLabel;
64
67
  export type FilterIndexVM = import("./view-model.js").FilterIndexVM;
65
68
  export type PhaseVM = import("./view-model.js").PhaseVM;
66
69
  export type ScorecardBandVM = import("./view-model.js").ScorecardBandVM;
@@ -68,5 +71,7 @@ export type TranscriptAnalyticsVM = import("./view-model.js").TranscriptAnalytic
68
71
  export { ROLES, ENTRY_TYPES, TOOL_CALL_KINDS, STOP_REASONS, SESSION_OUTCOMES, HARNESSES } from "./wire-types.js";
69
72
  export { adaptTranscript, prefilterTurns, diffLines } from "./adapter.js";
70
73
  export { computeTasks, computeTurnLabels, buildTaskWaterfall, annotateTranscript, computePersonalMedians, detectPhases, assessScorecard, computeAnalytics, computeTaskGroups, phaseLabel } from "./analytics.js";
74
+ export { formatRelative, formatDurationMins, formatDateLong } from "./time.js";
75
+ export { summarizePrompt, composeSessionTitle, projectLabel } from "./title.js";
71
76
  export { default as TranscriptDiffEntryCard, DiffHunks as TranscriptDiffHunks } from "./DiffEntryCard.jsx";
72
77
  export { advanceTranscriptInitialPositionConsumption, normalizeTranscriptInitialPosition, resolveTranscriptInitialPosition, shouldApplyTranscriptInitialPosition, transcriptInitialPositionReadiness, transcriptInitialPositionToken } from "./initial-position.js";
@@ -91,7 +91,8 @@ export type ViewerCallbacks = {
91
91
  /**
92
92
  * What the `graphSlot` render-prop receives. The composite owns NO graph engine
93
93
  * (no `@xyflow` dependency); in `viewMode: 'graph'` it hands the consumer this
94
- * cooked context and renders whatever the consumer returns (transcript-browser plugs its
94
+ * cooked context and renders whatever the consumer returns (a consuming app plugs
95
+ * fairtrade's own `/graph`
95
96
  */
96
97
  export type GraphSlotContext = {
97
98
  viewModel: import("./view-model.js").TranscriptViewModel;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Human-readable relative time: "3m ago", "2h ago", "4d ago", "Jan 12".
3
+ *
4
+ * @param {string} iso an ISO 8601 timestamp
5
+ * @param {number} [now] reference "now" in epoch millis (defaults to `Date.now()`; pass explicitly for deterministic tests)
6
+ * @returns {string}
7
+ */
8
+ export function formatRelative(iso: string, now?: number): string;
9
+ /**
10
+ * A duration expressed in minutes → "1h 16m" / "9m" / "42s".
11
+ *
12
+ * @param {number | undefined} mins
13
+ * @returns {string}
14
+ */
15
+ export function formatDurationMins(mins: number | undefined): string;
16
+ /**
17
+ * "Jan 12, 4:23 PM" — long datetime for tooltips.
18
+ *
19
+ * @param {string} iso
20
+ * @returns {string}
21
+ */
22
+ export function formatDateLong(iso: string): string;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Produce a short, human-readable summary of a raw prompt. Heuristic, in order:
3
+ * 1. Strip leading <system-reminder> blocks and leading fenced code blocks.
4
+ * 2. Pull out a <command-name> (e.g. `/mcp`) if present, keep following prose.
5
+ * 3. Strip remaining XML-ish tags, collapse whitespace, take the first sentence.
6
+ * 4. Capitalize the first letter and cap at `limit` chars with `…`.
7
+ *
8
+ * @param {string | undefined} raw
9
+ * @param {number} [limit]
10
+ * @returns {string}
11
+ */
12
+ export function summarizePrompt(raw: string | undefined, limit?: number): string;
13
+ /**
14
+ * Last path segment of a project string. `/Users/x/Projects/phaze` → `phaze`.
15
+ * Falls back to the whole string if there's no separator. Returns `''` when the
16
+ * input is empty/undefined.
17
+ *
18
+ * @param {string | undefined} project
19
+ * @returns {string}
20
+ */
21
+ export function projectLabel(project: string | undefined): string;
22
+ /**
23
+ * Compose the session detail h1.
24
+ *
25
+ * • {project}: {Summary} — project + meaningful prompt
26
+ * • {project} · {shortId} — project, no usable prompt
27
+ * • {shortId} — {Summary} — no project, but a prompt
28
+ * • Session {shortId} — nothing useful at all
29
+ *
30
+ * The full prompt text (or composed title) is returned alongside as a tooltip
31
+ * string so `<h1 title=…>` can expose the raw prompt on hover.
32
+ *
33
+ * @param {object} args
34
+ * @param {string} args.id
35
+ * @param {string | undefined} args.project
36
+ * @param {string | undefined} args.promptContent
37
+ * @param {number} [args.limit]
38
+ * @returns {{ title: string, tooltip: string }}
39
+ */
40
+ export function composeSessionTitle(args: {
41
+ id: string;
42
+ project: string | undefined;
43
+ promptContent: string | undefined;
44
+ limit?: number;
45
+ }): {
46
+ title: string;
47
+ tooltip: string;
48
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resolve the next visible turn index for a keyboard-nav step.
3
+ *
4
+ * @param {readonly number[]} turnIndices ordered visible turn indices (display order)
5
+ * @param {number | undefined} current the current anchor turn (typically the top visible turn)
6
+ * @param {1 | -1} dir +1 = down/next, -1 = up/prev
7
+ * @returns {number | undefined} the turn to move to; `undefined` when there are no turns
8
+ */
9
+ export function nextNavTurn(turnIndices: readonly number[], current: number | undefined, dir: 1 | -1): number | undefined;
@@ -0,0 +1,19 @@
1
+ /** @param {import('@peasant-labs/schema').TurnDetail[]} turns
2
+ * @returns {import('./view-model.js').UsageScopeVM[]} */
3
+ export function aggregateUsage(turns: import("@peasant-labs/schema").TurnDetail[]): import("./view-model.js").UsageScopeVM[];
4
+ export const TOKEN_FIELDS: Readonly<{
5
+ input: "input";
6
+ output: "output";
7
+ cacheRead: "cache read";
8
+ cacheWrite: "cache write";
9
+ cacheWrite1h: "cache write 1h (subset)";
10
+ reasoning: "reasoning (subset)";
11
+ totalTokens: "total tokens";
12
+ }>;
13
+ export const COST_FIELDS: Readonly<{
14
+ input: "input";
15
+ output: "output";
16
+ cacheRead: "cache read";
17
+ cacheWrite: "cache write";
18
+ total: "total";
19
+ }>;