Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3a552a4
feat(marketing): redesign website and product showcase
maria-rcks Jul 30, 2026
cc2fa0b
docs: link mobile app downloads in README
maria-rcks Jul 30, 2026
b88912f
fix(marketing): address site review feedback
maria-rcks Jul 30, 2026
cc1b7b1
fix(marketing): address follow-up review feedback
maria-rcks Jul 30, 2026
4a8f40c
fix(marketing): address latest review findings
maria-rcks Jul 30, 2026
7f7d1c7
fix(marketing): align demo state mutations
maria-rcks Jul 30, 2026
30dfba2
fix(marketing): report blocked demo deletes
maria-rcks Jul 30, 2026
c6d9103
fix(marketing): resolve latest review feedback
maria-rcks Jul 30, 2026
fbcdbd9
fix(web): preserve demo catalog during seed migration
maria-rcks Jul 30, 2026
03ad061
fix(web): harden demo state recovery
maria-rcks Jul 30, 2026
612837c
fix(web): migrate legacy demo seed markers
maria-rcks Jul 30, 2026
e664383
fix(web): prefer current demo seed marker
maria-rcks Jul 30, 2026
86b5c28
Merge branch 'main' into fix/new-marketing-website
maria-rcks Jul 31, 2026
1f1d583
fix(marketing): rewrite the slop answers a bit
maria-rcks Jul 31, 2026
800d9ee
Merge branch 'main' into fix/new-marketing-website
maria-rcks Jul 31, 2026
0df16ea
fix(web): restore live channel switching in the marketing demo
maria-rcks Jul 31, 2026
c78df09
fix(marketing): keep device previews with the hero demo
maria-rcks Jul 31, 2026
ba2b3ed
fix(marketing): wait for hero store images before is-loaded
maria-rcks Jul 31, 2026
a32d658
fix(marketing): polish mobile website experience
shivamhwp Aug 1, 2026
c29d56a
fix(marketing): make agent support unmistakable
shivamhwp Aug 1, 2026
e96b0bb
fix(marketing): tighten hero intro
shivamhwp Aug 1, 2026
be2cf81
feat(marketing): explore five hero directions
shivamhwp Aug 1, 2026
8728406
feat(marketing): show product promises visually
shivamhwp Aug 1, 2026
9c752c9
feat(marketing): give each hero direction its own world
shivamhwp Aug 1, 2026
25eaf62
feat(marketing): show agents across every screen
shivamhwp Aug 3, 2026
eb1f024
feat(marketing): brand T3 Connect and settle the hero on version 1
shivamhwp Aug 3, 2026
b57c453
feat(marketing): retell T3 Connect as one switch and paired screens
shivamhwp Aug 3, 2026
3e799b7
feat(marketing): polish T3 Connect beams, copy, and stage-aware backdrop
shivamhwp Aug 3, 2026
7012855
fix(marketing): quiet the connect scene and boot the full hero demo
shivamhwp Aug 3, 2026
13c7c3b
fix(marketing): drop the purple glow behind the T3 Connect scene
shivamhwp Aug 3, 2026
37bd394
chore(marketing): strip dead variant-4 hero CSS
shivamhwp Aug 3, 2026
f52b5aa
refactor(marketing): make T3 Connect a normal static section
shivamhwp Aug 4, 2026
1b6995e
feat(marketing): stretch the T3 Connect fan across the container
shivamhwp Aug 4, 2026
e4d4592
feat(marketing): present T3 Connect as a showcase row with an entranc…
shivamhwp Aug 4, 2026
cc0a33d
feat(marketing): flow signals down the connect beams and flip the col…
shivamhwp Aug 4, 2026
e753967
fix(marketing): make the connect line signals barely-there
shivamhwp Aug 4, 2026
bd980eb
fix(marketing): play the connect signal once, then rest
shivamhwp Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions .github/workflows/mobile-showcase-screenshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
if: inputs.platform == 'all' || inputs.platform == 'ios'
runs-on: blacksmith-12vcpu-macos-26
timeout-minutes: 60
outputs:
artifact_id: ${{ steps.upload_ios.outputs.artifact-id }}
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -68,6 +70,7 @@ jobs:
run: pnpm screenshots:mobile --platform ios --appearance "${{ inputs.appearance }}" --validate-only

- name: Upload iOS screenshots
id: upload_ios
if: always()
uses: actions/upload-artifact@v7
with:
Expand All @@ -76,11 +79,160 @@ jobs:
if-no-files-found: warn
retention-days: 14

publish_marketing_preview:
name: Publish marketing mobile preview
if: |
always() &&
needs.ios.result == 'success' &&
needs.android.result == 'success' &&
inputs.platform == 'all' &&
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) &&
inputs.appearance != 'light'
needs: [ios, android]
runs-on: blacksmith-8vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- id: app_token
name: Mint release app token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

- name: Checkout default branch
uses: actions/checkout@v6
with:
ref: ${{ github.event.repository.default_branch }}
fetch-depth: 0
token: ${{ steps.app_token.outputs.token }}
persist-credentials: true
Comment on lines +104 to +109

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium workflows/mobile-showcase-screenshots.yml:104

