| author | |
| committer | |
| log | 748203ea19fb68741709614b33b305079f0f4c05 |
| tree | b7fac98d1946830bac322805ca8991eaaed8d1b0 |
| parent | b125b7635170ec0c33f8ddf39299155a21f8c9b9 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>5 files changed, 70 insertions(+), 4 deletions(-)
README.md+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # T3 Code | 1 | # T3 Code |
| 2 | 2 | ||
| 3 | T3 Code is an "agent harness control surface". It enables control of the agents on your machine with a best-in-class mobile app, [web app](https://app.t3.codes) and [Electron-based desktop app](https://t3.codes). | 3 | T3 Code is an "agent harness control surface". It enables control of the agents on your machine with a best-in-class mobile app ([iOS](https://apps.apple.com/us/app/t3-code-remote-claude-more/id6787819824), [Android](https://play.google.com/store/apps/details?id=com.t3tools.t3code)), [web app](https://app.t3.codes) and [Electron-based desktop app](https://t3.codes). |
| 4 | 4 | ||
| 5 | Works with your subscriptions on Claude Code, Codex, Cursor, Grok Build, and OpenCode. If they're set up on your computer, T3 Code can control them. | 5 | Works with your subscriptions on Claude Code, Codex, Cursor, Grok Build, and OpenCode. If they're set up on your computer, T3 Code can control them. |
| 6 | 6 |
apps/marketing/src/layouts/Layout.astro+8-1| ... | @@ -1,5 +1,10 @@ | ... | @@ -1,5 +1,10 @@ |
| 1 | --- | 1 | --- |
| 2 | import { GITHUB_REPOSITORY_URL, MARKETING_STATS } from "../lib/site"; | 2 | import { |
| 3 | ANDROID_PLAY_STORE_URL, | ||
| 4 | GITHUB_REPOSITORY_URL, | ||
| 5 | IOS_APP_STORE_URL, | ||
| 6 | MARKETING_STATS, | ||
| 7 | } from "../lib/site"; | ||
| 3 | 8 | ||
| 4 | interface Props { | 9 | interface Props { |
| 5 | title?: string; | 10 | title?: string; |
| ... | @@ -69,6 +74,8 @@ const { | ... | @@ -69,6 +74,8 @@ const { |
| 69 | <a href={GITHUB_REPOSITORY_URL} target="_blank" rel="noopener noreferrer">GitHub</a> | 74 | <a href={GITHUB_REPOSITORY_URL} target="_blank" rel="noopener noreferrer">GitHub</a> |
| 70 | <a href="https://discord.gg/jn4EGJjrvv" target="_blank" rel="noopener noreferrer">Discord</a> | 75 | <a href="https://discord.gg/jn4EGJjrvv" target="_blank" rel="noopener noreferrer">Discord</a> |
| 71 | <a href="/download">Download</a> | 76 | <a href="/download">Download</a> |
| 77 | <a href={IOS_APP_STORE_URL} target="_blank" rel="noopener noreferrer">iOS app</a> | ||
| 78 | <a href={ANDROID_PLAY_STORE_URL} target="_blank" rel="noopener noreferrer">Android app</a> | ||
| 72 | <a href="/terms-of-service">Terms</a> | 79 | <a href="/terms-of-service">Terms</a> |
| 73 | <a href="/privacy-policy">Privacy</a> | 80 | <a href="/privacy-policy">Privacy</a> |
| 74 | <a href="/security-policy">Security</a> | 81 | <a href="/security-policy">Security</a> |
apps/marketing/src/lib/site.ts+6| ... | @@ -1,5 +1,11 @@ | ... | @@ -1,5 +1,11 @@ |
| 1 | export const GITHUB_REPOSITORY_URL = "https://github.com/pingdotgg/t3code"; | 1 | export const GITHUB_REPOSITORY_URL = "https://github.com/pingdotgg/t3code"; |
| 2 | 2 | ||
| 3 | export const IOS_APP_STORE_URL = | ||
| 4 | "https://apps.apple.com/us/app/t3-code-remote-claude-more/id6787819824"; | ||
| 5 | |||
| 6 | export const ANDROID_PLAY_STORE_URL = | ||
| 7 | "https://play.google.com/store/apps/details?id=com.t3tools.t3code"; | ||
| 8 | |||
| 3 | export const MARKETING_STATS = { | 9 | export const MARKETING_STATS = { |
| 4 | githubStars: "14k+", | 10 | githubStars: "14k+", |
| 5 | users: "100,000", | 11 | users: "100,000", |
apps/marketing/src/pages/download.astro+21-1| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | --- | 1 | --- |
| 2 | import Layout from "../layouts/Layout.astro"; | 2 | import Layout from "../layouts/Layout.astro"; |
| 3 | import { RELEASES_URL } from "../lib/releases"; | 3 | import { RELEASES_URL } from "../lib/releases"; |
| 4 | import { ANDROID_PLAY_STORE_URL, IOS_APP_STORE_URL } from "../lib/site"; | ||
| 4 | --- | 5 | --- |
| 5 | 6 | ||
| 6 | <Layout title="Download — T3 Code" description="Download T3 Code for macOS, Windows, or Linux."> | 7 | <Layout title="Download — T3 Code" description="Download T3 Code for macOS, Windows, or Linux."> |
| ... | @@ -57,6 +58,24 @@ import { RELEASES_URL } from "../lib/releases"; | ... | @@ -57,6 +58,24 @@ import { RELEASES_URL } from "../lib/releases"; |
| 57 | </a> | 58 | </a> |
| 58 | </div> | 59 | </div> |
| 59 | </section> | 60 | </section> |
| 61 | |||
| 62 | <!-- Mobile --> | ||
| 63 | <section class="platform-section"> | ||
| 64 | <div class="platform-header"> | ||
| 65 | <svg class="platform-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="7" y="2" width="10" height="20" rx="2.5"/><path d="M11 18.5h2"/></svg> | ||
| 66 | <h2 class="platform-name">Mobile</h2> | ||
| 67 | </div> | ||
| 68 | <div class="download-cards"> | ||
| 69 | <a class="download-card" href={IOS_APP_STORE_URL} target="_blank" rel="noopener noreferrer"> | ||
| 70 | <span class="card-arch">iPhone &amp; iPad</span> | ||
| 71 | <span class="card-format">App Store</span> | ||
| 72 | </a> | ||
| 73 | <a class="download-card" href={ANDROID_PLAY_STORE_URL} target="_blank" rel="noopener noreferrer"> | ||
| 74 | <span class="card-arch">Android</span> | ||
| 75 | <span class="card-format">Google Play</span> | ||
| 76 | </a> | ||
| 77 | </div> | ||
| 78 | </section> | ||
| 60 | </div> | 79 | </div> |
| 61 | 80 | ||
| 62 | <p class="releases-link"> | 81 | <p class="releases-link"> |
| ... | @@ -73,7 +92,8 @@ import { RELEASES_URL } from "../lib/releases"; | ... | @@ -73,7 +92,8 @@ import { RELEASES_URL } from "../lib/releases"; |
| 73 | 92 | ||
| 74 | async function init() { | 93 | async function init() { |
| 75 | const versionLabel = document.getElementById("version-label"); | 94 | const versionLabel = document.getElementById("version-label"); |
| 76 | const cards = document.querySelectorAll<HTMLAnchorElement>(".download-card"); | 95 | // Only release-asset cards; mobile store cards have no data-asset and keep their href. |
| 96 | const cards = document.querySelectorAll<HTMLAnchorElement>(".download-card[data-asset]"); | ||
| 77 | 97 | ||
| 78 | try { | 98 | try { |
| 79 | const release = await fetchLatestRelease(); | 99 | const release = await fetchLatestRelease(); |
apps/marketing/src/pages/index.astro+34-1| ... | @@ -1,6 +1,11 @@ | ... | @@ -1,6 +1,11 @@ |
| 1 | --- | 1 | --- |
| 2 | import Layout from "../layouts/Layout.astro"; | 2 | import Layout from "../layouts/Layout.astro"; |
| 3 | import { GITHUB_REPOSITORY_URL, MARKETING_STATS } from "../lib/site"; | 3 | import { |
| 4 | ANDROID_PLAY_STORE_URL, | ||
| 5 | GITHUB_REPOSITORY_URL, | ||
| 6 | IOS_APP_STORE_URL, | ||
| 7 | MARKETING_STATS, | ||
| 8 | } from "../lib/site"; | ||
| 4 | import { tweets } from "../lib/tweets"; | 9 | import { tweets } from "../lib/tweets"; |
| 5 | 10 | ||
| 6 | const desktopEndorsementRows = [ | 11 | const desktopEndorsementRows = [ |
| ... | @@ -66,6 +71,12 @@ const mobileEndorsementRows = [ | ... | @@ -66,6 +71,12 @@ const mobileEndorsementRows = [ |
| 66 | <span>Steal our code (legally)</span> | 71 | <span>Steal our code (legally)</span> |
| 67 | <svg class="hero-source-arrow" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 17L17 7M8 7h9v9"/></svg> | 72 | <svg class="hero-source-arrow" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 17L17 7M8 7h9v9"/></svg> |
| 68 | </a> | 73 | </a> |
| 74 | <p class="hero-mobile-line"> | ||
| 75 | Also on your phone: | ||
| 76 | <a href={IOS_APP_STORE_URL} target="_blank" rel="noopener noreferrer">iOS</a> | ||
| 77 | <span aria-hidden="true">·</span> | ||
| 78 | <a href={ANDROID_PLAY_STORE_URL} target="_blank" rel="noopener noreferrer">Android</a> | ||
| 79 | </p> | ||
| 69 | </div> | 80 | </div> |
| 70 | 81 | ||
| 71 | <div class="hero-preview"> | 82 | <div class="hero-preview"> |
| ... | @@ -578,6 +589,28 @@ const mobileEndorsementRows = [ | ... | @@ -578,6 +589,28 @@ const mobileEndorsementRows = [ |
| 578 | opacity: 1; | 589 | opacity: 1; |
| 579 | } | 590 | } |
| 580 | 591 | ||
| 592 | .hero-mobile-line { | ||
| 593 | display: inline-flex; | ||
| 594 | align-items: center; | ||
| 595 | gap: 6px; | ||
| 596 | color: var(--fg-dim); | ||
| 597 | font-size: 13px; | ||
| 598 | letter-spacing: -0.005em; | ||
| 599 | } | ||
| 600 | |||
| 601 | .hero-mobile-line a { | ||
| 602 | color: var(--fg-muted); | ||
| 603 | text-decoration: underline; | ||
| 604 | text-decoration-color: rgba(161, 161, 170, 0.4); | ||
| 605 | text-underline-offset: 3px; | ||
| 606 | transition: color 0.18s ease, text-decoration-color 0.18s ease; | ||
| 607 | } | ||
| 608 | |||
| 609 | .hero-mobile-line a:hover { | ||
| 610 | color: var(--fg); | ||
| 611 | text-decoration-color: var(--fg); | ||
| 612 | } | ||
| 613 | |||
| 581 | /* Download button icons (platform-aware) */ | 614 | /* Download button icons (platform-aware) */ |
| 582 | .dl-icon { | 615 | .dl-icon { |
| 583 | display: none; | 616 | display: none; |