@xenosystem/blocks 0.12.2 → 0.12.4

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.
@@ -1361,7 +1361,14 @@ declare class InspectorPanelController {
1361
1361
  * components cannot cross a sandbox RPC boundary, so a sandboxed host simply cannot supply them and
1362
1362
  * `type:'custom'` fields degrade to their JSON representation (union spec §1.1).
1363
1363
  */
1364
- type CreateInspectorPanelOptions = InspectorPanelControllerOptions;
1364
+ interface CreateInspectorPanelOptions extends InspectorPanelControllerOptions {
1365
+ /**
1366
+ * Draw the panel yourself — a host that mounts the block AS ITS DECLARATION renders
1367
+ * `INSPECTOR_DECLARATION` from `inspectorViewState(controller)` with `inspectorRuntimeComponents(controller)`
1368
+ * in its registry and applies `ui` intents with `applyInspectorUi`. Default: the code view.
1369
+ */
1370
+ render?: (root: HTMLElement, controller: InspectorPanelController) => () => void;
1371
+ }
1365
1372
  /**
1366
1373
  * Build the Inspector panel module.
1367
1374
  *
@@ -1608,7 +1615,7 @@ declare function inspectorViewState(c: InspectorPanelController): InspectorViewS
1608
1615
  /** Apply a `ui` intent to the controller — the runtime's half of the contract. */
1609
1616
  declare function applyInspectorUi(c: InspectorPanelController, intent: InspectorUiIntent): void;
1610
1617
  declare const inspectorViewManifest: PanelManifest;
1611
- declare const BEHAVIOURS: {
1618
+ declare const BEHAVIOURS$1: {
1612
1619
  'edit/inspectorPanelView': (inputs: Record<string, unknown>) => InspectorViewState;
1613
1620
  };
1614
1621
  declare const INSPECTOR_DECLARATION: BlockDeclaration;
@@ -1976,7 +1983,14 @@ declare class HistoryPanelController {
1976
1983
  */
1977
1984
 
1978
1985
  /** Options for {@link createHistoryPanel}. */
1979
- type CreateHistoryPanelOptions = HistoryPanelControllerOptions;
1986
+ interface CreateHistoryPanelOptions extends HistoryPanelControllerOptions {
1987
+ /**
1988
+ * Draw the panel yourself — a host that mounts the block AS ITS DECLARATION renders
1989
+ * `HISTORY_DECLARATION` from `historyViewState(controller)` with `historyRuntimeComponents(controller)`
1990
+ * in its registry and applies `ui` intents with `applyHistoryUi`. Default: the code view.
1991
+ */
1992
+ render?: (root: HTMLElement, controller: HistoryPanelController) => () => void;
1993
+ }
1980
1994
  /**
1981
1995
  * Build the History panel module.
1982
1996
  *
@@ -2098,10 +2112,10 @@ declare function resolveIconName(kind: string | undefined, hostMap?: Record<stri
2098
2112
  * `useSyncExternalStore` and forwards interactions. No projection logic, no intent construction and
2099
2113
  * no virtualization math live here.
2100
2114
  *
2101
- * Rendered over the chrome family: a `Toolbar` of undo/redo/search/count/clear, an `InlineConfirm`
2102
- * for clearing, a `ScrollArea` the virtualizer measures, a `VirtualWindow` of `Row`s (the current
2103
- * row `selected`, the keyboard row `focused`, future entries `struck` — Photoshop's affordance),
2104
- * and a `StatusBar` for memory. The window math and the keyboard model stay in the controller.
2115
+ * Drawn from the SAME view state as `HISTORY_DECLARATION` (`historyViewState(controller)`) — the
2116
+ * declaration test holds the two byte-identical. The window math and the keyboard model stay in the
2117
+ * controller; the scroller (`HistoryScroller`) is the one runtime-bound unit: the element the
2118
+ * virtualizer measures, whose scrollTop the controller mirrors, the keys listen on.
2105
2119
  *
2106
2120
  * @module
2107
2121
  */
@@ -2111,6 +2125,109 @@ interface HistoryPanelViewProps {
2111
2125
  controller: HistoryPanelController;
2112
2126
  }
2113
2127
  declare function HistoryPanelView({ controller }: HistoryPanelViewProps): ReactElement;
2128
+ /**
2129
+ * The units the runtime registers for `HISTORY_DECLARATION`, bound to ITS controller: the scroller,
2130
+ * the cancel button, and the glyphs.
2131
+ */
2132
+ declare function historyRuntimeComponents(controller: HistoryPanelController): Record<string, React.ComponentType<any>>;
2133
+
2134
+ /**
2135
+ * The history panel AS A DECLARATION — the sixth block written the §8d way (auth gate, agent, account,
2136
+ * transport, inspector, history), and the first virtualized list.
2137
+ *
2138
+ * Presentation contract: input `view` (a {@link HistoryViewState} the runtime derives from the
2139
+ * controller on every draw — the window already computed, every row flag decided), output `ui`
2140
+ * (a {@link HistoryUiIntent}) applied by the runtime to the controller's own methods. The declaration
2141
+ * composes everything a reader sees: the toolbar, the inline confirmation, the pruned note, the
2142
+ * virtual window of rows, the empty state, the memory status bar.
2143
+ *
2144
+ * What a declaration cannot hold is the SCROLLER: the element the virtualizer measures, whose
2145
+ * `scrollTop` the controller mirrors, the keyboard model listens on. That is `history/Scroller`, a
2146
+ * unit the runtime registers bound to its controller ({@link historyRuntimeComponents}) — the same
2147
+ * shape as the inspector's cell. The rows inside it are data.
2148
+ */
2149
+
2150
+ interface HistoryViewRow {
2151
+ key: string;
2152
+ entryId: string | null;
2153
+ label: string;
2154
+ meta?: number;
2155
+ current: boolean;
2156
+ future: boolean;
2157
+ focused: boolean;
2158
+ jumpable: boolean;
2159
+ showIcon: boolean;
2160
+ hideIcon: boolean;
2161
+ iconName: string;
2162
+ pending: boolean;
2163
+ failed: boolean;
2164
+ showSource: boolean;
2165
+ sourceGlyph: string;
2166
+ sourceTitle: string;
2167
+ showCoalesced: boolean;
2168
+ coalescedText: string;
2169
+ coalescedTitle: string;
2170
+ showTime: boolean;
2171
+ time: string;
2172
+ height: number;
2173
+ cancelId?: string;
2174
+ }
2175
+ interface HistoryViewState {
2176
+ canUndo: boolean;
2177
+ canRedo: boolean;
2178
+ cannotUndo: boolean;
2179
+ cannotRedo: boolean;
2180
+ searchShown: boolean;
2181
+ filter: string;
2182
+ counter: string;
2183
+ clearAllowed: boolean;
2184
+ confirmingClear: boolean;
2185
+ pruned: boolean;
2186
+ totalHeight: number;
2187
+ offsetTop: number;
2188
+ rows: HistoryViewRow[];
2189
+ empty: boolean;
2190
+ hasMemory: boolean;
2191
+ memoryText: string;
2192
+ memoryDisk?: string;
2193
+ }
2194
+ type HistoryUiIntent = {
2195
+ kind: 'undo';
2196
+ } | {
2197
+ kind: 'redo';
2198
+ } | {
2199
+ kind: 'filter';
2200
+ value: string;
2201
+ } | {
2202
+ kind: 'requestClear';
2203
+ } | {
2204
+ kind: 'confirmClear';
2205
+ } | {
2206
+ kind: 'cancelClear';
2207
+ } | {
2208
+ kind: 'jump';
2209
+ entryId: string | null;
2210
+ } | {
2211
+ kind: 'hover';
2212
+ entryId: string | null;
2213
+ } | {
2214
+ kind: 'contextMenu';
2215
+ entryId: string | null;
2216
+ x: number;
2217
+ y: number;
2218
+ } | {
2219
+ kind: 'cancelPending';
2220
+ entryId?: string;
2221
+ };
2222
+ /** Derive the view state from the live controller — the runtime calls this on every draw. */
2223
+ declare function historyViewState(c: HistoryPanelController): HistoryViewState;
2224
+ /** Apply a `ui` intent to the controller — the runtime's half of the contract. */
2225
+ declare function applyHistoryUi(c: HistoryPanelController, intent: HistoryUiIntent): void;
2226
+ declare const historyViewManifest: PanelManifest;
2227
+ declare const BEHAVIOURS: {
2228
+ 'edit/historyPanelView': (inputs: Record<string, unknown>) => HistoryViewState;
2229
+ };
2230
+ declare const HISTORY_DECLARATION: BlockDeclaration;
2114
2231
 
2115
2232
  /**
2116
2233
  * Internal color math for `@xenosystem/blocks/edit`.
@@ -6610,4 +6727,4 @@ declare function TreeIcon({ name, size }: {
6610
6727
  size?: number;
6611
6728
  }): ReactNode;
6612
6729
 
6613
- export { type BlendModeGroup, type BlendModeOption, type Box, COLOR_SPACES, COMMENTS_PANEL_ID, CURVE_PANEL_ID, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsViewState, type ConnectRules, type ConnectVerdict, type CreateColorPanelOptions, type CreateCommentsPanelOptions, type CreateCurvePanelOptions, type CreateFindPanelOptions, type CreateHistoryPanelOptions, type CreateInspectorPanelOptions, type CreateLayersPanelOptions, type CreateNodeGraphPanelOptions, type CreateTreePanelOptions, type CreateViewportPanelOptions, CurveController, type CurveControllerOptions, type CurveDragKind, type CurveDragState, type CurveHostBridge, type CurvePanelState, CurvePanelView, type CurvePanelViewProps, type CurvePreview, type CurveRenderConfig, type CurveRenderContext, type CurveViewState, DEFAULT_BLEND_MODES, DEFAULT_CURVE_ZOOM, DEFAULT_GRAPH_ZOOM, DEFAULT_ICON_MAP, DEFAULT_ORIGINAL_LABEL, type DropInput, EASING_PRESETS, EDIT_SPACES, EMPTY_HISTORY, EMPTY_SCHEMA, EMPTY_TREE, EMPTY_TREE_SOURCE, FIND_PANEL_ID, FindController, type FindControllerOptions, type FindHostBridge, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindViewState, type FlatRow, type FlattenOptions, GENERIC_ICON, GraphController, type GraphControllerOptions, type GraphDragKind, type GraphDragState, type GraphHostBridge, type GraphPanelState, type GraphPreview, type GraphRenderConfig, type GraphRenderContext, type GraphViewState, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, BEHAVIOURS as INSPECTOR_BEHAVIOURS, INSPECTOR_DECLARATION, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, type InspectorUiIntent, type InspectorViewField, type InspectorViewSection, type InspectorViewState, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, MIXED, NODEGRAPH_PANEL_ID, NodeGraphPanelView, type NodeGraphPanelViewProps, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, type ScrubOptions, type SelectMods, TREE_PANEL_ID, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, type TreeViewState, VIEWPORT_PANEL_ID, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, type ViewportViewState, type XenoAddMenuItem, type XenoAnchorState, type XenoColorValue, type XenoCommentAuthor, type XenoCommentFilter, type XenoCommentMessage, type XenoCommentOp, type XenoCommentReaction, type XenoCommentSort, type XenoCommentThread, type XenoCommitPolicy, type XenoContextMenuRequest, type XenoCurveChannel, type XenoCurveInterpolation, type XenoCurveKey, type XenoCurveKeyRef, type XenoCurveOp, type XenoCurvePoint, XenoCurveScale, type XenoCurveScaleGeometry, type XenoCurveScaleState, type XenoCurveSelection, type XenoCurveSet, type XenoCurveViewport, type XenoCurveZoom, type XenoEasingPreset, type XenoEdge, type XenoFieldAnim, type XenoFieldFocus, type XenoFieldOption, type XenoFieldToken, type XenoFieldType, type XenoFieldValue, type XenoFindMatch, type XenoFindNavigate, type XenoFindOptions, type XenoFindQuery, type XenoFindReplace, type XenoFindResults, type XenoFindStatus, type XenoGradient, type XenoGraph, type XenoGraphOp, XenoGraphScale, type XenoGraphScaleGeometry, type XenoGraphScaleState, type XenoGraphSelection, type XenoGraphViewport, type XenoGraphZoom, type XenoHistoryEntry, type XenoHistoryIntent, type XenoHistoryMemory, type XenoHistoryOrder, type XenoHistoryScope, type XenoHistorySnapshot, type XenoHistorySource, type XenoHistoryState, type XenoHistoryStatus, type XenoInspectorEdit, type XenoInspectorField, type XenoInspectorSchema, type XenoInspectorSection, type XenoInspectorTarget, type XenoInspectorToken, type XenoKeyframeKind, type XenoLayerAdornment, type XenoLayerCap, type XenoLayerKind, type XenoLayerNode, type XenoLayerOp, type XenoLayerTree, type XenoNavigateRequest, type XenoNode, XenoNodeIndex, type XenoPort, type XenoPortDirection, type XenoPortRef, type XenoSectionAction, type XenoTangent, type XenoTangentMode, type XenoTangentSide, type XenoThreadActivate, type XenoThumbnailRequest, type XenoThumbnailResponse, type XenoTreeAction, type XenoTreeBadge, type XenoTreeCaps, type XenoTreeChildState, type XenoTreeChildrenResponse, type XenoTreeError, type XenoTreeGlyph, type XenoTreeIcon, type XenoTreeInvalidate, type XenoTreeMode, type XenoTreeModifiers, type XenoTreeNode, type XenoTreeNodeKind, type XenoTreeOp, type XenoTreeReveal, type XenoTreeSource, type XenoTreeSourceKind, type XenoTreeSourceState, type XenoViewportClient, type XenoViewportKey, type XenoViewportPointer, type XenoViewportSlot, type XenoViewportStats, type XenoViewportSurface, allFields, allIds, anchorStateOf, appliedCount, applyInspectorUi, applyPrecision, applyTangentDrag, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, commentsManifest, commentsPanel, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findSectionOf, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, hslToRgb, hsvFromHex, hsvToRgb, inspectorManifest, inspectorPanel, inspectorRuntimeComponents, inspectorViewManifest, inspectorViewState, interpolateSegment, isAncestorOf, isAnimated, isCollapsed, isColorSpace, isContainer, isEmptyContainer, isFieldEditable, isFieldMixed, isJumpable, isKeyEditable, isLayerColumn, isMixedValue, isOrphaned, isTreeContainer, isValidHex, isViewStateOp, keyRefId, layersManifest, layersPanel, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, normalizeColorInput, normalizeHistoryState, normalizeKindKey, normalizeNumeric, normalizeRanges, normalizeSchema, normalizeTree, nudgeValue, oklchToRgb, parseCssColor, parseHexColor, parseNumeric, passesFilter, patternError, portHasRoom, portRefId, positionToValue, projectRows, projectSections, rangeBetween, resolveDropTarget, resolveIconName, rgbToHex, rgbToHsl, rgbToHsv, rgbToOklch, rgbaToCssHex, roundRgb, rowIndexOf, rowIndexOfEntry, safeAddColorStop, safeAddColorStops, sameKey, sampleChannel, scrubValue, segmentsAround, solveBezierT, sortThreads, surfaceChanged, tangentsForMode, tangentsToControlPoints, toViewportCoords, totalCount, treeManifest, treePanel, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
6730
+ export { type BlendModeGroup, type BlendModeOption, type Box, COLOR_SPACES, COMMENTS_PANEL_ID, CURVE_PANEL_ID, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsViewState, type ConnectRules, type ConnectVerdict, type CreateColorPanelOptions, type CreateCommentsPanelOptions, type CreateCurvePanelOptions, type CreateFindPanelOptions, type CreateHistoryPanelOptions, type CreateInspectorPanelOptions, type CreateLayersPanelOptions, type CreateNodeGraphPanelOptions, type CreateTreePanelOptions, type CreateViewportPanelOptions, CurveController, type CurveControllerOptions, type CurveDragKind, type CurveDragState, type CurveHostBridge, type CurvePanelState, CurvePanelView, type CurvePanelViewProps, type CurvePreview, type CurveRenderConfig, type CurveRenderContext, type CurveViewState, DEFAULT_BLEND_MODES, DEFAULT_CURVE_ZOOM, DEFAULT_GRAPH_ZOOM, DEFAULT_ICON_MAP, DEFAULT_ORIGINAL_LABEL, type DropInput, EASING_PRESETS, EDIT_SPACES, EMPTY_HISTORY, EMPTY_SCHEMA, EMPTY_TREE, EMPTY_TREE_SOURCE, FIND_PANEL_ID, FindController, type FindControllerOptions, type FindHostBridge, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindViewState, type FlatRow, type FlattenOptions, GENERIC_ICON, GraphController, type GraphControllerOptions, type GraphDragKind, type GraphDragState, type GraphHostBridge, type GraphPanelState, type GraphPreview, type GraphRenderConfig, type GraphRenderContext, type GraphViewState, BEHAVIOURS as HISTORY_BEHAVIOURS, HISTORY_DECLARATION, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type HistoryUiIntent, type HistoryViewRow, type HistoryViewState, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, BEHAVIOURS$1 as INSPECTOR_BEHAVIOURS, INSPECTOR_DECLARATION, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, type InspectorUiIntent, type InspectorViewField, type InspectorViewSection, type InspectorViewState, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, MIXED, NODEGRAPH_PANEL_ID, NodeGraphPanelView, type NodeGraphPanelViewProps, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, type ScrubOptions, type SelectMods, TREE_PANEL_ID, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, type TreeViewState, VIEWPORT_PANEL_ID, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, type ViewportViewState, type XenoAddMenuItem, type XenoAnchorState, type XenoColorValue, type XenoCommentAuthor, type XenoCommentFilter, type XenoCommentMessage, type XenoCommentOp, type XenoCommentReaction, type XenoCommentSort, type XenoCommentThread, type XenoCommitPolicy, type XenoContextMenuRequest, type XenoCurveChannel, type XenoCurveInterpolation, type XenoCurveKey, type XenoCurveKeyRef, type XenoCurveOp, type XenoCurvePoint, XenoCurveScale, type XenoCurveScaleGeometry, type XenoCurveScaleState, type XenoCurveSelection, type XenoCurveSet, type XenoCurveViewport, type XenoCurveZoom, type XenoEasingPreset, type XenoEdge, type XenoFieldAnim, type XenoFieldFocus, type XenoFieldOption, type XenoFieldToken, type XenoFieldType, type XenoFieldValue, type XenoFindMatch, type XenoFindNavigate, type XenoFindOptions, type XenoFindQuery, type XenoFindReplace, type XenoFindResults, type XenoFindStatus, type XenoGradient, type XenoGraph, type XenoGraphOp, XenoGraphScale, type XenoGraphScaleGeometry, type XenoGraphScaleState, type XenoGraphSelection, type XenoGraphViewport, type XenoGraphZoom, type XenoHistoryEntry, type XenoHistoryIntent, type XenoHistoryMemory, type XenoHistoryOrder, type XenoHistoryScope, type XenoHistorySnapshot, type XenoHistorySource, type XenoHistoryState, type XenoHistoryStatus, type XenoInspectorEdit, type XenoInspectorField, type XenoInspectorSchema, type XenoInspectorSection, type XenoInspectorTarget, type XenoInspectorToken, type XenoKeyframeKind, type XenoLayerAdornment, type XenoLayerCap, type XenoLayerKind, type XenoLayerNode, type XenoLayerOp, type XenoLayerTree, type XenoNavigateRequest, type XenoNode, XenoNodeIndex, type XenoPort, type XenoPortDirection, type XenoPortRef, type XenoSectionAction, type XenoTangent, type XenoTangentMode, type XenoTangentSide, type XenoThreadActivate, type XenoThumbnailRequest, type XenoThumbnailResponse, type XenoTreeAction, type XenoTreeBadge, type XenoTreeCaps, type XenoTreeChildState, type XenoTreeChildrenResponse, type XenoTreeError, type XenoTreeGlyph, type XenoTreeIcon, type XenoTreeInvalidate, type XenoTreeMode, type XenoTreeModifiers, type XenoTreeNode, type XenoTreeNodeKind, type XenoTreeOp, type XenoTreeReveal, type XenoTreeSource, type XenoTreeSourceKind, type XenoTreeSourceState, type XenoViewportClient, type XenoViewportKey, type XenoViewportPointer, type XenoViewportSlot, type XenoViewportStats, type XenoViewportSurface, allFields, allIds, anchorStateOf, appliedCount, applyHistoryUi, applyInspectorUi, applyPrecision, applyTangentDrag, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, commentsManifest, commentsPanel, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findSectionOf, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, historyRuntimeComponents, historyViewManifest, historyViewState, hslToRgb, hsvFromHex, hsvToRgb, inspectorManifest, inspectorPanel, inspectorRuntimeComponents, inspectorViewManifest, inspectorViewState, interpolateSegment, isAncestorOf, isAnimated, isCollapsed, isColorSpace, isContainer, isEmptyContainer, isFieldEditable, isFieldMixed, isJumpable, isKeyEditable, isLayerColumn, isMixedValue, isOrphaned, isTreeContainer, isValidHex, isViewStateOp, keyRefId, layersManifest, layersPanel, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, normalizeColorInput, normalizeHistoryState, normalizeKindKey, normalizeNumeric, normalizeRanges, normalizeSchema, normalizeTree, nudgeValue, oklchToRgb, parseCssColor, parseHexColor, parseNumeric, passesFilter, patternError, portHasRoom, portRefId, positionToValue, projectRows, projectSections, rangeBetween, resolveDropTarget, resolveIconName, rgbToHex, rgbToHsl, rgbToHsv, rgbToOklch, rgbaToCssHex, roundRgb, rowIndexOf, rowIndexOfEntry, safeAddColorStop, safeAddColorStops, sameKey, sampleChannel, scrubValue, segmentsAround, solveBezierT, sortThreads, surfaceChanged, tangentsForMode, tangentsToControlPoints, toViewportCoords, totalCount, treeManifest, treePanel, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
@@ -1871,8 +1871,8 @@ function constraintsOf(field) {
1871
1871
  scale: field.scale
1872
1872
  };
1873
1873
  }
1874
- function parseNumeric(text2) {
1875
- const trimmed = String(text2).trim();
1874
+ function parseNumeric(text3) {
1875
+ const trimmed = String(text3).trim();
1876
1876
  if (trimmed.length === 0) return { ok: false, reason: "empty" };
1877
1877
  const match = /^[+-]?(\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/.exec(trimmed);
1878
1878
  if (!match) return { ok: false, reason: "nan" };
@@ -1897,8 +1897,8 @@ function normalizeNumeric(value, c) {
1897
1897
  function formatNumeric(value, field) {
1898
1898
  if (!Number.isFinite(value)) return "";
1899
1899
  const precision = field.precision;
1900
- const text2 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
1901
- return field.unit ? `${text2}${field.unit}` : text2;
1900
+ const text3 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
1901
+ return field.unit ? `${text3}${field.unit}` : text3;
1902
1902
  }
1903
1903
  function usesLogScale(c) {
1904
1904
  return c.scale === "log" && typeof c.min === "number" && typeof c.max === "number" && c.min > 0 && c.max > c.min;
@@ -2232,44 +2232,44 @@ var InspectorPanelController = class {
2232
2232
  if (!field || !isFieldEditable(field)) return;
2233
2233
  const mixed = isFieldMixed(field);
2234
2234
  const value = this.getFieldValue(fieldId);
2235
- const text2 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
2236
- this.drafts.set(fieldId, { text: text2, original: value });
2235
+ const text3 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
2236
+ this.drafts.set(fieldId, { text: text3, original: value });
2237
2237
  this.focusedFieldId = fieldId;
2238
2238
  this.emitFieldFocus(fieldId);
2239
2239
  this.notify();
2240
2240
  }
2241
2241
  /** Update the draft text (typing). Emits nothing under the `blur` policy. */
2242
- setDraft(fieldId, text2) {
2242
+ setDraft(fieldId, text3) {
2243
2243
  const draft = this.drafts.get(fieldId);
2244
2244
  if (!draft) {
2245
- this.drafts.set(fieldId, { text: text2, original: this.getFieldValue(fieldId) });
2245
+ this.drafts.set(fieldId, { text: text3, original: this.getFieldValue(fieldId) });
2246
2246
  } else {
2247
- draft.text = text2;
2247
+ draft.text = text3;
2248
2248
  }
2249
2249
  const field = this.getField(fieldId);
2250
2250
  if (field && commitPolicyOf(field) === "live") {
2251
- const parsed = this.parseDraft(fieldId, text2);
2251
+ const parsed = this.parseDraft(fieldId, text3);
2252
2252
  if (parsed.ok) this.emitSet(fieldId, parsed.value);
2253
2253
  }
2254
2254
  this.notify();
2255
2255
  }
2256
2256
  /** Parse a draft string into a field-appropriate value. */
2257
- parseDraft(fieldId, text2) {
2257
+ parseDraft(fieldId, text3) {
2258
2258
  const field = this.getField(fieldId);
2259
2259
  if (!field) return { ok: false };
2260
2260
  if (field.type === "number") {
2261
- const parsed = parseNumeric(text2);
2261
+ const parsed = parseNumeric(text3);
2262
2262
  if (!parsed.ok) return { ok: false };
2263
2263
  return { ok: true, value: normalizeNumeric(parsed.value, constraintsOf(field)) };
2264
2264
  }
2265
2265
  if (field.type === "json") {
2266
2266
  try {
2267
- return { ok: true, value: JSON.parse(text2) };
2267
+ return { ok: true, value: JSON.parse(text3) };
2268
2268
  } catch {
2269
2269
  return { ok: false };
2270
2270
  }
2271
2271
  }
2272
- return { ok: true, value: text2 };
2272
+ return { ok: true, value: text3 };
2273
2273
  }
2274
2274
  /**
2275
2275
  * Commit the draft (Enter / blur). Invalid input reverts instead of committing garbage.
@@ -3244,7 +3244,7 @@ function NumberWidget({ field, controller, component }) {
3244
3244
  },
3245
3245
  [controller, editable, field.id, component]
3246
3246
  );
3247
- const text2 = component !== void 0 ? (() => {
3247
+ const text3 = component !== void 0 ? (() => {
3248
3248
  const raw = controller.getFieldValue(field.id);
3249
3249
  const v = Array.isArray(raw) ? raw[component] : void 0;
3250
3250
  return typeof v === "number" ? formatNumeric(v, field) : "";
@@ -3256,7 +3256,7 @@ function NumberWidget({ field, controller, component }) {
3256
3256
  Input2,
3257
3257
  {
3258
3258
  inputMode: "decimal",
3259
- value: text2,
3259
+ value: text3,
3260
3260
  placeholder: mixed ? controller.getMixedPlaceholder() : field.placeholder,
3261
3261
  mixed,
3262
3262
  readOnly: !editable,
@@ -3474,7 +3474,7 @@ function ActionGlyph({ glyph }) {
3474
3474
  return /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: glyph });
3475
3475
  }
3476
3476
  function SectionView({ section, controller }) {
3477
- const ui2 = (intent) => applyInspectorUi(controller, intent);
3477
+ const ui3 = (intent) => applyInspectorUi(controller, intent);
3478
3478
  const hasActions = section.actions.length > 0 || section.hasAddMenu;
3479
3479
  return /* @__PURE__ */ jsxs5(
3480
3480
  Section,
@@ -3483,13 +3483,13 @@ function SectionView({ section, controller }) {
3483
3483
  flush: true,
3484
3484
  collapsible: section.collapsible,
3485
3485
  collapsed: section.collapsed,
3486
- onCollapsedChange: () => ui2({ kind: "toggleSectionCollapsed", sectionId: section.id }),
3486
+ onCollapsedChange: () => ui3({ kind: "toggleSectionCollapsed", sectionId: section.id }),
3487
3487
  enabled: section.enabled,
3488
- onEnabledChange: () => ui2({ kind: "toggleSectionEnabled", sectionId: section.id }),
3488
+ onEnabledChange: () => ui3({ kind: "toggleSectionEnabled", sectionId: section.id }),
3489
3489
  badge: section.badge ? /* @__PURE__ */ jsx6(Badge2, { children: section.badge }) : null,
3490
3490
  actions: hasActions ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3491
- section.actions.map((action) => /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui2({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
3492
- section.hasAddMenu ? /* @__PURE__ */ jsx6(Select2, { size: "sm", placeholder: "\uFF0B", options: section.addOptions, value: "", label: section.addLabel, onChange: (id) => ui2({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
3491
+ section.actions.map((action) => /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui3({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
3492
+ section.hasAddMenu ? /* @__PURE__ */ jsx6(Select2, { size: "sm", placeholder: "\uFF0B", options: section.addOptions, value: "", label: section.addLabel, onChange: (id) => ui3({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
3493
3493
  ] }) : null,
3494
3494
  children: [
3495
3495
  section.showEmptyHint ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: section.emptyHint }) }) : null,
@@ -3499,7 +3499,7 @@ function SectionView({ section, controller }) {
3499
3499
  );
3500
3500
  }
3501
3501
  function FieldRow({ row, controller }) {
3502
- const ui2 = (intent) => applyInspectorUi(controller, intent);
3502
+ const ui3 = (intent) => applyInspectorUi(controller, intent);
3503
3503
  return /* @__PURE__ */ jsxs5(Fragment3, { children: [
3504
3504
  /* @__PURE__ */ jsxs5(
3505
3505
  Field,
@@ -3507,19 +3507,19 @@ function FieldRow({ row, controller }) {
3507
3507
  label: row.label,
3508
3508
  title: row.title,
3509
3509
  focused: row.focused,
3510
- onLabelClick: () => ui2({ kind: "focusField", fieldId: row.id }),
3511
- onContextMenu: (x, y) => ui2({ kind: "contextMenu", fieldId: row.id, x, y }),
3510
+ onLabelClick: () => ui3({ kind: "focusField", fieldId: row.id }),
3511
+ onContextMenu: (x, y) => ui3({ kind: "contextMenu", fieldId: row.id, x, y }),
3512
3512
  leading: row.showKeyframes ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3513
- /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active: row.animated, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "toggleAnim" }) }),
3514
- row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(PrevIcon, {}), label: "Previous keyframe", disabled: row.prevDisabled, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "prev" }) }) : null,
3515
- row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(DiamondIcon, { filled: row.onKeyframe }), label: row.keyframeLabel, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: row.keyframeOp }) }) : null,
3516
- row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: row.nextDisabled, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "next" }) }) : null
3513
+ /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active: row.animated, onClick: () => ui3({ kind: "keyframe", fieldId: row.id, op: "toggleAnim" }) }),
3514
+ row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(PrevIcon, {}), label: "Previous keyframe", disabled: row.prevDisabled, onClick: () => ui3({ kind: "keyframe", fieldId: row.id, op: "prev" }) }) : null,
3515
+ row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(DiamondIcon, { filled: row.onKeyframe }), label: row.keyframeLabel, onClick: () => ui3({ kind: "keyframe", fieldId: row.id, op: row.keyframeOp }) }) : null,
3516
+ row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: row.nextDisabled, onClick: () => ui3({ kind: "keyframe", fieldId: row.id, op: "next" }) }) : null
3517
3517
  ] }) : null,
