@comergehq/studio 0.1.30 → 0.1.32

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/dist/index.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,6 +30,482 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
33
+ // src/assets/lottie/remix-x-loop.lottie.json
34
+ var require_remix_x_loop_lottie = __commonJS({
35
+ "src/assets/lottie/remix-x-loop.lottie.json"(exports2, module2) {
36
+ module2.exports = {
37
+ v: "5.7.4",
38
+ fr: 30,
39
+ ip: 0,
40
+ op: 50,
41
+ w: 120,
42
+ h: 120,
43
+ nm: "Remix X Loop",
44
+ ddd: 0,
45
+ assets: [],
46
+ layers: [
47
+ {
48
+ ddd: 0,
49
+ ind: 1,
50
+ ty: 3,
51
+ nm: "Controller",
52
+ ks: {
53
+ o: { a: 0, k: 100 },
54
+ r: {
55
+ a: 1,
56
+ k: [
57
+ { t: 0, s: [0] },
58
+ { t: 5, s: [0] },
59
+ { t: 9, s: [40] },
60
+ { t: 13, s: [180] },
61
+ { t: 17, s: [320] },
62
+ { t: 20, s: [360] },
63
+ { t: 29, s: [360] },
64
+ { t: 33, s: [400] },
65
+ { t: 37, s: [540] },
66
+ { t: 41, s: [680] },
67
+ { t: 44, s: [720] },
68
+ { t: 50, s: [720] }
69
+ ]
70
+ },
71
+ p: { a: 0, k: [60, 60, 0] },
72
+ a: { a: 0, k: [35, 35, 0] },
73
+ s: { a: 0, k: [100, 100, 100] }
74
+ },
75
+ ao: 0,
76
+ ip: 0,
77
+ op: 50,
78
+ st: 0,
79
+ bm: 0
80
+ },
81
+ {
82
+ ddd: 0,
83
+ ind: 2,
84
+ ty: 4,
85
+ nm: "Chevron Right",
86
+ parent: 1,
87
+ ks: {
88
+ o: {
89
+ a: 1,
90
+ k: [
91
+ { t: 0, s: [100] },
92
+ { t: 17, s: [100] },
93
+ { t: 20, s: [0] },
94
+ { t: 29, s: [0] },
95
+ { t: 44, s: [100] },
96
+ { t: 50, s: [100] }
97
+ ]
98
+ },
99
+ r: { a: 0, k: 0 },
100
+ p: {
101
+ a: 1,
102
+ k: [
103
+ { t: 0, s: [73, 35, 0] },
104
+ { t: 5, s: [73, 35, 0] },
105
+ { t: 9, s: [69, 35, 0] },
106
+ { t: 13, s: [54, 35, 0] },
107
+ { t: 17, s: [39, 35, 0] },
108
+ { t: 20, s: [35, 35, 0] },
109
+ { t: 29, s: [35, 35, 0] },
110
+ { t: 33, s: [39, 35, 0] },
111
+ { t: 37, s: [54, 35, 0] },
112
+ { t: 41, s: [69, 35, 0] },
113
+ { t: 44, s: [73, 35, 0] },
114
+ { t: 50, s: [73, 35, 0] }
115
+ ]
116
+ },
117
+ a: { a: 0, k: [35, 35, 0] },
118
+ s: { a: 0, k: [100, 100, 100] }
119
+ },
120
+ ao: 0,
121
+ shapes: [
122
+ {
123
+ ty: "gr",
124
+ nm: "Right",
125
+ it: [
126
+ {
127
+ ty: "sh",
128
+ nm: "Path",
129
+ ks: {
130
+ a: 0,
131
+ k: {
132
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
133
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
134
+ v: [[48.2249, 34.8401], [13.266, 69.546], [0, 56.28], [21.44, 34.84], [0, 13.266], [13.266, 0], [48.2249, 34.8401]],
135
+ c: true
136
+ }
137
+ }
138
+ },
139
+ {
140
+ ty: "fl",
141
+ nm: "Fill",
142
+ c: { a: 0, k: [0, 0.7961, 0.7529, 1] },
143
+ o: { a: 0, k: 100 },
144
+ r: 1
145
+ },
146
+ {
147
+ ty: "tr",
148
+ nm: "Transform",
149
+ p: { a: 0, k: [0, 0] },
150
+ a: { a: 0, k: [0, 0] },
151
+ s: { a: 0, k: [100, 100] },
152
+ r: { a: 0, k: 0 },
153
+ o: { a: 0, k: 100 },
154
+ sk: { a: 0, k: 0 },
155
+ sa: { a: 0, k: 0 }
156
+ }
157
+ ]
158
+ }
159
+ ],
160
+ ip: 0,
161
+ op: 50,
162
+ st: 0,
163
+ bm: 0
164
+ },
165
+ {
166
+ ddd: 0,
167
+ ind: 3,
168
+ ty: 4,
169
+ nm: "Chevron Left",
170
+ parent: 1,
171
+ ks: {
172
+ o: {
173
+ a: 1,
174
+ k: [
175
+ { t: 0, s: [100] },
176
+ { t: 17, s: [100] },
177
+ { t: 20, s: [0] },
178
+ { t: 29, s: [0] },
179
+ { t: 44, s: [100] },
180
+ { t: 50, s: [100] }
181
+ ]
182
+ },
183
+ r: { a: 0, k: 0 },
184
+ p: {
185
+ a: 1,
186
+ k: [
187
+ { t: 0, s: [-3, 35, 0] },
188
+ { t: 5, s: [-3, 35, 0] },
189
+ { t: 9, s: [1, 35, 0] },
190
+ { t: 13, s: [16, 35, 0] },
191
+ { t: 17, s: [31, 35, 0] },
192
+ { t: 20, s: [35, 35, 0] },
193
+ { t: 29, s: [35, 35, 0] },
194
+ { t: 33, s: [31, 35, 0] },
195
+ { t: 37, s: [16, 35, 0] },
196
+ { t: 41, s: [1, 35, 0] },
197
+ { t: 44, s: [-3, 35, 0] },
198
+ { t: 50, s: [-3, 35, 0] }
199
+ ]
200
+ },
201
+ a: { a: 0, k: [35, 35, 0] },
202
+ s: { a: 0, k: [100, 100, 100] }
203
+ },
204
+ ao: 0,
205
+ shapes: [
206
+ {
207
+ ty: "gr",
208
+ nm: "Left",
209
+ it: [
210
+ {
211
+ ty: "sh",
212
+ nm: "Path",
213
+ ks: {
214
+ a: 0,
215
+ k: {
216
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
217
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
218
+ v: [[48.106, 56.28], [34.84, 69.546], [0, 34.84], [34.84, 0], [48.106, 13.266], [26.532, 34.84], [48.106, 56.28]],
219
+ c: true
220
+ }
221
+ }
222
+ },
223
+ {
224
+ ty: "fl",
225
+ nm: "Fill",
226
+ c: { a: 0, k: [1, 0.0941, 0.1255, 1] },
227
+ o: { a: 0, k: 100 },
228
+ r: 1
229
+ },
230
+ {
231
+ ty: "tr",
232
+ nm: "Transform",
233
+ p: { a: 0, k: [21, 0] },
234
+ a: { a: 0, k: [0, 0] },
235
+ s: { a: 0, k: [100, 100] },
236
+ r: { a: 0, k: 0 },
237
+ o: { a: 0, k: 100 },
238
+ sk: { a: 0, k: 0 },
239
+ sa: { a: 0, k: 0 }
240
+ }
241
+ ]
242
+ }
243
+ ],
244
+ ip: 0,
245
+ op: 50,
246
+ st: 0,
247
+ bm: 0
248
+ },
249
+ {
250
+ ddd: 0,
251
+ ind: 4,
252
+ ty: 4,
253
+ nm: "Diamond",
254
+ parent: 1,
255
+ ks: {
256
+ o: {
257
+ a: 1,
258
+ k: [
259
+ { t: 0, s: [0] },
260
+ { t: 1, s: [0] },
261
+ { t: 2, s: [0] },
262
+ { t: 3, s: [0] },
263
+ { t: 4, s: [0] },
264
+ { t: 5, s: [0] },
265
+ { t: 6, s: [0] },
266
+ { t: 7, s: [0] },
267
+ { t: 8, s: [0] },
268
+ { t: 9, s: [0] },
269
+ { t: 10, s: [5] },
270
+ { t: 11, s: [33.889] },
271
+ { t: 12, s: [66.111] },
272
+ { t: 13, s: [95] },
273
+ { t: 14, s: [100] },
274
+ { t: 15, s: [71.111] },
275
+ { t: 16, s: [40] },
276
+ { t: 17, s: [17.778] },
277
+ { t: 18, s: [4.444] },
278
+ { t: 19, s: [0] },
279
+ { t: 20, s: [0] },
280
+ { t: 21, s: [0] },
281
+ { t: 22, s: [0] },
282
+ { t: 23, s: [0] },
283
+ { t: 24, s: [0] },
284
+ { t: 25, s: [0] },
285
+ { t: 26, s: [0] },
286
+ { t: 27, s: [0] },
287
+ { t: 28, s: [0] },
288
+ { t: 29, s: [4.444] },
289
+ { t: 30, s: [17.778] },
290
+ { t: 31, s: [40] },
291
+ { t: 32, s: [71.111] },
292
+ { t: 33, s: [100] },
293
+ { t: 34, s: [95] },
294
+ { t: 35, s: [66.111] },
295
+ { t: 36, s: [33.889] },
296
+ { t: 37, s: [5] },
297
+ { t: 38, s: [0] },
298
+ { t: 39, s: [0] },
299
+ { t: 40, s: [0] },
300
+ { t: 41, s: [0] },
301
+ { t: 42, s: [0] },
302
+ { t: 43, s: [0] },
303
+ { t: 44, s: [0] },
304
+ { t: 45, s: [0] },
305
+ { t: 46, s: [0] },
306
+ { t: 47, s: [0] },
307
+ { t: 48, s: [0] },
308
+ { t: 49, s: [0] },
309
+ { t: 50, s: [0] }
310
+ ]
311
+ },
312
+ r: { a: 0, k: 0 },
313
+ p: { a: 0, k: [35, 35, 0] },
314
+ a: { a: 0, k: [35, 35, 0] },
315
+ s: { a: 0, k: [100, 100, 100] }
316
+ },
317
+ ao: 0,
318
+ shapes: [
319
+ {
320
+ ty: "gr",
321
+ nm: "Diamond",
322
+ it: [
323
+ {
324
+ ty: "sh",
325
+ nm: "Path",
326
+ ks: {
327
+ a: 0,
328
+ k: {
329
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
330
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
331
+ v: [[13.3257, 515e-7], [0, 13.2661], [13.266, 26.5321], [26.532, 13.2661], [13.3257, 515e-7]],
332
+ c: true
333
+ }
334
+ }
335
+ },
336
+ {
337
+ ty: "fl",
338
+ nm: "Fill",
339
+ c: { a: 0, k: [0, 0.1961, 0.1647, 1] },
340
+ o: { a: 0, k: 100 },
341
+ r: 1
342
+ },
343
+ {
344
+ ty: "tr",
345
+ nm: "Transform",
346
+ p: { a: 0, k: [21.5, 21.5] },
347
+ a: { a: 0, k: [0, 0] },
348
+ s: { a: 0, k: [100, 100] },
349
+ r: { a: 0, k: 0 },
350
+ o: { a: 0, k: 100 },
351
+ sk: { a: 0, k: 0 },
352
+ sa: { a: 0, k: 0 }
353
+ }
354
+ ]
355
+ }
356
+ ],
357
+ ip: 0,
358
+ op: 50,
359
+ st: 0,
360
+ bm: 0
361
+ },
362
+ {
363
+ ddd: 0,
364
+ ind: 5,
365
+ ty: 4,
366
+ nm: "Final X",
367
+ parent: 1,
368
+ ks: {
369
+ o: {
370
+ a: 1,
371
+ k: [
372
+ { t: 0, s: [0] },
373
+ { t: 17, s: [0] },
374
+ { t: 20, s: [100] },
375
+ { t: 29, s: [100] },
376
+ { t: 44, s: [0] },
377
+ { t: 50, s: [0] }
378
+ ]
379
+ },
380
+ r: { a: 0, k: 0 },
381
+ p: { a: 0, k: [35, 35, 0] },
382
+ a: { a: 0, k: [35, 35, 0] },
383
+ s: { a: 0, k: [100, 100, 100] }
384
+ },
385
+ ao: 0,
386
+ shapes: [
387
+ {
388
+ ty: "gr",
389
+ nm: "Teal Arm",
390
+ it: [
391
+ {
392
+ ty: "sh",
393
+ nm: "Path",
394
+ ks: {
395
+ a: 0,
396
+ k: {
397
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
398
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
399
+ v: [[34.706, 48.106], [13.266, 69.546], [0, 56.28], [21.44, 34.84], [0, 13.266], [13.266, 0], [34.706, 21.574], [21.44, 34.84], [34.706, 48.106]],
400
+ c: true
401
+ }
402
+ }
403
+ },
404
+ {
405
+ ty: "fl",
406
+ nm: "Fill",
407
+ c: { a: 0, k: [0, 0.7961, 0.7529, 1] },
408
+ o: { a: 0, k: 100 },
409
+ r: 1
410
+ },
411
+ {
412
+ ty: "tr",
413
+ nm: "Transform",
414
+ p: { a: 0, k: [0, 0] },
415
+ a: { a: 0, k: [0, 0] },
416
+ s: { a: 0, k: [100, 100] },
417
+ r: { a: 0, k: 0 },
418
+ o: { a: 0, k: 100 },
419
+ sk: { a: 0, k: 0 },
420
+ sa: { a: 0, k: 0 }
421
+ }
422
+ ]
423
+ },
424
+ {
425
+ ty: "gr",
426
+ nm: "Red Arm",
427
+ it: [
428
+ {
429
+ ty: "sh",
430
+ nm: "Path",
431
+ ks: {
432
+ a: 0,
433
+ k: {
434
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
435
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
436
+ v: [[69.546, 56.2801], [56.28, 69.5461], [34.706, 48.106], [47.972, 34.8401], [34.706, 21.574], [56.28, 534e-7], [69.546, 13.2661], [47.972, 34.8401], [69.546, 56.2801]],
437
+ c: true
438
+ }
439
+ }
440
+ },
441
+ {
442
+ ty: "fl",
443
+ nm: "Fill",
444
+ c: { a: 0, k: [1, 0.0941, 0.1255, 1] },
445
+ o: { a: 0, k: 100 },
446
+ r: 1
447
+ },
448
+ {
449
+ ty: "tr",
450
+ nm: "Transform",
451
+ p: { a: 0, k: [0, 0] },
452
+ a: { a: 0, k: [0, 0] },
453
+ s: { a: 0, k: [100, 100] },
454
+ r: { a: 0, k: 0 },
455
+ o: { a: 0, k: 100 },
456
+ sk: { a: 0, k: 0 },
457
+ sa: { a: 0, k: 0 }
458
+ }
459
+ ]
460
+ },
461
+ {
462
+ ty: "gr",
463
+ nm: "Center Diamond",
464
+ it: [
465
+ {
466
+ ty: "sh",
467
+ nm: "Path",
468
+ ks: {
469
+ a: 0,
470
+ k: {
471
+ i: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
472
+ o: [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
473
+ v: [[34.7656, 48.1061], [21.44, 34.84], [34.706, 21.574], [47.972, 34.8401], [34.7656, 48.1061]],
474
+ c: true
475
+ }
476
+ }
477
+ },
478
+ {
479
+ ty: "fl",
480
+ nm: "Fill",
481
+ c: { a: 0, k: [0, 0.1961, 0.1647, 1] },
482
+ o: { a: 0, k: 100 },
483
+ r: 1
484
+ },
485
+ {
486
+ ty: "tr",
487
+ nm: "Transform",
488
+ p: { a: 0, k: [0, 0] },
489
+ a: { a: 0, k: [0, 0] },
490
+ s: { a: 0, k: [100, 100] },
491
+ r: { a: 0, k: 0 },
492
+ o: { a: 0, k: 100 },
493
+ sk: { a: 0, k: 0 },
494
+ sa: { a: 0, k: 0 }
495
+ }
496
+ ]
497
+ }
498
+ ],
499
+ ip: 0,
500
+ op: 50,
501
+ st: 0,
502
+ bm: 0
503
+ }
504
+ ]
505
+ };
506
+ }
507
+ });
508
+
30
509
  // src/index.ts
31
510
  var index_exports = {};
32
511
  __export(index_exports, {
@@ -38,7 +517,7 @@ module.exports = __toCommonJS(index_exports);
38
517
 
39
518
  // src/studio/ComergeStudio.tsx
40
519
  var React51 = __toESM(require("react"));
41
- var import_react_native60 = require("react-native");
520
+ var import_react_native61 = require("react-native");
42
521
  var import_bottom_sheet6 = require("@gorhom/bottom-sheet");
43
522
  var import_runtime2 = require("@comergehq/runtime");
44
523
 
@@ -2420,6 +2899,13 @@ var AttachmentRemoteDataSourceImpl = class extends BaseRemote {
2420
2899
  );
2421
2900
  return data;
2422
2901
  }
2902
+ async stagePresign(payload) {
2903
+ const { data } = await api.post(
2904
+ "/v1/attachments/stage/presign",
2905
+ payload
2906
+ );
2907
+ return data;
2908
+ }
2423
2909
  };
2424
2910
  var attachmentRemoteDataSource = new AttachmentRemoteDataSourceImpl();
2425
2911
 
@@ -2433,6 +2919,10 @@ var AttachmentRepositoryImpl = class extends BaseRepository {
2433
2919
  const res = await this.remote.presign(payload);
2434
2920
  return this.unwrapOrThrow(res);
2435
2921
  }
2922
+ async stagePresign(payload) {
2923
+ const res = await this.remote.stagePresign(payload);
2924
+ return this.unwrapOrThrow(res);
2925
+ }
2436
2926
  async upload(upload, file) {
2437
2927
  const resp = await fetch(upload.uploadUrl, {
2438
2928
  method: "PUT",
@@ -2443,6 +2933,16 @@ var AttachmentRepositoryImpl = class extends BaseRepository {
2443
2933
  throw new Error(`upload failed: ${resp.status}`);
2444
2934
  }
2445
2935
  }
2936
+ async uploadStaged(upload, file) {
2937
+ const resp = await fetch(upload.uploadUrl, {
2938
+ method: "PUT",
2939
+ headers: upload.headers,
2940
+ body: file
2941
+ });
2942
+ if (!resp.ok) {
2943
+ throw new Error(`staged upload failed: ${resp.status}`);
2944
+ }
2945
+ }
2446
2946
  };
2447
2947
  var attachmentRepository = new AttachmentRepositoryImpl(
2448
2948
  attachmentRemoteDataSource
@@ -2516,7 +3016,36 @@ function useAttachmentUpload() {
2516
3016
  setUploading(false);
2517
3017
  }
2518
3018
  }, []);
2519
- return { uploadBase64Images, uploading, error };
3019
+ const stageBase64Images = React7.useCallback(async ({ dataUrls }) => {
3020
+ if (!dataUrls || dataUrls.length === 0) return [];
3021
+ setUploading(true);
3022
+ setError(null);
3023
+ try {
3024
+ const blobs = await Promise.all(
3025
+ dataUrls.map(async (dataUrl) => {
3026
+ const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
3027
+ const blob = import_react_native6.Platform.OS === "android" ? await dataUrlToBlobAndroid(normalized) : await (await fetch(normalized)).blob();
3028
+ const mimeType = getMimeTypeFromDataUrl(normalized);
3029
+ return { blob, mimeType };
3030
+ })
3031
+ );
3032
+ const files = blobs.map(({ blob, mimeType }, idx) => ({
3033
+ name: `attachment-${Date.now()}-${idx}.png`,
3034
+ size: blob.size,
3035
+ mimeType
3036
+ }));
3037
+ const presign = await attachmentRepository.stagePresign({ files });
3038
+ await Promise.all(presign.uploads.map((u, index) => attachmentRepository.uploadStaged(u, blobs[index].blob)));
3039
+ return presign.uploads.map((u) => u.attachmentToken);
3040
+ } catch (e) {
3041
+ const err = e instanceof Error ? e : new Error(String(e));
3042
+ setError(err);
3043
+ throw err;
3044
+ } finally {
3045
+ setUploading(false);
3046
+ }
3047
+ }, []);
3048
+ return { uploadBase64Images, stageBase64Images, uploading, error };
2520
3049
  }
