yaver-feedback-react-native 0.6.1 → 0.7.0

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.
@@ -68,6 +68,30 @@ export declare class P2PClient {
68
68
  reloadApp(mode?: 'dev' | 'bundle'): Promise<{
69
69
  ok: boolean;
70
70
  }>;
71
+ /**
72
+ * Open a vibing session on the connected agent. Vibing is the Yaver
73
+ * interactive coding-agent flow — `/vibing/execute` creates a task with
74
+ * the project context plus the user's prompt. Returns the task id the
75
+ * caller can poll via `/tasks/{id}` if needed.
76
+ *
77
+ * Requires an owner/CLI/paired token — the `/vibing*` routes do not
78
+ * currently accept SDK-minted tokens. Power users typically drive
79
+ * vibing from Claude Code / the Yaver mobile app; this method is a
80
+ * convenience for the SDK's one-tap bug-report-to-vibing path.
81
+ */
82
+ vibing(prompt: string, projectPath?: string): Promise<{
83
+ taskId: string;
84
+ }>;
85
+ /**
86
+ * After uploading a feedback bundle with `uploadFeedback`, call this
87
+ * with the returned report id to create a fix task on the agent. The
88
+ * task includes the feedback's screenshots, errors, and (when available)
89
+ * the BlackBox context for the originating device.
90
+ */
91
+ triggerFix(feedbackId: string): Promise<{
92
+ taskId: string;
93
+ prompt: string;
94
+ }>;
71
95
  /** Get the download URL for a build artifact. */
72
96
  getArtifactUrl(buildId: string): string;
73
97
  /**
package/dist/P2PClient.js CHANGED
@@ -62,13 +62,6 @@ class P2PClient {
62
62
  name: `screenshot_${i}.png`,
63
63
  });
64
64
  }
65
- if (bundle.audio) {
66
- formData.append('audio', {
67
- uri: react_native_1.Platform.OS === 'android' ? `file://${bundle.audio}` : bundle.audio,
68
- type: 'audio/m4a',
69
- name: 'voice_note.m4a',
70
- });
71
- }
72
65
  if (bundle.video) {
73
66
  formData.append('video', {
74
67
  uri: react_native_1.Platform.OS === 'android' ? `file://${bundle.video}` : bundle.video,
@@ -188,17 +181,79 @@ class P2PClient {
188
181
  * @param mode - "dev" for hot reload, "bundle" for native bundle rebuild
189
182
  */
190
183
  async reloadApp(mode = 'dev') {
191
- const response = await fetch(`${this.baseUrl}/dev/reload-app`, {
184
+ // Primary path: /dev/reload — same endpoint the Yaver mobile app uses.
185
+ // Triggers Metro/Expo HMR synchronously and emits an SSE `reload` event
186
+ // on /dev/events that the FeedbackModal can subscribe to for progress.
187
+ //
188
+ // Only fall back to /dev/reload-app (the BlackBox-SSE-broadcast path)
189
+ // when the primary path reports "no dev server running" — that mode is
190
+ // really for the mobile app remotely kicking a third-party app, not
191
+ // for the app kicking itself.
192
+ const primary = await fetch(`${this.baseUrl}/dev/reload`, {
193
+ method: 'POST',
194
+ headers: { Authorization: `Bearer ${this.authToken}` },
195
+ });
196
+ if (primary.ok) {
197
+ return primary.json().catch(() => ({ ok: true }));
198
+ }
199
+ if (primary.status >= 500 || primary.status === 404 || mode === 'bundle') {
200
+ const fallback = await fetch(`${this.baseUrl}/dev/reload-app`, {
201
+ method: 'POST',
202
+ headers: {
203
+ Authorization: `Bearer ${this.authToken}`,
204
+ 'Content-Type': 'application/json',
205
+ },
206
+ body: JSON.stringify({ mode }),
207
+ });
208
+ if (!fallback.ok) {
209
+ const text = await fallback.text().catch(() => '');
210
+ throw new Error(`[P2PClient] Reload failed (${fallback.status}): ${text}`);
211
+ }
212
+ return fallback.json().catch(() => ({ ok: true }));
213
+ }
214
+ const text = await primary.text().catch(() => '');
215
+ throw new Error(`[P2PClient] Reload failed (${primary.status}): ${text}`);
216
+ }
217
+ /**
218
+ * Open a vibing session on the connected agent. Vibing is the Yaver
219
+ * interactive coding-agent flow — `/vibing/execute` creates a task with
220
+ * the project context plus the user's prompt. Returns the task id the
221
+ * caller can poll via `/tasks/{id}` if needed.
222
+ *
223
+ * Requires an owner/CLI/paired token — the `/vibing*` routes do not
224
+ * currently accept SDK-minted tokens. Power users typically drive
225
+ * vibing from Claude Code / the Yaver mobile app; this method is a
226
+ * convenience for the SDK's one-tap bug-report-to-vibing path.
227
+ */
228
+ async vibing(prompt, projectPath) {
229
+ const response = await fetch(`${this.baseUrl}/vibing/execute`, {
192
230
  method: 'POST',
193
231
  headers: {
194
232
  Authorization: `Bearer ${this.authToken}`,
195
233
  'Content-Type': 'application/json',
196
234
  },
197
- body: JSON.stringify({ mode }),
235
+ body: JSON.stringify({ prompt, projectPath: projectPath ?? '' }),
236
+ });
237
+ if (!response.ok) {
238
+ const text = await response.text().catch(() => '');
239
+ throw new Error(`[P2PClient] Vibing failed (${response.status}): ${text}`);
240
+ }
241
+ return response.json();
242
+ }
243
+ /**
244
+ * After uploading a feedback bundle with `uploadFeedback`, call this
245
+ * with the returned report id to create a fix task on the agent. The
246
+ * task includes the feedback's screenshots, errors, and (when available)
247
+ * the BlackBox context for the originating device.
248
+ */
249
+ async triggerFix(feedbackId) {
250
+ const response = await fetch(`${this.baseUrl}/feedback/${encodeURIComponent(feedbackId)}/fix`, {
251
+ method: 'POST',
252
+ headers: { Authorization: `Bearer ${this.authToken}` },
198
253
  });
199
254
  if (!response.ok) {
200
255
  const text = await response.text().catch(() => '');
201
- throw new Error(`[P2PClient] Reload app failed (${response.status}): ${text}`);
256
+ throw new Error(`[P2PClient] Fix trigger failed (${response.status}): ${text}`);
202
257
  }
203
258
  return response.json();
204
259
  }
@@ -116,10 +116,6 @@ export declare class YaverFeedback {
116
116
  * Available after init if agentUrl is set, or after first successful discovery.
117
117
  */
118
118
  static getP2PClient(): P2PClient | null;
119
- /** Returns the current feedback mode. */
120
- static getFeedbackMode(): 'live' | 'narrated' | 'batch';
121
- /** Returns the agent commentary level (0-10). */
122
- static getCommentaryLevel(): number;
123
119
  /**
124
120
  * Record a business event. Routes through BlackBox so the agent
125
121
  * persists it to the analytics ledger (no dashboards — export
@@ -65,8 +65,6 @@ class YaverFeedback {
65
65
  config = {
66
66
  trigger: 'shake',
67
67
  maxRecordingDuration: 120,
68
- feedbackMode: 'batch',
69
- agentCommentaryLevel: 0,
70
68
  autoLogin: true,
71
69
  ...cfg,
72
70
  };
@@ -464,14 +462,6 @@ class YaverFeedback {
464
462
  static getP2PClient() {
465
463
  return p2pClient;
466
464
  }
467
- /** Returns the current feedback mode. */
468
- static getFeedbackMode() {
469
- return config?.feedbackMode ?? 'batch';
470
- }
471
- /** Returns the agent commentary level (0-10). */
472
- static getCommentaryLevel() {
473
- return config?.agentCommentaryLevel ?? 0;
474
- }
475
465
  // ─── One-stop SaaS replacement methods ─────────────────────────
476
466
  //
477
467
  // These are the three solo-dev SaaS-replacement entry points
@@ -36,22 +36,18 @@ describe('YaverFeedback', () => {
36
36
  expect(cfg.agentUrl).toBe('http://localhost:18080');
37
37
  expect(cfg.trigger).toBe('shake');
38
38
  expect(cfg.maxRecordingDuration).toBe(120);
39
- expect(cfg.feedbackMode).toBe('batch');
40
- expect(cfg.agentCommentaryLevel).toBe(0);
41
39
  });
42
40
  it('respects user-provided values over defaults', () => {
43
41
  YaverFeedback_1.YaverFeedback.init({
44
42
  authToken: 'tok',
45
43
  trigger: 'floating-button',
46
44
  maxRecordingDuration: 60,
47
- feedbackMode: 'live',
48
- agentCommentaryLevel: 7,
45
+ strictNativeAuth: true,
49
46
  });
50
47
  const cfg = YaverFeedback_1.YaverFeedback.getConfig();
51
48
  expect(cfg.trigger).toBe('floating-button');
52
49
  expect(cfg.maxRecordingDuration).toBe(60);
53
- expect(cfg.feedbackMode).toBe('live');
54
- expect(cfg.agentCommentaryLevel).toBe(7);
50
+ expect(cfg.strictNativeAuth).toBe(true);
55
51
  });
56
52
  it('with enabled=false sets enabled to false', () => {
57
53
  YaverFeedback_1.YaverFeedback.init({
@@ -110,35 +106,6 @@ describe('YaverFeedback', () => {
110
106
  expect(cfg.agentUrl).toBe('http://10.0.0.1:18080');
111
107
  });
112
108
  });
113
- describe('getFeedbackMode()', () => {
114
- it('defaults to batch when no config', () => {
115
- // After any init, feedbackMode defaults to 'batch'
116
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok' });
117
- expect(YaverFeedback_1.YaverFeedback.getFeedbackMode()).toBe('batch');
118
- });
119
- it('returns configured mode', () => {
120
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', feedbackMode: 'narrated' });
121
- expect(YaverFeedback_1.YaverFeedback.getFeedbackMode()).toBe('narrated');
122
- });
123
- it('returns live when configured', () => {
124
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', feedbackMode: 'live' });
125
- expect(YaverFeedback_1.YaverFeedback.getFeedbackMode()).toBe('live');
126
- });
127
- });
128
- describe('getCommentaryLevel()', () => {
129
- it('defaults to 0', () => {
130
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok' });
131
- expect(YaverFeedback_1.YaverFeedback.getCommentaryLevel()).toBe(0);
132
- });
133
- it('returns configured level', () => {
134
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', agentCommentaryLevel: 5 });
135
- expect(YaverFeedback_1.YaverFeedback.getCommentaryLevel()).toBe(5);
136
- });
137
- it('returns max level when set to 10', () => {
138
- YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', agentCommentaryLevel: 10 });
139
- expect(YaverFeedback_1.YaverFeedback.getCommentaryLevel()).toBe(10);
140
- });
141
- });
142
109
  describe('startReport()', () => {
143
110
  it('does nothing when not enabled', async () => {
144
111
  YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', enabled: false });
@@ -11,8 +11,6 @@ describe('React Native SDK types', () => {
11
11
  expect(config.trigger).toBeUndefined();
12
12
  expect(config.enabled).toBeUndefined();
13
13
  expect(config.maxRecordingDuration).toBeUndefined();
14
- expect(config.feedbackMode).toBeUndefined();
15
- expect(config.agentCommentaryLevel).toBeUndefined();
16
14
  });
17
15
  it('can be constructed with all optional fields', () => {
18
16
  const config = {
@@ -21,12 +19,10 @@ describe('React Native SDK types', () => {
21
19
  trigger: 'shake',
22
20
  enabled: true,
23
21
  maxRecordingDuration: 60,
24
- feedbackMode: 'live',
25
- agentCommentaryLevel: 7,
22
+ strictNativeAuth: true,
26
23
  };
27
24
  expect(config.trigger).toBe('shake');
28
- expect(config.feedbackMode).toBe('live');
29
- expect(config.agentCommentaryLevel).toBe(7);
25
+ expect(config.strictNativeAuth).toBe(true);
30
26
  });
31
27
  it('accepts all trigger types', () => {
32
28
  const triggers = ['shake', 'floating-button', 'manual'];
@@ -35,13 +31,6 @@ describe('React Native SDK types', () => {
35
31
  expect(config.trigger).toBe(trigger);
36
32
  });
37
33
  });
38
- it('accepts all feedback modes', () => {
39
- const modes = ['live', 'narrated', 'batch'];
40
- modes.forEach((mode) => {
41
- const config = { authToken: 'tok', feedbackMode: mode };
42
- expect(config.feedbackMode).toBe(mode);
43
- });
44
- });
45
34
  });
46
35
  describe('FeedbackBundle', () => {
47
36
  it('can be constructed with required fields', () => {
@@ -67,9 +56,8 @@ describe('React Native SDK types', () => {
67
56
  expect(bundle.metadata.device.platform).toBe('ios');
68
57
  expect(bundle.screenshots).toEqual([]);
69
58
  expect(bundle.video).toBeUndefined();
70
- expect(bundle.audio).toBeUndefined();
71
59
  });
72
- it('can include optional video, audio, and screenshots', () => {
60
+ it('can include optional video + screenshots', () => {
73
61
  const bundle = {
74
62
  metadata: {
75
63
  timestamp: '2026-03-24T12:00:00Z',
@@ -84,11 +72,9 @@ describe('React Native SDK types', () => {
84
72
  userNote: 'This button does not work',
85
73
  },
86
74
  video: '/tmp/recording.mp4',
87
- audio: '/tmp/voice.m4a',
88
75
  screenshots: ['/tmp/ss1.png', '/tmp/ss2.png'],
89
76
  };
90
77
  expect(bundle.video).toBe('/tmp/recording.mp4');
91
- expect(bundle.audio).toBe('/tmp/voice.m4a');
92
78
  expect(bundle.screenshots).toHaveLength(2);
93
79
  expect(bundle.metadata.userNote).toBe('This button does not work');
94
80
  });
@@ -187,24 +173,6 @@ describe('React Native SDK types', () => {
187
173
  });
188
174
  });
189
175
  });
190
- describe('AgentCommentary', () => {
191
- it('has correct structure', () => {
192
- const commentary = {
193
- id: 'cmt-1',
194
- timestamp: '2026-03-24T12:00:00Z',
195
- message: 'I see a layout issue on the login screen',
196
- type: 'observation',
197
- };
198
- expect(commentary.type).toBe('observation');
199
- });
200
- it('accepts all commentary types', () => {
201
- const types = ['observation', 'suggestion', 'question', 'action'];
202
- types.forEach((type) => {
203
- const c = { id: '1', timestamp: 'now', message: 'test', type };
204
- expect(c.type).toBe(type);
205
- });
206
- });
207
- });
208
176
  describe('FeedbackStreamEvent', () => {
209
177
  it('has correct structure', () => {
210
178
  const event = {
package/dist/capture.d.ts CHANGED
@@ -1,27 +1,40 @@
1
1
  /**
2
- * Screen capture and audio recording helpers.
2
+ * Screen capture helpers screenshot + video recording.
3
3
  *
4
- * Screenshot capture requires `react-native-view-shot` as a peer dependency.
5
- * Audio recording requires `react-native-audio-recorder-player` or a
6
- * similar library the implementation below uses a minimal approach
7
- * that works when one of those is available.
4
+ * Peer deps (all optional loaded lazily):
5
+ * - `react-native-view-shot` screenshot
6
+ * - `react-native-record-screen` video recording (iOS ReplayKit /
7
+ * Android MediaProjection)
8
+ *
9
+ * Each helper surfaces a clear error if the module is missing so a host
10
+ * app knows exactly which peer dep to add. Audio-note / voice-command
11
+ * recording was removed in 0.7.0 — see FeedbackModal for the new
12
+ * 5-button surface.
8
13
  */
9
14
  /**
10
15
  * Capture the current screen as a PNG image.
11
16
  * Requires `react-native-view-shot` to be installed.
12
- * @returns File path of the captured screenshot.
17
+ *
18
+ * Note: the feedback modal should hide itself *before* calling this so the
19
+ * screenshot contains the underlying app state (the actual bug), not the
20
+ * modal. See `FeedbackModal.handleScreenshotForFix`.
13
21
  */
14
22
  export declare function captureScreenshot(): Promise<string>;
15
23
  /**
16
- * Start recording an audio voice note.
17
- * Requires `react-native-audio-recorder-player` to be installed.
24
+ * Start a screen-recording session. Requires
25
+ * `react-native-record-screen` as a peer dep.
26
+ *
27
+ * The user must grant the iOS ReplayKit / Android MediaProjection
28
+ * permission the first time; the prompt is shown by the native module,
29
+ * not the SDK.
18
30
  */
19
- export declare function startAudioRecording(): Promise<void>;
31
+ export declare function startVideoRecording(): Promise<void>;
20
32
  /**
21
- * Stop the current audio recording.
22
- * @returns Object with the file path and duration in seconds.
33
+ * Stop the current video recording and return the on-device file path.
23
34
  */
24
- export declare function stopAudioRecording(): Promise<{
35
+ export declare function stopVideoRecording(): Promise<{
25
36
  path: string;
26
37
  duration: number;
27
38
  }>;
39
+ /** Whether a video recording is currently active. */
40
+ export declare function isVideoRecording(): boolean;
package/dist/capture.js CHANGED
@@ -1,21 +1,29 @@
1
1
  "use strict";
2
2
  /**
3
- * Screen capture and audio recording helpers.
3
+ * Screen capture helpers screenshot + video recording.
4
4
  *
5
- * Screenshot capture requires `react-native-view-shot` as a peer dependency.
6
- * Audio recording requires `react-native-audio-recorder-player` or a
7
- * similar library the implementation below uses a minimal approach
8
- * that works when one of those is available.
5
+ * Peer deps (all optional loaded lazily):
6
+ * - `react-native-view-shot` screenshot
7
+ * - `react-native-record-screen` video recording (iOS ReplayKit /
8
+ * Android MediaProjection)
9
+ *
10
+ * Each helper surfaces a clear error if the module is missing so a host
11
+ * app knows exactly which peer dep to add. Audio-note / voice-command
12
+ * recording was removed in 0.7.0 — see FeedbackModal for the new
13
+ * 5-button surface.
9
14
  */
10
15
  Object.defineProperty(exports, "__esModule", { value: true });
11
16
  exports.captureScreenshot = captureScreenshot;
12
- exports.startAudioRecording = startAudioRecording;
13
- exports.stopAudioRecording = stopAudioRecording;
14
- let audioRecorderModule = null;
17
+ exports.startVideoRecording = startVideoRecording;
18
+ exports.stopVideoRecording = stopVideoRecording;
19
+ exports.isVideoRecording = isVideoRecording;
15
20
  /**
16
21
  * Capture the current screen as a PNG image.
17
22
  * Requires `react-native-view-shot` to be installed.
18
- * @returns File path of the captured screenshot.
23
+ *
24
+ * Note: the feedback modal should hide itself *before* calling this so the
25
+ * screenshot contains the underlying app state (the actual bug), not the
26
+ * modal. See `FeedbackModal.handleScreenshotForFix`.
19
27
  */
20
28
  async function captureScreenshot() {
21
29
  try {
@@ -27,48 +35,79 @@ async function captureScreenshot() {
27
35
  return uri;
28
36
  }
29
37
  catch (err) {
30
- throw new Error('[YaverFeedback] Screenshot capture failed. Make sure react-native-view-shot is installed. ' +
38
+ throw new Error('[YaverFeedback] Screenshot capture failed. Install react-native-view-shot as a peer dep. ' +
31
39
  String(err));
32
40
  }
33
41
  }
42
+ let videoRecorderModule = null;
43
+ let videoRecordingActive = false;
34
44
  /**
35
- * Start recording an audio voice note.
36
- * Requires `react-native-audio-recorder-player` to be installed.
45
+ * Start a screen-recording session. Requires
46
+ * `react-native-record-screen` as a peer dep.
47
+ *
48
+ * The user must grant the iOS ReplayKit / Android MediaProjection
49
+ * permission the first time; the prompt is shown by the native module,
50
+ * not the SDK.
37
51
  */
38
- async function startAudioRecording() {
52
+ async function startVideoRecording() {
53
+ if (videoRecordingActive) {
54
+ throw new Error('[YaverFeedback] A video recording is already in progress.');
55
+ }
39
56
  try {
40
- const AudioRecorderPlayer = require('react-native-audio-recorder-player').default;
41
- audioRecorderModule = new AudioRecorderPlayer();
42
- await audioRecorderModule.startRecorder();
57
+ videoRecorderModule = require('react-native-record-screen').default ??
58
+ require('react-native-record-screen');
59
+ if (typeof videoRecorderModule.startRecording !== 'function') {
60
+ throw new Error('react-native-record-screen missing startRecording()');
61
+ }
62
+ const result = await videoRecorderModule.startRecording({
63
+ mic: false,
64
+ width: 720,
65
+ bitrate: 1024 * 1000,
66
+ });
67
+ if (result && result.status && result.status !== 'success') {
68
+ throw new Error(`startRecording returned ${result.status}`);
69
+ }
70
+ videoRecordingActive = true;
43
71
  }
44
72
  catch (err) {
45
- audioRecorderModule = null;
46
- throw new Error('[YaverFeedback] Audio recording failed to start. Make sure react-native-audio-recorder-player is installed. ' +
73
+ videoRecorderModule = null;
74
+ videoRecordingActive = false;
75
+ throw new Error('[YaverFeedback] Could not start screen recording. Install react-native-record-screen. ' +
47
76
  String(err));
48
77
  }
49
78
  }
50
79
  /**
51
- * Stop the current audio recording.
52
- * @returns Object with the file path and duration in seconds.
80
+ * Stop the current video recording and return the on-device file path.
53
81
  */
54
- async function stopAudioRecording() {
55
- if (!audioRecorderModule) {
56
- throw new Error('[YaverFeedback] No audio recording in progress.');
82
+ async function stopVideoRecording() {
83
+ if (!videoRecordingActive || !videoRecorderModule) {
84
+ throw new Error('[YaverFeedback] No video recording in progress.');
57
85
  }
58
86
  try {
59
- const result = await audioRecorderModule.stopRecorder();
60
- const recorder = audioRecorderModule;
61
- audioRecorderModule = null;
62
- // result is the file path on most implementations
63
- const path = typeof result === 'string' ? result : result?.uri ?? '';
64
- // Duration tracking — recorder-player provides currentPosition in ms
65
- const durationMs = typeof recorder.currentPosition === 'number'
66
- ? recorder.currentPosition
67
- : 0;
87
+ const res = await videoRecorderModule.stopRecording();
88
+ videoRecordingActive = false;
89
+ const path = typeof res === 'string'
90
+ ? res
91
+ : res?.result?.outputURL ??
92
+ res?.outputURL ??
93
+ res?.uri ??
94
+ '';
95
+ const durationMs = typeof res?.result?.duration === 'number'
96
+ ? res.result.duration
97
+ : typeof res?.duration === 'number'
98
+ ? res.duration
99
+ : 0;
100
+ if (!path) {
101
+ throw new Error('stopRecording() returned no file path');
102
+ }
68
103
  return { path, duration: durationMs / 1000 };
69
104
  }
70
105
  catch (err) {
71
- audioRecorderModule = null;
72
- throw new Error('[YaverFeedback] Failed to stop audio recording. ' + String(err));
106
+ videoRecordingActive = false;
107
+ throw new Error('[YaverFeedback] Failed to stop screen recording. ' + String(err));
73
108
  }
74
109
  }
110
+ /** Whether a video recording is currently active. */
111
+ function isVideoRecording() {
112
+ return videoRecordingActive;
113
+ }
package/dist/expo.d.ts CHANGED
@@ -7,7 +7,6 @@ import type { FeedbackConfig } from './types';
7
7
  *
8
8
  * Defaults:
9
9
  * - trigger: 'shake'
10
- * - feedbackMode: 'batch'
11
10
  * - enabled: __DEV__ (only active in development)
12
11
  *
13
12
  * @param overrides - Optional partial config to override defaults
package/dist/expo.js CHANGED
@@ -32,7 +32,6 @@ const YaverFeedback_1 = require("./YaverFeedback");
32
32
  *
33
33
  * Defaults:
34
34
  * - trigger: 'shake'
35
- * - feedbackMode: 'batch'
36
35
  * - enabled: __DEV__ (only active in development)
37
36
  *
38
37
  * @param overrides - Optional partial config to override defaults
@@ -54,7 +53,6 @@ function initExpo(overrides) {
54
53
  YaverFeedback_1.YaverFeedback.init({
55
54
  authToken: '', // LAN auto-discovery doesn't require a token
56
55
  trigger: 'shake',
57
- feedbackMode: 'batch',
58
56
  enabled: __DEV__,
59
57
  ...overrides,
60
58
  ...(agentUrl ? { agentUrl } : {}),
package/dist/index.d.ts CHANGED
@@ -1,24 +1,29 @@
1
1
  /**
2
- * @yaver/feedback-react-native — Visual feedback SDK for Yaver.
2
+ * yaver-feedback-react-native — Visual feedback SDK for Yaver.
3
3
  *
4
- * Shake-to-report, screenshots, voice annotations, P2P connection,
5
- * device discovery, and live/narrated/batch feedback modes for vibe coding.
4
+ * Shake-to-report surface with five one-tap actions:
5
+ * 1. Hot Reload — instant JS reload
6
+ * 2. Screenshot & Fix — capture the screen under the modal and
7
+ * kick a fix task on the agent
8
+ * 3. Vibing — open a vibing session on the agent
9
+ * 4. Start / Stop Recording — screen recording toggle
10
+ * 5. Send Video — submit the last recording
6
11
  *
7
12
  * @example
8
13
  * ```tsx
9
- * import { YaverFeedback, FeedbackProvider } from '@yaver/feedback-react-native';
14
+ * import { YaverFeedback, FeedbackModal } from 'yaver-feedback-react-native';
10
15
  *
11
16
  * YaverFeedback.init({
12
17
  * agentUrl: 'http://192.168.1.10:18080',
13
18
  * authToken: 'your-token',
14
19
  * trigger: 'shake',
15
- * feedbackMode: 'live',
20
+ * strictNativeAuth: true,
16
21
  * });
17
22
  *
18
- * // Wrap your app root:
19
- * <FeedbackProvider>
23
+ * <>
20
24
  * <App />
21
- * </FeedbackProvider>
25
+ * <FeedbackModal />
26
+ * </>
22
27
  * ```
23
28
  */
24
29
  export { YaverFeedback } from './YaverFeedback';
@@ -40,9 +45,9 @@ export { FeedbackModal } from './FeedbackModal';
40
45
  export { FixReport } from './FixReport';
41
46
  export { configureAuthEndpoints, getConvexSiteUrl, getWebBaseUrl, getToken, saveToken, clearToken, getUser, saveUser, getSelectedDeviceId, saveSelectedDeviceId, clearSelectedDeviceId, validateToken, signInWithApple, signInWithOAuth, signupWithEmail, loginWithEmail, listReachableDevices, DEFAULT_CONVEX_SITE_URL, DEFAULT_WEB_BASE_URL, DEFAULT_OAUTH_REDIRECT, } from './auth';
42
47
  export type { OAuthProvider, User, RemoteDevice, DeviceList, } from './auth';
43
- export { captureScreenshot, startAudioRecording, stopAudioRecording } from './capture';
48
+ export { captureScreenshot, startVideoRecording, stopVideoRecording, isVideoRecording, } from './capture';
44
49
  export { uploadFeedback } from './upload';
45
- export type { FeedbackConfig, FeedbackBundle, FeedbackMetadata, DeviceInfo, AppInfo, TimelineEvent, FeedbackReport, AgentCommentary, FeedbackStreamEvent, VoiceCapability, CapturedError, TestFix, TestSession, } from './types';
50
+ export type { FeedbackConfig, FeedbackBundle, FeedbackMetadata, DeviceInfo, AppInfo, TimelineEvent, FeedbackReport, FeedbackStreamEvent, VoiceCapability, CapturedError, TestFix, TestSession, } from './types';
46
51
  export type { BlackBoxEvent, BlackBoxConfig, BlackBoxCommand, CommandHandler } from './BlackBox';
47
52
  export type { DiscoveryResult } from './Discovery';
48
53
  export type { FeedbackEvent } from './P2PClient';
package/dist/index.js CHANGED
@@ -1,29 +1,34 @@
1
1
  "use strict";
2
2
  /**
3
- * @yaver/feedback-react-native — Visual feedback SDK for Yaver.
3
+ * yaver-feedback-react-native — Visual feedback SDK for Yaver.
4
4
  *
5
- * Shake-to-report, screenshots, voice annotations, P2P connection,
6
- * device discovery, and live/narrated/batch feedback modes for vibe coding.
5
+ * Shake-to-report surface with five one-tap actions:
6
+ * 1. Hot Reload — instant JS reload
7
+ * 2. Screenshot & Fix — capture the screen under the modal and
8
+ * kick a fix task on the agent
9
+ * 3. Vibing — open a vibing session on the agent
10
+ * 4. Start / Stop Recording — screen recording toggle
11
+ * 5. Send Video — submit the last recording
7
12
  *
8
13
  * @example
9
14
  * ```tsx
10
- * import { YaverFeedback, FeedbackProvider } from '@yaver/feedback-react-native';
15
+ * import { YaverFeedback, FeedbackModal } from 'yaver-feedback-react-native';
11
16
  *
12
17
  * YaverFeedback.init({
13
18
  * agentUrl: 'http://192.168.1.10:18080',
14
19
  * authToken: 'your-token',
15
20
  * trigger: 'shake',
16
- * feedbackMode: 'live',
21
+ * strictNativeAuth: true,
17
22
  * });
18
23
  *
19
- * // Wrap your app root:
20
- * <FeedbackProvider>
24
+ * <>
21
25
  * <App />
22
- * </FeedbackProvider>
26
+ * <FeedbackModal />
27
+ * </>
23
28
  * ```
24
29
  */
25
30
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.uploadFeedback = exports.stopAudioRecording = exports.startAudioRecording = exports.captureScreenshot = exports.DEFAULT_OAUTH_REDIRECT = exports.DEFAULT_WEB_BASE_URL = exports.DEFAULT_CONVEX_SITE_URL = exports.listReachableDevices = exports.loginWithEmail = exports.signupWithEmail = exports.signInWithOAuth = exports.signInWithApple = exports.validateToken = exports.clearSelectedDeviceId = exports.saveSelectedDeviceId = exports.getSelectedDeviceId = exports.saveUser = exports.getUser = exports.clearToken = exports.saveToken = exports.getToken = exports.getWebBaseUrl = exports.getConvexSiteUrl = exports.configureAuthEndpoints = exports.FixReport = exports.FeedbackModal = exports.FloatingButton = exports.ShakeDetector = exports.AuthOverlay = exports.YaverMachinePickerScreen = exports.YaverLoginScreen = exports.YaverConnectionScreen = exports.P2PClient = exports.YaverDiscovery = exports.initExpo = exports.YaverUpdates = exports.BlackBox = exports.YaverFeedback = void 0;
31
+ exports.uploadFeedback = exports.isVideoRecording = exports.stopVideoRecording = exports.startVideoRecording = exports.captureScreenshot = exports.DEFAULT_OAUTH_REDIRECT = exports.DEFAULT_WEB_BASE_URL = exports.DEFAULT_CONVEX_SITE_URL = exports.listReachableDevices = exports.loginWithEmail = exports.signupWithEmail = exports.signInWithOAuth = exports.signInWithApple = exports.validateToken = exports.clearSelectedDeviceId = exports.saveSelectedDeviceId = exports.getSelectedDeviceId = exports.saveUser = exports.getUser = exports.clearToken = exports.saveToken = exports.getToken = exports.getWebBaseUrl = exports.getConvexSiteUrl = exports.configureAuthEndpoints = exports.FixReport = exports.FeedbackModal = exports.FloatingButton = exports.ShakeDetector = exports.AuthOverlay = exports.YaverMachinePickerScreen = exports.YaverLoginScreen = exports.YaverConnectionScreen = exports.P2PClient = exports.YaverDiscovery = exports.initExpo = exports.YaverUpdates = exports.BlackBox = exports.YaverFeedback = void 0;
27
32
  var YaverFeedback_1 = require("./YaverFeedback");
28
33
  Object.defineProperty(exports, "YaverFeedback", { enumerable: true, get: function () { return YaverFeedback_1.YaverFeedback; } });
29
34
  var BlackBox_1 = require("./BlackBox");
@@ -75,7 +80,8 @@ Object.defineProperty(exports, "DEFAULT_WEB_BASE_URL", { enumerable: true, get:
75
80
  Object.defineProperty(exports, "DEFAULT_OAUTH_REDIRECT", { enumerable: true, get: function () { return auth_1.DEFAULT_OAUTH_REDIRECT; } });
76
81
  var capture_1 = require("./capture");
77
82
  Object.defineProperty(exports, "captureScreenshot", { enumerable: true, get: function () { return capture_1.captureScreenshot; } });
78
- Object.defineProperty(exports, "startAudioRecording", { enumerable: true, get: function () { return capture_1.startAudioRecording; } });
79
- Object.defineProperty(exports, "stopAudioRecording", { enumerable: true, get: function () { return capture_1.stopAudioRecording; } });
83
+ Object.defineProperty(exports, "startVideoRecording", { enumerable: true, get: function () { return capture_1.startVideoRecording; } });
84
+ Object.defineProperty(exports, "stopVideoRecording", { enumerable: true, get: function () { return capture_1.stopVideoRecording; } });
85
+ Object.defineProperty(exports, "isVideoRecording", { enumerable: true, get: function () { return capture_1.isVideoRecording; } });
80
86
  var upload_1 = require("./upload");
81
87
  Object.defineProperty(exports, "uploadFeedback", { enumerable: true, get: function () { return upload_1.uploadFeedback; } });