3518
3518
  trailing: /* @__PURE__ */ jsxs5(Fragment3, { children: [
3519
- row.showEasing ? /* @__PURE__ */ jsx6(Select2, { size: "sm", options: row.easingOptions, value: row.easing, label: "Easing", onChange: (v) => ui2({ kind: "setEasing", fieldId: row.id, easing: v }) }) : null,
3519
+ row.showEasing ? /* @__PURE__ */ jsx6(Select2, { size: "sm", options: row.easingOptions, value: row.easing, label: "Easing", onChange: (v) => ui3({ kind: "setEasing", fieldId: row.id, easing: v }) }) : null,
3520
3520
  row.showKeyframes ? /* @__PURE__ */ jsx6(Badge2, { size: "sm", children: row.keyframeChip }) : null,
3521
- row.showToken ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(LinkIcon, {}), label: row.tokenActionLabel, active: row.bound, onClick: () => ui2({ kind: "bindToken", fieldId: row.id }) }) : null,
3522
- row.showReset ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ResetIcon, {}), label: "Reset to default", onClick: () => ui2({ kind: "resetField", fieldId: row.id }) }) : null
3521
+ row.showToken ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(LinkIcon, {}), label: row.tokenActionLabel, active: row.bound, onClick: () => ui3({ kind: "bindToken", fieldId: row.id }) }) : null,
3522
+ row.showReset ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ResetIcon, {}), label: "Reset to default", onClick: () => ui3({ kind: "resetField", fieldId: row.id }) }) : null
3523
3523
  ] }),
3524
3524
  children: [
3525
3525
  row.bound ? /* @__PURE__ */ jsx6(Badge2, { title: row.tokenTitle, children: row.tokenLabel }) : null,
@@ -3587,11 +3587,20 @@ function createInspectorPanel(options = {}) {
3587
3587
  return {
3588
3588
  manifest: inspectorManifest,
3589
3589
  activate(host) {
3590
- const controller = new InspectorPanelController(host, options);
3590
+ const { render: customRender, ...controllerOptions } = options;
3591
+ const controller = new InspectorPanelController(host, controllerOptions);
3591
3592
  void controller.load();
3592
3593
  let root = null;
3594
+ let unrender = null;
3593
3595
  return {
3594
3596
  render(el) {
3597
+ if (customRender) {
3598
+ unrender = customRender(el, controller);
3599
+ return () => {
3600
+ unrender?.();
3601
+ unrender = null;
3602
+ };
3603
+ }
3595
3604
  root = createRoot2(el);
3596
3605
  root.render(createElement2(InspectorPanelView, { controller }));
3597
3606
  return () => {
@@ -3614,6 +3623,8 @@ function createInspectorPanel(options = {}) {
3614
3623
  dispose() {
3615
3624
  root?.unmount();
3616
3625
  root = null;
3626
+ unrender?.();
3627
+ unrender = null;
3617
3628
  controller.dispose();
3618
3629
  }
3619
3630
  };
@@ -4528,6 +4539,231 @@ var HistoryPanelController = class {
4528
4539
 
4529
4540
  // src/edit/history/react/HistoryPanelView.tsx
4530
4541
  import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef4, useSyncExternalStore as useSyncExternalStore3 } from "react";
4542
+
4543
+ // src/edit/history/react/format.ts
4544
+ function formatTime(at) {
4545
+ const date = typeof at === "number" ? new Date(at) : new Date(at);
4546
+ if (Number.isNaN(date.getTime())) return typeof at === "string" ? at : "";
4547
+ return date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
4548
+ }
4549
+
4550
+ // src/edit/history/declaration.ts
4551
+ function historyViewState(c) {
4552
+ const rows = c.getRows();
4553
+ const window_ = c.getWindow();
4554
+ const rowHeight = c.getRowHeight();
4555
+ const memory = c.getMemory();
4556
+ const focused = c.getFocused();
4557
+ const showIcons = c.areIconsShown();
4558
+ const showSource = c.isSourceShown();
4559
+ const showTime = c.areTimestampsShown();
4560
+ const jumpAllowed = c.isJumpAllowed();
4561
+ return {
4562
+ canUndo: c.canUndo(),
4563
+ canRedo: c.canRedo(),
4564
+ cannotUndo: !c.canUndo(),
4565
+ cannotRedo: !c.canRedo(),
4566
+ searchShown: c.isSearchShown(),
4567
+ filter: c.getFilter(),
4568
+ counter: `${c.getAppliedCount()} / ${c.getTotalCount()}`,
4569
+ clearAllowed: c.isClearAllowed(),
4570
+ confirmingClear: c.isConfirmingClear(),
4571
+ pruned: c.isPruned(),
4572
+ totalHeight: window_.totalHeight,
4573
+ offsetTop: window_.offsetTop,
4574
+ rows: c.getWindowRows().map((row) => {
4575
+ const entry = row.entry;
4576
+ const pending = entry?.status === "pending";
4577
+ const source = entry?.source;
4578
+ return {
4579
+ key: row.entryId ?? "__original__",
4580
+ entryId: row.entryId,
4581
+ label: row.label,
4582
+ meta: row.kind === "entry" ? row.ordinal : void 0,
4583
+ current: row.current,
4584
+ future: row.future,
4585
+ focused: focused === row.entryId,
4586
+ jumpable: jumpAllowed && entry?.caps?.jumpable !== false,
4587
+ showIcon: showIcons,
4588
+ hideIcon: !showIcons,
4589
+ iconName: row.kind === "original" ? "original" : c.getIconName(entry?.kind),
4590
+ pending,
4591
+ failed: entry?.status === "failed",
4592
+ showSource: showSource && !!source && source !== "user",
4593
+ sourceGlyph: source === "agent" ? "AI" : "S",
4594
+ sourceTitle: `Source: ${source ?? ""}`,
4595
+ showCoalesced: !!entry?.coalesced && entry.coalesced > 1,
4596
+ coalescedText: `\xD7${entry?.coalesced ?? 0}`,
4597
+ coalescedTitle: `${entry?.coalesced ?? 0} actions coalesced`,
4598
+ showTime: showTime && entry?.at !== void 0,
4599
+ time: entry?.at !== void 0 ? formatTime(entry.at) : "",
4600
+ height: rowHeight,
4601
+ cancelId: pending ? entry?.id : void 0
4602
+ };
4603
+ }),
4604
+ empty: rows.length === 0,
4605
+ hasMemory: !!memory,
4606
+ memoryText: memory ? `${memory.usedMB.toFixed(1)} MB${memory.limitMB ? ` / ${memory.limitMB} MB` : ""}` : "",
4607
+ memoryDisk: memory?.onDiskCount !== void 0 ? `${memory.onDiskCount} on disk` : void 0
4608
+ };
4609
+ }
4610
+ function applyHistoryUi(c, intent) {
4611
+ switch (intent.kind) {
4612
+ case "undo":
4613
+ c.undo();
4614
+ break;
4615
+ case "redo":
4616
+ c.redo();
4617
+ break;
4618
+ case "filter":
4619
+ c.setFilter(intent.value);
4620
+ break;
4621
+ case "requestClear":
4622
+ c.requestClear();
4623
+ break;
4624
+ case "confirmClear":
4625
+ c.confirmClearNow();
4626
+ break;
4627
+ case "cancelClear":
4628
+ c.cancelClear();
4629
+ break;
4630
+ case "jump":
4631
+ c.jumpTo(intent.entryId);
4632
+ break;
4633
+ case "hover":
4634
+ c.setHovered(intent.entryId);
4635
+ break;
4636
+ case "contextMenu":
4637
+ c.requestContextMenu(intent.entryId, intent.x, intent.y);
4638
+ break;
4639
+ case "cancelPending":
4640
+ c.cancelPending(intent.entryId);
4641
+ break;
4642
+ }
4643
+ }
4644
+ var historyViewManifest = {
4645
+ id: historyManifest.id,
4646
+ version: "1.0.0",
4647
+ title: "History",
4648
+ category: "edit",
4649
+ layout: { slot: "side" },
4650
+ inputs: [{ id: "view", type: "object", label: "View state", description: "The HistoryViewState the runtime derives from the controller on every draw." }],
4651
+ outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, entryId?, value?, x?, y? } \u2014 applied by the runtime to the controller." }],
4652
+ commands: []
4653
+ };
4654
+ var EMPTY2 = { canUndo: false, canRedo: false, cannotUndo: true, cannotRedo: true, searchShown: true, filter: "", counter: "0 / 0", clearAllowed: false, confirmingClear: false, pruned: false, totalHeight: 0, offsetTop: 0, rows: [], empty: true, hasMemory: false, memoryText: "" };
4655
+ var BEHAVIOURS2 = {
4656
+ "edit/historyPanelView": (inputs) => inputs.view ?? EMPTY2
4657
+ };
4658
+ var text2 = (b) => ({ component: "text", props: { text: b } });
4659
+ var ui2 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
4660
+ var HISTORY_DECLARATION = {
4661
+ format: "xeno.block@1",
4662
+ manifest: historyViewManifest,
4663
+ behaviour: "edit/historyPanelView",
4664
+ composition: {
4665
+ component: "chrome/Column",
4666
+ props: { className: { value: "xeno-history-panel" } },
4667
+ children: [
4668
+ {
4669
+ component: "chrome/Toolbar",
4670
+ props: {
4671
+ left: {
4672
+ node: {
4673
+ component: "fragment",
4674
+ children: [
4675
+ { component: "chrome/IconButton", props: { size: { value: "sm" }, icon: { node: { component: "history/UndoIcon" } }, label: { value: "Undo" }, disabled: { input: "view.cannotUndo" } }, on: { onClick: ui2("undo") } },
4676
+ { component: "chrome/IconButton", props: { size: { value: "sm" }, icon: { node: { component: "history/RedoIcon" } }, label: { value: "Redo" }, disabled: { input: "view.cannotRedo" } }, on: { onClick: ui2("redo") } }
4677
+ ]
4678
+ }
4679
+ },
4680
+ right: {
4681
+ node: {
4682
+ component: "fragment",
4683
+ children: [
4684
+ { component: "chrome/Text", props: { role: { value: "number" } }, children: [text2({ input: "view.counter" })] },
4685
+ { component: "chrome/IconButton", when: { input: "view.clearAllowed" }, props: { size: { value: "sm" }, icon: { node: { component: "history/TrashIcon" } }, label: { value: "Clear history" } }, on: { onClick: ui2("requestClear") } }
4686
+ ]
4687
+ }
4688
+ }
4689
+ },
4690
+ children: [
4691
+ { component: "chrome/SearchField", when: { input: "view.searchShown" }, props: { value: { input: "view.filter" }, placeholder: { value: "Search history" }, label: { value: "Search history" } }, on: { onChange: ui2("filter", { value: { arg: "" } }) } }
4692
+ ]
4693
+ },
4694
+ {
4695
+ component: "chrome/InlineConfirm",
4696
+ when: { input: "view.confirmingClear" },
4697
+ props: { message: { value: "Clear all history?" }, label: { value: "Confirm clear history" }, confirmLabel: { value: "Clear" } },
4698
+ on: { onConfirm: ui2("confirmClear"), onCancel: ui2("cancelClear") }
4699
+ },
4700
+ { component: "chrome/Text", when: { input: "view.pruned" }, props: { role: { value: "caption" } }, children: [text2({ value: "Earlier history discarded (limit reached)" })] },
4701
+ {
4702
+ component: "history/Scroller",
4703
+ children: [
4704
+ {
4705
+ component: "chrome/RowList",
4706
+ props: { role: { value: "listbox" }, "aria-label": { value: "History" } },
4707
+ children: [
4708
+ {
4709
+ component: "chrome/VirtualWindow",
4710
+ props: { totalHeight: { input: "view.totalHeight" }, offsetTop: { input: "view.offsetTop" } },
4711
+ children: [
4712
+ {
4713
+ component: "chrome/Row",
4714
+ each: { input: "view.rows", key: "key" },
4715
+ props: {
4716
+ height: { item: "height" },
4717
+ selected: { item: "current" },
4718
+ focused: { item: "focused" },
4719
+ struck: { item: "future" },
4720
+ noIcon: { item: "hideIcon" },
4721
+ interactive: { item: "jumpable" },
4722
+ icon: { node: { component: "history/EntryIcon", props: { name: { item: "iconName" } } } },
4723
+ label: { item: "label" },
4724
+ meta: { item: "meta" },
4725
+ "data-history-row": { item: "key" },
4726
+ title: { item: "label" },
4727
+ trailing: {
4728
+ node: {
4729
+ component: "fragment",
4730
+ children: [
4731
+ { component: "history/PendingGlyph", when: { item: "pending" } },
4732
+ { component: "chrome/Badge", when: { item: "failed" }, props: { size: { value: "sm" }, tone: { value: "error" } }, children: [text2({ value: "failed" })] },
4733
+ { component: "chrome/Badge", when: { item: "showSource" }, props: { size: { value: "sm" }, title: { item: "sourceTitle" } }, children: [text2({ item: "sourceGlyph" })] },
4734
+ { component: "chrome/Badge", when: { item: "showCoalesced" }, props: { size: { value: "sm" }, title: { item: "coalescedTitle" } }, children: [text2({ item: "coalescedText" })] },
4735
+ { component: "chrome/Text", when: { item: "showTime" }, props: { role: { value: "meta" } }, children: [text2({ item: "time" })] },
4736
+ { component: "history/CancelButton", when: { item: "pending" }, props: { entryId: { item: "cancelId" } } }
4737
+ ]
4738
+ }
4739
+ }
4740
+ },
4741
+ on: {
4742
+ onClick: ui2("jump", { entryId: { item: "entryId" } }),
4743
+ onMouseEnter: ui2("hover", { entryId: { item: "entryId" } }),
4744
+ onContextMenuAt: ui2("contextMenu", { entryId: { item: "entryId" }, x: { arg: "" }, y: { arg: "", index: 1 } })
4745
+ }
4746
+ }
4747
+ ]
4748
+ }
4749
+ ]
4750
+ },
4751
+ { component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { value: "No history" } } }
4752
+ ]
4753
+ },
4754
+ {
4755
+ component: "chrome/StatusBar",
4756
+ when: { input: "view.hasMemory" },
4757
+ props: {
4758
+ left: { node: { component: "chrome/Text", props: { role: { value: "number" } }, children: [text2({ input: "view.memoryText" })] } },
4759
+ right: { node: { component: "chrome/Text", when: { input: "view.memoryDisk" }, props: { role: { value: "meta" } }, children: [text2({ input: "view.memoryDisk" })] } }
4760
+ }
4761
+ }
4762
+ ]
4763
+ }
4764
+ };
4765
+
4766
+ // src/edit/history/react/HistoryPanelView.tsx
4531
4767
  import { Badge as Badge3, Column as Column3, EmptyState as EmptyState3, IconButton as IconButton4, InlineConfirm, RowList as RowList2, Row as Row2, ScrollArea as ScrollArea3, SearchField as SearchField3, StatusBar as StatusBar2, Text as Text4, Toolbar as Toolbar2, VirtualWindow as VirtualWindow2 } from "@xenosystem/components/chrome";
4532
4768
 
4533
4769
  // src/edit/history/react/icons.tsx
@@ -4629,12 +4865,34 @@ function HistoryPanelView({ controller }) {
4629
4865
  const subscribe = useCallback4((cb) => controller.subscribe(cb), [controller]);
4630
4866
  const getSnapshot = useCallback4(() => controller.getRevision(), [controller]);
4631
4867
  useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
4868
+ const view = historyViewState(controller);
4869
+ const ui3 = (intent) => applyHistoryUi(controller, intent);
4870
+ return /* @__PURE__ */ jsxs7(Column3, { className: "xeno-history-panel", children: [
4871
+ /* @__PURE__ */ jsx8(
4872
+ Toolbar2,
4873
+ {
4874
+ left: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4875
+ /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(UndoIcon, {}), label: "Undo", disabled: view.cannotUndo, onClick: () => ui3({ kind: "undo" }) }),
4876
+ /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(RedoIcon, {}), label: "Redo", disabled: view.cannotRedo, onClick: () => ui3({ kind: "redo" }) })
4877
+ ] }),
4878
+ right: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4879
+ /* @__PURE__ */ jsx8(Text4, { role: "number", children: view.counter }),
4880
+ view.clearAllowed ? /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(TrashIcon, {}), label: "Clear history", onClick: () => ui3({ kind: "requestClear" }) }) : null
4881
+ ] }),
4882
+ children: view.searchShown ? /* @__PURE__ */ jsx8(SearchField3, { value: view.filter, onChange: (v) => ui3({ kind: "filter", value: v }), placeholder: "Search history", label: "Search history" }) : null
4883
+ }
4884
+ ),
4885
+ view.confirmingClear ? /* @__PURE__ */ jsx8(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => ui3({ kind: "confirmClear" }), onCancel: () => ui3({ kind: "cancelClear" }) }) : null,
4886
+ view.pruned ? /* @__PURE__ */ jsx8(Text4, { role: "caption", children: "Earlier history discarded (limit reached)" }) : null,
4887
+ /* @__PURE__ */ jsxs7(HistoryScroller, { controller, children: [
4888
+ /* @__PURE__ */ jsx8(RowList2, { role: "listbox", "aria-label": "History", children: /* @__PURE__ */ jsx8(VirtualWindow2, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map((row) => /* @__PURE__ */ jsx8(HistoryRowView, { row, controller }, row.key)) }) }),
4889
+ view.empty ? /* @__PURE__ */ jsx8(EmptyState3, { title: "No history" }) : null
4890
+ ] }),
4891
+ view.hasMemory ? /* @__PURE__ */ jsx8(StatusBar2, { left: /* @__PURE__ */ jsx8(Text4, { role: "number", children: view.memoryText }), right: view.memoryDisk ? /* @__PURE__ */ jsx8(Text4, { role: "meta", children: view.memoryDisk }) : null }) : null
4892
+ ] });
4893
+ }
4894
+ function HistoryScroller({ controller, children }) {
4632
4895
  const scrollRef = useRef4(null);
4633
- const rows = controller.getRows();
4634
- const window_ = controller.getWindow();
4635
- const windowRows = controller.getWindowRows();
4636
- const rowHeight = controller.getRowHeight();
4637
- const memory = controller.getMemory();
4638
4896
  useEffect3(() => {
4639
4897
  const el = scrollRef.current;
4640
4898
  if (!el) return;
@@ -4654,18 +4912,10 @@ function HistoryPanelView({ controller }) {
4654
4912
  el.scrollTop = controller.getScrollTop();
4655
4913
  }
4656
4914
  });
4657
- const onScroll = useCallback4(
4658
- (e) => controller.setScrollTop(e.currentTarget.scrollTop),
4659
- [controller]
4660
- );
4915
+ const onScroll = useCallback4((e) => controller.setScrollTop(e.currentTarget.scrollTop), [controller]);
4661
4916
  const onKeyDown = useCallback4(
4662
4917
  (e) => {
4663
- const handled = controller.handleKey({
4664
- key: e.key,
4665
- ctrl: e.ctrlKey,
4666
- meta: e.metaKey,
4667
- shift: e.shiftKey
4668
- });
4918
+ const handled = controller.handleKey({ key: e.key, ctrl: e.ctrlKey, meta: e.metaKey, shift: e.shiftKey });
4669
4919
  if (handled) {
4670
4920
  e.preventDefault();
4671
4921
  e.stopPropagation();
@@ -4673,109 +4923,62 @@ function HistoryPanelView({ controller }) {
4673
4923
  },
4674
4924
  [controller]
4675
4925
  );
4676
- return /* @__PURE__ */ jsxs7(Column3, { className: "xeno-history-panel", children: [
4677
- /* @__PURE__ */ jsx8(
4678
- Toolbar2,
4679
- {
4680
- left: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4681
- /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(UndoIcon, {}), label: "Undo", disabled: !controller.canUndo(), onClick: () => controller.undo() }),
4682
- /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(RedoIcon, {}), label: "Redo", disabled: !controller.canRedo(), onClick: () => controller.redo() })
4683
- ] }),
4684
- right: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4685
- /* @__PURE__ */ jsxs7(Text4, { role: "number", children: [
4686
- controller.getAppliedCount(),
4687
- " / ",
4688
- controller.getTotalCount()
4689
- ] }),
4690
- controller.isClearAllowed() ? /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(TrashIcon, {}), label: "Clear history", onClick: () => controller.requestClear() }) : null
4691
- ] }),
4692
- children: controller.isSearchShown() ? /* @__PURE__ */ jsx8(SearchField3, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search history", label: "Search history" }) : null
4693
- }
4694
- ),
4695
- controller.isConfirmingClear() ? /* @__PURE__ */ jsx8(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => controller.confirmClearNow(), onCancel: () => controller.cancelClear() }) : null,
4696
- controller.isPruned() ? /* @__PURE__ */ jsx8(Text4, { role: "caption", children: "Earlier history discarded (limit reached)" }) : null,
4697
- /* @__PURE__ */ jsxs7(ScrollArea3, { ref: scrollRef, onScroll, onKeyDown, onMouseLeave: () => controller.setHovered(null), tabIndex: 0, children: [
4698
- /* @__PURE__ */ jsx8(RowList2, { role: "listbox", "aria-label": "History", children: /* @__PURE__ */ jsx8(VirtualWindow2, { totalHeight: window_.totalHeight, offsetTop: window_.offsetTop, children: windowRows.map((row) => /* @__PURE__ */ jsx8(
4699
- HistoryRowView,
4700
- {
4701
- row,
4702
- controller,
4703
- rowHeight,
4704
- focused: controller.getFocused() === row.entryId
4705
- },
4706
- row.entryId ?? "__original__"
4707
- )) }) }),
4708
- rows.length === 0 ? /* @__PURE__ */ jsx8(EmptyState3, { title: "No history" }) : null
4709
- ] }),
4710
- memory ? /* @__PURE__ */ jsx8(
4711
- StatusBar2,
4712
- {
4713
- left: /* @__PURE__ */ jsxs7(Text4, { role: "number", children: [
4714
- memory.usedMB.toFixed(1),
4715
- " MB",
4716
- memory.limitMB ? ` / ${memory.limitMB} MB` : ""
4717
- ] }),
4718
- right: memory.onDiskCount !== void 0 ? /* @__PURE__ */ jsxs7(Text4, { role: "meta", children: [
4719
- memory.onDiskCount,
4720
- " on disk"
4721
- ] }) : null
4926
+ return /* @__PURE__ */ jsx8(ScrollArea3, { ref: scrollRef, onScroll, onKeyDown, onMouseLeave: () => controller.setHovered(null), tabIndex: 0, children });
4927
+ }
4928
+ function HistoryCancelButton({ entryId, controller }) {
4929
+ return /* @__PURE__ */ jsx8(
4930
+ IconButton4,
4931
+ {
4932
+ size: "sm",
4933
+ icon: /* @__PURE__ */ jsx8(XIcon2, {}),
4934
+ label: "Cancel operation",
4935
+ onClick: (e) => {
4936
+ e.stopPropagation();
4937
+ controller.cancelPending(entryId);
4722
4938
  }
4723
- ) : null
4724
- ] });
4939
+ }
4940
+ );
4725
4941
  }
