@vibefield/rosetta-room 0.0.0-stage → 0.1.1
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 +247 -2
- package/dist/HistoryRoom.d.ts +98 -0
- package/dist/HistoryRoom.js +440 -0
- package/dist/TranscriptReader.d.ts +22 -0
- package/dist/TranscriptReader.js +72 -0
- package/dist/components/ColdStart.d.ts +4 -0
- package/dist/components/ColdStart.js +5 -0
- package/dist/components/FilterChips.d.ts +4 -0
- package/dist/components/FilterChips.js +5 -0
- package/dist/components/HostAct.d.ts +9 -0
- package/dist/components/HostAct.js +16 -0
- package/dist/components/HostMenu.d.ts +41 -0
- package/dist/components/HostMenu.js +216 -0
- package/dist/components/IngestStatus.d.ts +4 -0
- package/dist/components/IngestStatus.js +20 -0
- package/dist/components/ListActivityNotice.d.ts +5 -0
- package/dist/components/ListActivityNotice.js +4 -0
- package/dist/components/ListSections.d.ts +20 -0
- package/dist/components/ListSections.js +39 -0
- package/dist/components/RenameHeading.d.ts +9 -0
- package/dist/components/RenameHeading.js +75 -0
- package/dist/components/SearchStrip.d.ts +5 -0
- package/dist/components/SearchStrip.js +8 -0
- package/dist/components/SummaryMetrics.d.ts +13 -0
- package/dist/components/SummaryMetrics.js +9 -0
- package/dist/components/SummaryPanels.d.ts +35 -0
- package/dist/components/SummaryPanels.js +117 -0
- package/dist/components/Transcript.d.ts +46 -0
- package/dist/components/Transcript.js +358 -0
- package/dist/components/charts/ActivityChartDetail.d.ts +13 -0
- package/dist/components/charts/ActivityChartDetail.js +78 -0
- package/dist/components/charts/CalendarHeatmap.d.ts +16 -0
- package/dist/components/charts/CalendarHeatmap.js +55 -0
- package/dist/components/charts/DayActivityChart.d.ts +8 -0
- package/dist/components/charts/DayActivityChart.js +71 -0
- package/dist/components/charts/ModelsChartDetail.d.ts +7 -0
- package/dist/components/charts/ModelsChartDetail.js +19 -0
- package/dist/components/charts/ProjectChartDialog.d.ts +19 -0
- package/dist/components/charts/ProjectChartDialog.js +39 -0
- package/dist/components/charts/Streamgraph.d.ts +16 -0
- package/dist/components/charts/Streamgraph.js +94 -0
- package/dist/components/charts/Treemap.d.ts +26 -0
- package/dist/components/charts/Treemap.js +81 -0
- package/dist/components/charts/index.d.ts +9 -0
- package/dist/components/charts/index.js +4 -0
- package/dist/components/charts/streamgraph-layout.d.ts +23 -0
- package/dist/components/charts/streamgraph-layout.js +114 -0
- package/dist/components/charts/treemap-layout.d.ts +32 -0
- package/dist/components/charts/treemap-layout.js +140 -0
- package/dist/components/charts/types.d.ts +65 -0
- package/dist/components/charts/types.js +8 -0
- package/dist/components/file-viewer/FileViewerBrowsers.d.ts +10 -0
- package/dist/components/file-viewer/FileViewerBrowsers.js +65 -0
- package/dist/components/file-viewer/FileViewerDialog.d.ts +33 -0
- package/dist/components/file-viewer/FileViewerDialog.js +82 -0
- package/dist/components/file-viewer/FileViewerHeader.d.ts +26 -0
- package/dist/components/file-viewer/FileViewerHeader.js +17 -0
- package/dist/components/file-viewer/ImageGalleryDialog.d.ts +14 -0
- package/dist/components/file-viewer/ImageGalleryDialog.js +98 -0
- package/dist/components/file-viewer/diff/index.d.ts +2 -0
- package/dist/components/file-viewer/diff/index.js +2 -0
- package/dist/components/file-viewer/diff/parse.d.ts +2 -0
- package/dist/components/file-viewer/diff/parse.js +164 -0
- package/dist/components/file-viewer/diff/types.d.ts +44 -0
- package/dist/components/file-viewer/diff/types.js +7 -0
- package/dist/components/file-viewer/gallery-source.d.ts +11 -0
- package/dist/components/file-viewer/gallery-source.js +75 -0
- package/dist/components/file-viewer/image-resource.d.ts +19 -0
- package/dist/components/file-viewer/image-resource.js +60 -0
- package/dist/components/file-viewer/index.d.ts +5 -0
- package/dist/components/file-viewer/index.js +8 -0
- package/dist/components/file-viewer/markdown/blocks.d.ts +2 -0
- package/dist/components/file-viewer/markdown/blocks.js +277 -0
- package/dist/components/file-viewer/markdown/index.d.ts +4 -0
- package/dist/components/file-viewer/markdown/index.js +35 -0
- package/dist/components/file-viewer/markdown/inline.d.ts +10 -0
- package/dist/components/file-viewer/markdown/inline.js +178 -0
- package/dist/components/file-viewer/markdown/render.d.ts +9 -0
- package/dist/components/file-viewer/markdown/render.js +78 -0
- package/dist/components/file-viewer/markdown/types.d.ts +57 -0
- package/dist/components/file-viewer/markdown/types.js +11 -0
- package/dist/components/file-viewer/minimap/CodeMinimap.d.ts +10 -0
- package/dist/components/file-viewer/minimap/CodeMinimap.js +296 -0
- package/dist/components/file-viewer/minimap/layout.d.ts +60 -0
- package/dist/components/file-viewer/minimap/layout.js +117 -0
- package/dist/components/file-viewer/minimap/palette.d.ts +2 -0
- package/dist/components/file-viewer/minimap/palette.js +73 -0
- package/dist/components/file-viewer/minimap/raster.d.ts +19 -0
- package/dist/components/file-viewer/minimap/raster.js +122 -0
- package/dist/components/file-viewer/registry.d.ts +25 -0
- package/dist/components/file-viewer/registry.js +182 -0
- package/dist/components/file-viewer/syntax/grammars.d.ts +16 -0
- package/dist/components/file-viewer/syntax/grammars.js +221 -0
- package/dist/components/file-viewer/syntax/index.d.ts +8 -0
- package/dist/components/file-viewer/syntax/index.js +9 -0
- package/dist/components/file-viewer/syntax/languages.d.ts +14 -0
- package/dist/components/file-viewer/syntax/languages.js +115 -0
- package/dist/components/file-viewer/syntax/tokenize-config.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-config.js +132 -0
- package/dist/components/file-viewer/syntax/tokenize-css.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-css.js +169 -0
- package/dist/components/file-viewer/syntax/tokenize-markup.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-markup.js +124 -0
- package/dist/components/file-viewer/syntax/tokenize.d.ts +9 -0
- package/dist/components/file-viewer/syntax/tokenize.js +289 -0
- package/dist/components/file-viewer/syntax/types.d.ts +74 -0
- package/dist/components/file-viewer/syntax/types.js +13 -0
- package/dist/components/file-viewer/types.d.ts +111 -0
- package/dist/components/file-viewer/types.js +8 -0
- package/dist/components/file-viewer/use-file-content.d.ts +26 -0
- package/dist/components/file-viewer/use-file-content.js +144 -0
- package/dist/components/file-viewer/views/BinaryView.d.ts +2 -0
- package/dist/components/file-viewer/views/BinaryView.js +34 -0
- package/dist/components/file-viewer/views/CodeView.d.ts +2 -0
- package/dist/components/file-viewer/views/CodeView.js +46 -0
- package/dist/components/file-viewer/views/DiffBody.d.ts +7 -0
- package/dist/components/file-viewer/views/DiffBody.js +77 -0
- package/dist/components/file-viewer/views/DiffView.d.ts +2 -0
- package/dist/components/file-viewer/views/DiffView.js +11 -0
- package/dist/components/file-viewer/views/ImageView.d.ts +9 -0
- package/dist/components/file-viewer/views/ImageView.js +28 -0
- package/dist/components/file-viewer/views/MarkdownView.d.ts +9 -0
- package/dist/components/file-viewer/views/MarkdownView.js +20 -0
- package/dist/components/file-viewer/views/SvgView.d.ts +9 -0
- package/dist/components/file-viewer/views/SvgView.js +10 -0
- package/dist/components/git/ChangeTree.d.ts +20 -0
- package/dist/components/git/ChangeTree.js +35 -0
- package/dist/components/git/CommitViewer.d.ts +12 -0
- package/dist/components/git/CommitViewer.js +85 -0
- package/dist/components/git/GitChanges.d.ts +17 -0
- package/dist/components/git/GitChanges.js +70 -0
- package/dist/components/git/GitHistory.d.ts +9 -0
- package/dist/components/git/GitHistory.js +58 -0
- package/dist/components/git/co-author.d.ts +14 -0
- package/dist/components/git/co-author.js +55 -0
- package/dist/components/git/git-file-source.d.ts +18 -0
- package/dist/components/git/git-file-source.js +53 -0
- package/dist/components/git/git-host.d.ts +24 -0
- package/dist/components/git/git-host.js +130 -0
- package/dist/components/git/index.d.ts +10 -0
- package/dist/components/git/index.js +12 -0
- package/dist/components/git/path-tree.d.ts +23 -0
- package/dist/components/git/path-tree.js +73 -0
- package/dist/components/git/session-files.d.ts +9 -0
- package/dist/components/git/session-files.js +50 -0
- package/dist/components/git/types.d.ts +92 -0
- package/dist/components/git/types.js +9 -0
- package/dist/components/projects/ProjectActivitySparkline.d.ts +6 -0
- package/dist/components/projects/ProjectActivitySparkline.js +12 -0
- package/dist/components/projects/ProjectList.d.ts +25 -0
- package/dist/components/projects/ProjectList.js +43 -0
- package/dist/components/projects/ProjectListItem.d.ts +19 -0
- package/dist/components/projects/ProjectListItem.js +78 -0
- package/dist/components/projects/ProjectsColumn.d.ts +19 -0
- package/dist/components/projects/ProjectsColumn.js +36 -0
- package/dist/components/projects/index.d.ts +8 -0
- package/dist/components/projects/index.js +4 -0
- package/dist/components/search/MatchStepper.d.ts +9 -0
- package/dist/components/search/MatchStepper.js +14 -0
- package/dist/components/search/SearchLauncher.d.ts +12 -0
- package/dist/components/search/SearchLauncher.js +13 -0
- package/dist/components/search/SearchSheet.d.ts +29 -0
- package/dist/components/search/SearchSheet.js +230 -0
- package/dist/components/search/index.d.ts +8 -0
- package/dist/components/search/index.js +4 -0
- package/dist/components/search/shortcut.d.ts +25 -0
- package/dist/components/search/shortcut.js +32 -0
- package/dist/components/sessions/SessionList.d.ts +24 -0
- package/dist/components/sessions/SessionList.js +76 -0
- package/dist/components/sessions/SessionListItem.d.ts +13 -0
- package/dist/components/sessions/SessionListItem.js +58 -0
- package/dist/components/sessions/SessionsColumn.d.ts +26 -0
- package/dist/components/sessions/SessionsColumn.js +32 -0
- package/dist/components/sessions/index.d.ts +9 -0
- package/dist/components/sessions/index.js +4 -0
- package/dist/components/sessions/session-display.d.ts +8 -0
- package/dist/components/sessions/session-display.js +18 -0
- package/dist/components/sessions/types.d.ts +7 -0
- package/dist/components/sessions/types.js +1 -0
- package/dist/components/transcript/Activity.d.ts +45 -0
- package/dist/components/transcript/Activity.js +75 -0
- package/dist/components/transcript/Anchor.d.ts +8 -0
- package/dist/components/transcript/Anchor.js +23 -0
- package/dist/components/transcript/Attachments.d.ts +21 -0
- package/dist/components/transcript/Attachments.js +138 -0
- package/dist/components/transcript/AuthoredMessage.d.ts +19 -0
- package/dist/components/transcript/AuthoredMessage.js +17 -0
- package/dist/components/transcript/Compaction.d.ts +9 -0
- package/dist/components/transcript/Compaction.js +50 -0
- package/dist/components/transcript/DayPill.d.ts +38 -0
- package/dist/components/transcript/DayPill.js +68 -0
- package/dist/components/transcript/Document.d.ts +32 -0
- package/dist/components/transcript/Document.js +503 -0
- package/dist/components/transcript/Favicon.d.ts +32 -0
- package/dist/components/transcript/Favicon.js +71 -0
- package/dist/components/transcript/HeadOfDocument.d.ts +19 -0
- package/dist/components/transcript/HeadOfDocument.js +44 -0
- package/dist/components/transcript/Ledger.d.ts +53 -0
- package/dist/components/transcript/Ledger.js +182 -0
- package/dist/components/transcript/LineDetail.d.ts +24 -0
- package/dist/components/transcript/LineDetail.js +81 -0
- package/dist/components/transcript/Marker.d.ts +33 -0
- package/dist/components/transcript/Marker.js +21 -0
- package/dist/components/transcript/MessagePreview.d.ts +12 -0
- package/dist/components/transcript/MessagePreview.js +58 -0
- package/dist/components/transcript/Prompt.d.ts +20 -0
- package/dist/components/transcript/Prompt.js +55 -0
- package/dist/components/transcript/Prose.d.ts +19 -0
- package/dist/components/transcript/Prose.js +109 -0
- package/dist/components/transcript/ReceiptPill.d.ts +10 -0
- package/dist/components/transcript/ReceiptPill.js +10 -0
- package/dist/components/transcript/ResponseHead.d.ts +9 -0
- package/dist/components/transcript/ResponseHead.js +36 -0
- package/dist/components/transcript/Subthread.d.ts +19 -0
- package/dist/components/transcript/Subthread.js +96 -0
- package/dist/components/transcript/Team.d.ts +53 -0
- package/dist/components/transcript/Team.js +185 -0
- package/dist/components/transcript/Thinking.d.ts +24 -0
- package/dist/components/transcript/Thinking.js +50 -0
- package/dist/components/transcript/TimelineMeta.d.ts +9 -0
- package/dist/components/transcript/TimelineMeta.js +161 -0
- package/dist/components/transcript/TranscriptLoading.d.ts +10 -0
- package/dist/components/transcript/TranscriptLoading.js +10 -0
- package/dist/components/transcript/WebDetail.d.ts +8 -0
- package/dist/components/transcript/WebDetail.js +29 -0
- package/dist/components/transcript/Workflow.d.ts +12 -0
- package/dist/components/transcript/Workflow.js +208 -0
- package/dist/components/transcript/activity-plan.d.ts +84 -0
- package/dist/components/transcript/activity-plan.js +209 -0
- package/dist/components/transcript/attachment-file-source.d.ts +23 -0
- package/dist/components/transcript/attachment-file-source.js +103 -0
- package/dist/components/transcript/attachment-gallery.d.ts +12 -0
- package/dist/components/transcript/attachment-gallery.js +33 -0
- package/dist/components/transcript/detail-parts.d.ts +50 -0
- package/dist/components/transcript/detail-parts.js +295 -0
- package/dist/components/transcript/disclosure-state.d.ts +6 -0
- package/dist/components/transcript/disclosure-state.js +32 -0
- package/dist/components/transcript/disclosure-store.d.ts +8 -0
- package/dist/components/transcript/disclosure-store.js +31 -0
- package/dist/components/transcript/document-model.d.ts +15 -0
- package/dist/components/transcript/document-model.js +104 -0
- package/dist/components/transcript/document-plan.d.ts +28 -0
- package/dist/components/transcript/document-plan.js +145 -0
- package/dist/components/transcript/fold-preference.d.ts +17 -0
- package/dist/components/transcript/fold-preference.js +63 -0
- package/dist/components/transcript/glyphs.d.ts +15 -0
- package/dist/components/transcript/glyphs.js +47 -0
- package/dist/components/transcript/index.d.ts +23 -0
- package/dist/components/transcript/index.js +22 -0
- package/dist/components/transcript/message-file-source.d.ts +15 -0
- package/dist/components/transcript/message-file-source.js +31 -0
- package/dist/components/transcript/message-preview.d.ts +9 -0
- package/dist/components/transcript/message-preview.js +46 -0
- package/dist/components/transcript/read-file-source.d.ts +7 -0
- package/dist/components/transcript/read-file-source.js +34 -0
- package/dist/components/transcript/reader-context.d.ts +13 -0
- package/dist/components/transcript/reader-context.js +55 -0
- package/dist/components/transcript/reading-identity.d.ts +2 -0
- package/dist/components/transcript/reading-identity.js +52 -0
- package/dist/components/transcript/scroll-to-row.d.ts +2 -0
- package/dist/components/transcript/scroll-to-row.js +13 -0
- package/dist/components/transcript/thread-index.d.ts +14 -0
- package/dist/components/transcript/thread-index.js +40 -0
- package/dist/components/transcript/thread-navigation.d.ts +5 -0
- package/dist/components/transcript/thread-navigation.js +3 -0
- package/dist/components/transcript/timeline-meta-file-source.d.ts +6 -0
- package/dist/components/transcript/timeline-meta-file-source.js +55 -0
- package/dist/components/transcript/timeline-meta-state.d.ts +12 -0
- package/dist/components/transcript/timeline-meta-state.js +24 -0
- package/dist/components/ui/ColumnHeading.d.ts +27 -0
- package/dist/components/ui/ColumnHeading.js +7 -0
- package/dist/components/ui/ConfirmDialog.d.ts +14 -0
- package/dist/components/ui/ConfirmDialog.js +22 -0
- package/dist/components/ui/DialogShell.d.ts +18 -0
- package/dist/components/ui/DialogShell.js +40 -0
- package/dist/components/ui/EmptyState.d.ts +10 -0
- package/dist/components/ui/EmptyState.js +6 -0
- package/dist/components/ui/ListSummaryHeader.d.ts +9 -0
- package/dist/components/ui/ListSummaryHeader.js +6 -0
- package/dist/components/ui/ListToolbar.d.ts +6 -0
- package/dist/components/ui/ListToolbar.js +5 -0
- package/dist/components/ui/ResultGroupHeader.d.ts +9 -0
- package/dist/components/ui/ResultGroupHeader.js +5 -0
- package/dist/components/ui/SegmentedControl.d.ts +16 -0
- package/dist/components/ui/SegmentedControl.js +9 -0
- package/dist/components/ui/SummaryMetric.d.ts +13 -0
- package/dist/components/ui/SummaryMetric.js +10 -0
- package/dist/components/ui/Veil.d.ts +7 -0
- package/dist/components/ui/Veil.js +5 -0
- package/dist/components/ui/index.d.ts +20 -0
- package/dist/components/ui/index.js +10 -0
- package/dist/components/worktree/WorktreeColumn.d.ts +22 -0
- package/dist/components/worktree/WorktreeColumn.js +170 -0
- package/dist/components/worktree/WorktreeFileTree.d.ts +19 -0
- package/dist/components/worktree/WorktreeFileTree.js +60 -0
- package/dist/components/worktree/WorktreeHeader.d.ts +32 -0
- package/dist/components/worktree/WorktreeHeader.js +81 -0
- package/dist/components/worktree/WorktreeList.d.ts +8 -0
- package/dist/components/worktree/WorktreeList.js +12 -0
- package/dist/components/worktree/index.d.ts +12 -0
- package/dist/components/worktree/index.js +7 -0
- package/dist/components/worktree/types.d.ts +17 -0
- package/dist/components/worktree/types.js +3 -0
- package/dist/components/worktree/use-worktree-guest.d.ts +21 -0
- package/dist/components/worktree/use-worktree-guest.js +92 -0
- package/dist/components/worktree/worktree-file-commands.d.ts +19 -0
- package/dist/components/worktree/worktree-file-commands.js +112 -0
- package/dist/components/worktree/worktree-file-source.d.ts +15 -0
- package/dist/components/worktree/worktree-file-source.js +75 -0
- package/dist/components/worktree/worktree-host.d.ts +31 -0
- package/dist/components/worktree/worktree-host.js +242 -0
- package/dist/fixtures/index.d.ts +24 -0
- package/dist/fixtures/index.js +292 -0
- package/dist/host-inputs.d.ts +231 -0
- package/dist/host-inputs.js +35 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +14 -0
- package/dist/lib/activity-details.d.ts +23 -0
- package/dist/lib/activity-details.js +78 -0
- package/dist/lib/activity-order.d.ts +32 -0
- package/dist/lib/activity-order.js +86 -0
- package/dist/lib/agent-paths.d.ts +6 -0
- package/dist/lib/agent-paths.js +19 -0
- package/dist/lib/agents.d.ts +15 -0
- package/dist/lib/agents.js +60 -0
- package/dist/lib/catalog-status.d.ts +3 -0
- package/dist/lib/catalog-status.js +10 -0
- package/dist/lib/chart-data.d.ts +14 -0
- package/dist/lib/chart-data.js +151 -0
- package/dist/lib/day-activity.d.ts +21 -0
- package/dist/lib/day-activity.js +56 -0
- package/dist/lib/format.d.ts +24 -0
- package/dist/lib/format.js +116 -0
- package/dist/lib/hooks.d.ts +118 -0
- package/dist/lib/hooks.js +608 -0
- package/dist/lib/icons.d.ts +21 -0
- package/dist/lib/icons.js +49 -0
- package/dist/lib/image-media.d.ts +6 -0
- package/dist/lib/image-media.js +30 -0
- package/dist/lib/ingest-activity.d.ts +50 -0
- package/dist/lib/ingest-activity.js +151 -0
- package/dist/lib/ingest.d.ts +25 -0
- package/dist/lib/ingest.js +70 -0
- package/dist/lib/model-labels.d.ts +5 -0
- package/dist/lib/model-labels.js +28 -0
- package/dist/lib/model.d.ts +73 -0
- package/dist/lib/model.js +141 -0
- package/dist/lib/motion.d.ts +13 -0
- package/dist/lib/motion.js +80 -0
- package/dist/lib/room-storage.d.ts +13 -0
- package/dist/lib/room-storage.js +40 -0
- package/dist/lib/search-results.d.ts +27 -0
- package/dist/lib/search-results.js +83 -0
- package/dist/lib/search-sheet.d.ts +119 -0
- package/dist/lib/search-sheet.js +282 -0
- package/dist/lib/sections.d.ts +19 -0
- package/dist/lib/sections.js +36 -0
- package/dist/lib/session-activity.d.ts +5 -0
- package/dist/lib/session-activity.js +15 -0
- package/dist/lib/session-leases.d.ts +15 -0
- package/dist/lib/session-leases.js +61 -0
- package/dist/lib/spend.d.ts +42 -0
- package/dist/lib/spend.js +112 -0
- package/dist/lib/tint.d.ts +9 -0
- package/dist/lib/tint.js +53 -0
- package/dist/lib/transcript/collaboration.d.ts +97 -0
- package/dist/lib/transcript/collaboration.js +423 -0
- package/dist/lib/transcript/families.d.ts +212 -0
- package/dist/lib/transcript/families.js +906 -0
- package/dist/lib/transcript/favicons.d.ts +54 -0
- package/dist/lib/transcript/favicons.js +183 -0
- package/dist/lib/transcript/head-of-document.d.ts +27 -0
- package/dist/lib/transcript/head-of-document.js +274 -0
- package/dist/lib/transcript/head-state.d.ts +182 -0
- package/dist/lib/transcript/head-state.js +305 -0
- package/dist/lib/transcript/history-window.d.ts +13 -0
- package/dist/lib/transcript/history-window.js +52 -0
- package/dist/lib/transcript/images.d.ts +8 -0
- package/dist/lib/transcript/images.js +60 -0
- package/dist/lib/transcript/index.d.ts +15 -0
- package/dist/lib/transcript/index.js +8 -0
- package/dist/lib/transcript/ledger.d.ts +143 -0
- package/dist/lib/transcript/ledger.js +513 -0
- package/dist/lib/transcript/protocol.d.ts +23 -0
- package/dist/lib/transcript/protocol.js +1 -0
- package/dist/lib/transcript/sittings.d.ts +75 -0
- package/dist/lib/transcript/sittings.js +147 -0
- package/dist/lib/transcript/tail-scroll.d.ts +36 -0
- package/dist/lib/transcript/tail-scroll.js +167 -0
- package/dist/lib/transcript/tail-state.d.ts +17 -0
- package/dist/lib/transcript/tail-state.js +30 -0
- package/dist/lib/transcript/turns.d.ts +192 -0
- package/dist/lib/transcript/turns.js +576 -0
- package/dist/lib/transcript/use-transcript-opening.d.ts +12 -0
- package/dist/lib/transcript/use-transcript-opening.js +31 -0
- package/dist/lib/transcript/use-transcript-tail.d.ts +25 -0
- package/dist/lib/transcript/use-transcript-tail.js +158 -0
- package/dist/lib/transcript/vocabulary.d.ts +119 -0
- package/dist/lib/transcript/vocabulary.js +293 -0
- package/dist/lib/transcript/web-address.d.ts +6 -0
- package/dist/lib/transcript/web-address.js +18 -0
- package/dist/lib/transcript/workflow.d.ts +31 -0
- package/dist/lib/transcript/workflow.js +133 -0
- package/dist/lib/use-activity-order.d.ts +2 -0
- package/dist/lib/use-activity-order.js +23 -0
- package/dist/lib/use-day-usage.d.ts +8 -0
- package/dist/lib/use-day-usage.js +31 -0
- package/dist/lib/use-deferred-list-order.d.ts +26 -0
- package/dist/lib/use-deferred-list-order.js +142 -0
- package/dist/lib/use-ingest-activity.d.ts +2 -0
- package/dist/lib/use-ingest-activity.js +49 -0
- package/dist/lib/use-list-motion.d.ts +4 -0
- package/dist/lib/use-list-motion.js +67 -0
- package/dist/ports.d.ts +222 -0
- package/dist/ports.js +3 -0
- package/dist/room-context.d.ts +60 -0
- package/dist/room-context.js +87 -0
- package/dist/styles/activity-chart.css +127 -0
- package/dist/styles/attachments.css +29 -0
- package/dist/styles/favicon.css +73 -0
- package/dist/styles/history-room.css +18 -0
- package/dist/styles/host-inputs.css +250 -0
- package/dist/styles/image-gallery.css +30 -0
- package/dist/styles/ingest.css +51 -0
- package/dist/styles/message-preview.css +34 -0
- package/dist/styles/models-chart.css +66 -0
- package/dist/styles/project-chart.css +19 -0
- package/dist/styles/reader.css +33 -0
- package/dist/styles/room.css +1411 -0
- package/dist/styles/search.css +252 -0
- package/dist/styles/transcript-activity.css +70 -0
- package/dist/styles/transcript-head.css +220 -0
- package/dist/styles/transcript-loading.css +57 -0
- package/dist/styles/transcript.css +1226 -0
- package/package.json +61 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { firstLine, spanText } from "../../lib/transcript/index.js";
|
|
4
|
+
import { useFoldPreference } from "./fold-preference.js";
|
|
5
|
+
import { LineChevron, ThoughtGlyph } from "./glyphs.js";
|
|
6
|
+
import { useRowDisclosure } from "./disclosure-state.js";
|
|
7
|
+
export function Thinking({ text, spanMs, domId, timelineId, hit, anchor }) {
|
|
8
|
+
const [open, setOpen] = useState(false);
|
|
9
|
+
const label = spanMs === null || spanMs < 1000
|
|
10
|
+
? "more · reasoning"
|
|
11
|
+
: `more · reasoning, ${spanText(spanMs)}`;
|
|
12
|
+
return (_jsxs("div", { className: "tr-seg tr-think", "data-open": open, id: domId, "data-timeline-id": timelineId, "data-hit": hit || undefined, children: [anchor, _jsx("div", { className: "tr-think__text", children: text.split(/\n{2,}/).map((paragraph, at) => paragraph.trim() === "" ? null : _jsx("p", { children: paragraph }, at)) }), _jsx("button", { type: "button", className: "tr-think__more", "aria-expanded": open, onClick: () => setOpen((value) => !value), children: open ? "less" : label })] }));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Q10 A (transcript-fold, 2026-09-08) — reasoning that stands alone between
|
|
16
|
+
* two paragraphs is a run of one, and a run of one is the line it already was:
|
|
17
|
+
* `Thought · its first words · the span`, on the ledger's rail, opening in
|
|
18
|
+
* place to the same muted prose the clamp holds. Inside a ladder `Thinking`
|
|
19
|
+
* keeps the clamp; this is the line form only. Q4 C moved one level down.
|
|
20
|
+
*/
|
|
21
|
+
export function ThoughtLine({ text, spanMs, domId, timelineId, hit, anchor, forceOpen = false, embedded = false, }) {
|
|
22
|
+
// §05 — the room's activity act is the default, a press is an override,
|
|
23
|
+
// and the next press of the act clears it — as the run's head does.
|
|
24
|
+
const everyRunOpen = !useFoldPreference().folded;
|
|
25
|
+
const [override, setOverride] = useRowDisclosure(domId, !embedded && everyRunOpen);
|
|
26
|
+
const actRef = useRef(everyRunOpen);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (actRef.current === everyRunOpen)
|
|
29
|
+
return;
|
|
30
|
+
actRef.current = everyRunOpen;
|
|
31
|
+
if (!embedded)
|
|
32
|
+
setOverride(everyRunOpen);
|
|
33
|
+
}, [everyRunOpen, embedded, setOverride]);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (forceOpen || hit)
|
|
36
|
+
setOverride(true);
|
|
37
|
+
}, [forceOpen, hit]);
|
|
38
|
+
const isOpen = override || forceOpen;
|
|
39
|
+
const span = spanMs === null || spanMs < 1000 ? null : spanText(spanMs);
|
|
40
|
+
// A thought may open with a blank line; the head names the first line
|
|
41
|
+
// that says something.
|
|
42
|
+
const lead = text.trimStart();
|
|
43
|
+
const toggle = () => setOverride(!isOpen);
|
|
44
|
+
return (_jsxs("div", { className: "tr-seg tr-ledger tr-thought", id: domId, "data-timeline-id": timelineId, "data-hit": hit || undefined, children: [anchor, _jsxs("div", { className: "tr-line", role: "button", tabIndex: 0, "aria-expanded": isOpen, "data-thought": "", onClick: toggle, onKeyDown: (event) => {
|
|
45
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
46
|
+
return;
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
toggle();
|
|
49
|
+
}, children: [_jsx("span", { className: "tr-line__g", children: _jsx(ThoughtGlyph, {}) }), _jsx("span", { className: "tr-line__v", children: "Thought" }), _jsx("span", { className: "tr-line__o", title: firstLine(lead, 400), children: firstLine(lead) }), _jsxs("span", { className: "tr-line__r", children: [span !== null && _jsx("span", { children: span }), _jsx("span", { className: "chev", children: _jsx(LineChevron, {}) })] })] }), isOpen && (_jsx("div", { className: "tr-think", "data-open": "true", children: _jsx("div", { className: "tr-think__text", children: text.split(/\n{2,}/).map((paragraph, at) => paragraph.trim() === "" ? null : _jsx("p", { children: paragraph }, at)) }) }))] }));
|
|
50
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TimelineMeta as TimelineMetaValue, TimelineMetaArtifact, TimelineMetaPlan, TimelineMetaTask, TimelineMetaWorkflow } from "@vibefield/rosetta-protocol";
|
|
2
|
+
export interface TimelineMetaProps {
|
|
3
|
+
readonly meta: TimelineMetaValue;
|
|
4
|
+
readonly onOpenTask: (task: TimelineMetaTask) => void;
|
|
5
|
+
readonly onOpenWorkflow: (workflow: TimelineMetaWorkflow) => void;
|
|
6
|
+
readonly onOpenPlan: (plan: TimelineMetaPlan) => void;
|
|
7
|
+
readonly onOpenArtifact: (artifact: TimelineMetaArtifact) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function TimelineMeta({ meta, onOpenTask, onOpenWorkflow, onOpenPlan, onOpenArtifact, }: TimelineMetaProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// §05A — timeline_meta is the map back into the transcript, never a second
|
|
3
|
+
// rendering of it. Up to four non-empty launchers share one non-modal island;
|
|
4
|
+
// tasks and Workflow runs land on retained messages, while file rows hand off
|
|
5
|
+
// to the room's existing viewer.
|
|
6
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
7
|
+
import { clockShort, fmtBytes } from "../../lib/format.js";
|
|
8
|
+
import { FamilyGlyph, LineChevron } from "./glyphs.js";
|
|
9
|
+
import { availableTimelineMetaKinds, resolveTimelineMetaKind, recordedTaskDuration, recordedWorkflowDuration, } from "./timeline-meta-state.js";
|
|
10
|
+
const GLYPH = { tasks: "task", workflows: "bolt", plans: "doc", artifacts: "box" };
|
|
11
|
+
function exactCount(meta, kind) {
|
|
12
|
+
return (meta[kind] ?? []).length;
|
|
13
|
+
}
|
|
14
|
+
function titleCase(value) {
|
|
15
|
+
return value.replaceAll("_", " ").replace(/^./, (letter) => letter.toUpperCase());
|
|
16
|
+
}
|
|
17
|
+
function taskState(task) {
|
|
18
|
+
if (task.status === "in_progress")
|
|
19
|
+
return "running";
|
|
20
|
+
if (task.status === "failed" || task.status === "cancelled")
|
|
21
|
+
return "failed";
|
|
22
|
+
return task.status ?? "unknown";
|
|
23
|
+
}
|
|
24
|
+
function taskStatus(task) {
|
|
25
|
+
return task.status === null ? "State not recorded" : titleCase(task.status);
|
|
26
|
+
}
|
|
27
|
+
function spanText(milliseconds) {
|
|
28
|
+
const seconds = Math.max(0, Math.floor(milliseconds / 1_000));
|
|
29
|
+
if (seconds < 60)
|
|
30
|
+
return `${seconds}s`;
|
|
31
|
+
const minutes = Math.floor(seconds / 60);
|
|
32
|
+
if (minutes < 60)
|
|
33
|
+
return `${minutes}m ${String(seconds % 60).padStart(2, "0")}s`;
|
|
34
|
+
const hours = Math.floor(minutes / 60);
|
|
35
|
+
if (hours < 48)
|
|
36
|
+
return `${hours}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
37
|
+
return `${Math.floor(hours / 24)}d ${hours % 24}h`;
|
|
38
|
+
}
|
|
39
|
+
function workflowState(workflow) {
|
|
40
|
+
if (workflow.status === "running")
|
|
41
|
+
return "running";
|
|
42
|
+
if (workflow.status === "failed")
|
|
43
|
+
return "failed";
|
|
44
|
+
return workflow.status;
|
|
45
|
+
}
|
|
46
|
+
function fileType(name) {
|
|
47
|
+
const extension = name.split(".").pop();
|
|
48
|
+
return extension === undefined || extension === name ? "File" : extension.toUpperCase();
|
|
49
|
+
}
|
|
50
|
+
function EmptyPanel({ kind }) {
|
|
51
|
+
return _jsxs("p", { className: "tr-meta-empty", children: ["No ", kind, " recorded in this session."] });
|
|
52
|
+
}
|
|
53
|
+
function TaskPanel({ tasks, onOpen, }) {
|
|
54
|
+
if (tasks.length === 0)
|
|
55
|
+
return _jsx(EmptyPanel, { kind: "tasks" });
|
|
56
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tr-meta-listhead", children: [_jsx("span", { children: "Task \u00B7 last recorded state \u00B7 started" }), _jsx("span", { children: "Duration" })] }), _jsx("ol", { className: "tr-meta-list", "aria-label": "Full task list", children: tasks.map((task) => {
|
|
57
|
+
const status = taskStatus(task);
|
|
58
|
+
const started = task.started_at === null ? "start not recorded" : `started ${clockShort(task.started_at)}`;
|
|
59
|
+
const durationMs = recordedTaskDuration(task);
|
|
60
|
+
const duration = durationMs === null ? "—" : spanText(durationMs);
|
|
61
|
+
const openable = task.timeline_id !== null;
|
|
62
|
+
return (_jsx("li", { children: _jsxs("button", { className: "tr-meta-row", type: "button", "data-state": taskState(task), disabled: !openable, "aria-label": `${task.subject}, ${status}, ${started}, duration ${duration}${openable ? "; jump to task message" : "; no task message anchor recorded"}`, onClick: () => onOpen(task), children: [_jsx("span", { className: "tr-meta-status", "aria-hidden": "true", children: task.status === "completed" ? "✓" : "" }), _jsxs("span", { className: "tr-meta-row__body", children: [_jsx("span", { className: "tr-meta-row__name", children: task.subject }), _jsxs("span", { className: "tr-meta-row__meta", children: [status, " \u00B7 ", started] })] }), _jsx("span", { className: "tr-meta-row__value", children: duration }), _jsx("span", { className: "tr-meta-row__chev", children: _jsx(LineChevron, {}) })] }) }, task.id));
|
|
63
|
+
}) })] }));
|
|
64
|
+
}
|
|
65
|
+
function WorkflowPanel({ workflows, onOpen, }) {
|
|
66
|
+
if (workflows.length === 0)
|
|
67
|
+
return _jsx(EmptyPanel, { kind: "workflows" });
|
|
68
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tr-meta-listhead", children: [_jsx("span", { children: "Workflow \u00B7 last recorded state \u00B7 started" }), _jsx("span", { children: "Duration" })] }), _jsx("ol", { className: "tr-meta-list", "aria-label": "Workflow runs", children: workflows.map((workflow) => {
|
|
69
|
+
const status = titleCase(workflow.status);
|
|
70
|
+
const started = workflow.started_at === null
|
|
71
|
+
? "start not recorded"
|
|
72
|
+
: `started ${clockShort(workflow.started_at)}`;
|
|
73
|
+
const durationMs = recordedWorkflowDuration(workflow);
|
|
74
|
+
const duration = durationMs === null ? "—" : spanText(durationMs);
|
|
75
|
+
const workers = workflow.worker_count === null
|
|
76
|
+
? "worker count not recorded"
|
|
77
|
+
: `${workflow.worker_count} ${workflow.worker_count === 1 ? "worker" : "workers"}`;
|
|
78
|
+
const openable = workflow.timeline_id !== null;
|
|
79
|
+
return (_jsx("li", { children: _jsxs("button", { className: "tr-meta-row", type: "button", "data-kind": "workflow", "data-state": workflowState(workflow), disabled: !openable, "aria-label": `${workflow.name}, ${status}, ${started}, ${workers}, duration ${duration}${openable ? "; jump to workflow message" : "; no workflow message anchor recorded"}`, onClick: () => onOpen(workflow), children: [_jsx("span", { className: "tr-meta-status", "aria-hidden": "true", children: workflow.status === "completed" ? "✓" : "" }), _jsxs("span", { className: "tr-meta-row__body", children: [_jsx("span", { className: "tr-meta-row__name", children: workflow.name }), _jsxs("span", { className: "tr-meta-row__meta", children: [status, " \u00B7 ", started, " \u00B7 ", workers] })] }), _jsx("span", { className: "tr-meta-row__value", children: duration }), _jsx("span", { className: "tr-meta-row__chev", children: _jsx(LineChevron, {}) })] }) }, workflow.id));
|
|
80
|
+
}) })] }));
|
|
81
|
+
}
|
|
82
|
+
function PlanPanel({ plans, onOpen, }) {
|
|
83
|
+
if (plans.length === 0)
|
|
84
|
+
return _jsx(EmptyPanel, { kind: "plans" });
|
|
85
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tr-meta-listhead", children: [_jsx("span", { children: "Plan file \u00B7 updated" }), _jsx("span", { children: "Size" })] }), _jsx("ol", { className: "tr-meta-list", "aria-label": "Plan files", children: plans.map((plan) => (_jsx("li", { children: _jsxs("button", { className: "tr-meta-row", type: "button", "aria-label": `Open ${plan.name} in file viewer`, onClick: () => onOpen(plan), children: [_jsx("span", { className: "tr-meta-file", children: _jsx(FamilyGlyph, { glyph: "doc" }) }), _jsxs("span", { className: "tr-meta-row__body", children: [_jsx("span", { className: "tr-meta-row__name", children: plan.name }), _jsxs("span", { className: "tr-meta-row__meta", children: [fileType(plan.name), " \u00B7 ", plan.updated_at === null ? "update time not recorded" : `updated ${clockShort(plan.updated_at)}`] })] }), _jsx("span", { className: "tr-meta-row__value", children: fmtBytes(plan.byte_len) }), _jsx("span", { className: "tr-meta-row__chev", children: _jsx(LineChevron, {}) })] }) }, plan.id))) })] }));
|
|
86
|
+
}
|
|
87
|
+
function ArtifactPanel({ artifacts, onOpen, }) {
|
|
88
|
+
if (artifacts.length === 0)
|
|
89
|
+
return _jsx(EmptyPanel, { kind: "artifacts" });
|
|
90
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tr-meta-listhead", children: [_jsx("span", { children: "Artifact \u00B7 created" }), _jsx("span", { children: "Size" })] }), _jsx("ol", { className: "tr-meta-list", "aria-label": "Artifact files", children: artifacts.map((artifact) => (_jsx("li", { children: _jsxs("button", { className: "tr-meta-row", type: "button", "aria-label": `Open ${artifact.name} in file viewer`, onClick: () => onOpen(artifact), children: [_jsx("span", { className: "tr-meta-file", children: _jsx(FamilyGlyph, { glyph: "doc" }) }), _jsxs("span", { className: "tr-meta-row__body", children: [_jsx("span", { className: "tr-meta-row__name", children: artifact.name }), _jsxs("span", { className: "tr-meta-row__meta", children: [titleCase(artifact.artifact_kind), " \u00B7 ", artifact.created_at === null ? "creation time not recorded" : `created ${clockShort(artifact.created_at)}`] })] }), _jsx("span", { className: "tr-meta-row__value", children: artifact.byte_len === null ? "—" : fmtBytes(artifact.byte_len) }), _jsx("span", { className: "tr-meta-row__chev", children: _jsx(LineChevron, {}) })] }) }, artifact.id))) })] }));
|
|
91
|
+
}
|
|
92
|
+
export function TimelineMeta({ meta, onOpenTask, onOpenWorkflow, onOpenPlan, onOpenArtifact, }) {
|
|
93
|
+
const [active, setActive] = useState(null);
|
|
94
|
+
const rootRef = useRef(null);
|
|
95
|
+
const launcherRefs = useRef({});
|
|
96
|
+
const id = useId().replaceAll(":", "");
|
|
97
|
+
const availableKinds = availableTimelineMetaKinds(meta);
|
|
98
|
+
const visibleActive = resolveTimelineMetaKind(active, availableKinds);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (active !== visibleActive)
|
|
101
|
+
setActive(visibleActive);
|
|
102
|
+
}, [active, visibleActive]);
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (visibleActive === null)
|
|
105
|
+
return;
|
|
106
|
+
const pointerDown = (event) => {
|
|
107
|
+
if (!rootRef.current?.contains(event.target))
|
|
108
|
+
setActive(null);
|
|
109
|
+
};
|
|
110
|
+
const keyDown = (event) => {
|
|
111
|
+
if (event.key !== "Escape")
|
|
112
|
+
return;
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
const selected = visibleActive;
|
|
115
|
+
setActive(null);
|
|
116
|
+
launcherRefs.current[selected]?.focus();
|
|
117
|
+
};
|
|
118
|
+
document.addEventListener("pointerdown", pointerDown);
|
|
119
|
+
document.addEventListener("keydown", keyDown);
|
|
120
|
+
return () => {
|
|
121
|
+
document.removeEventListener("pointerdown", pointerDown);
|
|
122
|
+
document.removeEventListener("keydown", keyDown);
|
|
123
|
+
};
|
|
124
|
+
}, [visibleActive]);
|
|
125
|
+
const selectTab = (kind) => setActive(kind);
|
|
126
|
+
const moveTab = (kind, direction) => {
|
|
127
|
+
const index = availableKinds.indexOf(kind);
|
|
128
|
+
const next = availableKinds[(index + direction + availableKinds.length) % availableKinds.length];
|
|
129
|
+
if (next === undefined)
|
|
130
|
+
return;
|
|
131
|
+
setActive(next);
|
|
132
|
+
document.getElementById(`${id}-tab-${next}`)?.focus();
|
|
133
|
+
};
|
|
134
|
+
if (availableKinds.length === 0)
|
|
135
|
+
return null;
|
|
136
|
+
return (_jsxs("div", { className: "tr-meta", ref: rootRef, children: [_jsx("div", { className: "tr-meta-launchers", role: "group", "aria-label": "Session work", children: availableKinds.map((kind) => {
|
|
137
|
+
const count = exactCount(meta, kind);
|
|
138
|
+
return (_jsxs("button", { ref: (element) => { launcherRefs.current[kind] = element; }, className: "tr-meta-launch", type: "button", "aria-label": `${titleCase(kind)}, ${count}`, "aria-expanded": visibleActive === kind, "aria-controls": `${id}-popover`, onClick: () => setActive((current) => current === kind ? null : kind), children: [_jsx(FamilyGlyph, { glyph: GLYPH[kind] }), _jsx("span", { className: "tr-meta-launch__count", children: count })] }, kind));
|
|
139
|
+
}) }), visibleActive !== null && (_jsxs("div", { className: "tr-meta-popover", id: `${id}-popover`, role: "dialog", "aria-modal": "false", "aria-label": "Session work index", children: [_jsxs("div", { className: "tr-meta-top", children: [_jsx("div", { className: "tr-meta-tabs", role: "tablist", "aria-label": "Session work type", children: availableKinds.map((kind) => (_jsx("button", { className: "tr-meta-tab", id: `${id}-tab-${kind}`, type: "button", role: "tab", "aria-selected": visibleActive === kind, "aria-controls": `${id}-panel`, tabIndex: visibleActive === kind ? 0 : -1, onClick: () => selectTab(kind), onKeyDown: (event) => {
|
|
140
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
|
|
141
|
+
return;
|
|
142
|
+
event.preventDefault();
|
|
143
|
+
moveTab(kind, event.key === "ArrowRight" ? 1 : -1);
|
|
144
|
+
}, children: titleCase(kind) }, kind))) }), _jsx("button", { className: "tr-meta-close", type: "button", "aria-label": "Close session work", onClick: () => {
|
|
145
|
+
const selected = visibleActive;
|
|
146
|
+
setActive(null);
|
|
147
|
+
launcherRefs.current[selected]?.focus();
|
|
148
|
+
}, children: _jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "m4.5 4.5 7 7M11.5 4.5l-7 7" }) }) })] }), _jsxs("div", { className: "tr-meta-panel", id: `${id}-panel`, role: "tabpanel", "aria-labelledby": `${id}-tab-${visibleActive}`, children: [visibleActive === "tasks" && (_jsx(TaskPanel, { tasks: meta.tasks, onOpen: (task) => {
|
|
149
|
+
setActive(null);
|
|
150
|
+
onOpenTask(task);
|
|
151
|
+
} })), visibleActive === "workflows" && (_jsx(WorkflowPanel, { workflows: meta.workflows, onOpen: (workflow) => {
|
|
152
|
+
setActive(null);
|
|
153
|
+
onOpenWorkflow(workflow);
|
|
154
|
+
} })), visibleActive === "plans" && (_jsx(PlanPanel, { plans: meta.plans, onOpen: (plan) => {
|
|
155
|
+
setActive(null);
|
|
156
|
+
onOpenPlan(plan);
|
|
157
|
+
} })), visibleActive === "artifacts" && (_jsx(ArtifactPanel, { artifacts: meta.artifacts, onOpen: (artifact) => {
|
|
158
|
+
setActive(null);
|
|
159
|
+
onOpenArtifact(artifact);
|
|
160
|
+
} }))] })] }))] }));
|
|
161
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "../../styles/transcript-loading.css";
|
|
2
|
+
export declare function TranscriptLoading({ error, waitingForTeam, seeking, canContinue, indexing, onRetry, onContinue }: {
|
|
3
|
+
readonly error: string | null;
|
|
4
|
+
readonly waitingForTeam: boolean;
|
|
5
|
+
readonly seeking: boolean;
|
|
6
|
+
readonly canContinue: boolean;
|
|
7
|
+
readonly indexing: boolean;
|
|
8
|
+
readonly onRetry: () => void;
|
|
9
|
+
readonly onContinue: () => void;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../../styles/transcript-loading.css";
|
|
3
|
+
export function TranscriptLoading({ error, waitingForTeam, seeking, canContinue, indexing, onRetry, onContinue }) {
|
|
4
|
+
const label = error !== null ? "Couldn’t load messages"
|
|
5
|
+
: waitingForTeam ? "Loading team messages…"
|
|
6
|
+
: seeking ? "Finding message…"
|
|
7
|
+
: indexing ? "Preparing messages…" : "Loading messages…";
|
|
8
|
+
return _jsx("div", { className: "tr-loading", "data-error": error !== null || undefined, children: _jsxs("div", { className: "tr-loading__body", children: [_jsxs("div", { className: "tr-loading__sketch", "aria-hidden": "true", children: [_jsxs("div", { className: "tr-loading__prompt", children: [_jsx("i", {}), _jsx("i", {})] }), _jsxs("div", { className: "tr-loading__reply", children: [_jsxs("div", { className: "tr-loading__byline", children: [_jsx("b", {}), _jsx("i", {})] }), _jsx("i", {}), _jsx("i", {}), _jsx("i", {})] }), _jsxs("div", { className: "tr-loading__fold", children: [_jsx("b", { children: "\u203A" }), _jsx("i", {})] })] }), _jsxs("div", { className: "tr-loading__status", role: "status", "aria-live": "polite", "aria-atomic": "true", children: [error === null && _jsx("div", { className: "tr-loading__meter", "aria-hidden": "true", children: _jsx("i", {}) }), _jsx("strong", { children: label }), error !== null && _jsx("p", { children: error })] }), error !== null ? _jsx("button", { type: "button", onClick: onRetry, children: "Try again" })
|
|
9
|
+
: canContinue && _jsx("button", { type: "button", onClick: onContinue, children: "Read available messages" })] }) });
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FetchFact, SourceFact } from "../../lib/transcript/index.js";
|
|
2
|
+
export declare function SourceList({ sources, total }: {
|
|
3
|
+
readonly sources: readonly SourceFact[];
|
|
4
|
+
readonly total: number | null;
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare function FetchDetails({ fetches }: {
|
|
7
|
+
readonly fetches: readonly FetchFact[];
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useSetSiteIconsEnabled, useSiteIconsEnabled } from "../../lib/transcript/favicons.js";
|
|
4
|
+
import { webAddress } from "../../lib/transcript/web-address.js";
|
|
5
|
+
import { Favicon } from "./Favicon.js";
|
|
6
|
+
/** One shared preference, exposed beside the content it controls. */
|
|
7
|
+
function SiteIconsSetting() {
|
|
8
|
+
const enabled = useSiteIconsEnabled();
|
|
9
|
+
const setSiteIconsEnabled = useSetSiteIconsEnabled();
|
|
10
|
+
return (_jsxs("label", { className: "tr-site-icons", title: "Load icons directly from their sites. Applies to all web activity.", children: [_jsx("input", { type: "checkbox", checked: enabled, onChange: (event) => setSiteIconsEnabled(event.target.checked) }), "Fetch site icons"] }));
|
|
11
|
+
}
|
|
12
|
+
const SOURCE_PREVIEW_LIMIT = 24;
|
|
13
|
+
export function SourceList({ sources, total }) {
|
|
14
|
+
const [expanded, setExpanded] = useState(false);
|
|
15
|
+
const shown = expanded ? sources : sources.slice(0, SOURCE_PREVIEW_LIMIT);
|
|
16
|
+
const omitted = total === null ? null : Math.max(0, total - sources.length);
|
|
17
|
+
return (_jsxs(_Fragment, { children: [shown.length > 0 && (_jsx("ul", { className: "tr-src", children: shown.map((source, at) => {
|
|
18
|
+
const address = webAddress(source.url);
|
|
19
|
+
const title = source.title || source.url;
|
|
20
|
+
const content = (_jsxs(_Fragment, { children: [_jsx(Favicon, { host: address?.host ?? null }), _jsx("span", { className: "title", children: title }), _jsx("span", { className: "dom", children: address?.host ?? "unknown site" })] }));
|
|
21
|
+
return (_jsx("li", { children: address ? (_jsx("a", { className: "tr-src__row", href: address.href, target: "_blank", rel: "noreferrer", title: `${title}\n${source.url}`, children: content })) : (_jsx("span", { className: "tr-src__row", title: source.url, children: content })) }, `${source.url}-${at}`));
|
|
22
|
+
}) })), sources.length === 0 && (_jsx("p", { className: "tr-web-note", children: total === 0 ? "No sources found." : "No source details recorded." })), sources.length > SOURCE_PREVIEW_LIMIT && (_jsx("button", { className: "tr-web-more", type: "button", "aria-expanded": expanded, onClick: () => setExpanded(!expanded), children: expanded ? "Show fewer sources" : `Show all ${sources.length} recorded sources` })), omitted !== null && omitted > 0 && (_jsxs("p", { className: "tr-web-note", children: [omitted, " additional ", omitted === 1 ? "source was" : "sources were", " not retained."] })), total === null && sources.length > 0 && (_jsx("p", { className: "tr-web-note", children: "Some source details were not recorded." })), _jsx(SiteIconsSetting, {})] }));
|
|
23
|
+
}
|
|
24
|
+
export function FetchDetails({ fetches }) {
|
|
25
|
+
return (_jsxs(_Fragment, { children: [fetches.map((fetch, at) => {
|
|
26
|
+
const address = webAddress(fetch.url);
|
|
27
|
+
return (_jsxs("dl", { className: "tr-kv tr-fetch", children: [fetch.url !== null && (_jsxs(_Fragment, { children: [_jsx("dt", { children: "url" }), _jsx("dd", { children: address ? (_jsx("a", { href: address.href, target: "_blank", rel: "noreferrer", children: fetch.url })) : fetch.url })] })), fetch.title !== null && (_jsxs(_Fragment, { children: [_jsx("dt", { children: "title" }), _jsxs("dd", { "data-prose": "", children: [_jsx(Favicon, { host: address?.host ?? null }), " ", fetch.title] })] })), fetch.status !== null && _jsxs(_Fragment, { children: [_jsx("dt", { children: "status" }), _jsxs("dd", { children: ["HTTP ", fetch.status] })] }), fetch.url === null && fetch.title === null && fetch.status === null && (_jsxs(_Fragment, { children: [_jsx("dt", { children: "page" }), _jsx("dd", { children: "No page details recorded." })] }))] }, at));
|
|
28
|
+
}), _jsx(SiteIconsSetting, {})] }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { PathFact, WorkflowAttemptFact, WorkflowFact } from "../../lib/transcript/index.js";
|
|
3
|
+
export interface WorkflowChildThread {
|
|
4
|
+
readonly childSessionId: string;
|
|
5
|
+
readonly node: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare function WorkflowDetail({ fact, attempts, children: childThreads, onOpenPath, }: {
|
|
8
|
+
readonly fact: WorkflowFact;
|
|
9
|
+
readonly attempts: readonly WorkflowAttemptFact[];
|
|
10
|
+
readonly children: readonly WorkflowChildThread[];
|
|
11
|
+
readonly onOpenPath?: ((path: PathFact) => void) | undefined;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { AgentMark } from "../../lib/agents.js";
|
|
4
|
+
import { clock, tokenText } from "../../lib/format.js";
|
|
5
|
+
import { useReadingSession, useRoom } from "../../room-context.js";
|
|
6
|
+
import { canonicalText, firstLine, workflowRuntime, workflowWorkerState, } from "../../lib/transcript/index.js";
|
|
7
|
+
import { LineChevron } from "./glyphs.js";
|
|
8
|
+
import { PathList } from "./detail-parts.js";
|
|
9
|
+
function elapsed(ms) {
|
|
10
|
+
const seconds = Math.max(0, Math.round(ms / 1000));
|
|
11
|
+
if (seconds < 60)
|
|
12
|
+
return `${seconds}s`;
|
|
13
|
+
const minutes = Math.floor(seconds / 60);
|
|
14
|
+
const rest = seconds % 60;
|
|
15
|
+
if (minutes < 60)
|
|
16
|
+
return rest === 0 ? `${minutes}m` : `${minutes}m ${rest}s`;
|
|
17
|
+
const hours = Math.floor(minutes / 60);
|
|
18
|
+
const mins = minutes % 60;
|
|
19
|
+
return mins === 0 ? `${hours}h` : `${hours}h ${String(mins).padStart(2, "0")}m`;
|
|
20
|
+
}
|
|
21
|
+
function quantity(value, one, many = `${one}s`) {
|
|
22
|
+
return `${value} ${value === 1 ? one : many}`;
|
|
23
|
+
}
|
|
24
|
+
function workerUsage(worker) {
|
|
25
|
+
if (worker.cached)
|
|
26
|
+
return "cached";
|
|
27
|
+
const parts = [
|
|
28
|
+
worker.duration_ms === null ? null : elapsed(worker.duration_ms),
|
|
29
|
+
worker.tokens === null ? null : tokenText(worker.tokens),
|
|
30
|
+
worker.tool_calls === null ? null : quantity(worker.tool_calls, "tool"),
|
|
31
|
+
].filter((part) => part !== null);
|
|
32
|
+
return parts.length === 0 ? null : parts.join(" · ");
|
|
33
|
+
}
|
|
34
|
+
function friendlyModel(model) {
|
|
35
|
+
const match = /^claude-(opus|sonnet|haiku)-(\d+)(?:[-.](\d+))?(?:-|$)/i.exec(model);
|
|
36
|
+
if (match === null)
|
|
37
|
+
return model;
|
|
38
|
+
const family = match[1][0].toUpperCase() + match[1].slice(1).toLowerCase();
|
|
39
|
+
return `${family} ${match[2]}${match[3] === undefined ? "" : `.${match[3]}`}`;
|
|
40
|
+
}
|
|
41
|
+
function RuntimeLine({ runtime }) {
|
|
42
|
+
return (_jsxs("span", { className: "wf-worker__runtime", children: [_jsx("span", { className: "wf-worker__basis", children: runtime.basis }), " ", _jsx("b", { children: friendlyModel(runtime.model) }), " ", _jsxs("span", { children: ["\u00B7 ", runtime.effort === "unknown" ? "effort unknown" : `${runtime.effort} effort`] })] }));
|
|
43
|
+
}
|
|
44
|
+
function workerDescription(worker) {
|
|
45
|
+
return worker.result_preview ?? worker.last_tool_summary ?? worker.prompt_preview;
|
|
46
|
+
}
|
|
47
|
+
function workerDescriptionLine(description) {
|
|
48
|
+
return firstLine(description.replace(/^#{1,6}\s+/, ""), 72);
|
|
49
|
+
}
|
|
50
|
+
function WorkerRow({ worker, run, child, }) {
|
|
51
|
+
const [open, setOpen] = useState(false);
|
|
52
|
+
const runtime = workflowRuntime(worker, run.default_model);
|
|
53
|
+
const state = workflowWorkerState(worker, run.status);
|
|
54
|
+
const description = workerDescription(worker);
|
|
55
|
+
const expandable = child !== null || description !== null || worker.error !== null;
|
|
56
|
+
const visualState = state === "error" ? "failed" : state === "running" ? "running" : undefined;
|
|
57
|
+
const body = worker.error ?? description;
|
|
58
|
+
const summary = (_jsxs(_Fragment, { children: [_jsx("span", { className: "tr-line__g tm-avatar", "aria-hidden": "true", children: _jsx(AgentMark, { kind: "claude-code" }) }), _jsx("span", { className: "tr-line__v", title: worker.label, children: worker.label }), _jsx("span", { className: "tr-line__o", title: description ?? undefined, children: description === null ? "no summary recorded" : workerDescriptionLine(description) }), _jsxs("span", { className: "tr-line__r", children: [_jsx("span", { className: visualState === "failed" || visualState === "running" ? "why" : undefined, children: state }), expandable && _jsx("span", { className: "chev", children: _jsx(LineChevron, {}) })] }), _jsx(RuntimeLine, { runtime: runtime }), workerUsage(worker) !== null && _jsx("span", { className: "wf-worker__usage", children: workerUsage(worker) })] }));
|
|
59
|
+
if (!expandable) {
|
|
60
|
+
return _jsx("div", { className: "tr-line wf-worker", "data-state": visualState, children: summary });
|
|
61
|
+
}
|
|
62
|
+
return (_jsxs("details", { className: "wf-worker-thread", open: open, onToggle: (event) => setOpen(event.currentTarget.open), children: [_jsx("summary", { className: "tr-line wf-worker", "data-state": visualState, children: summary }), _jsxs("div", { className: "wf-worker__detail", children: [body !== null && (_jsx("div", { className: "wf-worker__result", "data-state": worker.error === null ? undefined : "failed", children: _jsx("p", { children: body }) })), open && child] })] }));
|
|
63
|
+
}
|
|
64
|
+
function phaseGroups(run) {
|
|
65
|
+
const known = new Set();
|
|
66
|
+
const groups = run.phases.map((phase) => {
|
|
67
|
+
known.add(phase.index);
|
|
68
|
+
return {
|
|
69
|
+
index: phase.index,
|
|
70
|
+
title: phase.title,
|
|
71
|
+
detail: phase.detail,
|
|
72
|
+
workers: run.workers.filter((worker) => worker.phase_index === phase.index),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
const orphaned = run.workers.filter((worker) => worker.phase_index === null || !known.has(worker.phase_index));
|
|
76
|
+
if (orphaned.length > 0) {
|
|
77
|
+
groups.push({
|
|
78
|
+
index: groups.length === 0 ? 1 : Math.max(...groups.map((group) => group.index)) + 1,
|
|
79
|
+
title: "Other workers",
|
|
80
|
+
detail: "phase was not recorded",
|
|
81
|
+
workers: orphaned,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return groups;
|
|
85
|
+
}
|
|
86
|
+
function Phase({ phase, run, current, children, }) {
|
|
87
|
+
const [open, setOpen] = useState(current);
|
|
88
|
+
const done = phase.workers.filter((worker) => worker.state === "done").length;
|
|
89
|
+
const errors = phase.workers.filter((worker) => worker.state === "error").length;
|
|
90
|
+
const count = `${done}/${phase.workers.length}${errors === 0 ? "" : ` · ${errors} error${errors === 1 ? "" : "s"}`}`;
|
|
91
|
+
return (_jsxs("details", { className: "wf-phase", open: open, onToggle: (event) => setOpen(event.currentTarget.open), children: [_jsxs("summary", { className: "wf-phase__head", children: [_jsx("span", { className: "wf-phase__index", children: phase.index }), _jsxs("span", { className: "wf-phase__name", children: [_jsx("strong", { children: phase.title }), phase.detail !== null && _jsx("span", { title: phase.detail, children: phase.detail })] }), _jsx("span", { className: "wf-phase__count", children: count }), _jsx("span", { className: "chev", children: _jsx(LineChevron, {}) })] }), _jsx("div", { className: "wf-phase__workers", children: phase.workers.length === 0 ? (_jsx("p", { className: "wf-empty", children: "No workers recorded for this phase" })) : phase.workers.map((worker) => (_jsx(WorkerRow, { worker: worker, run: run, child: worker.child_session_id === null ? null : (children.get(worker.child_session_id) ?? null) }, `${worker.index}-${worker.key ?? worker.label}`))) })] }));
|
|
92
|
+
}
|
|
93
|
+
function attemptOutcome(attempt, latest, run) {
|
|
94
|
+
if (latest && run !== null && run.status !== "unknown")
|
|
95
|
+
return run.status;
|
|
96
|
+
switch (attempt.status) {
|
|
97
|
+
case "succeeded": return "completed";
|
|
98
|
+
case "pending":
|
|
99
|
+
case "running": return "running";
|
|
100
|
+
case "timed_out": return "timed out";
|
|
101
|
+
case "cancelled": return "cancelled";
|
|
102
|
+
case "interrupted": return "interrupted";
|
|
103
|
+
case "denied": return "denied";
|
|
104
|
+
case "failed": return "failed";
|
|
105
|
+
case "unknown": return "status unknown";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function Attempts({ attempts, run, }) {
|
|
109
|
+
if (attempts.length === 0)
|
|
110
|
+
return null;
|
|
111
|
+
const total = Math.max(run?.attempt_total_count ?? 0, attempts.length);
|
|
112
|
+
const omitted = total - attempts.length;
|
|
113
|
+
return (_jsxs("section", { className: "wf-attempts", "aria-label": "Workflow attempts", children: [_jsx("span", { className: "wf-section-label", children: "Attempts" }), omitted > 0 && (_jsxs("p", { className: "wf-empty", children: [quantity(omitted, "earlier attempt"), " omitted from this view"] })), attempts.map((attempt, at) => {
|
|
114
|
+
const outcome = attemptOutcome(attempt, at === attempts.length - 1, run);
|
|
115
|
+
const state = ["failed", "denied", "timed out"].includes(outcome)
|
|
116
|
+
? "failed"
|
|
117
|
+
: outcome === "running" ? "running" : undefined;
|
|
118
|
+
const measured = attempt.durationMs ?? (at === attempts.length - 1 ? run?.usage.duration_ms ?? null : null);
|
|
119
|
+
return (_jsxs("div", { className: "wf-attempt", "data-state": state, title: attempt.taskId ?? undefined, children: [_jsx("i", { className: "wf-attempt__dot", "aria-hidden": "true" }), _jsxs("strong", { children: ["Attempt ", attempt.attempt] }), _jsxs("span", { className: "wf-attempt__launch", children: [attempt.resumed ? "resume" : "async launch", attempt.at === null ? "" : ` · ${clock(attempt.at)}`] }), _jsxs("span", { className: "wf-attempt__outcome", children: [outcome, measured === null ? "" : ` · ${elapsed(measured)}`] })] }, attempt.timelineId));
|
|
120
|
+
})] }));
|
|
121
|
+
}
|
|
122
|
+
function fieldLabel(key) {
|
|
123
|
+
return key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll("_", " ").toLowerCase();
|
|
124
|
+
}
|
|
125
|
+
function resultFields(text) {
|
|
126
|
+
try {
|
|
127
|
+
const value = JSON.parse(text);
|
|
128
|
+
if (value === null || Array.isArray(value) || typeof value !== "object")
|
|
129
|
+
return [];
|
|
130
|
+
return Object.entries(value).slice(0, 16).map(([key, item]) => ({
|
|
131
|
+
label: fieldLabel(key),
|
|
132
|
+
value: typeof item === "string" ? item : JSON.stringify(item),
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function FullResult({ canonical }) {
|
|
140
|
+
const [open, setOpen] = useState(false);
|
|
141
|
+
const [loaded, setLoaded] = useState(null);
|
|
142
|
+
const member = canonical.type === "member" ? canonical : null;
|
|
143
|
+
const { sessions } = useRoom();
|
|
144
|
+
const readingSession = useReadingSession();
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (!open
|
|
147
|
+
|| member === null
|
|
148
|
+
|| (loaded?.digest === member.asset.digest && loaded.text !== null))
|
|
149
|
+
return;
|
|
150
|
+
const controller = new AbortController();
|
|
151
|
+
const digest = member.asset.digest;
|
|
152
|
+
setLoaded({ digest, text: null, error: null });
|
|
153
|
+
const read = readingSession === null
|
|
154
|
+
? Promise.reject(new Error("No session is open to read the stored result"))
|
|
155
|
+
: sessions.run(readingSession, (client) => client.readTextAsset(member.asset, controller.signal));
|
|
156
|
+
void read.then((text) => setLoaded({ digest, text, error: null }), (error) => {
|
|
157
|
+
if (controller.signal.aborted)
|
|
158
|
+
return;
|
|
159
|
+
setLoaded({
|
|
160
|
+
digest,
|
|
161
|
+
text: null,
|
|
162
|
+
error: error instanceof Error ? error.message : "stored result is unavailable",
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
return () => controller.abort();
|
|
166
|
+
}, [member, open, sessions, readingSession]);
|
|
167
|
+
const body = canonical.type === "inline"
|
|
168
|
+
? canonical.text
|
|
169
|
+
: loaded?.digest !== canonical.asset.digest
|
|
170
|
+
? "Loading full result…"
|
|
171
|
+
: loaded.error ?? loaded.text ?? "Loading full result…";
|
|
172
|
+
return (_jsxs("details", { className: "wf-full-result", open: open, onToggle: (event) => setOpen(event.currentTarget.open), children: [_jsx("summary", { className: "wf-action", children: "View full result" }), open && _jsx("pre", { className: "tr-diag", children: body })] }));
|
|
173
|
+
}
|
|
174
|
+
function Result({ fact, onOpenPath, }) {
|
|
175
|
+
const run = fact.action.run ?? null;
|
|
176
|
+
const canonical = run?.result ?? fact.action.callback_result ?? null;
|
|
177
|
+
const text = canonical === null ? null : canonicalText(canonical);
|
|
178
|
+
const allFields = canonical?.type === "inline" ? resultFields(canonical.text) : [];
|
|
179
|
+
const resourcePaths = new Set(fact.resources.flatMap((resource) => resource.resource.type === "file" ? [resource.resource.path] : []));
|
|
180
|
+
const fields = allFields.filter((field) => !(field.label === "final doc" && resourcePaths.has(field.value)));
|
|
181
|
+
const resourceLabel = allFields.some((field) => field.label === "final doc" && resourcePaths.has(field.value)) && fact.resources.length === 1
|
|
182
|
+
? "final document"
|
|
183
|
+
: "files";
|
|
184
|
+
const journal = run?.journal ?? [];
|
|
185
|
+
const loadedStarted = journal.filter((observation) => observation.kind === "started").length;
|
|
186
|
+
const loadedReturned = journal.filter((observation) => observation.kind === "result").length;
|
|
187
|
+
const journalTotal = Math.max(run?.journal_total_count ?? 0, journal.length);
|
|
188
|
+
const started = Math.max(run?.journal_started_count ?? 0, loadedStarted);
|
|
189
|
+
const returned = Math.max(run?.journal_result_count ?? 0, loadedReturned);
|
|
190
|
+
const error = run?.error === null || run?.error === undefined ? null : canonicalText(run.error);
|
|
191
|
+
if (text === null && fact.resources.length === 0 && error === null)
|
|
192
|
+
return null;
|
|
193
|
+
return (_jsxs("section", { className: "wf-result", "aria-label": "Workflow result", children: [_jsx("span", { className: "wf-section-label", children: "Result" }), fact.resources.length > 0 && (_jsxs("div", { className: "wf-result__resources", children: [_jsx("span", { children: resourceLabel }), _jsx(PathList, { paths: fact.resources, total: fact.resources.length, onOpenPath: onOpenPath })] })), fields.length > 0 ? (_jsx("dl", { className: "wf-output", children: fields.map((field) => (_jsxs("div", { className: "wf-output__row", children: [_jsx("dt", { children: field.label }), _jsx("dd", { className: field.label === "verdict" ? "wf-output__verdict" : undefined, children: field.value })] }, field.label))) })) : text !== null ? (canonical !== null && _jsx(FullResult, { canonical: canonical })) : null, error !== null && _jsx("pre", { className: "tr-diag wf-result__error", children: error }), _jsxs("div", { className: "wf-result__foot", children: [_jsxs("span", { children: ["terminal evidence \u00B7 ", run === null ? "correlated task notification" : "run snapshot + correlated task notification", journalTotal === 0 ? "" : ` · journal ${started} started, ${returned} results`] }), fields.length > 0 && canonical !== null && _jsx(FullResult, { canonical: canonical })] })] }));
|
|
194
|
+
}
|
|
195
|
+
export function WorkflowDetail({ fact, attempts, children: childThreads, onOpenPath, }) {
|
|
196
|
+
const run = fact.action.run ?? null;
|
|
197
|
+
const childMap = new Map(childThreads.map((child) => [child.childSessionId, child.node]));
|
|
198
|
+
const name = run?.name ?? fact.action.name ?? "dynamic workflow";
|
|
199
|
+
const groups = run === null ? [] : phaseGroups(run);
|
|
200
|
+
const activePhase = groups.find((phase) => phase.workers.some((worker) => worker.state === "progress"));
|
|
201
|
+
const initialPhase = activePhase?.index ?? groups.at(-1)?.index ?? null;
|
|
202
|
+
const workerCount = run?.usage.agent_count ?? run?.workers.length ?? null;
|
|
203
|
+
const finished = run?.updated_at ?? null;
|
|
204
|
+
return (_jsxs("div", { className: "wf-run__detail", children: [_jsxs("div", { className: "wf-run__mast", children: [_jsxs("div", { className: "wf-run__title", children: [_jsx("strong", { children: name }), (run?.run_id ?? fact.action.run_id) !== null && (_jsx("span", { className: "wf-run__id", children: run?.run_id ?? fact.action.run_id })), finished !== null && (_jsxs("span", { className: "wf-run__finished", children: [run?.status === "running" ? "updated" : "finished", " ", clock(finished)] }))] }), fact.objective !== null && _jsx("p", { className: "wf-run__objective", children: fact.objective }), _jsxs("div", { className: "wf-run__facts", children: [workerCount !== null && _jsxs("span", { children: [_jsx("b", { children: workerCount }), " workers"] }), run !== null && _jsxs("span", { children: [_jsx("b", { children: run.phases.length }), " phases"] }), run?.usage.tokens !== null && run?.usage.tokens !== undefined && _jsxs("span", { children: [_jsx("b", { children: tokenText(run.usage.tokens) }), " tokens"] }), run?.usage.tool_calls !== null && run?.usage.tool_calls !== undefined && _jsxs("span", { children: [_jsx("b", { children: run.usage.tool_calls }), " tools"] }), _jsxs("span", { className: "wf-run__actions", children: [fact.script !== null && (_jsx("button", { className: "wf-action", type: "button", disabled: fact.script.read === undefined || onOpenPath === undefined, onClick: () => {
|
|
205
|
+
if (fact.script !== null)
|
|
206
|
+
onOpenPath?.(fact.script);
|
|
207
|
+
}, children: "View workflow script" })), run !== null && run.logs.length > 0 && (_jsxs("details", { className: "wf-logs", children: [_jsx("summary", { className: "wf-action", children: quantity(run.logs.length, "log") }), _jsx("pre", { className: "tr-diag", children: run.logs.join("\n") })] }))] })] })] }), _jsx(Attempts, { attempts: attempts, run: run }), run !== null && groups.length > 0 && (_jsxs("section", { className: "wf-phases", "aria-label": "Workflow phases", children: [_jsx("span", { className: "wf-section-label", children: "Phases" }), groups.map((phase) => (_jsx(Phase, { phase: phase, run: run, current: phase.index === initialPhase, children: childMap }, `${phase.index}-${phase.title}`)))] })), _jsx(Result, { fact: fact, onOpenPath: onOpenPath }), run === null && fact.action.arguments !== null && fact.objective === null && (_jsx("pre", { className: "tr-diag", children: canonicalText(fact.action.arguments) }))] }));
|
|
208
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { TimelineEntry } from "@vibefield/rosetta-protocol";
|
|
2
|
+
import type { LedgerLine } from "../../lib/transcript/ledger.js";
|
|
3
|
+
import type { Prompt, ResponseHead, Segment } from "../../lib/transcript/turns.js";
|
|
4
|
+
import type { PlannedSitting } from "./document-plan.js";
|
|
5
|
+
export type ActivityItem = {
|
|
6
|
+
readonly kind: "tool";
|
|
7
|
+
readonly key: string;
|
|
8
|
+
readonly line: LedgerLine;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: "prompt";
|
|
11
|
+
readonly key: string;
|
|
12
|
+
readonly prompt: Prompt;
|
|
13
|
+
} | Exclude<Segment, {
|
|
14
|
+
kind: "ledger" | "prose";
|
|
15
|
+
}>;
|
|
16
|
+
export type ReadingBlock = {
|
|
17
|
+
readonly kind: "prompt";
|
|
18
|
+
readonly key: string;
|
|
19
|
+
readonly prompts: readonly Prompt[];
|
|
20
|
+
readonly at: number | null;
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: "reply";
|
|
23
|
+
readonly key: string;
|
|
24
|
+
readonly segment: Extract<Segment, {
|
|
25
|
+
kind: "prose";
|
|
26
|
+
}>;
|
|
27
|
+
readonly head: ResponseHead | null;
|
|
28
|
+
readonly at: number | null;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "activity";
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly items: readonly ActivityItem[];
|
|
33
|
+
readonly rows: readonly TimelineEntry[];
|
|
34
|
+
readonly partial: boolean;
|
|
35
|
+
readonly at: number | null;
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: "request";
|
|
38
|
+
readonly key: string;
|
|
39
|
+
readonly item: ActivityItem;
|
|
40
|
+
readonly at: number | null;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: "gap";
|
|
43
|
+
readonly key: string;
|
|
44
|
+
readonly count: number;
|
|
45
|
+
readonly at: number | null;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: "watermark";
|
|
48
|
+
readonly key: string;
|
|
49
|
+
readonly at: number | null;
|
|
50
|
+
};
|
|
51
|
+
export interface ReadingSitting {
|
|
52
|
+
/** React identity is separate from the canonical day-navigation anchor. */
|
|
53
|
+
readonly renderKey?: string;
|
|
54
|
+
readonly sitting: PlannedSitting["sitting"];
|
|
55
|
+
readonly blocks: readonly ReadingBlock[];
|
|
56
|
+
}
|
|
57
|
+
export declare function activityRows(item: ActivityItem): readonly TimelineEntry[];
|
|
58
|
+
export declare function activityRowKey(row: TimelineEntry): string;
|
|
59
|
+
/** Tool lines must already have been cut at these boundaries before coalescing. */
|
|
60
|
+
export declare function activityCuts(rows: readonly TimelineEntry[], watermark: number | null, displayedRows?: readonly TimelineEntry[]): {
|
|
61
|
+
gaps: Map<string, number>;
|
|
62
|
+
watermarkId: string | null;
|
|
63
|
+
cutBefore: Set<string>;
|
|
64
|
+
};
|
|
65
|
+
export declare function activityPlan(plan: readonly PlannedSitting[], options: {
|
|
66
|
+
readonly gaps: ReadonlyMap<string, number>;
|
|
67
|
+
readonly watermarkId: string | null;
|
|
68
|
+
readonly partial: boolean;
|
|
69
|
+
}): ReadingSitting[];
|
|
70
|
+
export interface ActivitySummary {
|
|
71
|
+
readonly nouns: readonly {
|
|
72
|
+
readonly key: string;
|
|
73
|
+
readonly text: string;
|
|
74
|
+
readonly names: readonly string[];
|
|
75
|
+
readonly more: number;
|
|
76
|
+
}[];
|
|
77
|
+
readonly failed: number;
|
|
78
|
+
readonly interrupted: number;
|
|
79
|
+
readonly cancelled: number;
|
|
80
|
+
readonly runningRows: readonly TimelineEntry[];
|
|
81
|
+
readonly firstAt: number | null;
|
|
82
|
+
readonly lastAt: number | null;
|
|
83
|
+
}
|
|
84
|
+
export declare function summarizeActivity(items: readonly ActivityItem[]): ActivitySummary;
|