publish_marketing_preview checks out the latest default branch instead of the ${{ github.sha }} used by the iOS and Android capture jobs. When the default branch advances during the capture jobs, this job commits the older revision's screenshots into the newer branch, overwriting the current preview assets with stale output.

The capture jobs build and screenshot the code at ${{ github.sha }}, but publish_marketing_preview checks out ${{ github.event.repository.default_branch }} and pushes the generated screenshots there. Checkout ${{ github.sha }} instead so the screenshots are committed to the same revision that produced them.

       - name: Checkout default branch
         uses: actions/checkout@v6
         with:
-          ref: ${{ github.event.repository.default_branch }}
+          ref: ${{ github.sha }}
           fetch-depth: 0
           token: ${{ steps.app_token.outputs.token }}
           persist-credentials: true
🤖 Copy this AI Prompt to have your agent fix this:
In file @.github/workflows/mobile-showcase-screenshots.yml around lines 104-109:

`publish_marketing_preview` checks out the latest default branch instead of the `${{ github.sha }}` used by the iOS and Android capture jobs. When the default branch advances during the capture jobs, this job commits the older revision's screenshots into the newer branch, overwriting the current preview assets with stale output.

The capture jobs build and screenshot the code at `${{ github.sha }}`, but `publish_marketing_preview` checks out `${{ github.event.repository.default_branch }}` and pushes the generated screenshots there. Checkout `${{ github.sha }}` instead so the screenshots are committed to the same revision that produced them.

Comment thread
cursor[bot] marked this conversation as resolved.

- name: Download iOS screenshots
uses: actions/download-artifact@v8
with:
name: app-store-connect-screenshots
path: ${{ runner.temp }}/mobile-showcase

- name: Download Android screenshots
uses: actions/download-artifact@v8
with:
name: google-play-screenshots
path: ${{ runner.temp }}/mobile-showcase

- id: app_bot
name: Resolve GitHub App bot identity
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
APP_SLUG: ${{ steps.app_token.outputs.app-slug }}
run: |
user_id="$(gh api "/users/${APP_SLUG}[bot]" --jq .id)"
echo "name=${APP_SLUG}[bot]" >> "$GITHUB_OUTPUT"
echo "email=${user_id}+${APP_SLUG}[bot]@users.noreply.github.com" >> "$GITHUB_OUTPUT"

