@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,170 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Column ③ — the project's repository: its files, what git has not recorded
|
|
3
|
+
// yet, and what it has.
|
|
4
|
+
//
|
|
5
|
+
// The design record draws these as two columns, a worktree beside a git
|
|
6
|
+
// panel, each opening from a different head. They are one column here,
|
|
7
|
+
// because they are three views of ONE object: this project's checkout. Two
|
|
8
|
+
// columns made the reader hold that identity in their head — the same folder
|
|
9
|
+
// named twice, in two heads, with two toggles — and cost 280px to say it. A
|
|
10
|
+
// switch says it in a row the column already had.
|
|
11
|
+
//
|
|
12
|
+
// It is still a guest (H-3), and now the only one, so the record's original
|
|
13
|
+
// single-subject rule applies again: below a 1360px frame it closes rather
|
|
14
|
+
// than squeeze the transcript.
|
|
15
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
16
|
+
import { useRoom } from "../../room-context.js";
|
|
17
|
+
import { FileViewerDialog } from "../file-viewer/index.js";
|
|
18
|
+
import { ConfirmDialog, EmptyState, SegmentedControl } from "../ui/index.js";
|
|
19
|
+
import { changeShapeOf, CommitViewer, createGitFileSource, diffHandle, GitChanges, GitHistory, useGitRead, } from "../git/index.js";
|
|
20
|
+
import { useGitFacts, useWorktreeConnection } from "./worktree-host.js";
|
|
21
|
+
import { createWorktreeFileSource, handleFor, isOpenable } from "./worktree-file-source.js";
|
|
22
|
+
import { WorktreeFileTree } from "./WorktreeFileTree.js";
|
|
23
|
+
import { WorktreeHeader } from "./WorktreeHeader.js";
|
|
24
|
+
import { WorktreeList } from "./WorktreeList.js";
|
|
25
|
+
const TABS = [
|
|
26
|
+
{ value: "files", label: "Files" },
|
|
27
|
+
{ value: "changes", label: "Changes" },
|
|
28
|
+
{ value: "history", label: "History" },
|
|
29
|
+
];
|
|
30
|
+
const readBranch = (client) => client.branch();
|
|
31
|
+
const readStatus = (client) => client.status();
|
|
32
|
+
const readLog = (client) => client.log();
|
|
33
|
+
export function WorktreeColumn({ projectRoot, tint, homeDirectory, sessionPaths, currentTimestamp, onReceipt, requestError, onRetry, folders = null, }) {
|
|
34
|
+
const elsewhere = folders?.shown?.elsewhere;
|
|
35
|
+
const lifecycle = useWorktreeConnection();
|
|
36
|
+
const live = lifecycle.status === "ready" ? lifecycle.connection : null;
|
|
37
|
+
const engine = live?.engine ?? null;
|
|
38
|
+
// The engine follows the selection with a lag (kill, re-fork, walk), so the
|
|
39
|
+
// head names what the column is actually showing, never what was asked for.
|
|
40
|
+
const shownRoot = lifecycle.status === "ready"
|
|
41
|
+
? lifecycle.connection.root
|
|
42
|
+
: lifecycle.status === "idle"
|
|
43
|
+
? projectRoot
|
|
44
|
+
: lifecycle.root;
|
|
45
|
+
const facts = useGitFacts(live?.root ?? null, live?.generation ?? null);
|
|
46
|
+
const connection = live?.git ?? null;
|
|
47
|
+
const client = connection?.client ?? null;
|
|
48
|
+
const [tab, setTab] = useState("files");
|
|
49
|
+
// Bumped after a write so the next read is immediate rather than waiting
|
|
50
|
+
// out the poll — a stage that takes four seconds to show reads as a stage
|
|
51
|
+
// that did not happen.
|
|
52
|
+
const [revision, setRevision] = useState(0);
|
|
53
|
+
const branch = useGitRead(connection, readBranch, revision).value;
|
|
54
|
+
const status = useGitRead(connection, readStatus, revision).value;
|
|
55
|
+
const log = useGitRead(connection, readLog, revision).value;
|
|
56
|
+
const entries = status?.entries ?? [];
|
|
57
|
+
const commits = log?.commits ?? [];
|
|
58
|
+
const unpushed = useMemo(() => commits.some((commit) => commit.pushed === null)
|
|
59
|
+
? null
|
|
60
|
+
: commits.filter((commit) => commit.pushed === false).length, [commits]);
|
|
61
|
+
const host = useRoom().host;
|
|
62
|
+
const hasShell = host?.worktree !== undefined;
|
|
63
|
+
const listBrowsers = useMemo(() => host?.browsers?.bind(host), [host]);
|
|
64
|
+
const openInBrowser = useMemo(() => (host === null ? null : (name, bytes, browserId) => host.openInBrowser(name, bytes, browserId)), [host]);
|
|
65
|
+
const stale = projectRoot !== null && shownRoot !== null && shownRoot !== projectRoot;
|
|
66
|
+
const hasSiblingWorktrees = facts !== null && facts.worktrees.length > 1;
|
|
67
|
+
const lifecycleError = lifecycle.status === "error" && lifecycle.root === projectRoot
|
|
68
|
+
? lifecycle.message
|
|
69
|
+
: requestError;
|
|
70
|
+
const [open, setOpen] = useState(null);
|
|
71
|
+
const [selection, setSelection] = useState(null);
|
|
72
|
+
const [openCommit, setOpenCommit] = useState(null);
|
|
73
|
+
const [commitFiles, setCommitFiles] = useState(null);
|
|
74
|
+
const [pendingDiscard, setPendingDiscard] = useState(null);
|
|
75
|
+
// One source per engine and one per client: the read hook treats a new
|
|
76
|
+
// source as a new request, and a project switch invalidates every id and
|
|
77
|
+
// every path the old ones issued.
|
|
78
|
+
const fileSource = useMemo(() => (engine === null ? null : createWorktreeFileSource(engine)), [engine]);
|
|
79
|
+
const gitSource = useMemo(() => (client === null ? null : createGitFileSource(client)), [client]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
setOpen(null);
|
|
82
|
+
setSelection(null);
|
|
83
|
+
setOpenCommit(null);
|
|
84
|
+
}, [fileSource, gitSource]);
|
|
85
|
+
const act = useCallback((label, paths, run) => {
|
|
86
|
+
void run(paths)
|
|
87
|
+
.then(() => {
|
|
88
|
+
onReceipt(`${label} ${paths.length} ${paths.length === 1 ? "file" : "files"}`);
|
|
89
|
+
setRevision((n) => n + 1);
|
|
90
|
+
})
|
|
91
|
+
.catch((error) => {
|
|
92
|
+
onReceipt(error instanceof Error ? error.message : `could not ${label.toLowerCase()}`);
|
|
93
|
+
setRevision((n) => n + 1);
|
|
94
|
+
});
|
|
95
|
+
}, [onReceipt]);
|
|
96
|
+
const showDiff = (path, staged) => {
|
|
97
|
+
if (connection === null)
|
|
98
|
+
return;
|
|
99
|
+
setSelection({ path, staged });
|
|
100
|
+
setOpen({
|
|
101
|
+
handle: diffHandle({ path, staged }, { root: connection.root, label: path }),
|
|
102
|
+
diff: true,
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
const showCommit = (commit) => {
|
|
106
|
+
setOpenCommit(commit);
|
|
107
|
+
setCommitFiles(null);
|
|
108
|
+
setSelection(null);
|
|
109
|
+
if (client === null)
|
|
110
|
+
return;
|
|
111
|
+
void client
|
|
112
|
+
.commitFiles(commit.sha)
|
|
113
|
+
.then((answer) => {
|
|
114
|
+
if (answer.error !== null) {
|
|
115
|
+
onReceipt(answer.error);
|
|
116
|
+
setCommitFiles([]);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
setCommitFiles(answer.files);
|
|
120
|
+
})
|
|
121
|
+
.catch((error) => {
|
|
122
|
+
onReceipt(error instanceof Error ? error.message : "could not read that commit");
|
|
123
|
+
setCommitFiles([]);
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
const count = tab === "history"
|
|
127
|
+
? commits.length
|
|
128
|
+
: tab === "changes"
|
|
129
|
+
? entries.length
|
|
130
|
+
: // The Files tab has no honest count: we know what the tree is
|
|
131
|
+
// showing, not what the repository holds.
|
|
132
|
+
null;
|
|
133
|
+
const source = open?.diff === true ? gitSource : fileSource;
|
|
134
|
+
return (_jsxs("div", { className: "ah-col ah-col--rail", children: [_jsx(WorktreeHeader, { root: shownRoot, tint: tint, homeDirectory: homeDirectory, facts: facts, branch: branch, tab: tab, count: count, changeShape: changeShapeOf(entries), unpushed: unpushed, folders: folders }), _jsx("div", { className: "ah-listbar", children: _jsx(SegmentedControl, { className: "ah-gitseg", accessibleLabel: "What this column shows", value: tab, options: TABS.map((option) => ({ value: option.value, label: option.label })), onValueChange: (next) => {
|
|
135
|
+
setTab(next);
|
|
136
|
+
setSelection(null);
|
|
137
|
+
} }) }), elsewhere !== undefined && elsewhere !== null ? (_jsx("div", { className: "ah-elsewhere", children: elsewhere })) : !hasShell ? (_jsx(EmptyState, { title: "No repository here", description: "This column needs the desktop shell \u2014 a browser tab has no worktree to read." })) : projectRoot === null ? (_jsx(EmptyState, { title: "No project selected", description: "Pick a project to browse its worktree." })) : lifecycleError !== null ? (_jsx(EmptyState, { title: "Worktree unavailable", description: lifecycleError, children: _jsx("button", { type: "button", onClick: onRetry, style: {
|
|
138
|
+
border: "1px solid var(--vf-hairline-strong)",
|
|
139
|
+
borderRadius: 6,
|
|
140
|
+
padding: "4px 9px",
|
|
141
|
+
color: "var(--vf-text-secondary)",
|
|
142
|
+
background: "var(--vf-fill)",
|
|
143
|
+
cursor: "pointer",
|
|
144
|
+
}, children: "Try again" }) })) : tab === "files" ? (engine === null || fileSource === null ? (_jsx(EmptyState, { title: "Opening the worktree", description: "The engine is walking the project root." })) : (_jsxs("div", { className: "ah-railbody", "data-split": hasSiblingWorktrees || undefined, children: [_jsx(WorktreeFileTree, { engine: engine, stale: stale, onReceipt: onReceipt, openEntryId: open?.diff === false && typeof open.handle.ref === "number" ? open.handle.ref : null, onOpen: (entry) => {
|
|
145
|
+
// A folder toggles rather than opens; mille only reports rows
|
|
146
|
+
// with no children, which an empty directory also is.
|
|
147
|
+
if (isOpenable(entry))
|
|
148
|
+
setOpen({ handle: handleFor(engine, entry), diff: false });
|
|
149
|
+
} }), hasSiblingWorktrees && (_jsx(WorktreeList, { facts: facts, openRoot: shownRoot, homeDirectory: homeDirectory }))] }))) : connection === null ? (_jsx(EmptyState, { title: "Reading the repository", description: "Asking git for its status." })) : tab === "changes" ? (_jsx(GitChanges, { entries: entries, sessionPaths: sessionPaths, selection: selection, onSelect: showDiff, onStage: client === null ? null : (paths) => act("Staged", paths, client.stage), onUnstage: client === null ? null : (paths) => act("Unstaged", paths, client.unstage), onDiscard: client === null ? null : setPendingDiscard })) : (_jsx(GitHistory, { commits: commits, selectedSha: openCommit, onSelect: showCommit, currentTimestamp: currentTimestamp })), openCommit !== null && (_jsx(CommitViewer, { commit: openCommit, files: commitFiles, client: client, sessionPaths: sessionPaths, currentTimestamp: currentTimestamp, onReceipt: onReceipt, onClose: () => {
|
|
150
|
+
setOpenCommit(null);
|
|
151
|
+
setCommitFiles(null);
|
|
152
|
+
} })), _jsx(ConfirmDialog, { question: pendingDiscard === null
|
|
153
|
+
? null
|
|
154
|
+
: {
|
|
155
|
+
title: pendingDiscard.length === 1
|
|
156
|
+
? "Discard this file's changes?"
|
|
157
|
+
: `Discard changes to ${pendingDiscard.length} files?`,
|
|
158
|
+
body: (_jsxs(_Fragment, { children: [_jsx("p", { children: "This throws the work away. It is not staged and it is not committed, so git has no copy of it and neither does this room." }), _jsxs("ul", { className: "ah-confirm__list", children: [pendingDiscard.slice(0, 8).map((path) => (_jsx("li", { children: path }, path))), pendingDiscard.length > 8 && (_jsxs("li", { "data-more": true, children: ["and ", pendingDiscard.length - 8, " more"] }))] })] })),
|
|
159
|
+
confirm: "Discard",
|
|
160
|
+
destructive: true,
|
|
161
|
+
}, onCancel: () => setPendingDiscard(null), onConfirm: () => {
|
|
162
|
+
if (pendingDiscard !== null && client !== null) {
|
|
163
|
+
act("Discarded", pendingDiscard, client.discard);
|
|
164
|
+
}
|
|
165
|
+
setPendingDiscard(null);
|
|
166
|
+
} }), source !== null && (_jsx(FileViewerDialog, { handle: open?.handle ?? null, source: source, tint: tint, homeDirectory: homeDirectory, onClose: () => setOpen(null), onReceipt: onReceipt, listBrowsers: listBrowsers, openInBrowser: open?.diff === true ? null : openInBrowser,
|
|
167
|
+
// The Files tab opens a FILE; the other two open a CHANGE. The
|
|
168
|
+
// registry reads kinds off a name, and a name cannot say which.
|
|
169
|
+
asDiff: open?.diff === true }))] }));
|
|
170
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Entry } from "@vibecook/mille";
|
|
2
|
+
import type { WorktreeEngine } from "./types.js";
|
|
3
|
+
export interface WorktreeFileTreeProps {
|
|
4
|
+
readonly engine: WorktreeEngine;
|
|
5
|
+
/** The engine is still walking a root the room has moved on from, so the
|
|
6
|
+
* tree is showing something true but stale. */
|
|
7
|
+
readonly stale: boolean;
|
|
8
|
+
/** A file the reader asked to see. Double-click or Enter, the way every
|
|
9
|
+
* file tree has worked for thirty years — a single click still just
|
|
10
|
+
* selects, because a row that throws a modal on every click is a row you
|
|
11
|
+
* learn not to touch. */
|
|
12
|
+
readonly onOpen: (entry: Entry) => void;
|
|
13
|
+
/** The file the viewer currently has open, so the row wears the active
|
|
14
|
+
* fill. The design record left this binding open (§10 delta 4) because a
|
|
15
|
+
* reader with no open FILE had nothing to bind it to; now there is one. */
|
|
16
|
+
readonly openEntryId: number | null;
|
|
17
|
+
readonly onReceipt: (message: string) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function WorktreeFileTree({ engine, stale, onOpen, openEntryId, onReceipt, }: WorktreeFileTreeProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Mille's shipped tree, with Rosetta's read-only commands: inspect a file,
|
|
3
|
+
// copy its path, or reveal it in the desktop file manager.
|
|
4
|
+
import { useMemo, useRef } from "react";
|
|
5
|
+
import { FileTree, FileTreeProvider } from "@vibecook/mille-ui";
|
|
6
|
+
import { vibefieldIconTheme } from "@vibecook/mille-ui/icons/vibefield";
|
|
7
|
+
import { useRoom } from "../../room-context.js";
|
|
8
|
+
import { createWorktreeFileCommands } from "./worktree-file-commands.js";
|
|
9
|
+
/** Mille's create/rename shortcuts also have direct engine fallbacks. Keep
|
|
10
|
+
* those out of this read-only tree, while letting its own copy binding and
|
|
11
|
+
* navigation run normally. Portaled menus and text inputs own their keys. */
|
|
12
|
+
function guardTreeKeys(event) {
|
|
13
|
+
const target = event.target;
|
|
14
|
+
if (!(target instanceof HTMLElement) || !target.closest('[role="tree"]'))
|
|
15
|
+
return;
|
|
16
|
+
if (target.closest('input, textarea, [contenteditable]:not([contenteditable="false"])')) {
|
|
17
|
+
event.stopPropagation();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const key = event.key.toLowerCase();
|
|
21
|
+
if (key === "f2" || key === "delete" || key === "backspace" ||
|
|
22
|
+
((event.ctrlKey || event.metaKey) && !event.altKey && ["x", "v", "n"].includes(key))) {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
event.stopPropagation();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** mille types `FileTreeProvider.fx` as the in-process engine, but the
|
|
28
|
+
* embedding guide's own architecture puts the walker in a utility process and
|
|
29
|
+
* the renderer on a port. The port client mirrors that surface — the one
|
|
30
|
+
* place the room states it, rather than casting at every call site. */
|
|
31
|
+
function asTreeEngine(engine) {
|
|
32
|
+
return engine.fx;
|
|
33
|
+
}
|
|
34
|
+
export function WorktreeFileTree({ engine, stale, onOpen, openEntryId, onReceipt, }) {
|
|
35
|
+
const host = useRoom().host;
|
|
36
|
+
const actions = host?.worktree ?? null;
|
|
37
|
+
const platform = host?.platform ?? null;
|
|
38
|
+
const environment = useRef({ actions, platform, stale, onReceipt });
|
|
39
|
+
environment.current = { actions, platform, stale, onReceipt };
|
|
40
|
+
const { commands, onSelectionChange, onFocusedIdChange } = useMemo(() => createWorktreeFileCommands(engine, () => environment.current), [engine]);
|
|
41
|
+
return (_jsx("div", {
|
|
42
|
+
// `ah-rail*` is the design record's name for this column; room.css is
|
|
43
|
+
// a port of the proto and keeps its vocabulary.
|
|
44
|
+
className: "ah-railtree", "data-mille-theme": "vibefield", "data-stale": stale ? "" : undefined, onKeyDownCapture: guardTreeKeys,
|
|
45
|
+
// macOS's native Edit > Copy can arrive as a copy event instead of a
|
|
46
|
+
// keydown. Route it through the very same selection-aware command.
|
|
47
|
+
onCopy: (event) => {
|
|
48
|
+
const target = event.target;
|
|
49
|
+
if (!(target instanceof HTMLElement) || !target.closest('[role="tree"]') ||
|
|
50
|
+
target.closest('input, textarea, [contenteditable]:not([contenteditable="false"])'))
|
|
51
|
+
return;
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
void commands.dispatch("file.copyAbsolutePath");
|
|
55
|
+
}, children: _jsx(FileTreeProvider, { fx: asTreeEngine(engine), commands: commands, children: _jsx(FileTree, { ariaLabel: "Project worktree", iconTheme: vibefieldIconTheme, disableDragDrop: true, onSelectionChange: onSelectionChange, onFocusedIdChange: onFocusedIdChange, onOpen: (entry) => onOpen(entry),
|
|
56
|
+
// Marks the row without revealing it: `autoRevealActiveEntry`
|
|
57
|
+
// defaults to false, and the reader who just clicked a row does not
|
|
58
|
+
// need the tree to scroll it back under their cursor.
|
|
59
|
+
activeEntry: openEntryId, style: { height: "100%" } }) }, engine.generation) }));
|
|
60
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { GitFacts } from "../../ports.js";
|
|
2
|
+
import type { BranchFacts } from "../git/index.js";
|
|
3
|
+
import type { RepoTab } from "./types.js";
|
|
4
|
+
import type { RoomFolder, RoomMenu } from "../../host-inputs.js";
|
|
5
|
+
export interface WorktreeHeaderProps {
|
|
6
|
+
/** The root the tree is actually showing, or null before one opens. */
|
|
7
|
+
readonly root: string | null;
|
|
8
|
+
readonly tint: string | null;
|
|
9
|
+
readonly homeDirectory: string | null;
|
|
10
|
+
/** Branch and dirty count from the shell, for the Files tab's caption. */
|
|
11
|
+
readonly facts: GitFacts | null;
|
|
12
|
+
/** Branch and upstream from the engine, for History's. */
|
|
13
|
+
readonly branch: BranchFacts | null;
|
|
14
|
+
readonly tab: RepoTab;
|
|
15
|
+
/** What the current tab is listing, or null for a tab with no honest count. */
|
|
16
|
+
readonly count: number | null;
|
|
17
|
+
readonly changeShape: string;
|
|
18
|
+
readonly unpushed: number | null;
|
|
19
|
+
/** R6: the host's folders; the name becomes their dropdown, its mark in front. */
|
|
20
|
+
readonly folders?: {
|
|
21
|
+
readonly menu: RoomMenu;
|
|
22
|
+
readonly shown: RoomFolder | null;
|
|
23
|
+
} | null | undefined;
|
|
24
|
+
}
|
|
25
|
+
/** `branch · n dirty` — and nothing at all without a branch to hang it on.
|
|
26
|
+
* The dirty count is the change set's size, not the number of letters the
|
|
27
|
+
* tree happens to be drawing: a file inside a collapsed folder is still
|
|
28
|
+
* dirty, and reporting fewer than git would is reporting the interface. */
|
|
29
|
+
export declare function formatGitFacts(facts: GitFacts | null): string | null;
|
|
30
|
+
/** `3 unpushed`, or the honest silence of a branch with no upstream. */
|
|
31
|
+
export declare function formatSync(branch: BranchFacts | null, unpushed: number | null): string;
|
|
32
|
+
export declare function WorktreeHeader({ root, tint, homeDirectory, facts, branch, tab, count, changeShape, unpushed, folders, }: WorktreeHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// The column is named by the folder it is showing, because that is the thing
|
|
3
|
+
// — "Worktree" was a category, and the head names objects. A path is an id,
|
|
4
|
+
// so it sets in mono.
|
|
5
|
+
//
|
|
6
|
+
// A commit no longer appears here: it opens over the room in its own
|
|
7
|
+
// surface, where a file list and its diff fit side by side, so the head
|
|
8
|
+
// never has to become something other than this column's own object.
|
|
9
|
+
//
|
|
10
|
+
// One column, three tabs, and the head names what THAT tab is a view of —
|
|
11
|
+
// which is a different object per tab, and the design record already draws
|
|
12
|
+
// it that way across the two columns this one merges: its rail head names
|
|
13
|
+
// the folder, its git head names the branch. Files is a view of a checkout,
|
|
14
|
+
// so it takes the path; changes and history are views of a ref, so they take
|
|
15
|
+
// the branch. Inside a commit the object is the commit.
|
|
16
|
+
//
|
|
17
|
+
// It is also what fits. A 280px head holding a path, a count and a
|
|
18
|
+
// three-term caption gave the path four characters, and a head that cannot
|
|
19
|
+
// say its object's name is not naming it.
|
|
20
|
+
//
|
|
21
|
+
// The caption is what git would say about that tab's set, and the badge
|
|
22
|
+
// counts what the tab is listing — which is why Files has none: we know how
|
|
23
|
+
// many files the tree is SHOWING, not how many the repository has, and a
|
|
24
|
+
// badge counting the interface is not a fact about the thing.
|
|
25
|
+
import { ColumnHeading } from "../ui/index.js";
|
|
26
|
+
import { tildePath } from "../../lib/format.js";
|
|
27
|
+
import { HostMenuButton } from "../HostMenu.js";
|
|
28
|
+
const CARET = (_jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "m4.5 6.5 3.5 3.5 3.5-3.5" }) }));
|
|
29
|
+
/** `branch · n dirty` — and nothing at all without a branch to hang it on.
|
|
30
|
+
* The dirty count is the change set's size, not the number of letters the
|
|
31
|
+
* tree happens to be drawing: a file inside a collapsed folder is still
|
|
32
|
+
* dirty, and reporting fewer than git would is reporting the interface. */
|
|
33
|
+
export function formatGitFacts(facts) {
|
|
34
|
+
if (facts === null || facts.branch === null)
|
|
35
|
+
return null;
|
|
36
|
+
if (facts.dirty === null)
|
|
37
|
+
return facts.branch;
|
|
38
|
+
return `${facts.branch} · ${facts.dirty} dirty`;
|
|
39
|
+
}
|
|
40
|
+
/** `3 unpushed`, or the honest silence of a branch with no upstream. */
|
|
41
|
+
export function formatSync(branch, unpushed) {
|
|
42
|
+
if (branch === null)
|
|
43
|
+
return "";
|
|
44
|
+
// Not "0 unpushed": with no upstream, nothing here knows.
|
|
45
|
+
if (branch.upstream === null)
|
|
46
|
+
return "no upstream";
|
|
47
|
+
const parts = [];
|
|
48
|
+
if (unpushed !== null && unpushed > 0)
|
|
49
|
+
parts.push(`${unpushed} unpushed`);
|
|
50
|
+
if (branch.behind !== null && branch.behind > 0)
|
|
51
|
+
parts.push(`${branch.behind} behind`);
|
|
52
|
+
return parts.length > 0 ? parts.join(" · ") : "up to date";
|
|
53
|
+
}
|
|
54
|
+
export function WorktreeHeader({ root, tint, homeDirectory, facts, branch, tab, count, changeShape, unpushed, folders = null, }) {
|
|
55
|
+
const shown = folders?.shown ?? null;
|
|
56
|
+
const caption = shown?.caption !== undefined
|
|
57
|
+
? shown.caption
|
|
58
|
+
: tab === "history"
|
|
59
|
+
? formatSync(branch, unpushed)
|
|
60
|
+
: tab === "changes"
|
|
61
|
+
? changeShape
|
|
62
|
+
: (formatGitFacts(facts) ?? "");
|
|
63
|
+
const onFiles = tab === "files";
|
|
64
|
+
const path = root === null ? "—" : tildePath(root, homeDirectory);
|
|
65
|
+
// A detached HEAD has no branch name; the checkout it is in is the honest
|
|
66
|
+
// fallback, and it is the same object either way.
|
|
67
|
+
const ref = branch?.name ?? facts?.branch ?? path;
|
|
68
|
+
if (folders !== null) {
|
|
69
|
+
// The head is the folder list: the shown folder's mark and name, one button.
|
|
70
|
+
const folderPath = shown === null ? path : tildePath(shown.path, homeDirectory);
|
|
71
|
+
const name = onFiles ? folderPath : ref;
|
|
72
|
+
return (_jsxs("header", { children: [_jsxs(HostMenuButton, { menu: folders.menu, className: "ah-folderpick", label: `Folder: ${shown?.path ?? root ?? "none"}`, title: shown?.path ?? root ?? undefined, align: "start", children: [_jsx("i", { style: tint !== null ? { "--tint": tint } : undefined }), shown?.mark !== undefined && shown.mark !== null && _jsx("span", { className: "ah-folderpick__mark", children: shown.mark }), _jsx("strong", { className: "ah-idname", children: name }), count !== null && _jsx("span", { className: "ah-bubble", children: count }), CARET] }), caption !== "" && _jsx("span", { className: "ah-caption tnum", children: caption })] }));
|
|
73
|
+
}
|
|
74
|
+
return (_jsxs("header", { children: [_jsx(ColumnHeading, { name: onFiles ? path : ref, tint: tint, mono: true, count: count, countTitle: count === null
|
|
75
|
+
? undefined
|
|
76
|
+
: `${count} ${tab === "history" ? "commits" : "changed files"}`,
|
|
77
|
+
// Files abbreviates to `~`, so the tooltip keeps the whole path; a
|
|
78
|
+
// branch on the other two is already whole, and its tooltip says
|
|
79
|
+
// which checkout it is a branch OF.
|
|
80
|
+
title: onFiles ? root : (root ?? undefined) }), caption !== "" && _jsx("span", { className: "ah-caption tnum", children: caption })] }));
|
|
81
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GitFacts } from "../../ports.js";
|
|
2
|
+
export interface WorktreeListProps {
|
|
3
|
+
readonly facts: GitFacts;
|
|
4
|
+
/** The root the tree is showing, which earns the dirty count. */
|
|
5
|
+
readonly openRoot: string | null;
|
|
6
|
+
readonly homeDirectory: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function WorktreeList({ facts, openRoot, homeDirectory }: WorktreeListProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { tildePath } from "../../lib/format.js";
|
|
3
|
+
export function WorktreeList({ facts, openRoot, homeDirectory }) {
|
|
4
|
+
// `ah-rail*` is the design record's name for this column; room.css is a
|
|
5
|
+
// port of the proto and keeps its vocabulary.
|
|
6
|
+
return (_jsxs("div", { className: "ah-railfoot", children: [_jsx("div", { className: "ah-railsplit", children: _jsx("span", { className: "ah-eyebrow", children: "Worktrees" }) }), _jsx("div", { className: "ah-railfoot__list", role: "region", "aria-label": "Worktrees", tabIndex: 0, children: facts.worktrees.map((worktree) => {
|
|
7
|
+
// The count belongs to the checkout the shell actually read, and
|
|
8
|
+
// git reports it for one worktree at a time.
|
|
9
|
+
const dirty = worktree.path === openRoot ? facts.dirty : null;
|
|
10
|
+
return (_jsxs("div", { className: "ah-worktree", title: worktree.path, children: [_jsx("span", { children: worktree.branch ?? tildePath(worktree.path, homeDirectory) }), dirty !== null && (_jsx("code", { "data-dirty": dirty > 0 ? "" : undefined, className: "tnum", children: dirty > 0 ? `${dirty} dirty` : "clean" }))] }, worktree.path));
|
|
11
|
+
}) })] }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { RepoTab, WorktreeEngine } from "./types.js";
|
|
2
|
+
export { useWorktreeGuest } from "./use-worktree-guest.js";
|
|
3
|
+
export type { WorktreeGuest } from "./use-worktree-guest.js";
|
|
4
|
+
export { WorktreeColumn } from "./WorktreeColumn.js";
|
|
5
|
+
export type { WorktreeColumnProps } from "./WorktreeColumn.js";
|
|
6
|
+
export { formatGitFacts, formatSync, WorktreeHeader } from "./WorktreeHeader.js";
|
|
7
|
+
export type { WorktreeHeaderProps } from "./WorktreeHeader.js";
|
|
8
|
+
export { createWorktreeFileSource, handleFor, isOpenable } from "./worktree-file-source.js";
|
|
9
|
+
export { WorktreeFileTree } from "./WorktreeFileTree.js";
|
|
10
|
+
export type { WorktreeFileTreeProps } from "./WorktreeFileTree.js";
|
|
11
|
+
export { WorktreeList } from "./WorktreeList.js";
|
|
12
|
+
export type { WorktreeListProps } from "./WorktreeList.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Column ③ — the project's repository: files, changes, history.
|
|
2
|
+
export { useWorktreeGuest } from "./use-worktree-guest.js";
|
|
3
|
+
export { WorktreeColumn } from "./WorktreeColumn.js";
|
|
4
|
+
export { formatGitFacts, formatSync, WorktreeHeader } from "./WorktreeHeader.js";
|
|
5
|
+
export { createWorktreeFileSource, handleFor, isOpenable } from "./worktree-file-source.js";
|
|
6
|
+
export { WorktreeFileTree } from "./WorktreeFileTree.js";
|
|
7
|
+
export { WorktreeList } from "./WorktreeList.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PortFileExplorer } from "@vibecook/mille/port";
|
|
2
|
+
/** The three views this column offers of one project: the worktree as it
|
|
3
|
+
* stands, what git has not recorded yet, and what it has. */
|
|
4
|
+
export type RepoTab = "files" | "changes" | "history";
|
|
5
|
+
/** A live connection to one mille engine, and the root it is walking.
|
|
6
|
+
*
|
|
7
|
+
* The root travels WITH the connection rather than beside it: the engine
|
|
8
|
+
* follows a project switch with a lag (kill, re-fork, walk), and the column
|
|
9
|
+
* must be able to name what the tree is actually showing at any moment, not
|
|
10
|
+
* what was last asked for. */
|
|
11
|
+
export interface WorktreeEngine {
|
|
12
|
+
readonly fx: PortFileExplorer;
|
|
13
|
+
readonly root: string;
|
|
14
|
+
/** Utility-process generation. Entry ids are scoped to this identity. */
|
|
15
|
+
readonly generation: number;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface WorktreeGuest {
|
|
2
|
+
/** Whether a worktree can be shown at all: a host without a worktree
|
|
3
|
+
* engine (a browser tab) has nothing to walk one with, so the toggle has
|
|
4
|
+
* nothing to offer. */
|
|
5
|
+
readonly available: boolean;
|
|
6
|
+
/** Whether the column is currently open. */
|
|
7
|
+
readonly visible: boolean;
|
|
8
|
+
/** A shell-level refusal before a process generation could start. */
|
|
9
|
+
readonly error: string | null;
|
|
10
|
+
/** Open a closed column, close an open one. */
|
|
11
|
+
toggle(): void;
|
|
12
|
+
/** Explicitly start a fresh generation, even for the same root. */
|
|
13
|
+
retry(): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Whether column ③ is open, and the act of flipping it — plus the standing
|
|
17
|
+
* instruction to the host to keep an engine on `projectRoot` while it is.
|
|
18
|
+
* `roomWidth` is the room's own measured width, not the window's: a host may
|
|
19
|
+
* seat the room in less than its window. Null until measured.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useWorktreeGuest(projectRoot: string | null, roomWidth: number | null): WorktreeGuest;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// H-3, in one place: the worktree column is a GUEST, and the measure is not.
|
|
2
|
+
// Below a frame the room cannot seat everyone in, the guest closes itself
|
|
3
|
+
// rather than squeeze the transcript — reading is the job, and when something
|
|
4
|
+
// has to give it is not the thing the room exists for.
|
|
5
|
+
//
|
|
6
|
+
// The column's whole lifecycle lives here because the two halves are one
|
|
7
|
+
// decision: what the room shows, and what the engine is therefore asked to
|
|
8
|
+
// walk. Keeping them together is what stops the shell from forking a walker
|
|
9
|
+
// for a column nobody can see.
|
|
10
|
+
import { useEffect, useRef, useState } from "react";
|
|
11
|
+
import { useRoom } from "../../room-context.js";
|
|
12
|
+
/** Below this room width the guest closes itself (design record H-3). 260 + 300 + 280
|
|
13
|
+
* of columns leaves the transcript its full measure down to ~1100px once the
|
|
14
|
+
* guest is out of the way, so the guest is what pays. */
|
|
15
|
+
const GUEST_MIN_FRAME_WIDTH = 1360;
|
|
16
|
+
/**
|
|
17
|
+
* Whether column ③ is open, and the act of flipping it — plus the standing
|
|
18
|
+
* instruction to the host to keep an engine on `projectRoot` while it is.
|
|
19
|
+
* `roomWidth` is the room's own measured width, not the window's: a host may
|
|
20
|
+
* seat the room in less than its window. Null until measured.
|
|
21
|
+
*/
|
|
22
|
+
export function useWorktreeGuest(projectRoot, roomWidth) {
|
|
23
|
+
const engine = useRoom().host?.worktree ?? null;
|
|
24
|
+
const available = engine !== null;
|
|
25
|
+
const [wanted, setWanted] = useState(true);
|
|
26
|
+
// An explicit choice outranks the automatic close: once the reader has
|
|
27
|
+
// pressed the toggle, the width heuristic stops speaking for them.
|
|
28
|
+
const [chosen, setChosen] = useState(false);
|
|
29
|
+
const [retryRevision, setRetryRevision] = useState(0);
|
|
30
|
+
const [failure, setFailure] = useState(null);
|
|
31
|
+
const openedRoot = useRef(null);
|
|
32
|
+
const requestId = useRef(0);
|
|
33
|
+
const frameWide = roomWidth !== null && roomWidth >= GUEST_MIN_FRAME_WIDTH;
|
|
34
|
+
// A wide room keeps the guest's empty state visible before a project is
|
|
35
|
+
// chosen. A missing root suppresses the engine, not the column explaining it.
|
|
36
|
+
const visible = available && wanted && (chosen || frameWide);
|
|
37
|
+
const toggle = () => {
|
|
38
|
+
// Flips what is SHOWN, not what was last wanted — the first press on an
|
|
39
|
+
// already-auto-closed column must never do nothing.
|
|
40
|
+
if (visible) {
|
|
41
|
+
setWanted(false);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
setWanted(true);
|
|
45
|
+
setChosen(true);
|
|
46
|
+
};
|
|
47
|
+
const retry = () => {
|
|
48
|
+
openedRoot.current = null;
|
|
49
|
+
setFailure(null);
|
|
50
|
+
setRetryRevision((revision) => revision + 1);
|
|
51
|
+
};
|
|
52
|
+
// Point the engine at the selected project's root. Killing and re-forking
|
|
53
|
+
// the walker is the shell's concern, so this only speaks when the root
|
|
54
|
+
// actually changes — a re-render is not news.
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (!visible || projectRoot === null)
|
|
57
|
+
return;
|
|
58
|
+
if (openedRoot.current === projectRoot)
|
|
59
|
+
return;
|
|
60
|
+
if (engine === null)
|
|
61
|
+
return;
|
|
62
|
+
const id = (requestId.current += 1);
|
|
63
|
+
openedRoot.current = projectRoot;
|
|
64
|
+
setFailure(null);
|
|
65
|
+
void engine
|
|
66
|
+
.open(projectRoot)
|
|
67
|
+
.then((result) => {
|
|
68
|
+
if (requestId.current !== id)
|
|
69
|
+
return;
|
|
70
|
+
if (result.ok)
|
|
71
|
+
return;
|
|
72
|
+
openedRoot.current = null;
|
|
73
|
+
setFailure({ root: projectRoot, message: result.error });
|
|
74
|
+
})
|
|
75
|
+
.catch((reason) => {
|
|
76
|
+
if (requestId.current !== id)
|
|
77
|
+
return;
|
|
78
|
+
openedRoot.current = null;
|
|
79
|
+
setFailure({
|
|
80
|
+
root: projectRoot,
|
|
81
|
+
message: reason instanceof Error ? reason.message : "Could not open the worktree.",
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}, [visible, projectRoot, retryRevision, engine]);
|
|
85
|
+
return {
|
|
86
|
+
available,
|
|
87
|
+
visible,
|
|
88
|
+
error: failure?.root === projectRoot ? failure.message : null,
|
|
89
|
+
toggle,
|
|
90
|
+
retry,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EntryId } from "@vibecook/mille";
|
|
2
|
+
import type { WorktreeHostPort } from "../../ports.js";
|
|
3
|
+
import type { WorktreeEngine } from "./types.js";
|
|
4
|
+
interface FileActionEnvironment {
|
|
5
|
+
/** The host's worktree engine, which performs the acts; null without one. */
|
|
6
|
+
readonly actions: Pick<WorktreeHostPort, "fileAction"> | null;
|
|
7
|
+
/** The desktop's platform, for the name of its file manager. */
|
|
8
|
+
readonly platform: string | null;
|
|
9
|
+
readonly stale: boolean;
|
|
10
|
+
readonly onReceipt: (message: string) => void;
|
|
11
|
+
}
|
|
12
|
+
/** One registry per engine generation. Menu commands receive Mille's live
|
|
13
|
+
* context; keyboard commands get the same selection through its observers. */
|
|
14
|
+
export declare function createWorktreeFileCommands(engine: WorktreeEngine, environment: () => FileActionEnvironment): {
|
|
15
|
+
commands: import("@vibecook/mille-ui/commands").CommandRegistry;
|
|
16
|
+
onSelectionChange: (ids: ReadonlySet<EntryId>) => void;
|
|
17
|
+
onFocusedIdChange: (id: EntryId | null) => void;
|
|
18
|
+
};
|
|
19
|
+
export {};
|