@apteva/integrations 0.3.61 → 0.15.3
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/dist/aws-sigv4.d.ts +32 -0
- package/dist/aws-sigv4.d.ts.map +1 -0
- package/dist/aws-sigv4.js +126 -0
- package/dist/aws-sigv4.js.map +1 -0
- package/dist/explorer/main.js +21617 -0
- package/dist/explorer/main.js.map +90 -0
- package/dist/explorer/style.css +2 -0
- package/dist/http-executor.d.ts.map +1 -1
- package/dist/http-executor.js +145 -12
- package/dist/http-executor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-generator.d.ts +7 -2
- package/dist/mcp-generator.d.ts.map +1 -1
- package/dist/mcp-generator.js +46 -5
- package/dist/mcp-generator.js.map +1 -1
- package/dist/oauth.js +1 -1
- package/dist/oauth.js.map +1 -1
- package/dist/types.d.ts +251 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/github/ActivityFeed.d.ts +24 -0
- package/dist/ui/github/ActivityFeed.d.ts.map +1 -0
- package/dist/ui/github/ActivityFeed.js +106 -0
- package/dist/ui/github/ActivityFeed.js.map +1 -0
- package/dist/ui/github/ActivityFeed.mjs +3 -0
- package/dist/ui/github/ActivityFeed.mjs.map +29 -0
- package/dist/ui/github/CommitCard.d.ts +24 -0
- package/dist/ui/github/CommitCard.d.ts.map +1 -0
- package/dist/ui/github/CommitCard.js +102 -0
- package/dist/ui/github/CommitCard.js.map +1 -0
- package/dist/ui/github/CommitCard.mjs +5 -0
- package/dist/ui/github/CommitCard.mjs.map +11 -0
- package/dist/ui/github/IssueCard.d.ts +33 -0
- package/dist/ui/github/IssueCard.d.ts.map +1 -0
- package/dist/ui/github/IssueCard.js +131 -0
- package/dist/ui/github/IssueCard.js.map +1 -0
- package/dist/ui/github/IssueCard.mjs +3 -0
- package/dist/ui/github/IssueCard.mjs.map +21 -0
- package/dist/ui/github/PullRequestCard.d.ts +36 -0
- package/dist/ui/github/PullRequestCard.d.ts.map +1 -0
- package/dist/ui/github/PullRequestCard.js +158 -0
- package/dist/ui/github/PullRequestCard.js.map +1 -0
- package/dist/ui/github/PullRequestCard.mjs +3 -0
- package/dist/ui/github/PullRequestCard.mjs.map +22 -0
- package/dist/ui/github/WorkflowRunCard.d.ts +30 -0
- package/dist/ui/github/WorkflowRunCard.d.ts.map +1 -0
- package/dist/ui/github/WorkflowRunCard.js +124 -0
- package/dist/ui/github/WorkflowRunCard.js.map +1 -0
- package/dist/ui/github/WorkflowRunCard.mjs +3 -0
- package/dist/ui/github/WorkflowRunCard.mjs.map +11 -0
- package/dist/ui/github/lib/github.d.ts +43 -0
- package/dist/ui/github/lib/github.d.ts.map +1 -0
- package/dist/ui/github/lib/github.js +151 -0
- package/dist/ui/github/lib/github.js.map +1 -0
- package/dist/ui/hubspot/ActivityFeed.d.ts +22 -0
- package/dist/ui/hubspot/ActivityFeed.d.ts.map +1 -0
- package/dist/ui/hubspot/ActivityFeed.js +52 -0
- package/dist/ui/hubspot/ActivityFeed.js.map +1 -0
- package/dist/ui/hubspot/ActivityFeed.mjs +3 -0
- package/dist/ui/hubspot/ActivityFeed.mjs.map +26 -0
- package/dist/ui/hubspot/CompanyCard.d.ts +22 -0
- package/dist/ui/hubspot/CompanyCard.d.ts.map +1 -0
- package/dist/ui/hubspot/CompanyCard.js +63 -0
- package/dist/ui/hubspot/CompanyCard.js.map +1 -0
- package/dist/ui/hubspot/CompanyCard.mjs +3 -0
- package/dist/ui/hubspot/CompanyCard.mjs.map +11 -0
- package/dist/ui/hubspot/ContactCard.d.ts +22 -0
- package/dist/ui/hubspot/ContactCard.d.ts.map +1 -0
- package/dist/ui/hubspot/ContactCard.js +62 -0
- package/dist/ui/hubspot/ContactCard.js.map +1 -0
- package/dist/ui/hubspot/ContactCard.mjs +3 -0
- package/dist/ui/hubspot/ContactCard.mjs.map +11 -0
- package/dist/ui/hubspot/ContactList.d.ts +21 -0
- package/dist/ui/hubspot/ContactList.d.ts.map +1 -0
- package/dist/ui/hubspot/ContactList.js +31 -0
- package/dist/ui/hubspot/ContactList.js.map +1 -0
- package/dist/ui/hubspot/ContactList.mjs +3 -0
- package/dist/ui/hubspot/ContactList.mjs.map +11 -0
- package/dist/ui/hubspot/DealCard.d.ts +23 -0
- package/dist/ui/hubspot/DealCard.d.ts.map +1 -0
- package/dist/ui/hubspot/DealCard.js +63 -0
- package/dist/ui/hubspot/DealCard.js.map +1 -0
- package/dist/ui/hubspot/DealCard.mjs +3 -0
- package/dist/ui/hubspot/DealCard.mjs.map +11 -0
- package/dist/ui/hubspot/DealList.d.ts +24 -0
- package/dist/ui/hubspot/DealList.d.ts.map +1 -0
- package/dist/ui/hubspot/DealList.js +35 -0
- package/dist/ui/hubspot/DealList.js.map +1 -0
- package/dist/ui/hubspot/DealList.mjs +3 -0
- package/dist/ui/hubspot/DealList.mjs.map +11 -0
- package/dist/ui/hubspot/EmailCard.d.ts +25 -0
- package/dist/ui/hubspot/EmailCard.d.ts.map +1 -0
- package/dist/ui/hubspot/EmailCard.js +62 -0
- package/dist/ui/hubspot/EmailCard.js.map +1 -0
- package/dist/ui/hubspot/EmailCard.mjs +5 -0
- package/dist/ui/hubspot/EmailCard.mjs.map +11 -0
- package/dist/ui/hubspot/InboxStrip.d.ts +23 -0
- package/dist/ui/hubspot/InboxStrip.d.ts.map +1 -0
- package/dist/ui/hubspot/InboxStrip.js +36 -0
- package/dist/ui/hubspot/InboxStrip.js.map +1 -0
- package/dist/ui/hubspot/InboxStrip.mjs +3 -0
- package/dist/ui/hubspot/InboxStrip.mjs.map +11 -0
- package/dist/ui/hubspot/PipelineStrip.d.ts +22 -0
- package/dist/ui/hubspot/PipelineStrip.d.ts.map +1 -0
- package/dist/ui/hubspot/PipelineStrip.js +54 -0
- package/dist/ui/hubspot/PipelineStrip.js.map +1 -0
- package/dist/ui/hubspot/PipelineStrip.mjs +3 -0
- package/dist/ui/hubspot/PipelineStrip.mjs.map +11 -0
- package/dist/ui/hubspot/TicketCard.d.ts +25 -0
- package/dist/ui/hubspot/TicketCard.d.ts.map +1 -0
- package/dist/ui/hubspot/TicketCard.js +53 -0
- package/dist/ui/hubspot/TicketCard.js.map +1 -0
- package/dist/ui/hubspot/TicketCard.mjs +3 -0
- package/dist/ui/hubspot/TicketCard.mjs.map +21 -0
- package/dist/ui/hubspot/TicketList.d.ts +21 -0
- package/dist/ui/hubspot/TicketList.d.ts.map +1 -0
- package/dist/ui/hubspot/TicketList.js +33 -0
- package/dist/ui/hubspot/TicketList.js.map +1 -0
- package/dist/ui/hubspot/TicketList.mjs +3 -0
- package/dist/ui/hubspot/TicketList.mjs.map +11 -0
- package/dist/ui/hubspot/lib/hubspot.d.ts +24 -0
- package/dist/ui/hubspot/lib/hubspot.d.ts.map +1 -0
- package/dist/ui/hubspot/lib/hubspot.js +176 -0
- package/dist/ui/hubspot/lib/hubspot.js.map +1 -0
- package/dist/ui/notion/DatabaseCard.d.ts +24 -0
- package/dist/ui/notion/DatabaseCard.d.ts.map +1 -0
- package/dist/ui/notion/DatabaseCard.js +86 -0
- package/dist/ui/notion/DatabaseCard.js.map +1 -0
- package/dist/ui/notion/DatabaseCard.mjs +3 -0
- package/dist/ui/notion/DatabaseCard.mjs.map +11 -0
- package/dist/ui/notion/DatabaseRowList.d.ts +36 -0
- package/dist/ui/notion/DatabaseRowList.d.ts.map +1 -0
- package/dist/ui/notion/DatabaseRowList.js +87 -0
- package/dist/ui/notion/DatabaseRowList.js.map +1 -0
- package/dist/ui/notion/DatabaseRowList.mjs +3 -0
- package/dist/ui/notion/DatabaseRowList.mjs.map +11 -0
- package/dist/ui/notion/PageCard.d.ts +27 -0
- package/dist/ui/notion/PageCard.d.ts.map +1 -0
- package/dist/ui/notion/PageCard.js +80 -0
- package/dist/ui/notion/PageCard.js.map +1 -0
- package/dist/ui/notion/PageCard.mjs +3 -0
- package/dist/ui/notion/PageCard.mjs.map +11 -0
- package/dist/ui/notion/PageList.d.ts +24 -0
- package/dist/ui/notion/PageList.d.ts.map +1 -0
- package/dist/ui/notion/PageList.js +51 -0
- package/dist/ui/notion/PageList.js.map +1 -0
- package/dist/ui/notion/PageList.mjs +3 -0
- package/dist/ui/notion/PageList.mjs.map +11 -0
- package/dist/ui/notion/lib/notion.d.ts +35 -0
- package/dist/ui/notion/lib/notion.d.ts.map +1 -0
- package/dist/ui/notion/lib/notion.js +119 -0
- package/dist/ui/notion/lib/notion.js.map +1 -0
- package/dist/xml-to-json.d.ts +20 -0
- package/dist/xml-to-json.d.ts.map +1 -0
- package/dist/xml-to-json.js +256 -0
- package/dist/xml-to-json.js.map +1 -0
- package/package.json +12 -1
- package/src/apps/adroll.json +254 -0
- package/src/apps/ahrefs.json +156 -0
- package/src/apps/airtable.json +4 -13
- package/src/apps/algolia.json +115 -0
- package/src/apps/alibaba-cloud.json +211 -0
- package/src/apps/aliexpress.json +369 -0
- package/src/apps/alpaca-market-data.json +699 -0
- package/src/apps/alpaca-trading.json +214 -989
- package/src/apps/amazon-ads.json +249 -0
- package/src/apps/amazon-associates.json +102 -0
- package/src/apps/amplitude.json +86 -0
- package/src/apps/anchor-browser.json +173 -0
- package/src/apps/anthropic-api.json +9 -4
- package/src/apps/api-sports.json +180 -0
- package/src/apps/apple-search-ads.json +266 -0
- package/src/apps/auth0.json +126 -0
- package/src/apps/awin.json +111 -0
- package/src/apps/aws-codebuild.json +139 -0
- package/src/apps/aws-mediaconvert.json +196 -0
- package/src/apps/aws-s3.json +108 -192
- package/src/apps/aws-ses.json +666 -303
- package/src/apps/aws-sns.json +128 -106
- package/src/apps/azure-container-apps.json +116 -0
- package/src/apps/backblaze-b2.json +175 -0
- package/src/apps/bamboohr.json +303 -0
- package/src/apps/basiq.json +308 -0
- package/src/apps/bigcommerce.json +366 -0
- package/src/apps/bigquery.json +121 -0
- package/src/apps/binance-trading.json +7 -4
- package/src/apps/bing-webmaster-tools.json +158 -0
- package/src/apps/bitbucket.json +163 -0
- package/src/apps/blacksmith.json +81 -0
- package/src/apps/bls.json +104 -0
- package/src/apps/bluesky.json +74 -0
- package/src/apps/braze.json +103 -0
- package/src/apps/brevo.json +4 -1
- package/src/apps/brightdata.json +94 -0
- package/src/apps/browserbase.json +237 -0
- package/src/apps/bscscan.json +150 -0
- package/src/apps/buffer.json +121 -0
- package/src/apps/buildjet.json +80 -0
- package/src/apps/builtwith.json +101 -0
- package/src/apps/bunny-cdn.json +104 -0
- package/src/apps/bunny-stream.json +205 -3
- package/src/apps/byrd.json +585 -0
- package/src/apps/calendly.json +10 -7
- package/src/apps/campaign-manager-360.json +264 -0
- package/src/apps/capturekit.json +51 -0
- package/src/apps/circleci.json +212 -0
- package/src/apps/cirrus-runners.json +75 -0
- package/src/apps/cj-affiliate.json +101 -0
- package/src/apps/cjdropshipping.json +278 -0
- package/src/apps/clerk.json +153 -0
- package/src/apps/cloudflare-containers.json +98 -0
- package/src/apps/cloudflare-r2.json +180 -0
- package/src/apps/cloudflare.json +474 -157
- package/src/apps/cloudinary.json +119 -97
- package/src/apps/coconut.json +94 -0
- package/src/apps/contentful.json +157 -0
- package/src/apps/criteo.json +222 -0
- package/src/apps/crunchbase.json +104 -0
- package/src/apps/customer-io.json +106 -0
- package/src/apps/databricks.json +94 -0
- package/src/apps/deepgram.json +3 -0
- package/src/apps/deepl.json +113 -0
- package/src/apps/deepseek.json +5 -2
- package/src/apps/depot.json +102 -0
- package/src/apps/digitalocean-spaces.json +121 -0
- package/src/apps/digitalocean.json +115 -0
- package/src/apps/discord.json +90 -1
- package/src/apps/docker-build-cloud.json +68 -0
- package/src/apps/duffel.json +193 -77
- package/src/apps/dux-soup.json +4 -1
- package/src/apps/dv360.json +287 -0
- package/src/apps/earthly-cloud.json +84 -0
- package/src/apps/eia.json +121 -0
- package/src/apps/elasticsearch.json +282 -0
- package/src/apps/elevenlabs.json +336 -192
- package/src/apps/etherscan.json +162 -0
- package/src/apps/etsy.json +484 -0
- package/src/apps/eventbrite-events.json +5 -2
- package/src/apps/exa.json +101 -0
- package/src/apps/facebook-ads.json +3 -3
- package/src/apps/facebook-api.json +1484 -37
- package/src/apps/finnhub.json +232 -0
- package/src/apps/flightapi.json +248 -0
- package/src/apps/fly-io.json +134 -0
- package/src/apps/fred.json +156 -0
- package/src/apps/gdelt.json +96 -0
- package/src/apps/gelato.json +123 -0
- package/src/apps/gemini.json +143 -49
- package/src/apps/getscreenshot.json +52 -0
- package/src/apps/github.json +355 -39
- package/src/apps/gmail.json +151 -2
- package/src/apps/gnews.json +71 -0
- package/src/apps/google-analytics.json +311 -0
- package/src/apps/google-cloud-storage.json +484 -0
- package/src/apps/google-docs.json +2 -2
- package/src/apps/google-drive.json +2 -2
- package/src/apps/google-places.json +127 -0
- package/src/apps/google-search-console.json +126 -0
- package/src/apps/google-sheets.json +2 -2
- package/src/apps/grafana-cloud.json +98 -0
- package/src/apps/groq.json +119 -0
- package/src/apps/hetzner-object-storage.json +177 -0
- package/src/apps/hetzner.json +255 -367
- package/src/apps/heygen.json +828 -141
- package/src/apps/hive-fulfillment.json +559 -0
- package/src/apps/hotjar.json +91 -0
- package/src/apps/huawei-cloud.json +189 -0
- package/src/apps/huboo.json +286 -0
- package/src/apps/hubspot.json +253 -637
- package/src/apps/huggingface.json +5 -2
- package/src/apps/hunter.json +5 -2
- package/src/apps/hyperbrowser.json +205 -0
- package/src/apps/idrive-e2.json +128 -0
- package/src/apps/impact.json +106 -0
- package/src/apps/instagram-api.json +185 -11
- package/src/apps/instantly.json +169 -0
- package/src/apps/ionos.json +250 -0
- package/src/apps/{learning-platform.json → kalio.json} +162 -3
- package/src/apps/kalshi.json +144 -0
- package/src/apps/keywords-everywhere.json +86 -0
- package/src/apps/kickbox.json +71 -0
- package/src/apps/launchdarkly.json +111 -0
- package/src/apps/leadbyte.json +600 -0
- package/src/apps/leadfeeder.json +89 -0
- package/src/apps/lemlist.json +109 -0
- package/src/apps/linkedin-ads.json +279 -0
- package/src/apps/linkedin.json +96 -2
- package/src/apps/linode-object-storage.json +183 -0
- package/src/apps/linode.json +160 -0
- package/src/apps/lnk-bio.json +5 -2
- package/src/apps/loom.json +5 -2
- package/src/apps/lusha.json +104 -0
- package/src/apps/magalu-cloud.json +187 -0
- package/src/apps/majestic.json +117 -0
- package/src/apps/manifold-markets.json +144 -0
- package/src/apps/mapbox.json +118 -0
- package/src/apps/microsoft-ads.json +246 -0
- package/src/apps/microsoft-onedrive.json +380 -0
- package/src/apps/microsoft-teams.json +315 -96
- package/src/apps/millionverifier.json +85 -0
- package/src/apps/mindee.json +246 -0
- package/src/apps/miro.json +138 -0
- package/src/apps/mistral.json +129 -0
- package/src/apps/mixpanel.json +95 -0
- package/src/apps/moz.json +127 -0
- package/src/apps/mux.json +201 -0
- package/src/apps/namecheap.json +321 -123
- package/src/apps/namespace-cloud.json +84 -0
- package/src/apps/naver-cloud.json +184 -0
- package/src/apps/neon.json +122 -0
- package/src/apps/netlify.json +124 -0
- package/src/apps/neverbounce.json +92 -0
- package/src/apps/newrelic.json +80 -0
- package/src/apps/newsapi.json +86 -0
- package/src/apps/ngrok.json +29 -0
- package/src/apps/nixbuild.json +116 -0
- package/src/apps/northflank.json +161 -0
- package/src/apps/notion.json +3 -0
- package/src/apps/okta.json +131 -0
- package/src/apps/omnikit-analytics.json +73 -1
- package/src/apps/omnikit-api-gateway.json +74 -2
- package/src/apps/omnikit-billing.json +73 -1
- package/src/apps/omnikit-cms.json +73 -1
- package/src/apps/omnikit-code-ops.json +76 -4
- package/src/apps/omnikit-functions.json +74 -2
- package/src/apps/omnikit-intelligence.json +176 -33
- package/src/apps/omnikit-management.json +73 -1
- package/src/apps/omnikit-media.json +73 -1
- package/src/apps/omnikit-messaging.json +72 -0
- package/src/apps/omnikit-redirects.json +73 -1
- package/src/apps/omnikit-sites.json +325 -66
- package/src/apps/omnikit-storage.json +105 -8
- package/src/apps/omnikit-webhooks.json +73 -1
- package/src/apps/omnikit-workflows.json +73 -1
- package/src/apps/onesignal.json +108 -0
- package/src/apps/openai-api.json +176 -30
- package/src/apps/openai-codex.json +187 -0
- package/src/apps/opencode-go.json +113 -0
- package/src/apps/optinmonster.json +7 -4
- package/src/apps/outlook-calendar.json +350 -0
- package/src/apps/outlook-mail.json +337 -0
- package/src/apps/outscraper.json +118 -0
- package/src/apps/ovhcloud.json +209 -0
- package/src/apps/paddle.json +170 -0
- package/src/apps/pagerduty.json +151 -0
- package/src/apps/partnerstack.json +118 -0
- package/src/apps/perplexity.json +37 -0
- package/src/apps/phantombuster.json +85 -0
- package/src/apps/pinecone.json +129 -0
- package/src/apps/pinterest-ads.json +261 -0
- package/src/apps/pinterest.json +217 -0
- package/src/apps/planetscale.json +139 -0
- package/src/apps/polygonscan.json +157 -0
- package/src/apps/polymarket-clob.json +184 -0
- package/src/apps/polymarket-data.json +153 -0
- package/src/apps/porkbun.json +609 -145
- package/src/apps/posthog.json +107 -0
- package/src/apps/pushover.json +28 -0
- package/src/apps/quora-ads.json +251 -0
- package/src/apps/railway.json +57 -0
- package/src/apps/reddit-ads.json +238 -0
- package/src/apps/reddit.json +274 -0
- package/src/apps/render.json +124 -0
- package/src/apps/replicate.json +5 -2
- package/src/apps/reply-io.json +111 -0
- package/src/apps/resend.json +110 -0
- package/src/apps/ringover.json +1144 -0
- package/src/apps/rocketreach.json +158 -0
- package/src/apps/rollbar.json +88 -0
- package/src/apps/runs-on.json +70 -0
- package/src/apps/sanity.json +89 -0
- package/src/apps/scaleway-object-storage.json +175 -0
- package/src/apps/scrapingbee.json +75 -0
- package/src/apps/screenshotlayer.json +49 -0
- package/src/apps/screenshotmachine.json +49 -0
- package/src/apps/se-ranking.json +239 -0
- package/src/apps/seamless-ai.json +91 -0
- package/src/apps/sec-edgar.json +107 -0
- package/src/apps/segment.json +104 -0
- package/src/apps/semrush.json +153 -0
- package/src/apps/sentry.json +109 -0
- package/src/apps/serpapi.json +95 -0
- package/src/apps/serper.json +139 -0
- package/src/apps/shareasale.json +130 -0
- package/src/apps/skimlinks.json +48 -0
- package/src/apps/slack.json +101 -0
- package/src/apps/smartlead.json +146 -0
- package/src/apps/snapchat-ads.json +238 -0
- package/src/apps/snaprender.json +64 -0
- package/src/apps/snowflake.json +70 -0
- package/src/apps/snyk.json +108 -0
- package/src/apps/socialcast.json +74 -8
- package/src/apps/sovrn.json +125 -0
- package/src/apps/spotify-ads.json +231 -0
- package/src/apps/steel.json +239 -0
- package/src/apps/stocktwits.json +120 -0
- package/src/apps/stripe.json +153 -0
- package/src/apps/target-circle.json +348 -0
- package/src/apps/tavily.json +104 -0
- package/src/apps/tavus.json +403 -0
- package/src/apps/telegram.json +5 -2
- package/src/apps/teller.json +187 -0
- package/src/apps/tencent-cloud.json +214 -0
- package/src/apps/tennis-abstract.json +108 -0
- package/src/apps/the-odds-api.json +132 -0
- package/src/apps/the-sports-db.json +163 -0
- package/src/apps/tiktok-ads.json +295 -0
- package/src/apps/tiktok-api.json +181 -7
- package/src/apps/together.json +5 -2
- package/src/apps/trade-desk.json +237 -0
- package/src/apps/trading212.json +26 -29
- package/src/apps/transloadit.json +138 -0
- package/src/apps/truelayer.json +318 -0
- package/src/apps/twilio.json +313 -42
- package/src/apps/twitter-api.json +216 -33
- package/src/apps/ubicloud.json +82 -0
- package/src/apps/uplead.json +105 -0
- package/src/apps/upstash.json +90 -0
- package/src/apps/valueserp.json +63 -0
- package/src/apps/venice-ai.json +685 -0
- package/src/apps/vercel.json +137 -0
- package/src/apps/wappalyzer.json +65 -0
- package/src/apps/wasabi.json +175 -0
- package/src/apps/whale-alert.json +74 -0
- package/src/apps/whatsapp-business.json +131 -0
- package/src/apps/wikipedia.json +112 -0
- package/src/apps/workos.json +123 -0
- package/src/apps/yahoo-dsp.json +265 -0
- package/src/apps/yahoo-finance.json +60 -0
- package/src/apps/youtube-api.json +520 -142
- package/src/apps/zenrows.json +47 -0
- package/src/apps/zenserp.json +99 -0
- package/src/apps/zerobounce.json +80 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// PullRequestCard — chat-attachment card for a single GitHub PR.
|
|
2
|
+
//
|
|
3
|
+
// The agent passes what it just got back from the github get_pull
|
|
4
|
+
// tool. Same prop-shape convention as IssueCard: each field optional,
|
|
5
|
+
// each carrying just enough so the title + status + a few stats
|
|
6
|
+
// render without needing a follow-up fetch.
|
|
7
|
+
//
|
|
8
|
+
// Composes ui-kit primitives only — Card, CardHeader, StatusPill,
|
|
9
|
+
// Avatar, AvatarStack, DataList, KPI. No GitHub-specific chrome.
|
|
10
|
+
import { GitMerge, GitPullRequest } from "lucide-react";
|
|
11
|
+
import { Avatar, AvatarStack, Card, CardHeader, DataList, StatusPill } from "@apteva/ui-kit";
|
|
12
|
+
import { avatarDataUrl, githubVendor, pullRequestState, pullRequestUrl, shortSha, timeAgo, } from "./lib/github";
|
|
13
|
+
const previewSample = {
|
|
14
|
+
repo: "acme/api",
|
|
15
|
+
pr_number: 847,
|
|
16
|
+
title: "Add idempotency keys to webhook receiver",
|
|
17
|
+
state: "open",
|
|
18
|
+
merged: false,
|
|
19
|
+
draft: false,
|
|
20
|
+
user: { login: "maya", avatar_url: avatarDataUrl("a78bfa") },
|
|
21
|
+
reviewers: [
|
|
22
|
+
{ login: "ari", avatar_url: avatarDataUrl("34d399") },
|
|
23
|
+
{ login: "lin", avatar_url: avatarDataUrl("60a5fa") },
|
|
24
|
+
{ login: "soren", avatar_url: avatarDataUrl("f59e0b") },
|
|
25
|
+
],
|
|
26
|
+
approvals: 1,
|
|
27
|
+
changes_requested: 0,
|
|
28
|
+
labels: [
|
|
29
|
+
{ name: "enhancement", color: "0e8a16" },
|
|
30
|
+
{ name: "api", color: "1f6feb" },
|
|
31
|
+
{ name: "needs-tests", color: "fbca04" },
|
|
32
|
+
],
|
|
33
|
+
comments: 4,
|
|
34
|
+
additions: 124,
|
|
35
|
+
deletions: 18,
|
|
36
|
+
changed_files: 7,
|
|
37
|
+
head_ref: "feature/idempotency-keys",
|
|
38
|
+
base_ref: "main",
|
|
39
|
+
mergeable: "mergeable",
|
|
40
|
+
created_at: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
|
|
41
|
+
};
|
|
42
|
+
export default function PullRequestCard(props) {
|
|
43
|
+
const p = props.preview
|
|
44
|
+
? previewSample
|
|
45
|
+
: {
|
|
46
|
+
...previewSample,
|
|
47
|
+
repo: props.repo,
|
|
48
|
+
pr_number: props.pr_number,
|
|
49
|
+
title: props.title || `PR #${props.pr_number}`,
|
|
50
|
+
state: props.state ?? "open",
|
|
51
|
+
merged: props.merged ?? false,
|
|
52
|
+
draft: props.draft ?? false,
|
|
53
|
+
user: { login: props.user_login || "", avatar_url: props.user_avatar_url || "" },
|
|
54
|
+
reviewers: (props.reviewers || "")
|
|
55
|
+
.split(",").map((s) => s.trim()).filter(Boolean)
|
|
56
|
+
.map((login) => ({ login, avatar_url: "" })),
|
|
57
|
+
approvals: props.approvals ?? 0,
|
|
58
|
+
changes_requested: props.changes_requested ?? 0,
|
|
59
|
+
labels: (props.labels || "")
|
|
60
|
+
.split(",").map((s) => s.trim()).filter(Boolean)
|
|
61
|
+
.map((name) => ({ name, color: "1f6feb" })),
|
|
62
|
+
comments: props.comments ?? 0,
|
|
63
|
+
additions: props.additions ?? 0,
|
|
64
|
+
deletions: props.deletions ?? 0,
|
|
65
|
+
changed_files: props.changed_files ?? 0,
|
|
66
|
+
head_ref: props.head_ref || "",
|
|
67
|
+
base_ref: props.base_ref || "main",
|
|
68
|
+
mergeable: props.mergeable ?? "unknown",
|
|
69
|
+
created_at: props.created_at || new Date().toISOString(),
|
|
70
|
+
};
|
|
71
|
+
const status = pullRequestState({ state: p.state, merged: p.merged, draft: p.draft });
|
|
72
|
+
const reviewSummary = reviewLine(p.approvals, p.changes_requested, p.reviewers.length);
|
|
73
|
+
const url = pullRequestUrl(p.repo, p.pr_number);
|
|
74
|
+
const StateIcon = p.merged ? GitMerge : GitPullRequest;
|
|
75
|
+
return (<Card>
|
|
76
|
+
<CardHeader vendor={githubVendor} title={p.repo} subtitle={<span className="inline-flex items-center gap-1.5">
|
|
77
|
+
<StateIcon className="w-3.5 h-3.5 inline-block"/>
|
|
78
|
+
<span>#{p.pr_number} · {p.title}</span>
|
|
79
|
+
</span>} status={{ label: status.label, variant: status.dot }} action={{ label: "View on GitHub", href: url }}/>
|
|
80
|
+
|
|
81
|
+
<div className="px-4 py-3 flex flex-col gap-3">
|
|
82
|
+
{/* author + creation time + diff stats */}
|
|
83
|
+
<div className="flex items-center gap-2 text-xs">
|
|
84
|
+
<Avatar src={p.user.avatar_url} name={p.user.login} size={18}/>
|
|
85
|
+
<span className="text-text font-medium">{p.user.login}</span>
|
|
86
|
+
<span className="text-text-dim">opened {timeAgo(p.created_at)}</span>
|
|
87
|
+
<span className="ml-auto inline-flex items-center gap-2 tabular-nums">
|
|
88
|
+
<span className="text-green-600 dark:text-success">+{p.additions}</span>
|
|
89
|
+
<span className="text-red-600 dark:text-error">−{p.deletions}</span>
|
|
90
|
+
<span className="text-text-dim">in {p.changed_files} file{p.changed_files === 1 ? "" : "s"}</span>
|
|
91
|
+
</span>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<DataList items={[
|
|
95
|
+
{
|
|
96
|
+
label: "Status",
|
|
97
|
+
value: (<span className="inline-flex items-center gap-2">
|
|
98
|
+
<StatusPill variant={status.variant}>{status.label}</StatusPill>
|
|
99
|
+
{p.mergeable === "conflicting" && (<StatusPill variant="warn">conflicts</StatusPill>)}
|
|
100
|
+
</span>),
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: "Branch",
|
|
104
|
+
value: (<span className="font-mono text-xs">
|
|
105
|
+
<span className="text-text">{p.head_ref || "—"}</span>
|
|
106
|
+
<span className="text-text-dim mx-1">→</span>
|
|
107
|
+
<span className="text-text-dim">{p.base_ref}</span>
|
|
108
|
+
</span>),
|
|
109
|
+
},
|
|
110
|
+
...(p.reviewers.length > 0
|
|
111
|
+
? [{
|
|
112
|
+
label: "Reviewers",
|
|
113
|
+
value: (<span className="inline-flex items-center gap-2">
|
|
114
|
+
<AvatarStack users={p.reviewers} size={18} max={4}/>
|
|
115
|
+
{reviewSummary && <span className="text-xs text-text-dim">{reviewSummary}</span>}
|
|
116
|
+
</span>),
|
|
117
|
+
}]
|
|
118
|
+
: []),
|
|
119
|
+
...(p.labels.length > 0
|
|
120
|
+
? [{
|
|
121
|
+
label: "Labels",
|
|
122
|
+
value: (<span className="inline-flex flex-wrap gap-1">
|
|
123
|
+
{p.labels.map((l) => (<span key={l.name} className="text-[11px] font-medium px-1.5 py-0.5 rounded-md" style={{
|
|
124
|
+
color: `#${l.color}`,
|
|
125
|
+
backgroundColor: `#${l.color}1F`,
|
|
126
|
+
}}>
|
|
127
|
+
{l.name}
|
|
128
|
+
</span>))}
|
|
129
|
+
</span>),
|
|
130
|
+
}]
|
|
131
|
+
: []),
|
|
132
|
+
{
|
|
133
|
+
label: "Activity",
|
|
134
|
+
value: (<span className="text-xs text-text-dim tabular-nums">
|
|
135
|
+
{p.comments} comment{p.comments === 1 ? "" : "s"}
|
|
136
|
+
</span>),
|
|
137
|
+
},
|
|
138
|
+
]}/>
|
|
139
|
+
</div>
|
|
140
|
+
</Card>);
|
|
141
|
+
}
|
|
142
|
+
function reviewLine(approvals, changes, total) {
|
|
143
|
+
if (total === 0)
|
|
144
|
+
return "";
|
|
145
|
+
const parts = [];
|
|
146
|
+
if (approvals > 0)
|
|
147
|
+
parts.push(`${approvals} approval${approvals === 1 ? "" : "s"}`);
|
|
148
|
+
if (changes > 0)
|
|
149
|
+
parts.push(`${changes} changes requested`);
|
|
150
|
+
if (parts.length === 0)
|
|
151
|
+
parts.push("no review yet");
|
|
152
|
+
return `· ${parts.join(",")}`;
|
|
153
|
+
}
|
|
154
|
+
// Make sure shortSha stays imported when not used yet — guards
|
|
155
|
+
// against linter pruning when other cards in the same lib reach
|
|
156
|
+
// for it. (Compile-time only.)
|
|
157
|
+
void shortSha;
|
|
158
|
+
//# sourceMappingURL=PullRequestCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PullRequestCard.js","sourceRoot":"","sources":["../../../src/ui/github/PullRequestCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{forwardRef as p,createElement as m}from"react";var K=(...J)=>J.filter((B,Q,O)=>{return Boolean(B)&&B.trim()!==""&&O.indexOf(B)===Q}).join(" ").trim();var A=(J)=>J.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var M=(J)=>J.replace(/^([A-Z])|[\s-_]+(\w)/g,(B,Q,O)=>O?O.toUpperCase():Q.toLowerCase());var q=(J)=>{let B=M(J);return B.charAt(0).toUpperCase()+B.slice(1)};import{forwardRef as j,createElement as R}from"react";var E={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var P=(J)=>{for(let B in J)if(B.startsWith("aria-")||B==="role"||B==="title")return!0;return!1};import{createContext as d,useContext as u,useMemo as HB,createElement as VB}from"react";var l=d({});var U=()=>u(l);var W=j(({color:J,size:B,strokeWidth:Q,absoluteStrokeWidth:O,className:$="",children:Z,iconNode:T,..._},k)=>{let{size:D=24,strokeWidth:I=2,absoluteStrokeWidth:v=!1,color:f="currentColor",className:x=""}=U()??{},w=O??v?Number(Q??I)*24/Number(B??D):Q??I;return R("svg",{ref:k,...E,width:B??D??E.width,height:B??D??E.height,stroke:J??f,strokeWidth:w,className:K("lucide",x,$),...!Z&&!P(_)&&{"aria-hidden":"true"},..._},[...T.map(([g,h])=>R(g,h)),...Array.isArray(Z)?Z:[Z]])});var G=(J,B)=>{let Q=p(({className:O,...$},Z)=>m(W,{ref:Z,iconNode:B,className:K(`lucide-${A(q(J))}`,`lucide-${J}`,O),...$}));return Q.displayName=q(J),Q};var a=[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M6 21V9a9 9 0 0 0 9 9",key:"7kw0sc"}]],H=G("git-merge",a);var r=[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M13 6h3a2 2 0 0 1 2 2v7",key:"1yeb86"}],["line",{x1:"6",x2:"6",y1:"9",y2:"21",key:"rroup"}]],V=G("git-pull-request",r);import{Avatar as n,AvatarStack as c,Card as i,CardHeader as e,DataList as o,StatusPill as C}from"@apteva/ui-kit";import{jsx as y}from"react/jsx-runtime";var t=y("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:y("path",{d:"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.807 1.305 3.492.998.108-.776.42-1.305.762-1.604-2.665-.305-5.466-1.334-5.466-5.93 0-1.31.467-2.38 1.235-3.22-.135-.303-.54-1.524.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.652.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.435.375.81 1.102.81 2.222 0 1.605-.015 2.898-.015 3.293 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"})});var S={name:"GitHub",logo:t,color:"#8957e5"};function L(J,B){return`https://github.com/${J}/pull/${B}`}function N(J){if(!J)return"";let B=new Date(J).getTime();if(!Number.isFinite(B))return"";let Q=Math.max(0,(Date.now()-B)/1000);if(Q<60)return"just now";let O=Q/60;if(O<60)return`${Math.round(O)}m ago`;let $=O/60;if($<24)return`${Math.round($)}h ago`;let Z=$/24;if(Z<30)return`${Math.round(Z)}d ago`;let T=Z/30;if(T<12)return`${Math.round(T)}mo ago`;return`${Math.round(T/12)}y ago`}function z(J){if(J.merged)return{label:"merged",variant:"success",dot:"live"};if(J.state==="closed")return{label:"closed",variant:"error",dot:"error"};if(J.draft)return{label:"draft",variant:"neutral",dot:"muted"};return{label:"open",variant:"info",dot:"active"}}function F(J){return"data:image/svg+xml;utf8,"+encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='8' cy='8' r='8' fill='%23${J}'/></svg>`)}import{jsx as X,jsxs as Y}from"react/jsx-runtime";var b={repo:"acme/api",pr_number:847,title:"Add idempotency keys to webhook receiver",state:"open",merged:!1,draft:!1,user:{login:"maya",avatar_url:F("a78bfa")},reviewers:[{login:"ari",avatar_url:F("34d399")},{login:"lin",avatar_url:F("60a5fa")},{login:"soren",avatar_url:F("f59e0b")}],approvals:1,changes_requested:0,labels:[{name:"enhancement",color:"0e8a16"},{name:"api",color:"1f6feb"},{name:"needs-tests",color:"fbca04"}],comments:4,additions:124,deletions:18,changed_files:7,head_ref:"feature/idempotency-keys",base_ref:"main",mergeable:"mergeable",created_at:new Date(Date.now()-259200000).toISOString()};function s(J){let B=J.preview?b:{...b,repo:J.repo,pr_number:J.pr_number,title:J.title||`PR #${J.pr_number}`,state:J.state??"open",merged:J.merged??!1,draft:J.draft??!1,user:{login:J.user_login||"",avatar_url:J.user_avatar_url||""},reviewers:(J.reviewers||"").split(",").map((T)=>T.trim()).filter(Boolean).map((T)=>({login:T,avatar_url:""})),approvals:J.approvals??0,changes_requested:J.changes_requested??0,labels:(J.labels||"").split(",").map((T)=>T.trim()).filter(Boolean).map((T)=>({name:T,color:"1f6feb"})),comments:J.comments??0,additions:J.additions??0,deletions:J.deletions??0,changed_files:J.changed_files??0,head_ref:J.head_ref||"",base_ref:J.base_ref||"main",mergeable:J.mergeable??"unknown",created_at:J.created_at||new Date().toISOString()},Q=z({state:B.state,merged:B.merged,draft:B.draft}),O=BB(B.approvals,B.changes_requested,B.reviewers.length),$=L(B.repo,B.pr_number),Z=B.merged?H:V;return Y(i,{children:[X(e,{vendor:S,title:B.repo,subtitle:Y("span",{className:"inline-flex items-center gap-1.5",children:[X(Z,{className:"w-3.5 h-3.5 inline-block"}),Y("span",{children:["#",B.pr_number," · ",B.title]})]}),status:{label:Q.label,variant:Q.dot},action:{label:"View on GitHub",href:$}}),Y("div",{className:"px-4 py-3 flex flex-col gap-3",children:[Y("div",{className:"flex items-center gap-2 text-xs",children:[X(n,{src:B.user.avatar_url,name:B.user.login,size:18}),X("span",{className:"text-text font-medium",children:B.user.login}),Y("span",{className:"text-text-dim",children:["opened ",N(B.created_at)]}),Y("span",{className:"ml-auto inline-flex items-center gap-2 tabular-nums",children:[Y("span",{className:"text-green-600 dark:text-success",children:["+",B.additions]}),Y("span",{className:"text-red-600 dark:text-error",children:["−",B.deletions]}),Y("span",{className:"text-text-dim",children:["in ",B.changed_files," file",B.changed_files===1?"":"s"]})]})]}),X(o,{items:[{label:"Status",value:Y("span",{className:"inline-flex items-center gap-2",children:[X(C,{variant:Q.variant,children:Q.label}),B.mergeable==="conflicting"&&X(C,{variant:"warn",children:"conflicts"})]})},{label:"Branch",value:Y("span",{className:"font-mono text-xs",children:[X("span",{className:"text-text",children:B.head_ref||"—"}),X("span",{className:"text-text-dim mx-1",children:"→"}),X("span",{className:"text-text-dim",children:B.base_ref})]})},...B.reviewers.length>0?[{label:"Reviewers",value:Y("span",{className:"inline-flex items-center gap-2",children:[X(c,{users:B.reviewers,size:18,max:4}),O&&X("span",{className:"text-xs text-text-dim",children:O})]})}]:[],...B.labels.length>0?[{label:"Labels",value:X("span",{className:"inline-flex flex-wrap gap-1",children:B.labels.map((T)=>X("span",{className:"text-[11px] font-medium px-1.5 py-0.5 rounded-md",style:{color:`#${T.color}`,backgroundColor:`#${T.color}1F`},children:T.name},T.name))})}]:[],{label:"Activity",value:Y("span",{className:"text-xs text-text-dim tabular-nums",children:[B.comments," comment",B.comments===1?"":"s"]})}]})]})]})}function BB(J,B,Q){if(Q===0)return"";let O=[];if(J>0)O.push(`${J} approval${J===1?"":"s"}`);if(B>0)O.push(`${B} changes requested`);if(O.length===0)O.push("no review yet");return`· ${O.join(",")}`}export{s as default};
|
|
2
|
+
|
|
3
|
+
//# debugId=3254742024EA964664756E2164756E21
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../node_modules/lucide-react/dist/esm/createLucideIcon.mjs", "../../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs", "../../../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs", "../../../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs", "../../../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs", "../../../node_modules/lucide-react/dist/esm/Icon.mjs", "../../../node_modules/lucide-react/dist/esm/defaultAttributes.mjs", "../../../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs", "../../../node_modules/lucide-react/dist/esm/context.mjs", "../../../node_modules/lucide-react/dist/esm/icons/git-merge.mjs", "../../../node_modules/lucide-react/dist/esm/icons/git-pull-request.mjs", "../../../src/ui/github/PullRequestCard.tsx", "../../../src/ui/github/lib/github.tsx"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.mjs';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.mjs';\nimport Icon from './Icon.mjs';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.mjs.map\n",
|
|
6
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.mjs.map\n",
|
|
7
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.mjs.map\n",
|
|
8
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.mjs.map\n",
|
|
9
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.mjs';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.mjs.map\n",
|
|
10
|
+
"\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.mjs';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { useLucideContext } from './context.mjs';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.mjs.map\n",
|
|
11
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n",
|
|
12
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.mjs.map\n",
|
|
13
|
+
"\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.mjs.map\n",
|
|
14
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }],\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M6 21V9a9 9 0 0 0 9 9\", key: \"7kw0sc\" }]\n];\nconst GitMerge = createLucideIcon(\"git-merge\", __iconNode);\n\nexport { __iconNode, GitMerge as default };\n//# sourceMappingURL=git-merge.mjs.map\n",
|
|
15
|
+
"/**\n * @license lucide-react v1.14.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }],\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M13 6h3a2 2 0 0 1 2 2v7\", key: \"1yeb86\" }],\n [\"line\", { x1: \"6\", x2: \"6\", y1: \"9\", y2: \"21\", key: \"rroup\" }]\n];\nconst GitPullRequest = createLucideIcon(\"git-pull-request\", __iconNode);\n\nexport { __iconNode, GitPullRequest as default };\n//# sourceMappingURL=git-pull-request.mjs.map\n",
|
|
16
|
+
"// PullRequestCard — chat-attachment card for a single GitHub PR.\n//\n// The agent passes what it just got back from the github get_pull\n// tool. Same prop-shape convention as IssueCard: each field optional,\n// each carrying just enough so the title + status + a few stats\n// render without needing a follow-up fetch.\n//\n// Composes ui-kit primitives only — Card, CardHeader, StatusPill,\n// Avatar, AvatarStack, DataList, KPI. No GitHub-specific chrome.\n\nimport { GitMerge, GitPullRequest } from \"lucide-react\";\nimport { Avatar, AvatarStack, Card, CardHeader, DataList, KPI, StatusPill } from \"@apteva/ui-kit\";\nimport {\n avatarDataUrl, githubVendor, pullRequestState, pullRequestUrl,\n shortSha, timeAgo,\n} from \"./lib/github\";\n\ninterface User { login: string; avatar_url: string; }\ninterface Label { name: string; color: string; }\n\ninterface Props {\n /**\"owner/name\" — required. */\n repo: string;\n /** Pull-request number, required. */\n pr_number: number;\n title?: string;\n state?:\"open\" |\"closed\";\n /** GitHub returns merged separately on closed PRs. */\n merged?: boolean;\n /** Draft PRs don't get the\"open\" treatment. */\n draft?: boolean;\n user_login?: string;\n user_avatar_url?: string;\n /** Comma-separated reviewer logins — terse agent calls. */\n reviewers?: string;\n /** Approval count (0+). */\n approvals?: number;\n /** Changes-requested count (0+). */\n changes_requested?: number;\n /** Comma-separated label names. */\n labels?: string;\n comments?: number;\n additions?: number;\n deletions?: number;\n changed_files?: number;\n head_ref?: string;\n base_ref?: string;\n /** Mergeable state from GitHub. */\n mergeable?:\"mergeable\" |\"conflicting\" |\"unknown\" |\"draft\";\n created_at?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewSample = {\n repo: \"acme/api\",\n pr_number: 847,\n title: \"Add idempotency keys to webhook receiver\",\n state: \"open\" as const,\n merged: false,\n draft: false,\n user: { login: \"maya\", avatar_url: avatarDataUrl(\"a78bfa\") },\n reviewers: [\n { login: \"ari\", avatar_url: avatarDataUrl(\"34d399\") },\n { login: \"lin\", avatar_url: avatarDataUrl(\"60a5fa\") },\n { login: \"soren\", avatar_url: avatarDataUrl(\"f59e0b\") },\n ],\n approvals: 1,\n changes_requested: 0,\n labels: [\n { name: \"enhancement\", color: \"0e8a16\" },\n { name: \"api\", color: \"1f6feb\" },\n { name: \"needs-tests\", color: \"fbca04\" },\n ],\n comments: 4,\n additions: 124,\n deletions: 18,\n changed_files: 7,\n head_ref: \"feature/idempotency-keys\",\n base_ref: \"main\",\n mergeable: \"mergeable\" as const,\n created_at: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),\n};\n\nexport default function PullRequestCard(props: Props) {\n const p = props.preview\n ? previewSample\n : {\n ...previewSample,\n repo: props.repo,\n pr_number: props.pr_number,\n title: props.title || `PR #${props.pr_number}`,\n state: props.state ?? \"open\",\n merged: props.merged ?? false,\n draft: props.draft ?? false,\n user: { login: props.user_login || \"\", avatar_url: props.user_avatar_url || \"\" },\n reviewers: (props.reviewers || \"\")\n .split(\",\").map((s) => s.trim()).filter(Boolean)\n .map((login) => ({ login, avatar_url: \"\" })),\n approvals: props.approvals ?? 0,\n changes_requested: props.changes_requested ?? 0,\n labels: (props.labels || \"\")\n .split(\",\").map((s) => s.trim()).filter(Boolean)\n .map((name) => ({ name, color: \"1f6feb\" })),\n comments: props.comments ?? 0,\n additions: props.additions ?? 0,\n deletions: props.deletions ?? 0,\n changed_files: props.changed_files ?? 0,\n head_ref: props.head_ref || \"\",\n base_ref: props.base_ref || \"main\",\n mergeable: props.mergeable ?? \"unknown\",\n created_at: props.created_at || new Date().toISOString(),\n };\n\n const status = pullRequestState({ state: p.state, merged: p.merged, draft: p.draft });\n const reviewSummary = reviewLine(p.approvals, p.changes_requested, p.reviewers.length);\n const url = pullRequestUrl(p.repo, p.pr_number);\n const StateIcon = p.merged ? GitMerge : GitPullRequest;\n\n return (\n <Card>\n <CardHeader\n vendor={githubVendor}\n title={p.repo}\n subtitle={\n <span className=\"inline-flex items-center gap-1.5\">\n <StateIcon className=\"w-3.5 h-3.5 inline-block\" />\n <span>#{p.pr_number} · {p.title}</span>\n </span>\n }\n status={{ label: status.label, variant: status.dot }}\n action={{ label: \"View on GitHub\", href: url }}\n />\n\n <div className=\"px-4 py-3 flex flex-col gap-3\">\n {/* author + creation time + diff stats */}\n <div className=\"flex items-center gap-2 text-xs\">\n <Avatar src={p.user.avatar_url} name={p.user.login} size={18} />\n <span className=\"text-text font-medium\">{p.user.login}</span>\n <span className=\"text-text-dim\">opened {timeAgo(p.created_at)}</span>\n <span className=\"ml-auto inline-flex items-center gap-2 tabular-nums\">\n <span className=\"text-green-600 dark:text-success\">+{p.additions}</span>\n <span className=\"text-red-600 dark:text-error\">−{p.deletions}</span>\n <span className=\"text-text-dim\">in {p.changed_files} file{p.changed_files === 1 ? \"\" :\"s\"}</span>\n </span>\n </div>\n\n <DataList\n items={[\n {\n label: \"Status\",\n value: (\n <span className=\"inline-flex items-center gap-2\">\n <StatusPill variant={status.variant}>{status.label}</StatusPill>\n {p.mergeable === \"conflicting\" && (\n <StatusPill variant=\"warn\">conflicts</StatusPill>\n )}\n </span>\n ),\n },\n {\n label: \"Branch\",\n value: (\n <span className=\"font-mono text-xs\">\n <span className=\"text-text\">{p.head_ref || \"—\"}</span>\n <span className=\"text-text-dim mx-1\">→</span>\n <span className=\"text-text-dim\">{p.base_ref}</span>\n </span>\n ),\n },\n ...(p.reviewers.length > 0\n ? [{\n label: \"Reviewers\",\n value: (\n <span className=\"inline-flex items-center gap-2\">\n <AvatarStack users={p.reviewers} size={18} max={4} />\n {reviewSummary && <span className=\"text-xs text-text-dim\">{reviewSummary}</span>}\n </span>\n ),\n }]\n : []),\n ...(p.labels.length > 0\n ? [{\n label: \"Labels\",\n value: (\n <span className=\"inline-flex flex-wrap gap-1\">\n {p.labels.map((l) => (\n <span\n key={l.name}\n className=\"text-[11px] font-medium px-1.5 py-0.5 rounded-md\"\n style={{\n color: `#${l.color}`,\n backgroundColor: `#${l.color}1F`,\n }}\n >\n {l.name}\n </span>\n ))}\n </span>\n ),\n }]\n : []),\n {\n label: \"Activity\",\n value: (\n <span className=\"text-xs text-text-dim tabular-nums\">\n {p.comments} comment{p.comments === 1 ? \"\" :\"s\"}\n </span>\n ),\n },\n ]}\n />\n </div>\n </Card>\n );\n}\n\nfunction reviewLine(approvals: number, changes: number, total: number): string {\n if (total === 0) return \"\";\n const parts: string[] = [];\n if (approvals > 0) parts.push(`${approvals} approval${approvals === 1 ? \"\" :\"s\"}`);\n if (changes > 0) parts.push(`${changes} changes requested`);\n if (parts.length === 0) parts.push(\"no review yet\");\n return `· ${parts.join(\",\")}`;\n}\n\n// Make sure shortSha stays imported when not used yet — guards\n// against linter pruning when other cards in the same lib reach\n// for it. (Compile-time only.)\nvoid shortSha;\n",
|
|
17
|
+
"// Shared helpers for every GitHub UI component.\n//\n// * githubVendor — CardHeader brand pill (logo + name + color)\n// * URL builders — repo, issue, PR, commit, workflow run, branch\n// * formatters — relative time, short sha, file-stat string\n// * status mappers — PR state → StatusPill variant, run conclusion\n// → StatusDot variant, etc.\n//\n// Mirrors the lib/hubspot.tsx pattern so any vendor lib has the\n// same shape (logo + vendor + URL helpers + status mappers + time\n// helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor, StatusDotVariant, StatusPillVariant } from \"@apteva/ui-kit\";\n\n// ─── Brand mark ───────────────────────────────────────────────────\n//\n// Octocat outline. currentColor so CardHeader's vendor pill can\n// recolor it via inline `style.color`.\n\nexport const githubLogo: ReactNode = (\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.807 1.305 3.492.998.108-.776.42-1.305.762-1.604-2.665-.305-5.466-1.334-5.466-5.93 0-1.31.467-2.38 1.235-3.22-.135-.303-.54-1.524.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.652.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.435.375.81 1.102.81 2.222 0 1.605-.015 2.898-.015 3.293 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n </svg>\n);\n\n// GitHub Mona Purple — secondary brand color, used in the vendor\n// pill and any GitHub-specific accents. Distinct from HubSpot orange\n// so two cards from different vendors read as different upstreams at\n// a glance.\nexport const GITHUB_BRAND_COLOR = \"#8957e5\";\n\nexport const githubVendor: CardVendor = {\n name: \"GitHub\",\n logo: githubLogo,\n color: GITHUB_BRAND_COLOR,\n};\n\n// ─── URL builders ─────────────────────────────────────────────────\n\nexport function repoUrl(repo: string): string {\n return `https://github.com/${repo}`;\n}\nexport function issueUrl(repo: string, number: number | string): string {\n return `https://github.com/${repo}/issues/${number}`;\n}\nexport function pullRequestUrl(repo: string, number: number | string): string {\n return `https://github.com/${repo}/pull/${number}`;\n}\nexport function commitUrl(repo: string, sha: string): string {\n return `https://github.com/${repo}/commit/${sha}`;\n}\nexport function workflowRunUrl(repo: string, run_id: number | string): string {\n return `https://github.com/${repo}/actions/runs/${run_id}`;\n}\nexport function branchUrl(repo: string, branch: string): string {\n return `https://github.com/${repo}/tree/${encodeURIComponent(branch)}`;\n}\nexport function userUrl(login: string): string {\n return `https://github.com/${login}`;\n}\n\n// ─── Formatters ───────────────────────────────────────────────────\n\n/** \"3d ago\" / \"12m ago\" / \"just now\" — coarse human-readable delta. */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Coerce ISO durations to mm:ss / hh:mm:ss. Used for run/job times. */\nexport function formatDuration(ms?: number): string {\n if (!ms || ms < 0) return \"—\";\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n const rs = s % 60;\n if (m < 60) return rs ? `${m}m ${rs}s` : `${m}m`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\n/** \"abc1234\" — 7-char short sha. Tolerates already-short input. */\nexport function shortSha(sha?: string): string {\n if (!sha) return \"\";\n return sha.length > 7 ? sha.slice(0, 7) : sha;\n}\n\n/** Test fixture helper — same shape as lib/hubspot's minusHoursISO. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// ─── Status mappers ───────────────────────────────────────────────\n\n/** PR state → StatusPill variant + label. */\nexport function pullRequestState(opts: {\n state?: \"open\" | \"closed\";\n merged?: boolean;\n draft?: boolean;\n}): { label: string; variant: StatusPillVariant; dot: StatusDotVariant } {\n if (opts.merged) return { label: \"merged\", variant: \"success\", dot: \"live\" };\n if (opts.state === \"closed\") return { label: \"closed\", variant: \"error\", dot: \"error\" };\n if (opts.draft) return { label: \"draft\", variant: \"neutral\", dot: \"muted\" };\n return { label: \"open\", variant: \"info\", dot: \"active\" };\n}\n\n/** Workflow-run status + conclusion → label/variant pair. */\nexport function runState(opts: {\n status?: string; // queued | in_progress | completed\n conclusion?: string; // success | failure | cancelled | skipped | neutral | timed_out\n}): { label: string; variant: StatusPillVariant; dot: StatusDotVariant } {\n if (opts.status === \"in_progress\") return { label: \"running\", variant: \"info\", dot: \"active\" };\n if (opts.status === \"queued\") return { label: \"queued\", variant: \"neutral\", dot: \"muted\" };\n switch (opts.conclusion) {\n case \"success\": return { label: \"success\", variant: \"success\", dot: \"live\" };\n case \"failure\": return { label: \"failed\", variant: \"error\", dot: \"error\" };\n case \"cancelled\": return { label: \"cancelled\", variant: \"neutral\", dot: \"muted\" };\n case \"skipped\": return { label: \"skipped\", variant: \"neutral\", dot: \"muted\" };\n case \"timed_out\": return { label: \"timed out\", variant: \"warn\", dot: \"warn\" };\n case \"neutral\": return { label: \"neutral\", variant: \"neutral\", dot: \"muted\" };\n default: return { label: \"—\", variant: \"neutral\", dot: \"muted\" };\n }\n}\n\n/** Job conclusion → small dot variant for inline lists. */\nexport function jobDot(conclusion?: string, status?: string): StatusDotVariant {\n if (status === \"in_progress\") return \"active\";\n if (status === \"queued\") return \"muted\";\n switch (conclusion) {\n case \"success\": return \"live\";\n case \"failure\": return \"error\";\n case \"cancelled\": return \"muted\";\n case \"skipped\": return \"muted\";\n case \"timed_out\": return \"warn\";\n default: return \"muted\";\n }\n}\n\n// ─── Mini avatar fallback (data URL) ──────────────────────────────\n//\n// IssueCard's preview avatars used inline data:image/svg+xml URLs so\n// the explorer doesn't depend on network requests. Same helper\n// reused across cards' preview samples.\n\nexport function avatarDataUrl(hexFill: string): string {\n return (\n \"data:image/svg+xml;utf8,\" +\n encodeURIComponent(\n `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='8' cy='8' r='8' fill='%23${hexFill}'/></svg>`,\n )\n );\n}\n"
|
|
18
|
+
],
|
|
19
|
+
"mappings": "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",
|
|
20
|
+
"debugId": "3254742024EA964664756E2164756E21",
|
|
21
|
+
"names": []
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
interface Job {
|
|
2
|
+
name: string;
|
|
3
|
+
status?: string;
|
|
4
|
+
conclusion?: string;
|
|
5
|
+
duration_ms?: number;
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
repo: string;
|
|
9
|
+
run_id: number;
|
|
10
|
+
workflow_name?: string;
|
|
11
|
+
status?: "queued" | "in_progress" | "completed";
|
|
12
|
+
conclusion?: "success" | "failure" | "cancelled" | "skipped" | "neutral" | "timed_out";
|
|
13
|
+
head_branch?: string;
|
|
14
|
+
head_sha?: string;
|
|
15
|
+
/** What triggered the run —"push","pull_request","schedule", etc. */
|
|
16
|
+
event?: string;
|
|
17
|
+
run_number?: number;
|
|
18
|
+
actor_login?: string;
|
|
19
|
+
actor_avatar_url?: string;
|
|
20
|
+
started_at?: string;
|
|
21
|
+
/** Total wall-clock duration in ms (server computes it). */
|
|
22
|
+
duration_ms?: number;
|
|
23
|
+
/** Either an array (preferred) or JSON-encoded string of jobs. */
|
|
24
|
+
jobs?: Job[] | string;
|
|
25
|
+
preview?: boolean;
|
|
26
|
+
projectId?: string;
|
|
27
|
+
}
|
|
28
|
+
export default function WorkflowRunCard(props: Props): import("react").JSX.Element;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=WorkflowRunCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowRunCard.d.ts","sourceRoot":"","sources":["../../../src/ui/github/WorkflowRunCard.tsx"],"names":[],"mappings":"AAgBA,UAAU,GAAG;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,KAAK;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAC,QAAQ,GAAE,aAAa,GAAE,WAAW,CAAC;IAC7C,UAAU,CAAC,EAAC,SAAS,GAAE,SAAS,GAAE,WAAW,GAAE,SAAS,GAAE,SAAS,GAAE,WAAW,CAAC;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA0BD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,KAAK,+BAqGnD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// WorkflowRunCard — single GitHub Actions run.
|
|
2
|
+
//
|
|
3
|
+
// Used after the agent pushes / re-runs / opens a PR — the operator
|
|
4
|
+
// pastes the URL and the card shows what's happening on CI without
|
|
5
|
+
// needing to load github.com. Auto-refreshes (via the host's
|
|
6
|
+
// IntegrationCard refresh_seconds prop) while status=in_progress.
|
|
7
|
+
//
|
|
8
|
+
// Job list is rendered as inline rows of [StatusDot · name · duration]
|
|
9
|
+
// — same density as the deal-stages KPI strip but vertical.
|
|
10
|
+
import { Avatar, Card, CardHeader, DataList, StatusDot, StatusPill } from "@apteva/ui-kit";
|
|
11
|
+
import { avatarDataUrl, formatDuration, githubVendor, jobDot, runState, shortSha, timeAgo, workflowRunUrl, } from "./lib/github";
|
|
12
|
+
const previewSample = {
|
|
13
|
+
repo: "acme/api",
|
|
14
|
+
run_id: 18723492,
|
|
15
|
+
workflow_name: "CI",
|
|
16
|
+
status: "in_progress",
|
|
17
|
+
conclusion: "neutral",
|
|
18
|
+
head_branch: "feature/idempotency-keys",
|
|
19
|
+
head_sha: "abc1234d5e6f7890abcdef",
|
|
20
|
+
event: "push",
|
|
21
|
+
run_number: 2841,
|
|
22
|
+
actor_login: "maya",
|
|
23
|
+
actor_avatar_url: avatarDataUrl("a78bfa"),
|
|
24
|
+
started_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
|
|
25
|
+
duration_ms: 2 * 60 * 1000,
|
|
26
|
+
jobs: [
|
|
27
|
+
{ name: "lint", status: "completed", conclusion: "success", duration_ms: 12_000 },
|
|
28
|
+
{ name: "unit", status: "completed", conclusion: "success", duration_ms: 63_000 },
|
|
29
|
+
{ name: "integration", status: "in_progress", conclusion: undefined, duration_ms: 120_000 },
|
|
30
|
+
{ name: "e2e", status: "queued", conclusion: undefined },
|
|
31
|
+
{ name: "build", status: "queued", conclusion: undefined },
|
|
32
|
+
{ name: "deploy", status: "queued", conclusion: undefined },
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
export default function WorkflowRunCard(props) {
|
|
36
|
+
const p = props.preview
|
|
37
|
+
? previewSample
|
|
38
|
+
: {
|
|
39
|
+
repo: props.repo,
|
|
40
|
+
run_id: props.run_id,
|
|
41
|
+
workflow_name: props.workflow_name || "Workflow",
|
|
42
|
+
status: props.status ?? "completed",
|
|
43
|
+
conclusion: props.conclusion ?? "neutral",
|
|
44
|
+
head_branch: props.head_branch || "main",
|
|
45
|
+
head_sha: props.head_sha || "",
|
|
46
|
+
event: props.event || "push",
|
|
47
|
+
run_number: props.run_number ?? 0,
|
|
48
|
+
actor_login: props.actor_login || "",
|
|
49
|
+
actor_avatar_url: props.actor_avatar_url || "",
|
|
50
|
+
started_at: props.started_at || new Date().toISOString(),
|
|
51
|
+
duration_ms: props.duration_ms ?? 0,
|
|
52
|
+
jobs: parseJobs(props.jobs) ?? [],
|
|
53
|
+
};
|
|
54
|
+
const overall = runState({ status: p.status, conclusion: p.conclusion });
|
|
55
|
+
const url = workflowRunUrl(p.repo, p.run_id);
|
|
56
|
+
// Rolling job tally — for the headline KPI under the title.
|
|
57
|
+
const total = p.jobs.length;
|
|
58
|
+
const done = p.jobs.filter((j) => j.status === "completed").length;
|
|
59
|
+
const tally = total > 0 ? `${done}/${total} jobs done` : null;
|
|
60
|
+
return (<Card>
|
|
61
|
+
<CardHeader vendor={githubVendor} title={`${p.repo} · ${p.workflow_name}`} subtitle={<span>
|
|
62
|
+
Run #{p.run_number} · {p.event} · <span className="font-mono">{p.head_branch}</span>
|
|
63
|
+
</span>} status={{ label: overall.label, variant: overall.dot }} action={{ label: "View run", href: url }}/>
|
|
64
|
+
|
|
65
|
+
<div className="px-4 py-3 flex flex-col gap-3">
|
|
66
|
+
{/* actor + relative time + duration */}
|
|
67
|
+
<div className="flex items-center gap-2 text-xs">
|
|
68
|
+
<Avatar src={p.actor_avatar_url} name={p.actor_login} size={18}/>
|
|
69
|
+
<span className="text-text font-medium">{p.actor_login}</span>
|
|
70
|
+
<span className="text-text-dim">triggered {timeAgo(p.started_at)}</span>
|
|
71
|
+
<span className="ml-auto text-text-dim tabular-nums">
|
|
72
|
+
{formatDuration(p.duration_ms)}
|
|
73
|
+
</span>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<DataList items={[
|
|
77
|
+
{
|
|
78
|
+
label: "Status",
|
|
79
|
+
value: (<span className="inline-flex items-center gap-2">
|
|
80
|
+
<StatusPill variant={overall.variant}>{overall.label}</StatusPill>
|
|
81
|
+
{tally && <span className="text-xs text-text-dim">{tally}</span>}
|
|
82
|
+
</span>),
|
|
83
|
+
},
|
|
84
|
+
...(p.head_sha
|
|
85
|
+
? [{
|
|
86
|
+
label: "Commit",
|
|
87
|
+
value: (<span className="font-mono text-xs">
|
|
88
|
+
<span className="text-text">{shortSha(p.head_sha)}</span>
|
|
89
|
+
<span className="text-text-dim"> · {p.head_branch}</span>
|
|
90
|
+
</span>),
|
|
91
|
+
}]
|
|
92
|
+
: []),
|
|
93
|
+
]}/>
|
|
94
|
+
|
|
95
|
+
{/* Job list — small dot + name + duration. Most CI runs have
|
|
96
|
+
6–10 jobs so this stays compact. */}
|
|
97
|
+
{p.jobs.length > 0 && (<ul className="flex flex-col divide-y divide-border-subtle border-t border-border-subtle -mx-4">
|
|
98
|
+
{p.jobs.map((j) => (<li key={j.name} className="flex items-center gap-3 px-4 py-1.5 text-xs">
|
|
99
|
+
<StatusDot variant={jobDot(j.conclusion, j.status)}>
|
|
100
|
+
{j.status === "in_progress" ? "running" : j.status === "queued" ? "queued" : (j.conclusion || "—")}
|
|
101
|
+
</StatusDot>
|
|
102
|
+
<span className="text-text font-medium font-mono">{j.name}</span>
|
|
103
|
+
<span className="ml-auto text-text-dim tabular-nums">
|
|
104
|
+
{j.status === "queued" ? "—" : formatDuration(j.duration_ms)}
|
|
105
|
+
</span>
|
|
106
|
+
</li>))}
|
|
107
|
+
</ul>)}
|
|
108
|
+
</div>
|
|
109
|
+
</Card>);
|
|
110
|
+
}
|
|
111
|
+
function parseJobs(raw) {
|
|
112
|
+
if (!raw)
|
|
113
|
+
return null;
|
|
114
|
+
if (Array.isArray(raw))
|
|
115
|
+
return raw;
|
|
116
|
+
try {
|
|
117
|
+
const parsed = JSON.parse(raw);
|
|
118
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=WorkflowRunCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowRunCard.js","sourceRoot":"","sources":["../../../src/ui/github/WorkflowRunCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{Avatar as V,Card as k,CardHeader as A,DataList as F,StatusDot as J,StatusPill as L}from"@apteva/ui-kit";import{jsx as X}from"react/jsx-runtime";var R=X("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:X("path",{d:"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.807 1.305 3.492.998.108-.776.42-1.305.762-1.604-2.665-.305-5.466-1.334-5.466-5.93 0-1.31.467-2.38 1.235-3.22-.135-.303-.54-1.524.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.652.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.435.375.81 1.102.81 2.222 0 1.605-.015 2.898-.015 3.293 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"})});var Y={name:"GitHub",logo:R,color:"#8957e5"};function Z(q,z){return`https://github.com/${q}/actions/runs/${z}`}function $(q){if(!q)return"";let z=new Date(q).getTime();if(!Number.isFinite(z))return"";let B=Math.max(0,(Date.now()-z)/1000);if(B<60)return"just now";let N=B/60;if(N<60)return`${Math.round(N)}m ago`;let O=N/60;if(O<24)return`${Math.round(O)}h ago`;let T=O/24;if(T<30)return`${Math.round(T)}d ago`;let Q=T/30;if(Q<12)return`${Math.round(Q)}mo ago`;return`${Math.round(Q/12)}y ago`}function W(q){if(!q||q<0)return"—";let z=Math.round(q/1000);if(z<60)return`${z}s`;let B=Math.floor(z/60),N=z%60;if(B<60)return N?`${B}m ${N}s`:`${B}m`;return`${Math.floor(B/60)}h ${B%60}m`}function H(q){if(!q)return"";return q.length>7?q.slice(0,7):q}function I(q){if(q.status==="in_progress")return{label:"running",variant:"info",dot:"active"};if(q.status==="queued")return{label:"queued",variant:"neutral",dot:"muted"};switch(q.conclusion){case"success":return{label:"success",variant:"success",dot:"live"};case"failure":return{label:"failed",variant:"error",dot:"error"};case"cancelled":return{label:"cancelled",variant:"neutral",dot:"muted"};case"skipped":return{label:"skipped",variant:"neutral",dot:"muted"};case"timed_out":return{label:"timed out",variant:"warn",dot:"warn"};case"neutral":return{label:"neutral",variant:"neutral",dot:"muted"};default:return{label:"—",variant:"neutral",dot:"muted"}}}function M(q,z){if(z==="in_progress")return"active";if(z==="queued")return"muted";switch(q){case"success":return"live";case"failure":return"error";case"cancelled":return"muted";case"skipped":return"muted";case"timed_out":return"warn";default:return"muted"}}function P(q){return"data:image/svg+xml;utf8,"+encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='8' cy='8' r='8' fill='%23${q}'/></svg>`)}import{jsx as E,jsxs as K}from"react/jsx-runtime";var U={repo:"acme/api",run_id:18723492,workflow_name:"CI",status:"in_progress",conclusion:"neutral",head_branch:"feature/idempotency-keys",head_sha:"abc1234d5e6f7890abcdef",event:"push",run_number:2841,actor_login:"maya",actor_avatar_url:P("a78bfa"),started_at:new Date(Date.now()-120000).toISOString(),duration_ms:120000,jobs:[{name:"lint",status:"completed",conclusion:"success",duration_ms:12000},{name:"unit",status:"completed",conclusion:"success",duration_ms:63000},{name:"integration",status:"in_progress",conclusion:void 0,duration_ms:120000},{name:"e2e",status:"queued",conclusion:void 0},{name:"build",status:"queued",conclusion:void 0},{name:"deploy",status:"queued",conclusion:void 0}]};function _(q){let z=q.preview?U:{repo:q.repo,run_id:q.run_id,workflow_name:q.workflow_name||"Workflow",status:q.status??"completed",conclusion:q.conclusion??"neutral",head_branch:q.head_branch||"main",head_sha:q.head_sha||"",event:q.event||"push",run_number:q.run_number??0,actor_login:q.actor_login||"",actor_avatar_url:q.actor_avatar_url||"",started_at:q.started_at||new Date().toISOString(),duration_ms:q.duration_ms??0,jobs:f(q.jobs)??[]},B=I({status:z.status,conclusion:z.conclusion}),N=Z(z.repo,z.run_id),O=z.jobs.length,T=z.jobs.filter((G)=>G.status==="completed").length,Q=O>0?`${T}/${O} jobs done`:null;return K(k,{children:[E(A,{vendor:Y,title:`${z.repo} · ${z.workflow_name}`,subtitle:K("span",{children:["Run #",z.run_number," · ",z.event," · ",E("span",{className:"font-mono",children:z.head_branch})]}),status:{label:B.label,variant:B.dot},action:{label:"View run",href:N}}),K("div",{className:"px-4 py-3 flex flex-col gap-3",children:[K("div",{className:"flex items-center gap-2 text-xs",children:[E(V,{src:z.actor_avatar_url,name:z.actor_login,size:18}),E("span",{className:"text-text font-medium",children:z.actor_login}),K("span",{className:"text-text-dim",children:["triggered ",$(z.started_at)]}),E("span",{className:"ml-auto text-text-dim tabular-nums",children:W(z.duration_ms)})]}),E(F,{items:[{label:"Status",value:K("span",{className:"inline-flex items-center gap-2",children:[E(L,{variant:B.variant,children:B.label}),Q&&E("span",{className:"text-xs text-text-dim",children:Q})]})},...z.head_sha?[{label:"Commit",value:K("span",{className:"font-mono text-xs",children:[E("span",{className:"text-text",children:H(z.head_sha)}),K("span",{className:"text-text-dim",children:[" · ",z.head_branch]})]})}]:[]]}),z.jobs.length>0&&E("ul",{className:"flex flex-col divide-y divide-border-subtle border-t border-border-subtle -mx-4",children:z.jobs.map((G)=>K("li",{className:"flex items-center gap-3 px-4 py-1.5 text-xs",children:[E(J,{variant:M(G.conclusion,G.status),children:G.status==="in_progress"?"running":G.status==="queued"?"queued":G.conclusion||"—"}),E("span",{className:"text-text font-medium font-mono",children:G.name}),E("span",{className:"ml-auto text-text-dim tabular-nums",children:G.status==="queued"?"—":W(G.duration_ms)})]},G.name))})]})]})}function f(q){if(!q)return null;if(Array.isArray(q))return q;try{let z=JSON.parse(q);return Array.isArray(z)?z:null}catch{return null}}export{_ as default};
|
|
2
|
+
|
|
3
|
+
//# debugId=76C3C55D07F3D19F64756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ui/github/WorkflowRunCard.tsx", "../../../src/ui/github/lib/github.tsx"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// WorkflowRunCard — single GitHub Actions run.\n//\n// Used after the agent pushes / re-runs / opens a PR — the operator\n// pastes the URL and the card shows what's happening on CI without\n// needing to load github.com. Auto-refreshes (via the host's\n// IntegrationCard refresh_seconds prop) while status=in_progress.\n//\n// Job list is rendered as inline rows of [StatusDot · name · duration]\n// — same density as the deal-stages KPI strip but vertical.\n\nimport { Avatar, Card, CardHeader, DataList, StatusDot, StatusPill } from \"@apteva/ui-kit\";\nimport {\n avatarDataUrl, formatDuration, githubVendor, jobDot, runState,\n shortSha, timeAgo, workflowRunUrl,\n} from \"./lib/github\";\n\ninterface Job {\n name: string;\n status?: string; // queued | in_progress | completed\n conclusion?: string; // success | failure | …\n duration_ms?: number;\n}\n\ninterface Props {\n repo: string;\n run_id: number;\n workflow_name?: string;\n status?:\"queued\" |\"in_progress\" |\"completed\";\n conclusion?:\"success\" |\"failure\" |\"cancelled\" |\"skipped\" |\"neutral\" |\"timed_out\";\n head_branch?: string;\n head_sha?: string;\n /** What triggered the run —\"push\",\"pull_request\",\"schedule\", etc. */\n event?: string;\n run_number?: number;\n actor_login?: string;\n actor_avatar_url?: string;\n started_at?: string;\n /** Total wall-clock duration in ms (server computes it). */\n duration_ms?: number;\n /** Either an array (preferred) or JSON-encoded string of jobs. */\n jobs?: Job[] | string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewSample: Required<Omit<Props,\"preview\" |\"projectId\">> & { jobs: Job[] } = {\n repo: \"acme/api\",\n run_id: 18723492,\n workflow_name: \"CI\",\n status: \"in_progress\",\n conclusion: \"neutral\",\n head_branch: \"feature/idempotency-keys\",\n head_sha: \"abc1234d5e6f7890abcdef\",\n event: \"push\",\n run_number: 2841,\n actor_login: \"maya\",\n actor_avatar_url: avatarDataUrl(\"a78bfa\"),\n started_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),\n duration_ms: 2 * 60 * 1000,\n jobs: [\n { name: \"lint\", status: \"completed\", conclusion: \"success\", duration_ms: 12_000 },\n { name: \"unit\", status: \"completed\", conclusion: \"success\", duration_ms: 63_000 },\n { name: \"integration\", status: \"in_progress\", conclusion: undefined, duration_ms: 120_000 },\n { name: \"e2e\", status: \"queued\", conclusion: undefined },\n { name: \"build\", status: \"queued\", conclusion: undefined },\n { name: \"deploy\", status: \"queued\", conclusion: undefined },\n ],\n};\n\nexport default function WorkflowRunCard(props: Props) {\n const p = props.preview\n ? previewSample\n : {\n repo: props.repo,\n run_id: props.run_id,\n workflow_name: props.workflow_name || \"Workflow\",\n status: props.status ?? \"completed\",\n conclusion: props.conclusion ?? \"neutral\",\n head_branch: props.head_branch || \"main\",\n head_sha: props.head_sha || \"\",\n event: props.event || \"push\",\n run_number: props.run_number ?? 0,\n actor_login: props.actor_login || \"\",\n actor_avatar_url: props.actor_avatar_url || \"\",\n started_at: props.started_at || new Date().toISOString(),\n duration_ms: props.duration_ms ?? 0,\n jobs: parseJobs(props.jobs) ?? [],\n };\n\n const overall = runState({ status: p.status, conclusion: p.conclusion });\n const url = workflowRunUrl(p.repo, p.run_id);\n\n // Rolling job tally — for the headline KPI under the title.\n const total = p.jobs.length;\n const done = p.jobs.filter((j) => j.status === \"completed\").length;\n const tally = total > 0 ? `${done}/${total} jobs done` : null;\n\n return (\n <Card>\n <CardHeader\n vendor={githubVendor}\n title={`${p.repo} · ${p.workflow_name}`}\n subtitle={\n <span>\n Run #{p.run_number} · {p.event} · <span className=\"font-mono\">{p.head_branch}</span>\n </span>\n }\n status={{ label: overall.label, variant: overall.dot }}\n action={{ label: \"View run\", href: url }}\n />\n\n <div className=\"px-4 py-3 flex flex-col gap-3\">\n {/* actor + relative time + duration */}\n <div className=\"flex items-center gap-2 text-xs\">\n <Avatar src={p.actor_avatar_url} name={p.actor_login} size={18} />\n <span className=\"text-text font-medium\">{p.actor_login}</span>\n <span className=\"text-text-dim\">triggered {timeAgo(p.started_at)}</span>\n <span className=\"ml-auto text-text-dim tabular-nums\">\n {formatDuration(p.duration_ms)}\n </span>\n </div>\n\n <DataList\n items={[\n {\n label: \"Status\",\n value: (\n <span className=\"inline-flex items-center gap-2\">\n <StatusPill variant={overall.variant}>{overall.label}</StatusPill>\n {tally && <span className=\"text-xs text-text-dim\">{tally}</span>}\n </span>\n ),\n },\n ...(p.head_sha\n ? [{\n label: \"Commit\",\n value: (\n <span className=\"font-mono text-xs\">\n <span className=\"text-text\">{shortSha(p.head_sha)}</span>\n <span className=\"text-text-dim\"> · {p.head_branch}</span>\n </span>\n ),\n }]\n : []),\n ]}\n />\n\n {/* Job list — small dot + name + duration. Most CI runs have\n 6–10 jobs so this stays compact. */}\n {p.jobs.length > 0 && (\n <ul className=\"flex flex-col divide-y divide-border-subtle border-t border-border-subtle -mx-4\">\n {p.jobs.map((j) => (\n <li\n key={j.name}\n className=\"flex items-center gap-3 px-4 py-1.5 text-xs\"\n >\n <StatusDot variant={jobDot(j.conclusion, j.status)}>\n {j.status === \"in_progress\" ? \"running\" : j.status === \"queued\" ? \"queued\" : (j.conclusion || \"—\")}\n </StatusDot>\n <span className=\"text-text font-medium font-mono\">{j.name}</span>\n <span className=\"ml-auto text-text-dim tabular-nums\">\n {j.status === \"queued\" ? \"—\" : formatDuration(j.duration_ms)}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </Card>\n );\n}\n\nfunction parseJobs(raw: Job[] | string | undefined): Job[] | null {\n if (!raw) return null;\n if (Array.isArray(raw)) return raw;\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n",
|
|
6
|
+
"// Shared helpers for every GitHub UI component.\n//\n// * githubVendor — CardHeader brand pill (logo + name + color)\n// * URL builders — repo, issue, PR, commit, workflow run, branch\n// * formatters — relative time, short sha, file-stat string\n// * status mappers — PR state → StatusPill variant, run conclusion\n// → StatusDot variant, etc.\n//\n// Mirrors the lib/hubspot.tsx pattern so any vendor lib has the\n// same shape (logo + vendor + URL helpers + status mappers + time\n// helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor, StatusDotVariant, StatusPillVariant } from \"@apteva/ui-kit\";\n\n// ─── Brand mark ───────────────────────────────────────────────────\n//\n// Octocat outline. currentColor so CardHeader's vendor pill can\n// recolor it via inline `style.color`.\n\nexport const githubLogo: ReactNode = (\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.807 1.305 3.492.998.108-.776.42-1.305.762-1.604-2.665-.305-5.466-1.334-5.466-5.93 0-1.31.467-2.38 1.235-3.22-.135-.303-.54-1.524.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.652.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.435.375.81 1.102.81 2.222 0 1.605-.015 2.898-.015 3.293 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n </svg>\n);\n\n// GitHub Mona Purple — secondary brand color, used in the vendor\n// pill and any GitHub-specific accents. Distinct from HubSpot orange\n// so two cards from different vendors read as different upstreams at\n// a glance.\nexport const GITHUB_BRAND_COLOR = \"#8957e5\";\n\nexport const githubVendor: CardVendor = {\n name: \"GitHub\",\n logo: githubLogo,\n color: GITHUB_BRAND_COLOR,\n};\n\n// ─── URL builders ─────────────────────────────────────────────────\n\nexport function repoUrl(repo: string): string {\n return `https://github.com/${repo}`;\n}\nexport function issueUrl(repo: string, number: number | string): string {\n return `https://github.com/${repo}/issues/${number}`;\n}\nexport function pullRequestUrl(repo: string, number: number | string): string {\n return `https://github.com/${repo}/pull/${number}`;\n}\nexport function commitUrl(repo: string, sha: string): string {\n return `https://github.com/${repo}/commit/${sha}`;\n}\nexport function workflowRunUrl(repo: string, run_id: number | string): string {\n return `https://github.com/${repo}/actions/runs/${run_id}`;\n}\nexport function branchUrl(repo: string, branch: string): string {\n return `https://github.com/${repo}/tree/${encodeURIComponent(branch)}`;\n}\nexport function userUrl(login: string): string {\n return `https://github.com/${login}`;\n}\n\n// ─── Formatters ───────────────────────────────────────────────────\n\n/** \"3d ago\" / \"12m ago\" / \"just now\" — coarse human-readable delta. */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Coerce ISO durations to mm:ss / hh:mm:ss. Used for run/job times. */\nexport function formatDuration(ms?: number): string {\n if (!ms || ms < 0) return \"—\";\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n const rs = s % 60;\n if (m < 60) return rs ? `${m}m ${rs}s` : `${m}m`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\n/** \"abc1234\" — 7-char short sha. Tolerates already-short input. */\nexport function shortSha(sha?: string): string {\n if (!sha) return \"\";\n return sha.length > 7 ? sha.slice(0, 7) : sha;\n}\n\n/** Test fixture helper — same shape as lib/hubspot's minusHoursISO. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// ─── Status mappers ───────────────────────────────────────────────\n\n/** PR state → StatusPill variant + label. */\nexport function pullRequestState(opts: {\n state?: \"open\" | \"closed\";\n merged?: boolean;\n draft?: boolean;\n}): { label: string; variant: StatusPillVariant; dot: StatusDotVariant } {\n if (opts.merged) return { label: \"merged\", variant: \"success\", dot: \"live\" };\n if (opts.state === \"closed\") return { label: \"closed\", variant: \"error\", dot: \"error\" };\n if (opts.draft) return { label: \"draft\", variant: \"neutral\", dot: \"muted\" };\n return { label: \"open\", variant: \"info\", dot: \"active\" };\n}\n\n/** Workflow-run status + conclusion → label/variant pair. */\nexport function runState(opts: {\n status?: string; // queued | in_progress | completed\n conclusion?: string; // success | failure | cancelled | skipped | neutral | timed_out\n}): { label: string; variant: StatusPillVariant; dot: StatusDotVariant } {\n if (opts.status === \"in_progress\") return { label: \"running\", variant: \"info\", dot: \"active\" };\n if (opts.status === \"queued\") return { label: \"queued\", variant: \"neutral\", dot: \"muted\" };\n switch (opts.conclusion) {\n case \"success\": return { label: \"success\", variant: \"success\", dot: \"live\" };\n case \"failure\": return { label: \"failed\", variant: \"error\", dot: \"error\" };\n case \"cancelled\": return { label: \"cancelled\", variant: \"neutral\", dot: \"muted\" };\n case \"skipped\": return { label: \"skipped\", variant: \"neutral\", dot: \"muted\" };\n case \"timed_out\": return { label: \"timed out\", variant: \"warn\", dot: \"warn\" };\n case \"neutral\": return { label: \"neutral\", variant: \"neutral\", dot: \"muted\" };\n default: return { label: \"—\", variant: \"neutral\", dot: \"muted\" };\n }\n}\n\n/** Job conclusion → small dot variant for inline lists. */\nexport function jobDot(conclusion?: string, status?: string): StatusDotVariant {\n if (status === \"in_progress\") return \"active\";\n if (status === \"queued\") return \"muted\";\n switch (conclusion) {\n case \"success\": return \"live\";\n case \"failure\": return \"error\";\n case \"cancelled\": return \"muted\";\n case \"skipped\": return \"muted\";\n case \"timed_out\": return \"warn\";\n default: return \"muted\";\n }\n}\n\n// ─── Mini avatar fallback (data URL) ──────────────────────────────\n//\n// IssueCard's preview avatars used inline data:image/svg+xml URLs so\n// the explorer doesn't depend on network requests. Same helper\n// reused across cards' preview samples.\n\nexport function avatarDataUrl(hexFill: string): string {\n return (\n \"data:image/svg+xml;utf8,\" +\n encodeURIComponent(\n `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='8' cy='8' r='8' fill='%23${hexFill}'/></svg>`,\n )\n );\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "76C3C55D07F3D19F64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { CardVendor, StatusDotVariant, StatusPillVariant } from "@apteva/ui-kit";
|
|
3
|
+
export declare const githubLogo: ReactNode;
|
|
4
|
+
export declare const GITHUB_BRAND_COLOR = "#8957e5";
|
|
5
|
+
export declare const githubVendor: CardVendor;
|
|
6
|
+
export declare function repoUrl(repo: string): string;
|
|
7
|
+
export declare function issueUrl(repo: string, number: number | string): string;
|
|
8
|
+
export declare function pullRequestUrl(repo: string, number: number | string): string;
|
|
9
|
+
export declare function commitUrl(repo: string, sha: string): string;
|
|
10
|
+
export declare function workflowRunUrl(repo: string, run_id: number | string): string;
|
|
11
|
+
export declare function branchUrl(repo: string, branch: string): string;
|
|
12
|
+
export declare function userUrl(login: string): string;
|
|
13
|
+
/** "3d ago" / "12m ago" / "just now" — coarse human-readable delta. */
|
|
14
|
+
export declare function timeAgo(iso?: string): string;
|
|
15
|
+
/** Coerce ISO durations to mm:ss / hh:mm:ss. Used for run/job times. */
|
|
16
|
+
export declare function formatDuration(ms?: number): string;
|
|
17
|
+
/** "abc1234" — 7-char short sha. Tolerates already-short input. */
|
|
18
|
+
export declare function shortSha(sha?: string): string;
|
|
19
|
+
/** Test fixture helper — same shape as lib/hubspot's minusHoursISO. */
|
|
20
|
+
export declare function minusHoursISO(h: number): string;
|
|
21
|
+
/** PR state → StatusPill variant + label. */
|
|
22
|
+
export declare function pullRequestState(opts: {
|
|
23
|
+
state?: "open" | "closed";
|
|
24
|
+
merged?: boolean;
|
|
25
|
+
draft?: boolean;
|
|
26
|
+
}): {
|
|
27
|
+
label: string;
|
|
28
|
+
variant: StatusPillVariant;
|
|
29
|
+
dot: StatusDotVariant;
|
|
30
|
+
};
|
|
31
|
+
/** Workflow-run status + conclusion → label/variant pair. */
|
|
32
|
+
export declare function runState(opts: {
|
|
33
|
+
status?: string;
|
|
34
|
+
conclusion?: string;
|
|
35
|
+
}): {
|
|
36
|
+
label: string;
|
|
37
|
+
variant: StatusPillVariant;
|
|
38
|
+
dot: StatusDotVariant;
|
|
39
|
+
};
|
|
40
|
+
/** Job conclusion → small dot variant for inline lists. */
|
|
41
|
+
export declare function jobDot(conclusion?: string, status?: string): StatusDotVariant;
|
|
42
|
+
export declare function avatarDataUrl(hexFill: string): string;
|
|
43
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../../src/ui/github/lib/github.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOtF,eAAO,MAAM,UAAU,EAAE,SAIxB,CAAC;AAMF,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,eAAO,MAAM,YAAY,EAAE,UAI1B,CAAC;AAIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEtE;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5E;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5E;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AACD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7C;AAID,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAW5C;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CASlD;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAID,6CAA6C;AAC7C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,GAAG,EAAE,gBAAgB,CAAA;CAAE,CAKvE;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,GAAG,EAAE,gBAAgB,CAAA;CAAE,CAYvE;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAW7E;AAQD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOrD"}
|