yaver-feedback-react-native 0.9.0 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -1
- package/app.plugin.js +126 -9
- package/dist/AuthOverlay.d.ts +1 -14
- package/dist/AuthOverlay.js +9 -62
- package/dist/BlackBox.js +9 -1
- package/dist/DeployPanel.js +65 -0
- package/dist/Discovery.js +13 -8
- package/dist/DogfoodRuntime.d.ts +124 -0
- package/dist/DogfoodRuntime.js +273 -0
- package/dist/FeedbackModal.js +505 -65
- package/dist/LoginScreen.d.ts +1 -5
- package/dist/LoginScreen.js +2 -6
- package/dist/MachinePickerScreen.d.ts +1 -3
- package/dist/MachinePickerScreen.js +6 -18
- package/dist/P2PClient.d.ts +178 -2
- package/dist/P2PClient.js +493 -3
- package/dist/P2PDogfoodDriver.d.ts +12 -0
- package/dist/P2PDogfoodDriver.js +118 -0
- package/dist/PairDeviceModal.d.ts +2 -3
- package/dist/ShakeDetector.js +2 -0
- package/dist/VibeChatScreen.d.ts +11 -1
- package/dist/VibeChatScreen.js +200 -41
- package/dist/YaverFeedback.d.ts +132 -0
- package/dist/YaverFeedback.js +633 -65
- package/dist/YaverModeBadge.d.ts +22 -0
- package/dist/YaverModeBadge.js +219 -0
- package/dist/__tests__/AuthDevices.test.js +1 -48
- package/dist/__tests__/BlackBox.relayPassword.test.d.ts +1 -0
- package/dist/__tests__/BlackBox.relayPassword.test.js +105 -0
- package/dist/__tests__/BlackBoxAutoStart.test.d.ts +1 -0
- package/dist/__tests__/BlackBoxAutoStart.test.js +91 -0
- package/dist/__tests__/BlackBoxAutoStartColdStart.test.d.ts +1 -0
- package/dist/__tests__/BlackBoxAutoStartColdStart.test.js +156 -0
- package/dist/__tests__/BrowserLaneIcon.test.d.ts +3 -0
- package/dist/__tests__/BrowserLaneIcon.test.js +80 -0
- package/dist/__tests__/DogfoodRuntime.test.d.ts +1 -0
- package/dist/__tests__/DogfoodRuntime.test.js +116 -0
- package/dist/__tests__/P2PClient.test.js +2 -2
- package/dist/__tests__/P2PDogfoodDriver.test.d.ts +1 -0
- package/dist/__tests__/P2PDogfoodDriver.test.js +64 -0
- package/dist/__tests__/ReportIdentity.test.d.ts +25 -0
- package/dist/__tests__/ReportIdentity.test.js +180 -0
- package/dist/__tests__/SDKToken.test.js +1 -1
- package/dist/__tests__/ShakeToggle.test.d.ts +1 -0
- package/dist/__tests__/ShakeToggle.test.js +121 -0
- package/dist/__tests__/YaverFeedback.test.js +13 -3
- package/dist/__tests__/deviceDogfood.test.d.ts +1 -0
- package/dist/__tests__/deviceDogfood.test.js +86 -0
- package/dist/__tests__/dogfoodPolicy.test.d.ts +1 -0
- package/dist/__tests__/dogfoodPolicy.test.js +33 -0
- package/dist/__tests__/pickTargetDevice.test.d.ts +1 -0
- package/dist/__tests__/pickTargetDevice.test.js +89 -0
- package/dist/__tests__/reloadActions.test.d.ts +1 -0
- package/dist/__tests__/reloadActions.test.js +129 -0
- package/dist/__tests__/reloadActionsParity.test.d.ts +1 -0
- package/dist/__tests__/reloadActionsParity.test.js +42 -0
- package/dist/__tests__/types.test.js +5 -5
- package/dist/_core/ansi.d.ts +117 -0
- package/dist/_core/ansi.js +468 -0
- package/dist/_core/ansi.test.d.ts +1 -0
- package/dist/_core/ansi.test.js +225 -0
- package/dist/_core/buildFeedbackPrompt.d.ts +4 -9
- package/dist/_core/buildFeedbackPrompt.js +18 -72
- package/dist/_core/constants.d.ts +19 -6
- package/dist/_core/constants.js +20 -7
- package/dist/_core/device.d.ts +1 -5
- package/dist/_core/device.js +5 -14
- package/dist/_core/endpoints.d.ts +0 -7
- package/dist/_core/endpoints.js +0 -7
- package/dist/_core/index.d.ts +4 -0
- package/dist/_core/index.js +4 -0
- package/dist/_core/remoteless.d.ts +44 -0
- package/dist/_core/remoteless.js +75 -0
- package/dist/_core/trace.d.ts +47 -0
- package/dist/_core/trace.js +38 -0
- package/dist/_core/trace.test.d.ts +1 -0
- package/dist/_core/trace.test.js +60 -0
- package/dist/auth.d.ts +3 -60
- package/dist/auth.js +6 -88
- package/dist/deviceDogfood.d.ts +53 -0
- package/dist/deviceDogfood.js +137 -0
- package/dist/dogfoodPolicy.d.ts +25 -0
- package/dist/dogfoodPolicy.js +24 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +33 -7
- package/dist/reloadActions.d.ts +88 -0
- package/dist/reloadActions.js +200 -0
- package/dist/storeShots.d.ts +67 -0
- package/dist/storeShots.js +137 -0
- package/dist/types.d.ts +208 -8
- package/package.json +13 -4
- package/src/AuthOverlay.tsx +20 -106
- package/src/BlackBox.ts +10 -1
- package/src/DeployPanel.tsx +74 -0
- package/src/Discovery.ts +13 -8
- package/src/DogfoodRuntime.ts +373 -0
- package/src/FeedbackModal.tsx +619 -79
- package/src/LoginScreen.tsx +2 -22
- package/src/MachinePickerScreen.tsx +6 -21
- package/src/P2PClient.ts +580 -4
- package/src/P2PDogfoodDriver.ts +132 -0
- package/src/PairDeviceModal.tsx +2 -3
- package/src/ShakeDetector.ts +1 -0
- package/src/VibeChatScreen.tsx +232 -42
- package/src/YaverFeedback.ts +631 -68
- package/src/YaverModeBadge.tsx +234 -0
- package/src/__tests__/AuthDevices.test.ts +1 -52
- package/src/__tests__/BlackBox.relayPassword.test.ts +129 -0
- package/src/__tests__/BlackBoxAutoStart.test.ts +111 -0
- package/src/__tests__/BlackBoxAutoStartColdStart.test.ts +191 -0
- package/src/__tests__/BrowserLaneIcon.test.ts +85 -0
- package/src/__tests__/DogfoodRuntime.test.ts +135 -0
- package/src/__tests__/P2PClient.test.ts +2 -2
- package/src/__tests__/P2PDogfoodDriver.test.ts +80 -0
- package/src/__tests__/ReportIdentity.test.ts +212 -0
- package/src/__tests__/SDKToken.test.ts +1 -1
- package/src/__tests__/ShakeToggle.test.ts +153 -0
- package/src/__tests__/YaverFeedback.test.ts +15 -3
- package/src/__tests__/deviceDogfood.test.ts +77 -0
- package/src/__tests__/dogfoodPolicy.test.ts +34 -0
- package/src/__tests__/pickTargetDevice.test.ts +101 -0
- package/src/__tests__/reloadActions.test.ts +171 -0
- package/src/__tests__/reloadActionsParity.test.ts +49 -0
- package/src/__tests__/types.test.ts +5 -5
- package/src/_core/ansi.test.ts +250 -0
- package/src/_core/ansi.ts +475 -0
- package/src/_core/buildFeedbackPrompt.ts +18 -95
- package/src/_core/constants.ts +20 -6
- package/src/_core/device.ts +5 -16
- package/src/_core/endpoints.ts +0 -7
- package/src/_core/index.ts +4 -0
- package/src/_core/remoteless.ts +110 -0
- package/src/_core/trace.test.ts +58 -0
- package/src/_core/trace.ts +75 -0
- package/src/auth.ts +7 -156
- package/src/deviceDogfood.ts +171 -0
- package/src/dogfoodPolicy.ts +40 -0
- package/src/index.ts +61 -11
- package/src/reloadActions.ts +273 -0
- package/src/storeShots.ts +189 -0
- package/src/types.ts +209 -8
- package/dist/GuestOnboardingScreen.d.ts +0 -8
- package/dist/GuestOnboardingScreen.js +0 -282
- package/src/GuestOnboardingScreen.tsx +0 -307
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-device App Store screenshot capture (Engine 2).
|
|
3
|
+
*
|
|
4
|
+
* The desktop `yaver shots` flow drives a simulator with Maestro. This is
|
|
5
|
+
* the in-app counterpart: the SDK, living inside the real running app,
|
|
6
|
+
* walks the app's own routes and screenshots each one with
|
|
7
|
+
* `react-native-view-shot`, then uploads the frames to the Yaver agent
|
|
8
|
+
* (POST /shots/upload). The agent normalizes them and runs the same App
|
|
9
|
+
* Store Connect backend (upload → metadata → submit).
|
|
10
|
+
*
|
|
11
|
+
* Why this exists alongside the simulator path: it captures *real device*
|
|
12
|
+
* pixels, knows the exact route map (no heuristics), and the user is
|
|
13
|
+
* already authenticated — so it sidesteps the i18n / no-testID fragility
|
|
14
|
+
* that makes a blind simulator walk hard.
|
|
15
|
+
*
|
|
16
|
+
* The host wires it once by handing us a navigation ref (react-navigation
|
|
17
|
+
* or expo-router router) plus the ordered list of routes to visit.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { captureScreenshotBase64 } from './capture';
|
|
21
|
+
|
|
22
|
+
export interface StoreShotFrame {
|
|
23
|
+
route: string;
|
|
24
|
+
base64: string;
|
|
25
|
+
mimeType: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CaptureStoreScreenshotsOptions {
|
|
29
|
+
/** Yaver agent base URL (e.g. http://192.168.1.5:18080 or a relay URL). */
|
|
30
|
+
agentUrl: string;
|
|
31
|
+
/** Bearer token for the agent (same-user envelope). */
|
|
32
|
+
authToken: string;
|
|
33
|
+
/** Relay password — required only when agentUrl is relay-routed. */
|
|
34
|
+
relayPassword?: string;
|
|
35
|
+
|
|
36
|
+
/** App name (vault scope / job label on the agent side). */
|
|
37
|
+
app: string;
|
|
38
|
+
/** iOS bundle id; the agent falls back to app.json if omitted. */
|
|
39
|
+
bundleId?: string;
|
|
40
|
+
/** App Store localization (default en-US). */
|
|
41
|
+
locale?: string;
|
|
42
|
+
/** When true, the agent also sets metadata + attempts submit-for-review. */
|
|
43
|
+
submit?: boolean;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Navigation handle. Either a react-navigation ref (has `.navigate`) or
|
|
47
|
+
* an expo-router `router` (has `.push`/`.navigate`). We call the first
|
|
48
|
+
* available method with the route string.
|
|
49
|
+
*/
|
|
50
|
+
navigationRef?: any;
|
|
51
|
+
/** Ordered routes to visit + screenshot (e.g. ['/(tabs)/dashboard', ...]). */
|
|
52
|
+
routes: string[];
|
|
53
|
+
|
|
54
|
+
/** Optional per-route screenshot names (defaults to NN_<sanitized route>). */
|
|
55
|
+
screens?: string[];
|
|
56
|
+
/** Milliseconds to wait after navigating before capturing (default 900). */
|
|
57
|
+
settleMs?: number;
|
|
58
|
+
/** Hook the host can use to hide its own overlay before each capture. */
|
|
59
|
+
onBeforeCapture?: (route: string, index: number) => void | Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface CaptureStoreScreenshotsResult {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
captured: number;
|
|
65
|
+
uploaded: number;
|
|
66
|
+
submitted?: boolean;
|
|
67
|
+
staged?: boolean;
|
|
68
|
+
message?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function sleep(ms: number): Promise<void> {
|
|
72
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function navigateTo(navRef: any, route: string): void {
|
|
76
|
+
if (!navRef) return;
|
|
77
|
+
// react-navigation ref
|
|
78
|
+
if (typeof navRef.navigate === 'function') {
|
|
79
|
+
navRef.navigate(route as never);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// expo-router router
|
|
83
|
+
if (typeof navRef.push === 'function') {
|
|
84
|
+
navRef.push(route);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (navRef.current && typeof navRef.current.navigate === 'function') {
|
|
88
|
+
navRef.current.navigate(route as never);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function shotName(route: string, index: number, override?: string): string {
|
|
94
|
+
if (override) return override;
|
|
95
|
+
const clean = route
|
|
96
|
+
.replace(/^\/+/, '')
|
|
97
|
+
.replace(/[()[\]/]+/g, '_')
|
|
98
|
+
.replace(/[^a-zA-Z0-9_]+/g, '')
|
|
99
|
+
.replace(/^_+|_+$/g, '');
|
|
100
|
+
const n = String(index + 1).padStart(2, '0');
|
|
101
|
+
return `${n}_${clean || 'screen'}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Walk the app's routes, screenshot each, and upload the batch to the
|
|
106
|
+
* agent. Returns a summary; never throws for a single missed route —
|
|
107
|
+
* it captures what it can and reports the count.
|
|
108
|
+
*/
|
|
109
|
+
export async function captureStoreScreenshots(
|
|
110
|
+
opts: CaptureStoreScreenshotsOptions,
|
|
111
|
+
): Promise<CaptureStoreScreenshotsResult> {
|
|
112
|
+
if (!opts.agentUrl || !opts.authToken) {
|
|
113
|
+
return { ok: false, captured: 0, uploaded: 0, message: 'agentUrl + authToken required' };
|
|
114
|
+
}
|
|
115
|
+
if (!opts.routes?.length) {
|
|
116
|
+
return { ok: false, captured: 0, uploaded: 0, message: 'no routes to capture' };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const settleMs = opts.settleMs ?? 900;
|
|
120
|
+
const frames: StoreShotFrame[] = [];
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < opts.routes.length; i++) {
|
|
123
|
+
const route = opts.routes[i];
|
|
124
|
+
try {
|
|
125
|
+
navigateTo(opts.navigationRef, route);
|
|
126
|
+
await sleep(settleMs);
|
|
127
|
+
if (opts.onBeforeCapture) await opts.onBeforeCapture(route, i);
|
|
128
|
+
const shot = await captureScreenshotBase64();
|
|
129
|
+
if (shot?.base64) {
|
|
130
|
+
frames.push({
|
|
131
|
+
route: shotName(route, i, opts.screens?.[i]),
|
|
132
|
+
base64: shot.base64,
|
|
133
|
+
mimeType: shot.mimeType,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
} catch {
|
|
137
|
+
// Skip a route that failed to render — keep walking.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (frames.length === 0) {
|
|
142
|
+
return { ok: false, captured: 0, uploaded: 0, message: 'captured no frames' };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const headers: Record<string, string> = {
|
|
146
|
+
Authorization: `Bearer ${opts.authToken}`,
|
|
147
|
+
'Content-Type': 'application/json',
|
|
148
|
+
};
|
|
149
|
+
if (opts.relayPassword) headers['X-Relay-Password'] = opts.relayPassword;
|
|
150
|
+
|
|
151
|
+
const base = opts.agentUrl.replace(/\/$/, '');
|
|
152
|
+
try {
|
|
153
|
+
const resp = await fetch(`${base}/shots/upload`, {
|
|
154
|
+
method: 'POST',
|
|
155
|
+
headers,
|
|
156
|
+
body: JSON.stringify({
|
|
157
|
+
app: opts.app,
|
|
158
|
+
bundleId: opts.bundleId ?? '',
|
|
159
|
+
locale: opts.locale ?? 'en-US',
|
|
160
|
+
submit: !!opts.submit,
|
|
161
|
+
frames,
|
|
162
|
+
}),
|
|
163
|
+
});
|
|
164
|
+
const j = await resp.json().catch(() => ({}));
|
|
165
|
+
if (!resp.ok || j?.ok === false) {
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
captured: frames.length,
|
|
169
|
+
uploaded: 0,
|
|
170
|
+
message: j?.error || `agent /shots/upload HTTP ${resp.status}`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
ok: true,
|
|
175
|
+
captured: frames.length,
|
|
176
|
+
uploaded: typeof j?.uploaded === 'number' ? j.uploaded : frames.length,
|
|
177
|
+
submitted: j?.submitted,
|
|
178
|
+
staged: j?.staged,
|
|
179
|
+
message: j?.message,
|
|
180
|
+
};
|
|
181
|
+
} catch (e: any) {
|
|
182
|
+
return {
|
|
183
|
+
ok: false,
|
|
184
|
+
captured: frames.length,
|
|
185
|
+
uploaded: 0,
|
|
186
|
+
message: `upload failed: ${e?.message ?? 'network error'}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// Type-only: BlackBox.ts already imports from this module, so a value import
|
|
2
|
+
// would close a cycle. `import type` is erased at compile time.
|
|
3
|
+
import type { BlackBoxConfig } from './BlackBox';
|
|
4
|
+
import type { SDKDogfoodConfig } from './dogfoodPolicy';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Remote browser-style sign-in session for a coding-agent CLI on the
|
|
3
8
|
* connected yaver host. Mirrors runnerBrowserAuthSession on the agent
|
|
@@ -32,6 +37,8 @@ export interface RunnerAuthStatusRow {
|
|
|
32
37
|
path?: string;
|
|
33
38
|
detail?: string;
|
|
34
39
|
version?: string;
|
|
40
|
+
isDefault?: boolean;
|
|
41
|
+
models?: Array<{ id: string; name?: string; provider?: string; isDefault?: boolean }>;
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
export interface OpenCodeProviderSummary {
|
|
@@ -122,9 +129,67 @@ export interface CapabilitySnapshot {
|
|
|
122
129
|
targets: Record<string, CapabilityTargetReadiness>;
|
|
123
130
|
}
|
|
124
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Opt-in config for the overlay's "App Store screenshots" action and the
|
|
134
|
+
* `capture_store_shots` remote command. When set, the SDK can walk the
|
|
135
|
+
* app's routes on-device, screenshot each, and upload them to the agent
|
|
136
|
+
* (which runs the App Store Connect backend).
|
|
137
|
+
*/
|
|
138
|
+
export interface StoreShotsConfig {
|
|
139
|
+
/** Ordered routes to visit + screenshot (e.g. ['/(tabs)/home', ...]). */
|
|
140
|
+
routes: string[];
|
|
141
|
+
/** Navigation handle: a react-navigation ref or expo-router `router`. */
|
|
142
|
+
navigationRef?: any;
|
|
143
|
+
/** Also set metadata + attempt submit-for-review after upload. */
|
|
144
|
+
submit?: boolean;
|
|
145
|
+
/** Optional per-route screenshot names (defaults to NN_<route>). */
|
|
146
|
+
screens?: string[];
|
|
147
|
+
}
|
|
148
|
+
|
|
125
149
|
export interface FeedbackConfig {
|
|
126
150
|
/** URL of the Yaver agent (e.g. "http://192.168.1.10:18080"). If omitted, auto-discovery is used. */
|
|
127
151
|
agentUrl?: string;
|
|
152
|
+
/** Optional coding route. Defaults to agentUrl. */
|
|
153
|
+
codingAgentUrl?: string;
|
|
154
|
+
/** Optional render/reload route. Defaults to codingAgentUrl/agentUrl. */
|
|
155
|
+
renderAgentUrl?: string;
|
|
156
|
+
/** Device identities shown in the unified Settings card when routes differ. */
|
|
157
|
+
codingDeviceId?: string;
|
|
158
|
+
renderDeviceId?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Show the small "Y" mark while this app is running INSIDE Yaver's container
|
|
161
|
+
* (a Hermes-pushed development bundle), so a tester can tell it apart from
|
|
162
|
+
* the build they installed — and can find the way back.
|
|
163
|
+
*
|
|
164
|
+
* DEFAULT TRUE. The failure it prevents is silent and lands on a tester
|
|
165
|
+
* rather than a developer: an app that looks installed but is someone's
|
|
166
|
+
* branch produces "bug reports" against unfinished work, and a tester with
|
|
167
|
+
* no visible way out is simply stuck. That class should not be opt-in.
|
|
168
|
+
*
|
|
169
|
+
* Costs nothing in a standalone build — outside Yaver's container the badge
|
|
170
|
+
* renders null (the YaverInfo native module is absent), so shipping with it
|
|
171
|
+
* enabled has no effect on what your users see.
|
|
172
|
+
*
|
|
173
|
+
* Set false if your app already shows its own in-container indicator, or if
|
|
174
|
+
* a pixel-exact surface cannot spare 22 points in a corner.
|
|
175
|
+
*/
|
|
176
|
+
modeBadge?: boolean;
|
|
177
|
+
/** Corner for the mode badge. Default 'bottom-left' — bottom-right is where
|
|
178
|
+
* most apps put a FAB, and the badge must never compete with the app's own
|
|
179
|
+
* primary action. */
|
|
180
|
+
modeBadgePosition?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
181
|
+
/** Account-scoped direct Dogfood UX for an approved third-party app.
|
|
182
|
+
* When the current app account is allowlisted, the small Y opens Vibing
|
|
183
|
+
* directly instead of the normal feedback actions. This is a client UX gate,
|
|
184
|
+
* never an authentication mechanism; agent calls still require Yaver auth. */
|
|
185
|
+
dogfood?: SDKDogfoodConfig;
|
|
186
|
+
/**
|
|
187
|
+
* Enables the overlay's "App Store screenshots" action + the
|
|
188
|
+
* `capture_store_shots` remote command. The host supplies the route
|
|
189
|
+
* list (and a navigation ref) once; the SDK captures the real running
|
|
190
|
+
* app — no simulator needed.
|
|
191
|
+
*/
|
|
192
|
+
storeShots?: StoreShotsConfig;
|
|
128
193
|
/**
|
|
129
194
|
* Auth token for the Yaver agent. Optional in 0.5+: if omitted, the SDK
|
|
130
195
|
* will hydrate one from AsyncStorage or show its in-app login screen
|
|
@@ -164,6 +229,47 @@ export interface FeedbackConfig {
|
|
|
164
229
|
* If omitted with convexUrl, connects to the first online device.
|
|
165
230
|
*/
|
|
166
231
|
preferredDeviceId?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Identity of the app this SDK instance reports for. Both fields are
|
|
234
|
+
* resolved automatically from expo-constants / native modules when
|
|
235
|
+
* omitted, so most apps never set them.
|
|
236
|
+
*
|
|
237
|
+
* Set them when the ambient answer would be wrong — above all when the
|
|
238
|
+
* app's JS is pushed into Yaver's container as a Hermes guest. There the
|
|
239
|
+
* runtime IS Yaver: `expo-constants` and `SettingsManager` describe the
|
|
240
|
+
* host (`Yaver` / `io.yaver.mobile`), not the guest, so auto-resolution
|
|
241
|
+
* would file every report against Yaver's own repo and the fix task would
|
|
242
|
+
* edit the SDK instead of the app. Declaring identity here is the only
|
|
243
|
+
* answer that holds in both a standalone build and a guest bundle.
|
|
244
|
+
*
|
|
245
|
+
* `bundleId` is the key that actually routes: the agent matches it against
|
|
246
|
+
* each project's pbxproj / build.gradle / app.json. `projectName` is a
|
|
247
|
+
* fallback for platforms with no bundle id.
|
|
248
|
+
*/
|
|
249
|
+
projectName?: string;
|
|
250
|
+
bundleId?: string;
|
|
251
|
+
/** Primary Yaver product surface for this app/package. */
|
|
252
|
+
surface?: YaverSurface;
|
|
253
|
+
/** All product surfaces this app/package owns. */
|
|
254
|
+
surfaces?: YaverSurface[];
|
|
255
|
+
/** Canonical development stack labels, e.g. react-native-expo, yaver-xml. */
|
|
256
|
+
stack?: string;
|
|
257
|
+
stacks?: string[];
|
|
258
|
+
/** Yaver preview/runtime targets that can exercise this app. */
|
|
259
|
+
testSurfaces?: string[];
|
|
260
|
+
feedbackSdk?: string;
|
|
261
|
+
feedbackTransport?: string;
|
|
262
|
+
voiceCapabilities?: string[];
|
|
263
|
+
sttProvider?: string;
|
|
264
|
+
ttsProvider?: string;
|
|
265
|
+
/**
|
|
266
|
+
* Opt in to the microphone/STT controls in the feedback Vibing card.
|
|
267
|
+
*
|
|
268
|
+
* This is deliberately false unless explicitly enabled: ordinary phone
|
|
269
|
+
* and tablet surfaces stay keyboard-first. Car/watch-style hosts that are
|
|
270
|
+
* inherently voice-driven may set this to true.
|
|
271
|
+
*/
|
|
272
|
+
voiceInputEnabled?: boolean;
|
|
167
273
|
/** How feedback collection is triggered */
|
|
168
274
|
trigger?: 'shake' | 'floating-button' | 'manual';
|
|
169
275
|
/**
|
|
@@ -204,6 +310,22 @@ export interface FeedbackConfig {
|
|
|
204
310
|
* Calling `BlackBox.start()` manually is still safe — it's idempotent.
|
|
205
311
|
*/
|
|
206
312
|
autoStartBlackBox?: boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Config handed to BlackBox when the SDK auto-starts it.
|
|
315
|
+
*
|
|
316
|
+
* Without this there was no way to configure the flight recorder at all.
|
|
317
|
+
* The obvious move — and the one the README's own snippet makes — is:
|
|
318
|
+
*
|
|
319
|
+
* YaverFeedback.init({ trigger: 'shake' });
|
|
320
|
+
* BlackBox.start({ appName: 'my-app' });
|
|
321
|
+
*
|
|
322
|
+
* but that start() early-returns, because a zero-config init has no
|
|
323
|
+
* agentUrl yet (discovery resolves it asynchronously). The auto-start then
|
|
324
|
+
* fires ~500ms later once the agent and token exist and calls `start()`
|
|
325
|
+
* with NO arguments — so the host's config is silently dropped and appName
|
|
326
|
+
* is ''. Pass it here instead and the auto-start will honour it.
|
|
327
|
+
*/
|
|
328
|
+
blackBox?: BlackBoxConfig;
|
|
207
329
|
/**
|
|
208
330
|
* Small tap-to-open icon that floats above the app so the user
|
|
209
331
|
* doesn't have to shake every time they want to open feedback.
|
|
@@ -289,6 +411,26 @@ export interface FeedbackConfig {
|
|
|
289
411
|
* Bugsnag, or any other error tracking tool.
|
|
290
412
|
*/
|
|
291
413
|
maxCapturedErrors?: number;
|
|
414
|
+
/**
|
|
415
|
+
* Crash-aware reporting/fixing. Defaults to disabled.
|
|
416
|
+
*
|
|
417
|
+
* - enabled: records fatal errors into the SDK error buffer and enables
|
|
418
|
+
* explicit `YaverFeedback.reportCrash(error)`.
|
|
419
|
+
* - installGlobalHandler: opt-in only. Wraps React Native's global ErrorUtils
|
|
420
|
+
* handler without suppressing the existing handler. Leave false when Sentry,
|
|
421
|
+
* Crashlytics, Bugsnag, or another crash tool owns the global handler.
|
|
422
|
+
* - autoFix: after uploading a crash report, ask the connected Yaver agent to
|
|
423
|
+
* create a fix task. The normal BlackBox command stream can then deliver a
|
|
424
|
+
* reload/reload_bundle command after the agent rebuilds.
|
|
425
|
+
* - captureScreenshot: attach a best-effort screenshot to the crash report.
|
|
426
|
+
*/
|
|
427
|
+
crashReporting?: {
|
|
428
|
+
enabled?: boolean;
|
|
429
|
+
installGlobalHandler?: boolean;
|
|
430
|
+
autoFix?: boolean;
|
|
431
|
+
captureScreenshot?: boolean;
|
|
432
|
+
metadata?: Record<string, unknown>;
|
|
433
|
+
};
|
|
292
434
|
/**
|
|
293
435
|
* Which platforms the Build button targets.
|
|
294
436
|
* - 'ios' — build iOS only
|
|
@@ -368,13 +510,6 @@ export interface FeedbackConfig {
|
|
|
368
510
|
* Default: false (preserve historical behavior).
|
|
369
511
|
*/
|
|
370
512
|
strictNativeAuth?: boolean;
|
|
371
|
-
/**
|
|
372
|
-
* Optional host invite code to prefill into the in-SDK guest onboarding
|
|
373
|
-
* flow. Useful when your app receives the code from a deep link, QR flow,
|
|
374
|
-
* or an out-of-band host handoff and you want the user to redeem it
|
|
375
|
-
* without typing.
|
|
376
|
-
*/
|
|
377
|
-
guestInviteCode?: string;
|
|
378
513
|
}
|
|
379
514
|
|
|
380
515
|
export interface FeedbackBundle {
|
|
@@ -404,9 +539,36 @@ export interface CapturedError {
|
|
|
404
539
|
|
|
405
540
|
export interface FeedbackMetadata {
|
|
406
541
|
timestamp: string;
|
|
407
|
-
|
|
542
|
+
/**
|
|
543
|
+
* Wire key is `deviceInfo`, matching the Flutter + web SDKs and the
|
|
544
|
+
* agent's `FeedbackReport.DeviceInfo` (`json:"deviceInfo"`). This was
|
|
545
|
+
* `device` until 0.9.2 — a key the agent never read, so the whole block
|
|
546
|
+
* (platform, model, and the app name the fix router needs) was silently
|
|
547
|
+
* dropped on every React Native report. The agent still accepts the old
|
|
548
|
+
* key so builds already in the field keep working.
|
|
549
|
+
*/
|
|
550
|
+
deviceInfo: DeviceInfo;
|
|
408
551
|
app: AppInfo;
|
|
552
|
+
/**
|
|
553
|
+
* Which of the host's projects this report is about. The agent resolves
|
|
554
|
+
* a feedback→fix task's working directory from this; without it the task
|
|
555
|
+
* falls back to whatever directory the agent happens to be sitting in.
|
|
556
|
+
* Populated automatically by `resolveReportIdentity()`.
|
|
557
|
+
*/
|
|
558
|
+
project?: FeedbackProjectRef;
|
|
409
559
|
userNote?: string;
|
|
560
|
+
reportKind?: 'feedback' | 'auto-report' | 'crash';
|
|
561
|
+
crash?: {
|
|
562
|
+
message: string;
|
|
563
|
+
isFatal: boolean;
|
|
564
|
+
source: 'manual' | 'global-handler';
|
|
565
|
+
autoFixRequested?: boolean;
|
|
566
|
+
};
|
|
567
|
+
twin?: {
|
|
568
|
+
sessionId?: string;
|
|
569
|
+
surface?: string;
|
|
570
|
+
artifactDir?: string;
|
|
571
|
+
};
|
|
410
572
|
}
|
|
411
573
|
|
|
412
574
|
export interface DeviceInfo {
|
|
@@ -415,6 +577,8 @@ export interface DeviceInfo {
|
|
|
415
577
|
model: string;
|
|
416
578
|
screenWidth: number;
|
|
417
579
|
screenHeight: number;
|
|
580
|
+
/** Host app name. First key the agent's fix router checks. */
|
|
581
|
+
appName?: string;
|
|
418
582
|
}
|
|
419
583
|
|
|
420
584
|
export interface AppInfo {
|
|
@@ -423,6 +587,43 @@ export interface AppInfo {
|
|
|
423
587
|
buildNumber?: string;
|
|
424
588
|
}
|
|
425
589
|
|
|
590
|
+
/**
|
|
591
|
+
* Identifies the host project a report belongs to. Mirrors the web SDK's
|
|
592
|
+
* `FeedbackProjectRef` and the agent's `FeedbackProject`.
|
|
593
|
+
*/
|
|
594
|
+
export interface FeedbackProjectRef {
|
|
595
|
+
appName?: string;
|
|
596
|
+
projectName?: string;
|
|
597
|
+
/**
|
|
598
|
+
* Bundle identifier / applicationId. The only unambiguous key: an app's
|
|
599
|
+
* display name ("Talos") does not match the agent's registry name for it
|
|
600
|
+
* ("talos / mobile"), and one repo can hold several mobile projects that
|
|
601
|
+
* all share a name prefix. The agent matches this against the project's
|
|
602
|
+
* pbxproj, build.gradle, and app.json.
|
|
603
|
+
*/
|
|
604
|
+
bundleId?: string;
|
|
605
|
+
/**
|
|
606
|
+
* Deliberately never set by this SDK. The agent ignores client-supplied
|
|
607
|
+
* paths for feedback reports (an untrusted guest could otherwise point the
|
|
608
|
+
* fix task's CWD at ~/.ssh) and resolves the path server-side. Present only
|
|
609
|
+
* so the type matches the wire format the agent parses.
|
|
610
|
+
*/
|
|
611
|
+
projectPath?: string;
|
|
612
|
+
surface?: YaverSurface;
|
|
613
|
+
surfaces?: YaverSurface[];
|
|
614
|
+
stack?: string;
|
|
615
|
+
stacks?: string[];
|
|
616
|
+
testSurfaces?: string[];
|
|
617
|
+
feedbackSdk?: string;
|
|
618
|
+
feedbackTransport?: string;
|
|
619
|
+
voiceCapabilities?: string[];
|
|
620
|
+
sttProvider?: string;
|
|
621
|
+
ttsProvider?: string;
|
|
622
|
+
releaseChannel?: 'production' | 'candidate' | 'development';
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export type YaverSurface = 'web' | 'mobile' | 'backend' | 'watch' | 'tv' | 'car' | 'vision' | 'desktop' | 'cli';
|
|
626
|
+
|
|
426
627
|
export interface TimelineEvent {
|
|
427
628
|
type: 'screenshot' | 'audio' | 'video';
|
|
428
629
|
path: string;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export interface YaverGuestOnboardingScreenProps {
|
|
3
|
-
token: string;
|
|
4
|
-
initialInviteCode?: string;
|
|
5
|
-
onContinue: () => void;
|
|
6
|
-
onCancel?: () => void;
|
|
7
|
-
}
|
|
8
|
-
export declare const YaverGuestOnboardingScreen: React.FC<YaverGuestOnboardingScreenProps>;
|