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
6 changes: 5 additions & 1 deletion .fallowrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
// @agent-device/provider-limrun owns the source import, while the published
// root build externalizes @limrun/api and retains runtime imports in packed chunks.
"@limrun/api",
// Oxlint resolves the shared config's JS plugins dynamically from their package names.
"@nkzw/eslint-plugin",
"eslint-plugin-no-only-tests",
"eslint-plugin-perfectionist",
// Packaging linters with no importable API surface here: scripts/check-package.ts runs their
// `node_modules/.bin` shims as subprocesses, which dependency analysis cannot follow to an import.
"publint",
Expand Down Expand Up @@ -116,7 +120,7 @@
},
{
"comment": "Tool config default exports, loaded by the tool rather than imported.",
"file": "{tsdown.config.ts,vitest.mutation.config.ts,website/rspress.config.ts}",
"file": "{oxlint.config.ts,tsdown.config.ts,vitest.mutation.config.ts,website/rspress.config.ts}",
"exports": ["default"]
},
{
Expand Down
74 changes: 0 additions & 74 deletions .oxlintrc.json

This file was deleted.

4 changes: 2 additions & 2 deletions examples/test-app/app/(tabs)/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export default function SettingsRoute() {
diagnosticsLoading={state.diagnosticsLoading}
diagnosticsState={state.diagnosticsState}
notificationsEnabled={state.notificationsEnabled}
onConfirmReset={state.resetLabState}
onLoadDiagnostics={state.loadDiagnostics}
onOpenAccessorySetup={() => router.push('/accessory-setup')}
onOpenAutomationLab={() => router.push('/automation')}
onOpenInertSurface={() => router.push('/inert')}
onOpenWebViewLab={() => router.push('/webview')}
onConfirmReset={state.resetLabState}
onLoadDiagnostics={state.loadDiagnostics}
onRetryDiagnostics={state.retryDiagnostics}
onSetNotificationsEnabled={state.setNotificationsEnabled}
onSetReducedMotionEnabled={state.setReducedMotionEnabled}
Expand Down
2 changes: 1 addition & 1 deletion examples/test-app/src/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ export function ToggleRow(props: {
accessibilityRole="switch"
accessibilityState={{ checked: props.value }}
ios_backgroundColor={colors.lineStrong}
onValueChange={props.onValueChange}
thumbColor={props.value ? colors.accent : colors.card}
trackColor={{ false: colors.lineStrong, true: colors.accentSoft }}
value={props.value}
onValueChange={props.onValueChange}
/>
</View>
);
Expand Down
4 changes: 2 additions & 2 deletions examples/test-app/src/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ export const PRODUCT_CATEGORIES = ['All', 'Starter Kits', 'Produce', 'Bakery', '
export type ProductCategory = (typeof PRODUCT_CATEGORIES)[number];

export interface LabProduct {
badge: string;
category: Exclude<ProductCategory, 'All'>;
id: string;
name: string;
category: Exclude<ProductCategory, 'All'>;
price: string;
subtitle: string;
badge: string;
}

export const LAB_PRODUCTS: LabProduct[] = [
Expand Down
18 changes: 9 additions & 9 deletions examples/test-app/src/lab-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,33 @@ interface ProductDraft {

interface LabStateContextValue {
activeCategory: ProductCategory;
addToCart: (productId: string, quantity?: number) => void;
cartCount: number;
cartCounts: Record<string, number>;
catalogProducts: typeof LAB_PRODUCTS;
decreaseProductQuantity: (productId: string) => void;
detailDrafts: Record<string, ProductDraft>;
diagnosticsExpanded: boolean;
diagnosticsLoading: boolean;
diagnosticsState: 'idle' | 'ready' | 'error';
dismissNotice: () => void;
favoriteIds: string[];
form: CheckoutFormState;
formErrors: string[];
increaseProductQuantity: (productId: string) => void;
isOnline: boolean;
isRefreshing: boolean;
lastSyncLabel: string;
loadDiagnostics: () => void;
noticeVisible: boolean;
notificationsEnabled: boolean;
reducedMotionEnabled: boolean;
searchDraft: string;
submittedSummary: string | null;
toastMessage: string | null;
addToCart: (productId: string, quantity?: number) => void;
decreaseProductQuantity: (productId: string) => void;
dismissNotice: () => void;
increaseProductQuantity: (productId: string) => void;
loadDiagnostics: () => void;
refreshMetrics: () => void;
resetForm: () => void;
resetLabState: () => void;
refreshMetrics: () => void;
retryDiagnostics: () => void;
saveProductToCart: (productId: string) => void;
searchDraft: string;
setActiveCategory: (value: ProductCategory) => void;
setDiagnosticsExpanded: (value: boolean) => void;
setIsOnline: (value: boolean) => void;
Expand All @@ -59,6 +57,8 @@ interface LabStateContextValue {
setReducedMotionEnabled: (value: boolean) => void;
setSearchDraft: (value: string) => void;
submitOrder: () => void;
submittedSummary: string | null;
toastMessage: string | null;
toggleFavorite: (productId: string) => void;
updateForm: <K extends keyof CheckoutFormState>(field: K, value: CheckoutFormState[K]) => void;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/test-app/src/screens/AudioScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ export function AudioScreen() {
<ScreenTitle
badge="Media"
subtitle="A short generated audio sample with a visible playback state."
title="Audio"
testID="audio-title"
title="Audio"
/>

<SectionCard subtitle="Generated 440 Hz beep, 6 seconds." title="Audio sample">
Expand Down
2 changes: 1 addition & 1 deletion examples/test-app/src/screens/AutomationLabScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export function AutomationLabScreen(props: {
<ScreenTitle
badge="E2E"
subtitle="Durable outcomes for simulator commands that need app-visible evidence."
title="Automation lab"
testID="automation-title"
title="Automation lab"
/>
<SectionCard title="Runtime state">
<StateRow label="Window" testID="automation-window" value={windowMode} />
Expand Down
14 changes: 7 additions & 7 deletions examples/test-app/src/screens/CatalogScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export interface CatalogScreenProps {
activeCategory: ProductCategory;
cart: Record<string, number>;
favorites: Set<string>;
products: LabProduct[];
searchDraft: string;
onAddToCart: (productId: string) => void;
onOpenDetails: (productId: string) => void;
onSearchDraftChange: (value: string) => void;
onSelectCategory: (value: ProductCategory) => void;
onToggleFavorite: (productId: string) => void;
products: LabProduct[];
searchDraft: string;
}

export function CatalogScreen(props: CatalogScreenProps) {
Expand Down Expand Up @@ -70,8 +70,8 @@ export function CatalogScreen(props: CatalogScreenProps) {
<ScreenTitle
badge={`${props.products.length} results`}
subtitle="Search, filter, scroll, favorite, and drill into detail without extra dependencies."
title="Catalog"
testID="catalog-title"
title="Catalog"
/>
<Text style={styles.scrollState} testID="catalog-scroll-state">
Catalog scroll: {scrollState}
Expand All @@ -93,7 +93,7 @@ export function CatalogScreen(props: CatalogScreenProps) {
label={category}
onPress={() => props.onSelectCategory(category)}
selected={props.activeCategory === category}
testID={`category-${category.toLowerCase().replace(/\s+/g, '-')}`}
testID={`category-${category.toLowerCase().replaceAll(/\s+/g, '-')}`}
/>
))}
</View>
Expand All @@ -107,8 +107,8 @@ export function CatalogScreen(props: CatalogScreenProps) {
<SectionCard
key={product.id}
subtitle={product.subtitle}
title={product.name}
testID={`product-card-${product.id}`}
title={product.name}
>
<View style={styles.metaRow}>
<InlineBadge label={product.badge} tone="info" />
Expand Down Expand Up @@ -146,12 +146,12 @@ export function CatalogScreen(props: CatalogScreenProps) {

<SectionCard
subtitle="This footer card sits at the end of the list to force scroll-into-view on smaller screens."
title="Seasonal footer target"
testID="catalog-footer"
title="Seasonal footer target"
>
<Text style={styles.footerText}>
If your run reaches this card, you already exercised long-list navigation. The durable
text here is "Seasonal footer target".
text here is &quot;Seasonal footer target&quot;.
</Text>
</SectionCard>
</ScrollView>
Expand Down
25 changes: 14 additions & 11 deletions examples/test-app/src/screens/FormScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ import {
import { useAppColors, type AppColors } from '../theme';

export interface CheckoutFormState {
name: string;
agree: boolean;
email: string;
phone: string;
imeCaptureTarget: string;
name: string;
notes: string;
shipping: 'Delivery' | 'Pickup';
payment: 'Card' | 'Cash';
phone: string;
shipping: 'Delivery' | 'Pickup';
subscribe: boolean;
agree: boolean;
}

export interface FormScreenProps {
errors: string[];
form: CheckoutFormState;
submittedSummary: string | null;
onChange: <K extends keyof CheckoutFormState>(field: K, value: CheckoutFormState[K]) => void;
onReset: () => void;
onSubmit: () => void;
submittedSummary: string | null;
}

function CheckboxRow(props: {
Expand Down Expand Up @@ -70,16 +70,16 @@ export function FormScreen(props: FormScreenProps) {
<ScreenTitle
badge="Validation"
subtitle="Text inputs, choice groups, checkbox state, multiline notes, and submit feedback."
title="Checkout form"
testID="form-title"
title="Checkout form"
/>

{props.errors.length > 0 ? (
<SectionCard
subtitle="These messages should disappear after a valid submit."
testID="form-errors"
title="Validation errors"
tone="danger"
testID="form-errors"
>
{props.errors.map((error) => (
<Text key={error} style={styles.errorText}>
Expand All @@ -92,8 +92,8 @@ export function FormScreen(props: FormScreenProps) {
{props.submittedSummary ? (
<SectionCard
subtitle="This card appears only after a valid submit."
title="Order summary"
testID="form-success"
title="Order summary"
>
<InlineBadge label="Submitted" tone="success" />
<Text style={styles.summaryText}>{props.submittedSummary}</Text>
Expand Down Expand Up @@ -137,8 +137,8 @@ export function FormScreen(props: FormScreenProps) {

<SectionCard
subtitle="A fixture for Android cases where Gboard handwriting owns the focused input."
title="Android IME capture"
testID="android-ime-capture-fixture"
title="Android IME capture"
>
{/* Fixture: static diagnostic copy, not live state. */}
<TextField
Expand All @@ -154,9 +154,12 @@ export function FormScreen(props: FormScreenProps) {
<Text style={styles.diagnosticText}>
Android fill input was captured by the active keyboard instead of the app field
</Text>
<Text style={styles.diagnosticMeta}>targetInput id="field-ime-capture-target"</Text>
<Text style={styles.diagnosticMeta}>
actualInput packageName="com.google.android.inputmethod.latin" inputMethodOwned=true
targetInput id=&quot;field-ime-capture-target&quot;
</Text>
<Text style={styles.diagnosticMeta}>
actualInput packageName=&quot;com.google.android.inputmethod.latin&quot;
inputMethodOwned=true
</Text>
</View>
</SectionCard>
Expand Down
2 changes: 1 addition & 1 deletion examples/test-app/src/screens/GestureLab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ export function GestureLab() {
return (
<SectionCard
subtitle={`Image target for pan, pinch, rotate, and fling. ${changeStatusLabel}`}
title="Gesture lab"
testID="gesture-lab-card"
title="Gesture lab"
>
<View style={styles.dragRow} testID="drag-gesture-fixture">
<GestureDetector gesture={holdDragGesture}>
Expand Down
6 changes: 3 additions & 3 deletions examples/test-app/src/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ export function HomeScreen(props: HomeScreenProps) {
<ScreenTitle
badge={`${props.cartCount} in cart`}
subtitle="An app for testing all the functionality of agent-device."
title="Agent Device Tester"
testID="home-title"
title="Agent Device Tester"
/>

<GestureLab />

{props.noticeVisible ? (
<SectionCard
subtitle="Dismiss this to exercise nearby mutations and compact diff verification."
testID="release-notice"
title="Release notice"
tone="accent"
testID="release-notice"
>
<Text style={styles.noticeText}>
The bakery list was refreshed this morning. Seasonal items moved to the bottom of the
Expand Down Expand Up @@ -105,8 +105,8 @@ export function HomeScreen(props: HomeScreenProps) {

<SectionCard
subtitle="Good for wait, get, and state assertions."
title="Live status"
testID="home-status-card"
title="Live status"
>
<View style={styles.row}>
<Text style={styles.label}>Session health</Text>
Expand Down
Loading
Loading