@peasant-labs/fairtrade 0.0.59 → 0.0.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/share.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _ as e, c as t, g as n, h as r, m as i, p as a, v as o } from "./time-CpVBzcqQ.js";
2
2
  import { r as s } from "./format-B3uT2wzU.js";
3
- import { c, l, t as u } from "./adapter-VlAohr64.js";
3
+ import { c, s as l, t as u } from "./adapter-BSfSbqWE.js";
4
4
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
5
5
  //#region public/tokens.json
6
6
  var p = {
@@ -556,7 +556,7 @@ function y(e) {
556
556
  return s(e);
557
557
  }
558
558
  function ce(e, t) {
559
- return c({
559
+ return l({
560
560
  title: typeof e.title == "string" && e.title.trim() !== "" ? e.title.trim() : void 0,
561
561
  hasNormalizedEvidence: t.session.hasNormalizedEvidence,
562
562
  firstTaskPrompt: t.tasks?.[0]?.prompt,
@@ -574,7 +574,7 @@ function le(e) {
574
574
  } catch {
575
575
  return null;
576
576
  }
577
- let i = r.session, a = ce(n, r), o = typeof i.harness == "string" ? i.harness : "", s = oe(o) ? t[o] : null, c = n.turns.find((e) => e?.role === "user" && (e.depth ?? 0) === 0), d = typeof c?.content == "string" ? c.content : "", f = ae(i.harness === "cursor" ? l(d) : d).trim(), p = f || a, m = i.inputSubmissionCount, h = i.totalTokens, g = !r.usageScopes?.length && h != null, _ = m != null && g ? {
577
+ let i = r.session, a = ce(n, r), o = typeof i.harness == "string" ? i.harness : "", s = oe(o) ? t[o] : null, l = n.turns.find((e) => e?.role === "user" && (e.depth ?? 0) === 0), d = typeof l?.content == "string" ? l.content : "", f = ae(i.harness === "cursor" ? c(d) : d).trim(), p = f || a, m = i.inputSubmissionCount, h = i.totalTokens, g = !r.usageScopes?.length && h != null, _ = m != null && g ? {
578
578
  prompts: Number(m),
579
579
  tokens: Number(h)
580
580
  } : null;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * A closed value: a frozen object that carries its wire value, the label a
3
+ * surface shows for it, and the conversion hooks.
4
+ *
5
+ * - `wire` is the exact value persisted, compared, and sent on the wire.
6
+ * - `label` is the human-readable text shown for the member.
7
+ * - `String()` is the Go-style explicit text conversion; it returns `String(wire)`.
8
+ * - `toString()` is the text conversion used by `String(value)` and template literals.
9
+ * - `toJSON()` is the persistence conversion used by `JSON.stringify`; it returns `wire`.
10
+ *
11
+ * @template {string | number} W - the exact value persisted, compared, and sent on the wire.
12
+ * @template {string} L - the human-readable label shown for the member.
13
+ * @typedef {{
14
+ * readonly wire: W,
15
+ * readonly label: L,
16
+ * String: () => string,
17
+ * toString: () => string,
18
+ * toJSON: () => W,
19
+ * }} ClosedValue
20
+ */
21
+ /**
22
+ * Create one frozen closed-set member.
23
+ *
24
+ * @template {string | number} W
25
+ * @template {string} L
26
+ * @param {W} wire - the exact value persisted, compared, and sent on the wire.
27
+ * @param {L} label - the human-readable text shown for the member.
28
+ * @returns {ClosedValue<W, L>} a new frozen member for this `(wire, label)` pair.
29
+ */
30
+ export function closed<W extends string | number, L extends string>(wire: W, label: L): ClosedValue<W, L>;
31
+ /**
32
+ * A closed value: a frozen object that carries its wire value, the label a
33
+ * surface shows for it, and the conversion hooks.
34
+ *
35
+ * - `wire` is the exact value persisted, compared, and sent on the wire.
36
+ * - `label` is the human-readable text shown for the member.
37
+ * - `String()` is the Go-style explicit text conversion; it returns `String(wire)`.
38
+ * - `toString()` is the text conversion used by `String(value)` and template literals.
39
+ * - `toJSON()` is the persistence conversion used by `JSON.stringify`; it returns `wire`.
40
+ */
41
+ export type ClosedValue<W extends string | number, L extends string> = {
42
+ readonly wire: W;
43
+ readonly label: L;
44
+ String: () => string;
45
+ toString: () => string;
46
+ toJSON: () => W;
47
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @param {object} props
3
+ * @param {TurnVM} [props.turn]
4
+ * @param {import('react').ReactNode} [props.actions] the turn's trailing controls (copy anchor + host actions)
5
+ * @param {number} [props.revealRequest] explicit search navigation sequence; a new value opens the row
6
+ */
7
+ export default function TranscriptControlRow({ turn, actions, revealRequest }: {
8
+ turn?: TurnVM;
9
+ actions?: import("react").ReactNode;
10
+ revealRequest?: number;
11
+ }): import("react").JSX.Element;
12
+ export type TurnVM = import("./view-model.js").TurnVM;
@@ -1,26 +1,26 @@
1
1
  export default function FiltersRail({ tab, filters, onFiltersChange, counts, checkpoints, filtersActive, onClear, onJumpStart, onJumpLatest, }: {
2
2
  tab: any;
3
- filters?: {
4
- categories: {
5
- prompts: boolean;
6
- responses: boolean;
7
- thinking: boolean;
8
- toolcalls: boolean;
9
- system: boolean;
10
- };
11
- toolGroups: {};
12
- tags: {
13
- errors: boolean;
14
- retries: boolean;
15
- revert: boolean;
16
- };
17
- views: {
18
- hidden: boolean;
19
- expandAll: boolean;
20
- compact: boolean;
21
- };
22
- checkpoint: string;
23
- };
3
+ filters?: Readonly<{
4
+ categories: Readonly<{
5
+ prompts: true;
6
+ responses: true;
7
+ thinking: true;
8
+ toolcalls: true;
9
+ system: false;
10
+ }>;
11
+ toolGroups: Readonly<Record<import("./view-model.js").ToolGroup, boolean>>;
12
+ tags: Readonly<{
13
+ errors: false;
14
+ retries: false;
15
+ revert: false;
16
+ }>;
17
+ views: Readonly<{
18
+ hidden: true;
19
+ expandAll: false;
20
+ compact: false;
21
+ }>;
22
+ checkpoint: "all";
23
+ }>;
24
24
  onFiltersChange?: () => void;
25
25
  counts?: {
26
26
  categories: {
@@ -0,0 +1,19 @@
1
+ /** @typedef {import('./system-groups.js').SystemGroupVM} SystemGroupVM */
2
+ /**
3
+ * @param {object} props
4
+ * @param {SystemGroupVM} props.group
5
+ * @param {boolean} [props.open]
6
+ * @param {(open: boolean) => void} [props.onToggle]
7
+ * @param {import('react').ReactNode} [props.owner] the owner's own row, rendered in place
8
+ * @param {import('react').ReactNode} [props.children] members 2..N, rendered inside the fold
9
+ * @param {number} [props.revealRequest] explicit navigation sequence; a new value opens the group
10
+ */
11
+ export default function TranscriptSystemGroup({ group, open: openProp, onToggle, owner, children, revealRequest }: {
12
+ group: SystemGroupVM;
13
+ open?: boolean;
14
+ onToggle?: (open: boolean) => void;
15
+ owner?: import("react").ReactNode;
16
+ children?: import("react").ReactNode;
17
+ revealRequest?: number;
18
+ }): import("react").JSX.Element;
19
+ export type SystemGroupVM = import("./system-groups.js").SystemGroupVM;
@@ -10,13 +10,6 @@
10
10
  * @returns {number | undefined}
11
11
  */
12
12
  export function thinkingDurationMs(previous: TurnDetail | undefined, turn: TurnDetail): number | undefined;
13
- /**
14
- * Is this wire turn one of Claude Code's session metadata records rather than conversation?
15
- * @param {TurnDetail} turn
16
- * @param {string | undefined} harness the session's harness
17
- * @returns {boolean}
18
- */
19
- export function isSessionMetadataTurn(turn: TurnDetail, harness: string | undefined): boolean;
20
13
  /**
21
14
  * Default turn prefilter the adapter applies independently per partition:
22
15
  * preserve normalized evidence, including unknown provenance and folded refs.
@@ -93,6 +93,12 @@ export function assessScorecard(sc: SessionScorecard | null | undefined, medians
93
93
  * The cooked task groups for a turn list (`computeTasks` mapped onto
94
94
  * `TaskGroupVM`). Exported so the adapter can populate the always-present
95
95
  * `vm.tasks` from the same single computation `computeAnalytics` uses.
96
+ *
97
+ * The list is the user turns: a session that opens with harness bookkeeping gets a
98
+ * leading span that starts on a system entry and has no prompt. That entry is not a
99
+ * user turn, so it never becomes a task card; the spans that survive keep their
100
+ * ORIGINAL ordinal so a card's `#` and the classic turn-boundary chip still agree
101
+ * with the turn labels they were cooked beside.
96
102
  * @param {TurnDetail[]} turns
97
103
  * @returns {TaskGroupVM[]}
98
104
  */
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The recorded value with its leading kind phrase removed; the recorded bytes
3
+ * otherwise, verbatim. Returns '' when the value names the kind and nothing else,
4
+ * so the row renders the kind once instead of printing it twice.
5
+ * @param {string | undefined | null} kind the producer's `controlKind`
6
+ * @param {string | undefined | null} value the recorded value
7
+ * @returns {string}
8
+ */
9
+ export function controlValueRemainder(kind: string | undefined | null, value: string | undefined | null): string;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * How many filter choices deviate from {@link DEFAULT_TRANSCRIPT_FILTERS}: the number
3
+ * the rail's "clear (N)" badge shows. Tool groups count only while `tool calls` is on,
4
+ * because the umbrella has already cascaded every group off and counting those would
5
+ * report eight active filters for one click.
6
+ *
7
+ * @param {TranscriptFilters} [filters]
8
+ * @returns {number}
9
+ */
10
+ export function filtersActive(filters?: TranscriptFilters): number;
1
11
  /** @typedef {import('./view-model.js').TurnVM} TurnVM */
2
12
  /** @typedef {import('./view-model.js').ToolGroup} ToolGroup */
3
13
  /** @typedef {import('./state-capabilities.js').TranscriptFilters} TranscriptFilters */
@@ -121,6 +131,36 @@ export function toggleToolGroup(filters: TranscriptFilters, id: ToolGroup, count
121
131
  * @returns {TranscriptFilters}
122
132
  */
123
133
  export function setToolCalls(filters: TranscriptFilters, next: boolean): TranscriptFilters;
134
+ /**
135
+ * The canonical filter state every consumer starts from. Complete (every category,
136
+ * every tool group, every tag, every view) because the viewer's controllable state
137
+ * does not merge a partial object: a host that supplies filters owns every key.
138
+ * Deep-frozen so a handler cannot mutate the default through a spread-by-reference.
139
+ *
140
+ * `system` is FALSE: system entries are harness bookkeeping, not conversation, and a
141
+ * reader reveals them from the rail when they want the evidence.
142
+ */
143
+ export const DEFAULT_TRANSCRIPT_FILTERS: Readonly<{
144
+ categories: Readonly<{
145
+ prompts: true;
146
+ responses: true;
147
+ thinking: true;
148
+ toolcalls: true;
149
+ system: false;
150
+ }>;
151
+ toolGroups: Readonly<Record<import("./view-model.js").ToolGroup, boolean>>;
152
+ tags: Readonly<{
153
+ errors: false;
154
+ retries: false;
155
+ revert: false;
156
+ }>;
157
+ views: Readonly<{
158
+ hidden: true;
159
+ expandAll: false;
160
+ compact: false;
161
+ }>;
162
+ checkpoint: "all";
163
+ }>;
124
164
  export type TurnVM = import("./view-model.js").TurnVM;
125
165
  export type ToolGroup = import("./view-model.js").ToolGroup;
126
166
  export type TranscriptFilters = import("./state-capabilities.js").TranscriptFilters;
@@ -1,4 +1,8 @@
1
1
  export { TOOL_GROUPS } from "./view-model.js";
2
+ export { default as TranscriptControlRow } from "./ControlRow.jsx";
3
+ export { default as TranscriptSystemGroup } from "./SystemGroup.jsx";
4
+ export { systemGroups } from "./system-groups.js";
5
+ export { systemGroupSummary } from "./system-summary.js";
2
6
  export { nextNavTurn } from "./turnNav.js";
3
7
  export { workSummary } from "./work-summary.js";
4
8
  export { default as TranscriptTurnCard } from "./TurnCard.jsx";
@@ -78,7 +82,7 @@ export type PhaseVM = import("./view-model.js").PhaseVM;
78
82
  export type ScorecardBandVM = import("./view-model.js").ScorecardBandVM;
79
83
  export type TranscriptAnalyticsVM = import("./view-model.js").TranscriptAnalyticsVM;
80
84
  export { ROLES, ENTRY_TYPES, TOOL_CALL_KINDS, STOP_REASONS, SESSION_OUTCOMES, HARNESSES } from "./wire-types.js";
81
- export { adaptTranscript, prefilterTurns, isSessionMetadataTurn, diffLines } from "./adapter.js";
85
+ export { adaptTranscript, prefilterTurns, diffLines } from "./adapter.js";
82
86
  export { computeTasks, computeTurnLabels, buildTaskWaterfall, annotateTranscript, computePersonalMedians, detectPhases, assessScorecard, computeAnalytics, computeTaskGroups, phaseLabel } from "./analytics.js";
83
87
  export { formatRelative, formatDurationMins, formatDurationMs, formatDurationSeconds, formatDateLong, isKnownTime } from "./time.js";
84
88
  export { summarizePrompt, composeSessionTitle, projectLabel, cleanSessionTitle, unwrapUserQuery } from "./title.js";
@@ -0,0 +1,30 @@
1
+ /** @typedef {import('./view-model.js').TurnVM} TurnVM */
2
+ /**
3
+ * @typedef {object} SystemGroupVM
4
+ * @property {string} id stable key for the run (its owner's turn index)
5
+ * @property {TurnVM} owner the first member; it renders in place, outside the collapsible
6
+ * @property {TurnVM[]} members every member in turn order, owner first
7
+ */
8
+ /**
9
+ * Group runs of two or more consecutive visible system turns.
10
+ *
11
+ * @param {TurnVM[]} [visibleTurns]
12
+ * @returns {Map<number, SystemGroupVM>} member turn index → its group; a non-system
13
+ * turn and a singleton system turn are absent
14
+ */
15
+ export function systemGroups(visibleTurns?: TurnVM[]): Map<number, SystemGroupVM>;
16
+ export type TurnVM = import("./view-model.js").TurnVM;
17
+ export type SystemGroupVM = {
18
+ /**
19
+ * stable key for the run (its owner's turn index)
20
+ */
21
+ id: string;
22
+ /**
23
+ * the first member; it renders in place, outside the collapsible
24
+ */
25
+ owner: TurnVM;
26
+ /**
27
+ * every member in turn order, owner first
28
+ */
29
+ members: TurnVM[];
30
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The summary under a system-entry group head: `6 entries: 4 mode, 2 attachment`.
3
+ * A member without a producer kind is a plain system message and is named `system`.
4
+ * Kinds sort by count (descending) then by name, so the head is stable across renders.
5
+ *
6
+ * @param {TurnVM[]} [members]
7
+ * @returns {string}
8
+ */
9
+ export function systemGroupSummary(members?: TurnVM[]): string;
10
+ export type TurnVM = import("./view-model.js").TurnVM;
@@ -360,6 +360,16 @@ export type TurnVM = {
360
360
  * subagent name when depth > 0
361
361
  */
362
362
  agentName?: string;
363
+ /**
364
+ * the producer's control-record kind for this turn, when the
365
+ * server classified it (mode / permission-mode / attachment /
366
+ * agent-name / custom-title); never inferred from any other field
367
+ */
368
+ controlKind?: string;
369
+ /**
370
+ * true exactly when `controlKind` is present
371
+ */
372
+ isControl?: boolean;
363
373
  thinking?: ThinkingVM;
364
374
  usage?: import("@peasant-labs/schema").UsageDetail;
365
375
  toolCalls: ToolCallVM[];
@@ -10,13 +10,6 @@
10
10
  * @returns {number | undefined}
11
11
  */
12
12
  export function thinkingDurationMs(previous: TurnDetail | undefined, turn: TurnDetail): number | undefined;
13
- /**
14
- * Is this wire turn one of Claude Code's session metadata records rather than conversation?
15
- * @param {TurnDetail} turn
16
- * @param {string | undefined} harness the session's harness
17
- * @returns {boolean}
18
- */
19
- export function isSessionMetadataTurn(turn: TurnDetail, harness: string | undefined): boolean;
20
13
  /**
21
14
  * Default turn prefilter the adapter applies independently per partition:
22
15
  * preserve normalized evidence, including unknown provenance and folded refs.
@@ -93,6 +93,12 @@ export function assessScorecard(sc: SessionScorecard | null | undefined, medians
93
93
  * The cooked task groups for a turn list (`computeTasks` mapped onto
94
94
  * `TaskGroupVM`). Exported so the adapter can populate the always-present
95
95
  * `vm.tasks` from the same single computation `computeAnalytics` uses.
96
+ *
97
+ * The list is the user turns: a session that opens with harness bookkeeping gets a
98
+ * leading span that starts on a system entry and has no prompt. That entry is not a
99
+ * user turn, so it never becomes a task card; the spans that survive keep their
100
+ * ORIGINAL ordinal so a card's `#` and the classic turn-boundary chip still agree
101
+ * with the turn labels they were cooked beside.
96
102
  * @param {TurnDetail[]} turns
97
103
  * @returns {TaskGroupVM[]}
98
104
  */
@@ -360,6 +360,16 @@ export type TurnVM = {
360
360
  * subagent name when depth > 0
361
361
  */
362
362
  agentName?: string;
363
+ /**
364
+ * the producer's control-record kind for this turn, when the
365
+ * server classified it (mode / permission-mode / attachment /
366
+ * agent-name / custom-title); never inferred from any other field
367
+ */
368
+ controlKind?: string;
369
+ /**
370
+ * true exactly when `controlKind` is present
371
+ */
372
+ isControl?: boolean;
363
373
  thinking?: ThinkingVM;
364
374
  usage?: import("@peasant-labs/schema").UsageDetail;
365
375
  toolCalls: ToolCallVM[];