Skip to content
Merged
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
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Ada

**Agentic Desktop Application. Engineering is better with Agents.**

Ada lets you direct the coding agents on your machine (Claude Code, Codex, Cursor, Grok Build,
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/agents/pip-lockup-dark.png">
<source media="(prefers-color-scheme: light)" srcset="assets/agents/pip-lockup-light.png">
<img src="assets/agents/pip-lockup-light.png" alt="Ada: Engineering is better with Agents." width="560">
</picture>
</p>

<p align="center">
<a href="https://x.com/jayleaton"><img src="https://img.shields.io/badge/Follow-%40jayleaton-000000?logo=x&logoColor=white" alt="Follow @jayleaton"></a> <a href="https://buymeacoffee.com/jayleaton"><img src="https://img.shields.io/badge/Buy_Me_a_Coffee-Support-FFDD00?logo=buymeacoffee&logoColor=black" alt="Buy Me a Coffee: Support"></a>
</p>

Ada (Agentic Desktop Application) lets you direct the coding agents on your machine (Claude Code, Codex, Cursor, Grok Build,
OpenCode, Google Antigravity, and fx) from one workspace, across a desktop app, a web app, and a
mobile app. Your agents run wherever Ada runs: your desktop, a server, or a VPS, and you can connect
to it from anywhere.
Expand All @@ -28,7 +36,7 @@ Download Ada from [GitHub Releases](https://github.com/jayleaton/t3code/releases

### Command line

The desktop app includes the `ada` command (**Settings → About → t3 command**). `ada update` and `ada service install` download Ada's releases. For a Linux machine without a desktop, see [Headless Linux host](./docs/operations/headless-linux.md).
The desktop app includes the `ada` command (**Settings → About → ada command**). `ada update` and `ada service install` download Ada's releases. For a Linux machine without a desktop, see [Headless Linux host](./docs/operations/headless-linux.md).

### Switching from T3 Code

Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/gnome-extension/captureFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class CaptureFeedback {
}
} catch (error) {
this._clearActors();
console.warn(`T3 capture effects unavailable: ${error.message}`);
console.warn(`Ada capture effects unavailable: ${error.message}`);
}
return Boolean(this._actor);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/gnome-extension/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function takeSnapshot(animate) {
try {
content = window.get_compositor_private().paint_to_content(null);
} catch (error) {
console.warn(`T3 capture preview unavailable: ${error.message}`);
console.warn(`Ada capture preview unavailable: ${error.message}`);
}
}
const metadata = JSON.stringify({
Expand Down
4 changes: 1 addition & 3 deletions apps/desktop/resources/dmg/dmg-background-latest.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 1 addition & 3 deletions apps/desktop/resources/dmg/dmg-background-nightly.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions apps/desktop/src/backend/DesktopBackendPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import * as DesktopWindow from "../window/DesktopWindow.ts";
import * as DesktopWslEnvironment from "../wsl/DesktopWslEnvironment.ts";
import * as ElectronDialog from "../electron/ElectronDialog.ts";
import * as ElectronApp from "../electron/ElectronApp.ts";
import { APP_NAME } from "@t3tools/shared/branding";
import { APP_NAME, CLI_COMMAND } from "@t3tools/shared/branding";

const { logWarning: logBackendPoolWarning } =
DesktopObservability.makeComponentLogger("desktop-backend-pool");
Expand Down Expand Up @@ -179,8 +179,8 @@ export const layer = Layer.effect(
onStateDirOwned: () =>
Effect.flatMap(HostProcess.Platform, (platform) =>
electronDialog.showErrorBox(
"This T3 home is unavailable",
`Another ${APP_NAME} server, such as the background service, is using this data directory, or an older background service is set up for it. Stop that server or try \`t3 update\`. If the older launcher cannot update, run \`t3 service uninstall\` and optionally reinstall with \`t3 service install\` from a current CLI. If \`t3\` is missing or outdated, install it with \`${cliInstallCommand(platform === "win32" ? "win32" : "posix")}\`, and pass \`--base-dir\` with the service's T3 home to each command. Then reopen ${APP_NAME}. You can also set a separate T3CODE_HOME and pair with the running server.`,
`This ${APP_NAME} home is unavailable`,
`Another ${APP_NAME} server, such as the background service, is using this data directory, or an older background service is set up for it. Stop that server or try \`${CLI_COMMAND} update\`. If the older launcher cannot update, run \`${CLI_COMMAND} service uninstall\` and optionally reinstall with \`${CLI_COMMAND} service install\` from a current CLI. If \`${CLI_COMMAND}\` is missing or outdated, install it with \`${cliInstallCommand(platform === "win32" ? "win32" : "posix")}\`, and pass \`--base-dir\` with the service's ${APP_NAME} home to each command. Then reopen ${APP_NAME}. You can also set a separate T3CODE_HOME and pair with the running server.`,
),
).pipe(Effect.andThen(electronApp.quit)),
onDatabaseRefused: () =>
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/wsl/DesktopWslBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import * as DesktopBackendPool from "../backend/DesktopBackendPool.ts";
import * as DesktopServerExposure from "../backend/DesktopServerExposure.ts";
import * as DesktopAppSettings from "../settings/DesktopAppSettings.ts";
import * as DesktopWslEnvironment from "./DesktopWslEnvironment.ts";
import { APP_NAME } from "@t3tools/shared/branding";
import { APP_NAME, CLI_COMMAND } from "@t3tools/shared/branding";

export const WSL_INSTANCE_ID_PREFIX = "wsl:";
const WSL_DEFAULT_DISTRO_ID = `${WSL_INSTANCE_ID_PREFIX}default`;
Expand Down Expand Up @@ -130,7 +130,7 @@ export const layer = Layer.effect(
Ref.set(preflightErrorRef, Option.some(failure.reason)).pipe(Effect.as(false)),
onStateDirOwned: () =>
refuse(
`Another ${APP_NAME} server is using this distro's T3 home, or an older background service is set up for it. Stop that server or pair with it, or try \`t3 update\` in the distro. If the older launcher cannot update, run \`t3 service uninstall\` and optionally reinstall with \`t3 service install\` from a current CLI in the distro. If \`t3\` is missing or outdated, install it in the distro with \`${cliInstallCommand("posix")}\`, and pass \`--base-dir\` with the service's T3 home to each command.`,
`Another ${APP_NAME} server is using this distro's ${APP_NAME} home, or an older background service is set up for it. Stop that server or pair with it, or try \`${CLI_COMMAND} update\` in the distro. If the older launcher cannot update, run \`${CLI_COMMAND} service uninstall\` and optionally reinstall with \`${CLI_COMMAND} service install\` from a current CLI in the distro. If \`${CLI_COMMAND}\` is missing or outdated, install it in the distro with \`${cliInstallCommand("posix")}\`, and pass \`--base-dir\` with the service's ${APP_NAME} home to each command.`,
),
onDatabaseRefused: () =>
refuse(
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/wsl/DesktopWslEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ export const buildWslRuntimeInstallScript = (
"trap cleanup_runtime_install EXIT",
`tar -xzf ${shellQuote(linuxArchivePath)} -C "$runtime_tmp" --strip-components=1`,
'if ! runtime_entry_runs "$runtime_tmp"; then',
" printf 'WSL runtime archive does not contain a working t3 executable\\n' >&2",
` printf 'WSL runtime archive does not contain a working ${APP_NAME} executable\\n' >&2`,
" exit 1",
"fi",
'installed_entry_digest=$(runtime_server_entry_digest "$runtime_tmp")',
Expand Down
Binary file modified apps/marketing/public/apple-touch-icon.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 modified apps/marketing/public/favicon-16x16.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 modified apps/marketing/public/favicon-32x32.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 modified apps/marketing/public/favicon.ico
Binary file not shown.
Binary file modified apps/marketing/src/assets/icon-nightly.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/marketing/src/assets/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/marketing/src/assets/social-card.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ if (
);
}

// This fork ships as T3 Agents: every variant uses the Agents mark from
// assets/agents/source.png (the desktop icon), told apart by name only. iOS
// Every variant uses Pip (scripts/export-android-icons.ts), told apart by name only. iOS
// gets a full-bleed square because it applies its own mask; Android gets the
// mark alone over a navy adaptive background so the launcher mask never crops it.
const AGENTS_NAVY = "#0A1442";
const AGENTS_NAVY = "#111925";
const AGENTS_ASSETS = {
appIcon: "./assets/agents/ios-icon-1024.png",
iosIcon: "./assets/agents/ios-icon-1024.png",
Expand Down
Binary file modified apps/mobile/assets/agents/android-icon-foreground.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 modified apps/mobile/assets/agents/android-icon-monochrome.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 modified apps/mobile/assets/agents/android-splash-icon.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 modified apps/mobile/assets/agents/ios-icon-1024.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 modified apps/mobile/assets/agents/splash-mark.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 removed apps/mobile/assets/android-icon-background-dev.png
Binary file not shown.
Binary file not shown.
Binary file removed apps/mobile/assets/android-icon-foreground.png
Binary file not shown.
Binary file removed apps/mobile/assets/android-icon-mark.png
Binary file not shown.
Binary file removed apps/mobile/assets/android-notification-icon.png
Binary file not shown.
Binary file removed apps/mobile/assets/android-splash-icon-dev.png
Binary file not shown.
Binary file removed apps/mobile/assets/android-splash-icon-nightly.png
Binary file not shown.
Binary file removed apps/mobile/assets/android-splash-icon-prod.png
Binary file not shown.
1 change: 1 addition & 0 deletions apps/mobile/assets/widget/PipMark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions apps/mobile/assets/widget/T3Mark.svg

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private fun saveImageToPictures(context: Context, source: Uri, mimeType: String,
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, name)
put(MediaStore.Images.Media.MIME_TYPE, mimeType)
put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/T3 Code")
put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/Ada")
put(MediaStore.Images.Media.IS_PENDING, 1)
}
val target = resolver.insert(
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/plugins/withWidgetLogoAsset.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const { addWidgetAssetCatalog } = require("./lib/addWidgetAssetCatalog.cjs");

const TARGET_NAME = "ExpoWidgetsTarget";
const CATALOG_NAME = "Assets.xcassets";
const IMAGE_SET = "T3Mark.imageset";
const SVG_NAME = "T3Mark.svg";
const IMAGE_SET = "PipMark.imageset";
const SVG_NAME = "PipMark.svg";

const CATALOG_CONTENTS = JSON.stringify({ info: { author: "expo", version: 1 } }, null, 2) + "\n";
const IMAGE_SET_CONTENTS =
Expand Down
29 changes: 29 additions & 0 deletions apps/mobile/src/components/PipMark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { ColorValue } from "react-native";
import Svg, { Path } from "react-native-svg";
import { withUniwind } from "uniwind";

const ThemedPath = withUniwind(Path);

/** Pip, the app's mark, in a single colour. The path is assets/agents/pip.svg. */
export function PipMark(props: {
readonly height: number;
readonly color?: ColorValue;
readonly colorClassName?: string;
}) {
return (
<Svg
accessibilityLabel="Ada"
height={props.height}
width={(props.height * 62) / 60}
viewBox="19 16 62 60"
>
<ThemedPath
d="M19 76V46C19 7 81 7 81 46V76H64V64H36V76ZM33 41A5 5 0 0 1 43 41V47A5 5 0 0 1 33 47ZM57 41A5 5 0 0 1 67 41V47A5 5 0 0 1 57 47Z"
color={props.color}
colorClassName={props.colorClassName}
fill="currentColor"
fillRule="evenodd"
/>
</Svg>
);
}
28 changes: 0 additions & 28 deletions apps/mobile/src/components/T3Wordmark.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ function PairingScanCard(props: {
)}
</View>
<Text className={cn("text-center text-sm", light ? "text-black/70" : "text-white/80")}>
Scan the code from t3 pair or desktop Connections settings
Scan the code from ada pair or desktop Connections settings
</Text>
</View>
</Pressable>
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/features/connection/pairing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function validateMobilePairingUrl(pairingUrl: string): void {
hostname === "::"
) {
throw new Error(
"Localhost points to this phone, not your Mac. Generate a new pairing link with t3 pair --tailscale, or use your Mac's LAN IP and a fresh pairing token.",
"Localhost points to this phone, not your Mac. Generate a new pairing link with ada pair --tailscale, or use your Mac's LAN IP and a fresh pairing token.",
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function AppSettingsSection() {
label="Open source licenses"
target="SettingsOpenSourceLicenses"
/>
<SettingsRow icon="doc.text" label="Legal" fullScreenTarget="SettingsLegal" />
<SettingsRow icon="doc.text" label="License" fullScreenTarget="SettingsLegal" />
{updateCheckAvailable ? (
<Pressable
accessibilityLabel={`Version ${versionLabel}`}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LICENSE_URL } from "@t3tools/shared/cliRelease";

import { SettingsLegalDocumentRouteScreen } from "./components/SettingsLegalDocumentRouteScreen";
import { LEGAL_URL } from "./lib/legal-document-url";

export function SettingsLegalRouteScreen() {
return <SettingsLegalDocumentRouteScreen documentName="Legal" documentUrl={LEGAL_URL} />;
return <SettingsLegalDocumentRouteScreen documentName="License" documentUrl={LICENSE_URL} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ export function SettingsNotificationsRouteScreen() {
Push notifications and Live Activities are not available in this app.
</Text>
<Text className="text-sm leading-normal text-foreground-muted">
They were delivered through T3 Connect, which this build does not include. Open the app to
see what your agents are doing.
Open the app to see what your agents are doing.
</Text>
</ScrollView>
</SettingsScreen>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function SettingsLabsRouteScreen() {
icon="bolt.circle"
capability="fastWorktreeCheckout"
setting="fastWorktreeCheckout"
description="On a Mac, clone new worktrees from a checkout cached in the T3 home folder instead of writing every file. Uses Git’s normal checkout when it can’t. Turning it off deletes the cache."
description="On a Mac, clone new worktrees from a checkout cached in the Ada home folder instead of writing every file. Uses Git’s normal checkout when it can’t. Turning it off deletes the cache."
/>
</ScrollView>
</SettingsScreen>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function render(
root.render(
<BranchNamingSettings
mode={mode}
prefix={saved.prefix ?? "t3"}
prefix={saved.prefix ?? "ada"}
instructions={saved.instructions ?? "Use issue IDs."}
disabled={{ mode: disabled, prefix: disabled, instructions: disabled }}
onChange={onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function BranchNamingSettings(props: {
{props.mode === "static" ? (
<View className="gap-2 px-4 py-3">
<Text className="text-sm text-foreground-muted">
Use t3 or t3/ for t3/add-search. Leave empty for no prefix.
Use ada or ada/ for ada/add-search. Leave empty for no prefix.
</Text>
<AppTextInput
key={props.prefix}
Expand Down
Loading
Loading