2521
3050
 
2522
3051
  // src/studio/hooks/useStudioActions.ts
@@ -2532,6 +3061,10 @@ var AgentRemoteDataSourceImpl = class extends BaseRemote {
2532
3061
  const { data } = await api.post("/v1/agent/editApp", payload);
2533
3062
  return data;
2534
3063
  }
3064
+ async forkEditStart(payload) {
3065
+ const { data } = await api.post("/v1/agent/forkEditStart", payload);
3066
+ return data;
3067
+ }
2535
3068
  };
2536
3069
  var agentRemoteDataSource = new AgentRemoteDataSourceImpl();
2537
3070
 
@@ -2549,6 +3082,10 @@ var AgentRepositoryImpl = class extends BaseRepository {
2549
3082
  const res = await this.remote.editApp(payload);
2550
3083
  return this.unwrapOrThrow(res);
2551
3084
  }
3085
+ async forkEditStart(payload) {
3086
+ const res = await this.remote.forkEditStart(payload);
3087
+ return this.unwrapOrThrow(res);
3088
+ }
2552
3089
  };
2553
3090
  var agentRepository = new AgentRepositoryImpl(agentRemoteDataSource);
2554
3091
 
@@ -2599,7 +3136,8 @@ function useStudioActions({
2599
3136
  onEditStart,
2600
3137
  onEditQueued,
2601
3138
  onEditFinished,
2602
- uploadAttachments
3139
+ uploadAttachments,
3140
+ stageAttachments
2603
3141
  }) {
2604
3142
  const [forking, setForking] = React8.useState(false);
2605
3143
  const [sending, setSending] = React8.useState(false);
@@ -2619,16 +3157,46 @@ function useStudioActions({
2619
3157
  const sourceAppId = app.id;
2620
3158
  if (shouldForkOnEdit) {
2621
3159
  setForking(true);
2622
- const forked = await appsRepository.fork(app.id, {});
2623
- targetApp = forked;
3160
+ let attachmentTokens;
3161
+ if (attachments && attachments.length > 0 && stageAttachments) {
3162
+ attachmentTokens = await stageAttachments({ dataUrls: attachments });
3163
+ }
3164
+ const idempotencyKey2 = generateIdempotencyKey();
3165
+ const startResult = await withRetry2(
3166
+ async () => await agentRepository.forkEditStart({
3167
+ source_app_id: sourceAppId,
3168
+ prompt,
3169
+ attachmentTokens,
3170
+ idempotencyKey: idempotencyKey2
3171
+ }),
3172
+ { attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
3173
+ );
3174
+ targetApp = {
3175
+ ...app,
3176
+ id: startResult.targetAppId,
3177
+ threadId: startResult.targetThreadId
3178
+ };
2624
3179
  await trackRemixApp({
2625
- appId: forked.id,
3180
+ appId: startResult.targetAppId,
2626
3181
  sourceAppId,
2627
- threadId: forked.threadId ?? void 0,
3182
+ threadId: startResult.targetThreadId ?? void 0,
2628
3183
  success: true
2629
3184
  });
2630
3185
  forkSucceeded = true;
2631
- onForkedApp == null ? void 0 : onForkedApp(forked.id, { keepRenderingAppId: sourceAppId });
3186
+ onForkedApp == null ? void 0 : onForkedApp(startResult.targetAppId, { keepRenderingAppId: sourceAppId });
3187
+ onEditStart == null ? void 0 : onEditStart();
3188
+ onEditQueued == null ? void 0 : onEditQueued({
3189
+ queueItemId: startResult.queueItemId ?? null,
3190
+ queuePosition: startResult.queuePosition ?? null
3191
+ });
3192
+ await trackEditApp({
3193
+ appId: startResult.targetAppId,
3194
+ threadId: startResult.targetThreadId,
3195
+ promptLength: prompt.trim().length,
3196
+ success: true
3197
+ });
3198
+ setForking(false);
3199
+ return;
2632
3200
  }
2633
3201
  setForking(false);
2634
3202
  const threadId = targetApp.threadId;
@@ -2689,7 +3257,18 @@ function useStudioActions({
2689
3257
  onEditFinished == null ? void 0 : onEditFinished();
2690
3258
  }
2691
3259
  },
2692
- [app, onEditFinished, onEditQueued, onEditStart, onForkedApp, sending, shouldForkOnEdit, uploadAttachments, userId]
3260
+ [
3261
+ app,
3262
+ onEditFinished,
3263
+ onEditQueued,
3264
+ onEditStart,
3265
+ onForkedApp,
3266
+ sending,
3267
+ shouldForkOnEdit,
3268
+ stageAttachments,
3269
+ uploadAttachments,
3270
+ userId
3271
+ ]
2693
3272
  );
2694
3273
  return { isOwner, shouldForkOnEdit, forking, sending, error, sendEdit };
2695
3274
  }
@@ -2737,7 +3316,7 @@ function RuntimeRenderer({
2737
3316
 
2738
3317
  // src/studio/ui/StudioOverlay.tsx
2739
3318
  var React46 = __toESM(require("react"));
2740
- var import_react_native59 = require("react-native");
3319
+ var import_react_native60 = require("react-native");
2741
3320
 
2742
3321
  // src/components/studio-sheet/StudioBottomSheet.tsx
2743
3322
  var React12 = __toESM(require("react"));
@@ -4640,7 +5219,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
4640
5219
 
4641
5220
  // src/studio/ui/PreviewPanel.tsx
4642
5221
  var React36 = __toESM(require("react"));
4643
- var import_react_native45 = require("react-native");
5222
+ var import_react_native46 = require("react-native");
4644
5223
 
4645
5224
  // src/components/preview/PreviewPage.tsx
4646
5225
  var import_react_native24 = require("react-native");
@@ -4669,8 +5248,7 @@ function PreviewPage({ header, children, contentStyle }) {
4669
5248
  }
4670
5249
 
4671
5250
  // src/studio/ui/preview-panel/PreviewPanelHeader.tsx
4672
- var React26 = __toESM(require("react"));
4673
- var import_react_native30 = require("react-native");
5251
+ var import_react_native27 = require("react-native");
4674
5252
 
4675
5253
  // src/components/studio-sheet/StudioSheetHeader.tsx
4676
5254
  var import_react_native25 = require("react-native");
@@ -4789,12 +5367,56 @@ function StudioSheetHeaderIconButton({
4789
5367
  ) });
4790
5368
  }
4791
5369
 
4792
- // src/components/primitives/Modal.tsx
4793
- var import_react_native28 = require("react-native");
5370
+ // src/studio/ui/preview-panel/PreviewPanelHeader.tsx
5371
+ var import_jsx_runtime24 = require("react/jsx-runtime");
5372
+ function PreviewPanelHeader({
5373
+ isOwner,
5374
+ isPublic,
5375
+ onClose,
5376
+ onNavigateHome,
5377
+ onGoToChat,
5378
+ onShare
5379
+ }) {
5380
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5381
+ StudioSheetHeader,
5382
+ {
5383
+ left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
5384
+ center: null,
5385
+ right: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native27.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5386
+ isOwner ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5387
+ StudioSheetHeaderIconButton,
5388
+ {
5389
+ onPress: onGoToChat,
5390
+ accessibilityLabel: "Chat",
5391
+ intent: "primary",
5392
+ appearance: "glass",
5393
+ style: { marginRight: 8 },
5394
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconChat, { size: 20, colorToken: "onPrimary" })
5395
+ }
5396
+ ) : null,
5397
+ isPublic && onShare ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5398
+ StudioSheetHeaderIconButton,
5399
+ {
5400
+ onPress: onShare,
5401
+ accessibilityLabel: "Share",
5402
+ intent: "primary",
5403
+ appearance: "glass",
5404
+ style: { marginRight: 8 },
5405
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconShare, { size: 20, colorToken: "onPrimary" })
5406
+ }
5407
+ ) : null,
5408
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconClose, { size: 20, colorToken: "onPrimary" }) })
5409
+ ] })
5410
+ }
5411
+ );
5412
+ }
5413
+
5414
+ // src/components/preview/PreviewHeroCard.tsx
5415
+ var import_react_native29 = require("react-native");
4794
5416
 
4795
5417
  // src/components/primitives/Surface.tsx
4796
- var import_react_native27 = require("react-native");
4797
- var import_jsx_runtime24 = require("react/jsx-runtime");
5418
+ var import_react_native28 = require("react-native");
5419
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4798
5420
  function backgroundFor(variant, theme) {
4799
5421
  const { colors } = theme;
4800
5422
  switch (variant) {
@@ -4811,8 +5433,8 @@ function backgroundFor(variant, theme) {
4811
5433
  }
4812
5434
  function Surface({ variant = "surface", border = false, style, ...props }) {
4813
5435
  const theme = useTheme();
4814
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4815
- import_react_native27.View,
5436
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5437
+ import_react_native28.View,
4816
5438
  {
4817
5439
  ...props,
4818
5440
  style: [
@@ -4825,12 +5447,12 @@ function Surface({ variant = "surface", border = false, style, ...props }) {
4825
5447
  }
4826
5448
 
4827
5449
  // src/components/primitives/Card.tsx
4828
- var import_jsx_runtime25 = require("react/jsx-runtime");
5450
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4829
5451
  function Card({ variant = "surface", padded = true, border = true, style, ...props }) {
4830
5452
  const theme = useTheme();
4831
5453
  const radius = theme.radii.lg;
4832
5454
  const padding = padded ? theme.spacing.lg : 0;
4833
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5455
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4834
5456
  Surface,
4835
5457
  {
4836
5458
  ...props,
@@ -4841,325 +5463,59 @@ function Card({ variant = "surface", padded = true, border = true, style, ...pro
4841
5463
  );
4842
5464
  }
4843
5465
 
4844
- // src/components/primitives/Modal.tsx
4845
- var import_jsx_runtime26 = require("react/jsx-runtime");
4846
- function Modal({
4847
- visible,
4848
- onRequestClose,
4849
- dismissOnBackdropPress = true,
4850
- children,
4851
- contentStyle
5466
+ // src/components/preview/PreviewHeroCard.tsx
5467
+ var import_jsx_runtime27 = require("react/jsx-runtime");
5468
+ function PreviewHeroCard({
5469
+ aspectRatio = 4 / 3,
5470
+ overlayTopLeft,
5471
+ background,
5472
+ image,
5473
+ overlayBottom,
5474
+ style
4852
5475
  }) {
4853
5476
  const theme = useTheme();
4854
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4855
- import_react_native28.Modal,
5477
+ const radius = 16;
5478
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5479
+ Card,
4856
5480
  {
4857
- visible,
4858
- transparent: true,
4859
- animationType: "fade",
4860
- onRequestClose,
4861
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native28.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
4862
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4863
- import_react_native28.Pressable,
4864
- {
4865
- accessibilityRole: "button",
4866
- onPress: dismissOnBackdropPress ? onRequestClose : void 0,
4867
- style: { position: "absolute", inset: 0 }
4868
- }
4869
- ),
4870
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
4871
- ] })
4872
- }
4873
- );
4874
- }
4875
-
4876
- // src/components/preview/PreviewStatusBadge.tsx
4877
- var import_react_native29 = require("react-native");
4878
- var import_lucide_react_native5 = require("lucide-react-native");
4879
-
4880
- // src/data/apps/types.ts
4881
- var APP_STATUS_LABEL = {
4882
- ready: "Ready",
4883
- creating: "Creating",
4884
- editing: "Editing",
4885
- forking: "Forking",
4886
- merging: "Merging",
4887
- error: "Error",
4888
- archived: "Archived"
4889
- };
4890
-
4891
- // src/components/preview/PreviewStatusBadge.tsx
4892
- var import_jsx_runtime27 = require("react/jsx-runtime");
4893
- var STATUS_BG = {
4894
- ready: "#10B981",
4895
- // emerald-500
4896
- creating: "#3B82F6",
4897
- // blue-500
4898
- editing: "#F59E0B",
4899
- // amber-500
4900
- forking: "#00CBC0",
4901
- // brand teal
4902
- merging: "#06B6D4",
4903
- // cyan-500
4904
- error: "#F43F5E",
4905
- // rose-500
4906
- archived: "#71717A"
4907
- // zinc-500
4908
- };
4909
- var STATUS_ICON = {
4910
- ready: import_lucide_react_native5.CheckCircle2,
4911
- creating: import_lucide_react_native5.Sparkles,
4912
- editing: import_lucide_react_native5.Pencil,
4913
- forking: import_lucide_react_native5.GitFork,
4914
- merging: import_lucide_react_native5.GitMerge,
4915
- error: import_lucide_react_native5.AlertTriangle,
4916
- archived: import_lucide_react_native5.Archive
4917
- };
4918
- function PreviewStatusBadge({ status }) {
4919
- const IconComp = STATUS_ICON[status];
4920
- const label = APP_STATUS_LABEL[status] ?? status;
4921
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4922
- import_react_native29.View,
4923
- {
4924
- style: {
4925
- flexDirection: "row",
4926
- alignItems: "center",
4927
- borderRadius: 999,
4928
- paddingHorizontal: 10,
4929
- paddingVertical: 4,
4930
- backgroundColor: STATUS_BG[status]
4931
- },
4932
- children: [
4933
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
4934
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
4935
- ]
4936
- }
4937
- );
4938
- }
4939
-
4940
- // src/studio/ui/preview-panel/PreviewPanelHeader.tsx
4941
- var import_jsx_runtime28 = require("react/jsx-runtime");
4942
- function PreviewPanelHeader({
4943
- isOwner,
4944
- isPublic,
4945
- onClose,
4946
- onNavigateHome,
4947
- onGoToChat,
4948
- onShare,
4949
- relatedApps,
4950
- relatedAppsLoading,
4951
- switchingRelatedAppId,
4952
- onOpenRelatedApps,
4953
- onSwitchRelatedApp
4954
- }) {
4955
- var _a;
4956
- const theme = useTheme();
4957
- const [relatedAppsOpen, setRelatedAppsOpen] = React26.useState(false);
4958
- const relatedAppItems = React26.useMemo(() => {
4959
- if (!relatedApps) return [];
4960
- const items = [];
4961
- if (relatedApps.original) {
4962
- items.push({ app: relatedApps.original, section: "original" });
4963
- }
4964
- for (const remix of relatedApps.remixes) {
4965
- items.push({ app: remix, section: "remix" });
4966
- }
4967
- return items;
4968
- }, [relatedApps]);
4969
- const uniqueRelatedCount = React26.useMemo(() => {
4970
- return new Set(relatedAppItems.map((item) => item.app.id)).size;
4971
- }, [relatedAppItems]);
4972
- const shouldShowRelatedApps = uniqueRelatedCount >= 2;
4973
- const currentAppId = relatedApps == null ? void 0 : relatedApps.current.id;
4974
- const originalAppId = ((_a = relatedApps == null ? void 0 : relatedApps.original) == null ? void 0 : _a.id) ?? null;
4975
- const sectionedRelatedApps = React26.useMemo(() => {
4976
- const original = [];
4977
- const remixes = [];
4978
- const seenIds = /* @__PURE__ */ new Set();
4979
- for (const item of relatedAppItems) {
4980
- if (seenIds.has(item.app.id)) continue;
4981
- seenIds.add(item.app.id);
4982
- if (item.section === "original") {
4983
- original.push(item);
4984
- } else {
4985
- remixes.push(item);
4986
- }
4987
- }
4988
- return { original, remixes };
4989
- }, [relatedAppItems]);
4990
- const openRelatedApps = React26.useCallback(() => {
4991
- setRelatedAppsOpen(true);
4992
- onOpenRelatedApps == null ? void 0 : onOpenRelatedApps();
4993
- }, [onOpenRelatedApps]);
4994
- const closeRelatedApps = React26.useCallback(() => {
4995
- setRelatedAppsOpen(false);
4996
- }, []);
4997
- const handleSelectRelatedApp = React26.useCallback(
4998
- (targetAppId) => {
4999
- if (!relatedApps) return;
5000
- if (targetAppId === relatedApps.current.id) return;
5001
- onSwitchRelatedApp == null ? void 0 : onSwitchRelatedApp(targetAppId);
5002
- setRelatedAppsOpen(false);
5003
- },
5004
- [onSwitchRelatedApp, relatedApps]
5005
- );
5006
- const renderRelatedRow = React26.useCallback(
5007
- (item) => {
5008
- const app = item.app;
5009
- const isCurrent = app.id === currentAppId;
5010
- const isOriginal = app.id === originalAppId;
5011
- const isReady = app.status === "ready";
5012
- const isSwitching = switchingRelatedAppId === app.id;
5013
- const disabled = isCurrent || !isReady || Boolean(switchingRelatedAppId);
5014
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5015
- import_react_native30.Pressable,
5016
- {
5017
- accessibilityRole: "button",
5018
- accessibilityLabel: `Switch to ${app.name}`,
5019
- disabled,
5020
- onPress: () => handleSelectRelatedApp(app.id),
5021
- style: {
5022
- borderRadius: theme.radii.md,
5023
- borderWidth: 1,
5024
- borderColor: theme.colors.border,
5025
- backgroundColor: theme.colors.surface,
5026
- paddingHorizontal: theme.spacing.md,
5027
- paddingVertical: theme.spacing.sm,
5028
- marginBottom: theme.spacing.sm,
5029
- opacity: disabled ? 0.6 : 1
5030
- },
5031
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 8 }, children: [
5032
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { flex: 1, paddingRight: 8 }, children: [
5033
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { numberOfLines: 1, style: { color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: app.name }),
5034
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.View, { style: { height: 4 } }),
5035
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: 6 }, children: [
5036
- isOriginal ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.View, { style: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2, backgroundColor: theme.colors.neutral }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 11 }, children: "Original" }) }) : null,
5037
- isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.View, { style: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2, backgroundColor: theme.colors.primary }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { style: { color: theme.colors.onPrimary, fontSize: 11 }, children: "Current" }) }) : null
5038
- ] })
5039
- ] }),
5040
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { alignItems: "flex-end", gap: 8 }, children: [
5041
- app.status ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(PreviewStatusBadge, { status: app.status }) : null,
5042
- isSwitching ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.ActivityIndicator, { size: "small", color: theme.colors.primary }) : null
5043
- ] })
5044
- ] })
5045
- },
5046
- app.id
5047
- );
5048
- },
5049
- [currentAppId, handleSelectRelatedApp, originalAppId, switchingRelatedAppId, theme]
5050
- );
5051
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5052
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5053
- StudioSheetHeader,
5054
- {
5055
- left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
5056
- center: null,
5057
- right: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5058
- isOwner ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5059
- StudioSheetHeaderIconButton,
5060
- {
5061
- onPress: onGoToChat,
5062
- accessibilityLabel: "Chat",
5063
- intent: "primary",
5064
- appearance: "glass",
5065
- style: { marginRight: 8 },
5066
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconChat, { size: 20, colorToken: "onPrimary" })
5067
- }
5068
- ) : null,
5069
- isPublic && onShare ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5070
- StudioSheetHeaderIconButton,
5071
- {
5072
- onPress: onShare,
5073
- accessibilityLabel: "Share",
5074
- intent: "primary",
5075
- appearance: "glass",
5076
- style: { marginRight: 8 },
5077
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconShare, { size: 20, colorToken: "onPrimary" })
5078
- }
5079
- ) : null,
5080
- shouldShowRelatedApps ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5081
- StudioSheetHeaderIconButton,
5082
- {
5083
- onPress: openRelatedApps,
5084
- accessibilityLabel: "Related apps",
5085
- intent: "primary",
5086
- appearance: "glass",
5087
- style: { marginRight: 8 },
5088
- children: relatedAppsLoading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.ActivityIndicator, { size: "small", color: theme.colors.onPrimary }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconChevronDown, { size: 20, colorToken: "onPrimary" })
5089
- }
5090
- ) : null,
5091
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconClose, { size: 20, colorToken: "onPrimary" }) })
5092
- ] })
5093
- }
5094
- ),
5095
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Modal, { visible: relatedAppsOpen, onRequestClose: closeRelatedApps, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { style: { gap: theme.spacing.sm }, children: [
5096
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { style: { color: theme.colors.text, fontSize: 18, fontWeight: theme.typography.fontWeight.semibold }, children: "Related apps" }),
5097
- sectionedRelatedApps.original.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { children: [
5098
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { style: { color: theme.colors.textMuted, marginBottom: theme.spacing.xs }, children: "Original" }),
5099
- sectionedRelatedApps.original.map(renderRelatedRow)
5100
- ] }) : null,
5101
- sectionedRelatedApps.remixes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native30.View, { children: [
5102
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { style: { color: theme.colors.textMuted, marginBottom: theme.spacing.xs }, children: "Remixes" }),
5103
- sectionedRelatedApps.remixes.map(renderRelatedRow)
5104
- ] }) : null
5105
- ] }) })
5106
- ] });
5107
- }
5108
-
5109
- // src/components/preview/PreviewHeroCard.tsx
5110
- var import_react_native31 = require("react-native");
5111
- var import_jsx_runtime29 = require("react/jsx-runtime");
5112
- function PreviewHeroCard({
5113
- aspectRatio = 4 / 3,
5114
- overlayTopLeft,
5115
- background,
5116
- image,
5117
- overlayBottom,
5118
- style
5119
- }) {
5120
- const theme = useTheme();
5121
- const radius = 16;
5122
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5123
- Card,
5124
- {
5125
- variant: "surfaceRaised",
5126
- padded: false,
5127
- border: false,
5128
- style: [
5129
- {
5130
- width: "100%",
5131
- aspectRatio,
5132
- borderRadius: radius,
5133
- overflow: "hidden"
5134
- },
5135
- style
5136
- ],
5137
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native31.View, { style: { flex: 1 }, children: [
5138
- background ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native31.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
5139
- image ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native31.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
5140
- overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native31.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
5141
- overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native31.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
5481
+ variant: "surfaceRaised",
5482
+ padded: false,
5483
+ border: false,
5484
+ style: [
5485
+ {
5486
+ width: "100%",
5487
+ aspectRatio,
5488
+ borderRadius: radius,
5489
+ overflow: "hidden"
5490
+ },
5491
+ style
5492
+ ],
5493
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native29.View, { style: { flex: 1 }, children: [
5494
+ background ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native29.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
5495
+ image ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native29.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
5496
+ overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native29.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
5497
+ overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native29.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
5142
5498
  ] })
5143
5499
  }
5144
5500
  );
5145
5501
  }
