@principal-ai/subsystems-react 0.17.0
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 +93 -0
- package/dist/components/ConfigurationSelector.d.ts +35 -0
- package/dist/components/ConfigurationSelector.d.ts.map +1 -0
- package/dist/components/ConfigurationSelector.js +63 -0
- package/dist/components/ConfigurationSelector.js.map +1 -0
- package/dist/components/GraphRenderer.d.ts +295 -0
- package/dist/components/GraphRenderer.d.ts.map +1 -0
- package/dist/components/GraphRenderer.js +2008 -0
- package/dist/components/GraphRenderer.js.map +1 -0
- package/dist/components/MultiCanvasRenderer.d.ts +75 -0
- package/dist/components/MultiCanvasRenderer.d.ts.map +1 -0
- package/dist/components/MultiCanvasRenderer.js +203 -0
- package/dist/components/MultiCanvasRenderer.js.map +1 -0
- package/dist/components/NodeTooltip.d.ts +24 -0
- package/dist/components/NodeTooltip.d.ts.map +1 -0
- package/dist/components/NodeTooltip.js +160 -0
- package/dist/components/NodeTooltip.js.map +1 -0
- package/dist/components/SelectionSidebar.d.ts +18 -0
- package/dist/components/SelectionSidebar.d.ts.map +1 -0
- package/dist/components/SelectionSidebar.js +190 -0
- package/dist/components/SelectionSidebar.js.map +1 -0
- package/dist/components/SequenceDiagramRenderer.d.ts +77 -0
- package/dist/components/SequenceDiagramRenderer.d.ts.map +1 -0
- package/dist/components/SequenceDiagramRenderer.js +604 -0
- package/dist/components/SequenceDiagramRenderer.js.map +1 -0
- package/dist/components/WorkflowSequenceDiagram.d.ts +63 -0
- package/dist/components/WorkflowSequenceDiagram.d.ts.map +1 -0
- package/dist/components/WorkflowSequenceDiagram.js +147 -0
- package/dist/components/WorkflowSequenceDiagram.js.map +1 -0
- package/dist/components/dashboard/DashboardRenderer.d.ts +10 -0
- package/dist/components/dashboard/DashboardRenderer.d.ts.map +1 -0
- package/dist/components/dashboard/DashboardRenderer.js +179 -0
- package/dist/components/dashboard/DashboardRenderer.js.map +1 -0
- package/dist/components/dashboard/MetricPanel.d.ts +10 -0
- package/dist/components/dashboard/MetricPanel.d.ts.map +1 -0
- package/dist/components/dashboard/MetricPanel.js +103 -0
- package/dist/components/dashboard/MetricPanel.js.map +1 -0
- package/dist/components/dashboard/MockDataProvider.d.ts +30 -0
- package/dist/components/dashboard/MockDataProvider.d.ts.map +1 -0
- package/dist/components/dashboard/MockDataProvider.js +270 -0
- package/dist/components/dashboard/MockDataProvider.js.map +1 -0
- package/dist/components/dashboard/components/BarChart.d.ts +10 -0
- package/dist/components/dashboard/components/BarChart.d.ts.map +1 -0
- package/dist/components/dashboard/components/BarChart.js +167 -0
- package/dist/components/dashboard/components/BarChart.js.map +1 -0
- package/dist/components/dashboard/components/LineChart.d.ts +10 -0
- package/dist/components/dashboard/components/LineChart.d.ts.map +1 -0
- package/dist/components/dashboard/components/LineChart.js +141 -0
- package/dist/components/dashboard/components/LineChart.js.map +1 -0
- package/dist/components/dashboard/components/MetricCard.d.ts +9 -0
- package/dist/components/dashboard/components/MetricCard.d.ts.map +1 -0
- package/dist/components/dashboard/components/MetricCard.js +163 -0
- package/dist/components/dashboard/components/MetricCard.js.map +1 -0
- package/dist/components/dashboard/components/SourceLink.d.ts +9 -0
- package/dist/components/dashboard/components/SourceLink.d.ts.map +1 -0
- package/dist/components/dashboard/components/SourceLink.js +39 -0
- package/dist/components/dashboard/components/SourceLink.js.map +1 -0
- package/dist/components/dashboard/components/TimeRangeSelector.d.ts +9 -0
- package/dist/components/dashboard/components/TimeRangeSelector.d.ts.map +1 -0
- package/dist/components/dashboard/components/TimeRangeSelector.js +167 -0
- package/dist/components/dashboard/components/TimeRangeSelector.js.map +1 -0
- package/dist/components/dashboard/components/index.d.ts +6 -0
- package/dist/components/dashboard/components/index.d.ts.map +1 -0
- package/dist/components/dashboard/components/index.js +6 -0
- package/dist/components/dashboard/components/index.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +6 -0
- package/dist/components/dashboard/index.d.ts.map +1 -0
- package/dist/components/dashboard/index.js +8 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/types.d.ts +74 -0
- package/dist/components/dashboard/types.d.ts.map +1 -0
- package/dist/components/dashboard/types.js +8 -0
- package/dist/components/dashboard/types.js.map +1 -0
- package/dist/components/session-events/SessionEventFeed.d.ts +34 -0
- package/dist/components/session-events/SessionEventFeed.d.ts.map +1 -0
- package/dist/components/session-events/SessionEventFeed.js +1196 -0
- package/dist/components/session-events/SessionEventFeed.js.map +1 -0
- package/dist/components/session-events/index.d.ts +7 -0
- package/dist/components/session-events/index.d.ts.map +1 -0
- package/dist/components/session-events/index.js +6 -0
- package/dist/components/session-events/index.js.map +1 -0
- package/dist/components/state-view/PipelineView.d.ts +14 -0
- package/dist/components/state-view/PipelineView.d.ts.map +1 -0
- package/dist/components/state-view/PipelineView.js +195 -0
- package/dist/components/state-view/PipelineView.js.map +1 -0
- package/dist/components/state-view/index.d.ts +14 -0
- package/dist/components/state-view/index.d.ts.map +1 -0
- package/dist/components/state-view/index.js +12 -0
- package/dist/components/state-view/index.js.map +1 -0
- package/dist/components/state-view/types.d.ts +188 -0
- package/dist/components/state-view/types.d.ts.map +1 -0
- package/dist/components/state-view/types.js +10 -0
- package/dist/components/state-view/types.js.map +1 -0
- package/dist/components/state-view/useStateView.d.ts +32 -0
- package/dist/components/state-view/useStateView.d.ts.map +1 -0
- package/dist/components/state-view/useStateView.js +129 -0
- package/dist/components/state-view/useStateView.js.map +1 -0
- package/dist/contexts/GraphEditContext.d.ts +20 -0
- package/dist/contexts/GraphEditContext.d.ts.map +1 -0
- package/dist/contexts/GraphEditContext.js +8 -0
- package/dist/contexts/GraphEditContext.js.map +1 -0
- package/dist/contexts/TooltipPortalContext.d.ts +8 -0
- package/dist/contexts/TooltipPortalContext.d.ts.map +1 -0
- package/dist/contexts/TooltipPortalContext.js +8 -0
- package/dist/contexts/TooltipPortalContext.js.map +1 -0
- package/dist/edges/CustomEdge.d.ts +24 -0
- package/dist/edges/CustomEdge.d.ts.map +1 -0
- package/dist/edges/CustomEdge.js +222 -0
- package/dist/edges/CustomEdge.js.map +1 -0
- package/dist/edges/GenericEdge.d.ts +18 -0
- package/dist/edges/GenericEdge.d.ts.map +1 -0
- package/dist/edges/GenericEdge.js +10 -0
- package/dist/edges/GenericEdge.js.map +1 -0
- package/dist/graphify/anchor.d.ts +28 -0
- package/dist/graphify/anchor.d.ts.map +1 -0
- package/dist/graphify/anchor.js +132 -0
- package/dist/graphify/anchor.js.map +1 -0
- package/dist/graphify/consolidated.d.ts +210 -0
- package/dist/graphify/consolidated.d.ts.map +1 -0
- package/dist/graphify/consolidated.js +11 -0
- package/dist/graphify/consolidated.js.map +1 -0
- package/dist/graphify/ids.d.ts +19 -0
- package/dist/graphify/ids.d.ts.map +1 -0
- package/dist/graphify/ids.js +46 -0
- package/dist/graphify/ids.js.map +1 -0
- package/dist/graphify/index.d.ts +18 -0
- package/dist/graphify/index.d.ts.map +1 -0
- package/dist/graphify/index.js +12 -0
- package/dist/graphify/index.js.map +1 -0
- package/dist/graphify/kind.d.ts +23 -0
- package/dist/graphify/kind.d.ts.map +1 -0
- package/dist/graphify/kind.js +77 -0
- package/dist/graphify/kind.js.map +1 -0
- package/dist/graphify/resolve.d.ts +48 -0
- package/dist/graphify/resolve.d.ts.map +1 -0
- package/dist/graphify/resolve.js +83 -0
- package/dist/graphify/resolve.js.map +1 -0
- package/dist/graphify/signature.d.ts +87 -0
- package/dist/graphify/signature.d.ts.map +1 -0
- package/dist/graphify/signature.js +276 -0
- package/dist/graphify/signature.js.map +1 -0
- package/dist/graphify/types.d.ts +141 -0
- package/dist/graphify/types.d.ts.map +1 -0
- package/dist/graphify/types.js +8 -0
- package/dist/graphify/types.js.map +1 -0
- package/dist/hooks/useElkLayout.d.ts +66 -0
- package/dist/hooks/useElkLayout.d.ts.map +1 -0
- package/dist/hooks/useElkLayout.js +136 -0
- package/dist/hooks/useElkLayout.js.map +1 -0
- package/dist/hooks/usePathBasedEvents.d.ts +42 -0
- package/dist/hooks/usePathBasedEvents.d.ts.map +1 -0
- package/dist/hooks/usePathBasedEvents.js +119 -0
- package/dist/hooks/usePathBasedEvents.js.map +1 -0
- package/dist/hooks/useSequenceLayout.d.ts +186 -0
- package/dist/hooks/useSequenceLayout.d.ts.map +1 -0
- package/dist/hooks/useSequenceLayout.js +327 -0
- package/dist/hooks/useSequenceLayout.js.map +1 -0
- package/dist/hooks/useUndoRedo.d.ts +80 -0
- package/dist/hooks/useUndoRedo.d.ts.map +1 -0
- package/dist/hooks/useUndoRedo.js +70 -0
- package/dist/hooks/useUndoRedo.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/CustomNode.d.ts +28 -0
- package/dist/nodes/CustomNode.d.ts.map +1 -0
- package/dist/nodes/CustomNode.js +820 -0
- package/dist/nodes/CustomNode.js.map +1 -0
- package/dist/nodes/GenericNode.d.ts +20 -0
- package/dist/nodes/GenericNode.d.ts.map +1 -0
- package/dist/nodes/GenericNode.js +20 -0
- package/dist/nodes/GenericNode.js.map +1 -0
- package/dist/nodes/otel/OtelBoundaryNode.d.ts +55 -0
- package/dist/nodes/otel/OtelBoundaryNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelBoundaryNode.js +81 -0
- package/dist/nodes/otel/OtelBoundaryNode.js.map +1 -0
- package/dist/nodes/otel/OtelEventNode.d.ts +59 -0
- package/dist/nodes/otel/OtelEventNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelEventNode.js +82 -0
- package/dist/nodes/otel/OtelEventNode.js.map +1 -0
- package/dist/nodes/otel/OtelResourceNode.d.ts +53 -0
- package/dist/nodes/otel/OtelResourceNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelResourceNode.js +105 -0
- package/dist/nodes/otel/OtelResourceNode.js.map +1 -0
- package/dist/nodes/otel/OtelScopeNode.d.ts +53 -0
- package/dist/nodes/otel/OtelScopeNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelScopeNode.js +81 -0
- package/dist/nodes/otel/OtelScopeNode.js.map +1 -0
- package/dist/nodes/otel/OtelSpanConventionNode.d.ts +61 -0
- package/dist/nodes/otel/OtelSpanConventionNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelSpanConventionNode.js +131 -0
- package/dist/nodes/otel/OtelSpanConventionNode.js.map +1 -0
- package/dist/nodes/otel/index.d.ts +17 -0
- package/dist/nodes/otel/index.d.ts.map +1 -0
- package/dist/nodes/otel/index.js +13 -0
- package/dist/nodes/otel/index.js.map +1 -0
- package/dist/nodes/otel/shared/NodeBadges.d.ts +10 -0
- package/dist/nodes/otel/shared/NodeBadges.d.ts.map +1 -0
- package/dist/nodes/otel/shared/NodeBadges.js +178 -0
- package/dist/nodes/otel/shared/NodeBadges.js.map +1 -0
- package/dist/nodes/otel/shared/NodeContent.d.ts +10 -0
- package/dist/nodes/otel/shared/NodeContent.d.ts.map +1 -0
- package/dist/nodes/otel/shared/NodeContent.js +96 -0
- package/dist/nodes/otel/shared/NodeContent.js.map +1 -0
- package/dist/nodes/otel/shared/index.d.ts +8 -0
- package/dist/nodes/otel/shared/index.d.ts.map +1 -0
- package/dist/nodes/otel/shared/index.js +8 -0
- package/dist/nodes/otel/shared/index.js.map +1 -0
- package/dist/nodes/otel/shared/types.d.ts +129 -0
- package/dist/nodes/otel/shared/types.d.ts.map +1 -0
- package/dist/nodes/otel/shared/types.js +5 -0
- package/dist/nodes/otel/shared/types.js.map +1 -0
- package/dist/nodes/otel/shared/useNodeBehavior.d.ts +42 -0
- package/dist/nodes/otel/shared/useNodeBehavior.d.ts.map +1 -0
- package/dist/nodes/otel/shared/useNodeBehavior.js +61 -0
- package/dist/nodes/otel/shared/useNodeBehavior.js.map +1 -0
- package/dist/pierre/PierreFileView.d.ts +17 -0
- package/dist/pierre/PierreFileView.d.ts.map +1 -0
- package/dist/pierre/PierreFileView.js +46 -0
- package/dist/pierre/PierreFileView.js.map +1 -0
- package/dist/pierre/PierreSnippetView.d.ts +28 -0
- package/dist/pierre/PierreSnippetView.d.ts.map +1 -0
- package/dist/pierre/PierreSnippetView.js +105 -0
- package/dist/pierre/PierreSnippetView.js.map +1 -0
- package/dist/pierre/PierreThroughlineCodeView.d.ts +22 -0
- package/dist/pierre/PierreThroughlineCodeView.d.ts.map +1 -0
- package/dist/pierre/PierreThroughlineCodeView.js +206 -0
- package/dist/pierre/PierreThroughlineCodeView.js.map +1 -0
- package/dist/pierre/constructColors.d.ts +24 -0
- package/dist/pierre/constructColors.d.ts.map +1 -0
- package/dist/pierre/constructColors.js +91 -0
- package/dist/pierre/constructColors.js.map +1 -0
- package/dist/pierre/index.d.ts +12 -0
- package/dist/pierre/index.d.ts.map +1 -0
- package/dist/pierre/index.js +7 -0
- package/dist/pierre/index.js.map +1 -0
- package/dist/pierre/pierreBackground.d.ts +15 -0
- package/dist/pierre/pierreBackground.d.ts.map +1 -0
- package/dist/pierre/pierreBackground.js +31 -0
- package/dist/pierre/pierreBackground.js.map +1 -0
- package/dist/pierre/pierreFileLang.d.ts +27 -0
- package/dist/pierre/pierreFileLang.d.ts.map +1 -0
- package/dist/pierre/pierreFileLang.js +52 -0
- package/dist/pierre/pierreFileLang.js.map +1 -0
- package/dist/pierre/pierreSyntaxTheme.d.ts +11 -0
- package/dist/pierre/pierreSyntaxTheme.d.ts.map +1 -0
- package/dist/pierre/pierreSyntaxTheme.js +20 -0
- package/dist/pierre/pierreSyntaxTheme.js.map +1 -0
- package/dist/pierre/scrollAnchor.d.ts +5 -0
- package/dist/pierre/scrollAnchor.d.ts.map +1 -0
- package/dist/pierre/scrollAnchor.js +9 -0
- package/dist/pierre/scrollAnchor.js.map +1 -0
- package/dist/pierre/sliceSnippet.d.ts +10 -0
- package/dist/pierre/sliceSnippet.d.ts.map +1 -0
- package/dist/pierre/sliceSnippet.js +16 -0
- package/dist/pierre/sliceSnippet.js.map +1 -0
- package/dist/pierre/syntaxTokens.d.ts +11 -0
- package/dist/pierre/syntaxTokens.d.ts.map +1 -0
- package/dist/pierre/syntaxTokens.js +51 -0
- package/dist/pierre/syntaxTokens.js.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +8 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js +116 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -0
- package/dist/subsystem/ComponentDeclaration.d.ts +87 -0
- package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -0
- package/dist/subsystem/ComponentDeclaration.js +374 -0
- package/dist/subsystem/ComponentDeclaration.js.map +1 -0
- package/dist/subsystem/FileDrawer.d.ts +17 -0
- package/dist/subsystem/FileDrawer.d.ts.map +1 -0
- package/dist/subsystem/FileDrawer.js +72 -0
- package/dist/subsystem/FileDrawer.js.map +1 -0
- package/dist/subsystem/GraphLayoutCover.d.ts +20 -0
- package/dist/subsystem/GraphLayoutCover.d.ts.map +1 -0
- package/dist/subsystem/GraphLayoutCover.js +42 -0
- package/dist/subsystem/GraphLayoutCover.js.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts +96 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.js +1059 -0
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -0
- package/dist/subsystem/SubsystemFileTree.d.ts +24 -0
- package/dist/subsystem/SubsystemFileTree.d.ts.map +1 -0
- package/dist/subsystem/SubsystemFileTree.js +150 -0
- package/dist/subsystem/SubsystemFileTree.js.map +1 -0
- package/dist/subsystem/declarationRef.d.ts +39 -0
- package/dist/subsystem/declarationRef.d.ts.map +1 -0
- package/dist/subsystem/declarationRef.js +32 -0
- package/dist/subsystem/declarationRef.js.map +1 -0
- package/dist/subsystem/formatDeclaration.d.ts +11 -0
- package/dist/subsystem/formatDeclaration.d.ts.map +1 -0
- package/dist/subsystem/formatDeclaration.js +146 -0
- package/dist/subsystem/formatDeclaration.js.map +1 -0
- package/dist/subsystem/model.d.ts +353 -0
- package/dist/subsystem/model.d.ts.map +1 -0
- package/dist/subsystem/model.js +503 -0
- package/dist/subsystem/model.js.map +1 -0
- package/dist/subsystem/nodes.d.ts +69 -0
- package/dist/subsystem/nodes.d.ts.map +1 -0
- package/dist/subsystem/nodes.js +289 -0
- package/dist/subsystem/nodes.js.map +1 -0
- package/dist/subsystem/paths.d.ts +63 -0
- package/dist/subsystem/paths.d.ts.map +1 -0
- package/dist/subsystem/paths.js +86 -0
- package/dist/subsystem/paths.js.map +1 -0
- package/dist/subsystem/tokenizeComponent.d.ts +20 -0
- package/dist/subsystem/tokenizeComponent.d.ts.map +1 -0
- package/dist/subsystem/tokenizeComponent.js +56 -0
- package/dist/subsystem/tokenizeComponent.js.map +1 -0
- package/dist/subsystem/tokenizeFormatted.d.ts +12 -0
- package/dist/subsystem/tokenizeFormatted.d.ts.map +1 -0
- package/dist/subsystem/tokenizeFormatted.js +13 -0
- package/dist/subsystem/tokenizeFormatted.js.map +1 -0
- package/dist/utils/animationMapping.d.ts +53 -0
- package/dist/utils/animationMapping.d.ts.map +1 -0
- package/dist/utils/animationMapping.js +126 -0
- package/dist/utils/animationMapping.js.map +1 -0
- package/dist/utils/canvasBounds.d.ts +50 -0
- package/dist/utils/canvasBounds.d.ts.map +1 -0
- package/dist/utils/canvasBounds.js +88 -0
- package/dist/utils/canvasBounds.js.map +1 -0
- package/dist/utils/elkLayout.d.ts +137 -0
- package/dist/utils/elkLayout.d.ts.map +1 -0
- package/dist/utils/elkLayout.js +596 -0
- package/dist/utils/elkLayout.js.map +1 -0
- package/dist/utils/graphConverter.d.ts +18 -0
- package/dist/utils/graphConverter.d.ts.map +1 -0
- package/dist/utils/graphConverter.js +114 -0
- package/dist/utils/graphConverter.js.map +1 -0
- package/dist/utils/iconResolver.d.ts +29 -0
- package/dist/utils/iconResolver.d.ts.map +1 -0
- package/dist/utils/iconResolver.js +30 -0
- package/dist/utils/iconResolver.js.map +1 -0
- package/dist/utils/orientationUtils.d.ts +19 -0
- package/dist/utils/orientationUtils.d.ts.map +1 -0
- package/dist/utils/orientationUtils.js +62 -0
- package/dist/utils/orientationUtils.js.map +1 -0
- package/package.json +80 -0
- package/src/components/ConfigurationSelector.tsx +133 -0
- package/src/components/GraphRenderer.tsx +3195 -0
- package/src/components/MultiCanvasRenderer.tsx +295 -0
- package/src/components/NodeTooltip.tsx +279 -0
- package/src/components/PendingChanges.test.tsx +375 -0
- package/src/components/SelectionSidebar.tsx +352 -0
- package/src/components/SequenceDiagramRenderer.tsx +1156 -0
- package/src/components/WorkflowSequenceDiagram.tsx +270 -0
- package/src/components/dashboard/DashboardRenderer.tsx +317 -0
- package/src/components/dashboard/MetricPanel.tsx +254 -0
- package/src/components/dashboard/MockDataProvider.ts +330 -0
- package/src/components/dashboard/components/BarChart.tsx +299 -0
- package/src/components/dashboard/components/LineChart.tsx +279 -0
- package/src/components/dashboard/components/MetricCard.tsx +270 -0
- package/src/components/dashboard/components/SourceLink.tsx +63 -0
- package/src/components/dashboard/components/TimeRangeSelector.tsx +280 -0
- package/src/components/dashboard/components/index.ts +5 -0
- package/src/components/dashboard/index.ts +47 -0
- package/src/components/dashboard/types.ts +126 -0
- package/src/components/session-events/SessionEventFeed.tsx +1797 -0
- package/src/components/session-events/index.ts +13 -0
- package/src/components/state-view/PipelineView.tsx +347 -0
- package/src/components/state-view/index.ts +14 -0
- package/src/components/state-view/types.ts +261 -0
- package/src/components/state-view/useStateView.ts +205 -0
- package/src/contexts/GraphEditContext.tsx +27 -0
- package/src/contexts/TooltipPortalContext.ts +8 -0
- package/src/edges/CustomEdge.tsx +402 -0
- package/src/edges/GenericEdge.tsx +36 -0
- package/src/graphify/anchor.test.ts +124 -0
- package/src/graphify/anchor.ts +160 -0
- package/src/graphify/consolidated.ts +246 -0
- package/src/graphify/ids.ts +48 -0
- package/src/graphify/index.ts +72 -0
- package/src/graphify/kind.test.ts +108 -0
- package/src/graphify/kind.ts +120 -0
- package/src/graphify/resolve.test.ts +89 -0
- package/src/graphify/resolve.ts +115 -0
- package/src/graphify/signature.test.ts +278 -0
- package/src/graphify/signature.ts +354 -0
- package/src/graphify/types.ts +164 -0
- package/src/hooks/useElkLayout.test.ts +134 -0
- package/src/hooks/useElkLayout.ts +191 -0
- package/src/hooks/usePathBasedEvents.ts +192 -0
- package/src/hooks/useSequenceLayout.ts +543 -0
- package/src/hooks/useUndoRedo.ts +144 -0
- package/src/index.ts +341 -0
- package/src/nodes/CustomNode.tsx +1231 -0
- package/src/nodes/GenericNode.tsx +55 -0
- package/src/nodes/otel/OtelBoundaryNode.tsx +224 -0
- package/src/nodes/otel/OtelEventNode.tsx +225 -0
- package/src/nodes/otel/OtelResourceNode.tsx +251 -0
- package/src/nodes/otel/OtelScopeNode.tsx +221 -0
- package/src/nodes/otel/OtelSpanConventionNode.tsx +295 -0
- package/src/nodes/otel/index.ts +23 -0
- package/src/nodes/otel/shared/NodeBadges.tsx +295 -0
- package/src/nodes/otel/shared/NodeContent.tsx +204 -0
- package/src/nodes/otel/shared/index.ts +8 -0
- package/src/nodes/otel/shared/types.ts +138 -0
- package/src/nodes/otel/shared/useNodeBehavior.ts +114 -0
- package/src/pierre/PierreFileView.tsx +81 -0
- package/src/pierre/PierreSnippetView.tsx +184 -0
- package/src/pierre/PierreThroughlineCodeView.tsx +304 -0
- package/src/pierre/constructColors.test.ts +52 -0
- package/src/pierre/constructColors.ts +112 -0
- package/src/pierre/index.ts +18 -0
- package/src/pierre/pierreBackground.ts +33 -0
- package/src/pierre/pierreFileLang.test.ts +26 -0
- package/src/pierre/pierreFileLang.ts +55 -0
- package/src/pierre/pierreSyntaxTheme.ts +23 -0
- package/src/pierre/scrollAnchor.test.ts +13 -0
- package/src/pierre/scrollAnchor.ts +11 -0
- package/src/pierre/sliceSnippet.test.ts +21 -0
- package/src/pierre/sliceSnippet.ts +31 -0
- package/src/pierre/syntaxTokens.test.ts +35 -0
- package/src/pierre/syntaxTokens.ts +60 -0
- package/src/stories/Audit/BoundaryNodes.stories.tsx +385 -0
- package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +1448 -0
- package/src/stories/Audit/CanvasNodeTypes.stories.tsx +1049 -0
- package/src/stories/Audit/ColorPriority.stories.tsx +895 -0
- package/src/stories/Audit/DiamondBadges.stories.tsx +629 -0
- package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +724 -0
- package/src/stories/Audit/NodeFieldsAudit.stories.tsx +996 -0
- package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +715 -0
- package/src/stories/Audit/NodeShapes.stories.tsx +1208 -0
- package/src/stories/Audit/WideNodesTesting.stories.tsx +1045 -0
- package/src/stories/Components/DashboardRenderer.stories.tsx +263 -0
- package/src/stories/Components/GraphRenderer.stories.tsx +3236 -0
- package/src/stories/Components/MultiCanvasRenderer.stories.tsx +370 -0
- package/src/stories/Components/SequenceDiagram.stories.tsx +255 -0
- package/src/stories/Components/StateView.stories.tsx +417 -0
- package/src/stories/Components/TraceViewer.stories.tsx +442 -0
- package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +802 -0
- package/src/stories/Features/AnimationWorkshop.stories.tsx +727 -0
- package/src/stories/Features/ChangeTypeVisual.stories.tsx +67 -0
- package/src/stories/Features/EventDrivenAnimations.stories.tsx +513 -0
- package/src/stories/Features/MultiConfig.stories.tsx +539 -0
- package/src/stories/Introduction.mdx +34 -0
- package/src/stories/Layout/ElkEdgeRouting.stories.tsx +539 -0
- package/src/stories/Layout/GraphOrientation.stories.tsx +500 -0
- package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +352 -0
- package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +560 -0
- package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +491 -0
- package/src/stories/Nodes/NumericColors.stories.tsx +440 -0
- package/src/stories/OTEL/EventNameDisplay.stories.tsx +694 -0
- package/src/stories/OTEL/EventNameFallback.stories.tsx +578 -0
- package/src/stories/OTEL/OtelComponents.stories.tsx +422 -0
- package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +806 -0
- package/src/stories/OTEL/RawEventCards.stories.tsx +57 -0
- package/src/stories/OTEL/SpanBadges.stories.tsx +840 -0
- package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +209 -0
- package/src/stories/Pierre/CodeView.stories.tsx +219 -0
- package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +721 -0
- package/src/stories/RealWorld/FileCitySequence.stories.tsx +516 -0
- package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +336 -0
- package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +321 -0
- package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +365 -0
- package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +137 -0
- package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +238 -0
- package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +315 -0
- package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +239 -0
- package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +216 -0
- package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +70 -0
- package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +68 -0
- package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +959 -0
- package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +681 -0
- package/src/stories/Subsystem/ComponentGraph/fixtures.ts +129 -0
- package/src/stories/__traces__/test-run.canvas.json +241 -0
- package/src/stories/data/activity-feed-analytics.dashboard.json +300 -0
- package/src/stories/data/file-city-images-transformed.otel.canvas.json +295 -0
- package/src/stories/data/file-city-workflows.json +269 -0
- package/src/stories/data/graph-converter-test-execution.json +443 -0
- package/src/stories/data/graph-converter-test.workflow.json +105 -0
- package/src/stories/data/graph-converter-validated-execution.json +58 -0
- package/src/stories/data/opencode-session-raw-events.json +273396 -0
- package/src/subsystem/ComponentDeclaration.tsx +643 -0
- package/src/subsystem/FileDrawer.tsx +106 -0
- package/src/subsystem/GraphLayoutCover.tsx +69 -0
- package/src/subsystem/SubsystemComponentGraph.tsx +1644 -0
- package/src/subsystem/SubsystemFileTree.tsx +190 -0
- package/src/subsystem/declarationRef.test.ts +33 -0
- package/src/subsystem/declarationRef.ts +63 -0
- package/src/subsystem/formatDeclaration.ts +174 -0
- package/src/subsystem/model.test.ts +244 -0
- package/src/subsystem/model.ts +850 -0
- package/src/subsystem/nodes.test.ts +56 -0
- package/src/subsystem/nodes.tsx +443 -0
- package/src/subsystem/paths.test.ts +123 -0
- package/src/subsystem/paths.ts +127 -0
- package/src/subsystem/tokenizeComponent.ts +70 -0
- package/src/subsystem/tokenizeFormatted.ts +19 -0
- package/src/utils/animationMapping.ts +166 -0
- package/src/utils/canvasBounds.ts +146 -0
- package/src/utils/elkLayout.test.ts +240 -0
- package/src/utils/elkLayout.ts +779 -0
- package/src/utils/graphConverter.ts +148 -0
- package/src/utils/iconResolver.tsx +53 -0
- package/src/utils/orientationUtils.ts +73 -0
|
@@ -0,0 +1,1196 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* SessionEventFeed — a three-column diagnostic feed over one agent session's
|
|
4
|
+
* events, showing the raw → repo-normalized → accumulated (UI) pipeline
|
|
5
|
+
* for every row.
|
|
6
|
+
*
|
|
7
|
+
* Input rows match the principal-studio's `SessionEventRow` wire shape:
|
|
8
|
+
* { seq, type, raw, normalized, accumulated }
|
|
9
|
+
* `raw` is the agent-specific payload (opencode V1 sqlite rows, or durable
|
|
10
|
+
* reader blobs such as Cursor store.db messages), `normalized` its
|
|
11
|
+
* repo-normalized form, and `accumulated` the AgentSessionEvent the File City
|
|
12
|
+
* UI actually renders (null when the accumulator drops the event).
|
|
13
|
+
*
|
|
14
|
+
* Dark diagnostic palette — intentionally self-contained rather than themed.
|
|
15
|
+
*/
|
|
16
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
17
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
18
|
+
import { Check, Copy } from 'lucide-react';
|
|
19
|
+
/** Shared collapse state keyed by row seq. */
|
|
20
|
+
function useCollapse(seqs, defaultCollapsed = false) {
|
|
21
|
+
const [collapsed, setCollapsed] = useState(() => (defaultCollapsed ? new Set(seqs) : new Set()));
|
|
22
|
+
// When the feed grows (incremental paging appends rows), default newly added
|
|
23
|
+
// rows to collapsed so the invariant holds for rows that arrive after mount.
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!defaultCollapsed)
|
|
26
|
+
return;
|
|
27
|
+
setCollapsed((prev) => {
|
|
28
|
+
let changed = false;
|
|
29
|
+
const next = new Set(prev);
|
|
30
|
+
for (const seq of seqs) {
|
|
31
|
+
if (!next.has(seq)) {
|
|
32
|
+
next.add(seq);
|
|
33
|
+
changed = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return changed ? next : prev;
|
|
37
|
+
});
|
|
38
|
+
}, [seqs, defaultCollapsed]);
|
|
39
|
+
const toggle = useCallback((seq) => {
|
|
40
|
+
setCollapsed((prev) => {
|
|
41
|
+
const next = new Set(prev);
|
|
42
|
+
if (next.has(seq))
|
|
43
|
+
next.delete(seq);
|
|
44
|
+
else
|
|
45
|
+
next.add(seq);
|
|
46
|
+
return next;
|
|
47
|
+
});
|
|
48
|
+
}, []);
|
|
49
|
+
const setAll = useCallback((value) => setCollapsed(value ? new Set(seqs) : new Set()), [seqs]);
|
|
50
|
+
return { collapsed, toggle, setAll };
|
|
51
|
+
}
|
|
52
|
+
function toRaw(raw) {
|
|
53
|
+
if (raw === null || raw === undefined || typeof raw !== 'object')
|
|
54
|
+
return null;
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
function toNormalized(normalized) {
|
|
58
|
+
return normalized;
|
|
59
|
+
}
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Raw event → presentable pieces
|
|
62
|
+
// =============================================================================
|
|
63
|
+
function dataOf(e) {
|
|
64
|
+
return (e?.data ?? {});
|
|
65
|
+
}
|
|
66
|
+
function partOf(e) {
|
|
67
|
+
return dataOf(e).part;
|
|
68
|
+
}
|
|
69
|
+
/** True when the payload looks like an opencode V1 sqlite event row. */
|
|
70
|
+
function isV1RawEvent(e) {
|
|
71
|
+
return typeof e?.type === 'string' && e.type.length > 0;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Cursor store.db blobs (and other durable readers) put the whole message in
|
|
75
|
+
* `raw` — no `type` / `data` envelope. Pull a presentable kind + summary from
|
|
76
|
+
* the common shapes CursorSessionReader emits:
|
|
77
|
+
* - chat message: `{ role, content, id? }`
|
|
78
|
+
* - tool wrapper: `{ message, block }` where block is tool-call / tool-result
|
|
79
|
+
* - session meta: `{ title?, cwd?, schemaVersion? }`
|
|
80
|
+
*/
|
|
81
|
+
function durableRawKind(e) {
|
|
82
|
+
const block = e.block;
|
|
83
|
+
if (block && typeof block === 'object') {
|
|
84
|
+
const toolName = (block.toolName ?? block.name);
|
|
85
|
+
const blockType = block.type;
|
|
86
|
+
if (blockType === 'tool-call' || blockType === 'tool_use') {
|
|
87
|
+
return toolName ? `tool-call:${toolName}` : 'tool-call';
|
|
88
|
+
}
|
|
89
|
+
if (blockType === 'tool-result' || blockType === 'tool_result') {
|
|
90
|
+
return toolName ? `tool-result:${toolName}` : 'tool-result';
|
|
91
|
+
}
|
|
92
|
+
if (typeof blockType === 'string')
|
|
93
|
+
return blockType;
|
|
94
|
+
}
|
|
95
|
+
if (typeof e.role === 'string')
|
|
96
|
+
return e.role;
|
|
97
|
+
if (typeof e.title === 'string' || typeof e.cwd === 'string' || typeof e.schemaVersion === 'number') {
|
|
98
|
+
return 'session-meta';
|
|
99
|
+
}
|
|
100
|
+
return 'durable-raw';
|
|
101
|
+
}
|
|
102
|
+
function durableRawDescribe(e) {
|
|
103
|
+
const block = e.block;
|
|
104
|
+
if (block && typeof block === 'object') {
|
|
105
|
+
const toolName = (block.toolName ?? block.name);
|
|
106
|
+
const blockType = block.type;
|
|
107
|
+
if (blockType === 'tool-call' || blockType === 'tool_use') {
|
|
108
|
+
const args = block.args ?? block.input;
|
|
109
|
+
const summary = toolSummary(args);
|
|
110
|
+
return [toolName, summary].filter(Boolean).join(' · ') || 'tool call';
|
|
111
|
+
}
|
|
112
|
+
if (blockType === 'tool-result' || blockType === 'tool_result') {
|
|
113
|
+
const result = block.result;
|
|
114
|
+
const text = typeof result === 'string'
|
|
115
|
+
? result.slice(0, 120)
|
|
116
|
+
: result !== undefined
|
|
117
|
+
? JSON.stringify(result).slice(0, 120)
|
|
118
|
+
: '';
|
|
119
|
+
return [toolName, text].filter(Boolean).join(' · ') || 'tool result';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (typeof e.role === 'string') {
|
|
123
|
+
const content = e.content;
|
|
124
|
+
if (typeof content === 'string') {
|
|
125
|
+
const tagged = content.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/i);
|
|
126
|
+
const text = (tagged?.[1] ?? content).trim().replace(/\s+/g, ' ');
|
|
127
|
+
return text.slice(0, 120) || e.role;
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(content)) {
|
|
130
|
+
const texts = content
|
|
131
|
+
.filter((c) => !!c && typeof c === 'object')
|
|
132
|
+
.map((c) => (typeof c.text === 'string' ? c.text : c.toolName ?? c.name ?? c.type))
|
|
133
|
+
.filter(Boolean);
|
|
134
|
+
return texts.join(' · ').slice(0, 120) || e.role;
|
|
135
|
+
}
|
|
136
|
+
return e.role;
|
|
137
|
+
}
|
|
138
|
+
if (typeof e.title === 'string')
|
|
139
|
+
return e.title;
|
|
140
|
+
if (typeof e.cwd === 'string')
|
|
141
|
+
return e.cwd;
|
|
142
|
+
return 'durable raw event';
|
|
143
|
+
}
|
|
144
|
+
function eventTimestamp(e) {
|
|
145
|
+
if (!e)
|
|
146
|
+
return 0;
|
|
147
|
+
const d = dataOf(e);
|
|
148
|
+
if (typeof d.time === 'number')
|
|
149
|
+
return d.time;
|
|
150
|
+
const info = d.info;
|
|
151
|
+
const infoTime = info?.time;
|
|
152
|
+
if (typeof infoTime?.created === 'number')
|
|
153
|
+
return infoTime.created;
|
|
154
|
+
const part = partOf(e);
|
|
155
|
+
if (typeof part?.time === 'number')
|
|
156
|
+
return part.time;
|
|
157
|
+
const state = part?.state;
|
|
158
|
+
const stateTime = state?.time;
|
|
159
|
+
if (typeof stateTime?.start === 'number')
|
|
160
|
+
return stateTime.start;
|
|
161
|
+
if (typeof stateTime?.end === 'number')
|
|
162
|
+
return stateTime.end;
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
const ALL_CATEGORIES = [
|
|
166
|
+
'session',
|
|
167
|
+
'conversation',
|
|
168
|
+
'tool',
|
|
169
|
+
'step',
|
|
170
|
+
'patch',
|
|
171
|
+
'compaction',
|
|
172
|
+
];
|
|
173
|
+
function eventCategory(e) {
|
|
174
|
+
if (!e)
|
|
175
|
+
return 'session';
|
|
176
|
+
if (!isV1RawEvent(e)) {
|
|
177
|
+
const kind = durableRawKind(e);
|
|
178
|
+
if (kind.startsWith('tool-call') || kind.startsWith('tool-result') || kind.startsWith('tool')) {
|
|
179
|
+
return 'tool';
|
|
180
|
+
}
|
|
181
|
+
if (kind === 'session-meta')
|
|
182
|
+
return 'session';
|
|
183
|
+
return 'conversation';
|
|
184
|
+
}
|
|
185
|
+
switch (e.type) {
|
|
186
|
+
case 'session.created.1':
|
|
187
|
+
case 'session.updated.1':
|
|
188
|
+
return 'session';
|
|
189
|
+
case 'message.updated.1':
|
|
190
|
+
case 'message.removed.1':
|
|
191
|
+
case 'message.part.updated.1': {
|
|
192
|
+
const partType = partOf(e)?.type;
|
|
193
|
+
switch (partType) {
|
|
194
|
+
case 'text':
|
|
195
|
+
case 'reasoning':
|
|
196
|
+
return 'conversation';
|
|
197
|
+
case 'tool':
|
|
198
|
+
return 'tool';
|
|
199
|
+
case 'step-start':
|
|
200
|
+
case 'step-finish':
|
|
201
|
+
return 'step';
|
|
202
|
+
case 'patch':
|
|
203
|
+
return 'patch';
|
|
204
|
+
case 'compaction':
|
|
205
|
+
return 'compaction';
|
|
206
|
+
default:
|
|
207
|
+
return 'conversation';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
default:
|
|
211
|
+
return 'conversation';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const PRESETS = [
|
|
215
|
+
{ id: 'all', label: 'All', include: ALL_CATEGORIES },
|
|
216
|
+
{ id: 'activity', label: 'Activity', include: ['conversation', 'tool', 'patch'] },
|
|
217
|
+
{ id: 'conversation', label: 'Conversation', include: ['conversation'] },
|
|
218
|
+
{ id: 'tools', label: 'Tools', include: ['tool'] },
|
|
219
|
+
{ id: 'noise', label: 'Session & steps', include: ['session', 'step', 'compaction'] },
|
|
220
|
+
];
|
|
221
|
+
/** Granular key for a card (raw event type, or part type for parts). */
|
|
222
|
+
function eventKind(e) {
|
|
223
|
+
if (!e)
|
|
224
|
+
return 'no-raw';
|
|
225
|
+
if (!isV1RawEvent(e))
|
|
226
|
+
return durableRawKind(e);
|
|
227
|
+
if (e.type === 'message.part.updated.1') {
|
|
228
|
+
return `part:${partOf(e)?.type ?? 'unknown'}`;
|
|
229
|
+
}
|
|
230
|
+
return e.type;
|
|
231
|
+
}
|
|
232
|
+
function kindLabel(kind) {
|
|
233
|
+
if (!kind)
|
|
234
|
+
return 'unknown';
|
|
235
|
+
if (kind.startsWith('part:'))
|
|
236
|
+
return `part · ${kind.slice(5)}`;
|
|
237
|
+
if (kind.startsWith('tool-call:'))
|
|
238
|
+
return `call · ${kind.slice('tool-call:'.length)}`;
|
|
239
|
+
if (kind.startsWith('tool-result:'))
|
|
240
|
+
return `result · ${kind.slice('tool-result:'.length)}`;
|
|
241
|
+
return kind;
|
|
242
|
+
}
|
|
243
|
+
const KIND_COLORS = {
|
|
244
|
+
'session.created.1': '#64748b',
|
|
245
|
+
'session.updated.1': '#94a3b8',
|
|
246
|
+
'message.updated.1': '#06b6d4',
|
|
247
|
+
'message.removed.1': '#ef4444',
|
|
248
|
+
'part:text': '#10b981',
|
|
249
|
+
'part:reasoning': '#8b5cf6',
|
|
250
|
+
'part:tool': '#3b82f6',
|
|
251
|
+
'part:step-start': '#f59e0b',
|
|
252
|
+
'part:step-finish': '#f59e0b',
|
|
253
|
+
'part:patch': '#ef4444',
|
|
254
|
+
'part:compaction': '#ec4899',
|
|
255
|
+
'part:unknown': '#6b7280',
|
|
256
|
+
};
|
|
257
|
+
function kindColor(kind) {
|
|
258
|
+
return KIND_COLORS[kind] ?? '#6b7280';
|
|
259
|
+
}
|
|
260
|
+
function describe(e) {
|
|
261
|
+
if (!e)
|
|
262
|
+
return 'finished';
|
|
263
|
+
if (!isV1RawEvent(e))
|
|
264
|
+
return durableRawDescribe(e);
|
|
265
|
+
const d = dataOf(e);
|
|
266
|
+
const info = d.info;
|
|
267
|
+
const part = partOf(e);
|
|
268
|
+
const state = part?.state;
|
|
269
|
+
switch (e.type) {
|
|
270
|
+
case 'session.created.1':
|
|
271
|
+
return info?.title ?? 'Session created';
|
|
272
|
+
case 'session.updated.1': {
|
|
273
|
+
const bits = [];
|
|
274
|
+
const tokens = info?.tokens;
|
|
275
|
+
if (typeof info?.cost === 'number')
|
|
276
|
+
bits.push(`$${info.cost.toFixed(4)}`);
|
|
277
|
+
if (typeof tokens?.input === 'number')
|
|
278
|
+
bits.push(`${tokens.input} in`);
|
|
279
|
+
if (typeof tokens?.output === 'number')
|
|
280
|
+
bits.push(`${tokens.output} out`);
|
|
281
|
+
return bits.length > 0 ? `Session updated · ${bits.join(' · ')}` : 'Session updated';
|
|
282
|
+
}
|
|
283
|
+
case 'message.updated.1': {
|
|
284
|
+
const role = info?.role ?? 'message';
|
|
285
|
+
const model = info?.model?.modelID;
|
|
286
|
+
return model ? `${role} message · ${model}` : `${role} message`;
|
|
287
|
+
}
|
|
288
|
+
case 'message.removed.1':
|
|
289
|
+
return `Removed ${d.messageID}`;
|
|
290
|
+
case 'message.part.updated.1': {
|
|
291
|
+
const partType = part?.type;
|
|
292
|
+
const toolName = part?.tool;
|
|
293
|
+
const status = state?.status;
|
|
294
|
+
switch (partType) {
|
|
295
|
+
case 'text':
|
|
296
|
+
return part?.text ?? 'Text';
|
|
297
|
+
case 'reasoning':
|
|
298
|
+
return part?.text || 'Reasoning';
|
|
299
|
+
case 'tool': {
|
|
300
|
+
const bits = [toolName, status];
|
|
301
|
+
const n = todoCountOf(state?.input);
|
|
302
|
+
if (n > 0)
|
|
303
|
+
bits.push(`${n} todo${n === 1 ? '' : 's'}`);
|
|
304
|
+
return bits.filter(Boolean).join(' · ') || 'Tool';
|
|
305
|
+
}
|
|
306
|
+
case 'step-start':
|
|
307
|
+
return 'Step start';
|
|
308
|
+
case 'step-finish':
|
|
309
|
+
return part?.reason ? `Step finish · ${part.reason}` : 'Step finish';
|
|
310
|
+
case 'patch': {
|
|
311
|
+
const files = part?.files;
|
|
312
|
+
return `Patch · ${files?.length ?? 0} file${(files?.length ?? 0) === 1 ? '' : 's'}`;
|
|
313
|
+
}
|
|
314
|
+
case 'compaction':
|
|
315
|
+
return `Compaction${part?.auto ? ' · auto' : ''}`;
|
|
316
|
+
default:
|
|
317
|
+
return partType ?? 'Part';
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
default:
|
|
321
|
+
return e.type;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/** Number of todos carried by a todowrite tool input, if any. */
|
|
325
|
+
function todoCountOf(input) {
|
|
326
|
+
if (input && typeof input === 'object') {
|
|
327
|
+
const todos = input['todos'];
|
|
328
|
+
if (Array.isArray(todos))
|
|
329
|
+
return todos.length;
|
|
330
|
+
}
|
|
331
|
+
return 0;
|
|
332
|
+
}
|
|
333
|
+
function toolSummary(input) {
|
|
334
|
+
if (input === null || input === undefined)
|
|
335
|
+
return '';
|
|
336
|
+
if (typeof input === 'string')
|
|
337
|
+
return input;
|
|
338
|
+
if (Array.isArray(input))
|
|
339
|
+
return JSON.stringify(input).slice(0, 120);
|
|
340
|
+
const obj = input;
|
|
341
|
+
// A todowrite input carries the full todo list — summarize by count rather
|
|
342
|
+
// than dumping truncated JSON.
|
|
343
|
+
if (Array.isArray(obj['todos']))
|
|
344
|
+
return `${obj['todos'].length} todos`;
|
|
345
|
+
for (const key of ['command', 'filePath', 'file_path', 'path', 'pattern', 'include', 'tool']) {
|
|
346
|
+
if (typeof obj[key] === 'string' && obj[key] !== '')
|
|
347
|
+
return obj[key];
|
|
348
|
+
}
|
|
349
|
+
return JSON.stringify(input).slice(0, 120);
|
|
350
|
+
}
|
|
351
|
+
// =============================================================================
|
|
352
|
+
// Cards
|
|
353
|
+
// =============================================================================
|
|
354
|
+
function formatTime(ts) {
|
|
355
|
+
if (!ts)
|
|
356
|
+
return '';
|
|
357
|
+
return new Date(ts).toLocaleTimeString([], {
|
|
358
|
+
hour: '2-digit',
|
|
359
|
+
minute: '2-digit',
|
|
360
|
+
second: '2-digit',
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function RawEventCard({ event, runCount, snapshotCount, expanded, onToggle, }) {
|
|
364
|
+
const { theme } = useTheme();
|
|
365
|
+
const kind = eventKind(event);
|
|
366
|
+
const d = dataOf(event);
|
|
367
|
+
const part = partOf(event);
|
|
368
|
+
const state = part?.state;
|
|
369
|
+
const color = kindColor(kind);
|
|
370
|
+
if (!event) {
|
|
371
|
+
return (_jsx("div", { style: {
|
|
372
|
+
display: 'flex',
|
|
373
|
+
alignItems: 'center',
|
|
374
|
+
gap: 8,
|
|
375
|
+
padding: '10px 14px',
|
|
376
|
+
borderRadius: 0,
|
|
377
|
+
minWidth: 0,
|
|
378
|
+
overflow: 'hidden',
|
|
379
|
+
border: '1px dashed #1f2937',
|
|
380
|
+
backgroundColor: '#0d1117',
|
|
381
|
+
fontFamily: theme.fonts.body,
|
|
382
|
+
fontSize: 12,
|
|
383
|
+
}, children: _jsx("span", { style: { color: '#4b5563', fontStyle: 'italic' }, children: "no raw payload" }) }));
|
|
384
|
+
}
|
|
385
|
+
const body = (() => {
|
|
386
|
+
switch (event.type) {
|
|
387
|
+
case 'session.created.1': {
|
|
388
|
+
const info = d.info;
|
|
389
|
+
return (_jsx(MetaRows, { rows: [
|
|
390
|
+
['agent', info?.agent],
|
|
391
|
+
['model', info?.model?.id ?? info?.model?.modelID],
|
|
392
|
+
['directory', info?.directory],
|
|
393
|
+
['version', info?.version],
|
|
394
|
+
['slug', info?.slug],
|
|
395
|
+
] }));
|
|
396
|
+
}
|
|
397
|
+
case 'session.updated.1': {
|
|
398
|
+
const info = d.info;
|
|
399
|
+
return (_jsx(MetaRows, { rows: [
|
|
400
|
+
['cost', typeof info?.cost === 'number' ? `$${info.cost.toFixed(4)}` : undefined],
|
|
401
|
+
['tokens', info?.tokens],
|
|
402
|
+
['title', info?.title],
|
|
403
|
+
] }));
|
|
404
|
+
}
|
|
405
|
+
case 'message.updated.1': {
|
|
406
|
+
const info = d.info;
|
|
407
|
+
return (_jsx(MetaRows, { rows: [
|
|
408
|
+
['role', info?.role],
|
|
409
|
+
['agent', info?.agent],
|
|
410
|
+
['model', info?.model],
|
|
411
|
+
['tokens', info?.tokens],
|
|
412
|
+
['messageID', info?.id],
|
|
413
|
+
] }));
|
|
414
|
+
}
|
|
415
|
+
case 'message.removed.1':
|
|
416
|
+
return _jsx(MetaRows, { rows: [['messageID', d.messageID]] });
|
|
417
|
+
case 'message.part.updated.1': {
|
|
418
|
+
switch (part?.type) {
|
|
419
|
+
case 'text':
|
|
420
|
+
case 'reasoning':
|
|
421
|
+
return _jsx(TextView, { text: part?.text });
|
|
422
|
+
case 'tool': {
|
|
423
|
+
const todos = state?.input?.['todos'];
|
|
424
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [_jsxs("div", { style: { fontSize: 12, color: '#9ca3af' }, children: ["callID ", String(part?.callID ?? ''), " \u00B7 ", String(state?.status ?? '')] }), Array.isArray(todos) ? _jsx(TodosView, { todos: todos }) : null, _jsx(ToolIO, { input: state?.input, output: state?.status === 'error' ? state?.error : state?.output })] }));
|
|
425
|
+
}
|
|
426
|
+
case 'step-start':
|
|
427
|
+
return _jsx(MetaRows, { rows: [['snapshot', part?.snapshot]] });
|
|
428
|
+
case 'step-finish':
|
|
429
|
+
return (_jsx(MetaRows, { rows: [
|
|
430
|
+
['reason', part?.reason],
|
|
431
|
+
['cost', typeof part?.cost === 'number' ? `$${part.cost.toFixed(4)}` : undefined],
|
|
432
|
+
['tokens', part?.tokens],
|
|
433
|
+
] }));
|
|
434
|
+
case 'patch':
|
|
435
|
+
return (_jsx(MetaRows, { rows: [
|
|
436
|
+
['files', part?.files],
|
|
437
|
+
['hash', part?.hash],
|
|
438
|
+
] }));
|
|
439
|
+
case 'compaction':
|
|
440
|
+
return (_jsx(MetaRows, { rows: [
|
|
441
|
+
['auto', typeof part?.auto === 'boolean' ? String(part.auto) : undefined],
|
|
442
|
+
['overflow', typeof part?.overflow === 'boolean' ? String(part.overflow) : undefined],
|
|
443
|
+
] }));
|
|
444
|
+
default:
|
|
445
|
+
return _jsx(JsonView, { value: d });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
default:
|
|
449
|
+
// Durable-agent raw blobs (Cursor store.db, etc.) have no V1 `data`
|
|
450
|
+
// envelope — dump the whole payload so the expanded card isn't empty.
|
|
451
|
+
return _jsx(JsonView, { value: isV1RawEvent(event) ? d : event });
|
|
452
|
+
}
|
|
453
|
+
})();
|
|
454
|
+
return (_jsxs("div", { style: {
|
|
455
|
+
display: 'flex',
|
|
456
|
+
flexDirection: 'column',
|
|
457
|
+
gap: expanded ? 8 : 0,
|
|
458
|
+
padding: '10px 14px',
|
|
459
|
+
borderRadius: 0,
|
|
460
|
+
minWidth: 0,
|
|
461
|
+
overflow: 'hidden',
|
|
462
|
+
backgroundColor: expanded ? '#111827' : '#161b26',
|
|
463
|
+
fontFamily: theme.fonts.body,
|
|
464
|
+
fontSize: 13,
|
|
465
|
+
}, children: [_jsxs("button", { onClick: onToggle, "aria-expanded": expanded, style: {
|
|
466
|
+
display: 'flex',
|
|
467
|
+
alignItems: 'center',
|
|
468
|
+
gap: 8,
|
|
469
|
+
width: '100%',
|
|
470
|
+
border: 'none',
|
|
471
|
+
background: 'none',
|
|
472
|
+
padding: 0,
|
|
473
|
+
cursor: 'pointer',
|
|
474
|
+
fontFamily: 'inherit',
|
|
475
|
+
textAlign: 'left',
|
|
476
|
+
}, children: [_jsxs("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: ["#", event.seq] }), _jsx("span", { style: {
|
|
477
|
+
fontSize: 11,
|
|
478
|
+
fontWeight: 600,
|
|
479
|
+
textTransform: 'uppercase',
|
|
480
|
+
letterSpacing: 0.5,
|
|
481
|
+
color,
|
|
482
|
+
whiteSpace: 'nowrap',
|
|
483
|
+
}, children: kindLabel(kind) }), runCount && runCount > 1 ? (_jsxs("span", { title: `${runCount} separate runs of this command`, style: {
|
|
484
|
+
fontSize: 11,
|
|
485
|
+
fontWeight: 700,
|
|
486
|
+
color: '#f59e0b',
|
|
487
|
+
whiteSpace: 'nowrap',
|
|
488
|
+
}, children: ["\u00D7", runCount] })) : null, snapshotCount && snapshotCount > 1 ? (_jsxs("span", { title: `${snapshotCount} raw event snapshots collapsed into this row`, style: {
|
|
489
|
+
fontSize: 11,
|
|
490
|
+
fontWeight: 600,
|
|
491
|
+
color: '#60a5fa',
|
|
492
|
+
whiteSpace: 'nowrap',
|
|
493
|
+
}, children: [snapshotCount, " events"] })) : null, _jsx("span", { style: {
|
|
494
|
+
flex: 1,
|
|
495
|
+
overflow: 'hidden',
|
|
496
|
+
textOverflow: 'ellipsis',
|
|
497
|
+
whiteSpace: 'nowrap',
|
|
498
|
+
color: '#e5e7eb',
|
|
499
|
+
}, children: describe(event) }), _jsx("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: formatTime(eventTimestamp(event)) })] }), expanded ? body : null] }));
|
|
500
|
+
}
|
|
501
|
+
function prettifyEventType(t) {
|
|
502
|
+
return (t ?? '').replace(/-/g, ' ');
|
|
503
|
+
}
|
|
504
|
+
function normalizedDescribe(n) {
|
|
505
|
+
if (n.toolName)
|
|
506
|
+
return [n.toolName, n.operation].filter(Boolean).join(' · ');
|
|
507
|
+
if (n.operation)
|
|
508
|
+
return n.operation;
|
|
509
|
+
const d = n.data;
|
|
510
|
+
if (typeof d?.message === 'string')
|
|
511
|
+
return d.message.slice(0, 90);
|
|
512
|
+
return prettifyEventType(n.eventType);
|
|
513
|
+
}
|
|
514
|
+
function repoLabel(repo) {
|
|
515
|
+
const identity = repo.owner && repo.repo ? `${repo.owner}/${repo.repo}` : repo.repo ?? '';
|
|
516
|
+
return identity && repo.root ? `${identity} @ ${repo.root}` : repo.root ?? '';
|
|
517
|
+
}
|
|
518
|
+
function NormalizedEventCard({ event, seq, color, expanded, onToggle, }) {
|
|
519
|
+
const { theme } = useTheme();
|
|
520
|
+
return (_jsxs("div", { style: {
|
|
521
|
+
display: 'flex',
|
|
522
|
+
flexDirection: 'column',
|
|
523
|
+
gap: expanded ? 8 : 0,
|
|
524
|
+
padding: '10px 14px',
|
|
525
|
+
borderRadius: 0,
|
|
526
|
+
minWidth: 0,
|
|
527
|
+
overflow: 'hidden',
|
|
528
|
+
backgroundColor: expanded ? '#0d1520' : '#101722',
|
|
529
|
+
fontFamily: theme.fonts.body,
|
|
530
|
+
fontSize: 13,
|
|
531
|
+
}, children: [_jsxs("button", { onClick: onToggle, "aria-expanded": expanded, style: {
|
|
532
|
+
display: 'flex',
|
|
533
|
+
alignItems: 'center',
|
|
534
|
+
gap: 8,
|
|
535
|
+
width: '100%',
|
|
536
|
+
border: 'none',
|
|
537
|
+
background: 'none',
|
|
538
|
+
padding: 0,
|
|
539
|
+
cursor: 'pointer',
|
|
540
|
+
fontFamily: 'inherit',
|
|
541
|
+
textAlign: 'left',
|
|
542
|
+
}, children: [_jsxs("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: ["#", seq] }), _jsx("span", { style: {
|
|
543
|
+
fontSize: 11,
|
|
544
|
+
fontWeight: 600,
|
|
545
|
+
textTransform: 'uppercase',
|
|
546
|
+
letterSpacing: 0.5,
|
|
547
|
+
color,
|
|
548
|
+
whiteSpace: 'nowrap',
|
|
549
|
+
}, children: prettifyEventType(event.eventType) }), _jsx("span", { style: {
|
|
550
|
+
flex: 1,
|
|
551
|
+
overflow: 'hidden',
|
|
552
|
+
textOverflow: 'ellipsis',
|
|
553
|
+
whiteSpace: 'nowrap',
|
|
554
|
+
color: '#e5e7eb',
|
|
555
|
+
}, children: normalizedDescribe(event) }), _jsx("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: formatTime(event.timestamp) })] }), expanded ? (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [_jsx(MetaRows, { rows: [
|
|
556
|
+
['eventType', event.eventType],
|
|
557
|
+
['operation', event.operation],
|
|
558
|
+
['toolName', event.toolName],
|
|
559
|
+
['sessionId', event.sessionId],
|
|
560
|
+
['workingDir', event.normalizedWorkingDirectory],
|
|
561
|
+
['repository', event.repository ? repoLabel(event.repository) : undefined],
|
|
562
|
+
] }), event.files && event.files.length > 0 ? (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs("div", { style: { fontSize: 11, color: '#6b7280' }, children: ["files (", event.files.length, ")"] }), event.files.map((file, i) => (_jsx(FileRow, { file: file }, i)))] })) : null, event.toolInput !== undefined ? (_jsx(ToolIO, { input: event.toolInput, output: event.toolOutput })) : null] })) : null] }));
|
|
563
|
+
}
|
|
564
|
+
function FileRow({ file }) {
|
|
565
|
+
const { theme } = useTheme();
|
|
566
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx("div", { style: {
|
|
567
|
+
color: '#93c5fd',
|
|
568
|
+
fontSize: 12,
|
|
569
|
+
wordBreak: 'break-word',
|
|
570
|
+
fontFamily: theme.fonts.monospace,
|
|
571
|
+
}, children: file.displayPath }), _jsxs("div", { style: { color: '#6b7280', fontSize: 11, wordBreak: 'break-word' }, children: [file.context, file.repository
|
|
572
|
+
? ` · ${file.repository.gitRoot} → ${file.repository.relativePath}`
|
|
573
|
+
: ` · ${file.absolutePath}`] })] }));
|
|
574
|
+
}
|
|
575
|
+
const OPERATION_COLORS = {
|
|
576
|
+
starting: '#6b7280',
|
|
577
|
+
prompting: '#a78bfa',
|
|
578
|
+
reading: '#a855f7',
|
|
579
|
+
grepping: '#e879f9',
|
|
580
|
+
globbing: '#14b8a6',
|
|
581
|
+
listing: '#f97316',
|
|
582
|
+
editing: '#22c55e',
|
|
583
|
+
tool: '#3b82f6',
|
|
584
|
+
errored: '#ef4444',
|
|
585
|
+
waiting: '#9ca3af',
|
|
586
|
+
finished: '#10b981',
|
|
587
|
+
compacting: '#ec4899',
|
|
588
|
+
subagent: '#f59e0b',
|
|
589
|
+
};
|
|
590
|
+
function AccumulatedEventCard({ event, seq, dropReason, expanded, onToggle, }) {
|
|
591
|
+
const { theme } = useTheme();
|
|
592
|
+
if (!event) {
|
|
593
|
+
return (_jsxs("div", { style: {
|
|
594
|
+
display: 'flex',
|
|
595
|
+
alignItems: 'center',
|
|
596
|
+
gap: 8,
|
|
597
|
+
padding: '10px 14px',
|
|
598
|
+
borderRadius: 0,
|
|
599
|
+
minWidth: 0,
|
|
600
|
+
overflow: 'hidden',
|
|
601
|
+
border: '1px dashed #1f2937',
|
|
602
|
+
backgroundColor: '#0d1117',
|
|
603
|
+
fontFamily: theme.fonts.body,
|
|
604
|
+
fontSize: 12,
|
|
605
|
+
}, children: [_jsxs("span", { style: { color: '#374151', whiteSpace: 'nowrap' }, children: ["#", seq] }), _jsx("span", { style: { color: dropReason ? '#b45309' : '#4b5563', fontStyle: 'italic' }, children: dropReason ?? 'no UI event (accumulator dropped)' })] }));
|
|
606
|
+
}
|
|
607
|
+
const opColor = OPERATION_COLORS[event.operation] ?? '#6b7280';
|
|
608
|
+
return (_jsxs("div", { style: {
|
|
609
|
+
display: 'flex',
|
|
610
|
+
flexDirection: 'column',
|
|
611
|
+
gap: expanded ? 8 : 0,
|
|
612
|
+
padding: '10px 14px',
|
|
613
|
+
borderRadius: 0,
|
|
614
|
+
minWidth: 0,
|
|
615
|
+
overflow: 'hidden',
|
|
616
|
+
backgroundColor: expanded ? '#121a13' : '#141b16',
|
|
617
|
+
fontFamily: theme.fonts.body,
|
|
618
|
+
fontSize: 13,
|
|
619
|
+
}, children: [_jsxs("button", { onClick: onToggle, "aria-expanded": expanded, style: {
|
|
620
|
+
display: 'flex',
|
|
621
|
+
alignItems: 'center',
|
|
622
|
+
gap: 8,
|
|
623
|
+
width: '100%',
|
|
624
|
+
border: 'none',
|
|
625
|
+
background: 'none',
|
|
626
|
+
padding: 0,
|
|
627
|
+
cursor: 'pointer',
|
|
628
|
+
fontFamily: 'inherit',
|
|
629
|
+
textAlign: 'left',
|
|
630
|
+
}, children: [_jsx("span", { style: {
|
|
631
|
+
width: 8,
|
|
632
|
+
height: 8,
|
|
633
|
+
borderRadius: '50%',
|
|
634
|
+
flexShrink: 0,
|
|
635
|
+
backgroundColor: event.sessionColor,
|
|
636
|
+
} }), _jsxs("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: ["#", seq] }), _jsx("span", { style: {
|
|
637
|
+
fontSize: 11,
|
|
638
|
+
fontWeight: 600,
|
|
639
|
+
textTransform: 'uppercase',
|
|
640
|
+
letterSpacing: 0.5,
|
|
641
|
+
color: opColor,
|
|
642
|
+
whiteSpace: 'nowrap',
|
|
643
|
+
}, children: event.operation }), _jsx("span", { style: {
|
|
644
|
+
flex: 1,
|
|
645
|
+
overflow: 'hidden',
|
|
646
|
+
textOverflow: 'ellipsis',
|
|
647
|
+
whiteSpace: 'nowrap',
|
|
648
|
+
color: '#e5e7eb',
|
|
649
|
+
}, children: event.description }), _jsx("span", { style: { color: '#6b7280', fontSize: 11, whiteSpace: 'nowrap' }, children: formatTime(event.timestamp) })] }), expanded ? (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [_jsx(MetaRows, { rows: [
|
|
650
|
+
['operation', event.operation],
|
|
651
|
+
['session', event.sessionName],
|
|
652
|
+
['contextTokens', event.contextTokens],
|
|
653
|
+
['toolName', event.toolName],
|
|
654
|
+
['subagent', event.subagentType],
|
|
655
|
+
['childSessionId', event.childSessionId],
|
|
656
|
+
] }), _jsx("div", { style: { fontSize: 12, color: '#6b7280' }, children: event.description }), event.files.length > 0 ? _jsx(PathList, { label: "files", paths: event.files }) : null, event.dependencies.length > 0 ? (_jsx(PathList, { label: "dependencies", paths: event.dependencies })) : null, event.layers.length > 0 ? (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx("div", { style: { fontSize: 11, color: '#6b7280' }, children: "layers" }), event.layers.map((layer) => (_jsxs("div", { style: { display: 'flex', gap: 6, alignItems: 'center', fontSize: 12 }, children: [_jsx("span", { style: {
|
|
657
|
+
width: 8,
|
|
658
|
+
height: 8,
|
|
659
|
+
borderRadius: '50%',
|
|
660
|
+
backgroundColor: layer.color,
|
|
661
|
+
opacity: 0.8,
|
|
662
|
+
} }), _jsxs("span", { style: { color: '#d1d5db' }, children: [layer.name, " (", layer.items.length, ")"] })] }, layer.id)))] })) : null] })) : null] }));
|
|
663
|
+
}
|
|
664
|
+
function PathList({ label, paths }) {
|
|
665
|
+
const { theme } = useTheme();
|
|
666
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx("div", { style: { fontSize: 11, color: '#6b7280' }, children: label }), paths.map((p, i) => (_jsx("div", { style: { color: '#93c5fd', fontSize: 11.5, fontFamily: theme.fonts.monospace, wordBreak: 'break-word' }, children: p.displayPath }, i)))] }));
|
|
667
|
+
}
|
|
668
|
+
function TextView({ text }) {
|
|
669
|
+
if (!text)
|
|
670
|
+
return _jsx("div", { style: { color: '#6b7280', fontSize: 12 }, children: "(empty)" });
|
|
671
|
+
return (_jsx("div", { style: {
|
|
672
|
+
color: '#d1d5db',
|
|
673
|
+
fontSize: 12.5,
|
|
674
|
+
lineHeight: 1.5,
|
|
675
|
+
maxHeight: 120,
|
|
676
|
+
overflowY: 'auto',
|
|
677
|
+
whiteSpace: 'pre-wrap',
|
|
678
|
+
wordBreak: 'break-word',
|
|
679
|
+
}, children: text }));
|
|
680
|
+
}
|
|
681
|
+
const TODO_STATUS_COLORS = {
|
|
682
|
+
completed: '#22c55e',
|
|
683
|
+
in_progress: '#f59e0b',
|
|
684
|
+
pending: '#6b7280',
|
|
685
|
+
};
|
|
686
|
+
function TodosView({ todos }) {
|
|
687
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs("div", { style: { fontSize: 11, color: '#6b7280' }, children: ["todos (", todos.length, ")"] }), todos.map((t, i) => (_jsxs("div", { style: { display: 'flex', gap: 8, fontSize: 12, alignItems: 'baseline' }, children: [_jsx("span", { style: {
|
|
688
|
+
color: TODO_STATUS_COLORS[String(t.status ?? '')] ?? '#6b7280',
|
|
689
|
+
fontWeight: 600,
|
|
690
|
+
minWidth: 84,
|
|
691
|
+
whiteSpace: 'nowrap',
|
|
692
|
+
}, children: String(t.status ?? '') }), _jsx("span", { style: { color: '#d1d5db', wordBreak: 'break-word' }, children: String(t.content ?? '') }), typeof t.priority === 'string' && t.priority ? (_jsxs("span", { style: { color: '#6b7280', whiteSpace: 'nowrap' }, children: ["\u00B7 ", t.priority] })) : null] }, i)))] }));
|
|
693
|
+
}
|
|
694
|
+
function ToolIO({ input, output }) {
|
|
695
|
+
const summary = toolSummary(input);
|
|
696
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: [summary ? (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("span", { style: { fontSize: 11, color: '#60a5fa', fontWeight: 600 }, children: "IN" }), _jsx("code", { style: { color: '#93c5fd', fontSize: 12, wordBreak: 'break-word' }, children: summary })] })) : null, input !== undefined && input !== null && typeof input === 'object' ? (_jsx(CodeBlock, { value: JSON.stringify(input, null, 2) })) : null, output !== undefined && output !== null ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("span", { style: { fontSize: 11, color: '#34d399', fontWeight: 600 }, children: "OUT" }), _jsx("span", { style: { fontSize: 11, color: '#6b7280' }, children: typeof output === 'string' ? `${output.length.toLocaleString()} chars` : 'object' })] }), _jsx(CodeBlock, { value: typeof output === 'string' ? output : JSON.stringify(output, null, 2) })] })) : null] }));
|
|
697
|
+
}
|
|
698
|
+
function CodeBlock({ value }) {
|
|
699
|
+
return (_jsx("pre", { style: {
|
|
700
|
+
margin: 0,
|
|
701
|
+
padding: 8,
|
|
702
|
+
borderRadius: 6,
|
|
703
|
+
backgroundColor: '#0b1220',
|
|
704
|
+
color: '#9ca3af',
|
|
705
|
+
fontSize: 11.5,
|
|
706
|
+
lineHeight: 1.45,
|
|
707
|
+
maxHeight: 180,
|
|
708
|
+
overflow: 'auto',
|
|
709
|
+
whiteSpace: 'pre-wrap',
|
|
710
|
+
wordBreak: 'break-word',
|
|
711
|
+
}, children: value }));
|
|
712
|
+
}
|
|
713
|
+
function MetaRows({ rows }) {
|
|
714
|
+
const present = rows.filter(([, v]) => v !== undefined && v !== null && v !== '');
|
|
715
|
+
if (present.length === 0)
|
|
716
|
+
return null;
|
|
717
|
+
return (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 3 }, children: present.map(([label, value]) => (_jsxs("div", { style: { display: 'flex', gap: 8, fontSize: 12 }, children: [_jsx("span", { style: { color: '#6b7280', minWidth: 76, whiteSpace: 'nowrap' }, children: label }), _jsx("span", { style: {
|
|
718
|
+
color: '#d1d5db',
|
|
719
|
+
wordBreak: 'break-word',
|
|
720
|
+
whiteSpace: typeof value === 'string' ? 'pre-wrap' : 'nowrap',
|
|
721
|
+
}, children: typeof value === 'string'
|
|
722
|
+
? value
|
|
723
|
+
: Array.isArray(value)
|
|
724
|
+
? value.join(', ')
|
|
725
|
+
: JSON.stringify(value) })] }, label))) }));
|
|
726
|
+
}
|
|
727
|
+
function JsonView({ value }) {
|
|
728
|
+
return _jsx(CodeBlock, { value: JSON.stringify(value, null, 2) });
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Why the accumulator dropped a row's UI event, derived from the raw event
|
|
732
|
+
* alone (no stream context needed). Rows that don't match a known category keep
|
|
733
|
+
* the generic "dropped" label.
|
|
734
|
+
*/
|
|
735
|
+
function dropReasonFor(raw) {
|
|
736
|
+
if (!raw)
|
|
737
|
+
return null;
|
|
738
|
+
if (raw.type === 'message.updated.1') {
|
|
739
|
+
const role = dataOf(raw).info?.role;
|
|
740
|
+
if (role === 'assistant') {
|
|
741
|
+
return 'assistant message — metadata only (feeds context/token tracking)';
|
|
742
|
+
}
|
|
743
|
+
return null; // user messages are handled by the re-save pass below
|
|
744
|
+
}
|
|
745
|
+
if (raw.type === 'message.removed.1')
|
|
746
|
+
return 'message removed — no UI event';
|
|
747
|
+
if (raw.type === 'message.part.updated.1') {
|
|
748
|
+
switch (partOf(raw)?.type) {
|
|
749
|
+
case 'reasoning':
|
|
750
|
+
return 'model reasoning — not surfaced in the UI';
|
|
751
|
+
case 'step-start':
|
|
752
|
+
case 'step-finish':
|
|
753
|
+
return 'step lifecycle — not surfaced in the UI';
|
|
754
|
+
case 'text':
|
|
755
|
+
return 'text content — not surfaced in the UI';
|
|
756
|
+
case 'tool':
|
|
757
|
+
return 'tool snapshot — folded into the tool run';
|
|
758
|
+
default:
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Annotate rows the accumulator drops with *why* they were dropped, walking in
|
|
766
|
+
* stream order. opencode re-saves a user message on every change (seq 1, 6, 24,
|
|
767
|
+
* 39, 51… share one messageID), so the first occurrence becomes the `prompting`
|
|
768
|
+
* UI event and every re-save is deduped away — those read "re-save, ignored"
|
|
769
|
+
* instead of a generic "dropped".
|
|
770
|
+
*/
|
|
771
|
+
function annotateDrops(items) {
|
|
772
|
+
const seenUserMessageIDs = new Set();
|
|
773
|
+
return items.map((item) => {
|
|
774
|
+
const raw = toRaw(item.raw);
|
|
775
|
+
if (!raw)
|
|
776
|
+
return item;
|
|
777
|
+
// Track user message IDs on every occurrence — the first one is the real
|
|
778
|
+
// prompt (it carries the accumulated UI event); later re-saves are deduped.
|
|
779
|
+
if (raw.type === 'message.updated.1') {
|
|
780
|
+
const info = dataOf(raw).info;
|
|
781
|
+
const messageID = info?.id;
|
|
782
|
+
const role = info?.role;
|
|
783
|
+
if (typeof messageID === 'string' && role === 'user') {
|
|
784
|
+
if (seenUserMessageIDs.has(messageID)) {
|
|
785
|
+
if (item.accumulated === null) {
|
|
786
|
+
return {
|
|
787
|
+
...item,
|
|
788
|
+
dropReason: 're-save of user message — already counted as a prompt',
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
return item;
|
|
792
|
+
}
|
|
793
|
+
seenUserMessageIDs.add(messageID);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (item.accumulated !== null)
|
|
797
|
+
return item;
|
|
798
|
+
const reason = dropReasonFor(raw);
|
|
799
|
+
if (reason)
|
|
800
|
+
return { ...item, dropReason: reason };
|
|
801
|
+
return item;
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Collapse a tool invocation's snapshots into a single row. The raw V1 stream
|
|
806
|
+
* emits one part update per status flip (pending → running → completed) — and
|
|
807
|
+
* those flips can be interleaved with other events (reasoning, text, session
|
|
808
|
+
* bookkeeping) — so snapshots are matched by callID across the whole stream,
|
|
809
|
+
* not just when consecutive. Distinct calls that repeat the same command and
|
|
810
|
+
* are consecutive still fold into one ×N row.
|
|
811
|
+
*
|
|
812
|
+
* The merged row keeps the run's first seq as a stable key and adopts the
|
|
813
|
+
* **latest** snapshot's raw/normalized payload (the completed/errored part
|
|
814
|
+
* carries the tool output). The UI (accumulated) column instead prefers the
|
|
815
|
+
* group's one non-null accumulated event — the accumulator dedupes to at most
|
|
816
|
+
* one per invocation, and it's usually the *first* snapshot (e.g. todowrite's
|
|
817
|
+
* pending emits the `tool` event; running/completed are dropped).
|
|
818
|
+
*/
|
|
819
|
+
function groupToolRuns(items) {
|
|
820
|
+
const out = [];
|
|
821
|
+
const byCallID = new Map();
|
|
822
|
+
let lastGroup = null;
|
|
823
|
+
let lastGroupCmd = null;
|
|
824
|
+
const adopt = (group, r, cmd) => {
|
|
825
|
+
group.snapshotCount = (group.snapshotCount ?? 1) + 1;
|
|
826
|
+
group.raw = r.raw;
|
|
827
|
+
group.normalized = r.normalized;
|
|
828
|
+
const acc = r.accumulated;
|
|
829
|
+
if (acc !== null) {
|
|
830
|
+
// Prefer the run's meaningful accumulated. The pending snapshot of a
|
|
831
|
+
// bash `ls` (empty input) emits a generic `tool` before the completed
|
|
832
|
+
// snapshot's `listing` arrives — replace a generic `tool` with a more
|
|
833
|
+
// specific operation, and never downgrade a specific one.
|
|
834
|
+
if (group.accumulated === null ||
|
|
835
|
+
(group.accumulated.operation === 'tool' && acc.operation !== 'tool')) {
|
|
836
|
+
group.accumulated = acc;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
group.type = r.type;
|
|
840
|
+
lastGroup = group;
|
|
841
|
+
lastGroupCmd = cmd;
|
|
842
|
+
};
|
|
843
|
+
for (const r of items) {
|
|
844
|
+
const raw = toRaw(r.raw);
|
|
845
|
+
const isTool = !!raw && raw.type === 'message.part.updated.1' && partOf(raw)?.type === 'tool';
|
|
846
|
+
const part = partOf(raw);
|
|
847
|
+
const cmd = isTool
|
|
848
|
+
? toolSummary(part?.state?.input)
|
|
849
|
+
: null;
|
|
850
|
+
const callID = isTool ? part?.callID : undefined;
|
|
851
|
+
if (!isTool) {
|
|
852
|
+
out.push(r);
|
|
853
|
+
lastGroup = null;
|
|
854
|
+
lastGroupCmd = null;
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
// Same invocation — fold this status snapshot in wherever it appears.
|
|
858
|
+
const existing = callID ? byCallID.get(callID) : undefined;
|
|
859
|
+
if (existing) {
|
|
860
|
+
adopt(existing, r, cmd);
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
// A distinct call repeating the previous group's command folds into it.
|
|
864
|
+
if (lastGroup && cmd !== null && cmd !== '' && cmd === lastGroupCmd) {
|
|
865
|
+
if (callID) {
|
|
866
|
+
lastGroup.callIDs = lastGroup.callIDs ?? new Set();
|
|
867
|
+
lastGroup.callIDs.add(callID);
|
|
868
|
+
byCallID.set(callID, lastGroup);
|
|
869
|
+
}
|
|
870
|
+
lastGroup.runCount = lastGroup.callIDs ? lastGroup.callIDs.size : 1;
|
|
871
|
+
adopt(lastGroup, r, cmd);
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
const group = {
|
|
875
|
+
...r,
|
|
876
|
+
runCount: 1,
|
|
877
|
+
snapshotCount: 1,
|
|
878
|
+
callIDs: new Set(callID ? [callID] : []),
|
|
879
|
+
};
|
|
880
|
+
if (callID)
|
|
881
|
+
byCallID.set(callID, group);
|
|
882
|
+
out.push(group);
|
|
883
|
+
lastGroup = group;
|
|
884
|
+
lastGroupCmd = cmd;
|
|
885
|
+
}
|
|
886
|
+
return out;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Fold a user message's events into a single row keyed by messageID: the
|
|
890
|
+
* original `message.updated.1` (which carries the `prompting` accumulated
|
|
891
|
+
* event), every re-save of the same message (opencode re-saves a user message
|
|
892
|
+
* on each change), and the text part(s) that carry its content (the
|
|
893
|
+
* `notification` events sharing the same messageID). They all resolve to the
|
|
894
|
+
* one `prompting` accumulated event, so they render as one row with a snapshot
|
|
895
|
+
* count instead of a wall of "re-save" rows.
|
|
896
|
+
*/
|
|
897
|
+
function groupPromptParts(items) {
|
|
898
|
+
const out = [];
|
|
899
|
+
const byMessageID = new Map();
|
|
900
|
+
for (const item of items) {
|
|
901
|
+
const raw = toRaw(item.raw);
|
|
902
|
+
if (!raw) {
|
|
903
|
+
out.push(item);
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
if (raw.type === 'message.updated.1') {
|
|
907
|
+
const info = dataOf(raw).info;
|
|
908
|
+
const messageID = info?.id;
|
|
909
|
+
const role = info?.role;
|
|
910
|
+
if (typeof messageID === 'string' && role === 'user') {
|
|
911
|
+
const existing = byMessageID.get(messageID);
|
|
912
|
+
if (existing) {
|
|
913
|
+
// re-save of the same user message — fold into its prompt row
|
|
914
|
+
existing.snapshotCount = (existing.snapshotCount ?? 1) + 1;
|
|
915
|
+
if (existing.accumulated === null && item.accumulated !== null) {
|
|
916
|
+
existing.accumulated = item.accumulated;
|
|
917
|
+
}
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
byMessageID.set(messageID, item);
|
|
921
|
+
}
|
|
922
|
+
out.push(item);
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
if (raw.type === 'message.part.updated.1') {
|
|
926
|
+
const part = partOf(raw);
|
|
927
|
+
const messageID = part?.messageID;
|
|
928
|
+
if (part?.type === 'text' && typeof messageID === 'string') {
|
|
929
|
+
const existing = byMessageID.get(messageID);
|
|
930
|
+
if (existing) {
|
|
931
|
+
existing.snapshotCount = (existing.snapshotCount ?? 1) + 1;
|
|
932
|
+
if (existing.accumulated === null && item.accumulated !== null) {
|
|
933
|
+
existing.accumulated = item.accumulated;
|
|
934
|
+
}
|
|
935
|
+
continue; // absorb the text part into its message row
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
out.push(item);
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
out.push(item);
|
|
942
|
+
}
|
|
943
|
+
return out;
|
|
944
|
+
}
|
|
945
|
+
export function SessionEventFeed({ title, rows }) {
|
|
946
|
+
const { theme } = useTheme();
|
|
947
|
+
const items = useMemo(() => [...rows].sort((a, b) => a.seq - b.seq), [rows]);
|
|
948
|
+
const [active, setActive] = useState('activity');
|
|
949
|
+
const [groupTools, setGroupTools] = useState(true);
|
|
950
|
+
const displayItems = useMemo(() => annotateDrops(groupPromptParts(groupTools ? groupToolRuns(items) : items)), [items, groupTools]);
|
|
951
|
+
const seqs = useMemo(() => displayItems.map((r) => r.seq), [displayItems]);
|
|
952
|
+
const { collapsed, toggle, setAll } = useCollapse(seqs, true);
|
|
953
|
+
const activePreset = PRESETS.find((p) => p.id === active) ?? PRESETS[0];
|
|
954
|
+
// "Generic tools" surfaces the improvement backlog: tool rows whose
|
|
955
|
+
// accumulated operation is still the generic `tool` fallback (e.g. bash
|
|
956
|
+
// commands that haven't been given a listing/reading/… type yet).
|
|
957
|
+
const [unprocessedOnly, setUnprocessedOnly] = useState(false);
|
|
958
|
+
const isVisible = (r) => unprocessedOnly
|
|
959
|
+
? r.accumulated?.operation === 'tool'
|
|
960
|
+
: activePreset.include.includes(eventCategory(toRaw(r.raw)));
|
|
961
|
+
const visibleEvents = displayItems.filter(isVisible);
|
|
962
|
+
const presetCounts = useMemo(() => {
|
|
963
|
+
const map = new Map();
|
|
964
|
+
for (const preset of PRESETS) {
|
|
965
|
+
map.set(preset.id, displayItems.filter((r) => preset.include.includes(eventCategory(toRaw(r.raw)))).length);
|
|
966
|
+
}
|
|
967
|
+
return map;
|
|
968
|
+
}, [displayItems]);
|
|
969
|
+
const unprocessedCount = useMemo(() => displayItems.filter((r) => r.accumulated?.operation === 'tool').length, [displayItems]);
|
|
970
|
+
const expandedCount = visibleEvents.filter((r) => !collapsed.has(r.seq)).length;
|
|
971
|
+
return (_jsxs("div", { style: { padding: 24, backgroundColor: '#0d1117', minHeight: '100vh' }, children: [_jsxs("div", { style: {
|
|
972
|
+
display: 'flex',
|
|
973
|
+
alignItems: 'baseline',
|
|
974
|
+
gap: 12,
|
|
975
|
+
marginBottom: 4,
|
|
976
|
+
fontFamily: theme.fonts.body,
|
|
977
|
+
}, children: [_jsx("h1", { style: { margin: 0, color: '#f3f4f6', fontSize: 18, fontWeight: 600 }, children: title }), _jsxs("span", { style: { color: '#6b7280', fontSize: 12 }, children: [items.length, " raw events \u00B7 ", visibleEvents.length, " visible \u00B7 ", expandedCount, " expanded"] })] }), _jsxs("div", { style: {
|
|
978
|
+
display: 'flex',
|
|
979
|
+
gap: 6,
|
|
980
|
+
flexWrap: 'wrap',
|
|
981
|
+
marginBottom: 16,
|
|
982
|
+
fontFamily: theme.fonts.body,
|
|
983
|
+
}, children: [_jsx(FilterChip, { label: "all", active: active === 'all', onClick: () => setActive('all') }), PRESETS.filter((p) => p.id !== 'all').map((preset) => (_jsx(FilterChip, { label: `${preset.label} (${presetCounts.get(preset.id) ?? 0})`, active: active === preset.id, onClick: () => setActive(preset.id) }, preset.id))), _jsx("span", { style: { flex: 1 } }), _jsx(FilterChip, { label: `Generic tools (${unprocessedCount})`, active: unprocessedOnly, onClick: () => setUnprocessedOnly((v) => !v) }), _jsx(FilterChip, { label: groupTools ? 'Group tool runs: on' : 'Group tool runs: off', active: groupTools, onClick: () => setGroupTools((v) => !v) }), _jsx(FilterChip, { label: "Expand all", active: false, onClick: () => setAll(false) }), _jsx(FilterChip, { label: "Collapse all", active: false, onClick: () => setAll(true) })] }), _jsx(ColumnHeaders, {}), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: displayItems.map((r) => (_jsx(EventRow, { row: r, sessionTitle: title, runCount: r.runCount, snapshotCount: r.snapshotCount, visible: isVisible(r), expanded: !collapsed.has(r.seq), onToggle: () => toggle(r.seq) }, r.seq))) })] }));
|
|
984
|
+
}
|
|
985
|
+
export function SessionEventFeedGrouped({ title, rows }) {
|
|
986
|
+
const { theme } = useTheme();
|
|
987
|
+
const items = useMemo(() => annotateDrops(groupPromptParts([...rows].sort((a, b) => a.seq - b.seq))), [rows]);
|
|
988
|
+
const byKind = useMemo(() => {
|
|
989
|
+
const map = new Map();
|
|
990
|
+
for (const r of items) {
|
|
991
|
+
const kind = eventKind(toRaw(r.raw));
|
|
992
|
+
map.set(kind, [...(map.get(kind) ?? []), r]);
|
|
993
|
+
}
|
|
994
|
+
return map;
|
|
995
|
+
}, [items]);
|
|
996
|
+
return (_jsxs("div", { style: { padding: 24, backgroundColor: '#0d1117', minHeight: '100vh' }, children: [title ? (_jsx("h1", { style: { margin: '0 0 12px', color: '#f3f4f6', fontSize: 18, fontWeight: 600, fontFamily: theme.fonts.body }, children: title })) : null, _jsx(ColumnHeaders, {}), Array.from(byKind.entries())
|
|
997
|
+
.sort((a, b) => b[1].length - a[1].length)
|
|
998
|
+
.map(([kind, group]) => (_jsx(GroupSection, { kind: kind, group: group, sessionTitle: title }, kind)))] }));
|
|
999
|
+
}
|
|
1000
|
+
function GroupSection({ kind, group, sessionTitle, }) {
|
|
1001
|
+
const { theme } = useTheme();
|
|
1002
|
+
const seqs = useMemo(() => group.map((r) => r.seq), [group]);
|
|
1003
|
+
const { collapsed, toggle, setAll } = useCollapse(seqs, true);
|
|
1004
|
+
return (_jsxs("div", { style: { marginBottom: 20 }, children: [_jsxs("div", { style: {
|
|
1005
|
+
display: 'flex',
|
|
1006
|
+
alignItems: 'center',
|
|
1007
|
+
gap: 8,
|
|
1008
|
+
marginBottom: 8,
|
|
1009
|
+
fontFamily: theme.fonts.body,
|
|
1010
|
+
}, children: [_jsx("span", { style: { color: kindColor(kind), fontWeight: 600, fontSize: 13 }, children: kindLabel(kind) }), _jsx("span", { style: { color: '#6b7280', fontSize: 12 }, children: group.length }), _jsx("span", { style: { flex: 1 } }), _jsx(FilterChip, { label: "Expand all", active: false, onClick: () => setAll(false) }), _jsx(FilterChip, { label: "Collapse all", active: false, onClick: () => setAll(true) })] }), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: group.map((r) => (_jsx(EventRow, { row: r, sessionTitle: sessionTitle, visible: true, expanded: !collapsed.has(r.seq), onToggle: () => toggle(r.seq) }, r.seq))) })] }));
|
|
1011
|
+
}
|
|
1012
|
+
function ColumnHeaders() {
|
|
1013
|
+
const { theme } = useTheme();
|
|
1014
|
+
return (_jsxs("div", { style: {
|
|
1015
|
+
position: 'sticky',
|
|
1016
|
+
top: 0,
|
|
1017
|
+
zIndex: 10,
|
|
1018
|
+
display: 'grid',
|
|
1019
|
+
gridTemplateColumns: '3px 1fr 1fr 1fr 28px',
|
|
1020
|
+
gap: 8,
|
|
1021
|
+
padding: '8px 14px',
|
|
1022
|
+
marginBottom: 8,
|
|
1023
|
+
backgroundColor: '#0d1117',
|
|
1024
|
+
borderBottom: '1px solid #1f2937',
|
|
1025
|
+
fontFamily: theme.fonts.body,
|
|
1026
|
+
}, children: [_jsx("span", {}), _jsx(HeaderLabel, { children: "Raw event" }), _jsx(HeaderLabel, { children: "Repo-normalized" }), _jsx(HeaderLabel, { children: "UI event (accumulated)" }), _jsx("span", {})] }));
|
|
1027
|
+
}
|
|
1028
|
+
function HeaderLabel({ children }) {
|
|
1029
|
+
return (_jsx("span", { style: {
|
|
1030
|
+
fontSize: 11,
|
|
1031
|
+
fontWeight: 600,
|
|
1032
|
+
textTransform: 'uppercase',
|
|
1033
|
+
letterSpacing: 0.5,
|
|
1034
|
+
color: '#9ca3af',
|
|
1035
|
+
}, children: children }));
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Assemble a self-contained, discussion-ready text block for one row: enough
|
|
1039
|
+
* identifiers and detail (session, seq, raw → normalized → UI) that the block
|
|
1040
|
+
* carries the whole issue without the viewer open. Paste this into a chat, an
|
|
1041
|
+
* agent conversation, or an issue to talk about the event.
|
|
1042
|
+
*/
|
|
1043
|
+
function buildRowContext(row, sessionTitle) {
|
|
1044
|
+
const raw = toRaw(row.raw);
|
|
1045
|
+
const d = dataOf(raw);
|
|
1046
|
+
const part = partOf(raw);
|
|
1047
|
+
const state = part?.state;
|
|
1048
|
+
const normalized = toNormalized(row.normalized);
|
|
1049
|
+
const acc = row.accumulated;
|
|
1050
|
+
const lines = [];
|
|
1051
|
+
const runCount = row.runCount;
|
|
1052
|
+
const snapshotCount = row.snapshotCount;
|
|
1053
|
+
const runLabel = runCount && runCount > 1 ? ` ×${runCount} runs` : '';
|
|
1054
|
+
const snapLabel = snapshotCount && snapshotCount > 1 ? ` · ${snapshotCount} snapshots collapsed` : '';
|
|
1055
|
+
lines.push(`## Event #${row.seq} — ${kindLabel(eventKind(raw))}${runLabel}${snapLabel}`);
|
|
1056
|
+
lines.push(`_${formatTime(eventTimestamp(raw))} · \`${row.type}\`_`);
|
|
1057
|
+
lines.push('');
|
|
1058
|
+
if (sessionTitle)
|
|
1059
|
+
lines.push(`**Session:** ${sessionTitle}`);
|
|
1060
|
+
const sessionID = d.sessionID ?? normalized?.sessionId ?? acc?.sessionId;
|
|
1061
|
+
if (sessionID)
|
|
1062
|
+
lines.push(`Session id: \`${sessionID}\``);
|
|
1063
|
+
lines.push('');
|
|
1064
|
+
lines.push('**Raw:**');
|
|
1065
|
+
if (!raw) {
|
|
1066
|
+
lines.push('- no raw payload');
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
lines.push(`- event type: \`${raw.type}\``);
|
|
1070
|
+
if (typeof part?.type === 'string')
|
|
1071
|
+
lines.push(`- part type: \`${part.type}\``);
|
|
1072
|
+
if (typeof part?.callID === 'string')
|
|
1073
|
+
lines.push(`- callID: \`${part.callID}\``);
|
|
1074
|
+
if (typeof part?.tool === 'string')
|
|
1075
|
+
lines.push(`- tool: \`${part.tool}\``);
|
|
1076
|
+
if (typeof state?.status === 'string')
|
|
1077
|
+
lines.push(`- status: \`${state.status}\``);
|
|
1078
|
+
const inSummary = toolSummary(state?.input);
|
|
1079
|
+
if (inSummary)
|
|
1080
|
+
lines.push(`- input: \`${inSummary}\``);
|
|
1081
|
+
const out = state?.status === 'error' ? state?.error : state?.output;
|
|
1082
|
+
if (typeof out === 'string') {
|
|
1083
|
+
const preview = out.length > 500 ? `${out.slice(0, 500)}\n…[+${out.length - 500} chars]` : out;
|
|
1084
|
+
lines.push(`- output (${out.length.toLocaleString()} chars):\n\`\`\`\n${preview}\n\`\`\``);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
lines.push('');
|
|
1088
|
+
if (normalized && typeof normalized.eventType === 'string') {
|
|
1089
|
+
lines.push('**Normalized:**');
|
|
1090
|
+
lines.push(`- eventType: \`${normalized.eventType}\``);
|
|
1091
|
+
if (typeof normalized.operation === 'string' && normalized.operation) {
|
|
1092
|
+
lines.push(`- operation: \`${normalized.operation}\``);
|
|
1093
|
+
}
|
|
1094
|
+
if (typeof normalized.toolName === 'string' && normalized.toolName) {
|
|
1095
|
+
lines.push(`- toolName: \`${normalized.toolName}\``);
|
|
1096
|
+
}
|
|
1097
|
+
const files = normalized.files ?? [];
|
|
1098
|
+
if (files.length > 0) {
|
|
1099
|
+
lines.push(`- files: ${files.map((f) => `\`${f.displayPath}\``).join(', ')}`);
|
|
1100
|
+
}
|
|
1101
|
+
lines.push('');
|
|
1102
|
+
}
|
|
1103
|
+
if (acc) {
|
|
1104
|
+
lines.push('**UI event (accumulated):**');
|
|
1105
|
+
lines.push(`- operation: \`${acc.operation}\``);
|
|
1106
|
+
lines.push(`- description: ${acc.description}`);
|
|
1107
|
+
if (typeof acc.contextTokens === 'number' && acc.contextTokens > 0) {
|
|
1108
|
+
lines.push(`- contextTokens: ${acc.contextTokens}`);
|
|
1109
|
+
}
|
|
1110
|
+
if (acc.files.length > 0) {
|
|
1111
|
+
lines.push(`- files: ${acc.files.map((f) => f.displayPath).join(', ')}`);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
else {
|
|
1115
|
+
const dropReason = row.dropReason;
|
|
1116
|
+
lines.push(`**UI event:** ${dropReason ?? 'none (accumulator dropped this event)'}`);
|
|
1117
|
+
}
|
|
1118
|
+
return lines.join('\n');
|
|
1119
|
+
}
|
|
1120
|
+
async function copyRowContext(row, sessionTitle) {
|
|
1121
|
+
const text = buildRowContext(row, sessionTitle);
|
|
1122
|
+
try {
|
|
1123
|
+
await navigator.clipboard.writeText(text);
|
|
1124
|
+
return true;
|
|
1125
|
+
}
|
|
1126
|
+
catch (err) {
|
|
1127
|
+
console.error('[session-events] copy failed:', err);
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function EventRow({ row, sessionTitle, runCount, snapshotCount, visible, expanded, onToggle, }) {
|
|
1132
|
+
const raw = toRaw(row.raw);
|
|
1133
|
+
const normalized = toNormalized(row.normalized);
|
|
1134
|
+
const { theme } = useTheme();
|
|
1135
|
+
const [copied, setCopied] = useState(false);
|
|
1136
|
+
if (!visible)
|
|
1137
|
+
return _jsx(FilteredOutLine, { raw: raw });
|
|
1138
|
+
const color = kindColor(eventKind(raw));
|
|
1139
|
+
const files = normalized?.files;
|
|
1140
|
+
const hasPaths = !!files && files.length > 0;
|
|
1141
|
+
const onCopy = () => {
|
|
1142
|
+
void copyRowContext(row, sessionTitle).then((ok) => {
|
|
1143
|
+
if (!ok)
|
|
1144
|
+
return;
|
|
1145
|
+
setCopied(true);
|
|
1146
|
+
setTimeout(() => setCopied(false), 2000);
|
|
1147
|
+
});
|
|
1148
|
+
};
|
|
1149
|
+
return (_jsxs("div", { style: {
|
|
1150
|
+
display: 'grid',
|
|
1151
|
+
gridTemplateColumns: '3px 1fr 1fr 1fr 28px',
|
|
1152
|
+
gridAutoRows: 'min-content',
|
|
1153
|
+
gap: 8,
|
|
1154
|
+
}, children: [_jsx("div", { title: hasPaths ? `${files.length} normalized path(s)` : 'no paths to normalize', style: {
|
|
1155
|
+
backgroundColor: hasPaths ? '#10b981' : '#232c39',
|
|
1156
|
+
} }), _jsx(RawEventCard, { event: raw, runCount: runCount, snapshotCount: snapshotCount, expanded: expanded, onToggle: onToggle }), normalized ? (_jsx(NormalizedEventCard, { event: normalized, seq: row.seq, color: color, expanded: expanded, onToggle: onToggle })) : null, _jsx(AccumulatedEventCard, { event: row.accumulated, seq: row.seq, dropReason: row.dropReason, expanded: expanded, onToggle: onToggle }), _jsx("button", { type: "button", onClick: (e) => {
|
|
1157
|
+
e.preventDefault();
|
|
1158
|
+
e.stopPropagation();
|
|
1159
|
+
onCopy();
|
|
1160
|
+
}, title: "Copy this row's context for a discussion", "aria-label": "Copy row context", style: {
|
|
1161
|
+
display: 'flex',
|
|
1162
|
+
alignItems: 'center',
|
|
1163
|
+
justifyContent: 'center',
|
|
1164
|
+
alignSelf: 'stretch',
|
|
1165
|
+
padding: 0,
|
|
1166
|
+
border: 'none',
|
|
1167
|
+
borderRadius: 4,
|
|
1168
|
+
appearance: 'none',
|
|
1169
|
+
cursor: 'pointer',
|
|
1170
|
+
background: copied ? 'rgba(16,185,129,0.12)' : 'transparent',
|
|
1171
|
+
color: copied ? '#10b981' : theme.colors.textTertiary,
|
|
1172
|
+
fontSize: 12,
|
|
1173
|
+
}, children: copied ? _jsx(Check, { size: 13 }) : _jsx(Copy, { size: 13 }) })] }));
|
|
1174
|
+
}
|
|
1175
|
+
function FilteredOutLine({ raw }) {
|
|
1176
|
+
const color = kindColor(eventKind(raw));
|
|
1177
|
+
return (_jsx("div", { title: describe(raw), style: {
|
|
1178
|
+
height: 2,
|
|
1179
|
+
backgroundColor: color,
|
|
1180
|
+
opacity: 0.16,
|
|
1181
|
+
cursor: 'default',
|
|
1182
|
+
} }));
|
|
1183
|
+
}
|
|
1184
|
+
function FilterChip({ label, active, color, onClick, }) {
|
|
1185
|
+
return (_jsx("button", { onClick: onClick, style: {
|
|
1186
|
+
padding: '4px 10px',
|
|
1187
|
+
borderRadius: 999,
|
|
1188
|
+
border: `1px solid ${active ? color ?? '#3b82f6' : '#1f2937'}`,
|
|
1189
|
+
backgroundColor: active ? (color ?? '#3b82f6') + '22' : 'transparent',
|
|
1190
|
+
color: active ? '#f3f4f6' : '#9ca3af',
|
|
1191
|
+
fontSize: 11.5,
|
|
1192
|
+
cursor: 'pointer',
|
|
1193
|
+
fontFamily: 'inherit',
|
|
1194
|
+
}, children: label }));
|
|
1195
|
+
}
|
|
1196
|
+
//# sourceMappingURL=SessionEventFeed.js.map
|