@vibefield/rosetta-room 0.0.0-stage → 0.1.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 +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,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// §08 — the head line, the pull bar, the failure sentences, the session start.
|
|
3
|
+
//
|
|
4
|
+
// A marker that counts, in the marker family's bare-text form, plus one
|
|
5
|
+
// instrument: the veil's colourless bar. The line measures the SESSION; the
|
|
6
|
+
// scrollbar measures the loaded document. Everything it renders comes from
|
|
7
|
+
// `describeHead`, so what it draws is provable without a DOM.
|
|
8
|
+
import { clock } from "../../lib/format.js";
|
|
9
|
+
import { describeHead } from "../../lib/transcript/head-state.js";
|
|
10
|
+
import "../../styles/transcript-head.css";
|
|
11
|
+
/** `Mon 31 Aug · 23:18:12` — the session's first second, said as a fact.
|
|
12
|
+
* Absolute, never "Today": the start of a session is a date, not a distance. */
|
|
13
|
+
export function sessionStartLabel(startedAt) {
|
|
14
|
+
if (startedAt === null || !Number.isFinite(startedAt))
|
|
15
|
+
return null;
|
|
16
|
+
const words = new Date(startedAt).toLocaleDateString("en-GB", {
|
|
17
|
+
weekday: "short",
|
|
18
|
+
day: "numeric",
|
|
19
|
+
month: "short",
|
|
20
|
+
});
|
|
21
|
+
return `${words} · ${clock(startedAt)}`;
|
|
22
|
+
}
|
|
23
|
+
/** The top fade — one sticky, zero-height element at the head of the scroller
|
|
24
|
+
* whose pseudo-element paints the gradient. Mount it as the FIRST child of
|
|
25
|
+
* `.ah-scroll`; `useHeadOfDocument` writes `--frost` onto the scroller. */
|
|
26
|
+
export function TopFade() {
|
|
27
|
+
return _jsx("div", { className: "tr-frost", "aria-hidden": "true" });
|
|
28
|
+
}
|
|
29
|
+
function HeadLine({ view, onRetry }) {
|
|
30
|
+
return (_jsxs("div", { className: "tr-top", "data-state": view.state, children: [_jsxs("div", { className: "tr-top__line", children: [view.lead !== "" && _jsx("span", { children: view.lead }), view.figure !== null && _jsx("b", { children: view.figure }), view.trail !== "" && _jsx("span", { children: view.trail }), view.retry && (_jsx("button", { type: "button", onClick: onRetry, children: "retry" }))] }), view.bar && (_jsx("div", { className: "tr-top__bar", children: _jsx("i", { style: view.fill === null ? undefined : { width: view.fill } }) }))] }));
|
|
31
|
+
}
|
|
32
|
+
export function HeadOfDocument({ feed, pull, startedAt, finding }) {
|
|
33
|
+
const view = describeHead({
|
|
34
|
+
earlier: feed.earlier,
|
|
35
|
+
above: feed.earlierAbove,
|
|
36
|
+
pull,
|
|
37
|
+
finding: finding ?? null,
|
|
38
|
+
startLabel: sessionStartLabel(startedAt),
|
|
39
|
+
});
|
|
40
|
+
return (_jsxs(_Fragment, { children: [_jsx(HeadLine, { view: view, onRetry: feed.retryEarlier }), feed.earlierNotice !== null && (
|
|
41
|
+
// Losing the place is stated, not hidden. Muted, never red — nothing
|
|
42
|
+
// was destroyed; the tail the reader is looking at is already current.
|
|
43
|
+
_jsx("div", { className: "tr-top", "data-state": "rewritten", children: _jsx("div", { className: "tr-top__line", children: _jsx("span", { children: feed.earlierNotice.message }) }) }))] }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { AttachmentFact, LedgerLine, LedgerMember, PathFact, RunSummary, TeamMemberPresentation, WorkflowAttemptFact } from "../../lib/transcript/index.js";
|
|
3
|
+
import type { WorkflowChildThread } from "./Workflow.js";
|
|
4
|
+
export interface LineProps {
|
|
5
|
+
readonly line: LedgerLine;
|
|
6
|
+
readonly domId: string;
|
|
7
|
+
readonly hit: boolean;
|
|
8
|
+
/** A live session below the watermark: the only place the green breath is
|
|
9
|
+
* honest (§04's status rows). */
|
|
10
|
+
readonly alive: boolean;
|
|
11
|
+
/** Force the line open — a search hit landed inside it. */
|
|
12
|
+
readonly forceOpen: boolean;
|
|
13
|
+
/** The child runs this line owns, already built (§03 F). */
|
|
14
|
+
readonly subthreads: readonly WorkflowChildThread[];
|
|
15
|
+
readonly workflowAttempts: readonly WorkflowAttemptFact[];
|
|
16
|
+
readonly hasChildren: boolean;
|
|
17
|
+
/** A later contact with an already-mounted worker navigates to the original
|
|
18
|
+
* disclosure instead of opening an empty duplicate. */
|
|
19
|
+
readonly onOpenLinkedChild: (() => void) | null;
|
|
20
|
+
readonly onOpenPath: (path: PathFact) => void;
|
|
21
|
+
}
|
|
22
|
+
export declare function Line({ line, domId, hit, alive, forceOpen, subthreads, workflowAttempts, hasChildren, onOpenLinkedChild, onOpenPath, }: LineProps): import("react").JSX.Element;
|
|
23
|
+
export interface LedgerProps {
|
|
24
|
+
/** A §04B group owns the outer fold; these are its existing tool rows. */
|
|
25
|
+
readonly embedded?: boolean;
|
|
26
|
+
/** The ladder in order: lines, and the thoughts, markers and summaries
|
|
27
|
+
* that happened between them (R-1). */
|
|
28
|
+
readonly members: readonly LedgerMember[];
|
|
29
|
+
readonly summary: RunSummary;
|
|
30
|
+
/** The margin anchor of a closed run, drawn by the caller (T-4). */
|
|
31
|
+
readonly anchor?: ReactNode;
|
|
32
|
+
readonly domIdOf: (timelineId: string) => string;
|
|
33
|
+
readonly highlightedTimelineId: string | null;
|
|
34
|
+
/** The reader is being sent to a row inside this run. */
|
|
35
|
+
readonly focusTimelineId: string | null;
|
|
36
|
+
readonly alive: (line: LedgerLine) => boolean;
|
|
37
|
+
readonly subthreadsFor: (line: LedgerLine) => readonly WorkflowChildThread[];
|
|
38
|
+
readonly workflowAttemptsFor: (line: LedgerLine) => readonly WorkflowAttemptFact[];
|
|
39
|
+
readonly hasChildren: (line: LedgerLine) => boolean;
|
|
40
|
+
/** A search hit landed inside a CHILD run this line owns: the line has to
|
|
41
|
+
* open for the subthread to mount at all, so the reader is not sent to an
|
|
42
|
+
* element that does not exist yet. */
|
|
43
|
+
readonly childFocused: (line: LedgerLine) => boolean;
|
|
44
|
+
/** The already-anchored worker named by a later delegate/resume line. */
|
|
45
|
+
readonly linkedChildId: (line: LedgerLine) => string | null;
|
|
46
|
+
readonly onOpenLinkedChild: (childId: string) => void;
|
|
47
|
+
/** A proven team delegate replaces the generic delegate sentence with its
|
|
48
|
+
* roster operation. Ordinary Agent workers return null and keep Line. */
|
|
49
|
+
readonly teamMemberFor: (line: LedgerLine) => TeamMemberPresentation | null;
|
|
50
|
+
readonly onOpenPath: (path: PathFact) => void;
|
|
51
|
+
readonly onOpenAttachment: (fact: AttachmentFact, row?: readonly AttachmentFact[]) => void;
|
|
52
|
+
}
|
|
53
|
+
export declare function Ledger({ embedded, members, summary, anchor, domIdOf, highlightedTimelineId, focusTimelineId, alive, subthreadsFor, workflowAttemptsFor, hasChildren, childFocused, linkedChildId, onOpenLinkedChild, teamMemberFor, onOpenPath, onOpenAttachment, }: LedgerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { clock } from "../../lib/format.js";
|
|
4
|
+
import { objectText, spanText } from "../../lib/transcript/index.js";
|
|
5
|
+
import { activityImages } from "../../lib/transcript/images.js";
|
|
6
|
+
import { Attachments } from "./Attachments.js";
|
|
7
|
+
import { FaviconStack, Favicon } from "./Favicon.js";
|
|
8
|
+
import { FailGlyph, FamilyGlyph, LineChevron } from "./glyphs.js";
|
|
9
|
+
import { useFoldPreference } from "./fold-preference.js";
|
|
10
|
+
import { useRowDisclosure } from "./disclosure-state.js";
|
|
11
|
+
import { hasDetail, LineDetail } from "./LineDetail.js";
|
|
12
|
+
import { Marker, SummaryNote } from "./Marker.js";
|
|
13
|
+
import { TeamInvocation } from "./Team.js";
|
|
14
|
+
import { Thinking } from "./Thinking.js";
|
|
15
|
+
const TONE_CLASS = {
|
|
16
|
+
plain: undefined,
|
|
17
|
+
dir: "dir",
|
|
18
|
+
query: "q",
|
|
19
|
+
aside: "in",
|
|
20
|
+
};
|
|
21
|
+
function ObjectParts({ parts }) {
|
|
22
|
+
return (_jsx(_Fragment, { children: parts.map((part, at) => {
|
|
23
|
+
const className = TONE_CLASS[part.tone];
|
|
24
|
+
return className === undefined ? (_jsx("span", { children: part.text }, at)) : (_jsx("span", { className: className, children: part.text }, at));
|
|
25
|
+
}) }));
|
|
26
|
+
}
|
|
27
|
+
export function Line({ line, domId, hit, alive, forceOpen, subthreads, workflowAttempts, hasChildren, onOpenLinkedChild, onOpenPath, }) {
|
|
28
|
+
const [open, setOpen] = useRowDisclosure(domId, line.openByDefault);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (forceOpen || hit)
|
|
31
|
+
setOpen(true);
|
|
32
|
+
}, [forceOpen, hit, setOpen]);
|
|
33
|
+
const navigatesToChild = onOpenLinkedChild !== null;
|
|
34
|
+
const pressable = navigatesToChild || hasChildren || hasDetail(line.detail, line.diagnostic);
|
|
35
|
+
const isOpen = !navigatesToChild && pressable && (open || forceOpen);
|
|
36
|
+
const running = line.state === "running" && alive;
|
|
37
|
+
const state = line.state === "failed"
|
|
38
|
+
? "failed"
|
|
39
|
+
: line.state === "running"
|
|
40
|
+
? running
|
|
41
|
+
? "running"
|
|
42
|
+
: "muted"
|
|
43
|
+
: line.state === "muted"
|
|
44
|
+
? "muted"
|
|
45
|
+
: undefined;
|
|
46
|
+
const sources = line.detail.kind === "sources" ? line.detail.sources : null;
|
|
47
|
+
const fetched = line.detail.kind === "fetch" ? line.detail.fetch : null;
|
|
48
|
+
const stamp = line.at === null ? null : clock(line.at);
|
|
49
|
+
const toggle = () => {
|
|
50
|
+
if (navigatesToChild) {
|
|
51
|
+
onOpenLinkedChild();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (pressable)
|
|
55
|
+
setOpen((value) => !value);
|
|
56
|
+
};
|
|
57
|
+
const content = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tr-line", id: domId, "data-timeline-id": line.rows[0]?.timeline_id, "data-state": state, "data-hit": hit || undefined, "data-web": line.family.startsWith("web_") ? line.family : undefined, "data-page-title": fetched?.title ? true : undefined, role: pressable ? "button" : undefined, tabIndex: pressable ? 0 : undefined, "aria-expanded": !navigatesToChild && pressable ? isOpen : undefined, "aria-controls": !navigatesToChild && hasDetail(line.detail, line.diagnostic) ? `${domId}-detail` : undefined, "aria-label": navigatesToChild ? `${line.verb}: open original worker subthread` : undefined, onClick: toggle, onKeyDown: (event) => {
|
|
58
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
59
|
+
return;
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
toggle();
|
|
62
|
+
}, children: [_jsx("span", { className: "tr-line__g", children: line.state === "failed" ? (_jsx(FailGlyph, {})) : running ? (_jsx("i", { className: "tr-dot" })) : (_jsx(FamilyGlyph, { glyph: line.glyph })) }), _jsx("span", { className: "tr-line__v", children: line.verb }), _jsx("span", { className: "tr-line__o", title: objectText(line.object), children: _jsx(ObjectParts, { parts: line.object }) }), _jsxs("span", { className: "tr-line__r", children: [sources !== null && sources.length > 0 && (_jsx(FaviconStack, { hosts: sources.map((source) => source.host) })), line.result !== null && (_jsx("span", { className: line.resultTone === "failed" || line.resultTone === "running" ? "why" : undefined, children: line.result })), fetched !== null && fetched.title !== null && (_jsxs(_Fragment, { children: [_jsx(Favicon, { host: fetched.host }), _jsx("span", { className: "ttl", title: fetched.title, children: fetched.title })] })), stamp !== null && _jsx("span", { className: "t", children: line.elided ? `→ ${stamp}` : stamp }), pressable && (_jsx("span", { className: "chev", children: _jsx(LineChevron, {}) }))] })] }), isOpen && (_jsxs(_Fragment, { children: [(() => {
|
|
63
|
+
const body = (_jsx(LineDetail, { detail: line.detail, diagnostic: line.diagnostic, workflowChildren: line.detail.kind === "workflow" ? subthreads : [], workflowAttempts: workflowAttempts, onOpenPath: onOpenPath }));
|
|
64
|
+
// `LineDetail` answers null when the family has nothing honest to
|
|
65
|
+
// show; a delegate whose child IS the detail is exactly that case.
|
|
66
|
+
return hasDetail(line.detail, line.diagnostic) ? (_jsx("div", { className: "tr-detail", id: `${domId}-detail`, children: body })) : null;
|
|
67
|
+
})(), line.detail.kind === "workflow" ? null : subthreads.map((thread) => thread.node)] }))] }));
|
|
68
|
+
return line.family.startsWith("web_") ? _jsx("div", { className: "tr-web", children: content }) : content;
|
|
69
|
+
}
|
|
70
|
+
const TEAM_START_BURST_MS = 5 * 60_000;
|
|
71
|
+
function sameStartBurst(first, candidate) {
|
|
72
|
+
if (candidate.operation !== "add" || candidate.team !== first.team)
|
|
73
|
+
return false;
|
|
74
|
+
if (first.row.at === null || candidate.row.at === null)
|
|
75
|
+
return true;
|
|
76
|
+
return candidate.row.at >= first.row.at && candidate.row.at - first.row.at <= TEAM_START_BURST_MS;
|
|
77
|
+
}
|
|
78
|
+
function rowsOf(member) {
|
|
79
|
+
return member.kind === "line" ? member.line.rows : [member.row];
|
|
80
|
+
}
|
|
81
|
+
export function Ledger({ embedded = false, members, summary, anchor, domIdOf, highlightedTimelineId, focusTimelineId, alive, subthreadsFor, workflowAttemptsFor, hasChildren, childFocused, linkedChildId, onOpenLinkedChild, teamMemberFor, onOpenPath, onOpenAttachment, }) {
|
|
82
|
+
const images = useMemo(() => activityImages(members), [members]);
|
|
83
|
+
const inside = (member) => (member.kind === "line" && childFocused(member.line)) ||
|
|
84
|
+
(focusTimelineId !== null &&
|
|
85
|
+
rowsOf(member).some((row) => row.timeline_id === focusTimelineId));
|
|
86
|
+
const focusInside = members.some(inside);
|
|
87
|
+
// §05 — the room's activity act is the DEFAULT every run follows: closed,
|
|
88
|
+
// or open while the act holds every run open. A press on the head is an
|
|
89
|
+
// override (`true`/`false`); the next press of the act clears it.
|
|
90
|
+
const everyRunOpen = !useFoldPreference().folded;
|
|
91
|
+
// Activity follows the room from its first line. A live run that grows
|
|
92
|
+
// keeps any explicit override, so it never closes on its own (R-5).
|
|
93
|
+
// Speech, such as a question, has no summary head and stays open.
|
|
94
|
+
const [override, setOverride] = useState(() => summary.closedByDefault ? null : true);
|
|
95
|
+
const actRef = useRef(everyRunOpen);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (actRef.current === everyRunOpen)
|
|
98
|
+
return;
|
|
99
|
+
actRef.current = everyRunOpen;
|
|
100
|
+
setOverride(null);
|
|
101
|
+
}, [everyRunOpen]);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (focusInside)
|
|
104
|
+
setOverride(true);
|
|
105
|
+
}, [focusInside]);
|
|
106
|
+
// A landing rings a row after scrolling to it, and the column scrolled
|
|
107
|
+
// before this ladder was shown. Open on the ring, then bring the row in.
|
|
108
|
+
const highlightInside = highlightedTimelineId !== null &&
|
|
109
|
+
members.some((member) => rowsOf(member).some((row) => row.timeline_id === highlightedTimelineId));
|
|
110
|
+
const domIdRef = useRef(domIdOf);
|
|
111
|
+
domIdRef.current = domIdOf;
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (embedded || !highlightInside || highlightedTimelineId === null)
|
|
114
|
+
return;
|
|
115
|
+
setOverride(true);
|
|
116
|
+
const frame = window.requestAnimationFrame(() => {
|
|
117
|
+
document
|
|
118
|
+
.getElementById(domIdRef.current(highlightedTimelineId))
|
|
119
|
+
?.scrollIntoView({ block: "center" });
|
|
120
|
+
});
|
|
121
|
+
return () => window.cancelAnimationFrame(frame);
|
|
122
|
+
}, [embedded, highlightInside, highlightedTimelineId]);
|
|
123
|
+
const drawn = [];
|
|
124
|
+
// Every member read below sits under a bound against members.length: the
|
|
125
|
+
// loop's own, or the burst's `index + 1 < members.length`.
|
|
126
|
+
const memberAt = (index) => members[index];
|
|
127
|
+
for (let index = 0; index < members.length; index += 1) {
|
|
128
|
+
const member = memberAt(index);
|
|
129
|
+
if (member.kind !== "line") {
|
|
130
|
+
// Inside the ladder every member keeps the form it had as a segment.
|
|
131
|
+
const rowId = member.row.timeline_id;
|
|
132
|
+
const hit = highlightedTimelineId === rowId;
|
|
133
|
+
if (member.kind === "thinking") {
|
|
134
|
+
drawn.push(_jsx(Thinking, { text: member.text, spanMs: member.spanMs, domId: domIdOf(rowId), timelineId: rowId, hit: hit, anchor: null }, member.key));
|
|
135
|
+
}
|
|
136
|
+
else if (member.kind === "marker") {
|
|
137
|
+
drawn.push(_jsx(Marker, { text: member.text, tone: member.tone, domId: domIdOf(rowId), timelineId: rowId, hit: hit }, member.key));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
drawn.push(_jsx(SummaryNote, { purpose: member.purpose, text: member.text, domId: domIdOf(rowId), timelineId: rowId, hit: hit }, member.key));
|
|
141
|
+
}
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const line = member.line;
|
|
145
|
+
const teamMember = teamMemberFor(line);
|
|
146
|
+
if (teamMember !== null) {
|
|
147
|
+
const burst = [teamMember];
|
|
148
|
+
if (teamMember.operation === "start" || teamMember.operation === "known") {
|
|
149
|
+
while (index + 1 < members.length) {
|
|
150
|
+
const next = memberAt(index + 1);
|
|
151
|
+
if (next.kind !== "line")
|
|
152
|
+
break;
|
|
153
|
+
const candidate = teamMemberFor(next.line);
|
|
154
|
+
if (candidate === null || !sameStartBurst(teamMember, candidate))
|
|
155
|
+
break;
|
|
156
|
+
burst.push(candidate);
|
|
157
|
+
index += 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
drawn.push(_jsx(TeamInvocation, { members: burst, domIdOf: domIdOf, highlightedTimelineId: highlightedTimelineId, focusTimelineId: focusTimelineId }, teamMember.row.timeline_id));
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const key = line.rows[0]?.timeline_id ?? line.key;
|
|
164
|
+
const linkedChild = linkedChildId(line);
|
|
165
|
+
drawn.push(_jsx(Line, { line: line, domId: domIdOf(key), hit: highlightedTimelineId !== null &&
|
|
166
|
+
line.rows.some((row) => row.timeline_id === highlightedTimelineId), alive: alive(line), forceOpen: inside(member), subthreads: subthreadsFor(line), workflowAttempts: workflowAttemptsFor(line), hasChildren: hasChildren(line), onOpenLinkedChild: linkedChild === null ? null : () => onOpenLinkedChild(linkedChild), onOpenPath: onOpenPath }, line.key));
|
|
167
|
+
}
|
|
168
|
+
// Activity gets a summary even for one line; speech has no outer fold.
|
|
169
|
+
const closed = !embedded && summary.closedByDefault;
|
|
170
|
+
// R-5: the green breath only in a live session below the watermark, and
|
|
171
|
+
// then the head carries the line that is happening.
|
|
172
|
+
const running = summary.running !== null && alive(summary.running) ? summary.running : null;
|
|
173
|
+
const span = summary.spanMs !== null && summary.spanMs >= 1000 ? spanText(summary.spanMs) : null;
|
|
174
|
+
const expanded = override ?? (everyRunOpen || focusInside);
|
|
175
|
+
const toggle = () => setOverride(!expanded);
|
|
176
|
+
return (_jsxs("div", { className: embedded ? "tr-activity-tools" : closed ? "tr-seg tr-ledger" : "tr-ledger", children: [closed ? anchor : null, closed ? _jsxs("div", { className: "tr-line tr-fold", role: "button", tabIndex: 0, "aria-expanded": expanded, "data-state": running === null ? undefined : "running", onClick: toggle, onKeyDown: (event) => {
|
|
177
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
178
|
+
return;
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
toggle();
|
|
181
|
+
}, children: [_jsx("span", { className: "tr-line__g chev", children: running === null ? _jsx(LineChevron, {}) : _jsx("i", { className: "tr-dot" }) }), _jsxs("span", { className: "tr-line__v", children: [summary.nouns.map((noun, index) => (_jsxs(Fragment, { children: [index > 0 && " · ", noun.text, noun.names.length > 0 && (_jsxs(_Fragment, { children: [" ", _jsxs("span", { className: "names", children: [noun.names.join(", "), noun.more > 0 ? ` … ${noun.more} more` : ""] })] }))] }, noun.family))), running !== null && (_jsxs("span", { className: "cur", children: [summary.nouns.length > 0 && " · ", running.verb, " ", _jsx("span", { className: "tr-line__o", children: objectText(running.object) })] }))] }), _jsxs("span", { className: "tr-line__r", children: [summary.failed > 0 && _jsxs("b", { children: [summary.failed, " failed"] }), summary.errors > 0 && (_jsxs("b", { children: [summary.errors, " ", summary.errors === 1 ? "error" : "errors"] })), span !== null && (_jsx("span", { className: running === null ? undefined : "why", children: running === null ? span : `${span} → …` }))] })] }) : null, !embedded && _jsx(Attachments, { facts: images, onOpenAttachment: onOpenAttachment }), _jsx("div", { className: closed ? "tr-ladder" : undefined, children: drawn })] }));
|
|
182
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { LedgerDetail, PathFact } from "../../lib/transcript/index.js";
|
|
3
|
+
import type { WorkflowChildThread } from "./Workflow.js";
|
|
4
|
+
export interface LineDetailProps {
|
|
5
|
+
readonly detail: LedgerDetail;
|
|
6
|
+
/** The bounded failure text. Never the tool's output. */
|
|
7
|
+
readonly diagnostic: string | null;
|
|
8
|
+
/** The delegate's child run, resolved by the document and passed in — this
|
|
9
|
+
* module knows the shape of a detail, not the shape of a session tree. */
|
|
10
|
+
readonly subthread?: ReactNode;
|
|
11
|
+
/** Workflow children stay attached to their own worker row instead of
|
|
12
|
+
* becoming an undifferentiated stack below the run document. */
|
|
13
|
+
readonly workflowChildren?: readonly WorkflowChildThread[];
|
|
14
|
+
readonly workflowAttempts?: readonly import("../../lib/transcript/index.js").WorkflowAttemptFact[];
|
|
15
|
+
/** The document owns the viewer; detail rows only report which exact path
|
|
16
|
+
* the reader pressed. */
|
|
17
|
+
readonly onOpenPath?: ((path: PathFact) => void) | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** The body of one open line. Returns null when the family has nothing honest
|
|
20
|
+
* to show, which is what makes the line unpressable in `Ledger`. */
|
|
21
|
+
export declare function LineDetail({ detail, diagnostic, subthread, workflowChildren, workflowAttempts, onOpenPath, }: LineDetailProps): import("react").JSX.Element | null;
|
|
22
|
+
/** Whether pressing the line has anything to open. Keeps the DOM honest: a
|
|
23
|
+
* line that opens into nothing is not focusable and does not take a press. */
|
|
24
|
+
export declare function hasDetail(detail: LedgerDetail, diagnostic: string | null): boolean;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { resourceDisplay } from "../../lib/transcript/index.js";
|
|
3
|
+
import { CommandList, DiffDetail, Document, Fields, Findings, Participants, PathList, Questions, Tasks, LIST_CAP, } from "./detail-parts.js";
|
|
4
|
+
import { SourceList, FetchDetails } from "./WebDetail.js";
|
|
5
|
+
import { WorkflowDetail } from "./Workflow.js";
|
|
6
|
+
function LocationList({ locations, total, }) {
|
|
7
|
+
const shown = locations.slice(0, LIST_CAP);
|
|
8
|
+
return (_jsxs("ul", { className: "tr-paths", children: [shown.map((location, at) => (_jsxs("li", { children: [resourceDisplay(location.resource, {}), location.line !== null && `:${location.line}`, location.summary !== null && _jsx("span", { className: "n", children: location.summary })] }, at))), total > shown.length && _jsxs("li", { className: "tr-more", children: ["\u2026 ", total - shown.length, " more"] })] }));
|
|
9
|
+
}
|
|
10
|
+
/** The body of one open line. Returns null when the family has nothing honest
|
|
11
|
+
* to show, which is what makes the line unpressable in `Ledger`. */
|
|
12
|
+
export function LineDetail({ detail, diagnostic, subthread, workflowChildren = [], workflowAttempts = [], onOpenPath, }) {
|
|
13
|
+
const body = (() => {
|
|
14
|
+
switch (detail.kind) {
|
|
15
|
+
case "none":
|
|
16
|
+
return null;
|
|
17
|
+
case "paths":
|
|
18
|
+
return (_jsxs(_Fragment, { children: [detail.description !== undefined && _jsx("p", { className: "tr-text", children: detail.description }), _jsx(PathList, { paths: detail.paths, total: detail.total, onOpenPath: onOpenPath })] }));
|
|
19
|
+
case "locations":
|
|
20
|
+
return _jsx(LocationList, { locations: detail.locations, total: detail.total });
|
|
21
|
+
case "sources":
|
|
22
|
+
return _jsx(SourceList, { sources: detail.sources, total: detail.total });
|
|
23
|
+
case "fetch":
|
|
24
|
+
return _jsx(FetchDetails, { fetches: [detail.fetch] });
|
|
25
|
+
case "fetches":
|
|
26
|
+
return _jsx(FetchDetails, { fetches: detail.fetches });
|
|
27
|
+
case "diff":
|
|
28
|
+
return _jsx(DiffDetail, { deltas: detail.deltas, diffstat: detail.diffstat });
|
|
29
|
+
case "command":
|
|
30
|
+
return _jsx(CommandList, { commands: detail.commands, code: false });
|
|
31
|
+
case "code":
|
|
32
|
+
return _jsx(CommandList, { commands: detail.commands, code: true });
|
|
33
|
+
case "names":
|
|
34
|
+
return (_jsxs("ul", { className: "tr-paths", children: [detail.names.slice(0, LIST_CAP).map((name, at) => (_jsx("li", { children: name }, at))), detail.total > Math.min(detail.names.length, LIST_CAP) && (_jsxs("li", { className: "tr-more", children: ["\u2026 ", detail.total - Math.min(detail.names.length, LIST_CAP), " more"] }))] }));
|
|
35
|
+
case "tasks":
|
|
36
|
+
return (_jsx(Tasks, { tasks: detail.tasks, total: detail.total, changedTaskId: detail.changedTaskId, change: detail.change }));
|
|
37
|
+
case "text":
|
|
38
|
+
return _jsx("p", { className: "tr-text", children: detail.text });
|
|
39
|
+
case "questions":
|
|
40
|
+
return _jsx(Questions, { questions: detail.questions, answers: detail.answers });
|
|
41
|
+
case "findings":
|
|
42
|
+
return _jsx(Findings, { findings: detail.findings, total: detail.total });
|
|
43
|
+
case "document":
|
|
44
|
+
return _jsx(Document, { document: detail.document });
|
|
45
|
+
case "fields":
|
|
46
|
+
return (_jsxs(_Fragment, { children: [_jsx(Fields, { fields: detail.fields }), detail.resources.length > 0 && (_jsx(PathList, { paths: detail.resources, total: detail.resources.length }))] }));
|
|
47
|
+
case "delegate":
|
|
48
|
+
return detail.delegate.orphanSummary === null ? null : (
|
|
49
|
+
// The child was never indexed, so the record draws its result
|
|
50
|
+
// summary as prose rather than an empty subthread.
|
|
51
|
+
_jsx("p", { className: "tr-text", children: detail.delegate.orphanSummary }));
|
|
52
|
+
case "workflow":
|
|
53
|
+
return (_jsx(WorkflowDetail, { fact: detail.workflow, attempts: workflowAttempts, children: workflowChildren, onOpenPath: onOpenPath }));
|
|
54
|
+
case "participants":
|
|
55
|
+
return (_jsx(Participants, { participants: detail.participants, total: detail.total, body: detail.body }));
|
|
56
|
+
case "diagnostic":
|
|
57
|
+
return _jsx("pre", { className: "tr-diag", children: detail.diagnostic });
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
// A failure always opens to its bounded diagnostic, even when the family
|
|
61
|
+
// already had something to say (§04: shell opens into the command, its cwd,
|
|
62
|
+
// AND on failure the diagnostic).
|
|
63
|
+
const extra = diagnostic !== null && detail.kind !== "diagnostic" ? (_jsx("pre", { className: "tr-diag", children: diagnostic })) : null;
|
|
64
|
+
if (body === null && extra === null && subthread === undefined)
|
|
65
|
+
return null;
|
|
66
|
+
return (_jsxs(_Fragment, { children: [body, extra, subthread] }));
|
|
67
|
+
}
|
|
68
|
+
/** Whether pressing the line has anything to open. Keeps the DOM honest: a
|
|
69
|
+
* line that opens into nothing is not focusable and does not take a press. */
|
|
70
|
+
export function hasDetail(detail, diagnostic) {
|
|
71
|
+
if (diagnostic !== null)
|
|
72
|
+
return true;
|
|
73
|
+
switch (detail.kind) {
|
|
74
|
+
case "none":
|
|
75
|
+
return false;
|
|
76
|
+
case "delegate":
|
|
77
|
+
return detail.delegate.childSessionId !== null || detail.delegate.orphanSummary !== null;
|
|
78
|
+
default:
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SummaryPurpose } from "@vibefield/rosetta-protocol";
|
|
2
|
+
export interface MarkerProps {
|
|
3
|
+
readonly text: string;
|
|
4
|
+
/** A runtime error is the one marker that takes hue (T-5). */
|
|
5
|
+
readonly tone?: "plain" | "failed";
|
|
6
|
+
readonly domId?: string;
|
|
7
|
+
readonly timelineId?: string;
|
|
8
|
+
readonly hit?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function Marker({ text, tone, domId, timelineId, hit }: MarkerProps): import("react").JSX.Element;
|
|
11
|
+
/** D33's line, kept: rows arriving after you did start here. Green, because
|
|
12
|
+
* this is the one marker that says something is alive. */
|
|
13
|
+
export declare function Watermark({ text, title }: {
|
|
14
|
+
readonly text: string;
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
/** A known unknown, and pressable because it should name its reason (§9).
|
|
18
|
+
* The count is an ORDINAL discontinuity inside the loaded document — rows the
|
|
19
|
+
* projection has, that this page does not. It is never drawn at the head,
|
|
20
|
+
* where the head line already states what is above. */
|
|
21
|
+
export declare function GapMarker({ count, onPress, }: {
|
|
22
|
+
readonly count: number;
|
|
23
|
+
readonly onPress: () => void;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
25
|
+
/** The session summary — a footnote at the end, not a state; and, inside a
|
|
26
|
+
* run, one member of its ladder. The same drawing in both places. */
|
|
27
|
+
export declare function SummaryNote({ purpose, text, domId, timelineId, hit, }: {
|
|
28
|
+
readonly purpose: SummaryPurpose;
|
|
29
|
+
readonly text: string;
|
|
30
|
+
readonly domId: string;
|
|
31
|
+
readonly timelineId: string;
|
|
32
|
+
readonly hit: boolean;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function Marker({ text, tone = "plain", domId, timelineId, hit }) {
|
|
3
|
+
return (_jsx("div", { className: tone === "failed" ? "tr-mark tr-mark--error" : "tr-mark", id: domId, "data-timeline-id": timelineId, "data-hit": hit || undefined, children: text }));
|
|
4
|
+
}
|
|
5
|
+
/** D33's line, kept: rows arriving after you did start here. Green, because
|
|
6
|
+
* this is the one marker that says something is alive. */
|
|
7
|
+
export function Watermark({ text, title }) {
|
|
8
|
+
return (_jsx("div", { className: "tr-mark tr-mark--live", title: title, children: text }));
|
|
9
|
+
}
|
|
10
|
+
/** A known unknown, and pressable because it should name its reason (§9).
|
|
11
|
+
* The count is an ORDINAL discontinuity inside the loaded document — rows the
|
|
12
|
+
* projection has, that this page does not. It is never drawn at the head,
|
|
13
|
+
* where the head line already states what is above. */
|
|
14
|
+
export function GapMarker({ count, onPress, }) {
|
|
15
|
+
return (_jsxs("button", { type: "button", className: "tr-mark tr-mark--gap", onClick: onPress, children: ["gap \u00B7 ", count, " ", count === 1 ? "message" : "messages", " not indexed"] }));
|
|
16
|
+
}
|
|
17
|
+
/** The session summary — a footnote at the end, not a state; and, inside a
|
|
18
|
+
* run, one member of its ladder. The same drawing in both places. */
|
|
19
|
+
export function SummaryNote({ purpose, text, domId, timelineId, hit, }) {
|
|
20
|
+
return (_jsxs("div", { className: "tr-summary", id: domId, "data-timeline-id": timelineId, "data-hit": hit || undefined, children: [_jsxs("span", { className: "eyebrow", children: [purpose, " summary"] }), text] }));
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FullMessage } from "./message-file-source.js";
|
|
2
|
+
import type { ProseProps } from "./Prose.js";
|
|
3
|
+
import "../../styles/message-preview.css";
|
|
4
|
+
/** The column owns one viewer, including messages inside nested worker runs. */
|
|
5
|
+
export declare const MessageViewerContext: import("react").Context<((message: FullMessage) => void) | null>;
|
|
6
|
+
export declare function MessagePreview({ messageKey, role, title, recordedText, matched, ...prose }: ProseProps & {
|
|
7
|
+
readonly messageKey: string;
|
|
8
|
+
readonly role: FullMessage["role"];
|
|
9
|
+
readonly title?: string | undefined;
|
|
10
|
+
readonly recordedText?: FullMessage["recordedText"] | undefined;
|
|
11
|
+
readonly matched?: boolean | undefined;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { MESSAGE_PREVIEW_CHARACTERS, messageExcerpt } from "./message-preview.js";
|
|
4
|
+
import { Prose } from "./Prose.js";
|
|
5
|
+
import "../../styles/message-preview.css";
|
|
6
|
+
/** The column owns one viewer, including messages inside nested worker runs. */
|
|
7
|
+
export const MessageViewerContext = createContext(null);
|
|
8
|
+
export function MessagePreview({ messageKey, role, title, recordedText, matched = false, ...prose }) {
|
|
9
|
+
const openMessage = useContext(MessageViewerContext);
|
|
10
|
+
const [matchedKey, setMatchedKey] = useState(matched ? messageKey : null);
|
|
11
|
+
useEffect(() => { if (matched)
|
|
12
|
+
setMatchedKey(messageKey); }, [matched, messageKey]);
|
|
13
|
+
const { text } = prose;
|
|
14
|
+
const member = recordedText?.type === "member" ? recordedText : null;
|
|
15
|
+
const viewportRef = useRef(null);
|
|
16
|
+
const contentRef = useRef(null);
|
|
17
|
+
const widthRef = useRef(0);
|
|
18
|
+
const [fit, setFit] = useState({ text, budget: MESSAGE_PREVIEW_CHARACTERS });
|
|
19
|
+
const budget = fit.text === text ? fit.budget : MESSAGE_PREVIEW_CHARACTERS;
|
|
20
|
+
const excerpt = useMemo(() => messageExcerpt(text, budget), [text, budget]);
|
|
21
|
+
useLayoutEffect(() => {
|
|
22
|
+
const viewport = viewportRef.current;
|
|
23
|
+
const content = contentRef.current;
|
|
24
|
+
if (viewport === null || content === null || openMessage === null)
|
|
25
|
+
return;
|
|
26
|
+
const measureWidth = viewport.closest(".tr-seg") ?? viewport;
|
|
27
|
+
const measure = () => {
|
|
28
|
+
const width = measureWidth.clientWidth;
|
|
29
|
+
if (width === 0)
|
|
30
|
+
return; // An unopened worker ladder has no measure yet.
|
|
31
|
+
if (widthRef.current > 0 && Math.abs(width - widthRef.current) > 1) {
|
|
32
|
+
widthRef.current = width;
|
|
33
|
+
setFit({ text, budget: MESSAGE_PREVIEW_CHARACTERS });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
widthRef.current = width;
|
|
37
|
+
const limit = Number.parseFloat(getComputedStyle(viewport).maxHeight);
|
|
38
|
+
const height = content.offsetHeight;
|
|
39
|
+
if (!Number.isFinite(limit) || height <= limit + 1 || excerpt.text.length === 0)
|
|
40
|
+
return;
|
|
41
|
+
// Remove text from the rendered tree, rather than leave invisible links
|
|
42
|
+
// and copy buttons behind a CSS clip. Shortening always makes progress;
|
|
43
|
+
// headings, lists, tables and code all count toward the same height.
|
|
44
|
+
const next = Math.max(0, Math.floor(excerpt.text.length * limit / height) - 48);
|
|
45
|
+
setFit({ text, budget: next });
|
|
46
|
+
};
|
|
47
|
+
measure();
|
|
48
|
+
const observer = new ResizeObserver(measure);
|
|
49
|
+
observer.observe(measureWidth);
|
|
50
|
+
observer.observe(content);
|
|
51
|
+
return () => observer.disconnect();
|
|
52
|
+
}, [text, excerpt.text, openMessage]);
|
|
53
|
+
// A document rendered without its column still has readable, complete text.
|
|
54
|
+
// Production documents always inherit the column's viewer capability.
|
|
55
|
+
if (openMessage === null)
|
|
56
|
+
return _jsx(Prose, { ...prose });
|
|
57
|
+
return (_jsxs("div", { className: "tr-message", "data-omitted": excerpt.omitted || member !== null || undefined, children: [_jsx("div", { className: "tr-message__viewport", ref: viewportRef, children: _jsx("div", { className: "tr-message__content", ref: contentRef, children: _jsx(Prose, { ...prose, text: excerpt.text, imageMarkerSource: text, excerpt: excerpt.omitted || member !== null }) }) }), (excerpt.omitted || member !== null) && (_jsx("div", { className: "tr-message__footer", children: _jsx("button", { type: "button", className: "tr-message__open", "aria-haspopup": "dialog", onClick: () => openMessage({ key: messageKey, role, title, text, recordedText, attachments: prose.imageAttachments }), children: matchedKey === messageKey ? "View match in full message" : "View full message" }) }))] }));
|
|
58
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AttachmentFact, Prompt as PromptModel } from "../../lib/transcript/index.js";
|
|
2
|
+
export interface PromptPanelProps {
|
|
3
|
+
readonly prompt: PromptModel;
|
|
4
|
+
readonly domId: string;
|
|
5
|
+
readonly landed: boolean;
|
|
6
|
+
readonly onReceipt: (message: string) => void;
|
|
7
|
+
readonly onOpenAttachment: (fact: AttachmentFact, row?: readonly AttachmentFact[]) => void;
|
|
8
|
+
}
|
|
9
|
+
/** The panel alone, so a cluster can stack several inside one segment. */
|
|
10
|
+
export declare function PromptPanel({ prompt, domId, landed, onReceipt, onOpenAttachment, }: PromptPanelProps): import("react").JSX.Element;
|
|
11
|
+
export interface PromptProps {
|
|
12
|
+
/** One conversational prompt, or adjacent successful setting commands. */
|
|
13
|
+
readonly prompts: readonly PromptModel[];
|
|
14
|
+
readonly domIdOf: (timelineId: string) => string;
|
|
15
|
+
readonly landedTimelineId: string | null;
|
|
16
|
+
readonly focusTimelineId?: string | null;
|
|
17
|
+
readonly onReceipt: (message: string) => void;
|
|
18
|
+
readonly onOpenAttachment: (fact: AttachmentFact, row?: readonly AttachmentFact[]) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function Prompt({ prompts, domIdOf, landedTimelineId, focusTimelineId, onReceipt, onOpenAttachment, }: PromptProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { firstLine } from "../../lib/transcript/index.js";
|
|
3
|
+
import { clock } from "../../lib/format.js";
|
|
4
|
+
import { Anchor } from "./Anchor.js";
|
|
5
|
+
import { AuthoredMessage } from "./AuthoredMessage.js";
|
|
6
|
+
import { messageAttachments } from "../../lib/transcript/images.js";
|
|
7
|
+
import { SegmentActs } from "./Prose.js";
|
|
8
|
+
import { ActivityEvent } from "./Activity.js";
|
|
9
|
+
import { FamilyGlyph } from "./glyphs.js";
|
|
10
|
+
/** The panel alone, so a cluster can stack several inside one segment. */
|
|
11
|
+
export function PromptPanel({ prompt, domId, landed, onReceipt, onOpenAttachment, }) {
|
|
12
|
+
return (_jsx("div", { className: landed ? "tr-prompt-message is-landed" : "tr-prompt-message", id: domId, "data-timeline-id": prompt.row.timeline_id, children: _jsx(AuthoredMessage, { text: prompt.text, attachments: prompt.attachments, recordedText: prompt.row.body.type === "user" ? prompt.row.body.text : null, messageKey: `${prompt.row.session_id}:${prompt.row.timeline_id}`, role: "user", onReceipt: onReceipt, onOpenAttachment: onOpenAttachment, renderText: content => content !== null || prompt.attachments.length === 0
|
|
13
|
+
? _jsx("div", { className: "tr-prompt", children: content ?? _jsx("p", { className: "tr-quiet", children: "no text recorded" }) })
|
|
14
|
+
: null }) }));
|
|
15
|
+
}
|
|
16
|
+
function senderLabel(sender) {
|
|
17
|
+
if (sender === "coordinator")
|
|
18
|
+
return "Claude Code";
|
|
19
|
+
return sender.startsWith("@") ? sender : `@${sender}`;
|
|
20
|
+
}
|
|
21
|
+
function MachinePrompt({ prompt, domId, onReceipt, onOpenAttachment, hit, forceOpen, }) {
|
|
22
|
+
const machine = prompt.machine ?? { label: "Assignment", sender: null };
|
|
23
|
+
const recordedText = prompt.row.body.type === "collaboration" ? prompt.row.body.event.body
|
|
24
|
+
: prompt.row.body.type === "user" ? prompt.row.body.text : null;
|
|
25
|
+
const facts = [
|
|
26
|
+
machine.label,
|
|
27
|
+
machine.sender === null ? null : `from ${senderLabel(machine.sender)}`,
|
|
28
|
+
prompt.at === null ? null : clock(prompt.at),
|
|
29
|
+
].filter((fact) => fact !== null);
|
|
30
|
+
return (_jsxs(ActivityEvent, { domId: domId, timelineId: prompt.row.timeline_id, label: machine.label, summary: machine.sender === null ? undefined : `from ${senderLabel(machine.sender)}`, at: prompt.at, hit: hit, forceOpen: forceOpen, glyph: _jsx(FamilyGlyph, { glyph: "delegate" }), children: [_jsx("span", { className: "tr-assignment__head", children: facts.join(" · ") }), prompt.text === null && recordedText?.type !== "member" ? (_jsx("span", { className: "tr-quiet", children: "no message body recorded" })) : (_jsx(AuthoredMessage, { messageKey: `${prompt.row.session_id}:${prompt.row.timeline_id}`, role: "agent", attachments: messageAttachments(prompt.row), imagesOutside: true, onOpenAttachment: onOpenAttachment, matched: hit, title: `${machine.label}${machine.sender === null ? "" : ` from ${senderLabel(machine.sender)}`}`, text: prompt.text ?? "", recordedText: recordedText, onReceipt: onReceipt }))] }));
|
|
31
|
+
}
|
|
32
|
+
function CommandPrompt({ prompt, domId }) {
|
|
33
|
+
if (prompt.setting !== null) {
|
|
34
|
+
return (_jsxs("div", { className: "tr-setting", id: domId, "data-setting": prompt.setting.kind, title: prompt.command ?? undefined, "aria-label": `${prompt.setting.label}: ${prompt.setting.value}`, children: [_jsx("span", { className: "tr-setting__label", children: prompt.setting.label }), _jsx("span", { className: "tr-setting__value", children: prompt.setting.value })] }));
|
|
35
|
+
}
|
|
36
|
+
return (_jsxs("div", { className: "tr-cmd", id: domId, children: [_jsx("code", { children: prompt.command }), prompt.commandOutput !== null && _jsx("span", { children: firstLine(prompt.commandOutput, 160) })] }));
|
|
37
|
+
}
|
|
38
|
+
export function Prompt({ prompts, domIdOf, landedTimelineId, focusTimelineId = null, onReceipt, onOpenAttachment, }) {
|
|
39
|
+
const first = prompts[0];
|
|
40
|
+
if (first === undefined)
|
|
41
|
+
return null;
|
|
42
|
+
const clustered = prompts.length > 1;
|
|
43
|
+
// The anchor sits against the first thing in the segment, and a pill is
|
|
44
|
+
// half a panel's height — so the offset follows what actually opens it.
|
|
45
|
+
const allCommands = prompts.every((prompt) => prompt.isCommand && prompt.command !== null);
|
|
46
|
+
const allMachine = prompts.every((prompt) => prompt.machine !== null || prompt.fromParent);
|
|
47
|
+
const text = prompts
|
|
48
|
+
.map((prompt) => prompt.text)
|
|
49
|
+
.filter((value) => value !== null)
|
|
50
|
+
.join("\n\n");
|
|
51
|
+
return (_jsxs("div", { className: clustered ? "tr-seg tr-cluster" : "tr-seg", "data-prompt": allCommands || allMachine ? undefined : "", "data-command": allCommands ? "" : undefined, "data-machine": allMachine ? "" : undefined, "data-timeline-id": first.row.timeline_id, children: [_jsx(Anchor, { at: first.at, sessionId: first.row.session_id, timelineId: first.row.timeline_id, onReceipt: onReceipt }), prompts.map((prompt) =>
|
|
52
|
+
// §03 H — a prompt that is a local command wears a pill instead of a
|
|
53
|
+
// panel, and its `command_output` rides beside it. One object.
|
|
54
|
+
prompt.machine !== null || prompt.fromParent ? (_jsx(MachinePrompt, { prompt: prompt, domId: domIdOf(prompt.row.timeline_id), onReceipt: onReceipt, onOpenAttachment: onOpenAttachment, hit: landedTimelineId === prompt.row.timeline_id, forceOpen: focusTimelineId === prompt.row.timeline_id }, prompt.key)) : prompt.isCommand && prompt.command !== null ? (_jsx(CommandPrompt, { prompt: prompt, domId: domIdOf(prompt.row.timeline_id) }, prompt.key)) : (_jsx(PromptPanel, { prompt: prompt, domId: domIdOf(prompt.row.timeline_id), landed: landedTimelineId === prompt.row.timeline_id, onReceipt: onReceipt, onOpenAttachment: onOpenAttachment }, prompt.key))), !allCommands && !allMachine && _jsx(SegmentActs, { text: text, onReceipt: onReceipt })] }));
|
|
55
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AttachmentFact } from "../../lib/transcript/index.js";
|
|
2
|
+
/** The hover acts. Today the room has exactly one honest act on a segment —
|
|
3
|
+
* copy — so that is what it draws; the record's chip and canvas belong to
|
|
4
|
+
* vibe-field, which this room is not. */
|
|
5
|
+
export declare function SegmentActs({ text, onReceipt, }: {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly onReceipt: (message: string) => void;
|
|
8
|
+
}): import("react").JSX.Element | null;
|
|
9
|
+
export interface ProseProps {
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly onReceipt: (message: string) => void;
|
|
12
|
+
readonly imageAttachments?: readonly AttachmentFact[];
|
|
13
|
+
/** Ranges are relative to the complete message, including in a preview. */
|
|
14
|
+
readonly imageMarkerSource?: string;
|
|
15
|
+
readonly onOpenAttachment?: (fact: AttachmentFact) => void;
|
|
16
|
+
/** An excerpt may end inside a fence; do not offer to copy partial code. */
|
|
17
|
+
readonly excerpt?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function Prose({ text, onReceipt, imageAttachments, imageMarkerSource, onOpenAttachment, excerpt, }: ProseProps): import("react").JSX.Element;
|