5146
5502
 
5147
5503
  // src/components/preview/PreviewPlaceholder.tsx
5148
- var React27 = __toESM(require("react"));
5149
- var import_react_native32 = require("react-native");
5504
+ var React26 = __toESM(require("react"));
5505
+ var import_react_native30 = require("react-native");
5150
5506
  var import_expo_linear_gradient2 = require("expo-linear-gradient");
5151
- var import_jsx_runtime30 = require("react/jsx-runtime");
5507
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5152
5508
  function PreviewPlaceholder({ visible, style }) {
5153
5509
  if (!visible) return null;
5154
- const opacityAnim = React27.useRef(new import_react_native32.Animated.Value(0)).current;
5155
- React27.useEffect(() => {
5510
+ const opacityAnim = React26.useRef(new import_react_native30.Animated.Value(0)).current;
5511
+ React26.useEffect(() => {
5156
5512
  if (!visible) return;
5157
- const animation = import_react_native32.Animated.loop(
5158
- import_react_native32.Animated.sequence([
5159
- import_react_native32.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
5160
- import_react_native32.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
5161
- import_react_native32.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
5162
- import_react_native32.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
5513
+ const animation = import_react_native30.Animated.loop(
5514
+ import_react_native30.Animated.sequence([
5515
+ import_react_native30.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
5516
+ import_react_native30.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
5517
+ import_react_native30.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
5518
+ import_react_native30.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
5163
5519
  ])
5164
5520
  );
5165
5521
  animation.start();
@@ -5169,8 +5525,8 @@ function PreviewPlaceholder({ visible, style }) {
5169
5525
  const opacity2 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 1, 0, 0] });
5170
5526
  const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
5171
5527
  const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
5172
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
5173
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native32.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5528
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5529
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5174
5530
  import_expo_linear_gradient2.LinearGradient,
5175
5531
  {
5176
5532
  colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
@@ -5179,7 +5535,7 @@ function PreviewPlaceholder({ visible, style }) {
5179
5535
  style: { width: "100%", height: "100%" }
5180
5536
  }
5181
5537
  ) }),
5182
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native32.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5538
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5183
5539
  import_expo_linear_gradient2.LinearGradient,
5184
5540
  {
5185
5541
  colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
@@ -5188,7 +5544,7 @@ function PreviewPlaceholder({ visible, style }) {
5188
5544
  style: { width: "100%", height: "100%" }
5189
5545
  }
5190
5546
  ) }),
5191
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native32.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5547
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5192
5548
  import_expo_linear_gradient2.LinearGradient,
5193
5549
  {
5194
5550
  colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
@@ -5197,7 +5553,7 @@ function PreviewPlaceholder({ visible, style }) {
5197
5553
  style: { width: "100%", height: "100%" }
5198
5554
  }
5199
5555
  ) }),
5200
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native32.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5556
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5201
5557
  import_expo_linear_gradient2.LinearGradient,
5202
5558
  {
5203
5559
  colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
@@ -5210,12 +5566,12 @@ function PreviewPlaceholder({ visible, style }) {
5210
5566
  }
5211
5567
 
5212
5568
  // src/components/preview/PreviewImage.tsx
5213
- var import_react_native33 = require("react-native");
5214
- var import_jsx_runtime31 = require("react/jsx-runtime");
5569
+ var import_react_native31 = require("react-native");
5570
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5215
5571
  function PreviewImage({ uri, onLoad, style }) {
5216
5572
  if (!uri) return null;
5217
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5218
- import_react_native33.Image,
5573
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5574
+ import_react_native31.Image,
5219
5575
  {
5220
5576
  source: { uri },
5221
5577
  resizeMode: "cover",
@@ -5226,15 +5582,15 @@ function PreviewImage({ uri, onLoad, style }) {
5226
5582
  }
5227
5583
 
5228
5584
  // src/components/preview/StatsBar.tsx
5229
- var import_react_native34 = require("react-native");
5585
+ var import_react_native32 = require("react-native");
5230
5586
  var import_liquid_glass7 = require("@callstack/liquid-glass");
5231
- var import_lucide_react_native6 = require("lucide-react-native");
5587
+ var import_lucide_react_native5 = require("lucide-react-native");
5232
5588
 
5233
5589
  // src/components/icons/MergeIcon.tsx
5234
5590
  var import_react_native_svg2 = __toESM(require("react-native-svg"));
5235
- var import_jsx_runtime32 = require("react/jsx-runtime");
5591
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5236
5592
  function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }) {
5237
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native_svg2.default, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5593
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native_svg2.default, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5238
5594
  import_react_native_svg2.Path,
5239
5595
  {
5240
5596
  d: "M237.025 0H243.664C254.876 95.0361 275.236 175.597 304.743 241.684C334.249 307.478 367.002 357.774 403 392.572L389.722 486C361.691 458.22 338.233 429.417 319.349 399.59C300.464 369.764 284.531 335.843 271.548 297.829C258.565 259.522 246.615 214.343 235.697 162.292L237.91 161.415C228.468 214.928 217.993 261.569 206.485 301.338C194.978 341.107 179.634 375.904 160.455 405.731C141.571 435.265 115.752 462.022 83 486L96.278 392.572C124.014 369.179 147.62 336.72 167.094 295.197C186.864 253.381 202.65 206.886 214.452 155.713C226.255 104.247 233.779 52.343 237.025 0Z",
@@ -5244,7 +5600,7 @@ function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }
5244
5600
  }
5245
5601
 
5246
5602
  // src/components/preview/StatsBar.tsx
5247
- var import_jsx_runtime33 = require("react/jsx-runtime");
5603
+ var import_jsx_runtime31 = require("react/jsx-runtime");
5248
5604
  function StatsBar({
5249
5605
  likeCount,
5250
5606
  commentCount,
@@ -5258,15 +5614,15 @@ function StatsBar({
5258
5614
  }) {
5259
5615
  const theme = useTheme();
5260
5616
  const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
5261
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5262
- import_react_native34.View,
5617
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5618
+ import_react_native32.View,
5263
5619
  {
5264
5620
  style: [
5265
5621
  { position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
5266
5622
  centered && { alignItems: "center" },
5267
5623
  style
5268
5624
  ],
5269
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5625
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5270
5626
  ResettableLiquidGlassView,
5271
5627
  {
5272
5628
  style: [
@@ -5275,17 +5631,17 @@ function StatsBar({
5275
5631
  !import_liquid_glass7.isLiquidGlassSupported && { backgroundColor: statsBgColor }
5276
5632
  ],
5277
5633
  effect: "clear",
5278
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
5279
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5280
- import_react_native34.Pressable,
5634
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
5635
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5636
+ import_react_native32.Pressable,
5281
5637
  {
5282
5638
  disabled: !onPressLike,
5283
5639
  onPress: onPressLike,
5284
5640
  hitSlop: 8,
5285
5641
  style: { paddingVertical: 8 },
5286
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5287
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5288
- import_lucide_react_native6.Heart,
5642
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5643
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5644
+ import_lucide_react_native5.Heart,
5289
5645
  {
5290
5646
  size: 16,
5291
5647
  strokeWidth: 2.5,
@@ -5293,8 +5649,8 @@ function StatsBar({
5293
5649
  fill: isLiked ? theme.colors.danger : "transparent"
5294
5650
  }
5295
5651
  ),
5296
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native34.View, { style: { width: 4 } }),
5297
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5652
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native32.View, { style: { width: 4 } }),
5653
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5298
5654
  Text,
5299
5655
  {
5300
5656
  variant: "caption",
@@ -5308,72 +5664,415 @@ function StatsBar({
5308
5664
  ] })
5309
5665
  }
5310
5666
  ),
5311
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5312
- import_react_native34.Pressable,
5667
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5668
+ import_react_native32.Pressable,
5313
5669
  {
5314
5670
  disabled: !onPressComments,
5315
5671
  onPress: onPressComments,
5316
5672
  hitSlop: 8,
5317
5673
  style: { paddingVertical: 8 },
5318
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5319
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react_native6.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
5320
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native34.View, { style: { width: 4 } }),
5321
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
5674
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5675
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
5676
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native32.View, { style: { width: 4 } }),
5677
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
5322
5678
  ] })
5323
5679
  }
5324
5680
  ),
5325
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
5326
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native34.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
5327
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native34.View, { style: { width: 4 } }),
5328
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
5681
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
5682
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native32.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
5683
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native32.View, { style: { width: 4 } }),
5684
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
5329
5685
  ] })
5330
5686
  ] })
5331
5687
  }
5332
5688
  )
5333
5689
  }
5334
5690
  );
5335
- }
5336
-
5337
- // src/studio/ui/preview-panel/PreviewHeroSection.tsx
5338
- var import_jsx_runtime34 = require("react/jsx-runtime");
5339
- function PreviewHeroSection({
5340
- appStatus,
5341
- showProcessing,
5342
- imageUrl,
5343
- imageLoaded,
5344
- onImageLoad,
5345
- stats
5346
- }) {
5347
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5348
- PreviewHeroCard,
5349
- {
5350
- overlayTopLeft: showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PreviewStatusBadge, { status: appStatus }) : null,
5351
- background: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PreviewPlaceholder, { visible: !imageLoaded }),
5352
- image: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
5353
- overlayBottom: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5354
- StatsBar,
5691
+ }
5692
+
5693
+ // src/components/preview/PreviewStatusBadge.tsx
5694
+ var import_react_native33 = require("react-native");
5695
+ var import_lucide_react_native6 = require("lucide-react-native");
5696
+
5697
+ // src/data/apps/types.ts
5698
+ var APP_STATUS_LABEL = {
5699
+ ready: "Ready",
5700
+ creating: "Creating",
5701
+ editing: "Editing",
5702
+ forking: "Forking",
5703
+ merging: "Merging",
5704
+ error: "Error",
5705
+ archived: "Archived"
5706
+ };
5707
+
5708
+ // src/components/preview/PreviewStatusBadge.tsx
5709
+ var import_jsx_runtime32 = require("react/jsx-runtime");
5710
+ var STATUS_BG = {
5711
+ ready: "#10B981",
5712
+ // emerald-500
5713
+ creating: "#3B82F6",
5714
+ // blue-500
5715
+ editing: "#F59E0B",
5716
+ // amber-500
5717
+ forking: "#00CBC0",
5718
+ // brand teal
5719
+ merging: "#06B6D4",
5720
+ // cyan-500
5721
+ error: "#F43F5E",
5722
+ // rose-500
5723
+ archived: "#71717A"
5724
+ // zinc-500
5725
+ };
5726
+ var STATUS_ICON = {
5727
+ ready: import_lucide_react_native6.CheckCircle2,
5728
+ creating: import_lucide_react_native6.Sparkles,
5729
+ editing: import_lucide_react_native6.Pencil,
5730
+ forking: import_lucide_react_native6.GitFork,
5731
+ merging: import_lucide_react_native6.GitMerge,
5732
+ error: import_lucide_react_native6.AlertTriangle,
5733
+ archived: import_lucide_react_native6.Archive
5734
+ };
5735
+ function PreviewStatusBadge({ status }) {
5736
+ const IconComp = STATUS_ICON[status];
5737
+ const label = APP_STATUS_LABEL[status] ?? status;
5738
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5739
+ import_react_native33.View,
5740
+ {
5741
+ style: {
5742
+ flexDirection: "row",
5743
+ alignItems: "center",
5744
+ borderRadius: 999,
5745
+ paddingHorizontal: 10,
5746
+ paddingVertical: 4,
5747
+ backgroundColor: STATUS_BG[status]
5748
+ },
5749
+ children: [
5750
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
5751
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
5752
+ ]
5753
+ }
5754
+ );
5755
+ }
5756
+
5757
+ // src/studio/ui/preview-panel/PreviewHeroSection.tsx
5758
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5759
+ function PreviewHeroSection({
5760
+ appStatus,
5761
+ showProcessing,
5762
+ imageUrl,
5763
+ imageLoaded,
5764
+ onImageLoad,
5765
+ stats
5766
+ }) {
5767
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5768
+ PreviewHeroCard,
5769
+ {
5770
+ overlayTopLeft: showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewStatusBadge, { status: appStatus }) : null,
5771
+ background: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewPlaceholder, { visible: !imageLoaded }),
5772
+ image: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
5773
+ overlayBottom: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5774
+ StatsBar,
5775
+ {
5776
+ likeCount: stats.likeCount,
5777
+ commentCount: stats.commentCount,
5778
+ forkCount: stats.forkCount,
5779
+ isLiked: stats.isLiked,
5780
+ onPressLike: () => void stats.handleLike(),
5781
+ onPressComments: stats.handleOpenComments,
5782
+ centered: true,
5783
+ fixedWidth: 160
5784
+ }
5785
+ ),
5786
+ style: { marginBottom: 16 }
5787
+ }
5788
+ );
5789
+ }
5790
+
5791
+ // src/studio/ui/preview-panel/PreviewRelatedAppsSection.tsx
5792
+ var React27 = __toESM(require("react"));
5793
+ var import_react_native35 = require("react-native");
5794
+
5795
+ // src/components/primitives/Modal.tsx
5796
+ var import_react_native34 = require("react-native");
5797
+ var import_jsx_runtime34 = require("react/jsx-runtime");
5798
+ function Modal({
5799
+ visible,
5800
+ onRequestClose,
5801
+ dismissOnBackdropPress = true,
5802
+ children,
5803
+ contentStyle
5804
+ }) {
5805
+ const theme = useTheme();
5806
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5807
+ import_react_native34.Modal,
5808
+ {
5809
+ visible,
5810
+ transparent: true,
5811
+ animationType: "fade",
5812
+ onRequestClose,
5813
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
5814
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5815
+ import_react_native34.Pressable,
5816
+ {
5817
+ accessibilityRole: "button",
5818
+ onPress: dismissOnBackdropPress ? onRequestClose : void 0,
5819
+ style: { position: "absolute", inset: 0 }
5820
+ }
5821
+ ),
5822
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
5823
+ ] })
5824
+ }
5825
+ );
5826
+ }
5827
+
5828
+ // src/studio/ui/preview-panel/SectionTitle.tsx
5829
+ var import_jsx_runtime35 = require("react/jsx-runtime");
5830
+ function SectionTitle({ children, marginTop }) {
5831
+ const theme = useTheme();
5832
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
5833
+ Text,
5834
+ {
5835
+ style: {
5836
+ color: theme.colors.textMuted,
5837
+ fontSize: 12,
5838
+ lineHeight: 16,
5839
+ textTransform: "uppercase",
5840
+ letterSpacing: 0.8,
5841
+ marginTop: marginTop ?? theme.spacing.sm,
5842
+ marginBottom: theme.spacing.sm,
5843
+ fontWeight: theme.typography.fontWeight.bold
5844
+ },
5845
+ children
5846
+ }
5847
+ );
5848
+ }
5849
+
5850
+ // src/studio/ui/preview-panel/PreviewRelatedAppsSection.tsx
5851
+ var import_jsx_runtime36 = require("react/jsx-runtime");
5852
+ var INLINE_VISIBLE_COUNT = 4;
5853
+ function formatRelativeUpdatedAt(updatedAt) {
5854
+ const parsed = new Date(updatedAt);
5855
+ const ms = parsed.getTime();
5856
+ if (!Number.isFinite(ms)) return "Updated recently";
5857
+ const diffMs = Date.now() - ms;
5858
+ if (diffMs < 6e4) return "Updated just now";
5859
+ const minutes = Math.floor(diffMs / 6e4);
5860
+ if (minutes < 60) return `Updated ${minutes}m ago`;
5861
+ const hours = Math.floor(minutes / 60);
5862
+ if (hours < 24) return `Updated ${hours}h ago`;
5863
+ const days = Math.floor(hours / 24);
5864
+ if (days === 1) return "Updated yesterday";
5865
+ if (days < 7) return `Updated ${days}d ago`;
5866
+ return `Updated ${parsed.toLocaleDateString(void 0, { month: "short", day: "numeric" })}`;
5867
+ }
5868
+ function PreviewRelatedAppsSection({
5869
+ relatedApps,
5870
+ relatedAppsLoading,
5871
+ switchingRelatedAppId,
5872
+ onOpenRelatedApps,
5873
+ onSwitchRelatedApp
5874
+ }) {
5875
+ var _a;
5876
+ const theme = useTheme();
5877
+ const [relatedAppsOpen, setRelatedAppsOpen] = React27.useState(false);
5878
+ const relatedAppItems = React27.useMemo(() => {
5879
+ if (!relatedApps) return [];
5880
+ const items = [];
5881
+ if (relatedApps.original) {
5882
+ items.push({ app: relatedApps.original, section: "original" });
5883
+ }
5884
+ for (const remix of relatedApps.remixes) {
5885
+ items.push({ app: remix, section: "remix" });
5886
+ }
5887
+ return items;
5888
+ }, [relatedApps]);
5889
+ const dedupedRelatedApps = React27.useMemo(() => {
5890
+ const seen = /* @__PURE__ */ new Set();
5891
+ const items = [];
5892
+ for (const item of relatedAppItems) {
5893
+ if (seen.has(item.app.id)) continue;
5894
+ seen.add(item.app.id);
5895
+ items.push(item);
5896
+ }
5897
+ return items;
5898
+ }, [relatedAppItems]);
5899
+ const uniqueRelatedCount = dedupedRelatedApps.length;
5900
+ const shouldShowRelatedApps = uniqueRelatedCount >= 2;
5901
+ const currentAppId = relatedApps == null ? void 0 : relatedApps.current.id;
5902
+ const originalAppId = ((_a = relatedApps == null ? void 0 : relatedApps.original) == null ? void 0 : _a.id) ?? null;
5903
+ const sectionedRelatedApps = React27.useMemo(() => {
5904
+ const original = [];
5905
+ const remixes = [];
5906
+ for (const item of dedupedRelatedApps) {
5907
+ if (item.section === "original") {
5908
+ original.push(item);
5909
+ } else {
5910
+ remixes.push(item);
5911
+ }
5912
+ }
5913
+ return { original, remixes };
5914
+ }, [dedupedRelatedApps]);
5915
+ const inlineItems = React27.useMemo(() => dedupedRelatedApps.slice(0, INLINE_VISIBLE_COUNT), [dedupedRelatedApps]);
5916
+ const overflowCount = Math.max(0, uniqueRelatedCount - inlineItems.length);
5917
+ const canOpenModal = overflowCount > 0;
5918
+ const closeRelatedApps = React27.useCallback(() => {
5919
+ setRelatedAppsOpen(false);
5920
+ }, []);
5921
+ const openRelatedApps = React27.useCallback(() => {
5922
+ if (!canOpenModal) return;
5923
+ setRelatedAppsOpen(true);
5924
+ onOpenRelatedApps == null ? void 0 : onOpenRelatedApps();
5925
+ }, [canOpenModal, onOpenRelatedApps]);
5926
+ const handleSelectRelatedApp = React27.useCallback(
5927
+ (targetAppId) => {
5928
+ if (!relatedApps) return;
5929
+ if (targetAppId === relatedApps.current.id) return;
5930
+ onSwitchRelatedApp == null ? void 0 : onSwitchRelatedApp(targetAppId);
5931
+ setRelatedAppsOpen(false);
5932
+ },
5933
+ [onSwitchRelatedApp, relatedApps]
5934
+ );
5935
+ const renderBadges = React27.useCallback(
5936
+ (item, isCurrent) => {
5937
+ const badges = [];
5938
+ if (item.app.id === originalAppId) {
5939
+ badges.push(
5940
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5941
+ import_react_native35.View,
5942
+ {
5943
+ style: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2, backgroundColor: withAlpha(theme.colors.neutral, 0.4) },
5944
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 11 }, children: "Original" })
5945
+ },
5946
+ "original"
5947
+ )
5948
+ );
5949
+ }
5950
+ if (isCurrent) {
5951
+ badges.push(
5952
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5953
+ import_react_native35.View,
5954
+ {
5955
+ style: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2, backgroundColor: theme.colors.primary },
5956
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.onPrimary, fontSize: 11 }, children: "Current" })
5957
+ },
5958
+ "current"
5959
+ )
5960
+ );
5961
+ }
5962
+ return badges;
5963
+ },
5964
+ [originalAppId, theme.colors.neutral, theme.colors.onPrimary, theme.colors.primary, theme.colors.textMuted]
5965
+ );
5966
+ const renderRelatedCard = React27.useCallback(
5967
+ (item, options) => {
5968
+ const isCurrent = item.app.id === currentAppId;
5969
+ const isReady = item.app.status === "ready";
5970
+ const isSwitching = switchingRelatedAppId === item.app.id;
5971
+ const disabled = isCurrent || !isReady || Boolean(switchingRelatedAppId);
5972
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5973
+ import_react_native35.Pressable,
5355
5974
  {
5356
- likeCount: stats.likeCount,
5357
- commentCount: stats.commentCount,
5358
- forkCount: stats.forkCount,
5359
- isLiked: stats.isLiked,
5360
- onPressLike: () => void stats.handleLike(),
5361
- onPressComments: stats.handleOpenComments,
5362
- centered: true,
5363
- fixedWidth: 160
5364
- }
5365
- ),
5366
- style: { marginBottom: 16 }
5367
- }
5975
+ accessibilityRole: "button",
5976
+ accessibilityLabel: `Switch to ${item.app.name}, ${formatRelativeUpdatedAt(item.app.updatedAt).toLowerCase()}`,
5977
+ disabled,
5978
+ onPress: () => handleSelectRelatedApp(item.app.id),
5979
+ style: {
5980
+ borderRadius: theme.radii.md,
5981
+ borderWidth: 1,
5982
+ borderColor: withAlpha(theme.colors.border, isCurrent ? 1 : 0.8),
5983
+ backgroundColor: isCurrent ? withAlpha(theme.colors.primary, 0.09) : withAlpha(theme.colors.surfaceRaised, 0.5),
5984
+ paddingHorizontal: theme.spacing.sm,
5985
+ paddingVertical: 8,
5986
+ opacity: disabled ? 0.7 : 1,
5987
+ width: (options == null ? void 0 : options.fullWidth) ? void 0 : 188,
5988
+ minWidth: (options == null ? void 0 : options.fullWidth) ? void 0 : 188,
5989
+ marginBottom: (options == null ? void 0 : options.fullWidth) ? theme.spacing.sm : 0
5990
+ },
5991
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flexDirection: "row", alignItems: "flex-start", justifyContent: "space-between", gap: 8 }, children: [
5992
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flex: 1, minWidth: 0 }, children: [
5993
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { numberOfLines: 1, style: { color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: item.app.name }),
5994
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { marginTop: 2, color: theme.colors.textMuted, fontSize: 12 }, children: formatRelativeUpdatedAt(item.app.updatedAt) }),
5995
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5996
+ import_react_native35.View,
5997
+ {
5998
+ style: {
5999
+ marginTop: 4,
6000
+ minHeight: 20,
6001
+ flexDirection: "row",
6002
+ alignItems: "center",
6003
+ flexWrap: "wrap",
6004
+ gap: 6
6005
+ },
6006
+ children: renderBadges(item, isCurrent)
6007
+ }
6008
+ )
6009
+ ] }),
6010
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { alignItems: "flex-end", gap: 6 }, children: [
6011
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.View, { style: { minHeight: 20, justifyContent: "center" }, children: !isReady ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PreviewStatusBadge, { status: item.app.status }) : null }),
6012
+ isSwitching ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.ActivityIndicator, { size: "small", color: theme.colors.primary }) : null
6013
+ ] })
6014
+ ] })
6015
+ },
6016
+ item.app.id
6017
+ );
6018
+ },
6019
+ [currentAppId, handleSelectRelatedApp, renderBadges, switchingRelatedAppId, theme]
5368
6020
  );
