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
11 changes: 11 additions & 0 deletions .papercuts/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,14 @@ owns; reopen the terminal before judging the final live state.

- Zsh does not split scalar loop values by default; use explicit delimiters in pairwise merge probes so branch names are not accidentally concatenated.
- Standalone green PRs still conflicted in shared settings, test registries, and UI fixtures. Assemble the exact combined stack and retain every feature's test registration before merging to main.
- UX review (2026-09-05): the active Xcode installation rejects tools until its license is accepted. Git and desktop C helpers can use the separately installed Command Line Tools via `DEVELOPER_DIR=/Library/Developer/CommandLineTools`; helper build scripts replace the child environment, so this run compiled their unchanged C sources with the same flags directly. iOS physical-device discovery/test remains blocked; do not claim it passed.
- Electron E2E failure diagnostics called `app.process()` outside their try/catch; a closed Electron target hid the original launch error. Keep that call within the best-effort diagnostic block. The isolated E2E profile also cannot establish native Bot Keychain authority; the editor test injects a test-owned IPC catalog and captures the submitted access, while storage/authority tests run separately.

## 2026-09-10 — PR96 readiness rebase

- The branch predated the unified Settings work and conflicted in headings, accessible switch names, shared test fixtures, and the tracked-but-ignored papercut log. Resolve these contracts additively and use `git add -f` for the already tracked `.papercuts/troubleshooting.md`.
- A parent save handler showed a toast but resolved its promise, making the editor's inline retry state unreachable. Propagate the rejection after the toast so the review dialog keeps the user's choices and exposes the error.
- Progressive disclosure made two inherited E2E locators inaccessible: tests must open the exact Remote or Telegram details before asserting the controls inside, rather than spending the full timeout waiting for hidden semantics.
- A single rollback `try` coupled external Tailscale route cleanup to local listener/state cleanup; keep independently knowable cleanup steps best-effort and report external versus local uncertainty separately.
- Distinct cleanup messages need branch-specific regressions: cover both newly enabled access being disabled and pre-existing access staying enabled when route removal fails.
- Hosted Electron can leave a controlled scheduled-task search unchanged after Playwright `fill("")`; use the native value setter plus a bubbling input event for deterministic cleanup.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
Expand All @@ -21,6 +23,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
Expand Down Expand Up @@ -183,29 +186,42 @@ fun AidenPairingScreen(

// Pair New Mac Section
Text(
text = "Pair New Mac",
text = "Connect your Mac",
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Bold,
color = palette.secondary
)
Spacer(modifier = Modifier.height(8.dp))

// M3 Expressive 3-Tab Pill Segmented Group
Text(
text = "On your Mac, open Settings → Aiden On The Go → Connect a device. Then scan its code here.",
style = MaterialTheme.typography.bodyMedium,
color = palette.secondary
)
Spacer(modifier = Modifier.height(12.dp))

// QR first, with a camera-free setup code fallback.
Surface(
color = palette.raised,
shape = RoundedCornerShape(20.dp),
modifier = Modifier.fillMaxWidth()
) {
Row(
modifier = Modifier.padding(4.dp)
modifier = Modifier
.padding(4.dp)
.selectableGroup()
) {
// Tab 0: Scan QR
Surface(
color = if (selectedTab == 0) palette.accent else Color.Transparent,
shape = RoundedCornerShape(16.dp),
modifier = Modifier
.weight(1f)
.tactilePress { selectedTab = 0 }
.selectable(
selected = selectedTab == 0,
role = Role.Tab,
onClick = { selectedTab = 0 }
)
) {
Box(
contentAlignment = Alignment.Center,
Expand All @@ -226,7 +242,11 @@ fun AidenPairingScreen(
shape = RoundedCornerShape(16.dp),
modifier = Modifier
.weight(1f)
.tactilePress { selectedTab = 1 }
.selectable(
selected = selectedTab == 1,
role = Role.Tab,
onClick = { selectedTab = 1 }
)
) {
Box(
contentAlignment = Alignment.Center,
Expand All @@ -241,31 +261,16 @@ fun AidenPairingScreen(
}
}

// Tab 2: Paste JSON
Surface(
color = if (selectedTab == 2) palette.accent else Color.Transparent,
shape = RoundedCornerShape(16.dp),
modifier = Modifier
.weight(1f)
.tactilePress { selectedTab = 2 }
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.padding(vertical = 8.dp)
) {
Text(
text = "Paste JSON",
style = MaterialTheme.typography.labelMedium,
fontWeight = FontWeight.Bold,
color = if (selectedTab == 2) Color.White else palette.secondary
)
}
}

}
}

Spacer(modifier = Modifier.height(16.dp))

TextButton(onClick = { selectedTab = if (selectedTab == 2) 0 else 2 }) {
Text(if (selectedTab == 2) "Back to scanning" else "Advanced: paste connection details")
}

errorMessage?.let { msg ->
Surface(
color = palette.danger.copy(alpha = 0.12f),
Expand Down Expand Up @@ -325,7 +330,7 @@ fun AidenPairingScreen(
colors = sbtbiswas.AidenOnTheGo.ui.theme.aidenTextFieldColors(),
value = endpointUrl,
onValueChange = { endpointUrl = it },
label = { Text("Mac Address (HTTPS Endpoint)") },
label = { Text("Mac address") },
singleLine = true,
shape = RoundedCornerShape(12.dp),
modifier = Modifier.fillMaxWidth()
Expand Down
30 changes: 17 additions & 13 deletions docs/aiden-on-the-go-remote-access.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
# Aiden On The Go remote access

Aiden Agent can expose a small authenticated API to Aiden On The Go on iPhone and iPad. Remote Access is off by default. Aiden must remain running on the Mac, although its window may be closed.
Aiden Agent can expose a small authenticated API to Aiden On The Go on phones and tablets. Phone access is off by default. Aiden must remain running on the Mac, although its window may be closed.

## Local Network setup

1. Open **Settings → Remote Access** in Aiden Agent.
2. Choose **Local Network** or **Local Network + Tailscale**.
3. Turn on **Enable Remote Access**.
4. Add only the folders the phone or iPad may explore. Selecting the entire home directory requires a second confirmation on the Mac; the filesystem root is never allowed.
5. Choose **Pair over Local Network** and scan the one-time QR code in Aiden On The Go.
1. Open **Settings → Aiden On The Go** in Aiden Agent.
2. Choose **On the same Wi-Fi**, then **Connect a device**.
3. Review what Aiden will enable and choose **Enable and show code**.
4. Scan the code in Aiden On The Go. If the camera is unavailable, use the setup code instead.

After choosing the method, setup takes two desktop actions. Scanning and any phone permissions are additional steps. Existing ready connections can add a device directly. Under **Workspace access**, approve any additional folders the phone may browse; existing workspace access is unchanged. Approving the whole home folder requires a separate confirmation.

The Mac advertises `_aiden-agent._tcp` with Bonjour only while Local Network access is running. LAN traffic uses a per-install P-256 HTTPS identity. The QR contains the private CA trust anchor and the server public-key pin so the mobile client can validate the hostname, certificate chain, and pinned key. A certificate renewal keeps the server key; an identity-key change requires pairing again.

## Tailscale setup

Tailscale supplies reachability and network encryption, but Aiden still requires its own device credential on every request.

1. Install Tailscale on the Mac and sign in to the intended tailnet.
2. Ensure HTTPS certificates are available for the tailnet. Aiden reports this prerequisite rather than enabling it silently.
3. In **Settings → Remote Access**, select **Tailscale** or **Local Network + Tailscale** and enable Remote Access.
4. Review the exact command-equivalent route preview, then choose **Connect**.
5. Pair with **Pair over Tailscale** after the stable `https://…ts.net/api/aiden/v1` address appears.
1. Install Tailscale on the Mac and phone, sign in to the intended network, and make sure HTTPS is authorized for the Mac’s Tailscale name.
2. Open **Settings → Aiden On The Go** and choose **Away from home**.
3. Choose **Connect a device → Enable and show code**. Aiden turns on access, sets up its private connection, checks it, and shows the one-time code.
4. Scan the code on your phone.

Aiden checks installation, sign-in, HTTPS availability, and route ownership before setup. Missing prerequisites remain user actions. Conflicts and uncertain changes direct you to the advanced **Connection** controls; setup never silently replaces another route. If setup fails, Aiden removes only access introduced by that attempt where the outcome is known. An uncertain external change remains available for explicit verification.

**This Mac settings** contains the Mac name and enable switch; **Connection** contains the saved mode and technical controls. Closing the code window stops pairing; phone access remains enabled until switched off. Removing a device’s access is separate from turning off all phone access.

Aiden owns only `/api/aiden/v1`, proxies it to the loopback-only HTTP listener's matching `/api/aiden/v1` base, and verifies the resulting route. The matching target base is required because Tailscale strips the public `--set-path` prefix before proxying. On macOS, Aiden invokes Tailscale's shared app executable in its documented explicit CLI mode, so Finder and Dock launches do not depend on terminal environment variables. First-time connection works from an empty Serve configuration only after the node's exact Tailscale certificate domain proves HTTPS was already authorized. Aiden never enables Tailscale Funnel, never runs `tailscale serve reset`, never completes Tailscale authorization for you, and never changes unrelated Serve handlers. **Disconnect** removes only the exact route and target recorded by Aiden. A conflict is reported instead of being overwritten.

## Devices, credentials, and revocation

Each phone or iPad receives a separate random credential. Aiden persists only a fast lookup digest, a salted scrypt digest, and redacted device metadata—not the credential or pairing secret. Pairing QR codes expire after five minutes and work once.
Each phone or tablet receives a separate random credential. Aiden persists only a fast lookup digest, a salted scrypt digest, and redacted device metadata—not the credential or pairing secret. Pairing QR codes expire after five minutes and work once.

Use **Revoke** beside a paired device to invalidate it immediately. Revocation does not rotate model-provider credentials or affect other paired devices. Pair the device again to restore access.
Use **Remove access** beside a paired device to invalidate it immediately. Revocation does not rotate model-provider credentials or affect other paired devices. Pair the device again to restore access.

## Offline behavior

Expand Down
1 change: 1 addition & 0 deletions docs/plans/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This directory is the source of truth for Aiden's implementation plans. The engi

| Plan | Status | Current state |
| -------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Nontechnical User Journey UX](nontechnical-user-journey-ux-plan.md) | Active | Approved ten-journey UX pass implemented for review: guided phone setup, four AI choices, two-step Create a bot, setup acknowledgements, recovery, and native pairing copy. Broader audit backlog and physical-device acceptance remain open. |
| [Aiden Assistant](aiden-assistant-plan.md) | Partial | The dock, Markdown rendering, and confirmed provider-connection/model-pinned project-or-MCP automation creation/editing ship; settings tools and proactivity remain planned. |
| [Aiden On The Go](aiden-on-the-go-plan.md) | Active | Version 0.1.0 build 22 is `VALID` and `IN_BETA_TESTING` for Internal Testers. Android matches iOS's app-icon switcher, Workspace hierarchy, warm scoped Bots/Usage/SSE lifecycle, Usage dashboard, image showcase/gallery, keyboard-safe elevated composer, and split Photo/File pickers. Both clients support native in-process dictation or bounded no-retention transcription by the paired Mac's local Parakeet model. iOS also ships progressive onboarding, bidirectional media, reliable mobile approvals, typed activity timelines, semantic haptics, and one-chat-per-Bot conversations with companion vision for text-only models. Physical iPad/manual permission-system-UI acceptance, privacy publication, final store assets, and external/public-release decisions remain open. |
| [Unified Workspace Sidebar](unified-workspace-sidebar-plan.md) | Active | Phases 1 and 2 ship the unified workspace/chat outline plus a feature-negotiated, transcript-free paginated summary read on Electron, iOS/iPadOS, and Android; physical-device performance acceptance remains open. |
Expand Down
Loading
Loading