@peasant-labs/fairtrade 0.0.5 → 0.0.7
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/LICENSE +202 -21
- package/dist/lib/{ChartLine-Dlp6-CLL.js → ChartLine-Cycmpjep.js} +45 -39
- package/dist/lib/InUseShell-VRWaysXY.js +2488 -0
- package/dist/lib/analytics.js +1 -1
- package/dist/lib/commons.js +801 -836
- package/dist/lib/components.css +1 -1
- package/dist/lib/graph.css +1 -1
- package/dist/lib/graph.js +684 -285
- package/dist/lib/types/ChartBar.d.ts +3 -1
- package/dist/lib/types/ChartLine.d.ts +3 -1
- package/dist/lib/types/CommitGraph.d.ts +12 -3
- package/dist/lib/types/MapCanvas.d.ts +45 -2
- package/dist/lib/types/ProviderIcon.d.ts +23 -20
- package/dist/lib/types/chart-shared.d.ts +1 -0
- package/dist/lib/types/commons/providers.d.ts +7 -8
- package/dist/lib/types/commons/types.d.ts +3 -6
- package/dist/lib/types/graph/Changes.d.ts +8 -4
- package/dist/lib/types/graph/CodeMap.d.ts +17 -1
- package/dist/lib/types/graph/CodeMapComposition.d.ts +25 -1
- package/dist/lib/types/graph/CodeMapNavigator.d.ts +35 -0
- package/dist/lib/types/graph/changeGraph.d.ts +12 -0
- package/dist/lib/types/graph/codeMapState.d.ts +136 -0
- package/dist/lib/types/graph/index.d.ts +15 -1
- package/dist/lib/types/graph/timelineNavigation.d.ts +33 -0
- package/dist/lib/types/graph/types.d.ts +67 -440
- package/dist/lib/types/index.d.ts +2 -0
- package/dist/lib/types/provider-policy.d.ts +27 -0
- package/dist/lib/types/transcript/TranscriptViewer.d.ts +1 -1
- package/dist/lib/types/transcript/TurnCard.d.ts +3 -1
- package/dist/lib/types/transcript/adapter.d.ts +5 -40
- package/dist/lib/types/transcript/graph/GraphLegend.d.ts +3 -3
- package/dist/lib/types/transcript/graph/GraphTurnNode.d.ts +2 -2
- package/dist/lib/types/transcript/index.d.ts +4 -1
- package/dist/lib/types/transcript/initial-position.d.ts +80 -0
- package/dist/lib/types/transcript/state-capabilities.d.ts +53 -1
- package/dist/lib/types/transcript/useTranscriptInitialPosition.d.ts +26 -0
- package/dist/lib/types/transcript/view-model.d.ts +16 -16
- package/dist/lib/types/transcript/wire-types.d.ts +46 -308
- package/dist/lib/{ui-oBFnHPFe.js → ui-CKqVB4x2.js} +3592 -3584
- package/dist/lib/ui.js +4 -4
- package/package.json +51 -26
- package/dist/lib/InUseShell-DZvmRdj-.js +0 -1532
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
* @param {number} [props.height=200] plot height in px.
|
|
18
18
|
* @param {number[]} [props.yTicks] explicit y ticks; omit to auto-pick integers.
|
|
19
19
|
* @param {(v:any)=>React.ReactNode} [props.xFormatter] format x tick + tooltip label.
|
|
20
|
+
* @param {(v:any)=>React.ReactNode} [props.yFormatter] format y ticks; defaults to thousands-compaction (3000 → 3k).
|
|
20
21
|
* @param {(v:any)=>React.ReactNode} [props.valueFormatter] format the tooltip value.
|
|
21
22
|
* @param {string} [props.className] extra class on the chart frame.
|
|
22
23
|
*/
|
|
23
|
-
export default function ChartBar({ data, xKey, series, stacked, icon, title, aside, sub, height, yTicks, xFormatter, valueFormatter, className, }: {
|
|
24
|
+
export default function ChartBar({ data, xKey, series, stacked, icon, title, aside, sub, height, yTicks, xFormatter, yFormatter, valueFormatter, className, }: {
|
|
24
25
|
data: any[];
|
|
25
26
|
xKey: string;
|
|
26
27
|
series: BarSeries[];
|
|
@@ -32,6 +33,7 @@ export default function ChartBar({ data, xKey, series, stacked, icon, title, asi
|
|
|
32
33
|
height?: number;
|
|
33
34
|
yTicks?: number[];
|
|
34
35
|
xFormatter?: (v: any) => React.ReactNode;
|
|
36
|
+
yFormatter?: (v: any) => React.ReactNode;
|
|
35
37
|
valueFormatter?: (v: any) => React.ReactNode;
|
|
36
38
|
className?: string;
|
|
37
39
|
}): any;
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
* @param {number} [props.height=200] plot height in px.
|
|
18
18
|
* @param {number[]} [props.yTicks] explicit y ticks; omit to auto-pick integers.
|
|
19
19
|
* @param {(v:any)=>React.ReactNode} [props.xFormatter] format x tick + tooltip label.
|
|
20
|
+
* @param {(v:any)=>React.ReactNode} [props.yFormatter] format y ticks; defaults to thousands-compaction (3000 → 3k).
|
|
20
21
|
* @param {(v:any)=>React.ReactNode} [props.valueFormatter] format the tooltip value.
|
|
21
22
|
* @param {string} [props.className] extra class on the chart frame.
|
|
22
23
|
*/
|
|
23
|
-
export default function ChartLine({ data, xKey, series, icon, title, aside, sub, height, yTicks, xFormatter, valueFormatter, className, }: {
|
|
24
|
+
export default function ChartLine({ data, xKey, series, icon, title, aside, sub, height, yTicks, xFormatter, yFormatter, valueFormatter, className, }: {
|
|
24
25
|
data: any[];
|
|
25
26
|
xKey: string;
|
|
26
27
|
series: LineSeries[];
|
|
@@ -31,6 +32,7 @@ export default function ChartLine({ data, xKey, series, icon, title, aside, sub,
|
|
|
31
32
|
height?: number;
|
|
32
33
|
yTicks?: number[];
|
|
33
34
|
xFormatter?: (v: any) => React.ReactNode;
|
|
35
|
+
yFormatter?: (v: any) => React.ReactNode;
|
|
34
36
|
valueFormatter?: (v: any) => React.ReactNode;
|
|
35
37
|
className?: string;
|
|
36
38
|
}): any;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @property {string} message - the commit subject (USER CONTENT — case preserved)
|
|
7
7
|
* @property {string} [branch] - branch name for the chip (USER CONTENT — case preserved)
|
|
8
8
|
* @property {boolean} [session] - a recorded AI session sits behind this commit (-> filled + sparkle)
|
|
9
|
+
* @property {import('./graph/types.js').TimelineSessionPayload[]} [sessionRefs] - named sessions bound to this commit
|
|
9
10
|
* @property {boolean} [merged] - this commit merged a branch back in (-> merged chip)
|
|
10
11
|
* @property {boolean} [tip] - this commit is a branch tip (-> small tip affordance)
|
|
11
12
|
* @property {string} [time] - relative time label (e.g. "8m ago") — already humanised by the caller
|
|
@@ -16,16 +17,20 @@
|
|
|
16
17
|
* @param {object} props
|
|
17
18
|
* @param {Commit[]} props.commits - the history, newest first; lane 0 is the main line.
|
|
18
19
|
* @param {string} [props.selectedId] - id of the active/selected row (the scarce amber treatment).
|
|
19
|
-
* @param {(
|
|
20
|
+
* @param {(action: import('./graph/timelineNavigation.js').TimelineNavigationAction) => void} [props.onNavigate] - canonical semantic action callback; when present, legacy callbacks do not fire.
|
|
21
|
+
* @param {(commit: Commit) => void} [props.onSelect] - deprecated legacy row callback; use onNavigate.
|
|
22
|
+
* @param {(sessionId: string) => void} [props.onOpenSession] - deprecated legacy session callback; use onNavigate.
|
|
20
23
|
* @param {boolean} [props.hasMore=false] - more history exists below the window -> show the "show older" ghost.
|
|
21
|
-
* @param {() => void} [props.onShowOlder] -
|
|
24
|
+
* @param {() => void} [props.onShowOlder] - deprecated legacy pagination callback; use onNavigate.
|
|
22
25
|
* @param {string} [props.label='commit history'] - accessible name for the list (lowercase chrome).
|
|
23
26
|
* @param {string} [props.className] - extra classes appended to the root.
|
|
24
27
|
*/
|
|
25
|
-
export default function CommitGraph({ commits, selectedId, onSelect, hasMore, onShowOlder, label, className, ...rest }: {
|
|
28
|
+
export default function CommitGraph({ commits, selectedId, onNavigate, onSelect, onOpenSession, hasMore, onShowOlder, label, className, ...rest }: {
|
|
26
29
|
commits: Commit[];
|
|
27
30
|
selectedId?: string;
|
|
31
|
+
onNavigate?: (action: import("./graph/timelineNavigation.js").TimelineNavigationAction) => void;
|
|
28
32
|
onSelect?: (commit: Commit) => void;
|
|
33
|
+
onOpenSession?: (sessionId: string) => void;
|
|
29
34
|
hasMore?: boolean;
|
|
30
35
|
onShowOlder?: () => void;
|
|
31
36
|
label?: string;
|
|
@@ -56,6 +61,10 @@ export type Commit = {
|
|
|
56
61
|
* - a recorded AI session sits behind this commit (-> filled + sparkle)
|
|
57
62
|
*/
|
|
58
63
|
session?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* - named sessions bound to this commit
|
|
66
|
+
*/
|
|
67
|
+
sessionRefs?: import("./graph/types.js").TimelineSessionPayload[];
|
|
59
68
|
/**
|
|
60
69
|
* - this commit merged a branch back in (-> merged chip)
|
|
61
70
|
*/
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
*/
|
|
24
24
|
/**
|
|
25
25
|
* MapCanvas — an interactive code-structure map. Pan (drag), zoom (square controls /
|
|
26
|
-
* +/- keys
|
|
26
|
+
* +/- keys / ctrl-or-cmd+wheel — a plain wheel always just scrolls the page),
|
|
27
|
+
* semantic zoom (overview / folders / files) with edge
|
|
27
28
|
* ancestor-lifting, a minimap, and a node search combobox. Square metric-encoded
|
|
28
29
|
* nodes (width ∝ LOC, monochrome coverage fill, folder/file icon, amber selection +
|
|
29
30
|
* marker, clay violation badge) and square orthogonal edges (solid structure /
|
|
@@ -34,6 +35,8 @@
|
|
|
34
35
|
* @param {{nodes: MapNode[], edges?: MapEdge[]}} [props.data] the graph
|
|
35
36
|
* @param {'overview'|'folders'|'files'} [props.grain='folders'] initial semantic zoom
|
|
36
37
|
* @param {Iterable<string>} [props.expandedIds] expanded node ids
|
|
38
|
+
* @param {Iterable<string>} [props.visibleIds] canonical derived visible node ids
|
|
39
|
+
* @param {import('./graph/codeMapState.js').CodeMapHierarchy} [props.hierarchy] canonical validated hierarchy
|
|
37
40
|
* @param {string|null} [props.selectedId] selected node id
|
|
38
41
|
* @param {Iterable<string>} [props.highlightedIds] host hover/relay ids
|
|
39
42
|
* @param {Record<string,'new'|'removed'>} [props.nodeDeltas] per-node review deltas
|
|
@@ -45,14 +48,42 @@
|
|
|
45
48
|
* @param {number|string} [props.height=520] canvas height
|
|
46
49
|
* @param {string} [props.ariaLabel='code map'] application label
|
|
47
50
|
* @param {string} [props.className] extra container class
|
|
51
|
+
* @param {{scale:number, panX:number, panY:number}|null} [props.viewport] controlled/restorable spatial viewport.
|
|
52
|
+
* In `canonicalControlled` mode this is the SOLE source of truth once a
|
|
53
|
+
* gesture ends: MapCanvas renders it directly and does not keep its own
|
|
54
|
+
* copy. CONTRACT: when a pan/zoom gesture ends, MapCanvas calls
|
|
55
|
+
* `onViewportChange`/`onStateAction` with the proposed viewport, and the
|
|
56
|
+
* owner is expected to feed that value straight back through this prop
|
|
57
|
+
* PROMPTLY (a same-tick/next-render `useState` update, as peasant's real
|
|
58
|
+
* integration does, is the reference case — not a debounce, network
|
|
59
|
+
* round-trip, or anything else that can take an unbounded amount of time).
|
|
60
|
+
* During the gesture itself MapCanvas tracks the pointer locally so the
|
|
61
|
+
* drag/zoom stays smooth without waiting on this round-trip; it holds that
|
|
62
|
+
* local preview for up to ~500ms after the gesture ends waiting for
|
|
63
|
+
* `viewport` to reflect (or nearly reflect — the owner may legitimately
|
|
64
|
+
* clamp scale/pan bounds) the proposal, THEN falls back to whatever this
|
|
65
|
+
* prop says. An owner that never updates `viewport` in response (rejects
|
|
66
|
+
* the change, or simply never wires the callback) will see the gesture
|
|
67
|
+
* held for that ~500ms window and then discarded — a visible snap-back to
|
|
68
|
+
* the pre-gesture position, not a smooth revert. An owner that reconciles
|
|
69
|
+
* slower than ~500ms (e.g. a debounce or a network-backed proposal) will
|
|
70
|
+
* see the SAME snap-back-then-jump-to-late-value symptom the pointer-drag
|
|
71
|
+
* fix in this file exists to prevent — reconcile synchronously.
|
|
72
|
+
* @param {(viewport:{scale:number, panX:number, panY:number})=>void} [props.onViewportChange]
|
|
73
|
+
* @param {(action:import('./graph/codeMapState.js').CodeMapAction)=>void} [props.onStateAction] one semantic canvas gesture
|
|
74
|
+
* @param {boolean} [props.canonicalControlled=false] canonical values render directly; gestures emit proposals only.
|
|
75
|
+
* See the `viewport` prop doc above for the synchronous-reconciliation
|
|
76
|
+
* contract this mode requires of its owner.
|
|
48
77
|
*/
|
|
49
|
-
export default function MapCanvas({ data, grain: grainProp, expandedIds, selectedId: selectedIdProp, highlightedIds, nodeDeltas, edgeDeltas, onSelect, onGrainChange, onExpandedIdsChange, onExpand, height, ariaLabel, className, }: {
|
|
78
|
+
export default function MapCanvas({ data, grain: grainProp, expandedIds, visibleIds: canonicalVisibleIds, hierarchy: canonicalHierarchy, selectedId: selectedIdProp, highlightedIds, nodeDeltas, edgeDeltas, onSelect, onGrainChange, onExpandedIdsChange, onExpand, height, ariaLabel, className, viewport, onViewportChange, onStateAction, canonicalControlled, }: {
|
|
50
79
|
data?: {
|
|
51
80
|
nodes: MapNode[];
|
|
52
81
|
edges?: MapEdge[];
|
|
53
82
|
};
|
|
54
83
|
grain?: "overview" | "folders" | "files";
|
|
55
84
|
expandedIds?: Iterable<string>;
|
|
85
|
+
visibleIds?: Iterable<string>;
|
|
86
|
+
hierarchy?: import("./graph/codeMapState.js").CodeMapHierarchy;
|
|
56
87
|
selectedId?: string | null;
|
|
57
88
|
highlightedIds?: Iterable<string>;
|
|
58
89
|
nodeDeltas?: Record<string, "new" | "removed">;
|
|
@@ -64,6 +95,18 @@ export default function MapCanvas({ data, grain: grainProp, expandedIds, selecte
|
|
|
64
95
|
height?: number | string;
|
|
65
96
|
ariaLabel?: string;
|
|
66
97
|
className?: string;
|
|
98
|
+
viewport?: {
|
|
99
|
+
scale: number;
|
|
100
|
+
panX: number;
|
|
101
|
+
panY: number;
|
|
102
|
+
} | null;
|
|
103
|
+
onViewportChange?: (viewport: {
|
|
104
|
+
scale: number;
|
|
105
|
+
panX: number;
|
|
106
|
+
panY: number;
|
|
107
|
+
}) => void;
|
|
108
|
+
onStateAction?: (action: import("./graph/codeMapState.js").CodeMapAction) => void;
|
|
109
|
+
canonicalControlled?: boolean;
|
|
67
110
|
}): any;
|
|
68
111
|
export type MapNode = {
|
|
69
112
|
/**
|
|
@@ -7,20 +7,20 @@
|
|
|
7
7
|
* the surrounding text color — but remember the accent is never the sole signal.
|
|
8
8
|
*
|
|
9
9
|
* @param {object} props
|
|
10
|
-
* @param {
|
|
10
|
+
* @param {Harness} props.harness
|
|
11
11
|
* @param {number} [props.size] explicit px; omit to inherit the contextual icon size.
|
|
12
12
|
* @param {boolean} [props.accent] tint with PROVIDER_ACCENT[harness] (default: currentColor).
|
|
13
13
|
* @param {boolean|string} [props.label] true → the provider name as aria-label; a string overrides.
|
|
14
14
|
* @param {string} [props.className] extra classes appended after `pv-icon`.
|
|
15
|
-
* @returns {JSX.Element
|
|
15
|
+
* @returns {JSX.Element}
|
|
16
16
|
*/
|
|
17
17
|
export function ProviderIcon({ harness, size, accent, label, className, ...rest }: {
|
|
18
|
-
harness:
|
|
18
|
+
harness: Harness;
|
|
19
19
|
size?: number;
|
|
20
20
|
accent?: boolean;
|
|
21
21
|
label?: boolean | string;
|
|
22
22
|
className?: string;
|
|
23
|
-
}): JSX.Element
|
|
23
|
+
}): JSX.Element;
|
|
24
24
|
/**
|
|
25
25
|
* ProviderTag — a square hairline chip: the real mark + the lowercase harness slug.
|
|
26
26
|
*
|
|
@@ -29,16 +29,16 @@ export function ProviderIcon({ harness, size, accent, label, className, ...rest
|
|
|
29
29
|
* monochrome it names the provider in words. pass `accent` to tint the mark.
|
|
30
30
|
*
|
|
31
31
|
* @param {object} props
|
|
32
|
-
* @param {
|
|
32
|
+
* @param {Harness} props.harness
|
|
33
33
|
* @param {boolean} [props.accent] tint the mark with the provider accent (default: ink).
|
|
34
34
|
* @param {string} [props.className]
|
|
35
|
-
* @returns {JSX.Element
|
|
35
|
+
* @returns {JSX.Element}
|
|
36
36
|
*/
|
|
37
37
|
export function ProviderTag({ harness, accent, className, ...rest }: {
|
|
38
|
-
harness:
|
|
38
|
+
harness: Harness;
|
|
39
39
|
accent?: boolean;
|
|
40
40
|
className?: string;
|
|
41
|
-
}): JSX.Element
|
|
41
|
+
}): JSX.Element;
|
|
42
42
|
/**
|
|
43
43
|
* ProviderName — mark + the harness slug as a plain inline label (no chip border).
|
|
44
44
|
*
|
|
@@ -47,16 +47,16 @@ export function ProviderTag({ harness, accent, className, ...rest }: {
|
|
|
47
47
|
* non-color cue regardless — it is real text, so it is readable mono-color too).
|
|
48
48
|
*
|
|
49
49
|
* @param {object} props
|
|
50
|
-
* @param {
|
|
50
|
+
* @param {Harness} props.harness
|
|
51
51
|
* @param {boolean} [props.accent] tint mark + label with the provider accent.
|
|
52
52
|
* @param {string} [props.className]
|
|
53
|
-
* @returns {JSX.Element
|
|
53
|
+
* @returns {JSX.Element}
|
|
54
54
|
*/
|
|
55
55
|
export function ProviderName({ harness, accent, className, ...rest }: {
|
|
56
|
-
harness:
|
|
56
|
+
harness: Harness;
|
|
57
57
|
accent?: boolean;
|
|
58
58
|
className?: string;
|
|
59
|
-
}): JSX.Element
|
|
59
|
+
}): JSX.Element;
|
|
60
60
|
/**
|
|
61
61
|
* AccentLegend — the per-provider accent map, documented as a UI.
|
|
62
62
|
*
|
|
@@ -73,12 +73,15 @@ export function ProviderName({ harness, accent, className, ...rest }: {
|
|
|
73
73
|
export function AccentLegend({ className, ...rest }: {
|
|
74
74
|
className?: string;
|
|
75
75
|
}): JSX.Element;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
76
|
+
/** ProviderIcon — the real brand mark for a harness, single-color via currentColor. */
|
|
77
|
+
/** @typedef {import('@peasant-labs/schema').Harness} Harness */
|
|
78
|
+
/** @type {readonly Harness[]} */
|
|
79
|
+
export const HARNESSES: readonly Harness[];
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated Use providerAccent(harness), which validates present values at
|
|
82
|
+
* the canonical schema boundary before returning an accent.
|
|
83
|
+
* @type {Readonly<Record<Harness, 'amber'|'teal'|'olive'|'mauve'|'clay'>>}
|
|
84
|
+
*/
|
|
85
|
+
export const PROVIDER_ACCENT: Readonly<Record<Harness, "amber" | "teal" | "olive" | "mauve" | "clay">>;
|
|
84
86
|
export default ProviderIcon;
|
|
87
|
+
export type Harness = import("@peasant-labs/schema").Harness;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
1
|
+
/** Format explicitly non-Harness prose. Never use this as a Harness fallback.
|
|
2
|
+
* @param {unknown} provider
|
|
3
|
+
*/
|
|
4
|
+
export function formatProvider(provider: unknown): string;
|
|
5
|
+
/** @param {import('@peasant-labs/schema').Harness} provider */
|
|
6
|
+
export function providerLabel(provider: import("@peasant-labs/schema").Harness): string;
|
|
7
|
+
export const PROVIDER_LABEL: Readonly<Record<"cursor" | "claude-code" | "gemini-cli" | "codex" | "opencode" | "antigravity", string>>;
|
|
@@ -129,10 +129,7 @@ export type ExploreTranscriptPayload = {
|
|
|
129
129
|
id: string;
|
|
130
130
|
title: string | null;
|
|
131
131
|
visibility: TranscriptVisibility;
|
|
132
|
-
|
|
133
|
-
* e.g. "claude-code", "opencode"
|
|
134
|
-
*/
|
|
135
|
-
modelProvider: string;
|
|
132
|
+
modelProvider: import("@peasant-labs/schema").Harness;
|
|
136
133
|
modelName: string | null;
|
|
137
134
|
harnessVersion: string | null;
|
|
138
135
|
/**
|
|
@@ -241,7 +238,7 @@ export type CollectiveTranscriptPayload = {
|
|
|
241
238
|
id: string;
|
|
242
239
|
title: string | null;
|
|
243
240
|
visibility: TranscriptVisibility;
|
|
244
|
-
modelProvider:
|
|
241
|
+
modelProvider: import("@peasant-labs/schema").Harness;
|
|
245
242
|
modelName: string | null;
|
|
246
243
|
/**
|
|
247
244
|
* ISO-8601 datetime or null
|
|
@@ -268,7 +265,7 @@ export type CollectiveStatsPayload = {
|
|
|
268
265
|
* Mirrors GroupModelBreakdown from frontend/src/lib/types.ts.
|
|
269
266
|
*/
|
|
270
267
|
export type CollectiveModelBreakdownPayload = {
|
|
271
|
-
modelProvider:
|
|
268
|
+
modelProvider: import("@peasant-labs/schema").Harness;
|
|
272
269
|
transcriptCount: number;
|
|
273
270
|
};
|
|
274
271
|
/**
|
|
@@ -3,19 +3,23 @@
|
|
|
3
3
|
* @param {import('./types.js').ChangesPayload} props.payload the cooked changes payload (adapter output)
|
|
4
4
|
* @param {string} [props.projectLabel] the head label (e.g. "peasant-labs/peasant"); host-supplied (not a payload field)
|
|
5
5
|
* @param {string} [props.selectedId] id of the active commit/tip row (the scarce amber treatment)
|
|
6
|
-
* @param {(
|
|
7
|
-
* @param {() => void} [props.
|
|
6
|
+
* @param {(action: import('./timelineNavigation.js').TimelineNavigationAction) => void} [props.onNavigate] canonical semantic action callback; when present, legacy callbacks do not fire
|
|
7
|
+
* @param {(commit: import('./changeGraph.js').CommitGraphRow) => void} [props.onSelectChange] deprecated legacy row callback; use onNavigate.
|
|
8
|
+
* @param {() => void} [props.onOpenMap] deprecated legacy map callback; use onNavigate.
|
|
8
9
|
* @param {boolean} [props.hasMore] more history exists below the window (→ "show older")
|
|
9
|
-
* @param {() => void} [props.onShowOlder]
|
|
10
|
+
* @param {() => void} [props.onShowOlder] deprecated legacy pagination callback; use onNavigate.
|
|
11
|
+
* @param {(sessionId: string) => void} [props.onOpenSession] deprecated legacy session callback; use onNavigate.
|
|
10
12
|
* @param {number} [props.nowMs] pins relative-time humanisation (default Date.now()); the harness fixes it for byte-stable captures
|
|
11
13
|
*/
|
|
12
|
-
export default function Changes({ payload, projectLabel, selectedId, onSelectChange, onOpenMap, hasMore, onShowOlder, nowMs, }: {
|
|
14
|
+
export default function Changes({ payload, projectLabel, selectedId, onNavigate, onSelectChange, onOpenMap, hasMore, onShowOlder, onOpenSession, nowMs, }: {
|
|
13
15
|
payload: import("./types.js").ChangesPayload;
|
|
14
16
|
projectLabel?: string;
|
|
15
17
|
selectedId?: string;
|
|
18
|
+
onNavigate?: (action: import("./timelineNavigation.js").TimelineNavigationAction) => void;
|
|
16
19
|
onSelectChange?: (commit: import("./changeGraph.js").CommitGraphRow) => void;
|
|
17
20
|
onOpenMap?: () => void;
|
|
18
21
|
hasMore?: boolean;
|
|
19
22
|
onShowOlder?: () => void;
|
|
23
|
+
onOpenSession?: (sessionId: string) => void;
|
|
20
24
|
nowMs?: number;
|
|
21
25
|
}): any;
|
|
@@ -18,8 +18,12 @@
|
|
|
18
18
|
* @param {number|string} [props.height]
|
|
19
19
|
* @param {string} [props.ariaLabel]
|
|
20
20
|
* @param {string} [props.className]
|
|
21
|
+
* @param {{scale:number, panX:number, panY:number}|null} [props.viewport]
|
|
22
|
+
* @param {(viewport:{scale:number, panX:number, panY:number})=>void} [props.onViewportChange]
|
|
23
|
+
* @param {import('./codeMapState.js').CodeMapState} [props.state]
|
|
24
|
+
* @param {(state:import('./codeMapState.js').CodeMapState)=>void} [props.onStateChange]
|
|
21
25
|
*/
|
|
22
|
-
export default function CodeMap({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, className, }: {
|
|
26
|
+
export default function CodeMap({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, className, viewport, onViewportChange, state, onStateChange, }: {
|
|
23
27
|
payload: import("./types.js").CodeMapPayload;
|
|
24
28
|
zoom?: {
|
|
25
29
|
level: "project" | "package" | "file";
|
|
@@ -38,6 +42,18 @@ export default function CodeMap({ payload, zoom, onZoomChange, selectedId, onSel
|
|
|
38
42
|
height?: number | string;
|
|
39
43
|
ariaLabel?: string;
|
|
40
44
|
className?: string;
|
|
45
|
+
viewport?: {
|
|
46
|
+
scale: number;
|
|
47
|
+
panX: number;
|
|
48
|
+
panY: number;
|
|
49
|
+
} | null;
|
|
50
|
+
onViewportChange?: (viewport: {
|
|
51
|
+
scale: number;
|
|
52
|
+
panX: number;
|
|
53
|
+
panY: number;
|
|
54
|
+
}) => void;
|
|
55
|
+
state?: import("./codeMapState.js").CodeMapState;
|
|
56
|
+
onStateChange?: (state: import("./codeMapState.js").CodeMapState) => void;
|
|
41
57
|
}): any;
|
|
42
58
|
/**
|
|
43
59
|
* @param {import('./types.js').CodeMapPayload | undefined} payload
|
|
@@ -45,8 +45,16 @@
|
|
|
45
45
|
* @param {React.CSSProperties} [props.canvasWrapperStyle] inline style on the canvas region wrapper
|
|
46
46
|
* (e.g. a host's own responsive height clamp)
|
|
47
47
|
* @param {string} [props.className] extra class on the root
|
|
48
|
+
* @param {'canvas'|'navigator'} [props.presentation='canvas'] additive presentation switch; omitted preserves the historical canvas DOM
|
|
49
|
+
* @param {React.ReactNode} [props.navigatorSlot] host-controlled navigator content
|
|
50
|
+
* @param {(presentation:'canvas'|'navigator')=>void} [props.onPresentationChange] when present, renders the canonical browse/map switch
|
|
51
|
+
* @param {{scale:number, panX:number, panY:number}} [props.viewport]
|
|
52
|
+
* @param {(viewport:{scale:number, panX:number, panY:number})=>void} [props.onViewportChange]
|
|
53
|
+
* @param {import('./codeMapState.js').CodeMapState} [props.state] canonical controlled state
|
|
54
|
+
* @param {Partial<import('./codeMapState.js').CodeMapState>} [props.defaultState] initial canonical uncontrolled state
|
|
55
|
+
* @param {(state:import('./codeMapState.js').CodeMapState)=>void} [props.onStateChange]
|
|
48
56
|
*/
|
|
49
|
-
export default function CodeMapComposition({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, canvasSlot, rail, toolbar, sheetTitle, sheetMeta, railSide, legend, canvasWrapperClassName, canvasWrapperStyle, className, }: {
|
|
57
|
+
export default function CodeMapComposition({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, canvasSlot, rail, toolbar, sheetTitle, sheetMeta, railSide, legend, canvasWrapperClassName, canvasWrapperStyle, className, presentation, navigatorSlot, onPresentationChange, viewport, onViewportChange, state, defaultState, onStateChange, }: {
|
|
50
58
|
payload?: import("./types.js").CodeMapPayload;
|
|
51
59
|
zoom?: {
|
|
52
60
|
level: "project" | "package" | "file";
|
|
@@ -74,6 +82,22 @@ export default function CodeMapComposition({ payload, zoom, onZoomChange, select
|
|
|
74
82
|
canvasWrapperClassName?: string;
|
|
75
83
|
canvasWrapperStyle?: React.CSSProperties;
|
|
76
84
|
className?: string;
|
|
85
|
+
presentation?: "canvas" | "navigator";
|
|
86
|
+
navigatorSlot?: React.ReactNode;
|
|
87
|
+
onPresentationChange?: (presentation: "canvas" | "navigator") => void;
|
|
88
|
+
viewport?: {
|
|
89
|
+
scale: number;
|
|
90
|
+
panX: number;
|
|
91
|
+
panY: number;
|
|
92
|
+
};
|
|
93
|
+
onViewportChange?: (viewport: {
|
|
94
|
+
scale: number;
|
|
95
|
+
panX: number;
|
|
96
|
+
panY: number;
|
|
97
|
+
}) => void;
|
|
98
|
+
state?: import("./codeMapState.js").CodeMapState;
|
|
99
|
+
defaultState?: Partial<import("./codeMapState.js").CodeMapState>;
|
|
100
|
+
onStateChange?: (state: import("./codeMapState.js").CodeMapState) => void;
|
|
77
101
|
}): any;
|
|
78
102
|
/**
|
|
79
103
|
* The persistent legend explaining the canvas's four orthogonal visual channels
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeMapNavigator presents the code tree as a readable, keyboard-operable
|
|
3
|
+
* starting point. Hosts keep selection, expansion, focus, and filter state so
|
|
4
|
+
* a transition to the spatial canvas and back is lossless.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} props
|
|
7
|
+
* @param {import('./types.js').CodeMapPayload} props.payload
|
|
8
|
+
* @param {'project'|'package'|'file'} [props.grain='package']
|
|
9
|
+
* @param {Iterable<string>} [props.expandedIds]
|
|
10
|
+
* @param {(ids:string[])=>void} [props.onExpandedIdsChange]
|
|
11
|
+
* @param {string|null} [props.selectedId]
|
|
12
|
+
* @param {(id:string|null, node:import('./types.js').MapNodePayload|null)=>void} [props.onSelect]
|
|
13
|
+
* @param {string|null} [props.focusedId]
|
|
14
|
+
* @param {(id:string|null)=>void} [props.onFocusChange]
|
|
15
|
+
* @param {string} [props.filter='']
|
|
16
|
+
* @param {(filter:string)=>void} [props.onFilterChange]
|
|
17
|
+
* @param {(id:string)=>void} [props.onOpenMap]
|
|
18
|
+
* @param {(action:import('./codeMapState.js').CodeMapAction)=>void} [props.onStateAction]
|
|
19
|
+
* @param {string} [props.ariaLabel='code map navigator']
|
|
20
|
+
*/
|
|
21
|
+
export default function CodeMapNavigator({ payload, grain, expandedIds, onExpandedIdsChange, selectedId, onSelect, focusedId, onFocusChange, filter, onFilterChange, onOpenMap, onStateAction, ariaLabel, }: {
|
|
22
|
+
payload: import("./types.js").CodeMapPayload;
|
|
23
|
+
grain?: "project" | "package" | "file";
|
|
24
|
+
expandedIds?: Iterable<string>;
|
|
25
|
+
onExpandedIdsChange?: (ids: string[]) => void;
|
|
26
|
+
selectedId?: string | null;
|
|
27
|
+
onSelect?: (id: string | null, node: import("./types.js").MapNodePayload | null) => void;
|
|
28
|
+
focusedId?: string | null;
|
|
29
|
+
onFocusChange?: (id: string | null) => void;
|
|
30
|
+
filter?: string;
|
|
31
|
+
onFilterChange?: (filter: string) => void;
|
|
32
|
+
onOpenMap?: (id: string) => void;
|
|
33
|
+
onStateAction?: (action: import("./codeMapState.js").CodeMapAction) => void;
|
|
34
|
+
ariaLabel?: string;
|
|
35
|
+
}): any;
|
|
@@ -58,6 +58,10 @@ export type CommitGraphRow = {
|
|
|
58
58
|
* a recorded session sits behind this commit (→ filled dot + sparkle)
|
|
59
59
|
*/
|
|
60
60
|
session?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* named sessions bound to this commit
|
|
63
|
+
*/
|
|
64
|
+
sessionRefs?: import("./types.js").TimelineSessionPayload[];
|
|
61
65
|
/**
|
|
62
66
|
* this commit merged a branch back in (→ merged chip)
|
|
63
67
|
*/
|
|
@@ -103,4 +107,12 @@ export type ChangesGraph = {
|
|
|
103
107
|
* number of merged changes
|
|
104
108
|
*/
|
|
105
109
|
mergedCount: number;
|
|
110
|
+
/**
|
|
111
|
+
* sessions not linked to a commit in this timeline window
|
|
112
|
+
*/
|
|
113
|
+
unlinkedSessions: import("./types.js").TimelineSessionPayload[];
|
|
114
|
+
/**
|
|
115
|
+
* sessions linked to a commit outside the displayed default-branch window
|
|
116
|
+
*/
|
|
117
|
+
outsideWindowSessions: import("./types.js").TimelineSessionPayload[];
|
|
106
118
|
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** @param {unknown} value @returns {value is number} */
|
|
2
|
+
export function isCodeMapViewportScale(value: unknown): value is number;
|
|
3
|
+
/**
|
|
4
|
+
* Creates a canonical, JSON-safe code-map interaction state.
|
|
5
|
+
* @param {Partial<CodeMapState>|null} [seed]
|
|
6
|
+
* @returns {CodeMapState}
|
|
7
|
+
*/
|
|
8
|
+
export function createCodeMapState(seed?: Partial<CodeMapState> | null): CodeMapState;
|
|
9
|
+
/** @param {CodeMapState} left @param {CodeMapState} right */
|
|
10
|
+
export function codeMapStatesEqual(left: CodeMapState, right: CodeMapState): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Applies one semantic interaction and returns a fresh canonical state.
|
|
13
|
+
* @param {CodeMapState} state
|
|
14
|
+
* @param {CodeMapAction} action
|
|
15
|
+
* @returns {CodeMapState}
|
|
16
|
+
*/
|
|
17
|
+
export function reduceCodeMapState(state: CodeMapState, action: CodeMapAction): CodeMapState;
|
|
18
|
+
/**
|
|
19
|
+
* Derives the complete navigator and canvas inputs from payload plus canonical state.
|
|
20
|
+
* Returned nodes are plain public payload data; no private indexes or depths are attached.
|
|
21
|
+
* @param {import('./types.js').CodeMapPayload|undefined|null} payload
|
|
22
|
+
* @param {CodeMapState} state
|
|
23
|
+
* @returns {CodeMapView}
|
|
24
|
+
*/
|
|
25
|
+
export function deriveCodeMapView(payload: import("./types.js").CodeMapPayload | undefined | null, state: CodeMapState): CodeMapView;
|
|
26
|
+
/** @typedef {import('./types.js').MapNodePayload} MapNodePayload */
|
|
27
|
+
/** @typedef {{type:'replace'|'hydrate', state:Partial<CodeMapState>} | {type:'set-presentation', presentation:CodeMapPresentation} | {type:'select'|'toggle-expanded'|'open-in-map', id:string} | {type:'focus', id:string|null} | {type:'clear-selection'} | {type:'set-filter', filter:string} | {type:'set-expanded', ids:Iterable<string>} | {type:'set-grain', grain:CodeMapGrain} | {type:'set-viewport', viewport:CodeMapViewport|null} | {type:'reveal', id:string, grain:CodeMapGrain, expandedIds:Iterable<string>}} CodeMapAction */
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {object} CodeMapState
|
|
30
|
+
* @property {1} version
|
|
31
|
+
* @property {CodeMapPresentation} presentation
|
|
32
|
+
* @property {string|null} selectedId
|
|
33
|
+
* @property {CodeMapGrain} grain
|
|
34
|
+
* @property {string[]} expandedIds
|
|
35
|
+
* @property {string} navigatorFilter
|
|
36
|
+
* @property {string|null} navigatorFocusedId
|
|
37
|
+
* @property {CodeMapViewport|null} viewport
|
|
38
|
+
*/
|
|
39
|
+
/** @typedef {{node:import('./types.js').MapNodePayload, depth:number, parentId:string|null, childIds:string[], hasChildren:boolean, canExpand:boolean, forcedOpen:boolean, expanded:boolean}} CodeMapNavigatorRow */
|
|
40
|
+
/** @typedef {{orderedIds:string[], rootIds:string[], childIdsByParent:Record<string,string[]>, depthById:Record<string,number>}} CodeMapHierarchy */
|
|
41
|
+
/** @typedef {{allNodes:import('./types.js').MapNodePayload[], nodes:import('./types.js').MapNodePayload[], visibleIds:string[], selectedId:string|null, grain:CodeMapGrain, expandedIds:string[], viewport:CodeMapViewport|null, hierarchy:CodeMapHierarchy}} CodeMapCanvasView */
|
|
42
|
+
/** @typedef {{state:CodeMapState, rows:CodeMapNavigatorRow[], focusedId:string|null, selected:import('./types.js').MapNodePayload|null, staleSelectedId:string|null, canvas:CodeMapCanvasView}} CodeMapView */
|
|
43
|
+
export const CODE_MAP_STATE_VERSION: 1;
|
|
44
|
+
export const CODE_MAP_VIEWPORT_SCALE: Readonly<{
|
|
45
|
+
min: 0.35;
|
|
46
|
+
max: 2.4;
|
|
47
|
+
}>;
|
|
48
|
+
export const CODE_MAP_GRAIN_DEPTH: Readonly<{
|
|
49
|
+
project: 0;
|
|
50
|
+
package: 1;
|
|
51
|
+
file: 1;
|
|
52
|
+
}>;
|
|
53
|
+
export type CodeMapPresentation = "navigator" | "canvas";
|
|
54
|
+
export type CodeMapGrain = "project" | "package" | "file";
|
|
55
|
+
export type CodeMapViewport = {
|
|
56
|
+
scale: number;
|
|
57
|
+
panX: number;
|
|
58
|
+
panY: number;
|
|
59
|
+
};
|
|
60
|
+
export type MapNodePayload = import("./types.js").MapNodePayload;
|
|
61
|
+
export type CodeMapAction = {
|
|
62
|
+
type: "replace" | "hydrate";
|
|
63
|
+
state: Partial<CodeMapState>;
|
|
64
|
+
} | {
|
|
65
|
+
type: "set-presentation";
|
|
66
|
+
presentation: CodeMapPresentation;
|
|
67
|
+
} | {
|
|
68
|
+
type: "select" | "toggle-expanded" | "open-in-map";
|
|
69
|
+
id: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: "focus";
|
|
72
|
+
id: string | null;
|
|
73
|
+
} | {
|
|
74
|
+
type: "clear-selection";
|
|
75
|
+
} | {
|
|
76
|
+
type: "set-filter";
|
|
77
|
+
filter: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: "set-expanded";
|
|
80
|
+
ids: Iterable<string>;
|
|
81
|
+
} | {
|
|
82
|
+
type: "set-grain";
|
|
83
|
+
grain: CodeMapGrain;
|
|
84
|
+
} | {
|
|
85
|
+
type: "set-viewport";
|
|
86
|
+
viewport: CodeMapViewport | null;
|
|
87
|
+
} | {
|
|
88
|
+
type: "reveal";
|
|
89
|
+
id: string;
|
|
90
|
+
grain: CodeMapGrain;
|
|
91
|
+
expandedIds: Iterable<string>;
|
|
92
|
+
};
|
|
93
|
+
export type CodeMapState = {
|
|
94
|
+
version: 1;
|
|
95
|
+
presentation: CodeMapPresentation;
|
|
96
|
+
selectedId: string | null;
|
|
97
|
+
grain: CodeMapGrain;
|
|
98
|
+
expandedIds: string[];
|
|
99
|
+
navigatorFilter: string;
|
|
100
|
+
navigatorFocusedId: string | null;
|
|
101
|
+
viewport: CodeMapViewport | null;
|
|
102
|
+
};
|
|
103
|
+
export type CodeMapNavigatorRow = {
|
|
104
|
+
node: import("./types.js").MapNodePayload;
|
|
105
|
+
depth: number;
|
|
106
|
+
parentId: string | null;
|
|
107
|
+
childIds: string[];
|
|
108
|
+
hasChildren: boolean;
|
|
109
|
+
canExpand: boolean;
|
|
110
|
+
forcedOpen: boolean;
|
|
111
|
+
expanded: boolean;
|
|
112
|
+
};
|
|
113
|
+
export type CodeMapHierarchy = {
|
|
114
|
+
orderedIds: string[];
|
|
115
|
+
rootIds: string[];
|
|
116
|
+
childIdsByParent: Record<string, string[]>;
|
|
117
|
+
depthById: Record<string, number>;
|
|
118
|
+
};
|
|
119
|
+
export type CodeMapCanvasView = {
|
|
120
|
+
allNodes: import("./types.js").MapNodePayload[];
|
|
121
|
+
nodes: import("./types.js").MapNodePayload[];
|
|
122
|
+
visibleIds: string[];
|
|
123
|
+
selectedId: string | null;
|
|
124
|
+
grain: CodeMapGrain;
|
|
125
|
+
expandedIds: string[];
|
|
126
|
+
viewport: CodeMapViewport | null;
|
|
127
|
+
hierarchy: CodeMapHierarchy;
|
|
128
|
+
};
|
|
129
|
+
export type CodeMapView = {
|
|
130
|
+
state: CodeMapState;
|
|
131
|
+
rows: CodeMapNavigatorRow[];
|
|
132
|
+
focusedId: string | null;
|
|
133
|
+
selected: import("./types.js").MapNodePayload | null;
|
|
134
|
+
staleSelectedId: string | null;
|
|
135
|
+
canvas: CodeMapCanvasView;
|
|
136
|
+
};
|