6021
+ if (!relatedAppsLoading && !shouldShowRelatedApps) return null;
6022
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6023
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SectionTitle, { children: "Related Apps" }),
6024
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6025
+ import_react_native35.View,
6026
+ {
6027
+ style: {
6028
+ flexDirection: "row",
6029
+ alignItems: "center",
6030
+ justifyContent: "flex-end",
6031
+ marginBottom: theme.spacing.xs,
6032
+ paddingHorizontal: theme.spacing.md
6033
+ },
6034
+ children: canOpenModal ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.Pressable, { accessibilityRole: "button", accessibilityLabel: "Open all related apps", onPress: openRelatedApps, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Text, { style: { color: theme.colors.primary, fontSize: 12, fontWeight: theme.typography.fontWeight.semibold }, children: [
6035
+ "See all (",
6036
+ uniqueRelatedCount,
6037
+ ")"
6038
+ ] }) }) : null
6039
+ }
6040
+ ),
6041
+ relatedAppsLoading ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.View, { style: { height: 72, alignItems: "center", justifyContent: "center", marginBottom: theme.spacing.xs }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.ActivityIndicator, { color: theme.colors.primary }) }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6042
+ import_react_native35.ScrollView,
6043
+ {
6044
+ horizontal: true,
6045
+ showsHorizontalScrollIndicator: false,
6046
+ style: { flexGrow: 0 },
6047
+ contentContainerStyle: {
6048
+ paddingHorizontal: theme.spacing.md,
6049
+ gap: theme.spacing.sm,
6050
+ paddingBottom: theme.spacing.xs,
6051
+ alignItems: "flex-start"
6052
+ },
6053
+ children: inlineItems.map((item) => renderRelatedCard(item))
6054
+ }
6055
+ ),
6056
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Modal, { visible: relatedAppsOpen, onRequestClose: closeRelatedApps, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { gap: theme.spacing.sm }, children: [
6057
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 18, fontWeight: theme.typography.fontWeight.semibold }, children: "Related apps" }),
6058
+ sectionedRelatedApps.original.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { children: [
6059
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, marginBottom: theme.spacing.xs }, children: "Original" }),
6060
+ sectionedRelatedApps.original.map((item) => renderRelatedCard(item, { fullWidth: true }))
6061
+ ] }) : null,
6062
+ sectionedRelatedApps.remixes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { children: [
6063
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, marginBottom: theme.spacing.xs }, children: "Remixes" }),
6064
+ sectionedRelatedApps.remixes.map((item) => renderRelatedCard(item, { fullWidth: true }))
6065
+ ] }) : null
6066
+ ] }) })
6067
+ ] });
5369
6068
  }
5370
6069
 
5371
6070
  // src/studio/ui/preview-panel/PreviewMetaSection.tsx
5372
- var import_react_native36 = require("react-native");
6071
+ var import_react_native37 = require("react-native");
5373
6072
 
5374
6073
  // src/components/preview/PreviewMetaRow.tsx
5375
- var import_react_native35 = require("react-native");
5376
- var import_jsx_runtime35 = require("react/jsx-runtime");
6074
+ var import_react_native36 = require("react-native");
6075
+ var import_jsx_runtime37 = require("react/jsx-runtime");
5377
6076
  function PreviewMetaRow({
5378
6077
  avatarUri,
5379
6078
  creatorName,
@@ -5384,11 +6083,11 @@ function PreviewMetaRow({
5384
6083
  style
5385
6084
  }) {
5386
6085
  const theme = useTheme();
5387
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_native35.View, { style: [{ alignSelf: "stretch" }, style], children: [
5388
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_native35.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5389
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
5390
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_native35.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
5391
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6086
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native36.View, { style: [{ alignSelf: "stretch" }, style], children: [
6087
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6088
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
6089
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
6090
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
5392
6091
  Text,
5393
6092
  {
5394
6093
  numberOfLines: 1,
@@ -5402,11 +6101,11 @@ function PreviewMetaRow({
5402
6101
  children: title
5403
6102
  }
5404
6103
  ),
5405
- tag ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native35.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
6104
+ tag ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native36.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
5406
6105
  ] }),
5407
- rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native35.View, { children: rightMetric }) : null
6106
+ rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native36.View, { children: rightMetric }) : null
5408
6107
  ] }),
5409
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6108
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
5410
6109
  Text,
5411
6110
  {
5412
6111
  numberOfLines: 2,
@@ -5449,20 +6148,20 @@ function statusDescription(status, statusError) {
5449
6148
  }
5450
6149
 
5451
6150
  // src/studio/ui/preview-panel/PreviewMetaSection.tsx
5452
- var import_jsx_runtime36 = require("react/jsx-runtime");
6151
+ var import_jsx_runtime38 = require("react/jsx-runtime");
5453
6152
  function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
5454
6153
  var _a;
5455
6154
  const theme = useTheme();
5456
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6155
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
5457
6156
  PreviewMetaRow,
5458
6157
  {
5459
6158
  title: app.name,
5460
6159
  subtitle: app.description,
5461
6160
  avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
5462
6161
  creatorName: (creator == null ? void 0 : creator.name) ?? null,
5463
- tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#007A75" }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
5464
- rightMetric: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
5465
- import_react_native36.View,
6162
+ tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#007A75" }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
6163
+ rightMetric: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
6164
+ import_react_native37.View,
5466
6165
  {
5467
6166
  style: {
5468
6167
  flexDirection: "row",
@@ -5473,7 +6172,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
5473
6172
  backgroundColor: withAlpha(theme.colors.neutral, 0.3)
5474
6173
  },
5475
6174
  children: [
5476
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6175
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
5477
6176
  Text,
5478
6177
  {
5479
6178
  style: {
@@ -5486,7 +6185,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
5486
6185
  children: formatCount(downloadsCount ?? ((_a = app.insights) == null ? void 0 : _a.totalDownloads) ?? 0)
5487
6186
  }
5488
6187
  ),
5489
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
6188
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
5490
6189
  ]
5491
6190
  }
5492
6191
  ),
@@ -5496,11 +6195,11 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
5496
6195
  }
5497
6196
 
5498
6197
  // src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
5499
- var import_react_native38 = require("react-native");
6198
+ var import_react_native39 = require("react-native");
5500
6199
 
5501
6200
  // src/studio/ui/preview-panel/PressableCardRow.tsx
5502
- var import_react_native37 = require("react-native");
5503
- var import_jsx_runtime37 = require("react/jsx-runtime");
6201
+ var import_react_native38 = require("react-native");
6202
+ var import_jsx_runtime39 = require("react/jsx-runtime");
5504
6203
  function PressableCardRow({
5505
6204
  accessibilityLabel,
5506
6205
  onPress,
@@ -5511,50 +6210,28 @@ function PressableCardRow({
5511
6210
  right,
5512
6211
  style
5513
6212
  }) {
5514
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
5515
- import_react_native37.Pressable,
6213
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6214
+ import_react_native38.Pressable,
5516
6215
  {
5517
6216
  accessibilityRole: "button",
5518
6217
  accessibilityLabel,
5519
6218
  disabled,
5520
6219
  onPress,
5521
6220
  style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
5522
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native37.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6221
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5523
6222
  left,
5524
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native37.View, { style: { flex: 1, minWidth: 0 }, children: [
6223
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
5525
6224
  title,
5526
6225
  subtitle ? subtitle : null
5527
6226
  ] }),
5528
- right ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native37.View, { style: { marginLeft: 16 }, children: right }) : null
6227
+ right ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native38.View, { style: { marginLeft: 16 }, children: right }) : null
5529
6228
  ] }) })
5530
6229
  }
5531
6230
  );
5532
6231
  }
5533
6232
 
5534
- // src/studio/ui/preview-panel/SectionTitle.tsx
5535
- var import_jsx_runtime38 = require("react/jsx-runtime");
5536
- function SectionTitle({ children, marginTop }) {
5537
- const theme = useTheme();
5538
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
5539
- Text,
5540
- {
5541
- style: {
5542
- color: theme.colors.textMuted,
5543
- fontSize: 12,
5544
- lineHeight: 16,
5545
- textTransform: "uppercase",
5546
- letterSpacing: 0.8,
5547
- marginTop: marginTop ?? theme.spacing.sm,
5548
- marginBottom: theme.spacing.sm,
5549
- fontWeight: theme.typography.fontWeight.bold
5550
- },
5551
- children
5552
- }
5553
- );
5554
- }
5555
-
5556
6233
  // src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
5557
- var import_jsx_runtime39 = require("react/jsx-runtime");
6234
+ var import_jsx_runtime40 = require("react/jsx-runtime");
5558
6235
  function PreviewCustomizeSection({
5559
6236
  app,
5560
6237
  isOwner,
@@ -5564,10 +6241,10 @@ function PreviewCustomizeSection({
5564
6241
  onStartDraw
5565
6242
  }) {
5566
6243
  const theme = useTheme();
5567
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
5568
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SectionTitle, { children: "Customize" }),
5569
- showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
5570
- import_react_native38.View,
6244
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
6245
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SectionTitle, { children: "Customize" }),
6246
+ showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
6247
+ import_react_native39.View,
5571
6248
  {
5572
6249
  style: {
5573
6250
  flexDirection: "row",
@@ -5580,8 +6257,8 @@ function PreviewCustomizeSection({
5580
6257
  marginBottom: theme.spacing.sm
5581
6258
  },
5582
6259
  children: [
5583
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
5584
- import_react_native38.View,
6260
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6261
+ import_react_native39.View,
5585
6262
  {
5586
6263
  style: {
5587
6264
  width: 40,
@@ -5592,17 +6269,17 @@ function PreviewCustomizeSection({
5592
6269
  backgroundColor: withAlpha(theme.colors.warning, 0.1),
5593
6270
  marginRight: theme.spacing.lg
5594
6271
  },
5595
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native38.ActivityIndicator, { color: theme.colors.warning, size: "small" })
6272
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.ActivityIndicator, { color: theme.colors.warning, size: "small" })
5596
6273
  }
5597
6274
  ),
5598
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
5599
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
5600
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
6275
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flex: 1, minWidth: 0 }, children: [
6276
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
6277
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
5601
6278
  ] })
5602
6279
  ]
5603
6280
  }
5604
6281
  ) : null,
5605
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6282
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
5606
6283
  PressableCardRow,
5607
6284
  {
5608
6285
  accessibilityLabel: isOwner ? "Edit app" : "Remix app",
@@ -5615,8 +6292,8 @@ function PreviewCustomizeSection({
5615
6292
  borderColor: withAlpha(theme.colors.primary, 0.1),
5616
6293
  marginBottom: theme.spacing.sm
5617
6294
  },
5618
- left: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
5619
- import_react_native38.View,
6295
+ left: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6296
+ import_react_native39.View,
5620
6297
  {
5621
6298
  style: {
5622
6299
  width: 40,
@@ -5627,15 +6304,15 @@ function PreviewCustomizeSection({
5627
6304
  backgroundColor: withAlpha(theme.colors.primary, 0.1),
5628
6305
  marginRight: theme.spacing.lg
5629
6306
  },
5630
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconChat, { size: 20, colorToken: "primary" })
6307
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(IconChat, { size: 20, colorToken: "primary" })
5631
6308
  }
5632
6309
  ),
5633
- title: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: isOwner ? app.forkedFromAppId ? "Edit your Remix" : "Edit Your App" : "Remix App" }),
5634
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isOwner && app.forkedFromAppId ? "Make changes to your remix with chat" : shouldForkOnEdit ? "Chat to create your own copy and edit it" : "Chat to apply changes" }),
5635
- right: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
6310
+ title: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: isOwner ? app.forkedFromAppId ? "Edit your Remix" : "Edit Your App" : "Remix App" }),
6311
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isOwner && app.forkedFromAppId ? "Make changes to your remix with chat" : shouldForkOnEdit ? "Chat to create your own copy and edit it" : "Chat to apply changes" }),
6312
+ right: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
5636
6313
  }
5637
6314
  ),
5638
- isOwner && onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6315
+ isOwner && onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
5639
6316
  PressableCardRow,
5640
6317
  {
5641
6318
  accessibilityLabel: "Draw changes",
@@ -5648,8 +6325,8 @@ function PreviewCustomizeSection({
5648
6325
  borderColor: withAlpha(theme.colors.danger, 0.1),
5649
6326
  marginBottom: theme.spacing.sm
5650
6327
  },
5651
- left: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
5652
- import_react_native38.View,
6328
+ left: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6329
+ import_react_native39.View,
5653
6330
  {
5654
6331
  style: {
5655
6332
  width: 40,
@@ -5660,12 +6337,12 @@ function PreviewCustomizeSection({
5660
6337
  backgroundColor: withAlpha(theme.colors.danger, 0.1),
5661
6338
  marginRight: theme.spacing.lg
5662
6339
  },
5663
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconDraw, { size: 20, colorToken: "danger" })
6340
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(IconDraw, { size: 20, colorToken: "danger" })
5664
6341
  }
5665
6342
  ),
5666
- title: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
5667
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
5668
- right: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
6343
+ title: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
6344
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
6345
+ right: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
5669
6346
  }
5670
6347
  ) : null
5671
6348
  ] });
