@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,143 @@
|
|
|
1
|
+
import type { TimelineEntry } from "@vibefield/rosetta-protocol";
|
|
2
|
+
import type { LedgerDetail } from "./families.js";
|
|
3
|
+
import type { LedgerClass, LedgerContext, LedgerGlyph, ObjectPart, ToolFamily } from "./vocabulary.js";
|
|
4
|
+
/** Even a single activity line closes to its head (2026-09-09 amendment). */
|
|
5
|
+
export declare const RUN_FOLD_THRESHOLD = 1;
|
|
6
|
+
/** How many members a fold names before it degrades to `… N more`. */
|
|
7
|
+
export declare const FOLD_NAME_LIMIT = 4;
|
|
8
|
+
/**
|
|
9
|
+
* T-5. `failed` is red (failed · denied · timed out — the act did not
|
|
10
|
+
* complete). `muted` is not red, because nothing failed: cancelled,
|
|
11
|
+
* interrupted, and a status the source never proved. `running` is the green
|
|
12
|
+
* breath, and only a live session should draw it as alive. Success is the
|
|
13
|
+
* absence of all three.
|
|
14
|
+
*/
|
|
15
|
+
export type LedgerState = "done" | "running" | "failed" | "muted";
|
|
16
|
+
/**
|
|
17
|
+
* How the result slot is drawn. `plain` and `muted` are bare spans; `failed`
|
|
18
|
+
* and `running` are the record's `.why` span, which takes its hue from the
|
|
19
|
+
* line's state.
|
|
20
|
+
*/
|
|
21
|
+
export type ResultTone = "plain" | "failed" | "muted" | "running";
|
|
22
|
+
export interface LedgerLine {
|
|
23
|
+
/** Stable across renders: the first member row's `timeline_id`. */
|
|
24
|
+
readonly key: string;
|
|
25
|
+
/** Every row behind this line — one, or a fold's members. Anchors, focus
|
|
26
|
+
* landing and the watermark all read `timeline_id` / `ordinal` from here. */
|
|
27
|
+
readonly rows: readonly TimelineEntry[];
|
|
28
|
+
readonly family: ToolFamily;
|
|
29
|
+
readonly cls: LedgerClass;
|
|
30
|
+
/** The FAMILY glyph. A `failed` line draws `#g-fail` in this slot instead,
|
|
31
|
+
* and a `running` line draws the breathing dot — state substitutes, the
|
|
32
|
+
* name does not change. */
|
|
33
|
+
readonly glyph: LedgerGlyph;
|
|
34
|
+
readonly verb: string;
|
|
35
|
+
/** Concatenate in order with no separator; each part carries its own
|
|
36
|
+
* spacing. `tone` names the record's own class: plain · dir · query · aside. */
|
|
37
|
+
readonly object: readonly ObjectPart[];
|
|
38
|
+
readonly result: string | null;
|
|
39
|
+
readonly resultTone: ResultTone;
|
|
40
|
+
readonly state: LedgerState;
|
|
41
|
+
/** Time-of-day for the margin anchor: `completed_at ?? row.at`, and a fold's
|
|
42
|
+
* first stamp — or its LAST when `elided`. */
|
|
43
|
+
readonly at: number | null;
|
|
44
|
+
readonly startedAt: number | null;
|
|
45
|
+
readonly endedAt: number | null;
|
|
46
|
+
/** The line's own span when the source proved one. When `result` is null the
|
|
47
|
+
* projection has already put this in `result` as `21s`. */
|
|
48
|
+
readonly durationMs: number | null;
|
|
49
|
+
readonly detail: LedgerDetail;
|
|
50
|
+
/** §04: a question, a finding, a structured document — and any failure whose
|
|
51
|
+
* diagnostic is longer than the one phrase the result slot can hold. */
|
|
52
|
+
readonly openByDefault: boolean;
|
|
53
|
+
readonly folded: boolean;
|
|
54
|
+
/** Members in the fold; 1 for a plain line. */
|
|
55
|
+
readonly foldCount: number;
|
|
56
|
+
/** The fold gave up naming its members; draw `→` before `at`. */
|
|
57
|
+
readonly elided: boolean;
|
|
58
|
+
/** Proven child sessions this line owns — the component resolves each to a
|
|
59
|
+
* subthread drawn under the line (§03 F). */
|
|
60
|
+
readonly childSessionIds: readonly string[];
|
|
61
|
+
/** The bounded failure text, when there is one. Never the tool's output. */
|
|
62
|
+
readonly diagnostic: string | null;
|
|
63
|
+
}
|
|
64
|
+
/** Every proven child session a row owns — the same fact `Transcript.tsx`
|
|
65
|
+
* already places subthreads by, exported so the component keeps one source. */
|
|
66
|
+
export declare function linkedChildSessionIds(row: TimelineEntry): readonly string[];
|
|
67
|
+
/**
|
|
68
|
+
* One `tool_use` row as one ledger line: the §04 sentence, wrapped in the
|
|
69
|
+
* evidence the row actually carries. Throws if the row is not a tool use —
|
|
70
|
+
* `documentTurns` never hands it anything else.
|
|
71
|
+
*/
|
|
72
|
+
export declare function ledgerLine(row: TimelineEntry, context?: LedgerContext): LedgerLine;
|
|
73
|
+
/**
|
|
74
|
+
* A command's name for a fold's list: the program, plus the first argument
|
|
75
|
+
* that is not a flag or a flag's value, each reduced to its own last segment.
|
|
76
|
+
* `pnpm -F field-app test` → `pnpm test`; `cargo clippy --all-targets --
|
|
77
|
+
* -D warnings` → `cargo clippy`; `node scripts/probe-silhouette.mjs --bays 1`
|
|
78
|
+
* → `node probe-silhouette`; `ls` → `ls`. Those are the record's own four
|
|
79
|
+
* drawings, and they are what this reproduces.
|
|
80
|
+
*
|
|
81
|
+
* Flag ARITY is unknowable from the text, so a single-dash flag is assumed to
|
|
82
|
+
* take a value (which is what `-F field-app` needs). When that assumption lands
|
|
83
|
+
* on a token that names nothing — `grep -r x .` reaches `.` — the program
|
|
84
|
+
* stands alone rather than the fold reading `grep .`.
|
|
85
|
+
*/
|
|
86
|
+
export declare function commandName(command: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* A contiguous run of `tool_use` rows as the lines the ledger draws. Folding
|
|
89
|
+
* happens here and only here — see the rules at the top of this module.
|
|
90
|
+
*/
|
|
91
|
+
export declare function ledgerLines(rows: readonly TimelineEntry[], context?: LedgerContext): LedgerLine[];
|
|
92
|
+
/**
|
|
93
|
+
* One noun of the head's sentence. `names` is non-empty only for `file_change`
|
|
94
|
+
* — the changed files, up to FOLD_NAME_LIMIT, the fold line's own device — and
|
|
95
|
+
* `more` counts the ones past the limit. Two files that share a name keep
|
|
96
|
+
* their directory (`a/index.ts, b/index.ts`), so two edits never read as one.
|
|
97
|
+
* A run with no tool lines says the one thing it holds: `2 thoughts`.
|
|
98
|
+
*/
|
|
99
|
+
export interface RunNoun {
|
|
100
|
+
readonly family: ToolFamily | "thinking";
|
|
101
|
+
readonly text: string;
|
|
102
|
+
readonly names: readonly string[];
|
|
103
|
+
readonly more: number;
|
|
104
|
+
}
|
|
105
|
+
/** A member of the run that is not a tool line, as the sentence needs it. */
|
|
106
|
+
export type RunOther = {
|
|
107
|
+
readonly kind: "thinking";
|
|
108
|
+
readonly row: TimelineEntry;
|
|
109
|
+
} | {
|
|
110
|
+
readonly kind: "marker";
|
|
111
|
+
readonly row: TimelineEntry;
|
|
112
|
+
readonly failed: boolean;
|
|
113
|
+
} | {
|
|
114
|
+
readonly kind: "summary";
|
|
115
|
+
readonly row: TimelineEntry;
|
|
116
|
+
};
|
|
117
|
+
export interface RunSummary {
|
|
118
|
+
/** Acts first, then looks, each class by count — `3 edits`, `17 commands`,
|
|
119
|
+
* `4 reads` — counted over ROWS so a fold does not shrink the figure. */
|
|
120
|
+
readonly nouns: readonly RunNoun[];
|
|
121
|
+
/** Lines that did not complete: failed, denied, timed out. Drawn in red at
|
|
122
|
+
* the right beside the span, where a narrow column cannot hide it. */
|
|
123
|
+
readonly failed: number;
|
|
124
|
+
/** Notices inside the run that state a failure: a runtime error, a failed
|
|
125
|
+
* async task. Drawn beside `failed`, in the same red. */
|
|
126
|
+
readonly errors: number;
|
|
127
|
+
/** The whole run's span, from its first known stamp to its last. Raw
|
|
128
|
+
* milliseconds: the record draws a span only once it is at least a second,
|
|
129
|
+
* which is a presentation threshold and stays with the component. */
|
|
130
|
+
readonly spanMs: number | null;
|
|
131
|
+
/** Tool lines the ladder draws. */
|
|
132
|
+
readonly lineCount: number;
|
|
133
|
+
readonly rowCount: number;
|
|
134
|
+
/** Lines plus thoughts, markers and summaries — what decides the fold. */
|
|
135
|
+
readonly memberCount: number;
|
|
136
|
+
/** Reasoning is silent in the sentence unless it is all the run has. */
|
|
137
|
+
readonly thoughtCount: number;
|
|
138
|
+
/** The last line still running — a live head carries it (Q11 A). */
|
|
139
|
+
readonly running: LedgerLine | null;
|
|
140
|
+
/** The run opens closed. The component may still force it open for focus. */
|
|
141
|
+
readonly closedByDefault: boolean;
|
|
142
|
+
}
|
|
143
|
+
export declare function runSummary(lines: readonly LedgerLine[], others?: readonly RunOther[]): RunSummary;
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { projectAction } from "./families.js";
|
|
2
|
+
import { FAMILY_CLASS, FOLD_NOUN, basename, canonicalText, familyNoun, firstLine, part, resourceLabel, rowStamps, spanText, stampSpan, urlHost, } from "./vocabulary.js";
|
|
3
|
+
/** Even a single activity line closes to its head (2026-09-09 amendment). */
|
|
4
|
+
export const RUN_FOLD_THRESHOLD = 1;
|
|
5
|
+
/** How many members a fold names before it degrades to `… N more`. */
|
|
6
|
+
export const FOLD_NAME_LIMIT = 4;
|
|
7
|
+
/* ── one row ─────────────────────────────────────────────────────────────── */
|
|
8
|
+
function toolOf(row) {
|
|
9
|
+
if (row.body.type !== "tool_use") {
|
|
10
|
+
throw new Error(`timeline entry ${row.timeline_id} is not a tool use`);
|
|
11
|
+
}
|
|
12
|
+
return row.body.tool;
|
|
13
|
+
}
|
|
14
|
+
function stateOf(status, basis) {
|
|
15
|
+
switch (status) {
|
|
16
|
+
case "failed":
|
|
17
|
+
case "denied":
|
|
18
|
+
case "timed_out":
|
|
19
|
+
return "failed";
|
|
20
|
+
case "cancelled":
|
|
21
|
+
case "interrupted":
|
|
22
|
+
return "muted";
|
|
23
|
+
case "unknown":
|
|
24
|
+
// A terminal record proves that the call finished even when its native
|
|
25
|
+
// format omitted success/failure. Treat that as neutral completion; it
|
|
26
|
+
// must not look live, failed, or like a warning.
|
|
27
|
+
return basis === "native_terminal_record" ? "done" : "muted";
|
|
28
|
+
case "pending":
|
|
29
|
+
case "running":
|
|
30
|
+
return "running";
|
|
31
|
+
case "succeeded":
|
|
32
|
+
return "done";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** `timed out` · `status unknown`. Proven completion says nothing at all. */
|
|
36
|
+
function statusWord(status, basis) {
|
|
37
|
+
if (status === "succeeded")
|
|
38
|
+
return null;
|
|
39
|
+
if (status === "unknown") {
|
|
40
|
+
return basis === "native_terminal_record" ? null : "status unknown";
|
|
41
|
+
}
|
|
42
|
+
return status.replaceAll("_", " ");
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The failure's own words, which always beat the family's outcome — Grok
|
|
46
|
+
* reporting `found 0 matches` as a failure is drawn in red with the source's
|
|
47
|
+
* sentence, not with the vocabulary's cheerful `found nothing`.
|
|
48
|
+
*/
|
|
49
|
+
function failureResult(tool, action) {
|
|
50
|
+
const text = tool.failure?.summary ?? tool.failure?.diagnostic ?? null;
|
|
51
|
+
const line = text === null ? null : firstLine(text, 60);
|
|
52
|
+
const timedOut = tool.status.value === "timed_out" || tool.failure?.kind === "timeout";
|
|
53
|
+
if ((action.type === "web_fetch" || action.type === "web_navigate") && !timedOut) {
|
|
54
|
+
const status = action.outcome?.http_status;
|
|
55
|
+
if (status != null && status >= 400)
|
|
56
|
+
return `HTTP ${status}`;
|
|
57
|
+
}
|
|
58
|
+
if (action.type === "shell" || action.type === "code_execute") {
|
|
59
|
+
if (timedOut) {
|
|
60
|
+
// The BUDGET, in the seconds the caller set it in — `timed out · 120s`
|
|
61
|
+
// (§04). It is a limit that was hit, not a span that was measured.
|
|
62
|
+
const budget = action.type === "shell" ? action.timeout_ms : null;
|
|
63
|
+
return budget === null ? "timed out" : `timed out · ${Math.round(budget / 1000)}s`;
|
|
64
|
+
}
|
|
65
|
+
const exit = action.outcome?.exit_code ?? null;
|
|
66
|
+
const code = exit === null || exit === 0 ? null : `exit ${exit}`;
|
|
67
|
+
if (code === null)
|
|
68
|
+
return line;
|
|
69
|
+
return line === null ? code : `${code} · ${line}`;
|
|
70
|
+
}
|
|
71
|
+
if (timedOut && line === null)
|
|
72
|
+
return "timed out";
|
|
73
|
+
return line;
|
|
74
|
+
}
|
|
75
|
+
function childSessionIdsOf(action) {
|
|
76
|
+
switch (action.type) {
|
|
77
|
+
case "delegate":
|
|
78
|
+
return action.child_session_id === null ? [] : [action.child_session_id];
|
|
79
|
+
case "collaborate":
|
|
80
|
+
return action.linked_session_id === null ? [] : [action.linked_session_id];
|
|
81
|
+
case "workflow":
|
|
82
|
+
return action.run == null
|
|
83
|
+
? []
|
|
84
|
+
: [...new Set(action.run.workers.flatMap((worker) => worker.child_session_id === null ? [] : [worker.child_session_id]))];
|
|
85
|
+
default:
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function workflowState(action, fallback) {
|
|
90
|
+
if (action.type !== "workflow" || action.run == null)
|
|
91
|
+
return fallback;
|
|
92
|
+
switch (action.run.status) {
|
|
93
|
+
case "completed":
|
|
94
|
+
return "done";
|
|
95
|
+
case "running":
|
|
96
|
+
return "running";
|
|
97
|
+
case "failed":
|
|
98
|
+
return "failed";
|
|
99
|
+
case "killed":
|
|
100
|
+
case "cancelled":
|
|
101
|
+
case "stopped":
|
|
102
|
+
case "unknown":
|
|
103
|
+
return "muted";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Every proven child session a row owns — the same fact `Transcript.tsx`
|
|
107
|
+
* already places subthreads by, exported so the component keeps one source. */
|
|
108
|
+
export function linkedChildSessionIds(row) {
|
|
109
|
+
return row.body.type === "tool_use" ? childSessionIdsOf(row.body.tool.action) : [];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* One `tool_use` row as one ledger line: the §04 sentence, wrapped in the
|
|
113
|
+
* evidence the row actually carries. Throws if the row is not a tool use —
|
|
114
|
+
* `documentTurns` never hands it anything else.
|
|
115
|
+
*/
|
|
116
|
+
export function ledgerLine(row, context = {}) {
|
|
117
|
+
const tool = toolOf(row);
|
|
118
|
+
const action = tool.action;
|
|
119
|
+
const projection = projectAction(action, tool.native, context, {
|
|
120
|
+
sessionId: row.session_id,
|
|
121
|
+
timelineId: row.timeline_id,
|
|
122
|
+
});
|
|
123
|
+
const status = tool.status.value;
|
|
124
|
+
const statusBasis = tool.status.basis;
|
|
125
|
+
// The unknown family is never plain: the row is honest about knowing nothing,
|
|
126
|
+
// and the muted state is what italicises `no detail recorded`.
|
|
127
|
+
const rawState = workflowState(action, stateOf(status, statusBasis));
|
|
128
|
+
const state = action.type === "unknown" && rawState === "done" ? "muted" : rawState;
|
|
129
|
+
const object = [...projection.object];
|
|
130
|
+
if (action.type === "unknown") {
|
|
131
|
+
const word = statusWord(status, statusBasis);
|
|
132
|
+
if (word !== null)
|
|
133
|
+
object.push(part(` · ${word}`));
|
|
134
|
+
}
|
|
135
|
+
const diagnostic = tool.failure?.diagnostic ?? tool.failure?.summary ?? null;
|
|
136
|
+
const rawFailure = failureResult(tool, action);
|
|
137
|
+
const failure = action.type === "workflow" && action.run_id == null && rawState === "failed"
|
|
138
|
+
? rawFailure === null
|
|
139
|
+
? "did not start"
|
|
140
|
+
: `did not start · ${rawFailure}`
|
|
141
|
+
: rawFailure;
|
|
142
|
+
const timing = tool.timing;
|
|
143
|
+
const startedAt = timing?.started_at ?? null;
|
|
144
|
+
const endedAt = timing?.completed_at ?? null;
|
|
145
|
+
const durationMs = timing?.duration_ms ??
|
|
146
|
+
(startedAt !== null && endedAt !== null && endedAt > startedAt ? endedAt - startedAt : null);
|
|
147
|
+
let result;
|
|
148
|
+
let resultTone;
|
|
149
|
+
if (state === "running") {
|
|
150
|
+
// The component appends the elapsed: `running · 12s`.
|
|
151
|
+
result = "running";
|
|
152
|
+
resultTone = "running";
|
|
153
|
+
}
|
|
154
|
+
else if (failure !== null) {
|
|
155
|
+
result = failure;
|
|
156
|
+
resultTone = state === "failed" ? "failed" : state === "muted" ? "muted" : "plain";
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
result = projection.result ?? statusWord(status, statusBasis);
|
|
160
|
+
resultTone =
|
|
161
|
+
state === "failed"
|
|
162
|
+
? "failed"
|
|
163
|
+
: state === "muted" || projection.resultMuted
|
|
164
|
+
? "muted"
|
|
165
|
+
: "plain";
|
|
166
|
+
}
|
|
167
|
+
if (result === null && durationMs !== null && durationMs >= 1000) {
|
|
168
|
+
result = spanText(durationMs);
|
|
169
|
+
resultTone = "plain";
|
|
170
|
+
}
|
|
171
|
+
const detail = projection.detail.kind === "none" && diagnostic !== null
|
|
172
|
+
? { kind: "diagnostic", diagnostic }
|
|
173
|
+
: projection.detail;
|
|
174
|
+
return {
|
|
175
|
+
key: row.timeline_id,
|
|
176
|
+
rows: [row],
|
|
177
|
+
family: action.type,
|
|
178
|
+
cls: FAMILY_CLASS[action.type],
|
|
179
|
+
glyph: projection.glyph,
|
|
180
|
+
verb: projection.verb,
|
|
181
|
+
object,
|
|
182
|
+
result,
|
|
183
|
+
resultTone,
|
|
184
|
+
state,
|
|
185
|
+
at: endedAt ?? row.at,
|
|
186
|
+
startedAt: startedAt ?? row.at,
|
|
187
|
+
endedAt,
|
|
188
|
+
durationMs,
|
|
189
|
+
detail,
|
|
190
|
+
openByDefault: projection.openByDefault ||
|
|
191
|
+
(state === "failed" && diagnostic !== null && diagnostic.includes("\n")),
|
|
192
|
+
folded: false,
|
|
193
|
+
foldCount: 1,
|
|
194
|
+
elided: false,
|
|
195
|
+
childSessionIds: childSessionIdsOf(action),
|
|
196
|
+
diagnostic,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/* ── the fold ────────────────────────────────────────────────────────────── */
|
|
200
|
+
const SCRIPT_EXTENSIONS = /\.(mjs|cjs|js|ts|tsx|sh|bash|zsh|py|rb|pl|lua)$/i;
|
|
201
|
+
/** `.`, `..`, `*` and their kin name nothing; a fold is better off silent. */
|
|
202
|
+
const EMPTY_NAMES = new Set(["", ".", "..", "*", "~", "-"]);
|
|
203
|
+
function tokenLabel(token) {
|
|
204
|
+
const bare = token.replace(/^["']|["']$/g, "");
|
|
205
|
+
const name = bare.split("/").filter(Boolean).at(-1) ?? bare;
|
|
206
|
+
const trimmed = name.replace(SCRIPT_EXTENSIONS, "");
|
|
207
|
+
return trimmed.length > 24 ? `${trimmed.slice(0, 23)}…` : trimmed;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* A command's name for a fold's list: the program, plus the first argument
|
|
211
|
+
* that is not a flag or a flag's value, each reduced to its own last segment.
|
|
212
|
+
* `pnpm -F field-app test` → `pnpm test`; `cargo clippy --all-targets --
|
|
213
|
+
* -D warnings` → `cargo clippy`; `node scripts/probe-silhouette.mjs --bays 1`
|
|
214
|
+
* → `node probe-silhouette`; `ls` → `ls`. Those are the record's own four
|
|
215
|
+
* drawings, and they are what this reproduces.
|
|
216
|
+
*
|
|
217
|
+
* Flag ARITY is unknowable from the text, so a single-dash flag is assumed to
|
|
218
|
+
* take a value (which is what `-F field-app` needs). When that assumption lands
|
|
219
|
+
* on a token that names nothing — `grep -r x .` reaches `.` — the program
|
|
220
|
+
* stands alone rather than the fold reading `grep .`.
|
|
221
|
+
*/
|
|
222
|
+
export function commandName(command) {
|
|
223
|
+
const tokens = firstLine(command, 400).split(/\s+/).filter(Boolean);
|
|
224
|
+
if (tokens.length === 0)
|
|
225
|
+
return "";
|
|
226
|
+
const program = tokenLabel(tokens[0]);
|
|
227
|
+
let argument = null;
|
|
228
|
+
let index = 1;
|
|
229
|
+
while (index < tokens.length) {
|
|
230
|
+
const token = tokens[index];
|
|
231
|
+
if (token === "--" || token.startsWith("--")) {
|
|
232
|
+
index += 1;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (token.startsWith("-") && token.length > 1) {
|
|
236
|
+
index += 2;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const label = tokenLabel(token);
|
|
240
|
+
if (EMPTY_NAMES.has(label)) {
|
|
241
|
+
index += 1;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
argument = label;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
return argument === null ? program : `${program} ${argument}`;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* What one folded member is called in the fold's name list: a file by its own
|
|
251
|
+
* name, a search by its query, a page by its host, a command by `commandName`.
|
|
252
|
+
* Only LOOK families ever fold, so every other family answers null.
|
|
253
|
+
*/
|
|
254
|
+
function memberName(action) {
|
|
255
|
+
switch (action.type) {
|
|
256
|
+
case "shell":
|
|
257
|
+
return commandName(canonicalText(action.command));
|
|
258
|
+
case "file_read": {
|
|
259
|
+
const target = action.targets[0];
|
|
260
|
+
return target === undefined ? null : basename(resourceLabel(target.resource));
|
|
261
|
+
}
|
|
262
|
+
case "file_list":
|
|
263
|
+
return basename(resourceLabel(action.directory));
|
|
264
|
+
case "file_search":
|
|
265
|
+
case "code_lookup":
|
|
266
|
+
case "tool_discovery":
|
|
267
|
+
return action.query;
|
|
268
|
+
case "web_search":
|
|
269
|
+
return action.query;
|
|
270
|
+
case "web_fetch":
|
|
271
|
+
return urlHost(resourceLabel(action.url));
|
|
272
|
+
case "web_navigate":
|
|
273
|
+
return action.url === null ? action.pattern : urlHost(resourceLabel(action.url));
|
|
274
|
+
default:
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function actionOf(row) {
|
|
279
|
+
return row.body.type === "tool_use" ? row.body.tool.action : null;
|
|
280
|
+
}
|
|
281
|
+
/** The fold's aggregate outcome — one drawing exists (`3 files · 1 truncated`)
|
|
282
|
+
* and the rest follow it: a fold states the same figure its members do, summed. */
|
|
283
|
+
function foldResult(family, rows) {
|
|
284
|
+
const actions = rows.map(actionOf).filter((action) => action !== null);
|
|
285
|
+
switch (family) {
|
|
286
|
+
case "file_read": {
|
|
287
|
+
const truncated = actions.filter((action) => action.type === "file_read" && action.outcome?.truncated === true).length;
|
|
288
|
+
return truncated === 0 ? null : `${truncated} truncated`;
|
|
289
|
+
}
|
|
290
|
+
case "file_list": {
|
|
291
|
+
const entries = sum(actions.map((action) => (action.type === "file_list" ? action.outcome?.entry_count : null)));
|
|
292
|
+
return entries === null ? null : `${entries} ${entries === 1 ? "entry" : "entries"}`;
|
|
293
|
+
}
|
|
294
|
+
case "file_search": {
|
|
295
|
+
const matches = sum(actions.map((action) => action.type === "file_search" ? action.outcome?.match_count : null));
|
|
296
|
+
const files = sum(actions.map((action) => (action.type === "file_search" ? action.outcome?.file_count : null)));
|
|
297
|
+
if (matches === null)
|
|
298
|
+
return null;
|
|
299
|
+
if (matches === 0)
|
|
300
|
+
return "found nothing";
|
|
301
|
+
const pieces = [`${matches} ${matches === 1 ? "match" : "matches"}`];
|
|
302
|
+
if (files !== null && files > 0)
|
|
303
|
+
pieces.push(`${files} ${files === 1 ? "file" : "files"}`);
|
|
304
|
+
return pieces.join(" · ");
|
|
305
|
+
}
|
|
306
|
+
case "code_lookup": {
|
|
307
|
+
const total = sum(actions.map((action) => action.type === "code_lookup" ? action.outcome?.total_count : null));
|
|
308
|
+
return total === null ? null : `${total} ${total === 1 ? "location" : "locations"}`;
|
|
309
|
+
}
|
|
310
|
+
case "web_search": {
|
|
311
|
+
const counts = actions.map((action) => action.type === "web_search" ? action.outcome?.total_count : null);
|
|
312
|
+
const total = counts.some((count) => count == null) ? null : sum(counts);
|
|
313
|
+
return total === null ? null : `${total} ${total === 1 ? "source" : "sources"}`;
|
|
314
|
+
}
|
|
315
|
+
default:
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function sum(values) {
|
|
320
|
+
const known = values.filter((value) => typeof value === "number");
|
|
321
|
+
return known.length === 0 ? null : known.reduce((total, value) => total + value, 0);
|
|
322
|
+
}
|
|
323
|
+
/** A fold's detail is its members' details, concatenated in order. */
|
|
324
|
+
function foldDetail(family, lines) {
|
|
325
|
+
if (family === "shell") {
|
|
326
|
+
const commands = lines.flatMap((line) => line.detail.kind === "command" ? [...line.detail.commands] : []);
|
|
327
|
+
return commands.length === 0 ? { kind: "none" } : { kind: "command", commands };
|
|
328
|
+
}
|
|
329
|
+
const paths = lines.flatMap((line) => line.detail.kind === "paths" ? [...line.detail.paths] : []);
|
|
330
|
+
if (paths.length > 0)
|
|
331
|
+
return { kind: "paths", paths, total: paths.length };
|
|
332
|
+
if (family === "web_search") {
|
|
333
|
+
const details = lines.flatMap((line) => line.detail.kind === "sources" ? [line.detail] : []);
|
|
334
|
+
return {
|
|
335
|
+
kind: "sources",
|
|
336
|
+
sources: details.flatMap((detail) => [...detail.sources]),
|
|
337
|
+
total: details.some((detail) => detail.total === null)
|
|
338
|
+
? null
|
|
339
|
+
: sum(details.map((detail) => detail.total)),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const fetches = lines.flatMap((line) => line.detail.kind === "fetch" ? [line.detail.fetch] : []);
|
|
343
|
+
if (fetches.length > 0)
|
|
344
|
+
return { kind: "fetches", fetches };
|
|
345
|
+
const locations = lines.flatMap((line) => line.detail.kind === "locations" ? [...line.detail.locations] : []);
|
|
346
|
+
if (locations.length > 0)
|
|
347
|
+
return { kind: "locations", locations, total: locations.length };
|
|
348
|
+
return { kind: "none" };
|
|
349
|
+
}
|
|
350
|
+
function foldable(line) {
|
|
351
|
+
return line.cls === "look" && line.state === "done";
|
|
352
|
+
}
|
|
353
|
+
function fold(lines) {
|
|
354
|
+
const family = lines[0].family;
|
|
355
|
+
const rows = lines.flatMap((line) => [...line.rows]);
|
|
356
|
+
const names = [];
|
|
357
|
+
for (const row of rows) {
|
|
358
|
+
const action = actionOf(row);
|
|
359
|
+
const members = action?.type === "file_read"
|
|
360
|
+
? action.targets.map((target) => basename(resourceLabel(target.resource)))
|
|
361
|
+
: [action === null ? null : memberName(action)];
|
|
362
|
+
for (const name of members) {
|
|
363
|
+
if (name !== null && name !== "" && !names.includes(name))
|
|
364
|
+
names.push(name);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// A read line is the file names in both its single and folded forms. The
|
|
368
|
+
// object column already ellipsizes visually, so removing names from the
|
|
369
|
+
// model would make the closed line less useful without saving any space.
|
|
370
|
+
const elided = family !== "file_read" && names.length > FOLD_NAME_LIMIT;
|
|
371
|
+
const [one, many] = FOLD_NOUN[family];
|
|
372
|
+
const noun = rows.length === 1 ? one : many;
|
|
373
|
+
const object = family === "file_read" && names.length > 0
|
|
374
|
+
? [part(names.join(", "))]
|
|
375
|
+
: elided
|
|
376
|
+
? [part(`… ${rows.length} more ${many}`)]
|
|
377
|
+
: [
|
|
378
|
+
part(`${rows.length} ${noun}`),
|
|
379
|
+
...(names.length === 0 ? [] : [part(` · ${names.join(", ")}`, "aside")]),
|
|
380
|
+
];
|
|
381
|
+
const stamps = rows.flatMap(rowStamps);
|
|
382
|
+
const first = stamps.length === 0 ? null : Math.min(...stamps);
|
|
383
|
+
const last = stamps.length === 0 ? null : Math.max(...stamps);
|
|
384
|
+
const durationMs = stampSpan(rows);
|
|
385
|
+
let result = foldResult(family, rows);
|
|
386
|
+
// The elided fold states its span as `→ <end>` in the time slot instead.
|
|
387
|
+
if (result === null && !elided && durationMs !== null && durationMs >= 1000) {
|
|
388
|
+
result = spanText(durationMs);
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
key: lines[0].key,
|
|
392
|
+
rows,
|
|
393
|
+
family,
|
|
394
|
+
cls: lines[0].cls,
|
|
395
|
+
glyph: lines[0].glyph,
|
|
396
|
+
verb: lines[0].verb,
|
|
397
|
+
object,
|
|
398
|
+
result,
|
|
399
|
+
resultTone: "plain",
|
|
400
|
+
state: "done",
|
|
401
|
+
at: elided ? last : first,
|
|
402
|
+
startedAt: first,
|
|
403
|
+
endedAt: last,
|
|
404
|
+
durationMs,
|
|
405
|
+
detail: foldDetail(family, lines),
|
|
406
|
+
openByDefault: false,
|
|
407
|
+
folded: true,
|
|
408
|
+
foldCount: rows.length,
|
|
409
|
+
elided,
|
|
410
|
+
childSessionIds: [],
|
|
411
|
+
diagnostic: null,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A contiguous run of `tool_use` rows as the lines the ledger draws. Folding
|
|
416
|
+
* happens here and only here — see the rules at the top of this module.
|
|
417
|
+
*/
|
|
418
|
+
export function ledgerLines(rows, context = {}) {
|
|
419
|
+
const singles = rows.map((row) => ledgerLine(row, context));
|
|
420
|
+
const out = [];
|
|
421
|
+
let run = [];
|
|
422
|
+
const flush = () => {
|
|
423
|
+
if (run.length === 0)
|
|
424
|
+
return;
|
|
425
|
+
out.push(run.length === 1 ? run[0] : fold(run));
|
|
426
|
+
run = [];
|
|
427
|
+
};
|
|
428
|
+
for (const line of singles) {
|
|
429
|
+
if (!foldable(line)) {
|
|
430
|
+
flush();
|
|
431
|
+
out.push(line);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (run.length > 0 && run[0].family !== line.family)
|
|
435
|
+
flush();
|
|
436
|
+
run.push(line);
|
|
437
|
+
}
|
|
438
|
+
flush();
|
|
439
|
+
return out;
|
|
440
|
+
}
|
|
441
|
+
/** The changed files by name. Distinct paths stay distinct: a name shared by
|
|
442
|
+
* two of them carries its parent directory. */
|
|
443
|
+
function fileNames(paths) {
|
|
444
|
+
return paths.map((path, index) => {
|
|
445
|
+
const name = basename(path);
|
|
446
|
+
const twin = paths.some((other, at) => at !== index && basename(other) === name);
|
|
447
|
+
if (!twin)
|
|
448
|
+
return name;
|
|
449
|
+
const parts = path.split("/").filter(Boolean);
|
|
450
|
+
return parts.length >= 2 ? `${parts[parts.length - 2]}/${name}` : name;
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
export function runSummary(lines, others = []) {
|
|
454
|
+
const rows = lines.flatMap((line) => [...line.rows]);
|
|
455
|
+
const order = [];
|
|
456
|
+
const counts = new Map();
|
|
457
|
+
const paths = [];
|
|
458
|
+
for (const row of rows) {
|
|
459
|
+
const action = actionOf(row);
|
|
460
|
+
if (action === null)
|
|
461
|
+
continue;
|
|
462
|
+
if (!counts.has(action.type))
|
|
463
|
+
order.push(action.type);
|
|
464
|
+
counts.set(action.type, (counts.get(action.type) ?? 0) + 1);
|
|
465
|
+
if (action.type === "file_change") {
|
|
466
|
+
for (const change of action.changes) {
|
|
467
|
+
const path = resourceLabel(change.path);
|
|
468
|
+
if (path !== "" && !paths.includes(path))
|
|
469
|
+
paths.push(path);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const names = fileNames(paths);
|
|
474
|
+
// Acts lead: the work product is what a reader wants first, and what
|
|
475
|
+
// survives when a narrow column ellipsizes the tail. Within a class the
|
|
476
|
+
// larger count comes first; ties keep first occurrence.
|
|
477
|
+
const byClass = (cls) => order
|
|
478
|
+
.filter((family) => FAMILY_CLASS[family] === cls)
|
|
479
|
+
.sort((a, b) => (counts.get(b) ?? 0) - (counts.get(a) ?? 0) || order.indexOf(a) - order.indexOf(b));
|
|
480
|
+
const nouns = [...byClass("act"), ...byClass("look")].map((family) => ({
|
|
481
|
+
family,
|
|
482
|
+
text: familyNoun(family, counts.get(family) ?? 0),
|
|
483
|
+
names: family === "file_change" ? names.slice(0, FOLD_NAME_LIMIT) : [],
|
|
484
|
+
more: family === "file_change" ? Math.max(0, names.length - FOLD_NAME_LIMIT) : 0,
|
|
485
|
+
}));
|
|
486
|
+
const thoughtCount = others.filter((other) => other.kind === "thinking").length;
|
|
487
|
+
if (nouns.length === 0 && thoughtCount > 0) {
|
|
488
|
+
nouns.push({
|
|
489
|
+
family: "thinking",
|
|
490
|
+
text: `${thoughtCount} ${thoughtCount === 1 ? "thought" : "thoughts"}`,
|
|
491
|
+
names: [],
|
|
492
|
+
more: 0,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
const allRows = [...rows, ...others.map((other) => other.row)];
|
|
496
|
+
const memberCount = lines.length + others.length;
|
|
497
|
+
return {
|
|
498
|
+
nouns,
|
|
499
|
+
failed: lines.filter((line) => line.state === "failed").length,
|
|
500
|
+
errors: others.filter((other) => other.kind === "marker" && other.failed).length,
|
|
501
|
+
spanMs: stampSpan(allRows),
|
|
502
|
+
lineCount: lines.length,
|
|
503
|
+
rowCount: allRows.length,
|
|
504
|
+
memberCount,
|
|
505
|
+
thoughtCount,
|
|
506
|
+
running: [...lines].reverse().find((line) => line.state === "running") ?? null,
|
|
507
|
+
// Notices and summaries alone have no sentence to close to (R-2).
|
|
508
|
+
// Questions addressed to the reader are speech and stay visible (R-1).
|
|
509
|
+
closedByDefault: memberCount >= RUN_FOLD_THRESHOLD &&
|
|
510
|
+
(lines.length > 0 || thoughtCount > 0) &&
|
|
511
|
+
!lines.some((line) => line.family === "question"),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ToolAction, ToolInteraction } from "@vibefield/rosetta-protocol";
|
|
2
|
+
type Family<K extends ToolAction["type"]> = Extract<ToolAction, {
|
|
3
|
+
type: K;
|
|
4
|
+
}>;
|
|
5
|
+
export type NativeToolRef = ToolInteraction["native"];
|
|
6
|
+
export type ToolFailure = NonNullable<ToolInteraction["failure"]>;
|
|
7
|
+
export type ToolTiming = NonNullable<ToolInteraction["timing"]>;
|
|
8
|
+
export type FileDelta = Family<"file_change">["changes"][number];
|
|
9
|
+
export type FindingItem = Family<"finding">["findings"][number];
|
|
10
|
+
export type DisplayField = Family<"external">["fields"][number];
|
|
11
|
+
export type DisplayValue = DisplayField["value"];
|
|
12
|
+
export type DisplayScalar = Extract<DisplayValue, {
|
|
13
|
+
type: "list";
|
|
14
|
+
}>["value"][number];
|
|
15
|
+
export type UserQuestion = Family<"question">["questions"][number];
|
|
16
|
+
export type UserAnswer = Family<"question">["answers"][number];
|
|
17
|
+
export type CollaboratorRef = NonNullable<Family<"collaborate">["outcome"]>["participants"][number];
|
|
18
|
+
export type SourceLocation = NonNullable<Family<"code_lookup">["outcome"]>["locations"][number];
|
|
19
|
+
export type SourceRange = NonNullable<Family<"file_read">["targets"][number]["range"]>;
|
|
20
|
+
export type CanonicalDocument = Family<"structured_output">["document"];
|
|
21
|
+
export type WebSource = NonNullable<Family<"web_search">["outcome"]>["sources"][number];
|
|
22
|
+
export type FindingSeverity = FindingItem["severity"];
|
|
23
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|