yaver-feedback-react-native 0.9.6 → 0.9.8

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.
@@ -0,0 +1,394 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DogfoodQuickControls = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const YaverFeedback_1 = require("./YaverFeedback");
40
+ const preferences_1 = require("./preferences");
41
+ const FALLBACK_SIZE = 36;
42
+ const DOCK_VISIBLE = 21;
43
+ const SAFE_TOP = 64;
44
+ const SAFE_BOTTOM = 92;
45
+ const EMPTY_STATE = {
46
+ configured: false,
47
+ authorized: false,
48
+ gestureSupported: false,
49
+ gestureEnabled: false,
50
+ fallbackVisible: false,
51
+ presentation: 'auto',
52
+ onboardingSeen: false,
53
+ reason: 'not-configured',
54
+ };
55
+ function preferenceScope(state) {
56
+ return state.appId && state.installationId ? `${state.appId}:${state.installationId}` : undefined;
57
+ }
58
+ /**
59
+ * The standalone SDK's only persistent chrome. A newly authorized tester sees
60
+ * this edge-docked Y until first-run onboarding is completed in Convex. After
61
+ * that, capable devices default to a passive three-finger hold; unsupported
62
+ * devices keep the Y. Both entry points open exactly the same compact card.
63
+ */
64
+ const DogfoodQuickControls = () => {
65
+ const { width, height } = (0, react_native_1.useWindowDimensions)();
66
+ const orientation = width > height ? 'landscape' : 'portrait';
67
+ const defaultPosition = (0, react_1.useMemo)(() => ({
68
+ x: Math.max(width - DOCK_VISIBLE, 0),
69
+ y: Math.max(Math.round(height * 0.45), SAFE_TOP),
70
+ }), [height, width]);
71
+ const pan = (0, react_1.useRef)(new react_native_1.Animated.ValueXY(defaultPosition)).current;
72
+ const opacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0.72)).current;
73
+ const lastPosition = (0, react_1.useRef)(defaultPosition);
74
+ const dragStart = (0, react_1.useRef)(defaultPosition);
75
+ const dragged = (0, react_1.useRef)(false);
76
+ const fadeTimer = (0, react_1.useRef)(null);
77
+ const [dockEdge, setDockEdge] = (0, react_1.useState)('right');
78
+ const [keyboardVisible, setKeyboardVisible] = (0, react_1.useState)(false);
79
+ const [state, setState] = (0, react_1.useState)(EMPTY_STATE);
80
+ const [open, setOpen] = (0, react_1.useState)(false);
81
+ const [showControlSettings, setShowControlSettings] = (0, react_1.useState)(false);
82
+ const [busy, setBusy] = (0, react_1.useState)(null);
83
+ const [message, setMessage] = (0, react_1.useState)(null);
84
+ const scheduleFade = (0, react_1.useCallback)(() => {
85
+ if (fadeTimer.current)
86
+ clearTimeout(fadeTimer.current);
87
+ fadeTimer.current = setTimeout(() => {
88
+ react_native_1.Animated.timing(opacity, { toValue: 0.42, duration: 260, useNativeDriver: true }).start();
89
+ }, 1800);
90
+ }, [opacity]);
91
+ const wakeControl = (0, react_1.useCallback)(() => {
92
+ if (fadeTimer.current)
93
+ clearTimeout(fadeTimer.current);
94
+ react_native_1.Animated.timing(opacity, { toValue: 1, duration: 100, useNativeDriver: true }).start();
95
+ }, [opacity]);
96
+ const refresh = (0, react_1.useCallback)(async () => {
97
+ try {
98
+ setState(await YaverFeedback_1.YaverFeedback.syncDogfoodControlGesture());
99
+ }
100
+ catch {
101
+ setState(EMPTY_STATE);
102
+ }
103
+ }, []);
104
+ (0, react_1.useEffect)(() => {
105
+ void refresh();
106
+ const trigger = react_native_1.DeviceEventEmitter.addListener('yaverDogfoodControlGesture', () => {
107
+ setMessage(null);
108
+ setShowControlSettings(false);
109
+ setOpen(true);
110
+ });
111
+ const capability = react_native_1.DeviceEventEmitter.addListener('yaverDogfoodControlCapability', () => {
112
+ void refresh();
113
+ });
114
+ return () => {
115
+ trigger.remove();
116
+ capability.remove();
117
+ };
118
+ }, [refresh]);
119
+ (0, react_1.useEffect)(() => {
120
+ const show = react_native_1.Keyboard.addListener('keyboardDidShow', () => setKeyboardVisible(true));
121
+ const hide = react_native_1.Keyboard.addListener('keyboardDidHide', () => setKeyboardVisible(false));
122
+ return () => { show.remove(); hide.remove(); };
123
+ }, []);
124
+ (0, react_1.useEffect)(() => {
125
+ let cancelled = false;
126
+ void (async () => {
127
+ const saved = await (0, preferences_1.getDogfoodControlPosition)(orientation, preferenceScope(state));
128
+ if (cancelled)
129
+ return;
130
+ const edge = saved?.edge || 'right';
131
+ const minY = SAFE_TOP;
132
+ const maxY = Math.max(minY, height - FALLBACK_SIZE - SAFE_BOTTOM);
133
+ const y = saved
134
+ ? minY + (maxY - minY) * saved.yRatio
135
+ : Math.max(minY, Math.min(maxY, Math.round(height * 0.45)));
136
+ const next = { x: edge === 'left' ? -FALLBACK_SIZE + DOCK_VISIBLE : width - DOCK_VISIBLE, y };
137
+ setDockEdge(edge);
138
+ lastPosition.current = next;
139
+ pan.setValue(next);
140
+ scheduleFade();
141
+ })();
142
+ return () => { cancelled = true; };
143
+ }, [height, orientation, pan, scheduleFade, state.appId, state.installationId, width]);
144
+ (0, react_1.useEffect)(() => () => {
145
+ if (fadeTimer.current)
146
+ clearTimeout(fadeTimer.current);
147
+ }, []);
148
+ const panResponder = (0, react_1.useMemo)(() => react_native_1.PanResponder.create({
149
+ onStartShouldSetPanResponder: () => true,
150
+ onMoveShouldSetPanResponder: (_, gesture) => Math.abs(gesture.dx) > 3 || Math.abs(gesture.dy) > 3,
151
+ onPanResponderGrant: () => {
152
+ wakeControl();
153
+ dragged.current = false;
154
+ dragStart.current = lastPosition.current;
155
+ pan.setOffset(lastPosition.current);
156
+ pan.setValue({ x: 0, y: 0 });
157
+ },
158
+ onPanResponderMove: (_, gesture) => {
159
+ if (Math.abs(gesture.dx) > 3 || Math.abs(gesture.dy) > 3)
160
+ dragged.current = true;
161
+ react_native_1.Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false })(_, gesture);
162
+ },
163
+ onPanResponderRelease: (_, gesture) => {
164
+ pan.flattenOffset();
165
+ const minY = SAFE_TOP;
166
+ const maxY = Math.max(minY, height - FALLBACK_SIZE - SAFE_BOTTOM);
167
+ const rawX = dragStart.current.x + gesture.dx;
168
+ const y = Math.max(minY, Math.min(maxY, dragStart.current.y + gesture.dy));
169
+ const edge = rawX + FALLBACK_SIZE / 2 < width / 2 ? 'left' : 'right';
170
+ const x = edge === 'left' ? -FALLBACK_SIZE + DOCK_VISIBLE : width - DOCK_VISIBLE;
171
+ const next = { x, y };
172
+ const yRatio = maxY === minY ? 0.5 : (y - minY) / (maxY - minY);
173
+ setDockEdge(edge);
174
+ lastPosition.current = next;
175
+ react_native_1.Animated.spring(pan, { toValue: next, useNativeDriver: false, friction: 7 }).start(scheduleFade);
176
+ void (0, preferences_1.setDogfoodControlPosition)(orientation, { edge, yRatio }, preferenceScope(state));
177
+ },
178
+ onPanResponderTerminate: scheduleFade,
179
+ }), [height, orientation, pan, scheduleFade, state.appId, state.installationId, wakeControl, width]);
180
+ const choosePresentation = (0, react_1.useCallback)(async (presentation) => {
181
+ if (busy)
182
+ return;
183
+ setBusy('preference');
184
+ setMessage(null);
185
+ try {
186
+ const next = await YaverFeedback_1.YaverFeedback.setDogfoodControlPresentation(presentation);
187
+ setState(next);
188
+ setShowControlSettings(false);
189
+ }
190
+ catch (error) {
191
+ setMessage(error instanceof Error ? error.message : String(error));
192
+ }
193
+ finally {
194
+ setBusy(null);
195
+ }
196
+ }, [busy]);
197
+ const fastReload = (0, react_1.useCallback)(async () => {
198
+ if (busy)
199
+ return;
200
+ setBusy('reload');
201
+ setMessage(null);
202
+ try {
203
+ const ack = await YaverFeedback_1.YaverFeedback.requestDogfoodFastReload();
204
+ setMessage(ack || 'Fast Reload requested.');
205
+ setTimeout(() => setOpen(false), 650);
206
+ }
207
+ catch (error) {
208
+ setMessage(error instanceof Error ? error.message : String(error));
209
+ }
210
+ finally {
211
+ setBusy(null);
212
+ }
213
+ }, [busy]);
214
+ const openChat = (0, react_1.useCallback)(async () => {
215
+ if (busy)
216
+ return;
217
+ setBusy('chat');
218
+ setMessage(null);
219
+ setOpen(false);
220
+ const result = await YaverFeedback_1.YaverFeedback.openDogfood();
221
+ if (result.phase === 'denied' || result.phase === 'error') {
222
+ setMessage(result.error || 'Dogfood access is not available on this installation.');
223
+ setOpen(true);
224
+ }
225
+ setBusy(null);
226
+ }, [busy]);
227
+ const openSessionSetup = (0, react_1.useCallback)(async () => {
228
+ if (busy)
229
+ return;
230
+ setOpen(false);
231
+ setShowControlSettings(false);
232
+ const result = await YaverFeedback_1.YaverFeedback.openDogfood();
233
+ if (result.phase === 'denied' || result.phase === 'error') {
234
+ setMessage(result.error || 'Dogfood session settings are not available on this installation.');
235
+ setOpen(true);
236
+ setShowControlSettings(true);
237
+ }
238
+ }, [busy]);
239
+ if (!state.configured || !state.authorized)
240
+ return null;
241
+ const onboarding = !state.onboardingSeen;
242
+ return (<>
243
+ {state.fallbackVisible && !keyboardVisible && !open ? (<react_native_1.Animated.View pointerEvents="box-none" style={[react_native_1.StyleSheet.absoluteFill, styles.layer]}>
244
+ <react_native_1.Animated.View {...panResponder.panHandlers} style={[
245
+ styles.fallbackPosition,
246
+ { opacity, transform: [{ translateX: pan.x }, { translateY: pan.y }] },
247
+ ]}>
248
+ <react_native_1.Pressable testID="yaver-dogfood-minimized-control" accessibilityRole="button" accessibilityLabel="Open Dogfood controls" hitSlop={10} onPressIn={wakeControl} onPress={() => {
249
+ if (dragged.current) {
250
+ dragged.current = false;
251
+ return;
252
+ }
253
+ setMessage(null);
254
+ setShowControlSettings(false);
255
+ setOpen(true);
256
+ }} style={({ pressed }) => [styles.fallback, pressed && styles.pressed]}>
257
+ <react_native_1.Text style={[
258
+ styles.fallbackText,
259
+ dockEdge === 'right' ? styles.rightDockText : styles.leftDockText,
260
+ ]}>y</react_native_1.Text>
261
+ </react_native_1.Pressable>
262
+ </react_native_1.Animated.View>
263
+ </react_native_1.Animated.View>) : null}
264
+
265
+ <react_native_1.Modal visible={open} transparent animationType="fade" onRequestClose={() => setOpen(false)}>
266
+ <react_native_1.Pressable style={styles.backdrop} onPress={() => setOpen(false)}>
267
+ <react_native_1.Pressable style={styles.card} onPress={(event) => event.stopPropagation()}>
268
+ {onboarding ? (<>
269
+ <react_native_1.Text style={styles.title}>Dogfood ready</react_native_1.Text>
270
+ <react_native_1.Text style={styles.explanation}>
271
+ {state.gestureSupported
272
+ ? 'Dogfood starts with the edge Y so you always know how to return. You can switch to a three-finger hold later from Controls.'
273
+ : 'This device cannot reliably use the three-finger hold, so the edge Y stays available.'}
274
+ </react_native_1.Text>
275
+ <ModeButton title={busy === 'preference' ? 'Saving…' : 'Continue with Y'} hint="Open Fast Reload and Chat from the edge" disabled={busy !== null} onPress={() => void choosePresentation('minimized-y')}/>
276
+ </>) : showControlSettings ? (<>
277
+ <react_native_1.Text style={styles.title}>Dogfood settings</react_native_1.Text>
278
+ {state.gestureSupported ? (<react_native_1.Text style={styles.supported}>Three-finger hold supported on this device</react_native_1.Text>) : null}
279
+ <react_native_1.View style={styles.stackedActions}>
280
+ {state.gestureSupported ? (<>
281
+ <ModeButton title="Three-finger hold" hint="No persistent Y over the app" selected={state.presentation === 'auto'} disabled={busy !== null} onPress={() => void choosePresentation('auto')}/>
282
+ <ModeButton title="Always show Y" hint="Keep the draggable edge control" selected={state.presentation === 'minimized-y'} disabled={busy !== null} onPress={() => void choosePresentation('minimized-y')}/>
283
+ </>) : null}
284
+ <ModeButton title="Session setup" hint="Change machine, coding agent, model, or runtime lane" disabled={busy !== null} onPress={() => void openSessionSetup()}/>
285
+ </react_native_1.View>
286
+ </>) : (<>
287
+ <react_native_1.View style={styles.titleRow}>
288
+ <react_native_1.Text style={styles.title}>Dogfood</react_native_1.Text>
289
+ <react_native_1.Pressable accessibilityRole="button" accessibilityLabel="Dogfood settings" onPress={() => setShowControlSettings(true)} style={styles.settingsButton}>
290
+ <react_native_1.Text style={styles.settingsText}>Settings</react_native_1.Text>
291
+ </react_native_1.Pressable>
292
+ </react_native_1.View>
293
+ <react_native_1.View style={styles.actions}>
294
+ <react_native_1.Pressable testID="yaver-dogfood-fast-reload" accessibilityRole="button" disabled={busy !== null} onPress={() => void fastReload()} style={({ pressed }) => [styles.action, pressed && styles.actionPressed]}>
295
+ <react_native_1.Text style={styles.actionTitle}>{busy === 'reload' ? 'Reloading…' : 'Fast Reload'}</react_native_1.Text>
296
+ <react_native_1.Text style={styles.actionHint}>Refresh the selected render target</react_native_1.Text>
297
+ </react_native_1.Pressable>
298
+ <react_native_1.Pressable testID="yaver-dogfood-chat" accessibilityRole="button" disabled={busy !== null} onPress={() => void openChat()} style={({ pressed }) => [styles.action, pressed && styles.actionPressed]}>
299
+ <react_native_1.Text style={styles.actionTitle}>{busy === 'chat' ? 'Opening…' : 'Chat'}</react_native_1.Text>
300
+ <react_native_1.Text style={styles.actionHint}>Open the current Yaver vibing session</react_native_1.Text>
301
+ </react_native_1.Pressable>
302
+ </react_native_1.View>
303
+ </>)}
304
+ {message ? <react_native_1.Text style={styles.message}>{message}</react_native_1.Text> : null}
305
+ </react_native_1.Pressable>
306
+ </react_native_1.Pressable>
307
+ </react_native_1.Modal>
308
+ </>);
309
+ };
310
+ exports.DogfoodQuickControls = DogfoodQuickControls;
311
+ const ModeButton = ({ title, hint, selected, disabled, onPress }) => (<react_native_1.Pressable accessibilityRole="button" disabled={disabled} onPress={onPress} style={({ pressed }) => [styles.modeAction, selected && styles.modeSelected, pressed && styles.actionPressed]}>
312
+ {typeof selected === 'boolean' ? <react_native_1.View style={[styles.radio, selected && styles.radioSelected]}/> : null}
313
+ <react_native_1.View style={styles.modeCopy}>
314
+ <react_native_1.Text style={styles.actionTitle}>{title}</react_native_1.Text>
315
+ <react_native_1.Text style={styles.actionHint}>{hint}</react_native_1.Text>
316
+ </react_native_1.View>
317
+ </react_native_1.Pressable>);
318
+ const styles = react_native_1.StyleSheet.create({
319
+ layer: { zIndex: 9997 },
320
+ fallbackPosition: { position: 'absolute', left: 0, top: 0 },
321
+ fallback: {
322
+ width: FALLBACK_SIZE,
323
+ height: FALLBACK_SIZE,
324
+ borderRadius: FALLBACK_SIZE / 2,
325
+ backgroundColor: '#f97316',
326
+ borderWidth: 1.5,
327
+ borderColor: 'rgba(255,255,255,0.92)',
328
+ shadowColor: '#000',
329
+ shadowOpacity: 0.28,
330
+ shadowRadius: 5,
331
+ shadowOffset: { width: 0, height: 2 },
332
+ elevation: 6,
333
+ overflow: 'hidden',
334
+ },
335
+ fallbackText: { position: 'absolute', top: 7, color: '#111827', fontSize: 17, lineHeight: 20, fontWeight: '800' },
336
+ rightDockText: { left: 6 },
337
+ leftDockText: { right: 6 },
338
+ pressed: { opacity: 0.78 },
339
+ backdrop: {
340
+ flex: 1,
341
+ justifyContent: 'center',
342
+ alignItems: 'center',
343
+ padding: 24,
344
+ backgroundColor: 'rgba(2,6,23,0.28)',
345
+ },
346
+ card: {
347
+ width: '100%',
348
+ maxWidth: 360,
349
+ borderRadius: 20,
350
+ padding: 16,
351
+ backgroundColor: '#111827',
352
+ shadowColor: '#000',
353
+ shadowOpacity: 0.3,
354
+ shadowRadius: 16,
355
+ shadowOffset: { width: 0, height: 8 },
356
+ elevation: 12,
357
+ },
358
+ titleRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 },
359
+ title: { color: '#f9fafb', fontSize: 16, fontWeight: '700', marginBottom: 12 },
360
+ explanation: { color: '#cbd5e1', fontSize: 13, lineHeight: 19, marginBottom: 14 },
361
+ supported: { color: '#9ca3af', fontSize: 12, lineHeight: 17, marginBottom: 14 },
362
+ settingsButton: { paddingVertical: 5, paddingHorizontal: 8, marginTop: -6 },
363
+ settingsText: { color: '#fdba74', fontSize: 12, fontWeight: '700' },
364
+ actions: { flexDirection: 'row', gap: 10 },
365
+ stackedActions: { gap: 9 },
366
+ action: {
367
+ flex: 1,
368
+ minHeight: 92,
369
+ borderRadius: 14,
370
+ padding: 12,
371
+ justifyContent: 'space-between',
372
+ backgroundColor: '#1f2937',
373
+ borderWidth: react_native_1.StyleSheet.hairlineWidth,
374
+ borderColor: '#4b5563',
375
+ },
376
+ modeAction: {
377
+ minHeight: 62,
378
+ borderRadius: 14,
379
+ padding: 12,
380
+ flexDirection: 'row',
381
+ alignItems: 'center',
382
+ backgroundColor: '#1f2937',
383
+ borderWidth: react_native_1.StyleSheet.hairlineWidth,
384
+ borderColor: '#4b5563',
385
+ },
386
+ modeSelected: { borderColor: '#f97316', backgroundColor: '#292524' },
387
+ radio: { width: 15, height: 15, borderRadius: 8, borderWidth: 1.5, borderColor: '#64748b', marginRight: 11 },
388
+ radioSelected: { borderWidth: 4, borderColor: '#f97316', backgroundColor: '#111827' },
389
+ modeCopy: { flex: 1, gap: 3 },
390
+ actionPressed: { backgroundColor: '#374151' },
391
+ actionTitle: { color: '#f9fafb', fontSize: 15, fontWeight: '700' },
392
+ actionHint: { color: '#9ca3af', fontSize: 11, lineHeight: 15 },
393
+ message: { color: '#fdba74', fontSize: 12, lineHeight: 17, marginTop: 12 },
394
+ });
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import type { DogfoodFailure, DogfoodLane, DogfoodLaneOption, DogfoodLogLine, DogfoodPhase } from './DogfoodRuntime';
3
+ export type DogfoodStatusTone = 'ready' | 'attention' | 'blocked' | 'pending';
4
+ export interface DogfoodStatusStep {
5
+ key: string;
6
+ label: string;
7
+ detail: string;
8
+ tone: DogfoodStatusTone;
9
+ actionLabel?: string;
10
+ actionDisabled?: boolean;
11
+ expanded?: boolean;
12
+ onAction?: () => void;
13
+ }
14
+ export interface DogfoodUiColors {
15
+ background: string;
16
+ border: string;
17
+ text: string;
18
+ muted: string;
19
+ accent: string;
20
+ accentSoft: string;
21
+ ready: string;
22
+ attention: string;
23
+ blocked: string;
24
+ console: string;
25
+ }
26
+ /** Shared readiness rail used by Yaver itself and every embedded SDK host. */
27
+ export declare const DogfoodStatusRail: React.FC<{
28
+ steps: readonly DogfoodStatusStep[];
29
+ colors?: Partial<DogfoodUiColors>;
30
+ }>;
31
+ /** One lane selector and one default policy across Yaver, SFMG, and Talos. */
32
+ export declare const DogfoodLanePicker: React.FC<{
33
+ options: readonly DogfoodLaneOption[];
34
+ selected: DogfoodLane;
35
+ onSelect: (lane: DogfoodLane) => void;
36
+ colors?: Partial<DogfoodUiColors>;
37
+ showUnsupportedReasons?: boolean;
38
+ }>;
39
+ /** Shared second-stage live console. Browser lane deliberately names Browser
40
+ * Logs; Hermes/WebRTC use the same lifecycle and failure/remedy treatment. */
41
+ export declare const DogfoodLiveConsole: React.FC<{
42
+ lane: DogfoodLane;
43
+ phase: DogfoodPhase;
44
+ message: string;
45
+ logs: readonly DogfoodLogLine[];
46
+ failure?: DogfoodFailure;
47
+ maxLines?: number;
48
+ colors?: Partial<DogfoodUiColors>;
49
+ renderText?: (text: string) => React.ReactNode;
50
+ }>;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DogfoodLiveConsole = exports.DogfoodLanePicker = exports.DogfoodStatusRail = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const DEFAULT_COLORS = {
10
+ background: '#111827',
11
+ border: '#334155',
12
+ text: '#f8fafc',
13
+ muted: '#94a3b8',
14
+ accent: '#818cf8',
15
+ accentSoft: '#312e81',
16
+ ready: '#22c55e',
17
+ attention: '#f59e0b',
18
+ blocked: '#ef4444',
19
+ console: '#070b12',
20
+ };
21
+ function resolvedColors(colors) {
22
+ return { ...DEFAULT_COLORS, ...colors };
23
+ }
24
+ function toneColor(tone, colors) {
25
+ if (tone === 'ready')
26
+ return colors.ready;
27
+ if (tone === 'blocked')
28
+ return colors.blocked;
29
+ if (tone === 'attention')
30
+ return colors.attention;
31
+ return colors.muted;
32
+ }
33
+ /** Shared readiness rail used by Yaver itself and every embedded SDK host. */
34
+ const DogfoodStatusRail = ({ steps, colors: colorOverrides }) => {
35
+ const colors = resolvedColors(colorOverrides);
36
+ return (<react_native_1.View style={styles.rail} accessibilityLabel="Dogfood session readiness">
37
+ {steps.map((step) => {
38
+ const tone = toneColor(step.tone, colors);
39
+ return (<react_native_1.View key={step.key} style={styles.statusRow}>
40
+ <react_native_1.View style={[styles.statusDot, { backgroundColor: tone }]}/>
41
+ <react_native_1.View style={styles.statusCopy}>
42
+ <react_native_1.Text style={[styles.statusLabel, { color: colors.text }]}>{step.label}</react_native_1.Text>
43
+ <react_native_1.Text style={[styles.statusDetail, { color: tone }]}>{step.detail}</react_native_1.Text>
44
+ </react_native_1.View>
45
+ {step.actionLabel && step.onAction ? (<react_native_1.Pressable accessibilityRole="button" accessibilityLabel={`${step.actionLabel} ${step.label}`} accessibilityState={{ expanded: step.expanded, disabled: step.actionDisabled }} disabled={step.actionDisabled} onPress={step.onAction} style={({ pressed }) => [
46
+ styles.statusAction,
47
+ { borderColor: colors.border, opacity: step.actionDisabled ? 0.5 : pressed ? 0.7 : 1 },
48
+ ]}>
49
+ <react_native_1.Text style={[styles.statusActionText, { color: colors.accent }]}>{step.actionLabel}</react_native_1.Text>
50
+ </react_native_1.Pressable>) : null}
51
+ </react_native_1.View>);
52
+ })}
53
+ </react_native_1.View>);
54
+ };
55
+ exports.DogfoodStatusRail = DogfoodStatusRail;
56
+ /** One lane selector and one default policy across Yaver, SFMG, and Talos. */
57
+ const DogfoodLanePicker = ({ options, selected, onSelect, colors: colorOverrides, showUnsupportedReasons = true }) => {
58
+ const colors = resolvedColors(colorOverrides);
59
+ return (<react_native_1.View accessibilityRole="radiogroup" accessibilityLabel="Dogfood runtime lane">
60
+ <react_native_1.View style={styles.choiceRow}>
61
+ {options.map((option) => {
62
+ const active = selected === option.lane;
63
+ return (<react_native_1.Pressable key={option.lane} disabled={!option.supported} onPress={() => onSelect(option.lane)} accessibilityRole="radio" accessibilityState={{ checked: active, disabled: !option.supported }} style={({ pressed }) => [
64
+ styles.choice,
65
+ {
66
+ borderColor: active ? colors.accent : colors.border,
67
+ backgroundColor: active ? colors.accentSoft : colors.background,
68
+ opacity: !option.supported ? 0.45 : pressed ? 0.72 : 1,
69
+ },
70
+ ]}>
71
+ <react_native_1.Text style={[styles.choiceText, { color: colors.text }, active && styles.choiceTextActive]}>
72
+ {option.label}{option.default ? ' · default' : ''}
73
+ </react_native_1.Text>
74
+ </react_native_1.Pressable>);
75
+ })}
76
+ </react_native_1.View>
77
+ {showUnsupportedReasons ? options.filter((option) => !option.supported && option.reason).map((option) => (<react_native_1.Text key={`${option.lane}-reason`} style={[styles.reason, { color: colors.muted }]}>
78
+ {option.label}: {option.reason}
79
+ </react_native_1.Text>)) : null}
80
+ </react_native_1.View>);
81
+ };
82
+ exports.DogfoodLanePicker = DogfoodLanePicker;
83
+ function runtimeTone(phase, colors) {
84
+ if (phase === 'ready')
85
+ return colors.ready;
86
+ if (phase === 'failed')
87
+ return colors.blocked;
88
+ if (phase === 'idle' || phase === 'stopped')
89
+ return colors.muted;
90
+ return colors.attention;
91
+ }
92
+ /** Shared second-stage live console. Browser lane deliberately names Browser
93
+ * Logs; Hermes/WebRTC use the same lifecycle and failure/remedy treatment. */
94
+ const DogfoodLiveConsole = ({ lane, phase, message, logs, failure, maxLines = 80, colors: colorOverrides, renderText }) => {
95
+ const colors = resolvedColors(colorOverrides);
96
+ const text = logs.slice(-maxLines).map((line) => line.text).join('\n');
97
+ const title = lane === 'browser' ? 'Browser Logs' : lane === 'hermes' ? 'Hermes Logs' : 'WebRTC Logs';
98
+ return (<react_native_1.View style={[styles.console, { backgroundColor: colors.console, borderColor: colors.border }]} accessibilityLabel={title}>
99
+ <react_native_1.View style={styles.consoleHeader}>
100
+ <react_native_1.View style={[styles.statusDot, { backgroundColor: runtimeTone(phase, colors) }]}/>
101
+ <react_native_1.Text style={[styles.consoleTitle, { color: colors.text }]}>{title}</react_native_1.Text>
102
+ </react_native_1.View>
103
+ <react_native_1.Text style={[styles.consoleStatus, { color: colors.muted }]}>{message}</react_native_1.Text>
104
+ {text ? (renderText ? renderText(text) : <react_native_1.Text selectable style={[styles.consoleText, { color: colors.text }]}>{text}</react_native_1.Text>) : (<react_native_1.Text style={[styles.consoleEmpty, { color: colors.muted }]}>Waiting for the first line from the remote PC…</react_native_1.Text>)}
105
+ {failure ? (<react_native_1.View style={[styles.failure, { borderColor: colors.blocked }]}>
106
+ <react_native_1.Text style={[styles.failureText, { color: colors.text }]}>{failure.error}</react_native_1.Text>
107
+ <react_native_1.Text style={[styles.failureRemedy, { color: colors.muted }]}>{failure.remedy}</react_native_1.Text>
108
+ </react_native_1.View>) : null}
109
+ </react_native_1.View>);
110
+ };
111
+ exports.DogfoodLiveConsole = DogfoodLiveConsole;
112
+ const styles = react_native_1.StyleSheet.create({
113
+ rail: { gap: 4 },
114
+ statusRow: { minHeight: 46, flexDirection: 'row', alignItems: 'center', gap: 9 },
115
+ statusDot: { width: 8, height: 8, borderRadius: 4 },
116
+ statusCopy: { flex: 1 },
117
+ statusLabel: { fontSize: 12, fontWeight: '700' },
118
+ statusDetail: { fontSize: 11, lineHeight: 16, marginTop: 1 },
119
+ statusAction: { borderWidth: 1, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 7 },
120
+ statusActionText: { fontSize: 11, fontWeight: '700' },
121
+ choiceRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 8 },
122
+ choice: { borderWidth: 1, borderRadius: 8, paddingHorizontal: 11, paddingVertical: 8 },
123
+ choiceText: { fontSize: 12, fontWeight: '500' },
124
+ choiceTextActive: { fontWeight: '700' },
125
+ reason: { fontSize: 10, lineHeight: 14, marginTop: 5 },
126
+ console: { width: '100%', maxHeight: 320, overflow: 'hidden', marginTop: 10, borderWidth: 1, borderRadius: 10, padding: 11, gap: 7 },
127
+ consoleHeader: { flexDirection: 'row', alignItems: 'center', gap: 7 },
128
+ consoleTitle: { fontSize: 12, fontWeight: '800' },
129
+ consoleStatus: { fontSize: 11, lineHeight: 16 },
130
+ consoleText: { fontFamily: 'monospace', fontSize: 10, lineHeight: 15 },
131
+ consoleEmpty: { fontSize: 10, fontStyle: 'italic' },
132
+ failure: { borderWidth: 1, borderRadius: 8, padding: 9, gap: 4 },
133
+ failureText: { fontSize: 11, fontWeight: '700' },
134
+ failureRemedy: { fontSize: 10, lineHeight: 15 },
135
+ });