@@ -5673,19 +6350,19 @@ function PreviewCustomizeSection({
5673
6350
 
5674
6351
  // src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
5675
6352
  var React33 = __toESM(require("react"));
5676
- var import_react_native44 = require("react-native");
6353
+ var import_react_native45 = require("react-native");
5677
6354
  var import_lucide_react_native9 = require("lucide-react-native");
5678
6355
 
5679
6356
  // src/components/merge-requests/MergeRequestStatusCard.tsx
5680
6357
  var React29 = __toESM(require("react"));
5681
- var import_react_native40 = require("react-native");
6358
+ var import_react_native41 = require("react-native");
5682
6359
  var import_lucide_react_native7 = require("lucide-react-native");
5683
6360
 
5684
6361
  // src/components/primitives/MarkdownText.tsx
5685
- var import_react_native39 = require("react-native");
6362
+ var import_react_native40 = require("react-native");
5686
6363
  var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
5687
6364
  var import_react2 = require("react");
5688
- var import_jsx_runtime40 = require("react/jsx-runtime");
6365
+ var import_jsx_runtime41 = require("react/jsx-runtime");
5689
6366
  function copyMarkdownToClipboard(markdown) {
5690
6367
  var _a;
5691
6368
  if (!markdown) {
@@ -5726,7 +6403,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
5726
6403
  const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
5727
6404
  const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
5728
6405
  const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
5729
- const screen = import_react_native39.Dimensions.get("window");
6406
+ const screen = import_react_native40.Dimensions.get("window");
5730
6407
  const tooltipPadding = theme.spacing.sm;
5731
6408
  const tooltipYOffset = theme.spacing.lg + 32;
5732
6409
  const minTooltipY = theme.spacing.xl;
@@ -5756,8 +6433,8 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
5756
6433
  setShowCopied(false);
5757
6434
  }, 1200);
5758
6435
  };
5759
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.Pressable, { style, onPress: import_react_native39.Keyboard.dismiss, onLongPress: handleLongPress, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { position: "relative" }, children: [
5760
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6436
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.Pressable, { style, onPress: import_react_native40.Keyboard.dismiss, onLongPress: handleLongPress, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: { position: "relative" }, children: [
6437
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5761
6438
  import_react_native_markdown_display.default,
5762
6439
  {
5763
6440
  style: {
@@ -5770,7 +6447,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
5770
6447
  paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
5771
6448
  paddingVertical: variant === "mergeRequest" ? 2 : 0,
5772
6449
  borderRadius: variant === "mergeRequest" ? 6 : 4,
5773
- fontFamily: import_react_native39.Platform.OS === "ios" ? "Menlo" : "monospace",
6450
+ fontFamily: import_react_native40.Platform.OS === "ios" ? "Menlo" : "monospace",
5774
6451
  fontSize: 13
5775
6452
  },
5776
6453
  code_block: {
@@ -5791,8 +6468,8 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
5791
6468
  children: markdown
5792
6469
  }
5793
6470
  ),
5794
- showCopied && tooltipAnchor ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.Modal, { transparent: true, visible: true, statusBarTranslucent: true, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.View, { pointerEvents: "none", style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
5795
- import_react_native39.View,
6471
+ showCopied && tooltipAnchor ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.Modal, { transparent: true, visible: true, statusBarTranslucent: true, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { pointerEvents: "none", style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
6472
+ import_react_native40.View,
5796
6473
  {
5797
6474
  pointerEvents: "none",
5798
6475
  style: {
@@ -5805,8 +6482,8 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
5805
6482
  paddingVertical: theme.spacing.xs
5806
6483
  },
5807
6484
  onLayout: (event) => setTooltipWidth(event.nativeEvent.layout.width),
5808
- children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
5809
- import_react_native39.Text,
6485
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
6486
+ import_react_native40.Text,
5810
6487
  {
5811
6488
  style: {
5812
6489
  color: theme.colors.onSuccess,
@@ -5865,7 +6542,7 @@ function useControlledExpansion(props) {
5865
6542
  }
5866
6543
 
5867
6544
  // src/components/merge-requests/MergeRequestStatusCard.tsx
5868
- var import_jsx_runtime41 = require("react/jsx-runtime");
6545
+ var import_jsx_runtime42 = require("react/jsx-runtime");
5869
6546
  function MergeRequestStatusCard({
5870
6547
  mergeRequest,
5871
6548
  expanded: expandedProp,
@@ -5910,15 +6587,15 @@ function MergeRequestStatusCard({
5910
6587
  const createdIso = toIsoString(mergeRequest.createdAt ?? null);
5911
6588
  const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
5912
6589
  const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
5913
- const rotate = React29.useRef(new import_react_native40.Animated.Value(expanded ? 1 : 0)).current;
6590
+ const rotate = React29.useRef(new import_react_native41.Animated.Value(expanded ? 1 : 0)).current;
5914
6591
  React29.useEffect(() => {
5915
- import_react_native40.Animated.timing(rotate, {
6592
+ import_react_native41.Animated.timing(rotate, {
5916
6593
  toValue: expanded ? 1 : 0,
5917
6594
  duration: 200,
5918
6595
  useNativeDriver: true
5919
6596
  }).start();
5920
6597
  }, [expanded, rotate]);
5921
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
6598
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
5922
6599
  Card,
5923
6600
  {
5924
6601
  padded: false,
@@ -5931,11 +6608,11 @@ function MergeRequestStatusCard({
5931
6608
  style
5932
6609
  ],
5933
6610
  children: [
5934
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
5935
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
5936
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: { flex: 1, minWidth: 0 }, children: [
5937
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
5938
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
6611
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native41.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
6612
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
6613
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native41.View, { style: { flex: 1, minWidth: 0 }, children: [
6614
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native41.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
6615
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5939
6616
  Text,
5940
6617
  {
5941
6618
  style: {
@@ -5949,12 +6626,12 @@ function MergeRequestStatusCard({
5949
6626
  children: statusText
5950
6627
  }
5951
6628
  ),
5952
- headerTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
6629
+ headerTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
5953
6630
  ] }),
5954
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
6631
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
5955
6632
  ] }),
5956
- headerRight ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5957
- import_react_native40.Animated.View,
6633
+ headerRight ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6634
+ import_react_native41.Animated.View,
5958
6635
  {
5959
6636
  style: {
5960
6637
  transform: [
@@ -5963,12 +6640,12 @@ function MergeRequestStatusCard({
5963
6640
  }
5964
6641
  ]
5965
6642
  },
5966
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react_native7.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
6643
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native7.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
5967
6644
  }
5968
6645
  )
5969
6646
  ] }),
5970
- expanded ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
5971
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
6647
+ expanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native41.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
6648
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5972
6649
  Text,
5973
6650
  {
5974
6651
  style: {
@@ -5982,7 +6659,7 @@ function MergeRequestStatusCard({
5982
6659
  children: status.text
5983
6660
  }
5984
6661
  ),
5985
- createdTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
6662
+ createdTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5986
6663
  Text,
5987
6664
  {
5988
6665
  style: {
@@ -5993,8 +6670,8 @@ function MergeRequestStatusCard({
5993
6670
  children: createdTimeAgo
5994
6671
  }
5995
6672
  ) : null,
5996
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
5997
- mergeRequest.description ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
6673
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
6674
+ mergeRequest.description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
5998
6675
  ] }) : null
5999
6676
  ]
6000
6677
  }
@@ -6003,17 +6680,17 @@ function MergeRequestStatusCard({
6003
6680
 
6004
6681
  // src/components/merge-requests/ReviewMergeRequestCarousel.tsx
6005
6682
  var React32 = __toESM(require("react"));
6006
- var import_react_native43 = require("react-native");
6683
+ var import_react_native44 = require("react-native");
6007
6684
 
6008
6685
  // src/components/merge-requests/ReviewMergeRequestCard.tsx
6009
6686
  var React31 = __toESM(require("react"));
6010
- var import_react_native42 = require("react-native");
6687
+ var import_react_native43 = require("react-native");
6011
6688
  var import_lucide_react_native8 = require("lucide-react-native");
6012
6689
 
6013
6690
  // src/components/merge-requests/ReviewMergeRequestActionButton.tsx
6014
6691
  var React30 = __toESM(require("react"));
6015
- var import_react_native41 = require("react-native");
6016
- var import_jsx_runtime42 = require("react/jsx-runtime");
6692
+ var import_react_native42 = require("react-native");
6693
+ var import_jsx_runtime43 = require("react/jsx-runtime");
6017
6694
  function ReviewMergeRequestActionButton({
6018
6695
  accessibilityLabel,
6019
6696
  backgroundColor,
@@ -6028,8 +6705,8 @@ function ReviewMergeRequestActionButton({
6028
6705
  const paddingHorizontal = iconOnly ? 0 : 16;
6029
6706
  const paddingVertical = iconOnly ? 0 : 8;
6030
6707
  const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
6031
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6032
- import_react_native41.View,
6708
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6709
+ import_react_native42.View,
6033
6710
  {
6034
6711
  style: {
6035
6712
  width,
@@ -6043,8 +6720,8 @@ function ReviewMergeRequestActionButton({
6043
6720
  paddingVertical,
6044
6721
  justifyContent: "center"
6045
6722
  },
6046
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6047
- import_react_native41.Pressable,
6723
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6724
+ import_react_native42.Pressable,
6048
6725
  {
6049
6726
  accessibilityRole: "button",
6050
6727
  accessibilityLabel,
@@ -6067,7 +6744,7 @@ function ReviewMergeRequestActionButton({
6067
6744
  }
6068
6745
 
6069
6746
  // src/components/merge-requests/ReviewMergeRequestCard.tsx
6070
- var import_jsx_runtime43 = require("react/jsx-runtime");
6747
+ var import_jsx_runtime44 = require("react/jsx-runtime");
6071
6748
  function ReviewMergeRequestCard({
6072
6749
  mr,
6073
6750
  index,
@@ -6086,12 +6763,12 @@ function ReviewMergeRequestCard({
6086
6763
  const theme = useTheme();
6087
6764
  const status = React31.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
6088
6765
  const canAct = mr.status === "open";
6089
- const rotate = React31.useRef(new import_react_native42.Animated.Value(isExpanded ? 1 : 0)).current;
6766
+ const rotate = React31.useRef(new import_react_native43.Animated.Value(isExpanded ? 1 : 0)).current;
6090
6767
  React31.useEffect(() => {
6091
- import_react_native42.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
6768
+ import_react_native43.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
6092
6769
  }, [isExpanded, rotate]);
6093
6770
  const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
6094
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
6771
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
6095
6772
  Card,
6096
6773
  {
6097
6774
  padded: false,
@@ -6104,10 +6781,10 @@ function ReviewMergeRequestCard({
6104
6781
  }
6105
6782
  ],
6106
6783
  children: [
6107
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
6108
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
6109
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flex: 1, minWidth: 0 }, children: [
6110
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6784
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
6785
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
6786
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flex: 1, minWidth: 0 }, children: [
6787
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6111
6788
  Text,
6112
6789
  {
6113
6790
  style: { fontWeight: theme.typography.fontWeight.semibold, color: theme.colors.text, fontSize: 16, lineHeight: 20 },
@@ -6115,24 +6792,24 @@ function ReviewMergeRequestCard({
6115
6792
  children: mr.title ?? "Untitled merge request"
6116
6793
  }
6117
6794
  ),
6118
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16 }, numberOfLines: 1, children: [
6795
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16 }, numberOfLines: 1, children: [
6119
6796
  (creator == null ? void 0 : creator.name) ?? "Loading...",
6120
6797
  " \xB7 ",
6121
6798
  position
6122
6799
  ] })
6123
6800
  ] }),
6124
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6125
- import_react_native42.Animated.View,
6801
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6802
+ import_react_native43.Animated.View,
6126
6803
  {
6127
6804
  style: {
6128
6805
  transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
6129
6806
  },
6130
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react_native8.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
6807
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native8.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
6131
6808
  }
6132
6809
  )
6133
6810
  ] }),
6134
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { marginTop: 16 }, children: [
6135
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6811
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { marginTop: 16 }, children: [
6812
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6136
6813
  Text,
6137
6814
  {
6138
6815
  style: {
@@ -6146,13 +6823,13 @@ function ReviewMergeRequestCard({
6146
6823
  children: status.text
6147
6824
  }
6148
6825
  ),
6149
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOrMergedMergeRequests} approved merge${creator.approvedOrMergedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
6150
- mr.description ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
6826
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOrMergedMergeRequests} approved merge${creator.approvedOrMergedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
6827
+ mr.description ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
6151
6828
  ] }) : null,
6152
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
6153
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
6154
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", gap: 8 }, children: [
6155
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6829
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
6830
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
6831
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", gap: 8 }, children: [
6832
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6156
6833
  ReviewMergeRequestActionButton,
6157
6834
  {
6158
6835
  accessibilityLabel: "Reject",
@@ -6160,13 +6837,13 @@ function ReviewMergeRequestCard({
6160
6837
  disabled: !canAct || isAnyProcessing,
6161
6838
  onPress: onReject,
6162
6839
  iconOnly: !isExpanded,
6163
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6164
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
6165
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
6840
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6841
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
6842
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
6166
6843
  ] })
6167
6844
  }
6168
6845
  ),
6169
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6846
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6170
6847
  ReviewMergeRequestActionButton,
6171
6848
  {
6172
6849
  accessibilityLabel: !canAct ? "Not actionable" : isProcessing ? "Processing" : "Approve",
@@ -6174,17 +6851,17 @@ function ReviewMergeRequestCard({
6174
6851
  disabled: !canAct || isAnyProcessing,
6175
6852
  onPress: onApprove,
6176
6853
  iconOnly: !isExpanded,
6177
- children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6178
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
6179
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
6180
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6181
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
6182
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
6854
+ children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6855
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
6856
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
6857
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6858
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
6859
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
6183
6860
  ] })
6184
6861
  }
6185
6862
  )
6186
6863
  ] }),
6187
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
6864
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6188
6865
  ReviewMergeRequestActionButton,
6189
6866
  {
6190
6867
  accessibilityLabel: "Test",
@@ -6192,9 +6869,9 @@ function ReviewMergeRequestCard({
6192
6869
  disabled: isBuilding || isTestingThis,
6193
6870
  onPress: onTest,
6194
6871
  iconOnly: !isExpanded,
6195
- children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6196
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
6197
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
6872
+ children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
6873
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
6874
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
6198
6875
  ] })
6199
6876
  }
6200
6877
  )
@@ -6205,7 +6882,7 @@ function ReviewMergeRequestCard({
6205
6882
  }
6206
6883
 
6207
6884
  // src/components/merge-requests/ReviewMergeRequestCarousel.tsx
6208
- var import_jsx_runtime44 = require("react/jsx-runtime");
6885
+ var import_jsx_runtime45 = require("react/jsx-runtime");
6209
6886
  function ReviewMergeRequestCarousel({
6210
6887
  mergeRequests,
6211
6888
  creatorStatsById,
@@ -6218,32 +6895,32 @@ function ReviewMergeRequestCarousel({
6218
6895
  style
6219
6896
  }) {
6220
6897
  const theme = useTheme();
6221
- const { width } = (0, import_react_native43.useWindowDimensions)();
6898
+ const { width } = (0, import_react_native44.useWindowDimensions)();
6222
6899
  const [expanded, setExpanded] = React32.useState({});
6223
- const carouselScrollX = React32.useRef(new import_react_native43.Animated.Value(0)).current;
6900
+ const carouselScrollX = React32.useRef(new import_react_native44.Animated.Value(0)).current;
6224
6901
  const peekAmount = 24;
6225
6902
  const gap = 16;
6226
6903
  const cardWidth = React32.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
6227
6904
  const snapInterval = cardWidth + gap;
6228
6905
  const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
6229
6906
  if (mergeRequests.length === 0) return null;
6230
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
6231
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6232
- import_react_native43.FlatList,
6907
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react_native44.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
6908
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6909
+ import_react_native44.FlatList,
6233
6910
  {
6234
6911
  horizontal: true,
6235
6912
  data: mergeRequests,
6236
6913
  keyExtractor: (mr) => mr.id,
6237
6914
  showsHorizontalScrollIndicator: false,
6238
6915
  contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
6239
- ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { width: gap } }),
6916
+ ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: { width: gap } }),
6240
6917
  snapToAlignment: "start",
6241
6918
  decelerationRate: "fast",
6242
6919
  snapToInterval: snapInterval,
6243
6920
  disableIntervalMomentum: true,
6244
6921
  style: { paddingRight: peekAmount },
6245
- ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { width: peekAmount } }),
6246
- onScroll: import_react_native43.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
6922
+ ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: { width: peekAmount } }),
6923
+ onScroll: import_react_native44.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
6247
6924
  useNativeDriver: false
6248
6925
  }),
6249
6926
  scrollEventThrottle: 16,
@@ -6254,7 +6931,7 @@ function ReviewMergeRequestCarousel({
6254
6931
  const isProcessing = Boolean(processingMrId && processingMrId === item.id);
6255
6932
  const isAnyProcessing = Boolean(processingMrId);
6256
6933
  const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
6257
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6934
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6258
6935
  ReviewMergeRequestCard,
6259
6936
  {
6260
6937
  mr: item,
@@ -6275,7 +6952,7 @@ function ReviewMergeRequestCarousel({
6275
6952
  }
6276
6953
  }
6277
6954
  ),
6278
- mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
6955
+ mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
6279
6956
  const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
6280
6957
  const scale = carouselScrollX.interpolate({
6281
6958
  inputRange,
@@ -6287,8 +6964,8 @@ function ReviewMergeRequestCarousel({
6287
6964
  outputRange: [0.4, 1, 0.4],
6288
6965
  extrapolate: "clamp"
6289
6966
  });
6290
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
6291
- import_react_native43.Animated.View,
6967
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6968
+ import_react_native44.Animated.View,
6292
6969
  {
6293
6970
  style: {
6294
6971
  width: 8,
@@ -6306,7 +6983,7 @@ function ReviewMergeRequestCarousel({
6306
6983
  }
6307
6984
 
6308
6985
  // src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
6309
- var import_jsx_runtime45 = require("react/jsx-runtime");
6986
+ var import_jsx_runtime46 = require("react/jsx-runtime");
6310
6987
  function PreviewCollaborateSection({
6311
6988
  canSubmitMergeRequest,
6312
6989
  canSyncUpstream,
@@ -6332,9 +7009,9 @@ function PreviewCollaborateSection({
6332
7009
  if (!hasSection) return null;
6333
7010
  const isSyncing = Boolean(syncingUpstream || syncingLocal);
6334
7011
  const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || canSyncUpstream && onSyncUpstream || onTestMr && incomingMergeRequests.length > 0;
6335
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
6336
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
6337
- showActionsSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7012
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
7013
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
7014
+ showActionsSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
6338
7015
  Text,
6339
7016
  {
6340
7017
  style: {
@@ -6349,13 +7026,13 @@ function PreviewCollaborateSection({
6349
7026
  children: "Actions"
6350
7027
  }
6351
7028
  ) : null,
6352
- canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7029
+ canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
6353
7030
  PressableCardRow,
6354
7031
  {
6355
7032
  accessibilityLabel: "Submit merge request",
6356
7033
  disabled: submittingMr,
6357
7034
  onPress: () => {
6358
- import_react_native44.Alert.alert(
7035
+ import_react_native45.Alert.alert(
6359
7036
  "Submit Merge Request",
6360
7037
  "Are you sure you want to submit your changes to the original app?",
6361
7038
  [
@@ -6380,8 +7057,8 @@ function PreviewCollaborateSection({
6380
7057
  borderColor: withAlpha("#03DAC6", 0.2),
6381
7058
  marginBottom: theme.spacing.sm
6382
7059
  },
6383
- left: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6384
- import_react_native44.View,
7060
+ left: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7061
+ import_react_native45.View,
6385
7062
  {
6386
7063
  style: {
6387
7064
  width: 40,
@@ -6392,21 +7069,21 @@ function PreviewCollaborateSection({
6392
7069
  backgroundColor: withAlpha("#03DAC6", 0.1),
6393
7070
  marginRight: theme.spacing.lg
6394
7071
  },
6395
- children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
7072
+ children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
6396
7073
  }
6397
7074
  ),
6398
- title: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
6399
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
6400
- right: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react_native9.Send, { size: 16, color: "#03DAC6" })
7075
+ title: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
7076
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
7077
+ right: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native9.Send, { size: 16, color: "#03DAC6" })
6401
7078
  }
6402
7079
  ) : null,
6403
- canSyncUpstream && onSyncUpstream ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7080
+ canSyncUpstream && onSyncUpstream ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
6404
7081
  PressableCardRow,
6405
7082
  {
6406
7083
  accessibilityLabel: "Sync from original",
6407
7084
  disabled: isSyncing,
6408
7085
  onPress: () => {
6409
- import_react_native44.Alert.alert(
7086
+ import_react_native45.Alert.alert(
6410
7087
  "Sync from Original",
6411
7088
  "This will pull the latest upstream changes into your remix.",
6412
7089
  [
@@ -6418,12 +7095,12 @@ function PreviewCollaborateSection({
6418
7095
  setSyncingLocal(true);
6419
7096
  Promise.resolve(onSyncUpstream()).then((result) => {
6420
7097
  if ((result == null ? void 0 : result.status) === "up-to-date") {
6421
- import_react_native44.Alert.alert("Up to date", "Your remix already includes the latest upstream changes.");
7098
+ import_react_native45.Alert.alert("Up to date", "Your remix already includes the latest upstream changes.");
6422
7099
  } else {
6423
- import_react_native44.Alert.alert("Sync started", "Upstream changes are being merged into your remix.");
7100
+ import_react_native45.Alert.alert("Sync started", "Upstream changes are being merged into your remix.");
6424
7101
  }
6425
7102
  }).catch(() => {
6426
- import_react_native44.Alert.alert("Sync failed", "We could not start the sync. Please try again.");
7103
+ import_react_native45.Alert.alert("Sync failed", "We could not start the sync. Please try again.");
6427
7104
  }).finally(() => setSyncingLocal(false));
6428
7105
  }
6429
7106
  }
@@ -6438,8 +7115,8 @@ function PreviewCollaborateSection({
6438
7115
  borderColor: withAlpha(theme.colors.primary, 0.25),
6439
7116
  marginBottom: theme.spacing.sm
6440
7117
  },
6441
- left: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6442
- import_react_native44.View,
7118
+ left: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7119
+ import_react_native45.View,
6443
7120
  {
6444
7121
  style: {
6445
7122
  width: 40,
@@ -6450,15 +7127,15 @@ function PreviewCollaborateSection({
6450
7127
  backgroundColor: withAlpha(theme.colors.primary, 0.12),
6451
7128
  marginRight: theme.spacing.lg
6452
7129
  },
6453
- children: isSyncing ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.ActivityIndicator, { color: theme.colors.primary, size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react_native9.RefreshCw, { size: 18, color: theme.colors.primary })
7130
+ children: isSyncing ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.ActivityIndicator, { color: theme.colors.primary, size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native9.RefreshCw, { size: 18, color: theme.colors.primary })
6454
7131
  }
6455
7132
  ),
6456
- title: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Sync from Original" }),
6457
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isSyncing ? "Syncing upstream changes..." : upstreamSyncStatus === "up-to-date" ? "You are already up to date with the original app" : "Pull the latest upstream changes into this remix" }),
6458
- right: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react_native9.RefreshCw, { size: 16, color: theme.colors.primary })
7133
+ title: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Sync from Original" }),
7134
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isSyncing ? "Syncing upstream changes..." : upstreamSyncStatus === "up-to-date" ? "You are already up to date with the original app" : "Pull the latest upstream changes into this remix" }),
7135
+ right: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native9.RefreshCw, { size: 16, color: theme.colors.primary })
6459
7136
  }
6460
7137
  ) : null,
6461
- onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7138
+ onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
6462
7139
  ReviewMergeRequestCarousel,
6463
7140
  {
6464
7141
  mergeRequests: incomingMergeRequests,
@@ -6471,8 +7148,8 @@ function PreviewCollaborateSection({
6471
7148
  onTest: (mr) => onTestMr ? onTestMr(mr) : void 0
6472
7149
  }
6473
7150
  ) : null,
6474
- outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
6475
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7151
+ outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
7152
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
6476
7153
  Text,
6477
7154
  {
6478
7155
  style: {
@@ -6488,7 +7165,7 @@ function PreviewCollaborateSection({
6488
7165
  children: "History"
6489
7166
  }
6490
7167
  ),
6491
- outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
7168
+ outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
6492
7169
  ] }) : null
6493
7170
  ] });
6494
7171
  }
@@ -6796,7 +7473,7 @@ function usePreviewPanelData(params) {
6796
7473
  }
6797
7474
 
6798
7475
  // src/studio/ui/PreviewPanel.tsx
6799
- var import_jsx_runtime46 = require("react/jsx-runtime");
7476
+ var import_jsx_runtime47 = require("react/jsx-runtime");
6800
7477
  function PreviewPanel({
6801
7478
  app,
6802
7479
  loading,
@@ -6836,7 +7513,7 @@ ${shareUrl}` : `Check out this app on Remix
6836
7513
  ${shareUrl}`;
6837
7514
  try {
6838
7515
  const title = app.name ?? "Remix app";
6839
- const payload = import_react_native45.Platform.OS === "ios" ? {
7516
+ const payload = import_react_native46.Platform.OS === "ios" ? {
6840
7517
  title,
6841
7518
  message
6842
7519
  } : {
@@ -6844,7 +7521,7 @@ ${shareUrl}`;
6844
7521
  message,
6845
7522
  url: shareUrl
6846
7523
  };
6847
- await import_react_native45.Share.share(payload);
7524
+ await import_react_native46.Share.share(payload);
6848
7525
  await trackShareApp({
6849
7526
  appId: app.id,
6850
7527
  success: true
@@ -6875,7 +7552,7 @@ ${shareUrl}`;
6875
7552
  onOpenComments,
6876
7553
  commentCountOverride
6877
7554
  });
6878
- const header = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7555
+ const header = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
6879
7556
  PreviewPanelHeader,
6880
7557
  {
6881
7558
  isOwner,
@@ -6883,23 +7560,18 @@ ${shareUrl}`;
6883
7560
  onClose,
6884
7561
  onNavigateHome,
6885
7562
  onGoToChat,
6886
- onShare: handleShare,
6887
- relatedApps,
6888
- relatedAppsLoading,
6889
- switchingRelatedAppId,
6890
- onOpenRelatedApps,
6891
- onSwitchRelatedApp
7563
+ onShare: handleShare
6892
7564
  }
6893
7565
  );
6894
7566
  if (loading || !app) {
6895
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native45.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
6896
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.ActivityIndicator, {}),
6897
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { height: 12 } }),
6898
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
7567
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native46.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
7568
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.ActivityIndicator, {}),
7569
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.View, { style: { height: 12 } }),
7570
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
6899
7571
  ] }) });
6900
7572
  }
6901
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(PreviewPage, { header, children: [
6902
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7573
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PreviewPage, { header, children: [
7574
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
6903
7575
  PreviewHeroSection,
6904
7576
  {
6905
7577
  appStatus: app.status,
@@ -6917,8 +7589,18 @@ ${shareUrl}`;
6917
7589
  }
6918
7590
  }
6919
7591
  ),
6920
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
6921
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7592
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
7593
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
7594
+ PreviewRelatedAppsSection,
7595
+ {
7596
+ relatedApps,
7597
+ relatedAppsLoading,
7598
+ switchingRelatedAppId,
7599
+ onOpenRelatedApps,
7600
+ onSwitchRelatedApp
7601
+ }
7602
+ ),
7603
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
6922
7604
  PreviewCustomizeSection,
6923
7605
  {
6924
7606
  app,
@@ -6929,7 +7611,7 @@ ${shareUrl}`;
6929
7611
  onStartDraw
6930
7612
  }
6931
7613
  ),
6932
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7614
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
6933
7615
  PreviewCollaborateSection,
6934
7616
  {
6935
7617
  canSubmitMergeRequest,
@@ -6955,26 +7637,26 @@ ${shareUrl}`;
6955
7637
 
6956
7638
  // src/studio/ui/ChatPanel.tsx
6957
7639
  var React43 = __toESM(require("react"));
6958
- var import_react_native57 = require("react-native");
7640
+ var import_react_native58 = require("react-native");
6959
7641
 
6960
7642
  // src/components/chat/ChatPage.tsx
6961
7643
  var React40 = __toESM(require("react"));
6962
- var import_react_native50 = require("react-native");
7644
+ var import_react_native51 = require("react-native");
6963
7645
  var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
6964
7646
 
6965
7647
  // src/components/chat/ChatMessageList.tsx
6966
7648
  var React39 = __toESM(require("react"));
6967
- var import_react_native49 = require("react-native");
7649
+ var import_react_native50 = require("react-native");
6968
7650
  var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
6969
7651
 
6970
7652
  // src/components/chat/ChatMessageBubble.tsx
6971
7653
  var React37 = __toESM(require("react"));
6972
- var import_react_native47 = require("react-native");
7654
+ var import_react_native48 = require("react-native");
6973
7655
  var import_lucide_react_native10 = require("lucide-react-native");
6974
7656
 
6975
7657
  // src/components/primitives/Button.tsx
6976
- var import_react_native46 = require("react-native");
6977
- var import_jsx_runtime47 = require("react/jsx-runtime");
7658
+ var import_react_native47 = require("react-native");
7659
+ var import_jsx_runtime48 = require("react/jsx-runtime");
6978
7660
  function backgroundFor2(variant, theme, pressed, disabled) {
6979
7661
  const { colors } = theme;
6980
7662
  if (variant === "ghost") return "transparent";
@@ -7010,8 +7692,8 @@ function Button({
7010
7692
  }) {
7011
7693
  const theme = useTheme();
7012
7694
  const isDisabled = disabled ?? void 0;
7013
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
7014
- import_react_native46.Pressable,
7695
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7696
+ import_react_native47.Pressable,
7015
7697
  {
7016
7698
  ...props,
7017
7699
  disabled: isDisabled,
@@ -7036,7 +7718,7 @@ function Button({
7036
7718
  }
7037
7719
 
7038
7720
  // src/components/chat/ChatMessageBubble.tsx
7039
- var import_jsx_runtime48 = require("react/jsx-runtime");
7721
+ var import_jsx_runtime49 = require("react/jsx-runtime");
7040
7722
  function areMessageMetaEqual(a, b) {
7041
7723
  if (a === b) return true;
7042
7724
  if (!a || !b) return a === b;
@@ -7069,8 +7751,8 @@ function ChatMessageBubbleInner({
7069
7751
  const handleRetryPress = React37.useCallback(() => {
7070
7752
  onRetryMessage == null ? void 0 : onRetryMessage(message.id);
7071
7753
  }, [message.id, onRetryMessage]);
7072
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native47.View, { style: [align, style], children: [
7073
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7754
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native48.View, { style: [align, style], children: [
7755
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7074
7756
  Surface,
7075
7757
  {
7076
7758
  variant: bubbleVariant,
@@ -7085,14 +7767,14 @@ function ChatMessageBubbleInner({
7085
7767
  },
7086
7768
  cornerStyle
7087
7769
  ],
7088
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native47.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7089
- isMergeCompleted || isSyncCompleted ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
7090
- isMergeApproved || isSyncStarted ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
7091
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native47.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
7770
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native48.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7771
+ isMergeCompleted || isSyncCompleted ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
7772
+ isMergeApproved || isSyncStarted ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
7773
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native48.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
7092
7774
  ] })
7093
7775
  }
7094
7776
  ),
7095
- showRetry ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native47.View, { style: { marginTop: theme.spacing.xs, alignSelf: align.alignSelf }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7777
+ showRetry ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native48.View, { style: { marginTop: theme.spacing.xs, alignSelf: align.alignSelf }, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7096
7778
  Button,
7097
7779
  {
7098
7780
  variant: "ghost",
@@ -7101,9 +7783,9 @@ function ChatMessageBubbleInner({
7101
7783
  disabled: retrying,
7102
7784
  style: { borderColor: theme.colors.danger },
7103
7785
  accessibilityLabel: "Retry send",
7104
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native47.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7105
- !retrying ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react_native10.RotateCcw, { size: 14, color: theme.colors.danger }) : null,
7106
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7786
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native48.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7787
+ !retrying ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react_native10.RotateCcw, { size: 14, color: theme.colors.danger }) : null,
7788
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7107
7789
  Text,
7108
7790
  {
7109
7791
  variant: "caption",
@@ -7126,23 +7808,23 @@ ChatMessageBubble.displayName = "ChatMessageBubble";
7126
7808
 
7127
7809
  // src/components/chat/TypingIndicator.tsx
7128
7810
  var React38 = __toESM(require("react"));
7129
- var import_react_native48 = require("react-native");
7130
- var import_jsx_runtime49 = require("react/jsx-runtime");
7811
+ var import_react_native49 = require("react-native");
7812
+ var import_jsx_runtime50 = require("react/jsx-runtime");
7131
7813
  function TypingIndicator({ style }) {
7132
7814
  const theme = useTheme();
7133
7815
  const dotColor = theme.colors.textSubtle;
7134
7816
  const anims = React38.useMemo(
7135
- () => [new import_react_native48.Animated.Value(0.3), new import_react_native48.Animated.Value(0.3), new import_react_native48.Animated.Value(0.3)],
7817
+ () => [new import_react_native49.Animated.Value(0.3), new import_react_native49.Animated.Value(0.3), new import_react_native49.Animated.Value(0.3)],
7136
7818
  []
7137
7819
  );
7138
7820
  React38.useEffect(() => {
7139
7821
  const loops = [];
7140
7822
  anims.forEach((a, idx) => {
7141
- const seq = import_react_native48.Animated.sequence([
7142
- import_react_native48.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
7143
- import_react_native48.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
7823
+ const seq = import_react_native49.Animated.sequence([
7824
+ import_react_native49.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
7825
+ import_react_native49.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
7144
7826
  ]);
7145
- const loop = import_react_native48.Animated.loop(seq);
7827
+ const loop = import_react_native49.Animated.loop(seq);
7146
7828
  loops.push(loop);
7147
7829
  loop.start();
7148
7830
  });
@@ -7150,8 +7832,8 @@ function TypingIndicator({ style }) {
7150
7832
  loops.forEach((l) => l.stop());
7151
7833
  };
7152
7834
  }, [anims]);
7153
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native48.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7154
- import_react_native48.Animated.View,
7835
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react_native49.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
7836
+ import_react_native49.Animated.View,
7155
7837
  {
7156
7838
  style: {
7157
7839
  width: 8,
@@ -7160,7 +7842,7 @@ function TypingIndicator({ style }) {
7160
7842
  marginHorizontal: 3,
7161
7843
  backgroundColor: dotColor,
7162
7844
  opacity: a,
7163
- transform: [{ translateY: import_react_native48.Animated.multiply(import_react_native48.Animated.subtract(a, 0.3), 2) }]
7845
+ transform: [{ translateY: import_react_native49.Animated.multiply(import_react_native49.Animated.subtract(a, 0.3), 2) }]
7164
7846
  }
7165
7847
  },
7166
7848
  i
@@ -7168,7 +7850,7 @@ function TypingIndicator({ style }) {
7168
7850
  }
7169
7851
 
7170
7852
  // src/components/chat/ChatMessageList.tsx
7171
- var import_jsx_runtime50 = require("react/jsx-runtime");
7853
+ var import_jsx_runtime51 = require("react/jsx-runtime");
7172
7854
  var ChatMessageList = React39.forwardRef(
7173
7855
  ({
7174
7856
  messages,
@@ -7244,16 +7926,16 @@ var ChatMessageList = React39.forwardRef(
7244
7926
  ],
7245
7927
  [contentStyle, theme.spacing.lg, theme.spacing.sm]
7246
7928
  );
7247
- const renderSeparator = React39.useCallback(() => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react_native49.View, { style: { height: theme.spacing.sm } }), [theme.spacing.sm]);
7929
+ const renderSeparator = React39.useCallback(() => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { height: theme.spacing.sm } }), [theme.spacing.sm]);
7248
7930
  const listHeader = React39.useMemo(
7249
- () => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_react_native49.View, { children: [
7250
- showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react_native49.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(TypingIndicator, {}) }) : null,
7251
- bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react_native49.View, { style: { height: bottomInset } }) : null
7931
+ () => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { children: [
7932
+ showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TypingIndicator, {}) }) : null,
7933
+ bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { height: bottomInset } }) : null
7252
7934
  ] }),
7253
7935
  [bottomInset, showTypingIndicator, theme.spacing.lg, theme.spacing.sm]
7254
7936
  );
7255
7937
  const renderItem = React39.useCallback(
7256
- ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
7938
+ ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
7257
7939
  ChatMessageBubble,
7258
7940
  {
7259
7941
  message: item,
@@ -7265,7 +7947,7 @@ var ChatMessageList = React39.forwardRef(
7265
7947
  ),
7266
7948
  [isRetryingMessage, lastMessageId, onRetryMessage, renderMessageContent]
7267
7949
  );
7268
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
7950
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
7269
7951
  import_bottom_sheet5.BottomSheetFlatList,
7270
7952
  {
7271
7953
  ref: listRef,
@@ -7288,7 +7970,7 @@ var ChatMessageList = React39.forwardRef(
7288
7970
  ChatMessageList.displayName = "ChatMessageList";
7289
7971
 
7290
7972
  // src/components/chat/ChatPage.tsx
7291
- var import_jsx_runtime51 = require("react/jsx-runtime");
7973
+ var import_jsx_runtime52 = require("react/jsx-runtime");
7292
7974
  function ChatPage({
7293
7975
  header,
7294
7976
  messages,
@@ -7309,7 +7991,7 @@ function ChatPage({
7309
7991
  const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
7310
7992
  const [composerHeight, setComposerHeight] = React40.useState(0);
7311
7993
  const [composerTopHeight, setComposerTopHeight] = React40.useState(0);
7312
- const footerBottomPadding = import_react_native50.Platform.OS === "ios" ? insets.bottom - 24 : insets.bottom + 10;
7994
+ const footerBottomPadding = import_react_native51.Platform.OS === "ios" ? insets.bottom - 24 : insets.bottom + 10;
7313
7995
  const totalComposerHeight = composerHeight + composerTopHeight;
7314
7996
  const overlayBottom = totalComposerHeight + footerBottomPadding + theme.spacing.lg;
7315
7997
  const bottomInset = totalComposerHeight + footerBottomPadding + theme.spacing.xl;
@@ -7326,16 +8008,16 @@ function ChatPage({
7326
8008
  if (composerTop) return;
7327
8009
  setComposerTopHeight(0);
7328
8010
  }, [composerTop]);
7329
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: [{ flex: 1 }, style], children: [
7330
- header ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { children: header }) : null,
7331
- topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
7332
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flex: 1 }, children: [
7333
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
7334
- import_react_native50.View,
8011
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native51.View, { style: [{ flex: 1 }, style], children: [
8012
+ header ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_react_native51.View, { children: header }) : null,
8013
+ topBanner ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_react_native51.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
8014
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native51.View, { style: { flex: 1 }, children: [
8015
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
8016
+ import_react_native51.View,
7335
8017
  {
7336
8018
  style: { flex: 1 },
7337
8019
  children: [
7338
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
8020
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
7339
8021
  ChatMessageList,
7340
8022
  {
7341
8023
  ref: listRef,
@@ -7352,8 +8034,8 @@ function ChatPage({
7352
8034
  ]
7353
8035
  }
7354
8036
  ),
7355
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
7356
- import_react_native50.View,
8037
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
8038
+ import_react_native51.View,
7357
8039
  {
7358
8040
  style: {
7359
8041
  position: "absolute",
@@ -7365,15 +8047,15 @@ function ChatPage({
7365
8047
  paddingBottom: footerBottomPadding
7366
8048
  },
7367
8049
  children: [
7368
- composerTop ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
7369
- import_react_native50.View,
8050
+ composerTop ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
8051
+ import_react_native51.View,
7370
8052
  {
7371
8053
  style: { marginBottom: theme.spacing.sm },
7372
8054
  onLayout: (e) => setComposerTopHeight(e.nativeEvent.layout.height),
7373
8055
  children: composerTop
7374
8056
  }
7375
8057
  ) : null,
7376
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
8058
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
7377
8059
  ChatComposer,
7378
8060
  {
7379
8061
  ...composer,
@@ -7390,9 +8072,9 @@ function ChatPage({
7390
8072
 
7391
8073
  // src/components/chat/ScrollToBottomButton.tsx
7392
8074
  var React41 = __toESM(require("react"));
7393
- var import_react_native51 = require("react-native");
8075
+ var import_react_native52 = require("react-native");
7394
8076
  var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
7395
- var import_jsx_runtime52 = require("react/jsx-runtime");
8077
+ var import_jsx_runtime53 = require("react/jsx-runtime");
7396
8078
  function ScrollToBottomButton({ visible, onPress, children, style }) {
7397
8079
  const theme = useTheme();
7398
8080
  const progress = (0, import_react_native_reanimated2.useSharedValue)(visible ? 1 : 0);
@@ -7406,7 +8088,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
7406
8088
  }));
7407
8089
  const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
7408
8090
  const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
7409
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
8091
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7410
8092
  import_react_native_reanimated2.default.View,
7411
8093
  {
7412
8094
  pointerEvents: visible ? "auto" : "none",
@@ -7420,8 +8102,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
7420
8102
  style,
7421
8103
  animStyle
7422
8104
  ],
7423
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
7424
- import_react_native51.View,
8105
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8106
+ import_react_native52.View,
7425
8107
  {
7426
8108
  style: {
7427
8109
  width: 44,
@@ -7439,8 +8121,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
7439
8121
  elevation: 5,
7440
8122
  opacity: pressed ? 0.85 : 1
7441
8123
  },
7442
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
7443
- import_react_native51.Pressable,
8124
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8125
+ import_react_native52.Pressable,
7444
8126
  {
7445
8127
  onPress,
7446
8128
  onPressIn: () => setPressed(true),
@@ -7457,16 +8139,16 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
7457
8139
  }
7458
8140
 
7459
8141
  // src/components/chat/ChatHeader.tsx
7460
- var import_react_native52 = require("react-native");
7461
- var import_jsx_runtime53 = require("react/jsx-runtime");
8142
+ var import_react_native53 = require("react-native");
8143
+ var import_jsx_runtime54 = require("react/jsx-runtime");
7462
8144
  function ChatHeader({ left, right, center, style }) {
7463
- const flattenedStyle = import_react_native52.StyleSheet.flatten([
8145
+ const flattenedStyle = import_react_native53.StyleSheet.flatten([
7464
8146
  {
7465
8147
  paddingTop: 0
7466
8148
  },
7467
8149
  style
7468
8150
  ]);
7469
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8151
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
7470
8152
  StudioSheetHeader,
7471
8153
  {
7472
8154
  left,
@@ -7478,13 +8160,13 @@ function ChatHeader({ left, right, center, style }) {
7478
8160
  }
7479
8161
 
7480
8162
  // src/components/chat/ForkNoticeBanner.tsx
7481
- var import_react_native53 = require("react-native");
7482
- var import_jsx_runtime54 = require("react/jsx-runtime");
8163
+ var import_react_native54 = require("react-native");
8164
+ var import_jsx_runtime55 = require("react/jsx-runtime");
7483
8165
  function ForkNoticeBanner({ isOwner = true, title, description, style }) {
7484
8166
  const theme = useTheme();
7485
8167
  const resolvedTitle = title ?? (isOwner ? "Remixed app" : "Remix app");
7486
8168
  const resolvedDescription = description ?? (isOwner ? "Any changes you make will be a remix of the original app. You can view the edited version in the Remix tab in your apps page." : "Once you make edits, this remixed version will appear on your Remixed apps page.");
7487
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
8169
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
7488
8170
  Card,
7489
8171
  {
7490
8172
  variant: "surfaceRaised",
@@ -7499,8 +8181,8 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
7499
8181
  },
7500
8182
  style
7501
8183
  ],
7502
- children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_react_native53.View, { style: { minWidth: 0 }, children: [
7503
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
8184
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_react_native54.View, { style: { minWidth: 0 }, children: [
8185
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
7504
8186
  Text,
7505
8187
  {
7506
8188
  style: {
@@ -7514,7 +8196,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
7514
8196
  children: resolvedTitle
7515
8197
  }
7516
8198
  ),
7517
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
8199
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
7518
8200
  Text,
7519
8201
  {
7520
8202
  style: {
@@ -7533,8 +8215,8 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
7533
8215
 
7534
8216
  // src/components/chat/ChatQueue.tsx
7535
8217
  var React42 = __toESM(require("react"));
7536
- var import_react_native54 = require("react-native");
7537
- var import_jsx_runtime55 = require("react/jsx-runtime");
8218
+ var import_react_native55 = require("react-native");
8219
+ var import_jsx_runtime56 = require("react/jsx-runtime");
7538
8220
  function ChatQueue({ items, onRemove }) {
7539
8221
  const theme = useTheme();
7540
8222
  const [expanded, setExpanded] = React42.useState({});
@@ -7566,8 +8248,8 @@ ${trimmedLine2}\u2026 `;
7566
8248
  setRemoving((prev) => Object.fromEntries(Object.entries(prev).filter(([id]) => ids.has(id))));
7567
8249
  }, [items]);
7568
8250
  if (items.length === 0) return null;
7569
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
7570
- import_react_native54.View,
8251
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
8252
+ import_react_native55.View,
7571
8253
  {
7572
8254
  style: {
7573
8255
  borderWidth: 1,
@@ -7578,16 +8260,16 @@ ${trimmedLine2}\u2026 `;
7578
8260
  backgroundColor: "transparent"
7579
8261
  },
7580
8262
  children: [
7581
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { variant: "caption", style: { marginBottom: theme.spacing.sm }, children: "Queue" }),
7582
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native54.View, { style: { gap: theme.spacing.sm }, children: items.map((item) => {
8263
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Text, { variant: "caption", style: { marginBottom: theme.spacing.sm }, children: "Queue" }),
8264
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native55.View, { style: { gap: theme.spacing.sm }, children: items.map((item) => {
7583
8265
  const isExpanded = Boolean(expanded[item.id]);
7584
8266
  const showToggle = Boolean(canExpand[item.id]);
7585
8267
  const prompt = item.prompt ?? "";
7586
8268
  const moreLabel = "more";
7587
8269
  const displayPrompt = !isExpanded && showToggle && collapsedText[item.id] ? collapsedText[item.id] : prompt;
7588
8270
  const isRemoving = Boolean(removing[item.id]);
7589
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
7590
- import_react_native54.View,
8271
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
8272
+ import_react_native55.View,
7591
8273
  {
7592
8274
  style: {
7593
8275
  flexDirection: "row",
@@ -7599,8 +8281,8 @@ ${trimmedLine2}\u2026 `;
7599
8281
  backgroundColor: withAlpha(theme.colors.surface, theme.scheme === "dark" ? 0.8 : 0.9)
7600
8282
  },
7601
8283
  children: [
7602
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_react_native54.View, { style: { flex: 1 }, children: [
7603
- !canExpand[item.id] ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
8284
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react_native55.View, { style: { flex: 1 }, children: [
8285
+ !canExpand[item.id] ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7604
8286
  Text,
7605
8287
  {
7606
8288
  style: { position: "absolute", opacity: 0, zIndex: -1, width: "100%" },
@@ -7619,14 +8301,14 @@ ${trimmedLine2}\u2026 `;
7619
8301
  children: prompt
7620
8302
  }
7621
8303
  ) : null,
7622
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
8304
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7623
8305
  Text,
7624
8306
  {
7625
8307
  variant: "bodyMuted",
7626
8308
  numberOfLines: isExpanded ? void 0 : 2,
7627
8309
  children: [
7628
8310
  displayPrompt,
7629
- !isExpanded && showToggle ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
8311
+ !isExpanded && showToggle ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7630
8312
  Text,
7631
8313
  {
7632
8314
  color: theme.colors.text,
@@ -7638,18 +8320,18 @@ ${trimmedLine2}\u2026 `;
7638
8320
  ]
7639
8321
  }
7640
8322
  ),
7641
- showToggle && isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
7642
- import_react_native54.Pressable,
8323
+ showToggle && isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
8324
+ import_react_native55.Pressable,
7643
8325
  {
7644
8326
  onPress: () => setExpanded((prev) => ({ ...prev, [item.id]: false })),
7645
8327
  hitSlop: 6,
7646
8328
  style: { alignSelf: "flex-start", marginTop: 4 },
7647
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { variant: "captionMuted", color: theme.colors.text, children: "less" })
8329
+ children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Text, { variant: "captionMuted", color: theme.colors.text, children: "less" })
7648
8330
  }
7649
8331
  ) : null
7650
8332
  ] }),
7651
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
7652
- import_react_native54.Pressable,
8333
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
8334
+ import_react_native55.Pressable,
7653
8335
  {
7654
8336
  onPress: () => {
7655
8337
  if (!onRemove || isRemoving) return;
@@ -7664,7 +8346,7 @@ ${trimmedLine2}\u2026 `;
7664
8346
  },
7665
8347
  hitSlop: 8,
7666
8348
  style: { alignSelf: "center" },
7667
- children: isRemoving ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native54.ActivityIndicator, { size: "small", color: theme.colors.text }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(IconClose, { size: 14, colorToken: "text" })
8349
+ children: isRemoving ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native55.ActivityIndicator, { size: "small", color: theme.colors.text }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(IconClose, { size: 14, colorToken: "text" })
7668
8350
  }
7669
8351
  )
7670
8352
  ]
@@ -7678,8 +8360,8 @@ ${trimmedLine2}\u2026 `;
7678
8360
  }
7679
8361
 
7680
8362
  // src/components/chat/AgentProgressCard.tsx
7681
- var import_react_native55 = require("react-native");
7682
- var import_jsx_runtime56 = require("react/jsx-runtime");
8363
+ var import_react_native56 = require("react-native");
8364
+ var import_jsx_runtime57 = require("react/jsx-runtime");
7683
8365
  function titleForPhase(phase) {
7684
8366
  if (phase === "planning") return "Planning";
7685
8367
  if (phase === "reasoning") return "Reasoning";
@@ -7703,8 +8385,8 @@ function AgentProgressCard({ progress }) {
7703
8385
  const phaseLabel = titleForPhase(progress.phase);
7704
8386
  const subtitle = progress.latestMessage || `Agent is ${phaseLabel.toLowerCase()}...`;
7705
8387
  const todo = progress.todoSummary;
7706
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7707
- import_react_native55.View,
8388
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
8389
+ import_react_native56.View,
7708
8390
  {
7709
8391
  style: {
7710
8392
  borderWidth: 1,
@@ -7715,20 +8397,20 @@ function AgentProgressCard({ progress }) {
7715
8397
  backgroundColor: withAlpha(theme.colors.surface, theme.scheme === "dark" ? 0.84 : 0.94)
7716
8398
  },
7717
8399
  children: [
7718
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react_native55.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 4 }, children: [
7719
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Text, { variant: "caption", children: statusLabel }),
7720
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Text, { variant: "captionMuted", children: phaseLabel })
8400
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_react_native56.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 4 }, children: [
8401
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Text, { variant: "caption", children: statusLabel }),
8402
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Text, { variant: "captionMuted", children: phaseLabel })
7721
8403
  ] }),
7722
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Text, { variant: "bodyMuted", children: subtitle }),
7723
- progress.changedFilesCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Text, { variant: "captionMuted", style: { marginTop: 8 }, children: [
8404
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Text, { variant: "bodyMuted", children: subtitle }),
8405
+ progress.changedFilesCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Text, { variant: "captionMuted", style: { marginTop: 8 }, children: [
7724
8406
  "Updated files: ",
7725
8407
  progress.changedFilesCount
7726
8408
  ] }) : null,
7727
- progress.recentFiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native55.View, { style: { marginTop: 6 }, children: progress.recentFiles.map((path) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Text, { variant: "captionMuted", numberOfLines: 1, children: [
8409
+ progress.recentFiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react_native56.View, { style: { marginTop: 6 }, children: progress.recentFiles.map((path) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Text, { variant: "captionMuted", numberOfLines: 1, children: [
7728
8410
  "\u2022 ",
7729
8411
  path
7730
8412
  ] }, path)) }) : null,
7731
- todo ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Text, { variant: "captionMuted", style: { marginTop: 8 }, children: [
8413
+ todo ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Text, { variant: "captionMuted", style: { marginTop: 8 }, children: [
7732
8414
  "Todos: ",
7733
8415
  todo.completed,
7734
8416
  "/",
@@ -7742,8 +8424,8 @@ function AgentProgressCard({ progress }) {
7742
8424
  }
7743
8425
 
7744
8426
  // src/components/chat/BundleProgressCard.tsx
7745
- var import_react_native56 = require("react-native");
7746
- var import_jsx_runtime57 = require("react/jsx-runtime");
8427
+ var import_react_native57 = require("react-native");
8428
+ var import_jsx_runtime58 = require("react/jsx-runtime");
7747
8429
  function titleForStatus2(status) {
7748
8430
  if (status === "succeeded") return "Completed";
7749
8431
  if (status === "failed") return "Failed";
@@ -7755,8 +8437,8 @@ function BundleProgressCard({ progress }) {
7755
8437
  const percent = Math.round(Math.max(0, Math.min(1, progress.progressValue)) * 100);
7756
8438
  const fillColor = progress.status === "failed" ? theme.colors.danger : progress.status === "succeeded" ? theme.colors.success : theme.colors.warning;
7757
8439
  const detail = progress.errorMessage || progress.phaseLabel;
7758
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
7759
- import_react_native56.View,
8440
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
8441
+ import_react_native57.View,
7760
8442
  {
7761
8443
  accessible: true,
7762
8444
  accessibilityRole: "progressbar",
@@ -7771,15 +8453,15 @@ function BundleProgressCard({ progress }) {
7771
8453
  backgroundColor: withAlpha(theme.colors.surface, theme.scheme === "dark" ? 0.84 : 0.94)
7772
8454
  },
7773
8455
  children: [
7774
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_react_native56.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }, children: [
7775
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Text, { variant: "caption", children: statusLabel }),
7776
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Text, { variant: "captionMuted", children: [
8456
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }, children: [
8457
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Text, { variant: "caption", children: statusLabel }),
8458
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Text, { variant: "captionMuted", children: [
7777
8459
  percent,
7778
8460
  "%"
7779
8461
  ] })
7780
8462
  ] }),
7781
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7782
- import_react_native56.View,
8463
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8464
+ import_react_native57.View,
7783
8465
  {
7784
8466
  style: {
7785
8467
  width: "100%",
@@ -7788,8 +8470,8 @@ function BundleProgressCard({ progress }) {
7788
8470
  backgroundColor: withAlpha(theme.colors.border, theme.scheme === "dark" ? 0.5 : 0.6),
7789
8471
  overflow: "hidden"
7790
8472
  },
7791
- children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7792
- import_react_native56.View,
8473
+ children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8474
+ import_react_native57.View,
7793
8475
  {
7794
8476
  style: {
7795
8477
  width: `${percent}%`,
@@ -7800,21 +8482,21 @@ function BundleProgressCard({ progress }) {
7800
8482
  )
7801
8483
  }
7802
8484
  ),
7803
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Text, { variant: "captionMuted", numberOfLines: 1, style: { marginTop: 8, minHeight: 16 }, children: detail })
8485
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Text, { variant: "captionMuted", numberOfLines: 1, style: { marginTop: 8, minHeight: 16 }, children: detail })
7804
8486
  ]
7805
8487
  }
7806
8488
  );
7807
8489
  }
7808
8490
 
7809
8491
  // src/studio/ui/ChatPanel.tsx
7810
- var import_jsx_runtime58 = require("react/jsx-runtime");
8492
+ var import_jsx_runtime59 = require("react/jsx-runtime");
7811
8493
  function ChatPanel({
7812
8494
  title = "Chat",
7813
8495
  messages,
7814
8496
  showTypingIndicator,
7815
8497
  loading,
7816
8498
  sendDisabled,
7817
- forking = false,
8499
+ forking: _forking = false,
7818
8500
  sending,
7819
8501
  shouldForkOnEdit,
7820
8502
  attachments = [],
@@ -7852,45 +8534,45 @@ function ChatPanel({
7852
8534
  var _a;
7853
8535
  (_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
7854
8536
  }, []);
7855
- const header = /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8537
+ const header = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7856
8538
  ChatHeader,
7857
8539
  {
7858
- left: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7859
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
7860
- onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
8540
+ left: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
8541
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
8542
+ onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
7861
8543
  ] }),
7862
- right: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
7863
- onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
7864
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
8544
+ right: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
8545
+ onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
8546
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
7865
8547
  ] }),
7866
8548
  center: null
7867
8549
  }
7868
8550
  );
7869
- const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8551
+ const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7870
8552
  ForkNoticeBanner,
7871
8553
  {
7872
8554
  isOwner: !shouldForkOnEdit,
7873
8555
  style: { marginBottom: 12 }
7874
8556
  }
7875
8557
  ) : null;
7876
- const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
8558
+ const showMessagesLoading = Boolean(loading) && messages.length === 0;
7877
8559
  if (showMessagesLoading) {
7878
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { flex: 1 }, children: [
7879
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native57.View, { children: header }),
7880
- topBanner ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native57.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
7881
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
7882
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native57.ActivityIndicator, {}),
7883
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native57.View, { style: { height: 12 } }),
7884
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
8560
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { flex: 1 }, children: [
8561
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { children: header }),
8562
+ topBanner ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
8563
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
8564
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.ActivityIndicator, {}),
8565
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { style: { height: 12 } }),
8566
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Text, { variant: "bodyMuted", children: "Loading messages\u2026" })
7885
8567
  ] })
7886
8568
  ] });
