@flanksource/clicky-ui 0.3.40 → 0.3.42
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/README.md +24 -0
- package/dist/ai.cjs +14 -0
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +14 -0
- package/dist/ai.js.map +1 -1
- package/dist/comments/CommentCard.cjs +3 -1
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +4 -2
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentCardParts.cjs +16 -0
- package/dist/comments/CommentCardParts.cjs.map +1 -1
- package/dist/comments/CommentCardParts.d.ts +4 -1
- package/dist/comments/CommentCardParts.d.ts.map +1 -1
- package/dist/comments/CommentCardParts.js +16 -0
- package/dist/comments/CommentCardParts.js.map +1 -1
- package/dist/comments/comment-types.cjs.map +1 -1
- package/dist/comments/comment-types.d.ts +4 -0
- package/dist/comments/comment-types.d.ts.map +1 -1
- package/dist/comments/comment-types.js.map +1 -1
- package/dist/components/AccordionList.cjs +5 -1
- package/dist/components/AccordionList.cjs.map +1 -1
- package/dist/components/AccordionList.d.ts +3 -1
- package/dist/components/AccordionList.d.ts.map +1 -1
- package/dist/components/AccordionList.js +5 -1
- package/dist/components/AccordionList.js.map +1 -1
- package/dist/components/Combobox.cjs +54 -8
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +56 -10
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/ComboboxMenu.cjs +139 -113
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts +3 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +139 -113
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/ComboboxMenuTrigger.cjs +87 -0
- package/dist/components/ComboboxMenuTrigger.cjs.map +1 -0
- package/dist/components/ComboboxMenuTrigger.d.ts +23 -0
- package/dist/components/ComboboxMenuTrigger.d.ts.map +1 -0
- package/dist/components/ComboboxMenuTrigger.js +87 -0
- package/dist/components/ComboboxMenuTrigger.js.map +1 -0
- package/dist/components/JsonSchemaForm.cjs +39 -11
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +38 -10
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/SegmentedControl.cjs +20 -3
- package/dist/components/SegmentedControl.cjs.map +1 -1
- package/dist/components/SegmentedControl.d.ts +11 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl.js +21 -4
- package/dist/components/SegmentedControl.js.map +1 -1
- package/dist/components/combobox-types.d.ts +8 -0
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-accordion-array.cjs +3 -1
- package/dist/components/json-schema-form-accordion-array.cjs.map +1 -1
- package/dist/components/json-schema-form-accordion-array.d.ts +4 -1
- package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-accordion-array.js +3 -1
- package/dist/components/json-schema-form-accordion-array.js.map +1 -1
- package/dist/components/json-schema-form-array-view.cjs +63 -0
- package/dist/components/json-schema-form-array-view.cjs.map +1 -0
- package/dist/components/json-schema-form-array-view.d.ts +21 -0
- package/dist/components/json-schema-form-array-view.d.ts.map +1 -0
- package/dist/components/json-schema-form-array-view.js +63 -0
- package/dist/components/json-schema-form-array-view.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +3 -7
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +3 -7
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-conditionals.cjs +67 -0
- package/dist/components/json-schema-form-conditionals.cjs.map +1 -0
- package/dist/components/json-schema-form-conditionals.d.ts +9 -0
- package/dist/components/json-schema-form-conditionals.d.ts.map +1 -0
- package/dist/components/json-schema-form-conditionals.js +67 -0
- package/dist/components/json-schema-form-conditionals.js.map +1 -0
- package/dist/components/json-schema-form-debug-badge.cjs +108 -0
- package/dist/components/json-schema-form-debug-badge.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-badge.d.ts +10 -0
- package/dist/components/json-schema-form-debug-badge.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-badge.js +108 -0
- package/dist/components/json-schema-form-debug-badge.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs +129 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.d.ts +20 -0
- package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.js +129 -0
- package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.cjs +13 -0
- package/dist/components/json-schema-form-debug-glyph.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.d.ts +6 -0
- package/dist/components/json-schema-form-debug-glyph.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.js +13 -0
- package/dist/components/json-schema-form-debug-glyph.js.map +1 -0
- package/dist/components/json-schema-form-debug-groups.cjs +56 -0
- package/dist/components/json-schema-form-debug-groups.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-groups.d.ts +8 -0
- package/dist/components/json-schema-form-debug-groups.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-groups.js +56 -0
- package/dist/components/json-schema-form-debug-groups.js.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.cjs +159 -0
- package/dist/components/json-schema-form-debug-keywords.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.d.ts +6 -0
- package/dist/components/json-schema-form-debug-keywords.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.js +159 -0
- package/dist/components/json-schema-form-debug-keywords.js.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.cjs +102 -0
- package/dist/components/json-schema-form-debug-listeners.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.d.ts +6 -0
- package/dist/components/json-schema-form-debug-listeners.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.js +102 -0
- package/dist/components/json-schema-form-debug-listeners.js.map +1 -0
- package/dist/components/json-schema-form-debug.cjs +31 -0
- package/dist/components/json-schema-form-debug.cjs.map +1 -0
- package/dist/components/json-schema-form-debug.d.ts +11 -0
- package/dist/components/json-schema-form-debug.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug.js +31 -0
- package/dist/components/json-schema-form-debug.js.map +1 -0
- package/dist/components/json-schema-form-defaults.cjs +68 -0
- package/dist/components/json-schema-form-defaults.cjs.map +1 -0
- package/dist/components/json-schema-form-defaults.d.ts +4 -0
- package/dist/components/json-schema-form-defaults.d.ts.map +1 -0
- package/dist/components/json-schema-form-defaults.js +68 -0
- package/dist/components/json-schema-form-defaults.js.map +1 -0
- package/dist/components/json-schema-form-enum-choice.cjs +114 -0
- package/dist/components/json-schema-form-enum-choice.cjs.map +1 -0
- package/dist/components/json-schema-form-enum-choice.d.ts +14 -0
- package/dist/components/json-schema-form-enum-choice.d.ts.map +1 -0
- package/dist/components/json-schema-form-enum-choice.js +114 -0
- package/dist/components/json-schema-form-enum-choice.js.map +1 -0
- package/dist/components/json-schema-form-errors.cjs +49 -31
- package/dist/components/json-schema-form-errors.cjs.map +1 -1
- package/dist/components/json-schema-form-errors.d.ts +4 -2
- package/dist/components/json-schema-form-errors.d.ts.map +1 -1
- package/dist/components/json-schema-form-errors.js +51 -33
- package/dist/components/json-schema-form-errors.js.map +1 -1
- package/dist/components/json-schema-form-fields.cjs +3 -93
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +1 -91
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-filter.cjs +2 -1
- package/dist/components/json-schema-form-filter.cjs.map +1 -1
- package/dist/components/json-schema-form-filter.js +2 -1
- package/dist/components/json-schema-form-filter.js.map +1 -1
- package/dist/components/json-schema-form-item-summary.cjs +6 -2
- package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
- package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
- package/dist/components/json-schema-form-item-summary.js +6 -2
- package/dist/components/json-schema-form-item-summary.js.map +1 -1
- package/dist/components/json-schema-form-layout.cjs +28 -19
- package/dist/components/json-schema-form-layout.cjs.map +1 -1
- package/dist/components/json-schema-form-layout.d.ts +8 -6
- package/dist/components/json-schema-form-layout.d.ts.map +1 -1
- package/dist/components/json-schema-form-layout.js +29 -20
- package/dist/components/json-schema-form-layout.js.map +1 -1
- package/dist/components/json-schema-form-listener-paths.cjs +52 -0
- package/dist/components/json-schema-form-listener-paths.cjs.map +1 -0
- package/dist/components/json-schema-form-listener-paths.d.ts +10 -0
- package/dist/components/json-schema-form-listener-paths.d.ts.map +1 -0
- package/dist/components/json-schema-form-listener-paths.js +52 -0
- package/dist/components/json-schema-form-listener-paths.js.map +1 -0
- package/dist/components/json-schema-form-listener-types.d.ts +22 -0
- package/dist/components/json-schema-form-listener-types.d.ts.map +1 -0
- package/dist/components/json-schema-form-listeners.cjs +256 -0
- package/dist/components/json-schema-form-listeners.cjs.map +1 -0
- package/dist/components/json-schema-form-listeners.d.ts +13 -0
- package/dist/components/json-schema-form-listeners.d.ts.map +1 -0
- package/dist/components/json-schema-form-listeners.js +256 -0
- package/dist/components/json-schema-form-listeners.js.map +1 -0
- package/dist/components/json-schema-form-object-array-view.cjs +62 -0
- package/dist/components/json-schema-form-object-array-view.cjs.map +1 -0
- package/dist/components/json-schema-form-object-array-view.d.ts +14 -0
- package/dist/components/json-schema-form-object-array-view.d.ts.map +1 -0
- package/dist/components/json-schema-form-object-array-view.js +62 -0
- package/dist/components/json-schema-form-object-array-view.js.map +1 -0
- package/dist/components/json-schema-form-object.cjs +3 -0
- package/dist/components/json-schema-form-object.cjs.map +1 -1
- package/dist/components/json-schema-form-object.d.ts.map +1 -1
- package/dist/components/json-schema-form-object.js +3 -0
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-preferences.cjs +1 -0
- package/dist/components/json-schema-form-preferences.cjs.map +1 -1
- package/dist/components/json-schema-form-preferences.d.ts +1 -0
- package/dist/components/json-schema-form-preferences.d.ts.map +1 -1
- package/dist/components/json-schema-form-preferences.js +1 -0
- package/dist/components/json-schema-form-preferences.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +36 -12
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +38 -14
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +6 -99
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts +1 -8
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +5 -98
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-runtime-types.d.ts +16 -0
- package/dist/components/json-schema-form-runtime-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-table-array.cjs +67 -16
- package/dist/components/json-schema-form-table-array.cjs.map +1 -1
- package/dist/components/json-schema-form-table-array.d.ts +4 -1
- package/dist/components/json-schema-form-table-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-table-array.js +70 -19
- package/dist/components/json-schema-form-table-array.js.map +1 -1
- package/dist/components/json-schema-form-tone.cjs +12 -0
- package/dist/components/json-schema-form-tone.cjs.map +1 -1
- package/dist/components/json-schema-form-tone.js +12 -0
- package/dist/components/json-schema-form-tone.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +17 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.cjs +7 -1
- package/dist/components/json-schema-form-utils.cjs.map +1 -1
- package/dist/components/json-schema-form-utils.d.ts +2 -1
- package/dist/components/json-schema-form-utils.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.js +7 -1
- package/dist/components/json-schema-form-utils.js.map +1 -1
- package/dist/components.cjs +3 -2
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -2
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +2 -1
- package/dist/components.js.map +1 -1
- package/dist/data/DataTable.cjs +9 -3
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +6 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +9 -3
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.cjs +43 -24
- package/dist/data/FixtureEditor/FixtureEditor.cjs.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.d.ts.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.js +43 -24
- package/dist/data/FixtureEditor/FixtureEditor.js.map +1 -1
- package/dist/data/GraphDiagram.cjs +125 -138
- package/dist/data/GraphDiagram.cjs.map +1 -1
- package/dist/data/GraphDiagram.d.ts +30 -23
- package/dist/data/GraphDiagram.d.ts.map +1 -1
- package/dist/data/GraphDiagram.js +128 -141
- package/dist/data/GraphDiagram.js.map +1 -1
- package/dist/data/GraphDiagramEdges.cjs +208 -0
- package/dist/data/GraphDiagramEdges.cjs.map +1 -0
- package/dist/data/GraphDiagramEdges.d.ts +40 -0
- package/dist/data/GraphDiagramEdges.d.ts.map +1 -0
- package/dist/data/GraphDiagramEdges.js +208 -0
- package/dist/data/GraphDiagramEdges.js.map +1 -0
- package/dist/data/GraphDiagramNodes.cjs +142 -0
- package/dist/data/GraphDiagramNodes.cjs.map +1 -0
- package/dist/data/GraphDiagramNodes.d.ts +22 -0
- package/dist/data/GraphDiagramNodes.d.ts.map +1 -0
- package/dist/data/GraphDiagramNodes.js +142 -0
- package/dist/data/GraphDiagramNodes.js.map +1 -0
- package/dist/data/Tree.cjs +10 -2
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +6 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +10 -2
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/RuntimeRows.cjs +8 -3
- package/dist/data/ai/PromptRunEditor/RuntimeRows.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/RuntimeRows.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/RuntimeRows.js +8 -3
- package/dist/data/ai/PromptRunEditor/RuntimeRows.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.cjs +37 -43
- package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts +3 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.js +38 -44
- package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs +16 -5
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts +4 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.js +17 -6
- package/dist/data/ai/PromptRunEditor/runtimeActions.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.cjs +12 -0
- package/dist/data/ai/SessionInspector.approvals-model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.d.ts +11 -2
- package/dist/data/ai/SessionInspector.approvals-model.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.js +12 -0
- package/dist/data/ai/SessionInspector.approvals-model.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.cjs +25 -1
- package/dist/data/ai/SessionInspector.approvals.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.js +26 -2
- package/dist/data/ai/SessionInspector.approvals.js.map +1 -1
- package/dist/data/ai/SessionInspector.cjs +143 -167
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection-types.d.ts +5 -0
- package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.collection.cjs +18 -5
- package/dist/data/ai/SessionInspector.collection.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection.d.ts +2 -0
- package/dist/data/ai/SessionInspector.collection.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.collection.fixtures.d.ts +6 -0
- package/dist/data/ai/SessionInspector.collection.fixtures.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.collection.js +18 -5
- package/dist/data/ai/SessionInspector.collection.js.map +1 -1
- package/dist/data/ai/SessionInspector.d.ts +24 -2
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs +105 -7
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts +12 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.js +107 -9
- package/dist/data/ai/SessionInspector.hierarchy-state.js.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
- package/dist/data/ai/SessionInspector.js +144 -168
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.cjs +116 -0
- package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.legacy.d.ts +19 -0
- package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.legacy.js +116 -0
- package/dist/data/ai/SessionInspector.legacy.js.map +1 -0
- package/dist/data/ai/SessionInspector.panels.cjs +3 -0
- package/dist/data/ai/SessionInspector.panels.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.panels.js +3 -0
- package/dist/data/ai/SessionInspector.panels.js.map +1 -1
- package/dist/data/ai/SessionInspector.plan.cjs +29 -12
- package/dist/data/ai/SessionInspector.plan.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.plan.js +30 -13
- package/dist/data/ai/SessionInspector.plan.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.cjs +44 -0
- package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.remote-view.d.ts +11 -0
- package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.remote-view.js +44 -0
- package/dist/data/ai/SessionInspector.remote-view.js.map +1 -0
- package/dist/data/ai/SessionInspector.remote.cjs +275 -0
- package/dist/data/ai/SessionInspector.remote.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.remote.d.ts +57 -0
- package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.remote.js +275 -0
- package/dist/data/ai/SessionInspector.remote.js.map +1 -0
- package/dist/data/ai/SessionInspector.summary.cjs +9 -159
- package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.summary.d.ts +0 -3
- package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.summary.js +11 -161
- package/dist/data/ai/SessionInspector.summary.js.map +1 -1
- package/dist/data/ai/SessionInspector.tab-state.cjs +15 -0
- package/dist/data/ai/SessionInspector.tab-state.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.tab-state.d.ts +3 -0
- package/dist/data/ai/SessionInspector.tab-state.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.tab-state.js +15 -0
- package/dist/data/ai/SessionInspector.tab-state.js.map +1 -0
- package/dist/data/ai/SessionInspector.tabs.model.cjs +31 -18
- package/dist/data/ai/SessionInspector.tabs.model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.tabs.model.d.ts +3 -1
- package/dist/data/ai/SessionInspector.tabs.model.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.tabs.model.js +32 -19
- package/dist/data/ai/SessionInspector.tabs.model.js.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.cjs +4 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.js +4 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
- package/dist/data/ai/SessionInspector.verification.cjs +53 -0
- package/dist/data/ai/SessionInspector.verification.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.verification.d.ts +7 -0
- package/dist/data/ai/SessionInspector.verification.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.verification.js +53 -0
- package/dist/data/ai/SessionInspector.verification.js.map +1 -0
- package/dist/data/ai/SessionViewer.approval-body.cjs +146 -0
- package/dist/data/ai/SessionViewer.approval-body.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.approval-body.d.ts +11 -0
- package/dist/data/ai/SessionViewer.approval-body.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.approval-body.js +146 -0
- package/dist/data/ai/SessionViewer.approval-body.js.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.cjs +150 -0
- package/dist/data/ai/SessionViewer.approval-forms.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.d.ts +23 -0
- package/dist/data/ai/SessionViewer.approval-forms.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.js +150 -0
- package/dist/data/ai/SessionViewer.approval-forms.js.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +57 -20
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +13 -3
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.decision-controls.cjs +313 -0
- package/dist/data/ai/SessionViewer.decision-controls.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.decision-controls.d.ts +43 -0
- package/dist/data/ai/SessionViewer.decision-controls.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.decision-controls.js +313 -0
- package/dist/data/ai/SessionViewer.decision-controls.js.map +1 -0
- package/dist/data/ai/SessionViewer.decision.cjs +21 -0
- package/dist/data/ai/SessionViewer.decision.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.decision.d.ts +12 -0
- package/dist/data/ai/SessionViewer.decision.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.decision.js +21 -0
- package/dist/data/ai/SessionViewer.decision.js.map +1 -0
- package/dist/data/ai/SessionViewer.input.cjs +14 -0
- package/dist/data/ai/SessionViewer.input.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.input.d.ts +5 -0
- package/dist/data/ai/SessionViewer.input.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.input.js +14 -0
- package/dist/data/ai/SessionViewer.input.js.map +1 -1
- package/dist/data/ai/SessionViewer.js +58 -21
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.model.cjs +7 -1
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +25 -3
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js +7 -1
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.rows.cjs +6 -3
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts +2 -1
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +6 -3
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.cjs +29 -237
- package/dist/data/ai/SessionViewer.tool-row.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.js +27 -235
- package/dist/data/ai/SessionViewer.tool-row.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +17 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.cjs +8 -2
- package/dist/data/ai/SessionViewerMenu.cjs.map +1 -1
- package/dist/data/ai/SessionViewerMenu.d.ts +4 -1
- package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.js +8 -2
- package/dist/data/ai/SessionViewerMenu.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs +28 -17
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts +10 -2
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js +29 -18
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs +9 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts +9 -2
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js +9 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.cjs +1 -1
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts +8 -2
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.cjs +14 -6
- package/dist/data/ai/SpecRuntimeEditor/update.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts +1 -0
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.js +14 -6
- package/dist/data/ai/SpecRuntimeEditor/update.js.map +1 -1
- package/dist/data/ai/approval-request.cjs +75 -0
- package/dist/data/ai/approval-request.cjs.map +1 -0
- package/dist/data/ai/approval-request.d.ts +155 -0
- package/dist/data/ai/approval-request.d.ts.map +1 -0
- package/dist/data/ai/approval-request.js +75 -0
- package/dist/data/ai/approval-request.js.map +1 -0
- package/dist/data/ai/index.d.ts +6 -1
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.cjs +125 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.d.ts +11 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.js +125 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.js.map +1 -0
- package/dist/data/ai/runtime-preset-menu/index.d.ts +3 -0
- package/dist/data/ai/runtime-preset-menu/index.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.cjs +73 -0
- package/dist/data/ai/runtime-preset-menu/model.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.d.ts +13 -0
- package/dist/data/ai/runtime-preset-menu/model.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.js +73 -0
- package/dist/data/ai/runtime-preset-menu/model.js.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.cjs +149 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.d.ts +15 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.js +149 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.js.map +1 -0
- package/dist/data/ai/runtime-spec-fields.cjs +166 -0
- package/dist/data/ai/runtime-spec-fields.cjs.map +1 -0
- package/dist/data/ai/runtime-spec-fields.d.ts +13 -0
- package/dist/data/ai/runtime-spec-fields.d.ts.map +1 -0
- package/dist/data/ai/runtime-spec-fields.js +166 -0
- package/dist/data/ai/runtime-spec-fields.js.map +1 -0
- package/dist/data/ai/session-categories.cjs +4 -0
- package/dist/data/ai/session-categories.cjs.map +1 -1
- package/dist/data/ai/session-categories.d.ts +1 -0
- package/dist/data/ai/session-categories.d.ts.map +1 -1
- package/dist/data/ai/session-categories.js +4 -0
- package/dist/data/ai/session-categories.js.map +1 -1
- package/dist/data/ai/use-session-scroll.cjs +49 -21
- package/dist/data/ai/use-session-scroll.cjs.map +1 -1
- package/dist/data/ai/use-session-scroll.d.ts +2 -0
- package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.js +49 -21
- package/dist/data/ai/use-session-scroll.js.map +1 -1
- package/dist/data/chat/Chat.runtime.cjs +1 -1
- package/dist/data/chat/Chat.runtime.cjs.map +1 -1
- package/dist/data/chat/Chat.runtime.d.ts.map +1 -1
- package/dist/data/chat/Chat.runtime.js +1 -1
- package/dist/data/chat/Chat.runtime.js.map +1 -1
- package/dist/data/graph-columns-layout.cjs +216 -0
- package/dist/data/graph-columns-layout.cjs.map +1 -0
- package/dist/data/graph-columns-layout.d.ts +56 -0
- package/dist/data/graph-columns-layout.d.ts.map +1 -0
- package/dist/data/graph-columns-layout.js +216 -0
- package/dist/data/graph-columns-layout.js.map +1 -0
- package/dist/data/graph-diagram-model.cjs +73 -0
- package/dist/data/graph-diagram-model.cjs.map +1 -0
- package/dist/data/graph-diagram-model.d.ts +90 -0
- package/dist/data/graph-diagram-model.d.ts.map +1 -0
- package/dist/data/graph-diagram-model.js +73 -0
- package/dist/data/graph-diagram-model.js.map +1 -0
- package/dist/data/graph-edge-routing.cjs +235 -0
- package/dist/data/graph-edge-routing.cjs.map +1 -0
- package/dist/data/graph-edge-routing.d.ts +73 -0
- package/dist/data/graph-edge-routing.d.ts.map +1 -0
- package/dist/data/graph-edge-routing.js +235 -0
- package/dist/data/graph-edge-routing.js.map +1 -0
- package/dist/data/graph-layout.cjs +0 -82
- package/dist/data/graph-layout.cjs.map +1 -1
- package/dist/data/graph-layout.d.ts +1 -28
- package/dist/data/graph-layout.d.ts.map +1 -1
- package/dist/data/graph-layout.js +1 -83
- package/dist/data/graph-layout.js.map +1 -1
- package/dist/data/har/HarPanel.cjs +129 -33
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts +13 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +130 -34
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/har/fixtures.d.ts +12 -0
- package/dist/data/har/fixtures.d.ts.map +1 -1
- package/dist/data/har/types.d.ts +12 -0
- package/dist/data/har/types.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.cjs +67 -84
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +4 -5
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.cjs +170 -0
- package/dist/data/runtime/RuntimeBar.fields.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBar.fields.d.ts +16 -0
- package/dist/data/runtime/RuntimeBar.fields.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.fields.js +170 -0
- package/dist/data/runtime/RuntimeBar.fields.js.map +1 -0
- package/dist/data/runtime/RuntimeBar.js +70 -87
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs +56 -0
- package/dist/data/runtime/RuntimeBar.selection.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBar.selection.d.ts +20 -0
- package/dist/data/runtime/RuntimeBar.selection.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.selection.js +56 -0
- package/dist/data/runtime/RuntimeBar.selection.js.map +1 -0
- package/dist/data/runtime/RuntimeBarActions.cjs +10 -6
- package/dist/data/runtime/RuntimeBarActions.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts +8 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.js +10 -6
- package/dist/data/runtime/RuntimeBarActions.js.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.cjs +166 -0
- package/dist/data/runtime/RuntimeBarIdentity.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBarIdentity.d.ts +25 -0
- package/dist/data/runtime/RuntimeBarIdentity.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBarIdentity.js +166 -0
- package/dist/data/runtime/RuntimeBarIdentity.js.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.cjs +95 -0
- package/dist/data/runtime/RuntimeBarLayout.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.d.ts +9 -0
- package/dist/data/runtime/RuntimeBarLayout.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.js +95 -0
- package/dist/data/runtime/RuntimeBarLayout.js.map +1 -0
- package/dist/data/runtime/RuntimeBarSegment.cjs +25 -14
- package/dist/data/runtime/RuntimeBarSegment.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.d.ts +4 -0
- package/dist/data/runtime/RuntimeBarSegment.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.js +25 -14
- package/dist/data/runtime/RuntimeBarSegment.js.map +1 -1
- package/dist/data/runtime/RuntimeLimitInput.cjs +41 -0
- package/dist/data/runtime/RuntimeLimitInput.cjs.map +1 -0
- package/dist/data/runtime/RuntimeLimitInput.d.ts +9 -0
- package/dist/data/runtime/RuntimeLimitInput.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeLimitInput.js +41 -0
- package/dist/data/runtime/RuntimeLimitInput.js.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.cjs +70 -0
- package/dist/data/runtime/use-runtime-bar-overflow.cjs.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts +13 -0
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.js +70 -0
- package/dist/data/runtime/use-runtime-bar-overflow.js.map +1 -0
- package/dist/data/use-edge-focus.cjs +20 -0
- package/dist/data/use-edge-focus.cjs.map +1 -0
- package/dist/data/use-edge-focus.d.ts +23 -0
- package/dist/data/use-edge-focus.d.ts.map +1 -0
- package/dist/data/use-edge-focus.js +20 -0
- package/dist/data/use-edge-focus.js.map +1 -0
- package/dist/data/use-pan-zoom.cjs +159 -0
- package/dist/data/use-pan-zoom.cjs.map +1 -0
- package/dist/data/use-pan-zoom.d.ts +79 -0
- package/dist/data/use-pan-zoom.d.ts.map +1 -0
- package/dist/data/use-pan-zoom.js +159 -0
- package/dist/data/use-pan-zoom.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +5 -1
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +4 -3
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +6 -2
- package/dist/data.js.map +1 -1
- package/dist/devtools/useDebugStream.cjs +5 -1
- package/dist/devtools/useDebugStream.cjs.map +1 -1
- package/dist/devtools/useDebugStream.d.ts.map +1 -1
- package/dist/devtools/useDebugStream.js +6 -2
- package/dist/devtools/useDebugStream.js.map +1 -1
- package/dist/hooks/event-source-provider.cjs +9 -0
- package/dist/hooks/event-source-provider.cjs.map +1 -0
- package/dist/hooks/event-source-provider.d.ts +15 -0
- package/dist/hooks/event-source-provider.d.ts.map +1 -0
- package/dist/hooks/event-source-provider.js +9 -0
- package/dist/hooks/event-source-provider.js.map +1 -0
- package/dist/hooks/event-source.cjs +11 -0
- package/dist/hooks/event-source.cjs.map +1 -0
- package/dist/hooks/event-source.d.ts +22 -0
- package/dist/hooks/event-source.d.ts.map +1 -0
- package/dist/hooks/event-source.js +11 -0
- package/dist/hooks/event-source.js.map +1 -0
- package/dist/hooks/use-log-tail.cjs +5 -1
- package/dist/hooks/use-log-tail.cjs.map +1 -1
- package/dist/hooks/use-log-tail.d.ts.map +1 -1
- package/dist/hooks/use-log-tail.js +5 -1
- package/dist/hooks/use-log-tail.js.map +1 -1
- package/dist/hooks/use-prompts.cjs +5 -1
- package/dist/hooks/use-prompts.cjs.map +1 -1
- package/dist/hooks/use-prompts.d.ts.map +1 -1
- package/dist/hooks/use-prompts.js +6 -2
- package/dist/hooks/use-prompts.js.map +1 -1
- package/dist/hooks/use-task-run.cjs +9 -2
- package/dist/hooks/use-task-run.cjs.map +1 -1
- package/dist/hooks/use-task-run.d.ts.map +1 -1
- package/dist/hooks/use-task-run.js +10 -3
- package/dist/hooks/use-task-run.js.map +1 -1
- package/dist/hooks.cjs +4 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/icons/programmingCatalog.cjs +34 -34
- package/dist/icons/programmingCatalog.cjs.map +1 -1
- package/dist/icons/programmingCatalog.js +34 -34
- package/dist/icons/programmingCatalog.js.map +1 -1
- package/dist/index.cjs +14 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/monaco/MonacoEditor.cjs +4 -1
- package/dist/monaco/MonacoEditor.cjs.map +1 -1
- package/dist/monaco/MonacoEditor.d.ts +1 -1
- package/dist/monaco/MonacoEditor.d.ts.map +1 -1
- package/dist/monaco/MonacoEditor.js +4 -1
- package/dist/monaco/MonacoEditor.js.map +1 -1
- package/dist/monaco/types.d.ts +2 -1
- package/dist/monaco/types.d.ts.map +1 -1
- package/dist/overlay/CommandPalette.cjs +14 -4
- package/dist/overlay/CommandPalette.cjs.map +1 -1
- package/dist/overlay/CommandPalette.d.ts +5 -1
- package/dist/overlay/CommandPalette.d.ts.map +1 -1
- package/dist/overlay/CommandPalette.js +14 -4
- package/dist/overlay/CommandPalette.js.map +1 -1
- package/dist/overlay/CommandPaletteList.cjs +5 -0
- package/dist/overlay/CommandPaletteList.cjs.map +1 -1
- package/dist/overlay/CommandPaletteList.d.ts +4 -2
- package/dist/overlay/CommandPaletteList.d.ts.map +1 -1
- package/dist/overlay/CommandPaletteList.js +5 -0
- package/dist/overlay/CommandPaletteList.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +2 -0
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +4 -0
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +2 -0
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +31 -15
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +31 -15
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +32 -27
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +11 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +32 -27
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.cjs +62 -256
- package/dist/rpc/OperationEntityContextPicker.cjs.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.js +64 -258
- package/dist/rpc/OperationEntityContextPicker.js.map +1 -1
- package/dist/rpc/OperationEntityPicker.cjs +185 -0
- package/dist/rpc/OperationEntityPicker.cjs.map +1 -0
- package/dist/rpc/OperationEntityPicker.d.ts +51 -0
- package/dist/rpc/OperationEntityPicker.d.ts.map +1 -0
- package/dist/rpc/OperationEntityPicker.js +185 -0
- package/dist/rpc/OperationEntityPicker.js.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.cjs +39 -0
- package/dist/rpc/OperationEntityPicker.model.cjs.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.d.ts +27 -0
- package/dist/rpc/OperationEntityPicker.model.d.ts.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.js +39 -0
- package/dist/rpc/OperationEntityPicker.model.js.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.cjs +85 -0
- package/dist/rpc/operationCatalogRowSelection.cjs.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.d.ts +57 -0
- package/dist/rpc/operationCatalogRowSelection.d.ts.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.js +85 -0
- package/dist/rpc/operationCatalogRowSelection.js.map +1 -0
- package/dist/rpc/operationEntityPicker.fixtures.d.ts +13 -0
- package/dist/rpc/operationEntityPicker.fixtures.d.ts.map +1 -0
- package/dist/rpc/useOperationPages.cjs +6 -1
- package/dist/rpc/useOperationPages.cjs.map +1 -1
- package/dist/rpc/useOperationPages.d.ts +3 -1
- package/dist/rpc/useOperationPages.d.ts.map +1 -1
- package/dist/rpc/useOperationPages.js +6 -1
- package/dist/rpc/useOperationPages.js.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +4 -1
- package/schemas/json-schema-form.schema.json +571 -0
- package/dist/data/runtime/RuntimeBarCombo.cjs +0 -423
- package/dist/data/runtime/RuntimeBarCombo.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts +0 -33
- package/dist/data/runtime/RuntimeBarCombo.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarCombo.js +0 -423
- package/dist/data/runtime/RuntimeBarCombo.js.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.cjs +0 -262
- package/dist/data/runtime/RuntimeBarLimits.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.d.ts +0 -17
- package/dist/data/runtime/RuntimeBarLimits.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.js +0 -262
- package/dist/data/runtime/RuntimeBarLimits.js.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.cjs +0 -346
- package/dist/data/runtime/RuntimeBarSegments.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.d.ts +0 -37
- package/dist/data/runtime/RuntimeBarSegments.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.js +0 -346
- package/dist/data/runtime/RuntimeBarSegments.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-categories.js","sources":["../../../src/data/ai/session-categories.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport {\n UiBeaker,\n UiBox,\n UiBoxes,\n UiCloudDownload,\n UiEye,\n UiGitBranch,\n UiPackage,\n UiPencilSimpleLine,\n UiPlayCircle,\n UiQuestion,\n UiSearch,\n UiShieldCheck,\n UiStrategy,\n UiTrash,\n UiWrench,\n} from \"../../icons\";\nimport { getSessionAction, type SessionEvent } from \"./SessionViewer.model\";\n\n// ── Captain category taxonomy ───────────────────────────────────────────────\n// A faithful TypeScript port of captain's `pkg/bash` category classifier\n// (`category.go` + `category_config.yaml`) so the SessionViewer's filter mirrors\n// what `captain history --category` / `--tool` expose. A tool maps to a category\n// either directly (Read → explore, Edit → edit, …) or, for Bash, by classifying\n// the command string.\n\nexport type SessionCategory =\n | \"build\"\n | \"test\"\n | \"install\"\n | \"explore\"\n | \"lint\"\n | \"cleanup\"\n | \"git\"\n | \"docker\"\n | \"k8s\"\n | \"run\"\n | \"plan\"\n | \"edit\"\n | \"clarify\"\n | \"read\"\n | \"other\";\n\nexport const CATEGORY_LABELS: Record<SessionCategory, string> = {\n build: \"Build\",\n test: \"Test\",\n install: \"Install\",\n explore: \"Explore\",\n lint: \"Lint\",\n cleanup: \"Cleanup\",\n git: \"Git\",\n docker: \"Docker\",\n k8s: \"Kubernetes\",\n run: \"Run\",\n plan: \"Plan\",\n edit: \"Edit\",\n clarify: \"Clarify\",\n read: \"Read\",\n other: \"Other\",\n};\n\n// Per-category glyph, following the \"Agent Action Icons\" workflow palette — run\n// plays, plan strategizes, verify-adjacent categories (test/lint) carry their\n// own marks so the filter menu reads at a glance.\nexport const CATEGORY_ICONS: Record<SessionCategory, StaticIconComponent> = {\n build: UiPackage,\n test: UiBeaker,\n install: UiCloudDownload,\n explore: UiSearch,\n lint: UiShieldCheck,\n cleanup: UiTrash,\n git: UiGitBranch,\n docker: UiBox,\n k8s: UiBoxes,\n run: UiPlayCircle,\n plan: UiStrategy,\n edit: UiPencilSimpleLine,\n clarify: UiQuestion,\n read: UiEye,\n other: UiWrench,\n};\n\nconst CATEGORY_PRIORITY: Record<SessionCategory, number> = {\n install: 100,\n edit: 90,\n run: 80,\n test: 70,\n build: 60,\n cleanup: 50,\n docker: 40,\n k8s: 40,\n git: 30,\n explore: 20,\n lint: 20,\n plan: 20,\n read: 15,\n clarify: 10,\n other: 0,\n};\n\ninterface CategoryRule {\n tools?: string[];\n commands?: string[];\n patterns?: string[];\n}\n\n// Mirrors pkg/bash/category_config.yaml. Order is irrelevant — ties resolve by\n// match specificity, then priority, then category name (see chooseBetterMatch).\nconst CATEGORY_CONFIG: Array<[SessionCategory, CategoryRule]> = [\n [\n \"build\",\n {\n commands: [\"go build\", \"make build\", \"make all\", \"cargo build\", \"npm run build\", \"yarn build\", \"task build\", \"gradle build\", \"mvn compile\", \"mvn package\", \"dotnet build\", \"pnpm build\", \"bun build\", \"mage\", \"bazel build\", \"nx build\", \"turbo build\", \"javac\"],\n patterns: [\".*gradle.*(build|compile|bootJar|jar).*\", \".*mvn.*(compile|package)\", \"^go build\", \"^make\\\\s*$\", \"^make\\\\s+(build|all)\\\\b\", \"^cargo build\", \"^task build\"],\n },\n ],\n [\n \"test\",\n {\n commands: [\"go test\", \"pytest\", \"npm test\", \"yarn test\", \"task test\", \"make test\", \"cargo test\", \"mvn test\", \"gradle test\", \"vitest\", \"jest\", \"bun test\", \"dotnet test\", \"ginkgo\", \"gotestsum\", \"zig test\"],\n patterns: [\".*gradle.*test\", \".*mvn.*test\", \"^go test\", \"^pytest\", \"^npm (run )?test\", \"^make\\\\s+test\", \"^vitest\", \"^jest\", \"^bun test\", \"^ginkgo\", \"^gotestsum\"],\n },\n ],\n [\n \"install\",\n {\n commands: [\"npm install\", \"npm i\", \"yarn install\", \"yarn add\", \"go mod tidy\", \"go mod download\", \"go get\", \"pip install\", \"pip3 install\", \"cargo add\", \"brew install\", \"apt install\", \"apt-get install\", \"pnpm install\", \"pnpm add\", \"bun install\", \"bun add\", \"poetry install\", \"poetry add\", \"uv pip install\", \"pdm install\", \"pdm add\"],\n patterns: [\"^npm (install|i)\\\\b\", \"^yarn (install|add)\\\\b\", \"^pip3? install\", \"^go (mod tidy|mod download|get)\", \"^pnpm (install|add)\\\\b\", \"^bun (install|add)\\\\b\", \"^poetry (install|add)\\\\b\", \"^uv pip install\", \"^pdm (install|add)\\\\b\"],\n },\n ],\n [\n \"explore\",\n {\n tools: [\"Read\", \"Grep\", \"Glob\", \"LSP\", \"WebFetch\", \"WebSearch\"],\n commands: [\"ls\", \"md5\", \"echo\", \"find\", \"grep\", \"rg\", \"ag\", \"cat\", \"head\", \"tail\", \"less\", \"more\", \"tree\", \"wc\", \"file\", \"stat\", \"du\", \"df\", \"pwd\", \"which\", \"whereis\", \"type\", \"fd\", \"bat\", \"exa\", \"eza\", \"fzf\", \"jq\", \"yq\", \"ripgrep\", \"sd\", \"diff\", \"go list\", \"git status\", \"git diff\", \"git log\", \"ps\", \"printenv\", \"sed\"],\n patterns: [\"^ls\\\\b\", \"^find\\\\b\", \"^grep\\\\b\", \"^rg\\\\b\", \"^cat\\\\b\", \"^head\\\\b\", \"^tail\\\\b\", \"^tree\\\\b\", \"^fd\\\\b\", \"^bat\\\\b\", \"^exa\\\\b\", \"^eza\\\\b\", \"^jq\\\\b\", \"^yq\\\\b\", \"^diff\\\\b\", \"^go list\\\\b\", \"^git\\\\s+(status|diff|log)\\\\b\"],\n },\n ],\n [\n \"lint\",\n {\n commands: [\"golangci-lint\", \"eslint\", \"gofmt\", \"go fmt\", \"prettier\", \"black\", \"flake8\", \"pylint\", \"rubocop\", \"shellcheck\", \"task fmt\", \"make fmt\", \"make lint\", \"biome\", \"ruff\", \"mypy\", \"staticcheck\", \"buf lint\", \"deno lint\", \"oxlint\"],\n patterns: [\"lint\", \"^go fmt\", \"^gofmt\", \"^prettier\", \"^black\\\\b\", \"^biome\\\\b\", \"^ruff\\\\b\", \"^mypy\\\\b\", \"^staticcheck\\\\b\"],\n },\n ],\n [\n \"cleanup\",\n {\n commands: [\"rm\", \"rmdir\", \"git clean\", \"make clean\", \"cargo clean\", \"go clean\", \"npm cache clean\", \"docker prune\", \"docker system prune\"],\n patterns: [\"^rm\\\\b\", \"^rmdir\\\\b\", \"clean\\\\b\", \"prune\\\\b\"],\n },\n ],\n [\n \"git\",\n {\n commands: [\"git show\", \"git branch\", \"git checkout\", \"git switch\", \"git commit\", \"git push\", \"git pull\", \"git fetch\", \"git merge\", \"git rebase\", \"git stash\", \"git add\", \"git reset\", \"git clone\", \"git remote\", \"git tag\"],\n patterns: [\"^git\\\\b\"],\n },\n ],\n [\n \"docker\",\n {\n commands: [\"docker run\", \"docker build\", \"docker push\", \"docker pull\", \"docker ps\", \"docker images\", \"docker logs\", \"docker exec\", \"docker stop\", \"docker start\", \"docker rm\", \"docker rmi\", \"docker-compose\", \"podman\"],\n patterns: [\"^docker\\\\b\", \"^docker-compose\\\\b\", \"^podman\\\\b\"],\n },\n ],\n [\n \"k8s\",\n {\n commands: [\"kubectl\", \"helm\", \"k9s\", \"kubectx\", \"kubens\", \"kustomize\", \"minikube\", \"kind\"],\n patterns: [\"^kubectl\\\\b\", \"^helm\\\\b\", \"^k9s\\\\b\", \"^kubectx\\\\b\", \"^kubens\\\\b\", \"^kustomize\\\\b\", \"^minikube\\\\b\", \"^kind\\\\b\"],\n },\n ],\n [\n \"run\",\n {\n tools: [\"KillShell\"],\n commands: [\"go run\", \"python\", \"python3\", \"node\", \"bun run\", \"deno run\", \"ruby\", \"perl\", \"php\", \"java\"],\n patterns: [\".*gradle.*run.*\", \"^go run\\\\b\", \"^python3?\\\\b\", \"^node\\\\b\", \"^bun run\\\\b\", \"^deno run\\\\b\", \"^ruby\\\\b\", \"^perl\\\\b\", \"^php\\\\b\", \"^java\\\\s+-jar\\\\b\", \"^\\\\./[\\\\w.-]+\\\\.(sh|bash|py|rb|pl)$\", \"^bash\\\\s+\\\\S+\\\\.sh\"],\n },\n ],\n [\n \"plan\",\n {\n tools: [\"Task\", \"TodoWrite\", \"EnterPlanMode\"],\n commands: [\"task\", \"make help\", \"task explore\", \"task plan\", \"task todos\", \"task todo\"],\n patterns: [\"^task\\\\s*$\", \"^task\\\\s+--list\", \"^make\\\\s+help\"],\n },\n ],\n [\n \"edit\",\n {\n tools: [\"Edit\", \"Write\", \"NotebookEdit\"],\n commands: [\"mkdir\"],\n patterns: [\"sed.* -i\"],\n },\n ],\n [\"clarify\", { tools: [\"AskUserQuestion\", \"ExitPlanMode\", \"TaskOutput\"] }],\n];\n\nconst COMPILED: Array<[SessionCategory, RegExp[]]> = CATEGORY_CONFIG.map(([cat, rule]) => [\n cat,\n (rule.patterns ?? []).map((p) => new RegExp(p)),\n]);\n\ninterface CategoryMatch {\n category: SessionCategory;\n specificity: number;\n matched: boolean;\n}\n\n// Port of betterCategoryMatch: prefer higher match specificity, then higher\n// category priority, then the lexicographically smaller name.\nfunction chooseBetterMatch(current: CategoryMatch, candidate: CategoryMatch): CategoryMatch {\n if (!candidate.matched || candidate.category === \"other\") return current;\n if (!current.matched || current.category === \"other\") return candidate;\n if (candidate.specificity > current.specificity) return candidate;\n if (candidate.specificity < current.specificity) return current;\n const cp = CATEGORY_PRIORITY[candidate.category];\n const kp = CATEGORY_PRIORITY[current.category];\n if (cp > kp) return candidate;\n if (cp < kp) return current;\n return candidate.category < current.category ? candidate : current;\n}\n\n/** Classify a raw shell command, mirroring captain's `Classify`. */\nexport function classifyCommand(command: string): SessionCategory {\n const cmd = command.trim();\n if (!cmd) return \"other\";\n let best: CategoryMatch = { category: \"other\", specificity: 0, matched: false };\n for (const [cat, rule] of CATEGORY_CONFIG) {\n for (const prefix of rule.commands ?? []) {\n if (cmd === prefix || cmd.startsWith(`${prefix} `)) {\n best = chooseBetterMatch(best, { category: cat, specificity: prefix.length, matched: true });\n }\n }\n }\n for (const [cat, regexps] of COMPILED) {\n for (const re of regexps) {\n if (re.test(cmd)) {\n best = chooseBetterMatch(best, { category: cat, specificity: re.source.length, matched: true });\n }\n }\n }\n return best.category;\n}\n\nfunction classifyTool(tool: string): SessionCategory {\n for (const [cat, rule] of CATEGORY_CONFIG) {\n if (rule.tools?.includes(tool)) return cat;\n }\n return \"other\";\n}\n\nfunction inputString(input: Record<string, unknown> | undefined, key: string): string {\n return typeof input?.[key] === \"string\" ? (input[key] as string) : \"\";\n}\n\n/** Category for a tool invocation, mirroring captain's classifyToolUse: a\n * `.claude/plans/` path is plan; a Bash command falls through to command\n * classification when the tool itself is uncategorized. */\nexport function classifyToolCategory(tool: string, input?: Record<string, unknown>): SessionCategory {\n const filePath =\n inputString(input, \"file_path\") || inputString(input, \"notebook_path\") || inputString(input, \"path\");\n if (filePath.includes(\"/.claude/plans/\")) return \"plan\";\n const cat = classifyTool(tool);\n if (cat === \"other\" && tool === \"Bash\") return classifyCommand(inputString(input, \"command\"));\n return cat;\n}\n\n/** The category of a normalized event, or null for non-tool events. */\nexport function eventCategory(event: SessionEvent): SessionCategory | null {\n if (event.kind !== \"tool\") return null;\n return classifyToolCategory(event.tool ?? \"\", event.toolInput);\n}\n\nexport interface SessionFilters {\n /** Distinct categories present, ordered by descending impact priority. */\n categories: SessionCategory[];\n /** Distinct tools present, with display labels, ordered by label. */\n tools: Array<{ key: string; label: string }>;\n /** Distinct sources present (e.g. \"claude\", \"codex\"). */\n sources: string[];\n}\n\nexport interface SessionVisibility {\n hiddenCategories: ReadonlySet<SessionCategory>;\n hiddenTools: ReadonlySet<string>;\n hiddenSources: ReadonlySet<string>;\n /** When false, reasoning (\"thinking\") events are hidden. */\n showThinking: boolean;\n}\n\n/** Whether an event survives the active filters. Tool events are gated by their\n * tool, category and source; reasoning by `showThinking`; everything else\n * (user/assistant/error) is always shown. */\nexport function isEventVisible(event: SessionEvent, v: SessionVisibility): boolean {\n if (event.pending) return true;\n if (event.kind === \"thinking\") return v.showThinking;\n if (event.kind !== \"tool\") return true;\n const tool = event.tool ?? \"\";\n if (v.hiddenTools.has(tool)) return false;\n if (v.hiddenCategories.has(classifyToolCategory(tool, event.toolInput))) return false;\n if (event.source && v.hiddenSources.has(event.source)) return false;\n return true;\n}\n\n/** Collect the filter facets (category / tool / source) present in a session. */\nexport function collectSessionFilters(events: SessionEvent[]): SessionFilters {\n const categories = new Set<SessionCategory>();\n const tools = new Map<string, string>();\n const sources = new Set<string>();\n for (const event of events) {\n if (event.kind !== \"tool\") continue;\n const tool = event.tool ?? \"\";\n categories.add(classifyToolCategory(tool, event.toolInput));\n if (!tools.has(tool)) tools.set(tool, getSessionAction(tool).label);\n if (event.source) sources.add(event.source);\n }\n return {\n categories: [...categories].sort(\n (a, b) => CATEGORY_PRIORITY[b] - CATEGORY_PRIORITY[a] || a.localeCompare(b),\n ),\n tools: [...tools].map(([key, label]) => ({ key, label })).sort((a, b) => a.label.localeCompare(b.label)),\n sources: [...sources].sort(),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-categories.js","sources":["../../../src/data/ai/session-categories.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport {\n UiBeaker,\n UiBox,\n UiBoxes,\n UiCloudDownload,\n UiEye,\n UiGitBranch,\n UiPackage,\n UiPencilSimpleLine,\n UiPlayCircle,\n UiQuestion,\n UiSearch,\n UiShieldCheck,\n UiStrategy,\n UiTrash,\n UiWrench,\n} from \"../../icons\";\nimport { getSessionAction, type SessionEvent } from \"./SessionViewer.model\";\n\n// ── Captain category taxonomy ───────────────────────────────────────────────\n// A faithful TypeScript port of captain's `pkg/bash` category classifier\n// (`category.go` + `category_config.yaml`) so the SessionViewer's filter mirrors\n// what `captain history --category` / `--tool` expose. A tool maps to a category\n// either directly (Read → explore, Edit → edit, …) or, for Bash, by classifying\n// the command string.\n\nexport type SessionCategory =\n | \"build\"\n | \"test\"\n | \"install\"\n | \"explore\"\n | \"lint\"\n | \"cleanup\"\n | \"git\"\n | \"docker\"\n | \"k8s\"\n | \"run\"\n | \"plan\"\n | \"edit\"\n | \"clarify\"\n | \"read\"\n | \"other\";\n\nexport const CATEGORY_LABELS: Record<SessionCategory, string> = {\n build: \"Build\",\n test: \"Test\",\n install: \"Install\",\n explore: \"Explore\",\n lint: \"Lint\",\n cleanup: \"Cleanup\",\n git: \"Git\",\n docker: \"Docker\",\n k8s: \"Kubernetes\",\n run: \"Run\",\n plan: \"Plan\",\n edit: \"Edit\",\n clarify: \"Clarify\",\n read: \"Read\",\n other: \"Other\",\n};\n\n// Per-category glyph, following the \"Agent Action Icons\" workflow palette — run\n// plays, plan strategizes, verify-adjacent categories (test/lint) carry their\n// own marks so the filter menu reads at a glance.\nexport const CATEGORY_ICONS: Record<SessionCategory, StaticIconComponent> = {\n build: UiPackage,\n test: UiBeaker,\n install: UiCloudDownload,\n explore: UiSearch,\n lint: UiShieldCheck,\n cleanup: UiTrash,\n git: UiGitBranch,\n docker: UiBox,\n k8s: UiBoxes,\n run: UiPlayCircle,\n plan: UiStrategy,\n edit: UiPencilSimpleLine,\n clarify: UiQuestion,\n read: UiEye,\n other: UiWrench,\n};\n\nconst CATEGORY_PRIORITY: Record<SessionCategory, number> = {\n install: 100,\n edit: 90,\n run: 80,\n test: 70,\n build: 60,\n cleanup: 50,\n docker: 40,\n k8s: 40,\n git: 30,\n explore: 20,\n lint: 20,\n plan: 20,\n read: 15,\n clarify: 10,\n other: 0,\n};\n\ninterface CategoryRule {\n tools?: string[];\n commands?: string[];\n patterns?: string[];\n}\n\n// Mirrors pkg/bash/category_config.yaml. Order is irrelevant — ties resolve by\n// match specificity, then priority, then category name (see chooseBetterMatch).\nconst CATEGORY_CONFIG: Array<[SessionCategory, CategoryRule]> = [\n [\n \"build\",\n {\n commands: [\"go build\", \"make build\", \"make all\", \"cargo build\", \"npm run build\", \"yarn build\", \"task build\", \"gradle build\", \"mvn compile\", \"mvn package\", \"dotnet build\", \"pnpm build\", \"bun build\", \"mage\", \"bazel build\", \"nx build\", \"turbo build\", \"javac\"],\n patterns: [\".*gradle.*(build|compile|bootJar|jar).*\", \".*mvn.*(compile|package)\", \"^go build\", \"^make\\\\s*$\", \"^make\\\\s+(build|all)\\\\b\", \"^cargo build\", \"^task build\"],\n },\n ],\n [\n \"test\",\n {\n commands: [\"go test\", \"pytest\", \"npm test\", \"yarn test\", \"task test\", \"make test\", \"cargo test\", \"mvn test\", \"gradle test\", \"vitest\", \"jest\", \"bun test\", \"dotnet test\", \"ginkgo\", \"gotestsum\", \"zig test\"],\n patterns: [\".*gradle.*test\", \".*mvn.*test\", \"^go test\", \"^pytest\", \"^npm (run )?test\", \"^make\\\\s+test\", \"^vitest\", \"^jest\", \"^bun test\", \"^ginkgo\", \"^gotestsum\"],\n },\n ],\n [\n \"install\",\n {\n commands: [\"npm install\", \"npm i\", \"yarn install\", \"yarn add\", \"go mod tidy\", \"go mod download\", \"go get\", \"pip install\", \"pip3 install\", \"cargo add\", \"brew install\", \"apt install\", \"apt-get install\", \"pnpm install\", \"pnpm add\", \"bun install\", \"bun add\", \"poetry install\", \"poetry add\", \"uv pip install\", \"pdm install\", \"pdm add\"],\n patterns: [\"^npm (install|i)\\\\b\", \"^yarn (install|add)\\\\b\", \"^pip3? install\", \"^go (mod tidy|mod download|get)\", \"^pnpm (install|add)\\\\b\", \"^bun (install|add)\\\\b\", \"^poetry (install|add)\\\\b\", \"^uv pip install\", \"^pdm (install|add)\\\\b\"],\n },\n ],\n [\n \"explore\",\n {\n tools: [\"Read\", \"Grep\", \"Glob\", \"LSP\", \"WebFetch\", \"WebSearch\"],\n commands: [\"ls\", \"md5\", \"echo\", \"find\", \"grep\", \"rg\", \"ag\", \"cat\", \"head\", \"tail\", \"less\", \"more\", \"tree\", \"wc\", \"file\", \"stat\", \"du\", \"df\", \"pwd\", \"which\", \"whereis\", \"type\", \"fd\", \"bat\", \"exa\", \"eza\", \"fzf\", \"jq\", \"yq\", \"ripgrep\", \"sd\", \"diff\", \"go list\", \"git status\", \"git diff\", \"git log\", \"ps\", \"printenv\", \"sed\"],\n patterns: [\"^ls\\\\b\", \"^find\\\\b\", \"^grep\\\\b\", \"^rg\\\\b\", \"^cat\\\\b\", \"^head\\\\b\", \"^tail\\\\b\", \"^tree\\\\b\", \"^fd\\\\b\", \"^bat\\\\b\", \"^exa\\\\b\", \"^eza\\\\b\", \"^jq\\\\b\", \"^yq\\\\b\", \"^diff\\\\b\", \"^go list\\\\b\", \"^git\\\\s+(status|diff|log)\\\\b\"],\n },\n ],\n [\n \"lint\",\n {\n commands: [\"golangci-lint\", \"eslint\", \"gofmt\", \"go fmt\", \"prettier\", \"black\", \"flake8\", \"pylint\", \"rubocop\", \"shellcheck\", \"task fmt\", \"make fmt\", \"make lint\", \"biome\", \"ruff\", \"mypy\", \"staticcheck\", \"buf lint\", \"deno lint\", \"oxlint\"],\n patterns: [\"lint\", \"^go fmt\", \"^gofmt\", \"^prettier\", \"^black\\\\b\", \"^biome\\\\b\", \"^ruff\\\\b\", \"^mypy\\\\b\", \"^staticcheck\\\\b\"],\n },\n ],\n [\n \"cleanup\",\n {\n commands: [\"rm\", \"rmdir\", \"git clean\", \"make clean\", \"cargo clean\", \"go clean\", \"npm cache clean\", \"docker prune\", \"docker system prune\"],\n patterns: [\"^rm\\\\b\", \"^rmdir\\\\b\", \"clean\\\\b\", \"prune\\\\b\"],\n },\n ],\n [\n \"git\",\n {\n commands: [\"git show\", \"git branch\", \"git checkout\", \"git switch\", \"git commit\", \"git push\", \"git pull\", \"git fetch\", \"git merge\", \"git rebase\", \"git stash\", \"git add\", \"git reset\", \"git clone\", \"git remote\", \"git tag\"],\n patterns: [\"^git\\\\b\"],\n },\n ],\n [\n \"docker\",\n {\n commands: [\"docker run\", \"docker build\", \"docker push\", \"docker pull\", \"docker ps\", \"docker images\", \"docker logs\", \"docker exec\", \"docker stop\", \"docker start\", \"docker rm\", \"docker rmi\", \"docker-compose\", \"podman\"],\n patterns: [\"^docker\\\\b\", \"^docker-compose\\\\b\", \"^podman\\\\b\"],\n },\n ],\n [\n \"k8s\",\n {\n commands: [\"kubectl\", \"helm\", \"k9s\", \"kubectx\", \"kubens\", \"kustomize\", \"minikube\", \"kind\"],\n patterns: [\"^kubectl\\\\b\", \"^helm\\\\b\", \"^k9s\\\\b\", \"^kubectx\\\\b\", \"^kubens\\\\b\", \"^kustomize\\\\b\", \"^minikube\\\\b\", \"^kind\\\\b\"],\n },\n ],\n [\n \"run\",\n {\n tools: [\"KillShell\"],\n commands: [\"go run\", \"python\", \"python3\", \"node\", \"bun run\", \"deno run\", \"ruby\", \"perl\", \"php\", \"java\"],\n patterns: [\".*gradle.*run.*\", \"^go run\\\\b\", \"^python3?\\\\b\", \"^node\\\\b\", \"^bun run\\\\b\", \"^deno run\\\\b\", \"^ruby\\\\b\", \"^perl\\\\b\", \"^php\\\\b\", \"^java\\\\s+-jar\\\\b\", \"^\\\\./[\\\\w.-]+\\\\.(sh|bash|py|rb|pl)$\", \"^bash\\\\s+\\\\S+\\\\.sh\"],\n },\n ],\n [\n \"plan\",\n {\n tools: [\"Task\", \"TodoWrite\", \"EnterPlanMode\"],\n commands: [\"task\", \"make help\", \"task explore\", \"task plan\", \"task todos\", \"task todo\"],\n patterns: [\"^task\\\\s*$\", \"^task\\\\s+--list\", \"^make\\\\s+help\"],\n },\n ],\n [\n \"edit\",\n {\n tools: [\"Edit\", \"Write\", \"NotebookEdit\"],\n commands: [\"mkdir\"],\n patterns: [\"sed.* -i\"],\n },\n ],\n [\"clarify\", { tools: [\"AskUserQuestion\", \"ExitPlanMode\", \"TaskOutput\"] }],\n];\n\nconst COMPILED: Array<[SessionCategory, RegExp[]]> = CATEGORY_CONFIG.map(([cat, rule]) => [\n cat,\n (rule.patterns ?? []).map((p) => new RegExp(p)),\n]);\n\ninterface CategoryMatch {\n category: SessionCategory;\n specificity: number;\n matched: boolean;\n}\n\n// Port of betterCategoryMatch: prefer higher match specificity, then higher\n// category priority, then the lexicographically smaller name.\nfunction chooseBetterMatch(current: CategoryMatch, candidate: CategoryMatch): CategoryMatch {\n if (!candidate.matched || candidate.category === \"other\") return current;\n if (!current.matched || current.category === \"other\") return candidate;\n if (candidate.specificity > current.specificity) return candidate;\n if (candidate.specificity < current.specificity) return current;\n const cp = CATEGORY_PRIORITY[candidate.category];\n const kp = CATEGORY_PRIORITY[current.category];\n if (cp > kp) return candidate;\n if (cp < kp) return current;\n return candidate.category < current.category ? candidate : current;\n}\n\n/** Classify a raw shell command, mirroring captain's `Classify`. */\nexport function classifyCommand(command: string): SessionCategory {\n const cmd = command.trim();\n if (!cmd) return \"other\";\n let best: CategoryMatch = { category: \"other\", specificity: 0, matched: false };\n for (const [cat, rule] of CATEGORY_CONFIG) {\n for (const prefix of rule.commands ?? []) {\n if (cmd === prefix || cmd.startsWith(`${prefix} `)) {\n best = chooseBetterMatch(best, { category: cat, specificity: prefix.length, matched: true });\n }\n }\n }\n for (const [cat, regexps] of COMPILED) {\n for (const re of regexps) {\n if (re.test(cmd)) {\n best = chooseBetterMatch(best, { category: cat, specificity: re.source.length, matched: true });\n }\n }\n }\n return best.category;\n}\n\nfunction classifyTool(tool: string): SessionCategory {\n for (const [cat, rule] of CATEGORY_CONFIG) {\n if (rule.tools?.includes(tool)) return cat;\n }\n return \"other\";\n}\n\nfunction inputString(input: Record<string, unknown> | undefined, key: string): string {\n return typeof input?.[key] === \"string\" ? (input[key] as string) : \"\";\n}\n\n/** Category for a tool invocation, mirroring captain's classifyToolUse: a\n * `.claude/plans/` path is plan; a Bash command falls through to command\n * classification when the tool itself is uncategorized. */\nexport function classifyToolCategory(tool: string, input?: Record<string, unknown>): SessionCategory {\n const filePath =\n inputString(input, \"file_path\") || inputString(input, \"notebook_path\") || inputString(input, \"path\");\n if (filePath.includes(\"/.claude/plans/\")) return \"plan\";\n const cat = classifyTool(tool);\n if (cat === \"other\" && tool === \"Bash\") return classifyCommand(inputString(input, \"command\"));\n return cat;\n}\n\n/** The category of a normalized event, or null for non-tool events. */\nexport function eventCategory(event: SessionEvent): SessionCategory | null {\n if (event.kind !== \"tool\") return null;\n return classifyToolCategory(event.tool ?? \"\", event.toolInput);\n}\n\nexport interface SessionFilters {\n /** Distinct categories present, ordered by descending impact priority. */\n categories: SessionCategory[];\n /** Distinct tools present, with display labels, ordered by label. */\n tools: Array<{ key: string; label: string }>;\n /** Distinct sources present (e.g. \"claude\", \"codex\"). */\n sources: string[];\n}\n\nexport interface SessionVisibility {\n hiddenCategories: ReadonlySet<SessionCategory>;\n hiddenTools: ReadonlySet<string>;\n hiddenSources: ReadonlySet<string>;\n /** When false, reasoning (\"thinking\") events are hidden. */\n showThinking: boolean;\n}\n\nexport function isEncryptedReasoning(event: SessionEvent): boolean {\n return event.kind === \"thinking\" && /^\\d+ encrypted reasoning records? (?:at|over) \\S/.test(event.text ?? \"\");\n}\n\n/** Whether an event survives the active filters. Tool events are gated by their\n * tool, category and source; reasoning by `showThinking`; everything else\n * (user/assistant/error) is always shown. */\nexport function isEventVisible(event: SessionEvent, v: SessionVisibility): boolean {\n if (event.pending) return true;\n if (event.kind === \"thinking\") return v.showThinking;\n if (event.kind !== \"tool\") return true;\n const tool = event.tool ?? \"\";\n if (v.hiddenTools.has(tool)) return false;\n if (v.hiddenCategories.has(classifyToolCategory(tool, event.toolInput))) return false;\n if (event.source && v.hiddenSources.has(event.source)) return false;\n return true;\n}\n\n/** Collect the filter facets (category / tool / source) present in a session. */\nexport function collectSessionFilters(events: SessionEvent[]): SessionFilters {\n const categories = new Set<SessionCategory>();\n const tools = new Map<string, string>();\n const sources = new Set<string>();\n for (const event of events) {\n if (event.kind !== \"tool\") continue;\n const tool = event.tool ?? \"\";\n categories.add(classifyToolCategory(tool, event.toolInput));\n if (!tools.has(tool)) tools.set(tool, getSessionAction(tool).label);\n if (event.source) sources.add(event.source);\n }\n return {\n categories: [...categories].sort(\n (a, b) => CATEGORY_PRIORITY[b] - CATEGORY_PRIORITY[a] || a.localeCompare(b),\n ),\n tools: [...tools].map(([key, label]) => ({ key, label })).sort((a, b) => a.label.localeCompare(b.label)),\n sources: [...sources].sort(),\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA4CO,MAAM,kBAAmD;AAAA,EAC9D,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AACT;AAKO,MAAM,iBAA+D;AAAA,EAC1E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AACT;AAEA,MAAM,oBAAqD;AAAA,EACzD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AACT;AAUA,MAAM,kBAA0D;AAAA,EAC9D;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,YAAY,cAAc,YAAY,eAAe,iBAAiB,cAAc,cAAc,gBAAgB,eAAe,eAAe,gBAAgB,cAAc,aAAa,QAAQ,eAAe,YAAY,eAAe,OAAO;AAAA,MAC/P,UAAU,CAAC,2CAA2C,4BAA4B,aAAa,cAAc,2BAA2B,gBAAgB,aAAa;AAAA,IAAA;AAAA,EACvK;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,WAAW,UAAU,YAAY,aAAa,aAAa,aAAa,cAAc,YAAY,eAAe,UAAU,QAAQ,YAAY,eAAe,UAAU,aAAa,UAAU;AAAA,MAC1M,UAAU,CAAC,kBAAkB,eAAe,YAAY,WAAW,oBAAoB,iBAAiB,WAAW,SAAS,aAAa,WAAW,YAAY;AAAA,IAAA;AAAA,EAClK;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,eAAe,SAAS,gBAAgB,YAAY,eAAe,mBAAmB,UAAU,eAAe,gBAAgB,aAAa,gBAAgB,eAAe,mBAAmB,gBAAgB,YAAY,eAAe,WAAW,kBAAkB,cAAc,kBAAkB,eAAe,SAAS;AAAA,MACzU,UAAU,CAAC,uBAAuB,0BAA0B,kBAAkB,mCAAmC,0BAA0B,yBAAyB,4BAA4B,mBAAmB,uBAAuB;AAAA,IAAA;AAAA,EAC5O;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,OAAO,CAAC,QAAQ,QAAQ,QAAQ,OAAO,YAAY,WAAW;AAAA,MAC9D,UAAU,CAAC,MAAM,OAAO,QAAQ,QAAQ,QAAQ,MAAM,MAAM,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM,OAAO,SAAS,WAAW,QAAQ,MAAM,OAAO,OAAO,OAAO,OAAO,MAAM,MAAM,WAAW,MAAM,QAAQ,WAAW,cAAc,YAAY,WAAW,MAAM,YAAY,KAAK;AAAA,MAC9T,UAAU,CAAC,UAAU,YAAY,YAAY,UAAU,WAAW,YAAY,YAAY,YAAY,UAAU,WAAW,WAAW,WAAW,UAAU,UAAU,YAAY,eAAe,8BAA8B;AAAA,IAAA;AAAA,EAChO;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,iBAAiB,UAAU,SAAS,UAAU,YAAY,SAAS,UAAU,UAAU,WAAW,cAAc,YAAY,YAAY,aAAa,SAAS,QAAQ,QAAQ,eAAe,YAAY,aAAa,QAAQ;AAAA,MACzO,UAAU,CAAC,QAAQ,WAAW,UAAU,aAAa,aAAa,aAAa,YAAY,YAAY,iBAAiB;AAAA,IAAA;AAAA,EAC1H;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,MAAM,SAAS,aAAa,cAAc,eAAe,YAAY,mBAAmB,gBAAgB,qBAAqB;AAAA,MACxI,UAAU,CAAC,UAAU,aAAa,YAAY,UAAU;AAAA,IAAA;AAAA,EAC1D;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,YAAY,cAAc,gBAAgB,cAAc,cAAc,YAAY,YAAY,aAAa,aAAa,cAAc,aAAa,WAAW,aAAa,aAAa,cAAc,SAAS;AAAA,MAC1N,UAAU,CAAC,SAAS;AAAA,IAAA;AAAA,EACtB;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,cAAc,gBAAgB,eAAe,eAAe,aAAa,iBAAiB,eAAe,eAAe,eAAe,gBAAgB,aAAa,cAAc,kBAAkB,QAAQ;AAAA,MACvN,UAAU,CAAC,cAAc,sBAAsB,YAAY;AAAA,IAAA;AAAA,EAC7D;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,UAAU,CAAC,WAAW,QAAQ,OAAO,WAAW,UAAU,aAAa,YAAY,MAAM;AAAA,MACzF,UAAU,CAAC,eAAe,YAAY,WAAW,eAAe,cAAc,iBAAiB,gBAAgB,UAAU;AAAA,IAAA;AAAA,EAC3H;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,OAAO,CAAC,WAAW;AAAA,MACnB,UAAU,CAAC,UAAU,UAAU,WAAW,QAAQ,WAAW,YAAY,QAAQ,QAAQ,OAAO,MAAM;AAAA,MACtG,UAAU,CAAC,mBAAmB,cAAc,gBAAgB,YAAY,eAAe,gBAAgB,YAAY,YAAY,WAAW,oBAAoB,uCAAuC,oBAAoB;AAAA,IAAA;AAAA,EAC3N;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,OAAO,CAAC,QAAQ,aAAa,eAAe;AAAA,MAC5C,UAAU,CAAC,QAAQ,aAAa,gBAAgB,aAAa,cAAc,WAAW;AAAA,MACtF,UAAU,CAAC,cAAc,mBAAmB,eAAe;AAAA,IAAA;AAAA,EAC7D;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,OAAO,CAAC,QAAQ,SAAS,cAAc;AAAA,MACvC,UAAU,CAAC,OAAO;AAAA,MAClB,UAAU,CAAC,UAAU;AAAA,IAAA;AAAA,EACvB;AAAA,EAEF,CAAC,WAAW,EAAE,OAAO,CAAC,mBAAmB,gBAAgB,YAAY,EAAA,CAAG;AAC1E;AAEA,MAAM,WAA+C,gBAAgB,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM;AAAA,EACxF;AAAA,GACC,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC;AAChD,CAAC;AAUD,SAAS,kBAAkB,SAAwB,WAAyC;AAC1F,MAAI,CAAC,UAAU,WAAW,UAAU,aAAa,QAAS,QAAO;AACjE,MAAI,CAAC,QAAQ,WAAW,QAAQ,aAAa,QAAS,QAAO;AAC7D,MAAI,UAAU,cAAc,QAAQ,YAAa,QAAO;AACxD,MAAI,UAAU,cAAc,QAAQ,YAAa,QAAO;AACxD,QAAM,KAAK,kBAAkB,UAAU,QAAQ;AAC/C,QAAM,KAAK,kBAAkB,QAAQ,QAAQ;AAC7C,MAAI,KAAK,GAAI,QAAO;AACpB,MAAI,KAAK,GAAI,QAAO;AACpB,SAAO,UAAU,WAAW,QAAQ,WAAW,YAAY;AAC7D;AAGO,SAAS,gBAAgB,SAAkC;AAChE,QAAM,MAAM,QAAQ,KAAA;AACpB,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAsB,EAAE,UAAU,SAAS,aAAa,GAAG,SAAS,MAAA;AACxE,aAAW,CAAC,KAAK,IAAI,KAAK,iBAAiB;AACzC,eAAW,UAAU,KAAK,YAAY,CAAA,GAAI;AACxC,UAAI,QAAQ,UAAU,IAAI,WAAW,GAAG,MAAM,GAAG,GAAG;AAClD,eAAO,kBAAkB,MAAM,EAAE,UAAU,KAAK,aAAa,OAAO,QAAQ,SAAS,KAAA,CAAM;AAAA,MAC7F;AAAA,IACF;AAAA,EACF;AACA,aAAW,CAAC,KAAK,OAAO,KAAK,UAAU;AACrC,eAAW,MAAM,SAAS;AACxB,UAAI,GAAG,KAAK,GAAG,GAAG;AAChB,eAAO,kBAAkB,MAAM,EAAE,UAAU,KAAK,aAAa,GAAG,OAAO,QAAQ,SAAS,KAAA,CAAM;AAAA,MAChG;AAAA,IACF;AAAA,EACF;AACA,SAAO,KAAK;AACd;AAEA,SAAS,aAAa,MAA+B;;AACnD,aAAW,CAAC,KAAK,IAAI,KAAK,iBAAiB;AACzC,SAAI,UAAK,UAAL,mBAAY,SAAS,MAAO,QAAO;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAA4C,KAAqB;AACpF,SAAO,QAAO,+BAAQ,UAAS,WAAY,MAAM,GAAG,IAAe;AACrE;AAKO,SAAS,qBAAqB,MAAc,OAAkD;AACnG,QAAM,WACJ,YAAY,OAAO,WAAW,KAAK,YAAY,OAAO,eAAe,KAAK,YAAY,OAAO,MAAM;AACrG,MAAI,SAAS,SAAS,iBAAiB,EAAG,QAAO;AACjD,QAAM,MAAM,aAAa,IAAI;AAC7B,MAAI,QAAQ,WAAW,SAAS,eAAe,gBAAgB,YAAY,OAAO,SAAS,CAAC;AAC5F,SAAO;AACT;AAGO,SAAS,cAAc,OAA6C;AACzE,MAAI,MAAM,SAAS,OAAQ,QAAO;AAClC,SAAO,qBAAqB,MAAM,QAAQ,IAAI,MAAM,SAAS;AAC/D;AAmBO,SAAS,qBAAqB,OAA8B;AACjE,SAAO,MAAM,SAAS,cAAc,mDAAmD,KAAK,MAAM,QAAQ,EAAE;AAC9G;AAKO,SAAS,eAAe,OAAqB,GAA+B;AACjF,MAAI,MAAM,QAAS,QAAO;AAC1B,MAAI,MAAM,SAAS,WAAY,QAAO,EAAE;AACxC,MAAI,MAAM,SAAS,OAAQ,QAAO;AAClC,QAAM,OAAO,MAAM,QAAQ;AAC3B,MAAI,EAAE,YAAY,IAAI,IAAI,EAAG,QAAO;AACpC,MAAI,EAAE,iBAAiB,IAAI,qBAAqB,MAAM,MAAM,SAAS,CAAC,EAAG,QAAO;AAChF,MAAI,MAAM,UAAU,EAAE,cAAc,IAAI,MAAM,MAAM,EAAG,QAAO;AAC9D,SAAO;AACT;AAGO,SAAS,sBAAsB,QAAwC;AAC5E,QAAM,iCAAiB,IAAA;AACvB,QAAM,4BAAY,IAAA;AAClB,QAAM,8BAAc,IAAA;AACpB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,OAAQ;AAC3B,UAAM,OAAO,MAAM,QAAQ;AAC3B,eAAW,IAAI,qBAAqB,MAAM,MAAM,SAAS,CAAC;AAC1D,QAAI,CAAC,MAAM,IAAI,IAAI,EAAG,OAAM,IAAI,MAAM,iBAAiB,IAAI,EAAE,KAAK;AAClE,QAAI,MAAM,OAAQ,SAAQ,IAAI,MAAM,MAAM;AAAA,EAC5C;AACA,SAAO;AAAA,IACL,YAAY,CAAC,GAAG,UAAU,EAAE;AAAA,MAC1B,CAAC,GAAG,MAAM,kBAAkB,CAAC,IAAI,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC;AAAA,IAAA;AAAA,IAE5E,OAAO,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,EAAE,KAAK,MAAA,EAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;AAAA,IACvG,SAAS,CAAC,GAAG,OAAO,EAAE,KAAA;AAAA,EAAK;AAE/B;"}
|
|
@@ -10,18 +10,20 @@ function isPinnedToBottom(metrics, threshold) {
|
|
|
10
10
|
function isNearTop(scrollTop, threshold) {
|
|
11
11
|
return scrollTop <= threshold;
|
|
12
12
|
}
|
|
13
|
-
const idleWindow = () => typeof window === "undefined" ? void 0 : window;
|
|
14
13
|
function useSessionScroll(options) {
|
|
15
14
|
const { total, enabled, windowSize, batchSize, resetKey } = options;
|
|
16
15
|
const bottomThreshold = options.bottomThreshold ?? 64;
|
|
17
16
|
const topThreshold = options.topThreshold ?? 600;
|
|
18
17
|
const scrollRef = react.useRef(null);
|
|
19
18
|
const contentRef = react.useRef(null);
|
|
20
|
-
const
|
|
19
|
+
const followingRef = react.useRef(true);
|
|
20
|
+
const lastScrollTopRef = react.useRef(0);
|
|
21
21
|
const anchorHeightRef = react.useRef(null);
|
|
22
22
|
const scrollBottomPendingRef = react.useRef(true);
|
|
23
23
|
const loadingOlderRef = react.useRef(false);
|
|
24
|
-
const
|
|
24
|
+
const previousTotalRef = react.useRef({ resetKey, total });
|
|
25
|
+
const [visibleCount, setVisibleCount] = react.useState(windowSize);
|
|
26
|
+
const [following, setFollowing] = react.useState(true);
|
|
25
27
|
const effectiveCount = enabled ? visibleCount : total;
|
|
26
28
|
const startIndex = Math.max(0, total - effectiveCount);
|
|
27
29
|
const hasMore = enabled && startIndex > 0;
|
|
@@ -29,8 +31,16 @@ function useSessionScroll(options) {
|
|
|
29
31
|
hasMoreRef.current = hasMore;
|
|
30
32
|
const scrollToBottom = react.useCallback(() => {
|
|
31
33
|
const el = scrollRef.current;
|
|
32
|
-
if (el)
|
|
34
|
+
if (el) {
|
|
35
|
+
el.scrollTop = el.scrollHeight;
|
|
36
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
37
|
+
}
|
|
33
38
|
}, []);
|
|
39
|
+
const resumeFollowing = react.useCallback(() => {
|
|
40
|
+
followingRef.current = true;
|
|
41
|
+
setFollowing(true);
|
|
42
|
+
scrollToBottom();
|
|
43
|
+
}, [scrollToBottom]);
|
|
34
44
|
const growOlder = react.useCallback(() => {
|
|
35
45
|
if (loadingOlderRef.current || !hasMoreRef.current) return;
|
|
36
46
|
loadingOlderRef.current = true;
|
|
@@ -42,52 +52,70 @@ function useSessionScroll(options) {
|
|
|
42
52
|
growOlderRef.current = growOlder;
|
|
43
53
|
react.useLayoutEffect(() => {
|
|
44
54
|
if (!enabled) return;
|
|
45
|
-
setVisibleCount(
|
|
46
|
-
|
|
55
|
+
setVisibleCount(windowSize);
|
|
56
|
+
followingRef.current = true;
|
|
57
|
+
setFollowing(true);
|
|
47
58
|
loadingOlderRef.current = false;
|
|
48
59
|
scrollBottomPendingRef.current = true;
|
|
49
|
-
}, [enabled, resetKey, windowSize
|
|
60
|
+
}, [enabled, resetKey, windowSize]);
|
|
61
|
+
react.useLayoutEffect(() => {
|
|
62
|
+
const previous = previousTotalRef.current;
|
|
63
|
+
previousTotalRef.current = { resetKey, total };
|
|
64
|
+
if (enabled && previous.resetKey === resetKey && !followingRef.current && total > previous.total) {
|
|
65
|
+
setVisibleCount((count) => count + total - previous.total);
|
|
66
|
+
}
|
|
67
|
+
}, [enabled, resetKey, total]);
|
|
50
68
|
react.useLayoutEffect(() => {
|
|
51
69
|
const el = scrollRef.current;
|
|
52
70
|
if (!enabled || !el) return;
|
|
53
71
|
if (scrollBottomPendingRef.current) {
|
|
54
72
|
scrollBottomPendingRef.current = false;
|
|
55
73
|
anchorHeightRef.current = null;
|
|
56
|
-
|
|
74
|
+
scrollToBottom();
|
|
57
75
|
} else if (anchorHeightRef.current != null) {
|
|
58
76
|
el.scrollTop += el.scrollHeight - anchorHeightRef.current;
|
|
59
77
|
anchorHeightRef.current = null;
|
|
78
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
79
|
+
} else if (followingRef.current) {
|
|
80
|
+
scrollToBottom();
|
|
60
81
|
}
|
|
61
82
|
loadingOlderRef.current = false;
|
|
62
|
-
}, [enabled, visibleCount]);
|
|
83
|
+
}, [enabled, visibleCount, total, scrollToBottom]);
|
|
63
84
|
react.useEffect(() => {
|
|
64
85
|
const el = scrollRef.current;
|
|
65
86
|
if (!enabled || !el) return;
|
|
66
87
|
const onScroll = () => {
|
|
67
|
-
|
|
88
|
+
const movedUp = el.scrollTop < lastScrollTopRef.current;
|
|
89
|
+
if (movedUp || !isPinnedToBottom(el, bottomThreshold)) {
|
|
90
|
+
followingRef.current = false;
|
|
91
|
+
setFollowing(false);
|
|
92
|
+
}
|
|
93
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
94
|
+
if (hasMoreRef.current && movedUp && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();
|
|
95
|
+
};
|
|
96
|
+
const onWheel = (event) => {
|
|
97
|
+
if (event.deltaY >= 0) return;
|
|
98
|
+
followingRef.current = false;
|
|
99
|
+
setFollowing(false);
|
|
68
100
|
if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();
|
|
69
101
|
};
|
|
70
102
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
71
|
-
|
|
103
|
+
el.addEventListener("wheel", onWheel, { passive: true });
|
|
104
|
+
return () => {
|
|
105
|
+
el.removeEventListener("scroll", onScroll);
|
|
106
|
+
el.removeEventListener("wheel", onWheel);
|
|
107
|
+
};
|
|
72
108
|
}, [enabled, bottomThreshold, topThreshold]);
|
|
73
109
|
react.useEffect(() => {
|
|
74
110
|
const content = contentRef.current;
|
|
75
111
|
if (!enabled || !content || typeof ResizeObserver === "undefined") return;
|
|
76
112
|
const observer = new ResizeObserver(() => {
|
|
77
|
-
if (
|
|
113
|
+
if (followingRef.current) scrollToBottom();
|
|
78
114
|
});
|
|
79
115
|
observer.observe(content);
|
|
80
116
|
return () => observer.disconnect();
|
|
81
117
|
}, [enabled, scrollToBottom]);
|
|
82
|
-
|
|
83
|
-
if (!enabled || !hasMore) return;
|
|
84
|
-
const win = idleWindow();
|
|
85
|
-
const request = (win == null ? void 0 : win.requestIdleCallback) ?? ((cb) => window.setTimeout(cb, 200));
|
|
86
|
-
const cancel = (win == null ? void 0 : win.cancelIdleCallback) ?? window.clearTimeout;
|
|
87
|
-
const handle = request(() => growOlderRef.current());
|
|
88
|
-
return () => cancel(handle);
|
|
89
|
-
}, [enabled, resetKey, hasMore]);
|
|
90
|
-
return { scrollRef, contentRef, startIndex, hasMore };
|
|
118
|
+
return { scrollRef, contentRef, startIndex, hasMore, following, resumeFollowing };
|
|
91
119
|
}
|
|
92
120
|
exports.isNearTop = isNearTop;
|
|
93
121
|
exports.isPinnedToBottom = isPinnedToBottom;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-scroll.cjs","sources":["../../../src/data/ai/use-session-scroll.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState, type RefObject } from \"react\";\n\n// Progressive windowing for the SessionViewer log. A recorded session runs to\n// thousands of rows (many with syntax-highlighted code blocks), so rendering the\n// whole transcript blocks first paint. Instead we render the *newest* screenful,\n// keep the view pinned to the bottom (most recent activity), and backfill older\n// rows as the reader scrolls up — the classic reverse-infinite-scroll of a chat\n// log. The pure helpers below hold the windowing math; the hook wires the DOM\n// listeners that drive it. Load-more is driven off scroll position rather than an\n// IntersectionObserver so it stays reliable in backgrounded/hidden tabs (where the\n// browser pauses observer callbacks tied to the render loop).\n\n/** The last `visibleCount` of `items`, plus where the window starts and whether\n * older items remain above it. */\nexport function windowSlice<T>(\n items: readonly T[],\n visibleCount: number,\n): { items: T[]; startIndex: number; hasMore: boolean } {\n const clamped = Math.max(0, Math.min(visibleCount, items.length));\n const startIndex = items.length - clamped;\n return { items: items.slice(startIndex), startIndex, hasMore: startIndex > 0 };\n}\n\n/** Grow the window by `batchSize`, never past `total`. */\nexport function nextVisibleCount(current: number, batchSize: number, total: number): number {\n return Math.min(current + Math.max(1, batchSize), total);\n}\n\n/** True when the scroll position sits within `threshold` px of the bottom. */\nexport function isPinnedToBottom(\n metrics: { scrollTop: number; scrollHeight: number; clientHeight: number },\n threshold: number,\n): boolean {\n return metrics.scrollHeight - metrics.scrollTop - metrics.clientHeight <= threshold;\n}\n\n/** True when the scroll position sits within `threshold` px of the top. */\nexport function isNearTop(scrollTop: number, threshold: number): boolean {\n return scrollTop <= threshold;\n}\n\nexport interface SessionScrollOptions {\n /** Number of filtered events available to render. */\n total: number;\n /** Turns the whole mechanism on; when false the hook renders every event. */\n enabled: boolean;\n /** Rows rendered on first paint (and after a session change). */\n windowSize: number;\n /** Rows added each time older content is loaded. */\n batchSize: number;\n /** Changing this resets the window and re-pins to the bottom — pass a value\n * derived from the session identity, not the filter state. */\n resetKey: string;\n /** Distance (px) from the bottom still counted as \"pinned\". */\n bottomThreshold?: number;\n /** Distance (px) from the top at which older rows start loading. */\n topThreshold?: number;\n}\n\nexport interface SessionScrollState {\n scrollRef: RefObject<HTMLDivElement | null>;\n contentRef: RefObject<HTMLDivElement | null>;\n startIndex: number;\n hasMore: boolean;\n}\n\nconst idleWindow = () =>\n (typeof window === \"undefined\" ? undefined : window) as\n | (Window & {\n requestIdleCallback?: (cb: () => void) => number;\n cancelIdleCallback?: (handle: number) => void;\n })\n | undefined;\n\nexport function useSessionScroll(options: SessionScrollOptions): SessionScrollState {\n const { total, enabled, windowSize, batchSize, resetKey } = options;\n const bottomThreshold = options.bottomThreshold ?? 64;\n const topThreshold = options.topThreshold ?? 600;\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const pinnedRef = useRef(true);\n const anchorHeightRef = useRef<number | null>(null);\n const scrollBottomPendingRef = useRef(true);\n const loadingOlderRef = useRef(false);\n\n const [visibleCount, setVisibleCount] = useState(() => Math.min(windowSize, total));\n const effectiveCount = enabled ? visibleCount : total;\n const startIndex = Math.max(0, total - effectiveCount);\n const hasMore = enabled && startIndex > 0;\n const hasMoreRef = useRef(hasMore);\n hasMoreRef.current = hasMore;\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, []);\n\n // Prepend an older batch, latching until the layout effect settles the prepend so\n // rapid scroll events don't stack multiple batches at once.\n const growOlder = useCallback(() => {\n if (loadingOlderRef.current || !hasMoreRef.current) return;\n loadingOlderRef.current = true;\n const el = scrollRef.current;\n anchorHeightRef.current = el ? el.scrollHeight : null;\n setVisibleCount((count) => nextVisibleCount(count, batchSize, total));\n }, [batchSize, total]);\n\n const growOlderRef = useRef(growOlder);\n growOlderRef.current = growOlder;\n\n // A new session (resetKey change) snaps back to the newest screenful and re-pins.\n useLayoutEffect(() => {\n if (!enabled) return;\n setVisibleCount(Math.min(windowSize, total));\n pinnedRef.current = true;\n loadingOlderRef.current = false;\n scrollBottomPendingRef.current = true;\n }, [enabled, resetKey, windowSize, total]);\n\n // After each commit, either snap to bottom (pending pin) or preserve the reader's\n // position when older rows were prepended (anchor), then release the load latch.\n useLayoutEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n if (scrollBottomPendingRef.current) {\n scrollBottomPendingRef.current = false;\n anchorHeightRef.current = null;\n el.scrollTop = el.scrollHeight;\n } else if (anchorHeightRef.current != null) {\n el.scrollTop += el.scrollHeight - anchorHeightRef.current;\n anchorHeightRef.current = null;\n }\n loadingOlderRef.current = false;\n }, [enabled, visibleCount]);\n\n // Track pinned-to-bottom, and load older rows as the reader nears the top.\n useEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n const onScroll = () => {\n pinnedRef.current = isPinnedToBottom(el, bottomThreshold);\n if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", onScroll);\n }, [enabled, bottomThreshold, topThreshold]);\n\n // Keep the newest row in view as rows grow (shiki highlighting settles after paint).\n useEffect(() => {\n const content = contentRef.current;\n if (!enabled || !content || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n if (pinnedRef.current) scrollToBottom();\n });\n observer.observe(content);\n return () => observer.disconnect();\n }, [enabled, scrollToBottom]);\n\n // Prefetch one batch while idle so the first scroll up is instant.\n useEffect(() => {\n if (!enabled || !hasMore) return;\n const win = idleWindow();\n const request = win?.requestIdleCallback ?? ((cb: () => void) => window.setTimeout(cb, 200));\n const cancel = win?.cancelIdleCallback ?? window.clearTimeout;\n const handle = request(() => growOlderRef.current());\n return () => cancel(handle);\n }, [enabled, resetKey, hasMore]);\n\n return { scrollRef, contentRef, startIndex, hasMore };\n}\n"],"names":["useRef","useState","useCallback","useLayoutEffect","useEffect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-session-scroll.cjs","sources":["../../../src/data/ai/use-session-scroll.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState, type RefObject } from \"react\";\n\n// Progressive windowing for the SessionViewer log. A recorded session runs to\n// thousands of rows (many with syntax-highlighted code blocks), so rendering the\n// whole transcript blocks first paint. Instead we render the *newest* screenful,\n// keep the view pinned to the bottom (most recent activity), and backfill older\n// rows as the reader scrolls up — the classic reverse-infinite-scroll of a chat\n// log. The pure helpers below hold the windowing math; the hook wires the DOM\n// listeners that drive it. Load-more is driven off scroll position rather than an\n// IntersectionObserver so it stays reliable in backgrounded/hidden tabs (where the\n// browser pauses observer callbacks tied to the render loop).\n\n/** The last `visibleCount` of `items`, plus where the window starts and whether\n * older items remain above it. */\nexport function windowSlice<T>(\n items: readonly T[],\n visibleCount: number,\n): { items: T[]; startIndex: number; hasMore: boolean } {\n const clamped = Math.max(0, Math.min(visibleCount, items.length));\n const startIndex = items.length - clamped;\n return { items: items.slice(startIndex), startIndex, hasMore: startIndex > 0 };\n}\n\n/** Grow the window by `batchSize`, never past `total`. */\nexport function nextVisibleCount(current: number, batchSize: number, total: number): number {\n return Math.min(current + Math.max(1, batchSize), total);\n}\n\n/** True when the scroll position sits within `threshold` px of the bottom. */\nexport function isPinnedToBottom(\n metrics: { scrollTop: number; scrollHeight: number; clientHeight: number },\n threshold: number,\n): boolean {\n return metrics.scrollHeight - metrics.scrollTop - metrics.clientHeight <= threshold;\n}\n\n/** True when the scroll position sits within `threshold` px of the top. */\nexport function isNearTop(scrollTop: number, threshold: number): boolean {\n return scrollTop <= threshold;\n}\n\nexport interface SessionScrollOptions {\n /** Number of filtered events available to render. */\n total: number;\n /** Turns the whole mechanism on; when false the hook renders every event. */\n enabled: boolean;\n /** Rows rendered on first paint (and after a session change). */\n windowSize: number;\n /** Rows added each time older content is loaded. */\n batchSize: number;\n /** Changing this resets the window and re-pins to the bottom — pass a value\n * derived from the session identity, not the filter state. */\n resetKey: string;\n /** Distance (px) from the bottom still counted as \"pinned\". */\n bottomThreshold?: number;\n /** Distance (px) from the top at which older rows start loading. */\n topThreshold?: number;\n}\n\nexport interface SessionScrollState {\n scrollRef: RefObject<HTMLDivElement | null>;\n contentRef: RefObject<HTMLDivElement | null>;\n startIndex: number;\n hasMore: boolean;\n following: boolean;\n resumeFollowing: () => void;\n}\n\nexport function useSessionScroll(options: SessionScrollOptions): SessionScrollState {\n const { total, enabled, windowSize, batchSize, resetKey } = options;\n const bottomThreshold = options.bottomThreshold ?? 64;\n const topThreshold = options.topThreshold ?? 600;\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const followingRef = useRef(true);\n const lastScrollTopRef = useRef(0);\n const anchorHeightRef = useRef<number | null>(null);\n const scrollBottomPendingRef = useRef(true);\n const loadingOlderRef = useRef(false);\n const previousTotalRef = useRef({ resetKey, total });\n\n const [visibleCount, setVisibleCount] = useState(windowSize);\n const [following, setFollowing] = useState(true);\n const effectiveCount = enabled ? visibleCount : total;\n const startIndex = Math.max(0, total - effectiveCount);\n const hasMore = enabled && startIndex > 0;\n const hasMoreRef = useRef(hasMore);\n hasMoreRef.current = hasMore;\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n lastScrollTopRef.current = el.scrollTop;\n }\n }, []);\n\n const resumeFollowing = useCallback(() => {\n followingRef.current = true;\n setFollowing(true);\n scrollToBottom();\n }, [scrollToBottom]);\n\n // Prepend an older batch, latching until the layout effect settles the prepend so\n // rapid scroll events don't stack multiple batches at once.\n const growOlder = useCallback(() => {\n if (loadingOlderRef.current || !hasMoreRef.current) return;\n loadingOlderRef.current = true;\n const el = scrollRef.current;\n anchorHeightRef.current = el ? el.scrollHeight : null;\n setVisibleCount((count) => nextVisibleCount(count, batchSize, total));\n }, [batchSize, total]);\n\n const growOlderRef = useRef(growOlder);\n growOlderRef.current = growOlder;\n\n // A new session (resetKey change) snaps back to the newest screenful and re-pins.\n useLayoutEffect(() => {\n if (!enabled) return;\n setVisibleCount(windowSize);\n followingRef.current = true;\n setFollowing(true);\n loadingOlderRef.current = false;\n scrollBottomPendingRef.current = true;\n }, [enabled, resetKey, windowSize]);\n\n useLayoutEffect(() => {\n const previous = previousTotalRef.current;\n previousTotalRef.current = { resetKey, total };\n if (enabled && previous.resetKey === resetKey && !followingRef.current && total > previous.total) {\n setVisibleCount((count) => count + total - previous.total);\n }\n }, [enabled, resetKey, total]);\n\n // After each commit, either snap to bottom (pending pin) or preserve the reader's\n // position when older rows were prepended (anchor), then release the load latch.\n useLayoutEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n if (scrollBottomPendingRef.current) {\n scrollBottomPendingRef.current = false;\n anchorHeightRef.current = null;\n scrollToBottom();\n } else if (anchorHeightRef.current != null) {\n el.scrollTop += el.scrollHeight - anchorHeightRef.current;\n anchorHeightRef.current = null;\n lastScrollTopRef.current = el.scrollTop;\n } else if (followingRef.current) {\n scrollToBottom();\n }\n loadingOlderRef.current = false;\n }, [enabled, visibleCount, total, scrollToBottom]);\n\n // Track pinned-to-bottom, and load older rows as the reader nears the top.\n useEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n const onScroll = () => {\n const movedUp = el.scrollTop < lastScrollTopRef.current;\n if (movedUp || !isPinnedToBottom(el, bottomThreshold)) {\n followingRef.current = false;\n setFollowing(false);\n }\n lastScrollTopRef.current = el.scrollTop;\n if (hasMoreRef.current && movedUp && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n const onWheel = (event: WheelEvent) => {\n if (event.deltaY >= 0) return;\n followingRef.current = false;\n setFollowing(false);\n if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n el.addEventListener(\"wheel\", onWheel, { passive: true });\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n el.removeEventListener(\"wheel\", onWheel);\n };\n }, [enabled, bottomThreshold, topThreshold]);\n\n // Keep the newest row in view as rows grow (shiki highlighting settles after paint).\n useEffect(() => {\n const content = contentRef.current;\n if (!enabled || !content || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n if (followingRef.current) scrollToBottom();\n });\n observer.observe(content);\n return () => observer.disconnect();\n }, [enabled, scrollToBottom]);\n\n return { scrollRef, contentRef, startIndex, hasMore, following, resumeFollowing };\n}\n"],"names":["useRef","useState","useCallback","useLayoutEffect","useEffect"],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ export interface SessionScrollState {
|
|
|
38
38
|
contentRef: RefObject<HTMLDivElement | null>;
|
|
39
39
|
startIndex: number;
|
|
40
40
|
hasMore: boolean;
|
|
41
|
+
following: boolean;
|
|
42
|
+
resumeFollowing: () => void;
|
|
41
43
|
}
|
|
42
44
|
export declare function useSessionScroll(options: SessionScrollOptions): SessionScrollState;
|
|
43
45
|
//# sourceMappingURL=use-session-scroll.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-scroll.d.ts","sourceRoot":"","sources":["../../../src/data/ai/use-session-scroll.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAYlG;mCACmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,YAAY,EAAE,MAAM,GACnB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAItD;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1F;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAC1E,SAAS,EAAE,MAAM,GAChB,OAAO,CAET;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB;mEAC+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5C,UAAU,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-session-scroll.d.ts","sourceRoot":"","sources":["../../../src/data/ai/use-session-scroll.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAYlG;mCACmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,YAAY,EAAE,MAAM,GACnB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAItD;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1F;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAC1E,SAAS,EAAE,MAAM,GAChB,OAAO,CAET;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB;mEAC+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5C,UAAU,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,kBAAkB,CA6HlF"}
|
|
@@ -8,18 +8,20 @@ function isPinnedToBottom(metrics, threshold) {
|
|
|
8
8
|
function isNearTop(scrollTop, threshold) {
|
|
9
9
|
return scrollTop <= threshold;
|
|
10
10
|
}
|
|
11
|
-
const idleWindow = () => typeof window === "undefined" ? void 0 : window;
|
|
12
11
|
function useSessionScroll(options) {
|
|
13
12
|
const { total, enabled, windowSize, batchSize, resetKey } = options;
|
|
14
13
|
const bottomThreshold = options.bottomThreshold ?? 64;
|
|
15
14
|
const topThreshold = options.topThreshold ?? 600;
|
|
16
15
|
const scrollRef = useRef(null);
|
|
17
16
|
const contentRef = useRef(null);
|
|
18
|
-
const
|
|
17
|
+
const followingRef = useRef(true);
|
|
18
|
+
const lastScrollTopRef = useRef(0);
|
|
19
19
|
const anchorHeightRef = useRef(null);
|
|
20
20
|
const scrollBottomPendingRef = useRef(true);
|
|
21
21
|
const loadingOlderRef = useRef(false);
|
|
22
|
-
const
|
|
22
|
+
const previousTotalRef = useRef({ resetKey, total });
|
|
23
|
+
const [visibleCount, setVisibleCount] = useState(windowSize);
|
|
24
|
+
const [following, setFollowing] = useState(true);
|
|
23
25
|
const effectiveCount = enabled ? visibleCount : total;
|
|
24
26
|
const startIndex = Math.max(0, total - effectiveCount);
|
|
25
27
|
const hasMore = enabled && startIndex > 0;
|
|
@@ -27,8 +29,16 @@ function useSessionScroll(options) {
|
|
|
27
29
|
hasMoreRef.current = hasMore;
|
|
28
30
|
const scrollToBottom = useCallback(() => {
|
|
29
31
|
const el = scrollRef.current;
|
|
30
|
-
if (el)
|
|
32
|
+
if (el) {
|
|
33
|
+
el.scrollTop = el.scrollHeight;
|
|
34
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
35
|
+
}
|
|
31
36
|
}, []);
|
|
37
|
+
const resumeFollowing = useCallback(() => {
|
|
38
|
+
followingRef.current = true;
|
|
39
|
+
setFollowing(true);
|
|
40
|
+
scrollToBottom();
|
|
41
|
+
}, [scrollToBottom]);
|
|
32
42
|
const growOlder = useCallback(() => {
|
|
33
43
|
if (loadingOlderRef.current || !hasMoreRef.current) return;
|
|
34
44
|
loadingOlderRef.current = true;
|
|
@@ -40,52 +50,70 @@ function useSessionScroll(options) {
|
|
|
40
50
|
growOlderRef.current = growOlder;
|
|
41
51
|
useLayoutEffect(() => {
|
|
42
52
|
if (!enabled) return;
|
|
43
|
-
setVisibleCount(
|
|
44
|
-
|
|
53
|
+
setVisibleCount(windowSize);
|
|
54
|
+
followingRef.current = true;
|
|
55
|
+
setFollowing(true);
|
|
45
56
|
loadingOlderRef.current = false;
|
|
46
57
|
scrollBottomPendingRef.current = true;
|
|
47
|
-
}, [enabled, resetKey, windowSize
|
|
58
|
+
}, [enabled, resetKey, windowSize]);
|
|
59
|
+
useLayoutEffect(() => {
|
|
60
|
+
const previous = previousTotalRef.current;
|
|
61
|
+
previousTotalRef.current = { resetKey, total };
|
|
62
|
+
if (enabled && previous.resetKey === resetKey && !followingRef.current && total > previous.total) {
|
|
63
|
+
setVisibleCount((count) => count + total - previous.total);
|
|
64
|
+
}
|
|
65
|
+
}, [enabled, resetKey, total]);
|
|
48
66
|
useLayoutEffect(() => {
|
|
49
67
|
const el = scrollRef.current;
|
|
50
68
|
if (!enabled || !el) return;
|
|
51
69
|
if (scrollBottomPendingRef.current) {
|
|
52
70
|
scrollBottomPendingRef.current = false;
|
|
53
71
|
anchorHeightRef.current = null;
|
|
54
|
-
|
|
72
|
+
scrollToBottom();
|
|
55
73
|
} else if (anchorHeightRef.current != null) {
|
|
56
74
|
el.scrollTop += el.scrollHeight - anchorHeightRef.current;
|
|
57
75
|
anchorHeightRef.current = null;
|
|
76
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
77
|
+
} else if (followingRef.current) {
|
|
78
|
+
scrollToBottom();
|
|
58
79
|
}
|
|
59
80
|
loadingOlderRef.current = false;
|
|
60
|
-
}, [enabled, visibleCount]);
|
|
81
|
+
}, [enabled, visibleCount, total, scrollToBottom]);
|
|
61
82
|
useEffect(() => {
|
|
62
83
|
const el = scrollRef.current;
|
|
63
84
|
if (!enabled || !el) return;
|
|
64
85
|
const onScroll = () => {
|
|
65
|
-
|
|
86
|
+
const movedUp = el.scrollTop < lastScrollTopRef.current;
|
|
87
|
+
if (movedUp || !isPinnedToBottom(el, bottomThreshold)) {
|
|
88
|
+
followingRef.current = false;
|
|
89
|
+
setFollowing(false);
|
|
90
|
+
}
|
|
91
|
+
lastScrollTopRef.current = el.scrollTop;
|
|
92
|
+
if (hasMoreRef.current && movedUp && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();
|
|
93
|
+
};
|
|
94
|
+
const onWheel = (event) => {
|
|
95
|
+
if (event.deltaY >= 0) return;
|
|
96
|
+
followingRef.current = false;
|
|
97
|
+
setFollowing(false);
|
|
66
98
|
if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();
|
|
67
99
|
};
|
|
68
100
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
69
|
-
|
|
101
|
+
el.addEventListener("wheel", onWheel, { passive: true });
|
|
102
|
+
return () => {
|
|
103
|
+
el.removeEventListener("scroll", onScroll);
|
|
104
|
+
el.removeEventListener("wheel", onWheel);
|
|
105
|
+
};
|
|
70
106
|
}, [enabled, bottomThreshold, topThreshold]);
|
|
71
107
|
useEffect(() => {
|
|
72
108
|
const content = contentRef.current;
|
|
73
109
|
if (!enabled || !content || typeof ResizeObserver === "undefined") return;
|
|
74
110
|
const observer = new ResizeObserver(() => {
|
|
75
|
-
if (
|
|
111
|
+
if (followingRef.current) scrollToBottom();
|
|
76
112
|
});
|
|
77
113
|
observer.observe(content);
|
|
78
114
|
return () => observer.disconnect();
|
|
79
115
|
}, [enabled, scrollToBottom]);
|
|
80
|
-
|
|
81
|
-
if (!enabled || !hasMore) return;
|
|
82
|
-
const win = idleWindow();
|
|
83
|
-
const request = (win == null ? void 0 : win.requestIdleCallback) ?? ((cb) => window.setTimeout(cb, 200));
|
|
84
|
-
const cancel = (win == null ? void 0 : win.cancelIdleCallback) ?? window.clearTimeout;
|
|
85
|
-
const handle = request(() => growOlderRef.current());
|
|
86
|
-
return () => cancel(handle);
|
|
87
|
-
}, [enabled, resetKey, hasMore]);
|
|
88
|
-
return { scrollRef, contentRef, startIndex, hasMore };
|
|
116
|
+
return { scrollRef, contentRef, startIndex, hasMore, following, resumeFollowing };
|
|
89
117
|
}
|
|
90
118
|
export {
|
|
91
119
|
isNearTop,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-scroll.js","sources":["../../../src/data/ai/use-session-scroll.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState, type RefObject } from \"react\";\n\n// Progressive windowing for the SessionViewer log. A recorded session runs to\n// thousands of rows (many with syntax-highlighted code blocks), so rendering the\n// whole transcript blocks first paint. Instead we render the *newest* screenful,\n// keep the view pinned to the bottom (most recent activity), and backfill older\n// rows as the reader scrolls up — the classic reverse-infinite-scroll of a chat\n// log. The pure helpers below hold the windowing math; the hook wires the DOM\n// listeners that drive it. Load-more is driven off scroll position rather than an\n// IntersectionObserver so it stays reliable in backgrounded/hidden tabs (where the\n// browser pauses observer callbacks tied to the render loop).\n\n/** The last `visibleCount` of `items`, plus where the window starts and whether\n * older items remain above it. */\nexport function windowSlice<T>(\n items: readonly T[],\n visibleCount: number,\n): { items: T[]; startIndex: number; hasMore: boolean } {\n const clamped = Math.max(0, Math.min(visibleCount, items.length));\n const startIndex = items.length - clamped;\n return { items: items.slice(startIndex), startIndex, hasMore: startIndex > 0 };\n}\n\n/** Grow the window by `batchSize`, never past `total`. */\nexport function nextVisibleCount(current: number, batchSize: number, total: number): number {\n return Math.min(current + Math.max(1, batchSize), total);\n}\n\n/** True when the scroll position sits within `threshold` px of the bottom. */\nexport function isPinnedToBottom(\n metrics: { scrollTop: number; scrollHeight: number; clientHeight: number },\n threshold: number,\n): boolean {\n return metrics.scrollHeight - metrics.scrollTop - metrics.clientHeight <= threshold;\n}\n\n/** True when the scroll position sits within `threshold` px of the top. */\nexport function isNearTop(scrollTop: number, threshold: number): boolean {\n return scrollTop <= threshold;\n}\n\nexport interface SessionScrollOptions {\n /** Number of filtered events available to render. */\n total: number;\n /** Turns the whole mechanism on; when false the hook renders every event. */\n enabled: boolean;\n /** Rows rendered on first paint (and after a session change). */\n windowSize: number;\n /** Rows added each time older content is loaded. */\n batchSize: number;\n /** Changing this resets the window and re-pins to the bottom — pass a value\n * derived from the session identity, not the filter state. */\n resetKey: string;\n /** Distance (px) from the bottom still counted as \"pinned\". */\n bottomThreshold?: number;\n /** Distance (px) from the top at which older rows start loading. */\n topThreshold?: number;\n}\n\nexport interface SessionScrollState {\n scrollRef: RefObject<HTMLDivElement | null>;\n contentRef: RefObject<HTMLDivElement | null>;\n startIndex: number;\n hasMore: boolean;\n}\n\nconst idleWindow = () =>\n (typeof window === \"undefined\" ? undefined : window) as\n | (Window & {\n requestIdleCallback?: (cb: () => void) => number;\n cancelIdleCallback?: (handle: number) => void;\n })\n | undefined;\n\nexport function useSessionScroll(options: SessionScrollOptions): SessionScrollState {\n const { total, enabled, windowSize, batchSize, resetKey } = options;\n const bottomThreshold = options.bottomThreshold ?? 64;\n const topThreshold = options.topThreshold ?? 600;\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const pinnedRef = useRef(true);\n const anchorHeightRef = useRef<number | null>(null);\n const scrollBottomPendingRef = useRef(true);\n const loadingOlderRef = useRef(false);\n\n const [visibleCount, setVisibleCount] = useState(() => Math.min(windowSize, total));\n const effectiveCount = enabled ? visibleCount : total;\n const startIndex = Math.max(0, total - effectiveCount);\n const hasMore = enabled && startIndex > 0;\n const hasMoreRef = useRef(hasMore);\n hasMoreRef.current = hasMore;\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, []);\n\n // Prepend an older batch, latching until the layout effect settles the prepend so\n // rapid scroll events don't stack multiple batches at once.\n const growOlder = useCallback(() => {\n if (loadingOlderRef.current || !hasMoreRef.current) return;\n loadingOlderRef.current = true;\n const el = scrollRef.current;\n anchorHeightRef.current = el ? el.scrollHeight : null;\n setVisibleCount((count) => nextVisibleCount(count, batchSize, total));\n }, [batchSize, total]);\n\n const growOlderRef = useRef(growOlder);\n growOlderRef.current = growOlder;\n\n // A new session (resetKey change) snaps back to the newest screenful and re-pins.\n useLayoutEffect(() => {\n if (!enabled) return;\n setVisibleCount(Math.min(windowSize, total));\n pinnedRef.current = true;\n loadingOlderRef.current = false;\n scrollBottomPendingRef.current = true;\n }, [enabled, resetKey, windowSize, total]);\n\n // After each commit, either snap to bottom (pending pin) or preserve the reader's\n // position when older rows were prepended (anchor), then release the load latch.\n useLayoutEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n if (scrollBottomPendingRef.current) {\n scrollBottomPendingRef.current = false;\n anchorHeightRef.current = null;\n el.scrollTop = el.scrollHeight;\n } else if (anchorHeightRef.current != null) {\n el.scrollTop += el.scrollHeight - anchorHeightRef.current;\n anchorHeightRef.current = null;\n }\n loadingOlderRef.current = false;\n }, [enabled, visibleCount]);\n\n // Track pinned-to-bottom, and load older rows as the reader nears the top.\n useEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n const onScroll = () => {\n pinnedRef.current = isPinnedToBottom(el, bottomThreshold);\n if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", onScroll);\n }, [enabled, bottomThreshold, topThreshold]);\n\n // Keep the newest row in view as rows grow (shiki highlighting settles after paint).\n useEffect(() => {\n const content = contentRef.current;\n if (!enabled || !content || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n if (pinnedRef.current) scrollToBottom();\n });\n observer.observe(content);\n return () => observer.disconnect();\n }, [enabled, scrollToBottom]);\n\n // Prefetch one batch while idle so the first scroll up is instant.\n useEffect(() => {\n if (!enabled || !hasMore) return;\n const win = idleWindow();\n const request = win?.requestIdleCallback ?? ((cb: () => void) => window.setTimeout(cb, 200));\n const cancel = win?.cancelIdleCallback ?? window.clearTimeout;\n const handle = request(() => growOlderRef.current());\n return () => cancel(handle);\n }, [enabled, resetKey, hasMore]);\n\n return { scrollRef, contentRef, startIndex, hasMore };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-session-scroll.js","sources":["../../../src/data/ai/use-session-scroll.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState, type RefObject } from \"react\";\n\n// Progressive windowing for the SessionViewer log. A recorded session runs to\n// thousands of rows (many with syntax-highlighted code blocks), so rendering the\n// whole transcript blocks first paint. Instead we render the *newest* screenful,\n// keep the view pinned to the bottom (most recent activity), and backfill older\n// rows as the reader scrolls up — the classic reverse-infinite-scroll of a chat\n// log. The pure helpers below hold the windowing math; the hook wires the DOM\n// listeners that drive it. Load-more is driven off scroll position rather than an\n// IntersectionObserver so it stays reliable in backgrounded/hidden tabs (where the\n// browser pauses observer callbacks tied to the render loop).\n\n/** The last `visibleCount` of `items`, plus where the window starts and whether\n * older items remain above it. */\nexport function windowSlice<T>(\n items: readonly T[],\n visibleCount: number,\n): { items: T[]; startIndex: number; hasMore: boolean } {\n const clamped = Math.max(0, Math.min(visibleCount, items.length));\n const startIndex = items.length - clamped;\n return { items: items.slice(startIndex), startIndex, hasMore: startIndex > 0 };\n}\n\n/** Grow the window by `batchSize`, never past `total`. */\nexport function nextVisibleCount(current: number, batchSize: number, total: number): number {\n return Math.min(current + Math.max(1, batchSize), total);\n}\n\n/** True when the scroll position sits within `threshold` px of the bottom. */\nexport function isPinnedToBottom(\n metrics: { scrollTop: number; scrollHeight: number; clientHeight: number },\n threshold: number,\n): boolean {\n return metrics.scrollHeight - metrics.scrollTop - metrics.clientHeight <= threshold;\n}\n\n/** True when the scroll position sits within `threshold` px of the top. */\nexport function isNearTop(scrollTop: number, threshold: number): boolean {\n return scrollTop <= threshold;\n}\n\nexport interface SessionScrollOptions {\n /** Number of filtered events available to render. */\n total: number;\n /** Turns the whole mechanism on; when false the hook renders every event. */\n enabled: boolean;\n /** Rows rendered on first paint (and after a session change). */\n windowSize: number;\n /** Rows added each time older content is loaded. */\n batchSize: number;\n /** Changing this resets the window and re-pins to the bottom — pass a value\n * derived from the session identity, not the filter state. */\n resetKey: string;\n /** Distance (px) from the bottom still counted as \"pinned\". */\n bottomThreshold?: number;\n /** Distance (px) from the top at which older rows start loading. */\n topThreshold?: number;\n}\n\nexport interface SessionScrollState {\n scrollRef: RefObject<HTMLDivElement | null>;\n contentRef: RefObject<HTMLDivElement | null>;\n startIndex: number;\n hasMore: boolean;\n following: boolean;\n resumeFollowing: () => void;\n}\n\nexport function useSessionScroll(options: SessionScrollOptions): SessionScrollState {\n const { total, enabled, windowSize, batchSize, resetKey } = options;\n const bottomThreshold = options.bottomThreshold ?? 64;\n const topThreshold = options.topThreshold ?? 600;\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const followingRef = useRef(true);\n const lastScrollTopRef = useRef(0);\n const anchorHeightRef = useRef<number | null>(null);\n const scrollBottomPendingRef = useRef(true);\n const loadingOlderRef = useRef(false);\n const previousTotalRef = useRef({ resetKey, total });\n\n const [visibleCount, setVisibleCount] = useState(windowSize);\n const [following, setFollowing] = useState(true);\n const effectiveCount = enabled ? visibleCount : total;\n const startIndex = Math.max(0, total - effectiveCount);\n const hasMore = enabled && startIndex > 0;\n const hasMoreRef = useRef(hasMore);\n hasMoreRef.current = hasMore;\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n lastScrollTopRef.current = el.scrollTop;\n }\n }, []);\n\n const resumeFollowing = useCallback(() => {\n followingRef.current = true;\n setFollowing(true);\n scrollToBottom();\n }, [scrollToBottom]);\n\n // Prepend an older batch, latching until the layout effect settles the prepend so\n // rapid scroll events don't stack multiple batches at once.\n const growOlder = useCallback(() => {\n if (loadingOlderRef.current || !hasMoreRef.current) return;\n loadingOlderRef.current = true;\n const el = scrollRef.current;\n anchorHeightRef.current = el ? el.scrollHeight : null;\n setVisibleCount((count) => nextVisibleCount(count, batchSize, total));\n }, [batchSize, total]);\n\n const growOlderRef = useRef(growOlder);\n growOlderRef.current = growOlder;\n\n // A new session (resetKey change) snaps back to the newest screenful and re-pins.\n useLayoutEffect(() => {\n if (!enabled) return;\n setVisibleCount(windowSize);\n followingRef.current = true;\n setFollowing(true);\n loadingOlderRef.current = false;\n scrollBottomPendingRef.current = true;\n }, [enabled, resetKey, windowSize]);\n\n useLayoutEffect(() => {\n const previous = previousTotalRef.current;\n previousTotalRef.current = { resetKey, total };\n if (enabled && previous.resetKey === resetKey && !followingRef.current && total > previous.total) {\n setVisibleCount((count) => count + total - previous.total);\n }\n }, [enabled, resetKey, total]);\n\n // After each commit, either snap to bottom (pending pin) or preserve the reader's\n // position when older rows were prepended (anchor), then release the load latch.\n useLayoutEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n if (scrollBottomPendingRef.current) {\n scrollBottomPendingRef.current = false;\n anchorHeightRef.current = null;\n scrollToBottom();\n } else if (anchorHeightRef.current != null) {\n el.scrollTop += el.scrollHeight - anchorHeightRef.current;\n anchorHeightRef.current = null;\n lastScrollTopRef.current = el.scrollTop;\n } else if (followingRef.current) {\n scrollToBottom();\n }\n loadingOlderRef.current = false;\n }, [enabled, visibleCount, total, scrollToBottom]);\n\n // Track pinned-to-bottom, and load older rows as the reader nears the top.\n useEffect(() => {\n const el = scrollRef.current;\n if (!enabled || !el) return;\n const onScroll = () => {\n const movedUp = el.scrollTop < lastScrollTopRef.current;\n if (movedUp || !isPinnedToBottom(el, bottomThreshold)) {\n followingRef.current = false;\n setFollowing(false);\n }\n lastScrollTopRef.current = el.scrollTop;\n if (hasMoreRef.current && movedUp && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n const onWheel = (event: WheelEvent) => {\n if (event.deltaY >= 0) return;\n followingRef.current = false;\n setFollowing(false);\n if (hasMoreRef.current && isNearTop(el.scrollTop, topThreshold)) growOlderRef.current();\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n el.addEventListener(\"wheel\", onWheel, { passive: true });\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n el.removeEventListener(\"wheel\", onWheel);\n };\n }, [enabled, bottomThreshold, topThreshold]);\n\n // Keep the newest row in view as rows grow (shiki highlighting settles after paint).\n useEffect(() => {\n const content = contentRef.current;\n if (!enabled || !content || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n if (followingRef.current) scrollToBottom();\n });\n observer.observe(content);\n return () => observer.disconnect();\n }, [enabled, scrollToBottom]);\n\n return { scrollRef, contentRef, startIndex, hasMore, following, resumeFollowing };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ function resolveChatRuntime({
|
|
|
16
16
|
let next;
|
|
17
17
|
if (selected) {
|
|
18
18
|
const preservesExecutionSelection = Boolean(
|
|
19
|
-
selected === currentModel && current.mode !== void 0 && ((_a = selected.runtime) == null ? void 0 : _a.mode) !==
|
|
19
|
+
selected === currentModel && current.mode !== void 0 && ((_a = selected.runtime) == null ? void 0 : _a.mode) !== current.mode
|
|
20
20
|
);
|
|
21
21
|
next = modelCapabilities.reconcileModelCapabilities(current, selected, reasoningEfforts, {
|
|
22
22
|
defaultEffort: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.runtime.cjs","sources":["../../../src/data/chat/Chat.runtime.ts"],"sourcesContent":["import {\n reconcileModelCapabilities,\n type ModelRuntimeSelection,\n} from \"../runtime/model-capabilities\";\nimport { runtimeModelForValue } from \"../runtime/RuntimeBar.model\";\nimport type { ChatModel, ChatModelRuntime } from \"./types\";\n\nexport type ResolveChatRuntimeOptions = {\n models: ChatModel[];\n current?: ChatModelRuntime | undefined;\n preferredModel?: string | undefined;\n effort?: string | undefined;\n temperature?: number | undefined;\n reasoningEfforts: readonly string[];\n};\n\nexport function resolveChatRuntime({\n models,\n current = {},\n preferredModel,\n effort,\n temperature,\n reasoningEfforts,\n}: ResolveChatRuntimeOptions): ChatModelRuntime {\n const currentModel = selectedChatModel(models, current);\n const selected = preferredModel\n ? currentModel?.id === preferredModel\n ? currentModel\n : models.find((model) => model.id === preferredModel)\n : currentModel;\n let next: ChatModelRuntime;\n if (selected) {\n const preservesExecutionSelection = Boolean(\n selected === currentModel &&\n current.mode !== undefined &&\n selected.runtime?.mode !==
|
|
1
|
+
{"version":3,"file":"Chat.runtime.cjs","sources":["../../../src/data/chat/Chat.runtime.ts"],"sourcesContent":["import {\n reconcileModelCapabilities,\n type ModelRuntimeSelection,\n} from \"../runtime/model-capabilities\";\nimport { runtimeModelForValue } from \"../runtime/RuntimeBar.model\";\nimport type { ChatModel, ChatModelRuntime } from \"./types\";\n\nexport type ResolveChatRuntimeOptions = {\n models: ChatModel[];\n current?: ChatModelRuntime | undefined;\n preferredModel?: string | undefined;\n effort?: string | undefined;\n temperature?: number | undefined;\n reasoningEfforts: readonly string[];\n};\n\nexport function resolveChatRuntime({\n models,\n current = {},\n preferredModel,\n effort,\n temperature,\n reasoningEfforts,\n}: ResolveChatRuntimeOptions): ChatModelRuntime {\n const currentModel = selectedChatModel(models, current);\n const selected = preferredModel\n ? currentModel?.id === preferredModel\n ? currentModel\n : models.find((model) => model.id === preferredModel)\n : currentModel;\n let next: ChatModelRuntime;\n if (selected) {\n const preservesExecutionSelection = Boolean(\n selected === currentModel &&\n current.mode !== undefined &&\n selected.runtime?.mode !== current.mode,\n );\n next = reconcileModelCapabilities(current, selected, reasoningEfforts, {\n defaultEffort: true,\n ...(preservesExecutionSelection ? { mode: current.mode } : {}),\n });\n if (!next.id && !next.model) next.id = selected.id;\n } else if (preferredModel) {\n next = { ...current, model: preferredModel };\n } else {\n next = { ...current };\n }\n return withRuntimeOverrides(next, effort, temperature);\n}\n\nexport function selectedChatModel(\n models: ChatModel[],\n runtime: ModelRuntimeSelection,\n): ChatModel | undefined {\n return runtimeModelForValue(models, runtime);\n}\n\nexport function withRuntimeOverrides<T extends ChatModelRuntime>(\n runtime: T,\n effort: string | undefined,\n temperature: number | undefined,\n): T {\n const next = { ...runtime };\n if (effort !== undefined) {\n setOptionalRuntimeField(next as Record<string, unknown>, \"effort\", effort);\n }\n if (temperature !== undefined) next.temperature = temperature;\n return next;\n}\n\nexport function withRuntimeField<T extends ChatModelRuntime>(\n runtime: T,\n key: keyof ChatModelRuntime,\n value: unknown,\n): T {\n const next = { ...runtime } as Record<string, unknown>;\n setOptionalRuntimeField(next, key, value);\n return next as T;\n}\n\nexport function hasStructuredRuntime(\n runtime: ChatModelRuntime,\n selected: ChatModel | undefined,\n): boolean {\n return Boolean(\n selected?.runtime ||\n runtime.id ||\n runtime.mode ||\n runtime.noCache ||\n runtime.fallbacks?.length,\n );\n}\n\nfunction setOptionalRuntimeField(\n runtime: Record<string, unknown>,\n key: keyof ChatModelRuntime,\n value: unknown,\n): void {\n if (value === undefined || value === \"\") {\n delete runtime[key];\n } else {\n runtime[key] = value;\n }\n}\n"],"names":["reconcileModelCapabilities","runtimeModelForValue"],"mappings":";;;;AAgBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,UAAU,CAAA;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgD;;AAC9C,QAAM,eAAe,kBAAkB,QAAQ,OAAO;AACtD,QAAM,WAAW,kBACb,6CAAc,QAAO,iBACnB,eACA,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,cAAc,IACpD;AACJ,MAAI;AACJ,MAAI,UAAU;AACZ,UAAM,8BAA8B;AAAA,MAClC,aAAa,gBACb,QAAQ,SAAS,YACjB,cAAS,YAAT,mBAAkB,UAAS,QAAQ;AAAA,IAAA;AAErC,WAAOA,kBAAAA,2BAA2B,SAAS,UAAU,kBAAkB;AAAA,MACrE,eAAe;AAAA,MACf,GAAI,8BAA8B,EAAE,MAAM,QAAQ,KAAA,IAAS,CAAA;AAAA,IAAC,CAC7D;AACD,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,MAAO,MAAK,KAAK,SAAS;AAAA,EAClD,WAAW,gBAAgB;AACzB,WAAO,EAAE,GAAG,SAAS,OAAO,eAAA;AAAA,EAC9B,OAAO;AACL,WAAO,EAAE,GAAG,QAAA;AAAA,EACd;AACA,SAAO,qBAAqB,MAAM,QAAQ,WAAW;AACvD;AAEO,SAAS,kBACd,QACA,SACuB;AACvB,SAAOC,iBAAAA,qBAAqB,QAAQ,OAAO;AAC7C;AAEO,SAAS,qBACd,SACA,QACA,aACG;AACH,QAAM,OAAO,EAAE,GAAG,QAAA;AAClB,MAAI,WAAW,QAAW;AACxB,4BAAwB,MAAiC,UAAU,MAAM;AAAA,EAC3E;AACA,MAAI,gBAAgB,OAAW,MAAK,cAAc;AAClD,SAAO;AACT;AAEO,SAAS,iBACd,SACA,KACA,OACG;AACH,QAAM,OAAO,EAAE,GAAG,QAAA;AAClB,0BAAwB,MAAM,KAAK,KAAK;AACxC,SAAO;AACT;AAEO,SAAS,qBACd,SACA,UACS;;AACT,SAAO;AAAA,KACL,qCAAU,YACV,QAAQ,MACR,QAAQ,QACR,QAAQ,aACR,aAAQ,cAAR,mBAAmB;AAAA,EAAA;AAEvB;AAEA,SAAS,wBACP,SACA,KACA,OACM;AACN,MAAI,UAAU,UAAa,UAAU,IAAI;AACvC,WAAO,QAAQ,GAAG;AAAA,EACpB,OAAO;AACL,YAAQ,GAAG,IAAI;AAAA,EACjB;AACF;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.runtime.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Chat.runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,OAAY,EACZ,cAAc,EACd,MAAM,EACN,WAAW,EACX,gBAAgB,GACjB,EAAE,yBAAyB,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"Chat.runtime.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Chat.runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,OAAY,EACZ,cAAc,EACd,MAAM,EACN,WAAW,EACX,gBAAgB,GACjB,EAAE,yBAAyB,GAAG,gBAAgB,CAyB9C;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,qBAAqB,GAC7B,SAAS,GAAG,SAAS,CAEvB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,EAC7D,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,CAAC,CAOH;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,EACzD,OAAO,EAAE,CAAC,EACV,GAAG,EAAE,MAAM,gBAAgB,EAC3B,KAAK,EAAE,OAAO,GACb,CAAC,CAIH;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,SAAS,GAAG,SAAS,GAC9B,OAAO,CAQT"}
|
|
@@ -14,7 +14,7 @@ function resolveChatRuntime({
|
|
|
14
14
|
let next;
|
|
15
15
|
if (selected) {
|
|
16
16
|
const preservesExecutionSelection = Boolean(
|
|
17
|
-
selected === currentModel && current.mode !== void 0 && ((_a = selected.runtime) == null ? void 0 : _a.mode) !==
|
|
17
|
+
selected === currentModel && current.mode !== void 0 && ((_a = selected.runtime) == null ? void 0 : _a.mode) !== current.mode
|
|
18
18
|
);
|
|
19
19
|
next = reconcileModelCapabilities(current, selected, reasoningEfforts, {
|
|
20
20
|
defaultEffort: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.runtime.js","sources":["../../../src/data/chat/Chat.runtime.ts"],"sourcesContent":["import {\n reconcileModelCapabilities,\n type ModelRuntimeSelection,\n} from \"../runtime/model-capabilities\";\nimport { runtimeModelForValue } from \"../runtime/RuntimeBar.model\";\nimport type { ChatModel, ChatModelRuntime } from \"./types\";\n\nexport type ResolveChatRuntimeOptions = {\n models: ChatModel[];\n current?: ChatModelRuntime | undefined;\n preferredModel?: string | undefined;\n effort?: string | undefined;\n temperature?: number | undefined;\n reasoningEfforts: readonly string[];\n};\n\nexport function resolveChatRuntime({\n models,\n current = {},\n preferredModel,\n effort,\n temperature,\n reasoningEfforts,\n}: ResolveChatRuntimeOptions): ChatModelRuntime {\n const currentModel = selectedChatModel(models, current);\n const selected = preferredModel\n ? currentModel?.id === preferredModel\n ? currentModel\n : models.find((model) => model.id === preferredModel)\n : currentModel;\n let next: ChatModelRuntime;\n if (selected) {\n const preservesExecutionSelection = Boolean(\n selected === currentModel &&\n current.mode !== undefined &&\n selected.runtime?.mode !==
|
|
1
|
+
{"version":3,"file":"Chat.runtime.js","sources":["../../../src/data/chat/Chat.runtime.ts"],"sourcesContent":["import {\n reconcileModelCapabilities,\n type ModelRuntimeSelection,\n} from \"../runtime/model-capabilities\";\nimport { runtimeModelForValue } from \"../runtime/RuntimeBar.model\";\nimport type { ChatModel, ChatModelRuntime } from \"./types\";\n\nexport type ResolveChatRuntimeOptions = {\n models: ChatModel[];\n current?: ChatModelRuntime | undefined;\n preferredModel?: string | undefined;\n effort?: string | undefined;\n temperature?: number | undefined;\n reasoningEfforts: readonly string[];\n};\n\nexport function resolveChatRuntime({\n models,\n current = {},\n preferredModel,\n effort,\n temperature,\n reasoningEfforts,\n}: ResolveChatRuntimeOptions): ChatModelRuntime {\n const currentModel = selectedChatModel(models, current);\n const selected = preferredModel\n ? currentModel?.id === preferredModel\n ? currentModel\n : models.find((model) => model.id === preferredModel)\n : currentModel;\n let next: ChatModelRuntime;\n if (selected) {\n const preservesExecutionSelection = Boolean(\n selected === currentModel &&\n current.mode !== undefined &&\n selected.runtime?.mode !== current.mode,\n );\n next = reconcileModelCapabilities(current, selected, reasoningEfforts, {\n defaultEffort: true,\n ...(preservesExecutionSelection ? { mode: current.mode } : {}),\n });\n if (!next.id && !next.model) next.id = selected.id;\n } else if (preferredModel) {\n next = { ...current, model: preferredModel };\n } else {\n next = { ...current };\n }\n return withRuntimeOverrides(next, effort, temperature);\n}\n\nexport function selectedChatModel(\n models: ChatModel[],\n runtime: ModelRuntimeSelection,\n): ChatModel | undefined {\n return runtimeModelForValue(models, runtime);\n}\n\nexport function withRuntimeOverrides<T extends ChatModelRuntime>(\n runtime: T,\n effort: string | undefined,\n temperature: number | undefined,\n): T {\n const next = { ...runtime };\n if (effort !== undefined) {\n setOptionalRuntimeField(next as Record<string, unknown>, \"effort\", effort);\n }\n if (temperature !== undefined) next.temperature = temperature;\n return next;\n}\n\nexport function withRuntimeField<T extends ChatModelRuntime>(\n runtime: T,\n key: keyof ChatModelRuntime,\n value: unknown,\n): T {\n const next = { ...runtime } as Record<string, unknown>;\n setOptionalRuntimeField(next, key, value);\n return next as T;\n}\n\nexport function hasStructuredRuntime(\n runtime: ChatModelRuntime,\n selected: ChatModel | undefined,\n): boolean {\n return Boolean(\n selected?.runtime ||\n runtime.id ||\n runtime.mode ||\n runtime.noCache ||\n runtime.fallbacks?.length,\n );\n}\n\nfunction setOptionalRuntimeField(\n runtime: Record<string, unknown>,\n key: keyof ChatModelRuntime,\n value: unknown,\n): void {\n if (value === undefined || value === \"\") {\n delete runtime[key];\n } else {\n runtime[key] = value;\n }\n}\n"],"names":[],"mappings":";;AAgBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,UAAU,CAAA;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgD;;AAC9C,QAAM,eAAe,kBAAkB,QAAQ,OAAO;AACtD,QAAM,WAAW,kBACb,6CAAc,QAAO,iBACnB,eACA,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,cAAc,IACpD;AACJ,MAAI;AACJ,MAAI,UAAU;AACZ,UAAM,8BAA8B;AAAA,MAClC,aAAa,gBACb,QAAQ,SAAS,YACjB,cAAS,YAAT,mBAAkB,UAAS,QAAQ;AAAA,IAAA;AAErC,WAAO,2BAA2B,SAAS,UAAU,kBAAkB;AAAA,MACrE,eAAe;AAAA,MACf,GAAI,8BAA8B,EAAE,MAAM,QAAQ,KAAA,IAAS,CAAA;AAAA,IAAC,CAC7D;AACD,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,MAAO,MAAK,KAAK,SAAS;AAAA,EAClD,WAAW,gBAAgB;AACzB,WAAO,EAAE,GAAG,SAAS,OAAO,eAAA;AAAA,EAC9B,OAAO;AACL,WAAO,EAAE,GAAG,QAAA;AAAA,EACd;AACA,SAAO,qBAAqB,MAAM,QAAQ,WAAW;AACvD;AAEO,SAAS,kBACd,QACA,SACuB;AACvB,SAAO,qBAAqB,QAAQ,OAAO;AAC7C;AAEO,SAAS,qBACd,SACA,QACA,aACG;AACH,QAAM,OAAO,EAAE,GAAG,QAAA;AAClB,MAAI,WAAW,QAAW;AACxB,4BAAwB,MAAiC,UAAU,MAAM;AAAA,EAC3E;AACA,MAAI,gBAAgB,OAAW,MAAK,cAAc;AAClD,SAAO;AACT;AAEO,SAAS,iBACd,SACA,KACA,OACG;AACH,QAAM,OAAO,EAAE,GAAG,QAAA;AAClB,0BAAwB,MAAM,KAAK,KAAK;AACxC,SAAO;AACT;AAEO,SAAS,qBACd,SACA,UACS;;AACT,SAAO;AAAA,KACL,qCAAU,YACV,QAAQ,MACR,QAAQ,QACR,QAAQ,aACR,aAAQ,cAAR,mBAAmB;AAAA,EAAA;AAEvB;AAEA,SAAS,wBACP,SACA,KACA,OACM;AACN,MAAI,UAAU,UAAa,UAAU,IAAI;AACvC,WAAO,QAAQ,GAAG;AAAA,EACpB,OAAO;AACL,YAAQ,GAAG,IAAI;AAAA,EACjB;AACF;"}
|