4726
- function HistoryRowView({ row, controller, rowHeight, focused }) {
4727
- const entry = row.entry;
4728
- const pending = entry?.status === "pending";
4729
- const failed = entry?.status === "failed";
4730
- const jumpable = controller.isJumpAllowed() && entry?.caps?.jumpable !== false;
4942
+ function HistoryRowView({ row, controller }) {
4943
+ const ui3 = (intent) => applyHistoryUi(controller, intent);
4731
4944
  return /* @__PURE__ */ jsx8(
4732
4945
  Row2,
4733
4946
  {
4734
- height: rowHeight,
4947
+ height: row.height,
4735
4948
  selected: row.current,
4736
- focused,
4949
+ focused: row.focused,
4737
4950
  struck: row.future,
4738
- noIcon: !controller.areIconsShown(),
4739
- icon: /* @__PURE__ */ jsx8(EntryIcon, { name: row.kind === "original" ? "original" : controller.getIconName(entry?.kind) }),
4951
+ noIcon: row.hideIcon,
4952
+ interactive: row.jumpable,
4953
+ icon: /* @__PURE__ */ jsx8(EntryIcon, { name: row.iconName }),
4740
4954
  label: row.label,
4741
- meta: row.kind === "entry" ? row.ordinal : void 0,
4742
- "data-history-row": row.entryId ?? "__original__",
4743
- onClick: jumpable ? () => controller.jumpTo(row.entryId) : void 0,
4744
- onMouseEnter: () => controller.setHovered(row.entryId),
4745
- onContextMenu: (e) => {
4746
- e.preventDefault();
4747
- controller.requestContextMenu(row.entryId, e.clientX, e.clientY);
4748
- },
4955
+ meta: row.meta,
4956
+ "data-history-row": row.key,
4749
4957
  title: row.label,
4750
4958
  trailing: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4751
- pending ? /* @__PURE__ */ jsx8(PendingGlyph, {}) : null,
4752
- failed ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", tone: "error", children: "failed" }) : null,
4753
- controller.isSourceShown() && entry?.source && entry.source !== "user" ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", title: `Source: ${entry.source}`, children: entry.source === "agent" ? "AI" : "S" }) : null,
4754
- entry?.coalesced && entry.coalesced > 1 ? /* @__PURE__ */ jsxs7(Badge3, { size: "sm", title: `${entry.coalesced} actions coalesced`, children: [
4755
- "\xD7",
4756
- entry.coalesced
4757
- ] }) : null,
4758
- controller.areTimestampsShown() && entry?.at !== void 0 ? /* @__PURE__ */ jsx8(Text4, { role: "meta", children: formatTime(entry.at) }) : null,
4759
- pending ? /* @__PURE__ */ jsx8(
4760
- IconButton4,
4761
- {
4762
- size: "sm",
4763
- icon: /* @__PURE__ */ jsx8(XIcon2, {}),
4764
- label: "Cancel operation",
4765
- onClick: (e) => {
4766
- e.stopPropagation();
4767
- controller.cancelPending(entry?.id);
4768
- }
4769
- }
4770
- ) : null
4771
- ] })
4959
+ row.pending ? /* @__PURE__ */ jsx8(PendingGlyph, {}) : null,
4960
+ row.failed ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", tone: "error", children: "failed" }) : null,
4961
+ row.showSource ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", title: row.sourceTitle, children: row.sourceGlyph }) : null,
4962
+ row.showCoalesced ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", title: row.coalescedTitle, children: row.coalescedText }) : null,
4963
+ row.showTime ? /* @__PURE__ */ jsx8(Text4, { role: "meta", children: row.time }) : null,
4964
+ row.pending ? /* @__PURE__ */ jsx8(HistoryCancelButton, { entryId: row.cancelId, controller }) : null
4965
+ ] }),
4966
+ onClick: () => ui3({ kind: "jump", entryId: row.entryId }),
4967
+ onMouseEnter: () => ui3({ kind: "hover", entryId: row.entryId }),
4968
+ onContextMenuAt: (x, y) => ui3({ kind: "contextMenu", entryId: row.entryId, x, y })
4772
4969
  }
4773
4970
  );
4774
4971
  }
4775
- function formatTime(at) {
4776
- const date = typeof at === "number" ? new Date(at) : new Date(at);
4777
- if (Number.isNaN(date.getTime())) return typeof at === "string" ? at : "";
4778
- return date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
4972
+ function historyRuntimeComponents(controller) {
4973
+ return {
4974
+ "history/Scroller": ({ children }) => /* @__PURE__ */ jsx8(HistoryScroller, { controller, children }),
4975
+ "history/CancelButton": ({ entryId }) => /* @__PURE__ */ jsx8(HistoryCancelButton, { entryId, controller }),
4976
+ "history/EntryIcon": EntryIcon,
4977
+ "history/PendingGlyph": PendingGlyph,
4978
+ "history/UndoIcon": UndoIcon,
4979
+ "history/RedoIcon": RedoIcon,
4980
+ "history/TrashIcon": TrashIcon
4981
+ };
4779
4982
  }
4780
4983
 
4781
4984
  // src/edit/history/panel.ts
@@ -4783,11 +4986,20 @@ function createHistoryPanel(options = {}) {
4783
4986
  return {
4784
4987
  manifest: historyManifest,
4785
4988
  activate(host) {
4786
- const controller = new HistoryPanelController(host, options);
4989
+ const { render: customRender, ...controllerOptions } = options;
4990
+ const controller = new HistoryPanelController(host, controllerOptions);
4787
4991
  void controller.load();
4788
4992
  let root = null;
4993
+ let unrender = null;
4789
4994
  return {
4790
4995
  render(el) {
4996
+ if (customRender) {
4997
+ unrender = customRender(el, controller);
4998
+ return () => {
4999
+ unrender?.();
5000
+ unrender = null;
5001
+ };
5002
+ }
4791
5003
  root = createRoot3(el);
4792
5004
  root.render(createElement3(HistoryPanelView, { controller }));
4793
5005
  return () => {
@@ -4810,6 +5022,8 @@ function createHistoryPanel(options = {}) {
4810
5022
  dispose() {
4811
5023
  root?.unmount();
4812
5024
  root = null;
5025
+ unrender?.();
5026
+ unrender = null;
4813
5027
  controller.dispose();
4814
5028
  }
4815
5029
  };
@@ -8587,11 +8801,11 @@ var FindController = class {
8587
8801
  * @param text - The new query text.
8588
8802
  * @param immediate - Skip the debounce (a paste, or pressing Enter).
8589
8803
  */
8590
- setText(text2, immediate = false) {
8591
- if (text2 === this.text) return;
8592
- this.text = text2;
8804
+ setText(text3, immediate = false) {
8805
+ if (text3 === this.text) return;
8806
+ this.text = text3;
8593
8807
  this.index = -1;
8594
- if (text2 === "") {
8808
+ if (text3 === "") {
8595
8809
  this.clearResults("idle");
8596
8810
  this.emitQuery(true);
8597
8811
  return;
@@ -8619,8 +8833,8 @@ var FindController = class {
8619
8833
  this.notify();
8620
8834
  }
8621
8835
  /** The replacement text. Never emitted on its own — a replacement is not a search. */
8622
- setReplaceText(text2) {
8623
- this.replaceText = text2;
8836
+ setReplaceText(text3) {
8837
+ this.replaceText = text3;
8624
8838
  this.notify();
8625
8839
  }
8626
8840
  /** Show or hide the replace row. */
@@ -12256,12 +12470,12 @@ var TreeController = class {
12256
12470
  }
12257
12471
  if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
12258
12472
  const fresh = now - this.typeAhead.at > this.typeAheadMs;
12259
- const text2 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
12260
- this.typeAhead = { text: text2, at: now };
12473
+ const text3 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
12474
+ this.typeAhead = { text: text3, at: now };
12261
12475
  const from = fresh ? current : current + 1;
12262
12476
  for (let i = 0; i < rows.length; i += 1) {
12263
12477
  const candidate = rows[(from + i) % rows.length];
12264
- if (candidate.node.label.toLowerCase().startsWith(text2)) {
12478
+ if (candidate.node.label.toLowerCase().startsWith(text3)) {
12265
12479
  this.focusedId = candidate.id;
12266
12480
  this.select([candidate.id]);
12267
12481
  return true;
@@ -12287,9 +12501,9 @@ var TreeController = class {
12287
12501
  return true;
12288
12502
  }
12289
12503
  /** Update the rename draft. */
12290
- updateRenameDraft(text2) {
12504
+ updateRenameDraft(text3) {
12291
12505
  if (!this.renaming) return;
12292
- this.renaming = { ...this.renaming, draft: text2 };
12506
+ this.renaming = { ...this.renaming, draft: text3 };
12293
12507
  this.notify();
12294
12508
  }
12295
12509
  /**
@@ -13478,6 +13692,8 @@ export {
13478
13692
  FindPanelView,
13479
13693
  GENERIC_ICON,
13480
13694
  GraphController,
13695
+ BEHAVIOURS2 as HISTORY_BEHAVIOURS,
13696
+ HISTORY_DECLARATION,
13481
13697
  HistoryPanelController,
13482
13698
  HistoryPanelView,
13483
13699
  IMPLEMENTED_TREE_MODES,
@@ -13508,6 +13724,7 @@ export {
13508
13724
  allIds,
13509
13725
  anchorStateOf,
13510
13726
  appliedCount,
13727
+ applyHistoryUi,
13511
13728
  applyInspectorUi,
13512
13729
  applyPrecision,
13513
13730
  applyTangentDrag,
@@ -13577,6 +13794,9 @@ export {
13577
13794
  highlightSegments,
13578
13795
  historyManifest,
13579
13796
  historyPanel,
13797
+ historyRuntimeComponents,
13798
+ historyViewManifest,
13799
+ historyViewState,
13580
13800
  hslToRgb,
13581
13801
  hsvFromHex,
13582
13802
  hsvToRgb,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenosystem/blocks",
3
- "version": "0.12.2",
3
+ "version": "0.12.4",
4
4
  "description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -60,7 +60,7 @@
60
60
  "peerDependencies": {
61
61
  "@duckdb/duckdb-wasm": ">=1.28.0",
62
62
  "@xenosystem/block-sdk": ">=0.3.3 <1",
63
- "@xenosystem/components": ">=0.16.0 <1",
63
+ "@xenosystem/components": ">=0.16.1 <1",
64
64
  "@xenosystem/data-core": "^0.1.0",
65
65
  "@xenosystem/elements-react": ">=0.0.1",
66
66
  "@xenosystem/time-core": "^0.1.0",
@@ -76,7 +76,7 @@
76
76
  "@types/react": "^19.0.0",
77
77
  "@types/react-dom": "^19.0.0",
78
78
  "@xenosystem/block-sdk": "^0.3.3",
79
- "@xenosystem/components": "^0.16.0",
79
+ "@xenosystem/components": "^0.16.1",
80
80
  "@xenosystem/data-core": "^0.1.0",
81
81
  "@xenosystem/elements-react": "0.0.1",
82
82
  "@xenosystem/time-core": "^0.1.0",