7887
8569
  }
7888
8570
  const bundleProgress = (progress == null ? void 0 : progress.bundle) ?? null;
7889
- const queueTop = progress || queueItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native57.View, { style: { gap: theme.spacing.sm }, children: [
7890
- progress ? bundleProgress ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(BundleProgressCard, { progress: bundleProgress }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(AgentProgressCard, { progress }) : null,
7891
- queueItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ChatQueue, { items: queueItems, onRemove: onRemoveQueueItem }) : null
8571
+ const queueTop = progress || queueItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { gap: theme.spacing.sm }, children: [
8572
+ progress ? bundleProgress ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(BundleProgressCard, { progress: bundleProgress }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(AgentProgressCard, { progress }) : null,
8573
+ !progress && queueItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ChatQueue, { items: queueItems, onRemove: onRemoveQueueItem }) : null
7892
8574
  ] }) : null;
7893
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8575
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7894
8576
  ChatPage,
7895
8577
  {
7896
8578
  header,
@@ -7903,20 +8585,20 @@ function ChatPanel({
7903
8585
  composerHorizontalPadding: 0,
7904
8586
  listRef,
7905
8587
  onNearBottomChange: setNearBottom,
7906
- overlay: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8588
+ overlay: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7907
8589
  ScrollToBottomButton,
7908
8590
  {
7909
8591
  visible: !nearBottom,
7910
8592
  onPress: handleScrollToBottom,
7911
8593
  style: { bottom: 80 },
7912
- children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(IconArrowDown, { size: 20, colorToken: "floatingContent" })
8594
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconArrowDown, { size: 20, colorToken: "floatingContent" })
7913
8595
  }
7914
8596
  ),
7915
8597
  composer: {
7916
8598
  // Keep the input editable even when sending is disallowed (e.g. agent still working),
7917
8599
  // otherwise iOS will drop focus/keyboard and BottomSheet can get "stuck" with a keyboard-sized gap.
7918
- disabled: Boolean(loading) || Boolean(forking),
7919
- sendDisabled: Boolean(sendDisabled) || Boolean(loading) || Boolean(forking),
8600
+ disabled: Boolean(loading),
8601
+ sendDisabled: Boolean(sendDisabled) || Boolean(loading),
7920
8602
  sending: Boolean(sending),
7921
8603
  onSend: handleSend,
7922
8604
  attachments,
@@ -7930,8 +8612,8 @@ function ChatPanel({
7930
8612
 
7931
8613
  // src/components/dialogs/ConfirmMergeRequestDialog.tsx
7932
8614
  var React44 = __toESM(require("react"));
7933
- var import_react_native58 = require("react-native");
7934
- var import_jsx_runtime59 = require("react/jsx-runtime");
8615
+ var import_react_native59 = require("react-native");
8616
+ var import_jsx_runtime60 = require("react/jsx-runtime");
7935
8617
  function ConfirmMergeRequestDialog({
7936
8618
  visible,
7937
8619
  onOpenChange,
@@ -7961,7 +8643,7 @@ function ConfirmMergeRequestDialog({
7961
8643
  justifyContent: "center",
7962
8644
  alignSelf: "stretch"
7963
8645
  };
7964
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8646
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
7965
8647
  Modal,
7966
8648
  {
7967
8649
  visible,
@@ -7972,7 +8654,7 @@ function ConfirmMergeRequestDialog({
7972
8654
  backgroundColor: theme.colors.background
7973
8655
  },
7974
8656
  children: [
7975
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8657
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_native59.View, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
7976
8658
  Text,
7977
8659
  {
7978
8660
  style: {
@@ -7984,9 +8666,9 @@ function ConfirmMergeRequestDialog({
7984
8666
  children: "Are you sure you want to approve this merge request?"
7985
8667
  }
7986
8668
  ) }),
7987
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_react_native58.View, { style: { marginTop: 16 }, children: [
7988
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7989
- import_react_native58.View,
8669
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_native59.View, { style: { marginTop: 16 }, children: [
8670
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8671
+ import_react_native59.View,
7990
8672
  {
7991
8673
  style: [
7992
8674
  fullWidthButtonBase,
@@ -7995,22 +8677,22 @@ function ConfirmMergeRequestDialog({
7995
8677
  opacity: canConfirm ? 1 : 0.5
7996
8678
  }
7997
8679
  ],
7998
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
7999
- import_react_native58.Pressable,
8680
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8681
+ import_react_native59.Pressable,
8000
8682
  {
8001
8683
  accessibilityRole: "button",
8002
8684
  accessibilityLabel: "Approve Merge",
8003
8685
  disabled: !canConfirm,
8004
8686
  onPress: handleConfirm,
8005
8687
  style: [fullWidthButtonBase, { flex: 1 }],
8006
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
8688
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
8007
8689
  }
8008
8690
  )
8009
8691
  }
8010
8692
  ),
8011
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { style: { height: 8 } }),
8012
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8013
- import_react_native58.View,
8693
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_native59.View, { style: { height: 8 } }),
8694
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8695
+ import_react_native59.View,
8014
8696
  {
8015
8697
  style: [
8016
8698
  fullWidthButtonBase,
@@ -8021,22 +8703,22 @@ function ConfirmMergeRequestDialog({
8021
8703
  opacity: isBuilding || !mergeRequest ? 0.5 : 1
8022
8704
  }
8023
8705
  ],
8024
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8025
- import_react_native58.Pressable,
8706
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8707
+ import_react_native59.Pressable,
8026
8708
  {
8027
8709
  accessibilityRole: "button",
8028
8710
  accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
8029
8711
  disabled: isBuilding || !mergeRequest,
8030
8712
  onPress: handleTestFirst,
8031
8713
  style: [fullWidthButtonBase, { flex: 1 }],
8032
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
8714
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
8033
8715
  }
8034
8716
  )
8035
8717
  }
8036
8718
  ),
8037
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react_native58.View, { style: { height: 8 } }),
8038
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8039
- import_react_native58.View,
8719
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_native59.View, { style: { height: 8 } }),
8720
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8721
+ import_react_native59.View,
8040
8722
  {
8041
8723
  style: [
8042
8724
  fullWidthButtonBase,
@@ -8046,14 +8728,14 @@ function ConfirmMergeRequestDialog({
8046
8728
  borderColor: theme.colors.border
8047
8729
  }
8048
8730
  ],
8049
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8050
- import_react_native58.Pressable,
8731
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8732
+ import_react_native59.Pressable,
8051
8733
  {
8052
8734
  accessibilityRole: "button",
8053
8735
  accessibilityLabel: "Cancel",
8054
8736
  onPress: close,
8055
8737
  style: [fullWidthButtonBase, { flex: 1 }],
8056
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
8738
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
8057
8739
  }
8058
8740
  )
8059
8741
  }
@@ -8065,7 +8747,7 @@ function ConfirmMergeRequestDialog({
8065
8747
  }
8066
8748
 
8067
8749
  // src/studio/ui/ConfirmMergeFlow.tsx
8068
- var import_jsx_runtime60 = require("react/jsx-runtime");
8750
+ var import_jsx_runtime61 = require("react/jsx-runtime");
8069
8751
  function ConfirmMergeFlow({
8070
8752
  visible,
8071
8753
  onOpenChange,
@@ -8076,7 +8758,7 @@ function ConfirmMergeFlow({
8076
8758
  onConfirm,
8077
8759
  onTestFirst
8078
8760
  }) {
8079
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8761
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
8080
8762
  ConfirmMergeRequestDialog,
8081
8763
  {
8082
8764
  visible,
@@ -8132,7 +8814,7 @@ function isOptimisticResolvedByServer(chatMessages, o) {
8132
8814
  }
8133
8815
  function useOptimisticChatMessages({
8134
8816
  threadId,
8135
- shouldForkOnEdit,
8817
+ shouldForkOnEdit: _shouldForkOnEdit,
8136
8818
  disableOptimistic = false,
8137
8819
  chatMessages,
8138
8820
  onSendChat
@@ -8167,7 +8849,7 @@ function useOptimisticChatMessages({
8167
8849
  }, [chatMessages, optimisticChat.length]);
8168
8850
  const onSend = React45.useCallback(
8169
8851
  async (text, attachments) => {
8170
- if (shouldForkOnEdit || disableOptimistic) {
8852
+ if (disableOptimistic) {
8171
8853
  await onSendChat(text, attachments);
8172
8854
  return;
8173
8855
  }
@@ -8191,11 +8873,11 @@ function useOptimisticChatMessages({
8191
8873
  setOptimisticChat((prev) => prev.map((m) => m.id === id ? { ...m, failed: true } : m));
8192
8874
  });
8193
8875
  },
8194
- [chatMessages, disableOptimistic, onSendChat, shouldForkOnEdit]
8876
+ [chatMessages, disableOptimistic, onSendChat]
8195
8877
  );
8196
8878
  const onRetry = React45.useCallback(
8197
8879
  async (messageId) => {
8198
- if (shouldForkOnEdit || disableOptimistic) return;
8880
+ if (disableOptimistic) return;
8199
8881
  const target = optimisticChat.find((m) => m.id === messageId);
8200
8882
  if (!target || target.retrying) return;
8201
8883
  const baseServerLastId = chatMessages.length > 0 ? chatMessages[chatMessages.length - 1].id : null;
@@ -8215,7 +8897,7 @@ function useOptimisticChatMessages({
8215
8897
  );
8216
8898
  }
8217
8899
  },
8218
- [chatMessages, disableOptimistic, onSendChat, optimisticChat, shouldForkOnEdit]
8900
+ [chatMessages, disableOptimistic, onSendChat, optimisticChat]
8219
8901
  );
8220
8902
  const isRetrying = React45.useCallback(
8221
8903
  (messageId) => {
@@ -8228,7 +8910,55 @@ function useOptimisticChatMessages({
8228
8910
 
8229
8911
  // src/studio/ui/StudioOverlay.tsx
8230
8912
  var import_studio_control = require("@comergehq/studio-control");
8231
- var import_jsx_runtime61 = require("react/jsx-runtime");
8913
+
8914
+ // src/components/icons/RemixUpIcon.tsx
8915
+ var import_react_native_svg3 = __toESM(require("react-native-svg"));
8916
+ var import_jsx_runtime62 = require("react/jsx-runtime");
8917
+ function RemixUpIcon({ width = 24, height = 24, ...props }) {
8918
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_react_native_svg3.default, { viewBox: "0 0 70 49", width, height, fill: "none", ...props, children: [
8919
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
8920
+ import_react_native_svg3.Path,
8921
+ {
8922
+ d: "M34.706 7.62939e-05L34.7656 2.28882e-05L21.44 13.2661L0 34.8401L13.266 48.1061L34.706 26.5321L21.44 13.2661L34.706 7.62939e-05Z",
8923
+ fill: "#00CBC0"
8924
+ }
8925
+ ),
8926
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
8927
+ import_react_native_svg3.Path,
8928
+ {
8929
+ d: "M47.972 13.266L34.7656 2.28882e-05L34.706 7.62939e-05L47.972 13.266L34.706 26.5321L56.28 48.106L69.546 34.84L47.972 13.266Z",
8930
+ fill: "#FF1820"
8931
+ }
8932
+ ),
8933
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
8934
+ import_react_native_svg3.Path,
8935
+ {
8936
+ d: "M34.7656 2.28882e-05L21.44 13.2661L34.706 26.5321L47.972 13.266L34.7656 2.28882e-05Z",
8937
+ fill: "#00322A"
8938
+ }
8939
+ )
8940
+ ] });
8941
+ }
8942
+
8943
+ // src/components/icons/RemixXLoopLottie.tsx
8944
+ var import_lottie_react_native = __toESM(require("lottie-react-native"));
8945
+ var import_jsx_runtime63 = require("react/jsx-runtime");
8946
+ var remixXLoopSource = require_remix_x_loop_lottie();
8947
+ var Lottie = import_lottie_react_native.default;
8948
+ function RemixXLoopLottie({ size = 24, style }) {
8949
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
8950
+ Lottie,
8951
+ {
8952
+ source: remixXLoopSource,
8953
+ autoPlay: true,
8954
+ loop: true,
8955
+ style: [{ width: size, height: size }, style]
8956
+ }
8957
+ );
8958
+ }
8959
+
8960
+ // src/studio/ui/StudioOverlay.tsx
8961
+ var import_jsx_runtime64 = require("react/jsx-runtime");
8232
8962
  function StudioOverlay({
8233
8963
  captureTargetRef,
8234
8964
  app,
@@ -8272,7 +9002,7 @@ function StudioOverlay({
8272
9002
  onSwitchRelatedApp
8273
9003
  }) {
8274
9004
  const theme = useTheme();
8275
- const { width } = (0, import_react_native59.useWindowDimensions)();
9005
+ const { width } = (0, import_react_native60.useWindowDimensions)();
8276
9006
  const [sheetOpen, setSheetOpen] = React46.useState(false);
8277
9007
  const sheetOpenRef = React46.useRef(sheetOpen);
8278
9008
  const pendingNavigateHomeRef = React46.useRef(false);
@@ -8283,6 +9013,7 @@ function StudioOverlay({
8283
9013
  const [commentsCount, setCommentsCount] = React46.useState(null);
8284
9014
  const threadId = (app == null ? void 0 : app.threadId) ?? null;
8285
9015
  const isForking = chatForking || (app == null ? void 0 : app.status) === "forking";
9016
+ const isBubbleLoading = (app == null ? void 0 : app.status) === "editing" || isBaseBundleDownloading;
8286
9017
  const queueItemsForChat = isForking ? [] : chatQueueItems;
8287
9018
  const disableOptimistic = Boolean(queueItemsForChat && queueItemsForChat.length > 0) || (app == null ? void 0 : app.status) === "editing";
8288
9019
  const optimistic = useOptimisticChatMessages({
@@ -8299,7 +9030,7 @@ function StudioOverlay({
8299
9030
  );
8300
9031
  const handleSheetOpenChange = React46.useCallback((open) => {
8301
9032
  setSheetOpen(open);
8302
- if (!open) import_react_native59.Keyboard.dismiss();
9033
+ if (!open) import_react_native60.Keyboard.dismiss();
8303
9034
  }, []);
8304
9035
  const closeSheet = React46.useCallback(() => {
8305
9036
  handleSheetOpenChange(false);
@@ -8310,8 +9041,8 @@ function StudioOverlay({
8310
9041
  openSheet();
8311
9042
  }, [openSheet]);
8312
9043
  const backToPreview = React46.useCallback(() => {
8313
- if (import_react_native59.Platform.OS !== "ios") {
8314
- import_react_native59.Keyboard.dismiss();
9044
+ if (import_react_native60.Platform.OS !== "ios") {
9045
+ import_react_native60.Keyboard.dismiss();
8315
9046
  setActivePage("preview");
8316
9047
  return;
8317
9048
  }
@@ -8323,9 +9054,9 @@ function StudioOverlay({
8323
9054
  clearTimeout(t);
8324
9055
  setActivePage("preview");
8325
9056
  };
8326
- const sub = import_react_native59.Keyboard.addListener("keyboardDidHide", finalize);
9057
+ const sub = import_react_native60.Keyboard.addListener("keyboardDidHide", finalize);
8327
9058
  const t = setTimeout(finalize, 350);
8328
- import_react_native59.Keyboard.dismiss();
9059
+ import_react_native60.Keyboard.dismiss();
8329
9060
  }, []);
8330
9061
  const startDraw = React46.useCallback(() => {
8331
9062
  setDrawing(true);
@@ -8362,26 +9093,26 @@ function StudioOverlay({
8362
9093
  );
8363
9094
  const handleNavigateHome = React46.useCallback(() => {
8364
9095
  if (!onNavigateHome) return;
8365
- if (import_react_native59.Platform.OS !== "android") {
9096
+ if (import_react_native60.Platform.OS !== "android") {
8366
9097
  onNavigateHome();
8367
9098
  return;
8368
9099
  }
8369
9100
  if (!sheetOpenRef.current) {
8370
- import_react_native59.InteractionManager.runAfterInteractions(() => {
9101
+ import_react_native60.InteractionManager.runAfterInteractions(() => {
8371
9102
  onNavigateHome();
8372
9103
  });
8373
9104
  return;
8374
9105
  }
8375
9106
  pendingNavigateHomeRef.current = true;
8376
- import_react_native59.Keyboard.dismiss();
9107
+ import_react_native60.Keyboard.dismiss();
8377
9108
  setActivePage("preview");
8378
9109
  closeSheet();
8379
9110
  }, [closeSheet, onNavigateHome]);
8380
9111
  const handleSheetDismiss = React46.useCallback(() => {
8381
- if (import_react_native59.Platform.OS !== "android") return;
9112
+ if (import_react_native60.Platform.OS !== "android") return;
8382
9113
  if (!pendingNavigateHomeRef.current) return;
8383
9114
  pendingNavigateHomeRef.current = false;
8384
- import_react_native59.InteractionManager.runAfterInteractions(() => {
9115
+ import_react_native60.InteractionManager.runAfterInteractions(() => {
8385
9116
  onNavigateHome == null ? void 0 : onNavigateHome();
8386
9117
  });
8387
9118
  }, [onNavigateHome]);
@@ -8410,14 +9141,14 @@ function StudioOverlay({
8410
9141
  React46.useEffect(() => {
8411
9142
  void (0, import_studio_control.publishComergeStudioUIState)(sheetOpen, studioControlOptions);
8412
9143
  }, [sheetOpen, studioControlOptions]);
8413
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
8414
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
8415
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, onDismiss: handleSheetDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9144
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
9145
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
9146
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, onDismiss: handleSheetDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8416
9147
  StudioSheetPager,
8417
9148
  {
8418
9149
  activePage,
8419
9150
  width,
8420
- preview: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9151
+ preview: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8421
9152
  PreviewPanel,
8422
9153
  {
8423
9154
  app,
@@ -8451,7 +9182,7 @@ function StudioOverlay({
8451
9182
  onSwitchRelatedApp
8452
9183
  }
8453
9184
  ),
8454
- chat: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9185
+ chat: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8455
9186
  ChatPanel,
8456
9187
  {
8457
9188
  messages: optimistic.messages,
@@ -8478,19 +9209,19 @@ function StudioOverlay({
8478
9209
  )
8479
9210
  }
8480
9211
  ) }),
8481
- showBubble && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9212
+ showBubble && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8482
9213
  Bubble,
8483
9214
  {
8484
9215
  visible: !sheetOpen && !drawing,
8485
9216
  ariaLabel: sheetOpen ? "Hide studio" : "Show studio",
8486
9217
  badgeCount: incomingMergeRequests.length,
8487
9218
  onPress: toggleSheet,
8488
- isLoading: (app == null ? void 0 : app.status) === "editing" || isBaseBundleDownloading,
9219
+ isLoading: isBubbleLoading,
8489
9220
  loadingBorderTone: isBaseBundleDownloading ? "warning" : "default",
8490
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_native59.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
9221
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react_native60.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: isBubbleLoading ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(RemixXLoopLottie, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(RemixUpIcon, { width: 24, height: 24 }) })
8491
9222
  }
8492
9223
  ),
8493
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9224
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8494
9225
  DrawModeOverlay,
8495
9226
  {
8496
9227
  visible: drawing,
@@ -8499,7 +9230,7 @@ function StudioOverlay({
8499
9230
  onCapture: handleDrawCapture
8500
9231
  }
8501
9232
  ),
8502
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9233
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8503
9234
  ConfirmMergeFlow,
8504
9235
  {
8505
9236
  visible: Boolean(confirmMr),
@@ -8513,7 +9244,7 @@ function StudioOverlay({
8513
9244
  onTestFirst: handleTestMr
8514
9245
  }
8515
9246
  ),
8516
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9247
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
8517
9248
  AppCommentsSheet,
8518
9249
  {
8519
9250
  appId: commentsAppId,
@@ -9152,7 +9883,7 @@ function useRelatedApps(appId) {
9152
9883
  }
9153
9884
 
9154
9885
  // src/studio/ComergeStudio.tsx
9155
- var import_jsx_runtime62 = require("react/jsx-runtime");
9886
+ var import_jsx_runtime65 = require("react/jsx-runtime");
9156
9887
  function ComergeStudio({
9157
9888
  appId,
9158
9889
  clientKey: clientKey2,
@@ -9170,20 +9901,20 @@ function ComergeStudio({
9170
9901
  const [activeAppId, setActiveAppId] = React51.useState(appId);
9171
9902
  const [runtimeAppId, setRuntimeAppId] = React51.useState(appId);
9172
9903
  const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React51.useState(null);
9173
- const platform = React51.useMemo(() => import_react_native60.Platform.OS === "ios" ? "ios" : "android", []);
9904
+ const platform = React51.useMemo(() => import_react_native61.Platform.OS === "ios" ? "ios" : "android", []);
9174
9905
  React51.useEffect(() => {
9175
9906
  setActiveAppId(appId);
9176
9907
  setRuntimeAppId(appId);
9177
9908
  setPendingRuntimeTargetAppId(null);
9178
9909
  }, [appId]);
9179
9910
  const captureTargetRef = React51.useRef(null);
9180
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
9911
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
9181
9912
  StudioBootstrap,
9182
9913
  {
9183
9914
  clientKey: clientKey2,
9184
9915
  analyticsEnabled,
9185
- fallback: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_react_native60.View, { style: { flex: 1 } }),
9186
- children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
9916
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react_native61.View, { style: { flex: 1 } }),
9917
+ children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
9187
9918
  ComergeStudioInner,
9188
9919
  {
9189
9920
  userId,
@@ -9319,6 +10050,7 @@ function ComergeStudioInner({
9319
10050
  }
9320
10051
  },
9321
10052
  uploadAttachments: uploader.uploadBase64Images,
10053
+ stageAttachments: uploader.stageBase64Images,
9322
10054
  onEditStart: () => {
9323
10055
  if (editQueue.items.length === 0) {
9324
10056
  setSuppressQueueUntilResponse(true);
@@ -9465,8 +10197,8 @@ function ComergeStudioInner({
9465
10197
  setRuntimeAppId
9466
10198
  ]
9467
10199
  );
9468
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_react_native60.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_react_native60.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
9469
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
10200
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react_native61.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_react_native61.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
10201
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
9470
10202
  RuntimeRenderer,
9471
10203
  {
9472
10204
  appKey,
@@ -9490,7 +10222,7 @@ function ComergeStudioInner({
9490
10222
  }
9491
10223
  }
9492
10224
  ),
9493
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
10225
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
9494
10226
  StudioOverlay,
9495
10227
  {
9496
10228
  captureTargetRef,