@digithings-ai/ui 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 +48 -2
- package/package.json +143 -4
- package/src/components/NavShell.tsx +776 -0
- package/src/components/SocialRow.tsx +87 -0
- package/src/components/Spinner.tsx +27 -0
- package/src/components/StackLogo.tsx +40 -0
- package/src/components/Terminal.tsx +110 -0
- package/src/components/TerminalManifest.tsx +212 -0
- package/src/components/ThemeProvider.tsx +271 -0
- package/src/components/account/AuthCard.tsx +309 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
- package/src/components/brand/BrandWordmark.tsx +32 -0
- package/src/components/changelog/ReleaseRail.tsx +81 -0
- package/src/components/changelog/index.ts +1 -0
- package/src/components/chat/ChatCodeBlock.tsx +67 -0
- package/src/components/chat/ChatMarkdown.tsx +66 -0
- package/src/components/chat/ChatMarkdownSource.tsx +203 -0
- package/src/components/chat/ChatMermaidBlock.tsx +202 -0
- package/src/components/chat/ChatMessage.tsx +77 -0
- package/src/components/chat/ChatPlayback.tsx +422 -0
- package/src/components/chat/ChatStreamCursor.tsx +25 -0
- package/src/components/chat/ChatThinking.tsx +113 -0
- package/src/components/chat/ChatToolCall.tsx +190 -0
- package/src/components/chat/ChatTranscript.tsx +60 -0
- package/src/components/chat/ChatWidgetFrame.tsx +107 -0
- package/src/components/chat/DigichatBootLoader.tsx +683 -0
- package/src/components/chat/DigichatLauncher.tsx +361 -0
- package/src/components/chat/DigichatThread.tsx +118 -0
- package/src/components/chat/DigichatThreadList.tsx +54 -0
- package/src/components/chat/DigichatWordmark.tsx +24 -0
- package/src/components/chat/DotMatrix.tsx +650 -0
- package/src/components/chat/boot-lab.tsx +766 -0
- package/src/components/chat/boot-signal.ts +144 -0
- package/src/components/chat/chat-surfaces.ts +52 -0
- package/src/components/chat/connection-status.ts +40 -0
- package/src/components/chat/digichat-wordmark.ts +355 -0
- package/src/components/chat/disclosure-chevron.tsx +49 -0
- package/src/components/chat/followable-href.ts +9 -0
- package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
- package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
- package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
- package/src/components/chat/gallery-thread/cn.ts +1 -0
- package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
- package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
- package/src/components/chat/gallery-thread/css.d.ts +6 -0
- package/src/components/chat/gallery-thread/file.tsx +238 -0
- package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
- package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
- package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
- package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
- package/src/components/chat/gallery-thread/image.tsx +519 -0
- package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
- package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
- package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
- package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
- package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
- package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
- package/src/components/chat/gallery-thread/source.tsx +76 -0
- package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
- package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
- package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
- package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
- package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
- package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
- package/src/components/chat/gallery-thread/work-status.ts +66 -0
- package/src/components/chat/overlay-scrollbar.tsx +86 -0
- package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
- package/src/components/chat/skins/SOURCE.md +36 -0
- package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
- package/src/components/chat/skins/base/aui-default/README.md +45 -0
- package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
- package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
- package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
- package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
- package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
- package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
- package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
- package/src/components/chat/skins/base/docs-model-options.ts +6 -0
- package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
- package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
- package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
- package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
- package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
- package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
- package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
- package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
- package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
- package/src/components/chat/skins/base/markdown-text.tsx +294 -0
- package/src/components/chat/skins/base/model.ts +1 -0
- package/src/components/chat/skins/base/thread.tsx +1050 -0
- package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
- package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
- package/src/components/chat/skins/base/ui/badge.tsx +51 -0
- package/src/components/chat/skins/base/ui/button.tsx +67 -0
- package/src/components/chat/skins/base/ui/command.tsx +185 -0
- package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
- package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
- package/src/components/chat/skins/base/ui/popover.tsx +97 -0
- package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
- package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
- package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
- package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
- package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
- package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
- package/src/components/chat/skins/chatgpt.tsx +448 -0
- package/src/components/chat/skins/claude.tsx +380 -0
- package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
- package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
- package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
- package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
- package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
- package/src/components/chat/skins/digichat.tsx +144 -0
- package/src/components/chat/skins/expo-react-native.tsx +29 -0
- package/src/components/chat/skins/gemini.tsx +322 -0
- package/src/components/chat/skins/grok-icon.tsx +34 -0
- package/src/components/chat/skins/grok.tsx +369 -0
- package/src/components/chat/skins/index.ts +46 -0
- package/src/components/chat/skins/perplexity.tsx +462 -0
- package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
- package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
- package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
- package/src/components/chat/skins/react-ink.tsx +97 -0
- package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
- package/src/components/chat/skins/thread-skin-view.tsx +156 -0
- package/src/components/chat/skins/thread-skins.ts +143 -0
- package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
- package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
- package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
- package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
- package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
- package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
- package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
- package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
- package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
- package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
- package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
- package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
- package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
- package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
- package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
- package/src/components/chat/stock/SOURCE.md +90 -0
- package/src/components/chat/stock/artifacts-panel.tsx +305 -0
- package/src/components/chat/stock/attachment.aui.tsx +280 -0
- package/src/components/chat/stock/chat-notice.tsx +143 -0
- package/src/components/chat/stock/chat-private-mode.tsx +64 -0
- package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
- package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
- package/src/components/chat/stock/file.tsx +265 -0
- package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
- package/src/components/chat/stock/image.tsx +531 -0
- package/src/components/chat/stock/index.ts +129 -0
- package/src/components/chat/stock/json-view.tsx +140 -0
- package/src/components/chat/stock/markdown-text.tsx +319 -0
- package/src/components/chat/stock/message-error.aui.tsx +96 -0
- package/src/components/chat/stock/message-export-menu.tsx +156 -0
- package/src/components/chat/stock/palette-row-preview.tsx +26 -0
- package/src/components/chat/stock/reasoning.aui.tsx +120 -0
- package/src/components/chat/stock/reasoning.tsx +335 -0
- package/src/components/chat/stock/skin-chrome.tsx +81 -0
- package/src/components/chat/stock/skin-credit.tsx +63 -0
- package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
- package/src/components/chat/stock/skin-palette-context.ts +16 -0
- package/src/components/chat/stock/skin-runtime.tsx +52 -0
- package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
- package/src/components/chat/stock/skin-types.ts +217 -0
- package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
- package/src/components/chat/stock/stock-send-gate.tsx +94 -0
- package/src/components/chat/stock/stock-shape.tsx +39 -0
- package/src/components/chat/stock/thread.aui.tsx +645 -0
- package/src/components/chat/stock/tool-display.ts +6 -0
- package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
- package/src/components/chat/stock/tool-group.aui.tsx +244 -0
- package/src/components/chat/stock/tool-surface.ts +120 -0
- package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
- package/src/components/chat/stock/ui/avatar.tsx +108 -0
- package/src/components/chat/stock/ui/button.tsx +81 -0
- package/src/components/chat/stock/ui/collapsible.tsx +21 -0
- package/src/components/chat/stock/ui/dialog.tsx +163 -0
- package/src/components/chat/stock/ui/skeleton.tsx +13 -0
- package/src/components/chat/stock/ui/textarea.tsx +20 -0
- package/src/components/chat/stock/ui/tooltip.tsx +68 -0
- package/src/components/chat/stock/use-attachment-src.ts +42 -0
- package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
- package/src/components/chat/strip-model-boilerplate.ts +42 -0
- package/src/components/chat/suggestion-cycle.tsx +230 -0
- package/src/components/chat/suggestion-scroll-row.tsx +81 -0
- package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
- package/src/components/chat/trace-grouping/chain-state.ts +141 -0
- package/src/components/chat/trace-grouping/index.ts +32 -0
- package/src/components/chat/trace-grouping/tool-row.ts +74 -0
- package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
- package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
- package/src/components/chat/trace-i18n/core.ts +48 -0
- package/src/components/chat/trace-i18n/index.tsx +23 -0
- package/src/components/chat/trace-i18n/locales/en.ts +24 -0
- package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
- package/src/components/chat/trace-i18n/types.ts +35 -0
- package/src/components/chat/trace-spacing.ts +249 -0
- package/src/components/chat/transcript/activity-view.ts +375 -0
- package/src/components/chat/transcript/chat-export.ts +133 -0
- package/src/components/chat/transcript/index.ts +10 -0
- package/src/components/chat/transcript/save-file.ts +209 -0
- package/src/components/chat/transcript/transcript-markdown.ts +428 -0
- package/src/components/chat/transcript/types.ts +81 -0
- package/src/components/chat/turn-outcome.ts +52 -0
- package/src/components/chat/use-warmup-phase.ts +18 -0
- package/src/components/chat/work-status-lead.tsx +49 -0
- package/src/components/chrome.tsx +264 -0
- package/src/components/command-palette/CommandPalette.tsx +404 -0
- package/src/components/command-palette/index.ts +6 -0
- package/src/components/contact/ContactMailto.tsx +112 -0
- package/src/components/contact/index.ts +5 -0
- package/src/components/conviction/ConvictionMeter.tsx +40 -0
- package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
- package/src/components/conviction/index.ts +7 -0
- package/src/components/data-layout/BentoGrid.tsx +52 -0
- package/src/components/data-layout/CardRail.tsx +150 -0
- package/src/components/data-layout/DotMatrixStat.tsx +65 -0
- package/src/components/data-layout/FeatureCell.tsx +80 -0
- package/src/components/data-layout/MediaFrame.tsx +125 -0
- package/src/components/data-layout/ModuleGrid.tsx +735 -0
- package/src/components/data-layout/Odometer.tsx +149 -0
- package/src/components/data-layout/ProductFrame.tsx +79 -0
- package/src/components/data-layout/TestimonialWall.tsx +139 -0
- package/src/components/data-layout/index.ts +19 -0
- package/src/components/data-layout/treemap.ts +368 -0
- package/src/components/deck/DeckStack.tsx +243 -0
- package/src/components/desk/DataTable.tsx +373 -0
- package/src/components/desk/KpiGrid.tsx +80 -0
- package/src/components/desk/Sparkline.tsx +63 -0
- package/src/components/desk/StateBlock.tsx +132 -0
- package/src/components/desk/index.ts +18 -0
- package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
- package/src/components/diagrams/ArchitectureTour.tsx +912 -0
- package/src/components/diagrams/TerminalSchematic.tsx +192 -0
- package/src/components/diagrams/architecture-svg.tsx +384 -0
- package/src/components/diagrams/index.ts +30 -0
- package/src/components/diagrams/mermaid-theme.ts +115 -0
- package/src/components/diagrams/tour-camera.ts +171 -0
- package/src/components/docs/CodeTabs.tsx +90 -0
- package/src/components/docs/CopyCommand.tsx +151 -0
- package/src/components/docs/DocsLayout.tsx +197 -0
- package/src/components/docs/DocsSearch.tsx +97 -0
- package/src/components/docs/Endpoint.tsx +135 -0
- package/src/components/document/DocumentFrame.tsx +43 -0
- package/src/components/document/GlyphList.tsx +51 -0
- package/src/components/document/PageTitle.tsx +44 -0
- package/src/components/document/Prose.tsx +38 -0
- package/src/components/document/Section.tsx +55 -0
- package/src/components/document/index.ts +13 -0
- package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
- package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
- package/src/components/effects-chrome/Pipeline.tsx +226 -0
- package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
- package/src/components/effects-chrome/StackingPanels.tsx +101 -0
- package/src/components/effects-chrome/TabStrip.tsx +232 -0
- package/src/components/effects-chrome/ToastStack.tsx +201 -0
- package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
- package/src/components/effects-chrome/index.ts +35 -0
- package/src/components/emblems.tsx +188 -0
- package/src/components/faviconTheme.ts +23 -0
- package/src/components/figure/Figure.tsx +38 -0
- package/src/components/figure/index.ts +2 -0
- package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
- package/src/components/finance-charts/EquityCurve.tsx +71 -0
- package/src/components/finance-charts/PriceChart.tsx +119 -0
- package/src/components/finance-charts/chart-host.tsx +236 -0
- package/src/components/finance-charts/chart-scale.ts +93 -0
- package/src/components/finance-charts/demo-data.ts +88 -0
- package/src/components/finance-charts/index.ts +46 -0
- package/src/components/finance-charts/lw-chart.tsx +292 -0
- package/src/components/finance-composites/MarketBar.tsx +243 -0
- package/src/components/finance-composites/OrderBook.tsx +133 -0
- package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
- package/src/components/finance-composites/SortableTable.tsx +144 -0
- package/src/components/finance-composites/StockTicker.tsx +65 -0
- package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
- package/src/components/finance-composites/index.ts +28 -0
- package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
- package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
- package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
- package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
- package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
- package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
- package/src/components/finance-tearsheet/charts.tsx +2624 -0
- package/src/components/finance-tearsheet/demo-data.ts +177 -0
- package/src/components/finance-tearsheet/format.ts +41 -0
- package/src/components/finance-tearsheet/index.ts +120 -0
- package/src/components/finance-tearsheet/print.ts +52 -0
- package/src/components/finance-tearsheet/risk-bands.ts +48 -0
- package/src/components/finance-tearsheet/stats.ts +35 -0
- package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
- package/src/components/finance-tearsheet/types.ts +58 -0
- package/src/components/footer/FooterCells.tsx +109 -0
- package/src/components/footer/index.ts +6 -0
- package/src/components/graph.tsx +158 -0
- package/src/components/icons.tsx +98 -0
- package/src/components/landing/PixelWordmark.tsx +36 -0
- package/src/components/logos.ts +39 -0
- package/src/components/marquee/Marquee.tsx +204 -0
- package/src/components/metrics/PerfMetrics.tsx +68 -0
- package/src/components/metrics/StatCounter.tsx +104 -0
- package/src/components/page-geometry.tsx +177 -0
- package/src/components/pricing/Pricing.tsx +174 -0
- package/src/components/pricing/PricingMatrix.tsx +219 -0
- package/src/components/prose/index.ts +2 -0
- package/src/components/prose/prose.tsx +86 -0
- package/src/components/repo-activity/RepoActivity.tsx +599 -0
- package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
- package/src/components/repo-activity/demo.ts +201 -0
- package/src/components/repo-activity/fetch.ts +211 -0
- package/src/components/repo-activity/heatmap.ts +123 -0
- package/src/components/repo-activity/index.ts +28 -0
- package/src/components/repo-activity/types.ts +99 -0
- package/src/components/stages/NumberedStages.tsx +116 -0
- package/src/components/symbols/marks.tsx +116 -0
- package/src/components/symbols/terminal-lockup.tsx +136 -0
- package/src/components/symbols/terminal-marks.tsx +226 -0
- package/src/components/terminal/ChatResponseLoader.tsx +67 -0
- package/src/components/terminal/ContainerBootLoader.tsx +82 -0
- package/src/components/terminal/TerminalStepCaret.tsx +202 -0
- package/src/components/themeInit.ts +24 -0
- package/src/components/typography/MotionReveal.tsx +108 -0
- package/src/components/typography/TypewriterReveal.tsx +101 -0
- package/src/components/typography/WordReveal.tsx +143 -0
- package/src/data/modules.ts +378 -0
- package/src/data/subsystems.ts +101 -0
- package/src/index.ts +587 -0
- package/src/lib/base-path.ts +60 -0
- package/src/lib/cx.ts +25 -0
- package/src/lib/gloomberb.ts +69 -0
- package/src/lib/record.ts +19 -0
- package/src/lib/stub-payload.ts +183 -0
- package/src/lib/useBodyScrollLock.ts +44 -0
- package/src/lib/utils.ts +6 -0
- package/src/motion/primitives.tsx +105 -0
- package/src/motion/scroll-glide.ts +62 -0
- package/src/motion/scrolly-core.ts +38 -0
- package/src/motion/scrolly.tsx +95 -0
- package/src/navigation/HashScrollManager.tsx +167 -0
- package/src/navigation/hashScroll.ts +78 -0
- package/src/replay/browser.ts +280 -0
- package/src/replay/chat-export-run.ts +121 -0
- package/src/replay/export-format.ts +25 -0
- package/src/replay/export-mount.ts +32 -0
- package/src/replay/filename.ts +54 -0
- package/src/replay/index.ts +21 -0
- package/src/replay/redact-dom.ts +178 -0
- package/src/replay/redact.ts +113 -0
- package/src/replay/snapshot.ts +659 -0
- package/src/styles/account-auth.css +339 -0
- package/src/styles/brand-wordmark.css +11 -0
- package/src/styles/card-rail.css +120 -0
- package/src/styles/chat-aui.css +1143 -0
- package/src/styles/chat-core.css +469 -0
- package/src/styles/chat-digichat.css +2531 -0
- package/src/styles/chat-math.css +70 -0
- package/src/styles/chat-skin-palette.css +138 -0
- package/src/styles/chat-stock-menu.css +37 -0
- package/src/styles/chat-widgets.css +190 -0
- package/src/styles/command-palette.css +372 -0
- package/src/styles/controls-core.css +2261 -0
- package/src/styles/controls-overlay.css +603 -0
- package/src/styles/data-layout.css +288 -0
- package/src/styles/deck.css +141 -0
- package/src/styles/diagrams.css +1860 -0
- package/src/styles/digichat-app-theme.css +250 -0
- package/src/styles/digichat-boot-loader.css +487 -0
- package/src/styles/digichat-launcher.css +377 -0
- package/src/styles/docs.css +165 -0
- package/src/styles/effects-chrome.css +888 -0
- package/src/styles/finance-composites.css +214 -0
- package/src/styles/finance-tearsheet-overlay.css +90 -0
- package/src/styles/finance-tearsheet.css +945 -0
- package/src/styles/marquee.css +168 -0
- package/src/styles/metrics.css +82 -0
- package/src/styles/nav-shell.css +551 -0
- package/src/styles/pricing.css +79 -0
- package/src/styles/repo-activity.css +575 -0
- package/src/styles/stages.css +69 -0
- package/src/styles/terminal-loaders.css +122 -0
- package/src/styles/terminal-manifest.css +228 -0
- package/src/styles/web-theme.css +1007 -0
- package/src/styles/word-reveal.css +204 -0
- package/src/theme/apply-theme.ts +214 -0
- package/src/theme/index.ts +27 -0
- package/src/theme/palette-registry.ts +855 -0
- package/src/theme/tui-prefs.ts +64 -0
- package/src/ui/alert.tsx +78 -0
- package/src/ui/avatar.tsx +104 -0
- package/src/ui/badge.tsx +75 -0
- package/src/ui/breadcrumb.tsx +61 -0
- package/src/ui/button.tsx +67 -0
- package/src/ui/card.tsx +139 -0
- package/src/ui/checkbox.tsx +27 -0
- package/src/ui/collapsible.tsx +32 -0
- package/src/ui/date-pager.tsx +325 -0
- package/src/ui/dialog.tsx +157 -0
- package/src/ui/dropdown-menu.tsx +267 -0
- package/src/ui/empty-state.tsx +165 -0
- package/src/ui/field.tsx +104 -0
- package/src/ui/form.tsx +36 -0
- package/src/ui/icon-button.tsx +36 -0
- package/src/ui/index.ts +34 -0
- package/src/ui/input.tsx +33 -0
- package/src/ui/kbd.tsx +30 -0
- package/src/ui/label.tsx +32 -0
- package/src/ui/pager.tsx +119 -0
- package/src/ui/pagination.tsx +126 -0
- package/src/ui/radio-group.tsx +51 -0
- package/src/ui/search-bar.tsx +85 -0
- package/src/ui/segmented-control.tsx +76 -0
- package/src/ui/select.tsx +257 -0
- package/src/ui/separator.tsx +24 -0
- package/src/ui/sheet.tsx +141 -0
- package/src/ui/skeleton.tsx +76 -0
- package/src/ui/slider.tsx +76 -0
- package/src/ui/switch.tsx +31 -0
- package/src/ui/table.tsx +179 -0
- package/src/ui/tabs.tsx +89 -0
- package/src/ui/tags-input.tsx +168 -0
- package/src/ui/textarea.tsx +17 -0
- package/src/ui/tooltip.tsx +71 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import * as HeatGraph from "heat-graph";
|
|
5
|
+
|
|
6
|
+
import { bucketContributions, levelFor, type HeatDay } from "./heatmap";
|
|
7
|
+
import { grouped, type RepoPullItem } from "./types";
|
|
8
|
+
|
|
9
|
+
export type RepoHeatmapProps = {
|
|
10
|
+
pulls: RepoPullItem[];
|
|
11
|
+
/** Extra contribution sources: commit timestamps (ISO) and closed-issue timestamps (ISO). */
|
|
12
|
+
commits?: Array<string | null | undefined>;
|
|
13
|
+
closedIssues?: Array<string | null | undefined>;
|
|
14
|
+
/** Pre-bucketed daily contributions (snapshot path). Overrides pulls/commits/issues when set. */
|
|
15
|
+
data?: HeatDay[];
|
|
16
|
+
/** Weeks of history, oldest week left. Defaults to 53 (a full year, GitHub-style). */
|
|
17
|
+
weeks?: number;
|
|
18
|
+
/** Window end (UTC day). Defaults to today. Test seam only. */
|
|
19
|
+
end?: Date;
|
|
20
|
+
/**
|
|
21
|
+
* Grow the squares to fill the container instead of scrolling it. The cell
|
|
22
|
+
* size is normally a fixed 10px and `.ra-heat-body` scrolls when the history
|
|
23
|
+
* is wider than its column; with `fit` the grid takes 100% of the column and
|
|
24
|
+
* each cell keeps a 1:1 aspect ratio, so the squares get bigger as the column
|
|
25
|
+
* widens and smaller as it narrows — the count still picks how many weeks are
|
|
26
|
+
* drawn (see `weeks`), the layout picks how large they are drawn.
|
|
27
|
+
*/
|
|
28
|
+
fit?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Build the cubes and the month names left to right, once, when the graph
|
|
31
|
+
* scrolls into view. Off by default so existing heatmaps stay settled.
|
|
32
|
+
*/
|
|
33
|
+
build?: boolean;
|
|
34
|
+
className?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* RepoHeatmap — repo-level contributions over the last year, GitHub
|
|
39
|
+
* profile-graph style, via assistant-ui's headless `heat-graph`.
|
|
40
|
+
* DigiWeb livery: perfect squares (no radius), categorical accent steps
|
|
41
|
+
* via `var(--accent)` — flat fills only, no gradients. Month row on top,
|
|
42
|
+
* Mon/Wed/Fri day labels, Less/More legend, per-cell title tooltip.
|
|
43
|
+
*/
|
|
44
|
+
const COLOR_SCALE = [
|
|
45
|
+
"color-mix(in srgb, var(--ink) 9%, transparent)",
|
|
46
|
+
"color-mix(in srgb, var(--accent) 28%, transparent)",
|
|
47
|
+
"color-mix(in srgb, var(--accent) 52%, transparent)",
|
|
48
|
+
"color-mix(in srgb, var(--accent) 76%, transparent)",
|
|
49
|
+
"var(--accent)",
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const DAY_LABELS = new Set(["Mon", "Wed", "Fri"]);
|
|
53
|
+
|
|
54
|
+
/** One column of cubes, then the next. A year of weeks stays under ~1.2s. */
|
|
55
|
+
const BUILD_COLUMN_MS = 22;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Hover text for one square. States the day, the total, and — when the caller
|
|
59
|
+
* bucketed the sources — the split behind it, because "5 contributions" and
|
|
60
|
+
* "5 commits" are different facts and the graph alone cannot tell them apart.
|
|
61
|
+
*/
|
|
62
|
+
function cellTitle(date: string, count: number, day: HeatDay | undefined): string {
|
|
63
|
+
const noun = count === 1 ? "contribution" : "contributions";
|
|
64
|
+
if (day && (day.commits != null || day.pulls != null || day.issues != null)) {
|
|
65
|
+
const parts: string[] = [];
|
|
66
|
+
if (day.commits) parts.push(`${day.commits} commit${day.commits === 1 ? "" : "s"}`);
|
|
67
|
+
if (day.pulls) parts.push(`${day.pulls} PR${day.pulls === 1 ? "" : "s"}`);
|
|
68
|
+
if (day.issues) parts.push(`${day.issues} issue${day.issues === 1 ? "" : "s"}`);
|
|
69
|
+
if (parts.length) return `${date} — ${count} ${noun}: ${parts.join(", ")}`;
|
|
70
|
+
}
|
|
71
|
+
return `${date} — ${count} ${noun}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function RepoHeatmap({
|
|
75
|
+
pulls,
|
|
76
|
+
commits = [],
|
|
77
|
+
closedIssues = [],
|
|
78
|
+
data,
|
|
79
|
+
weeks = 53,
|
|
80
|
+
end,
|
|
81
|
+
fit = false,
|
|
82
|
+
build = false,
|
|
83
|
+
className,
|
|
84
|
+
}: RepoHeatmapProps) {
|
|
85
|
+
const days: HeatDay[] =
|
|
86
|
+
data ?? bucketContributions(pulls, commits, closedIssues, weeks, end ?? new Date());
|
|
87
|
+
const total = days.reduce((m, d) => m + d.count, 0);
|
|
88
|
+
const rootRef = useRef<HTMLDivElement>(null);
|
|
89
|
+
const [armed, setArmed] = useState(!build);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!build) return;
|
|
92
|
+
const el = rootRef.current;
|
|
93
|
+
if (!el || typeof IntersectionObserver === "undefined") {
|
|
94
|
+
setArmed(true);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
98
|
+
if (reduced) {
|
|
99
|
+
setArmed(true);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// IntersectionObserver(callback, options) is the real DOM signature —
|
|
103
|
+
// the threshold option below is required behaviour, not a superfluous
|
|
104
|
+
// argument (CodeQL #3016 flagged for dismissal in GitHub UI).
|
|
105
|
+
const observer = new IntersectionObserver(
|
|
106
|
+
(entries) => {
|
|
107
|
+
if (!entries.some((entry) => entry.isIntersecting)) return;
|
|
108
|
+
setArmed(true);
|
|
109
|
+
observer.disconnect();
|
|
110
|
+
},
|
|
111
|
+
{ threshold: 0.35 },
|
|
112
|
+
);
|
|
113
|
+
observer.observe(el);
|
|
114
|
+
return () => observer.disconnect();
|
|
115
|
+
}, [build]);
|
|
116
|
+
const cls = [
|
|
117
|
+
"ra-heat",
|
|
118
|
+
fit ? "ra-heat--fit" : "",
|
|
119
|
+
build ? "ra-heat--build" : "",
|
|
120
|
+
build && armed ? "is-armed" : "",
|
|
121
|
+
className ?? "",
|
|
122
|
+
]
|
|
123
|
+
.filter(Boolean)
|
|
124
|
+
.join(" ");
|
|
125
|
+
const range = weeks >= 50 ? "the last year" : `the last ${weeks} weeks`;
|
|
126
|
+
const points = days.map((d) => ({ date: d.date, count: d.count }));
|
|
127
|
+
// The grid hands back its own cells, so the per-day split is looked up by
|
|
128
|
+
// date to build the hover title.
|
|
129
|
+
const byDate = new Map(days.map((d) => [d.date, d]));
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div className={cls} ref={rootRef}>
|
|
133
|
+
<p className="ra-heat-total">
|
|
134
|
+
{grouped(total)} contributions in {range}
|
|
135
|
+
</p>
|
|
136
|
+
<HeatGraph.Root
|
|
137
|
+
data={points}
|
|
138
|
+
start={days[0]?.date ?? points[0]?.date}
|
|
139
|
+
end={days[days.length - 1]?.date ?? new Date()}
|
|
140
|
+
weekStart="sunday"
|
|
141
|
+
colorScale={COLOR_SCALE}
|
|
142
|
+
classify={(counts) => {
|
|
143
|
+
const max = counts.reduce((m, c) => Math.max(m, c), 0);
|
|
144
|
+
return (count: number) => levelFor(count, max);
|
|
145
|
+
}}
|
|
146
|
+
className="ra-heat-graph"
|
|
147
|
+
role="img"
|
|
148
|
+
aria-label={`${grouped(total)} contributions in ${range}.`}
|
|
149
|
+
>
|
|
150
|
+
<div className="ra-heat-body">
|
|
151
|
+
{/* One max-content frame holds the month row, the cell row and the
|
|
152
|
+
legend, so the month-label coordinate space is exactly the grid
|
|
153
|
+
width. Without it .ra-heat-months spans the full body width while
|
|
154
|
+
.ra-heat-grid is only max-content wide, and the %-positioned
|
|
155
|
+
labels drift right of their columns (last label ~172px past the
|
|
156
|
+
last cell at 1440). The frame is max-content at every viewport;
|
|
157
|
+
.ra-heat-body scrolls when it does not fit. */}
|
|
158
|
+
<div className="ra-heat-frame">
|
|
159
|
+
<div className="ra-heat-months" aria-hidden="true">
|
|
160
|
+
<HeatGraph.MonthLabels>
|
|
161
|
+
{({ label, totalWeeks }) => (
|
|
162
|
+
<span
|
|
163
|
+
key={`${label.month}-${label.column}`}
|
|
164
|
+
className="ra-heat-month"
|
|
165
|
+
style={{
|
|
166
|
+
left: `${(label.column / totalWeeks) * 100}%`,
|
|
167
|
+
...(build ? { animationDelay: `${label.column * BUILD_COLUMN_MS}ms` } : {}),
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
{HeatGraph.MONTH_SHORT[label.month]}
|
|
171
|
+
</span>
|
|
172
|
+
)}
|
|
173
|
+
</HeatGraph.MonthLabels>
|
|
174
|
+
</div>
|
|
175
|
+
<div className="ra-heat-row">
|
|
176
|
+
<div className="ra-heat-days" aria-hidden="true">
|
|
177
|
+
<HeatGraph.DayLabels>
|
|
178
|
+
{({ label }) => {
|
|
179
|
+
const name = HeatGraph.DAY_SHORT[label.dayOfWeek];
|
|
180
|
+
if (!DAY_LABELS.has(name))
|
|
181
|
+
return <span key={label.row} className="ra-heat-day" />;
|
|
182
|
+
return (
|
|
183
|
+
<span key={label.row} className="ra-heat-day">
|
|
184
|
+
{name}
|
|
185
|
+
</span>
|
|
186
|
+
);
|
|
187
|
+
}}
|
|
188
|
+
</HeatGraph.DayLabels>
|
|
189
|
+
</div>
|
|
190
|
+
<HeatGraph.Grid className="ra-heat-grid">
|
|
191
|
+
{({ cell }) => {
|
|
192
|
+
const date = cell.date.toISOString().slice(0, 10);
|
|
193
|
+
const n = cell.count;
|
|
194
|
+
return (
|
|
195
|
+
<HeatGraph.Cell
|
|
196
|
+
key={`${cell.column}-${cell.row}`}
|
|
197
|
+
className="ra-heat-cell"
|
|
198
|
+
data-level={cell.level}
|
|
199
|
+
title={cellTitle(date, n, byDate.get(date))}
|
|
200
|
+
style={
|
|
201
|
+
build
|
|
202
|
+
? { animationDelay: `${cell.column * BUILD_COLUMN_MS}ms` }
|
|
203
|
+
: undefined
|
|
204
|
+
}
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
}}
|
|
208
|
+
</HeatGraph.Grid>
|
|
209
|
+
</div>
|
|
210
|
+
<div className="ra-heat-foot">
|
|
211
|
+
<span />
|
|
212
|
+
<div className="ra-heat-legend" aria-hidden="true">
|
|
213
|
+
<span>Less</span>
|
|
214
|
+
<HeatGraph.Legend>
|
|
215
|
+
{() => <HeatGraph.LegendLevel className="ra-heat-cell" />}
|
|
216
|
+
</HeatGraph.Legend>
|
|
217
|
+
<span>More</span>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</HeatGraph.Root>
|
|
223
|
+
</div>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type { RepoActivitySnapshot } from "./types";
|
|
2
|
+
|
|
3
|
+
/** Realistic fixture for the design-reference specimens. Not live data. */
|
|
4
|
+
export const REPO_ACTIVITY_DEMO: RepoActivitySnapshot = {
|
|
5
|
+
generatedAt: "2026-08-24T07:15:49Z",
|
|
6
|
+
windowDays: 30,
|
|
7
|
+
branch: "main",
|
|
8
|
+
commits: 940,
|
|
9
|
+
pullsMerged: 546,
|
|
10
|
+
issuesClosed: 605,
|
|
11
|
+
pullsOpen: 4,
|
|
12
|
+
issuesOpen: 6,
|
|
13
|
+
latestRelease: {
|
|
14
|
+
tag: "digichat-v1.3.1",
|
|
15
|
+
name: "digichat: v1.3.1",
|
|
16
|
+
publishedAt: "2026-08-21T00:49:33Z",
|
|
17
|
+
url: "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.3.1",
|
|
18
|
+
},
|
|
19
|
+
mergedPulls: [
|
|
20
|
+
{
|
|
21
|
+
number: 2574,
|
|
22
|
+
title: "trade idea continuity, levels ladder, formatting",
|
|
23
|
+
url: "https://github.com/digithings-ai/digithings/pull/2574",
|
|
24
|
+
mergedAt: "2026-08-21T17:35:10Z",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
number: 1081,
|
|
28
|
+
title: "wrap SDCA engine as NautilusTrader strategy",
|
|
29
|
+
url: "https://github.com/digithings-ai/digithings/pull/1081",
|
|
30
|
+
mergedAt: "2026-08-20T22:32:46Z",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
number: 2519,
|
|
34
|
+
title: "add SDCA core engine (composite-risk + accum/dist curve + backtest)",
|
|
35
|
+
url: "https://github.com/digithings-ai/digithings/pull/2519",
|
|
36
|
+
mergedAt: "2026-08-20T13:47:08Z",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
number: 2489,
|
|
40
|
+
title: "book paper fills from the order ledger at the open",
|
|
41
|
+
url: "https://github.com/digithings-ai/digithings/pull/2489",
|
|
42
|
+
mergedAt: "2026-08-19T22:29:27Z",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
number: 2482,
|
|
46
|
+
title: "make H9 append the authoritative commit chain",
|
|
47
|
+
url: "https://github.com/digithings-ai/digithings/pull/2482",
|
|
48
|
+
mergedAt: "2026-08-19T16:06:51Z",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
number: 2432,
|
|
52
|
+
title: "add append-only portfolio lineage ledger schema",
|
|
53
|
+
url: "https://github.com/digithings-ai/digithings/pull/2432",
|
|
54
|
+
mergedAt: "2026-08-17T19:24:40Z",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
number: 2398,
|
|
58
|
+
title: "rate-limit live refresh behind a shared budget",
|
|
59
|
+
url: "https://github.com/digithings-ai/digithings/pull/2398",
|
|
60
|
+
mergedAt: "2026-08-14T11:02:19Z",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
number: 2381,
|
|
64
|
+
title: "collapse two-column activity on narrow screens",
|
|
65
|
+
url: "https://github.com/digithings-ai/digithings/pull/2381",
|
|
66
|
+
mergedAt: "2026-08-11T15:44:52Z",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
number: 2377,
|
|
70
|
+
title: "hairline lists for merged PRs and open issues",
|
|
71
|
+
url: "https://github.com/digithings-ai/digithings/pull/2377",
|
|
72
|
+
mergedAt: "2026-08-11T09:18:03Z",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
number: 2355,
|
|
76
|
+
title: "snapshot-first velocity with atomic live swap",
|
|
77
|
+
url: "https://github.com/digithings-ai/digithings/pull/2355",
|
|
78
|
+
mergedAt: "2026-08-06T20:31:47Z",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
number: 2319,
|
|
82
|
+
title: "mono numerals with tabular figures",
|
|
83
|
+
url: "https://github.com/digithings-ai/digithings/pull/2319",
|
|
84
|
+
mergedAt: "2026-07-30T14:09:55Z",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
number: 2314,
|
|
88
|
+
title: "kicker grammar across data specimens",
|
|
89
|
+
url: "https://github.com/digithings-ai/digithings/pull/2314",
|
|
90
|
+
mergedAt: "2026-07-29T18:52:36Z",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
number: 2290,
|
|
94
|
+
title: "clone-box geometry that keeps beating utilities",
|
|
95
|
+
url: "https://github.com/digithings-ai/digithings/pull/2290",
|
|
96
|
+
mergedAt: "2026-07-24T10:27:11Z",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
number: 2271,
|
|
100
|
+
title: "design tokens bridge for reference and web",
|
|
101
|
+
url: "https://github.com/digithings-ai/digithings/pull/2271",
|
|
102
|
+
mergedAt: "2026-07-17T16:40:28Z",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
number: 2244,
|
|
106
|
+
title: "no stars, forks, or watchers on activity",
|
|
107
|
+
url: "https://github.com/digithings-ai/digithings/pull/2244",
|
|
108
|
+
mergedAt: "2026-07-10T12:14:59Z",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
number: 2210,
|
|
112
|
+
title: "compact card for portfolio surfaces",
|
|
113
|
+
url: "https://github.com/digithings-ai/digithings/pull/2210",
|
|
114
|
+
mergedAt: "2026-07-02T09:33:22Z",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
number: 2187,
|
|
118
|
+
title: "detailed view with backlog split",
|
|
119
|
+
url: "https://github.com/digithings-ai/digithings/pull/2187",
|
|
120
|
+
mergedAt: "2026-06-25T21:48:07Z",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
number: 2179,
|
|
124
|
+
title: "release link with honest timestamps",
|
|
125
|
+
url: "https://github.com/digithings-ai/digithings/pull/2179",
|
|
126
|
+
mergedAt: "2026-06-25T08:05:41Z",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
number: 2152,
|
|
130
|
+
title: "copy button for the clone command",
|
|
131
|
+
url: "https://github.com/digithings-ai/digithings/pull/2152",
|
|
132
|
+
mergedAt: "2026-06-18T13:57:30Z",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
number: 2118,
|
|
136
|
+
title: "first activity snapshot fixture",
|
|
137
|
+
url: "https://github.com/digithings-ai/digithings/pull/2118",
|
|
138
|
+
mergedAt: "2026-06-11T17:22:54Z",
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
openIssues: [
|
|
142
|
+
{
|
|
143
|
+
number: 3445,
|
|
144
|
+
title: "website: progressively enhance repository section with live GitHub data",
|
|
145
|
+
url: "https://github.com/digithings-ai/digithings/issues/3445",
|
|
146
|
+
updatedAt: "2026-09-02T19:57:46Z",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
number: 3291,
|
|
150
|
+
title: "chore(website): refresh repository activity snapshot",
|
|
151
|
+
url: "https://github.com/digithings-ai/digithings/issues/3291",
|
|
152
|
+
updatedAt: "2026-08-31T09:12:00Z",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
number: 2547,
|
|
156
|
+
title: "worktree task must branch from origin base, not a stale local develop",
|
|
157
|
+
url: "https://github.com/digithings-ai/digithings/issues/2547",
|
|
158
|
+
updatedAt: "2026-08-20T11:04:00Z",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
number: 1981,
|
|
162
|
+
title: "lint and type-check the design-reference workspace in CI",
|
|
163
|
+
url: "https://github.com/digithings-ai/digithings/issues/1981",
|
|
164
|
+
updatedAt: "2026-08-18T16:40:00Z",
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
number: 1450,
|
|
168
|
+
title: "promote F1 component families into @digithings-ai/ui",
|
|
169
|
+
url: "https://github.com/digithings-ai/digithings/issues/1450",
|
|
170
|
+
updatedAt: "2026-08-12T08:22:00Z",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
number: 1310,
|
|
174
|
+
title: "frontend scoring exception for presentation-only surfaces",
|
|
175
|
+
url: "https://github.com/digithings-ai/digithings/issues/1310",
|
|
176
|
+
updatedAt: "2026-08-08T14:01:00Z",
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
/** Synthetic 14-day series so the specimen shows graded cells. Not live data. */
|
|
180
|
+
dailyContributions: [
|
|
181
|
+
{ date: "2026-08-11", count: 1 },
|
|
182
|
+
{ date: "2026-08-12", count: 3 },
|
|
183
|
+
{ date: "2026-08-13", count: 2 },
|
|
184
|
+
{ date: "2026-08-14", count: 6 },
|
|
185
|
+
{ date: "2026-08-15", count: 1 },
|
|
186
|
+
{ date: "2026-08-16", count: 4 },
|
|
187
|
+
{ date: "2026-08-17", count: 8 },
|
|
188
|
+
{ date: "2026-08-18", count: 2 },
|
|
189
|
+
{ date: "2026-08-19", count: 5 },
|
|
190
|
+
{ date: "2026-08-20", count: 3 },
|
|
191
|
+
{ date: "2026-08-21", count: 9 },
|
|
192
|
+
{ date: "2026-08-22", count: 1 },
|
|
193
|
+
{ date: "2026-08-23", count: 4 },
|
|
194
|
+
{ date: "2026-08-24", count: 7 },
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export const REPO_ACTIVITY_DEMO_URL = "https://github.com/digithings-ai/digithings";
|
|
199
|
+
export const REPO_ACTIVITY_DEMO_CLONE = "git clone https://github.com/digithings-ai/digithings";
|
|
200
|
+
export const REPO_ACTIVITY_DEMO_CONTRIBUTING =
|
|
201
|
+
"https://github.com/digithings-ai/digithings/blob/main/CONTRIBUTING.md";
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unauthenticated GitHub refresh for repository activity.
|
|
3
|
+
*
|
|
4
|
+
* All requests must succeed and validate before a result is returned. The
|
|
5
|
+
* caller (RepoActivity) applies that result atomically or keeps the snapshot.
|
|
6
|
+
* Commits are counted on the configured branch via the Link last-page trick
|
|
7
|
+
* (per_page=1); Search supplies the four issue/PR totals plus list rows.
|
|
8
|
+
* `/repos/{owner}/{repo}` is never fetched — that payload carries stars/forks.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
DEFAULT_LIVE_TIMEOUT_MS,
|
|
13
|
+
type RepoActivityLiveConfig,
|
|
14
|
+
type RepoActivitySnapshot,
|
|
15
|
+
type RepoIssueItem,
|
|
16
|
+
type RepoPullItem,
|
|
17
|
+
type RepoRelease,
|
|
18
|
+
} from "./types";
|
|
19
|
+
|
|
20
|
+
export type FetchRepoActivityLiveOptions = RepoActivityLiveConfig & {
|
|
21
|
+
fetch?: typeof globalThis.fetch;
|
|
22
|
+
now?: () => Date;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type LiveResult = Omit<RepoActivitySnapshot, "features" | "modules">;
|
|
26
|
+
|
|
27
|
+
const API = "https://api.github.com";
|
|
28
|
+
|
|
29
|
+
export async function fetchRepoActivityLive(
|
|
30
|
+
options: FetchRepoActivityLiveOptions,
|
|
31
|
+
): Promise<LiveResult> {
|
|
32
|
+
const owner = options.owner.trim();
|
|
33
|
+
const repo = options.repo.trim();
|
|
34
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(owner) || !/^[A-Za-z0-9_.-]+$/.test(repo)) {
|
|
35
|
+
throw new Error("malformed repo activity: invalid owner/repo");
|
|
36
|
+
}
|
|
37
|
+
const branch = options.branch?.trim() || "main";
|
|
38
|
+
const windowDays = options.windowDays ?? 30;
|
|
39
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_LIVE_TIMEOUT_MS;
|
|
40
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
41
|
+
const now = options.now ?? (() => new Date());
|
|
42
|
+
const generatedAt = toIsoZ(now());
|
|
43
|
+
const since = new Date(Date.parse(generatedAt) - windowDays * 86_400_000);
|
|
44
|
+
const sinceIso = toIsoZ(since);
|
|
45
|
+
const sinceDay = sinceIso.slice(0, 10);
|
|
46
|
+
const slug = `${owner}/${repo}`;
|
|
47
|
+
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
50
|
+
const get = (path: string) =>
|
|
51
|
+
fetchJson(fetchFn, `${API}${path}`, controller.signal);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const [commitsRes, merged, closed, openPrs, openIssues, releases] = await Promise.all([
|
|
55
|
+
get(`/repos/${slug}/commits?sha=${encodeURIComponent(branch)}&since=${sinceIso}&per_page=1`),
|
|
56
|
+
get(
|
|
57
|
+
`/search/issues?q=repo:${slug}+is:pr+is:merged+merged:>=${sinceDay}&per_page=6&sort=updated`,
|
|
58
|
+
),
|
|
59
|
+
get(`/search/issues?q=repo:${slug}+is:issue+is:closed+closed:>=${sinceDay}&per_page=1`),
|
|
60
|
+
get(`/search/issues?q=repo:${slug}+is:pr+is:open&per_page=1`),
|
|
61
|
+
get(`/search/issues?q=repo:${slug}+is:issue+is:open&per_page=6&sort=updated`),
|
|
62
|
+
get(`/repos/${slug}/releases?per_page=1`),
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
generatedAt,
|
|
67
|
+
windowDays,
|
|
68
|
+
branch,
|
|
69
|
+
commits: commitCount(commitsRes),
|
|
70
|
+
pullsMerged: searchTotal(merged.body),
|
|
71
|
+
issuesClosed: searchTotal(closed.body),
|
|
72
|
+
pullsOpen: searchTotal(openPrs.body),
|
|
73
|
+
issuesOpen: searchTotal(openIssues.body),
|
|
74
|
+
latestRelease: parseLatestRelease(releases.body),
|
|
75
|
+
mergedPulls: parsePullItems(merged.body),
|
|
76
|
+
openIssues: parseIssueItems(openIssues.body),
|
|
77
|
+
};
|
|
78
|
+
} catch (err) {
|
|
79
|
+
if (isAbort(err)) throw new Error("repo activity timeout");
|
|
80
|
+
throw err;
|
|
81
|
+
} finally {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type Fetched = { body: unknown; headers: Headers };
|
|
87
|
+
|
|
88
|
+
async function fetchJson(
|
|
89
|
+
fetchFn: typeof globalThis.fetch,
|
|
90
|
+
url: string,
|
|
91
|
+
signal: AbortSignal,
|
|
92
|
+
): Promise<Fetched> {
|
|
93
|
+
let res: Response;
|
|
94
|
+
try {
|
|
95
|
+
res = await fetchFn(url, { signal });
|
|
96
|
+
} catch (err) {
|
|
97
|
+
if (isAbort(err)) throw new Error("repo activity timeout");
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
throw new Error(`repo activity HTTP ${res.status}`);
|
|
102
|
+
}
|
|
103
|
+
let body: unknown;
|
|
104
|
+
try {
|
|
105
|
+
body = await res.json();
|
|
106
|
+
} catch {
|
|
107
|
+
throw new Error("malformed repo activity");
|
|
108
|
+
}
|
|
109
|
+
return { body, headers: res.headers };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function commitCount(res: Fetched): number {
|
|
113
|
+
const last = lastPage(res.headers.get("Link") ?? res.headers.get("link"));
|
|
114
|
+
if (last != null) return last;
|
|
115
|
+
if (!Array.isArray(res.body)) throw new Error("malformed repo activity");
|
|
116
|
+
return res.body.length;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function lastPage(link: string | null): number | null {
|
|
120
|
+
if (!link) return null;
|
|
121
|
+
for (const part of link.split(",")) {
|
|
122
|
+
if (!part.includes('rel="last"')) continue;
|
|
123
|
+
const m = /[?&]page=(\d+)/.exec(part);
|
|
124
|
+
if (m) return Number(m[1]);
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function searchTotal(body: unknown): number {
|
|
130
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
131
|
+
throw new Error("malformed repo activity");
|
|
132
|
+
}
|
|
133
|
+
const count = (body as { total_count?: unknown }).total_count;
|
|
134
|
+
return intCount(count);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function parsePullItems(body: unknown): RepoPullItem[] {
|
|
138
|
+
return searchItems(body).map((item) => ({
|
|
139
|
+
number: intCount(item.number, { min: 1 }),
|
|
140
|
+
title: str(item.title),
|
|
141
|
+
url: githubUrl(item.html_url),
|
|
142
|
+
mergedAt: stamp(item.closed_at) ?? stamp(item.updated_at),
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function parseIssueItems(body: unknown): RepoIssueItem[] {
|
|
147
|
+
return searchItems(body).map((item) => ({
|
|
148
|
+
number: intCount(item.number, { min: 1 }),
|
|
149
|
+
title: str(item.title),
|
|
150
|
+
url: githubUrl(item.html_url),
|
|
151
|
+
updatedAt: stamp(item.updated_at),
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function searchItems(body: unknown): Record<string, unknown>[] {
|
|
156
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
157
|
+
throw new Error("malformed repo activity");
|
|
158
|
+
}
|
|
159
|
+
const items = (body as { items?: unknown }).items;
|
|
160
|
+
if (items == null) return [];
|
|
161
|
+
if (!Array.isArray(items)) throw new Error("malformed repo activity");
|
|
162
|
+
return items.filter((it): it is Record<string, unknown> => !!it && typeof it === "object");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function parseLatestRelease(body: unknown): RepoRelease | null {
|
|
166
|
+
if (!Array.isArray(body)) throw new Error("malformed repo activity");
|
|
167
|
+
const first = body[0];
|
|
168
|
+
if (!first || typeof first !== "object") return null;
|
|
169
|
+
const row = first as Record<string, unknown>;
|
|
170
|
+
return {
|
|
171
|
+
tag: str(row.tag_name),
|
|
172
|
+
name: row.name == null ? null : str(row.name),
|
|
173
|
+
publishedAt: str(row.published_at),
|
|
174
|
+
url: githubUrl(row.html_url),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function intCount(v: unknown, opts: { min?: number } = {}): number {
|
|
179
|
+
if (typeof v !== "number" || !Number.isInteger(v) || !Number.isFinite(v) || v < (opts.min ?? 0)) {
|
|
180
|
+
throw new Error("malformed repo activity");
|
|
181
|
+
}
|
|
182
|
+
return v;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function str(v: unknown): string {
|
|
186
|
+
if (typeof v !== "string" || !v.trim()) throw new Error("malformed repo activity");
|
|
187
|
+
return v;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function githubUrl(v: unknown): string {
|
|
191
|
+
const url = str(v);
|
|
192
|
+
if (!url.startsWith("https://github.com/")) throw new Error("malformed repo activity");
|
|
193
|
+
return url;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function stamp(v: unknown): string | null {
|
|
197
|
+
if (v == null) return null;
|
|
198
|
+
if (typeof v !== "string") throw new Error("malformed repo activity");
|
|
199
|
+
return v;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function toIsoZ(d: Date): string {
|
|
203
|
+
return d.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function isAbort(err: unknown): boolean {
|
|
207
|
+
return (
|
|
208
|
+
(err instanceof DOMException && err.name === "AbortError") ||
|
|
209
|
+
(err instanceof Error && (err.name === "AbortError" || /aborted/i.test(err.message)))
|
|
210
|
+
);
|
|
211
|
+
}
|