Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 116 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 All @@ -59,6 +61,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 @@ -67,6 +70,119 @@ jobs:
if-no-files-found: warn
retention-days: 14

publish_marketing_preview:
name: Publish marketing mobile preview
if: |
always() &&
needs.ios.result == 'success' &&
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) &&
inputs.appearance != 'light'
needs: ios
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

- name: Download iOS screenshots
uses: actions/download-artifact@v8
with:
name: app-store-connect-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:
ARTIFACT_ID: ${{ needs.ios.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: |
phone_source_path="$RUNNER_TEMP/mobile-showcase/iphone-6.9/dark/threads.png"
tablet_source_path="$RUNNER_TEMP/mobile-showcase/ipad-13/dark/threads.png"
output_directory="apps/marketing/public/mobile-states"
phone_output_path="$output_directory/threads.png"
tablet_output_path="$output_directory/ipad-threads.png"

if [[ ! -f "$phone_source_path" || ! -f "$tablet_source_path" ]]; then
echo "Missing expected website preview source." >&2
echo "Phone: $phone_source_path" >&2
echo "Tablet: $tablet_source_path" >&2
exit 1
fi

if [[ -f "$phone_output_path" && -f "$tablet_output_path" ]] &&
cmp --silent "$phone_source_path" "$phone_output_path" &&
cmp --silent "$tablet_source_path" "$tablet_output_path"; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "Website previews already match the generated screenshots."
exit 0
fi

mkdir -p "$output_directory"
cp "$phone_source_path" "$phone_output_path"
cp "$tablet_source_path" "$tablet_output_path"
node --input-type=module <<'NODE'
import { writeFile } from "node:fs/promises";

const metadata = {
artifactId: Number(process.env.ARTIFACT_ID),
artifactName: "app-store-connect-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"],
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/source.json \
apps/marketing/public/mobile-states/threads.png \
apps/marketing/public/mobile-states/ipad-threads.png
git commit -m "chore(marketing): refresh mobile showcase screenshot"
git pull --rebase origin "$DEFAULT_BRANCH"
git push origin "HEAD:$DEFAULT_BRANCH"

android:
name: Android phone, 7-inch tablet, and 10-inch tablet
if: inputs.platform == 'all' || inputs.platform == 'android'
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
8 changes: 8 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 Expand Up @@ -66,6 +73,7 @@ There's no public docs site yet, checkout the miscellaneous markdown files in [d
## Documentation

- [Getting started](./docs/getting-started/quick-start.md)
- [Mobile app](./docs/user/mobile-app.md)
- [Remote access](./docs/user/remote-access.md)
- [Keeping T3 Code in sync](./docs/user/server-updates.md)
- [Architecture overview](./docs/architecture/overview.md)
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.
11 changes: 11 additions & 0 deletions apps/marketing/public/mobile-states/source.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"artifactId": 8683082605,
"artifactName": "app-store-connect-screenshots",
"artifactCreatedAt": "2026-07-28T09:24:29Z",
"runId": 30345538492,
"runUrl": "https://github.com/pingdotgg/t3code/actions/runs/30345538492",
"headSha": "d25b15737a058614ab6632bbad23d2497e49b62c",
"workflow": "mobile-showcase-screenshots.yml",
"devices": ["iphone-6.9", "ipad-13"],
"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