- id: preview
name: Update website preview asset
env:
IOS_ARTIFACT_ID: ${{ needs.ios.outputs.artifact_id }}
ANDROID_ARTIFACT_ID: ${{ needs.android.outputs.artifact_id }}
HEAD_SHA: ${{ github.sha }}
RUN_ID: ${{ github.run_id }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
WORKFLOW_NAME: ${{ github.workflow }}
run: |
output_directory="apps/marketing/public/mobile-states"
declare -A preview_sources=(
["threads.png"]="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/threads.png"
["ipad-threads.png"]="$RUNNER_TEMP/mobile-showcase/ipad-13/dark/threads.png"
["ios-thread.png"]="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/thread.png"
["ios-terminal.png"]="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/terminal.png"
["ios-review.png"]="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/review.png"
["ios-environments.png"]="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/environments.png"
["android-threads.png"]="$RUNNER_TEMP/mobile-showcase/phone/dark/threads.png"
["android-thread.png"]="$RUNNER_TEMP/mobile-showcase/phone/dark/thread.png"
["android-terminal.png"]="$RUNNER_TEMP/mobile-showcase/phone/dark/terminal.png"
["android-review.png"]="$RUNNER_TEMP/mobile-showcase/phone/dark/review.png"
["android-environments.png"]="$RUNNER_TEMP/mobile-showcase/phone/dark/environments.png"
)

for output_name in "${!preview_sources[@]}"; do
source_path="${preview_sources[$output_name]}"
if [[ ! -f "$source_path" ]]; then
echo "Missing expected website preview source: $source_path" >&2
exit 1
fi
done

changed=false
for output_name in "${!preview_sources[@]}"; do
source_path="${preview_sources[$output_name]}"
output_path="$output_directory/$output_name"
if [[ ! -f "$output_path" ]] || ! cmp --silent "$source_path" "$output_path"; then
changed=true
break
fi
done

if [[ "$changed" == "false" ]]; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "Website previews already match the generated screenshots."
exit 0
fi

mkdir -p "$output_directory"
for output_name in "${!preview_sources[@]}"; do
cp "${preview_sources[$output_name]}" "$output_directory/$output_name"
done
node --input-type=module <<'NODE'
import { writeFile } from "node:fs/promises";

const metadata = {
artifacts: [
{
id: Number(process.env.IOS_ARTIFACT_ID),
name: "app-store-connect-screenshots",
},
{
id: Number(process.env.ANDROID_ARTIFACT_ID),
name: "google-play-screenshots",
},
],
artifactCreatedAt: new Date().toISOString(),
runId: Number(process.env.RUN_ID),
runUrl: process.env.RUN_URL,
headSha: process.env.HEAD_SHA,
workflow: process.env.WORKFLOW_NAME,
devices: ["iphone-6.9", "ipad-13", "pixel"],
scenes: ["thread", "terminal", "review", "threads", "environments"],
appearance: "dark",
};

await writeFile(
"apps/marketing/public/mobile-states/source.json",
`${JSON.stringify(metadata, null, 2)}\n`,
);
NODE
echo "changed=true" >> "$GITHUB_OUTPUT"

- name: Commit website preview
if: steps.preview.outputs.changed == 'true'
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
git config user.name "${{ steps.app_bot.outputs.name }}"
git config user.email "${{ steps.app_bot.outputs.email }}"
git add apps/marketing/public/mobile-states
git commit -m "chore(marketing): refresh mobile showcase screenshot"
git pull --rebase origin "$DEFAULT_BRANCH"
git push origin "HEAD:$DEFAULT_BRANCH"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preview commit lacks conflict handling

Medium Severity

The marketing preview commit runs git pull --rebase then git push with no retry or merge fallback. A concurrent push to the same mobile-states paths (another workflow run or manual commit) can leave the rebase failed and the job red without updated previews.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eb1f024. Configure here.


android:
name: Android phone, 7-inch tablet, and 10-inch tablet
if: inputs.platform == 'all' || inputs.platform == 'android'
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 60
outputs:
artifact_id: ${{ steps.upload_android.outputs.artifact-id }}
env:
T3_SHOWCASE_ANDROID_ABI: x86_64
steps:
Expand Down Expand Up @@ -143,6 +295,7 @@ jobs:
run: pnpm screenshots:mobile --platform android --appearance "${{ inputs.appearance }}" --validate-only

- name: Upload Android screenshots
id: upload_android
if: always()
uses: actions/upload-artifact@v7
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules
*.log
*.tsbuildinfo
apps/*/dist
apps/marketing/public/sidebar-demo
infra/*/dist
.astro
packages/*/dist
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ This will launch T3 Code's backend on your machine as well as the local web app

Tip: Use `npx t3@latest --help` for the full CLI reference.

### Mobile apps

Control your T3 Code environments from your phone or tablet:

- [Download for iPhone and iPad on the App Store](https://apps.apple.com/us/app/t3-code-remote-claude-more/id6787819824)
- [Get the Android app on Google Play](https://play.google.com/store/apps/details?id=com.t3tools.t3code)

### Desktop app

Install the latest version of the desktop app from [GitHub Releases](https://github.com/pingdotgg/t3code/releases), or from your favorite package registry:
Expand Down
21 changes: 21 additions & 0 deletions apps/marketing/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
import { defineConfig } from "astro/config";

const cacheSidebarDemoAssets = {
name: "cache-sidebar-demo-assets",
configureServer(server) {
server.middlewares.use((request, response, next) => {
if (request.url?.startsWith("/sidebar-demo/assets/")) {
response.setHeader("Cache-Control", "public, max-age=31536000, immutable");
} else if (
request.url?.startsWith("/demo-states/") ||
request.url?.startsWith("/mobile-states/")
) {
response.setHeader("Cache-Control", "public, max-age=3600, stale-while-revalidate=86400");
}
next();
});
},
};

export default defineConfig({
site: "https://t3.codes",
server: {
port: Number(process.env.PORT ?? 4173),
},
vite: {
plugins: [cacheSidebarDemoAssets],
},
});
7 changes: 5 additions & 2 deletions apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"dev": "npm run prepare:assets && astro dev",
"build": "npm run prepare:assets && astro build",
"prepare:assets": "npm run build:sidebar-demo",
"build:sidebar-demo": "npm run --prefix ../web build:sidebar-demo && node scripts/capture-demo-screenshots.mjs",
"preview": "astro preview",
"typecheck": "astro check"
},
Expand All @@ -16,6 +18,7 @@
"devDependencies": {
"@astrojs/check": "^0.9.7",
"@vercel/config": "^0.3.0",
"playwright-core": "1.60.0",
"typescript": "catalog:"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 16 additions & 1 deletion apps/marketing/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions apps/marketing/public/mobile-states/source.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"artifacts": [
{
"id": 8791333399,
"name": "app-store-connect-screenshots"
},
{
"id": 8791283952,
"name": "google-play-screenshots"
}
],
"artifactCreatedAt": "2026-07-31T10:54:46Z",
"runId": 30625175356,
"runUrl": "https://github.com/pingdotgg/t3code/actions/runs/30625175356",
"headSha": "0647dbc12be4e83b95337eb0bccbeaa982967d39",
"workflow": "mobile-showcase-screenshots.yml",
"devices": ["iphone-6.9", "ipad-13", "pixel"],
"scenes": ["thread", "terminal", "review", "threads", "environments"],
"appearance": "dark"
}
Binary file added apps/marketing/public/mobile-states/threads.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/marketing/public/nightly-clouds.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions apps/marketing/public/nightly-stars.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/marketing/public/og-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/marketing/public/og-source.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/marketing/public/store-logos/appstore.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/marketing/public/store-logos/googleplay.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading