fix(onboarding): clarify opencode-serve requirement + fail connect fast (retention) (#107)
* fix(onboarding): clarify opencode-serve requirement and fail connect tests fast New users bounce at ~0% 7-day retention because nothing tells them the app needs a computer running `opencode serve` on the same network/Tailscale, and a bad IP hangs for the full 30s request timeout before failing. - Rewrite the no-connection empty state subtitle and add a "How to set up a server" link to the setup guide (app/(tabs)/index.tsx, src/lib/links.ts). - Surface the opencode-serve prerequisite as a one-line notice at the top of the Quick Connect form, above the existing detailed help box (app/connection/add.tsx). - Give the interactive connection test (testConnection) its own 12s timeout via an optional Client.global.health(timeoutMs) parameter, instead of reusing the general 30s REQUEST_TIMEOUT_MS used for real session traffic (src/lib/sdk.ts, src/stores/connections.ts). - Mirror all new/changed strings in the zh-Hans catalog; catalog-parity test keeps them in sync. * docs(distribution): add retention analysis motivating first-run fixes Diagnoses ~0% D7 retention as product-shape (no path to value without a self-hosted server, no demo mode, store copy sets no expectation). Ranks fixes and isolates the two owner-only strategic calls (store-copy honesty, hosted OpenCode Connect). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6 * fix(onboarding): drop connect-screen prerequisite notice (kept off-screen the submit button in E2E) The added notice pushed connect-submit-button below the fold, breaking the Maestro activation-positive flow (and the other flows sharing the connect prelude). The empty state already sets the opencode-serve expectation one screen earlier, so this notice was redundant. Empty-state guidance + guide link and the fast-fail connect timeout are unaffected and retained. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6 --------- Co-authored-by: engineer <engineer@macbookpro.lan> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
Alert,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Linking,
|
||||
} from "react-native"
|
||||
import { router, useFocusEffect } from "expo-router"
|
||||
import { Ionicons } from "@expo/vector-icons"
|
||||
@@ -27,6 +28,7 @@ import type { Session, Project } from "../../src/lib/sdk"
|
||||
import { DirectorySwitcher, DirectoryBrowserSheet } from "../../src/components/chat"
|
||||
import { groupByDirectory } from "../../src/lib/session-grouping"
|
||||
import { nameOf } from "../../src/lib/path-utils"
|
||||
import { SETUP_GUIDE_URL } from "../../src/lib/links"
|
||||
|
||||
function formatTime(timestamp: number, t: (key: string, opts?: Record<string, unknown>) => string): string {
|
||||
const date = new Date(timestamp)
|
||||
@@ -435,6 +437,13 @@ export default function SessionsScreen() {
|
||||
{t("sessionsList.empty.addConnectionButton")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.setupGuideLink}
|
||||
onPress={() => Linking.openURL(SETUP_GUIDE_URL)}
|
||||
testID="setup-guide-link"
|
||||
>
|
||||
<Text style={styles.setupGuideLinkText}>{t("sessionsList.empty.setupGuideLink")}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -1013,6 +1022,14 @@ const styles = StyleSheet.create({
|
||||
addButtonTextDark: {
|
||||
color: "#0a0a0a",
|
||||
},
|
||||
setupGuideLink: {
|
||||
marginTop: 16,
|
||||
},
|
||||
setupGuideLinkText: {
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
color: "#6366f1",
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
|
||||
Reference in New Issue
Block a user