yaver-cli 1.99.411 → 1.99.416

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaver-cli",
3
- "version": "1.99.411",
3
+ "version": "1.99.416",
4
4
  "mcpName": "io.github.yaver-io/yaver",
5
5
  "description": "Unified npm bootstrap for the Yaver agent, SDK injection, and local-first developer runtime",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  },
12
12
  "main": "src/index.js",
13
13
  "scripts": {
14
+ "test": "node --test test/*.test.js",
14
15
  "postinstall": "node src/postinstall.js",
15
16
  "preuninstall": "node src/preuninstall.js"
16
17
  },
@@ -39,7 +40,7 @@
39
40
  "license": "Apache-2.0",
40
41
  "repository": {
41
42
  "type": "git",
42
- "url": "git+https://github.com/kivanccakmak/yaver.io.git"
43
+ "url": "git+https://github.com/yaver-io/yaver.io.git"
43
44
  },
44
45
  "homepage": "https://yaver.io",
45
46
  "engines": {
@@ -49,4 +50,4 @@
49
50
  "semver": "^7.6.0",
50
51
  "yaver-mobile-headless": "^0.1.2"
51
52
  }
52
- }
53
+ }
package/sdk-manifest.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "reactNative": "0.81.5",
5
5
  "react": "19.1.0",
6
6
  "hermes": {
7
- "version": "1.99.410",
7
+ "version": "1.99.416",
8
8
  "bytecodeVersion": 96
9
9
  },
10
10
  "arch": {
@@ -125,637 +125,637 @@
125
125
  },
126
126
  "moduleSupport": {
127
127
  "@amplitude/analytics-react-native": {
128
- "version": "1.99.410",
128
+ "version": "1.99.416",
129
129
  "hostApp": true,
130
130
  "cliPush": true,
131
131
  "agentOpenInYaver": true,
132
132
  "pluginEnabled": false
133
133
  },
134
134
  "@intercom/intercom-react-native": {
135
- "version": "1.99.410",
135
+ "version": "1.99.416",
136
136
  "hostApp": true,
137
137
  "cliPush": true,
138
138
  "agentOpenInYaver": true,
139
139
  "pluginEnabled": false
140
140
  },
141
141
  "@notifee/react-native": {
142
- "version": "1.99.410",
142
+ "version": "1.99.416",
143
143
  "hostApp": true,
144
144
  "cliPush": true,
145
145
  "agentOpenInYaver": true,
146
146
  "pluginEnabled": false
147
147
  },
148
148
  "@react-native-async-storage/async-storage": {
149
- "version": "1.99.410",
149
+ "version": "1.99.416",
150
150
  "hostApp": true,
151
151
  "cliPush": true,
152
152
  "agentOpenInYaver": true,
153
153
  "pluginEnabled": false
154
154
  },
155
155
  "@react-native-community/datetimepicker": {
156
- "version": "1.99.410",
156
+ "version": "1.99.416",
157
157
  "hostApp": true,
158
158
  "cliPush": true,
159
159
  "agentOpenInYaver": true,
160
160
  "pluginEnabled": false
161
161
  },
162
162
  "@react-native-community/netinfo": {
163
- "version": "1.99.410",
163
+ "version": "1.99.416",
164
164
  "hostApp": true,
165
165
  "cliPush": true,
166
166
  "agentOpenInYaver": true,
167
167
  "pluginEnabled": false
168
168
  },
169
169
  "@react-native-community/slider": {
170
- "version": "1.99.410",
170
+ "version": "1.99.416",
171
171
  "hostApp": true,
172
172
  "cliPush": true,
173
173
  "agentOpenInYaver": true,
174
174
  "pluginEnabled": false
175
175
  },
176
176
  "@react-native-google-signin/google-signin": {
177
- "version": "1.99.410",
177
+ "version": "1.99.416",
178
178
  "hostApp": true,
179
179
  "cliPush": true,
180
180
  "agentOpenInYaver": true,
181
181
  "pluginEnabled": false
182
182
  },
183
183
  "@react-native-masked-view/masked-view": {
184
- "version": "1.99.410",
184
+ "version": "1.99.416",
185
185
  "hostApp": true,
186
186
  "cliPush": true,
187
187
  "agentOpenInYaver": true,
188
188
  "pluginEnabled": false
189
189
  },
190
190
  "@react-native-menu/menu": {
191
- "version": "1.99.410",
191
+ "version": "1.99.416",
192
192
  "hostApp": true,
193
193
  "cliPush": true,
194
194
  "agentOpenInYaver": true,
195
195
  "pluginEnabled": false
196
196
  },
197
197
  "@react-native-ml-kit/text-recognition": {
198
- "version": "1.99.410",
198
+ "version": "1.99.416",
199
199
  "hostApp": true,
200
200
  "cliPush": true,
201
201
  "agentOpenInYaver": true,
202
202
  "pluginEnabled": false
203
203
  },
204
204
  "@react-native-picker/picker": {
205
- "version": "1.99.410",
205
+ "version": "1.99.416",
206
206
  "hostApp": true,
207
207
  "cliPush": true,
208
208
  "agentOpenInYaver": true,
209
209
  "pluginEnabled": false
210
210
  },
211
211
  "@react-native-segmented-control/segmented-control": {
212
- "version": "1.99.410",
212
+ "version": "1.99.416",
213
213
  "hostApp": true,
214
214
  "cliPush": true,
215
215
  "agentOpenInYaver": true,
216
216
  "pluginEnabled": false
217
217
  },
218
218
  "@sentry/react-native": {
219
- "version": "1.99.410",
219
+ "version": "1.99.416",
220
220
  "hostApp": true,
221
221
  "cliPush": true,
222
222
  "agentOpenInYaver": true,
223
223
  "pluginEnabled": false
224
224
  },
225
225
  "@shopify/react-native-skia": {
226
- "version": "1.99.410",
226
+ "version": "1.99.416",
227
227
  "hostApp": true,
228
228
  "cliPush": true,
229
229
  "agentOpenInYaver": true,
230
230
  "pluginEnabled": false
231
231
  },
232
232
  "@stripe/stripe-react-native": {
233
- "version": "1.99.410",
233
+ "version": "1.99.416",
234
234
  "hostApp": true,
235
235
  "cliPush": true,
236
236
  "agentOpenInYaver": true,
237
237
  "pluginEnabled": false
238
238
  },
239
239
  "expo-apple-authentication": {
240
- "version": "1.99.410",
240
+ "version": "1.99.416",
241
241
  "hostApp": true,
242
242
  "cliPush": true,
243
243
  "agentOpenInYaver": true,
244
244
  "pluginEnabled": true
245
245
  },
246
246
  "expo-asset": {
247
- "version": "1.99.410",
247
+ "version": "1.99.416",
248
248
  "hostApp": true,
249
249
  "cliPush": true,
250
250
  "agentOpenInYaver": true,
251
251
  "pluginEnabled": false
252
252
  },
253
253
  "expo-av": {
254
- "version": "1.99.410",
254
+ "version": "1.99.416",
255
255
  "hostApp": true,
256
256
  "cliPush": true,
257
257
  "agentOpenInYaver": true,
258
258
  "pluginEnabled": false
259
259
  },
260
260
  "expo-background-fetch": {
261
- "version": "1.99.410",
261
+ "version": "1.99.416",
262
262
  "hostApp": true,
263
263
  "cliPush": true,
264
264
  "agentOpenInYaver": true,
265
265
  "pluginEnabled": false
266
266
  },
267
267
  "expo-battery": {
268
- "version": "1.99.410",
268
+ "version": "1.99.416",
269
269
  "hostApp": true,
270
270
  "cliPush": true,
271
271
  "agentOpenInYaver": true,
272
272
  "pluginEnabled": false
273
273
  },
274
274
  "expo-blur": {
275
- "version": "1.99.410",
275
+ "version": "1.99.416",
276
276
  "hostApp": true,
277
277
  "cliPush": true,
278
278
  "agentOpenInYaver": true,
279
279
  "pluginEnabled": false
280
280
  },
281
281
  "expo-brightness": {
282
- "version": "1.99.410",
282
+ "version": "1.99.416",
283
283
  "hostApp": true,
284
284
  "cliPush": true,
285
285
  "agentOpenInYaver": true,
286
286
  "pluginEnabled": false
287
287
  },
288
288
  "expo-calendar": {
289
- "version": "1.99.410",
289
+ "version": "1.99.416",
290
290
  "hostApp": true,
291
291
  "cliPush": true,
292
292
  "agentOpenInYaver": true,
293
293
  "pluginEnabled": false
294
294
  },
295
295
  "expo-camera": {
296
- "version": "1.99.410",
296
+ "version": "1.99.416",
297
297
  "hostApp": true,
298
298
  "cliPush": true,
299
299
  "agentOpenInYaver": true,
300
300
  "pluginEnabled": true
301
301
  },
302
302
  "expo-clipboard": {
303
- "version": "1.99.410",
303
+ "version": "1.99.416",
304
304
  "hostApp": true,
305
305
  "cliPush": true,
306
306
  "agentOpenInYaver": true,
307
307
  "pluginEnabled": false
308
308
  },
309
309
  "expo-constants": {
310
- "version": "1.99.410",
310
+ "version": "1.99.416",
311
311
  "hostApp": true,
312
312
  "cliPush": true,
313
313
  "agentOpenInYaver": true,
314
314
  "pluginEnabled": false
315
315
  },
316
316
  "expo-contacts": {
317
- "version": "1.99.410",
317
+ "version": "1.99.416",
318
318
  "hostApp": true,
319
319
  "cliPush": true,
320
320
  "agentOpenInYaver": true,
321
321
  "pluginEnabled": false
322
322
  },
323
323
  "expo-crypto": {
324
- "version": "1.99.410",
324
+ "version": "1.99.416",
325
325
  "hostApp": true,
326
326
  "cliPush": true,
327
327
  "agentOpenInYaver": true,
328
328
  "pluginEnabled": false
329
329
  },
330
330
  "expo-device": {
331
- "version": "1.99.410",
331
+ "version": "1.99.416",
332
332
  "hostApp": true,
333
333
  "cliPush": true,
334
334
  "agentOpenInYaver": true,
335
335
  "pluginEnabled": false
336
336
  },
337
337
  "expo-document-picker": {
338
- "version": "1.99.410",
338
+ "version": "1.99.416",
339
339
  "hostApp": true,
340
340
  "cliPush": true,
341
341
  "agentOpenInYaver": true,
342
342
  "pluginEnabled": false
343
343
  },
344
344
  "expo-file-system": {
345
- "version": "1.99.410",
345
+ "version": "1.99.416",
346
346
  "hostApp": true,
347
347
  "cliPush": true,
348
348
  "agentOpenInYaver": true,
349
349
  "pluginEnabled": false
350
350
  },
351
351
  "expo-font": {
352
- "version": "1.99.410",
352
+ "version": "1.99.416",
353
353
  "hostApp": true,
354
354
  "cliPush": true,
355
355
  "agentOpenInYaver": true,
356
356
  "pluginEnabled": true
357
357
  },
358
358
  "expo-haptics": {
359
- "version": "1.99.410",
359
+ "version": "1.99.416",
360
360
  "hostApp": true,
361
361
  "cliPush": true,
362
362
  "agentOpenInYaver": true,
363
363
  "pluginEnabled": false
364
364
  },
365
365
  "expo-image": {
366
- "version": "1.99.410",
366
+ "version": "1.99.416",
367
367
  "hostApp": true,
368
368
  "cliPush": true,
369
369
  "agentOpenInYaver": true,
370
370
  "pluginEnabled": false
371
371
  },
372
372
  "expo-image-manipulator": {
373
- "version": "1.99.410",
373
+ "version": "1.99.416",
374
374
  "hostApp": true,
375
375
  "cliPush": true,
376
376
  "agentOpenInYaver": true,
377
377
  "pluginEnabled": false
378
378
  },
379
379
  "expo-image-picker": {
380
- "version": "1.99.410",
380
+ "version": "1.99.416",
381
381
  "hostApp": true,
382
382
  "cliPush": true,
383
383
  "agentOpenInYaver": true,
384
384
  "pluginEnabled": true
385
385
  },
386
386
  "expo-keep-awake": {
387
- "version": "1.99.410",
387
+ "version": "1.99.416",
388
388
  "hostApp": true,
389
389
  "cliPush": true,
390
390
  "agentOpenInYaver": true,
391
391
  "pluginEnabled": false
392
392
  },
393
393
  "expo-linear-gradient": {
394
- "version": "1.99.410",
394
+ "version": "1.99.416",
395
395
  "hostApp": true,
396
396
  "cliPush": true,
397
397
  "agentOpenInYaver": true,
398
398
  "pluginEnabled": false
399
399
  },
400
400
  "expo-linking": {
401
- "version": "1.99.410",
401
+ "version": "1.99.416",
402
402
  "hostApp": true,
403
403
  "cliPush": true,
404
404
  "agentOpenInYaver": true,
405
405
  "pluginEnabled": false
406
406
  },
407
407
  "expo-local-authentication": {
408
- "version": "1.99.410",
408
+ "version": "1.99.416",
409
409
  "hostApp": true,
410
410
  "cliPush": true,
411
411
  "agentOpenInYaver": true,
412
412
  "pluginEnabled": false
413
413
  },
414
414
  "expo-localization": {
415
- "version": "1.99.410",
415
+ "version": "1.99.416",
416
416
  "hostApp": true,
417
417
  "cliPush": true,
418
418
  "agentOpenInYaver": true,
419
419
  "pluginEnabled": true
420
420
  },
421
421
  "expo-location": {
422
- "version": "1.99.410",
422
+ "version": "1.99.416",
423
423
  "hostApp": true,
424
424
  "cliPush": true,
425
425
  "agentOpenInYaver": true,
426
426
  "pluginEnabled": true
427
427
  },
428
428
  "expo-mail-composer": {
429
- "version": "1.99.410",
429
+ "version": "1.99.416",
430
430
  "hostApp": true,
431
431
  "cliPush": true,
432
432
  "agentOpenInYaver": true,
433
433
  "pluginEnabled": true
434
434
  },
435
435
  "expo-media-library": {
436
- "version": "1.99.410",
436
+ "version": "1.99.416",
437
437
  "hostApp": true,
438
438
  "cliPush": true,
439
439
  "agentOpenInYaver": true,
440
440
  "pluginEnabled": false
441
441
  },
442
442
  "expo-notifications": {
443
- "version": "1.99.410",
443
+ "version": "1.99.416",
444
444
  "hostApp": true,
445
445
  "cliPush": true,
446
446
  "agentOpenInYaver": true,
447
447
  "pluginEnabled": true
448
448
  },
449
449
  "expo-print": {
450
- "version": "1.99.410",
450
+ "version": "1.99.416",
451
451
  "hostApp": true,
452
452
  "cliPush": true,
453
453
  "agentOpenInYaver": true,
454
454
  "pluginEnabled": false
455
455
  },
456
456
  "expo-screen-orientation": {
457
- "version": "1.99.410",
457
+ "version": "1.99.416",
458
458
  "hostApp": true,
459
459
  "cliPush": true,
460
460
  "agentOpenInYaver": true,
461
461
  "pluginEnabled": false
462
462
  },
463
463
  "expo-secure-store": {
464
- "version": "1.99.410",
464
+ "version": "1.99.416",
465
465
  "hostApp": true,
466
466
  "cliPush": true,
467
467
  "agentOpenInYaver": true,
468
468
  "pluginEnabled": true
469
469
  },
470
470
  "expo-sensors": {
471
- "version": "1.99.410",
471
+ "version": "1.99.416",
472
472
  "hostApp": true,
473
473
  "cliPush": true,
474
474
  "agentOpenInYaver": true,
475
475
  "pluginEnabled": true
476
476
  },
477
477
  "expo-share-intent": {
478
- "version": "1.99.410",
478
+ "version": "1.99.416",
479
479
  "hostApp": true,
480
480
  "cliPush": true,
481
481
  "agentOpenInYaver": true,
482
482
  "pluginEnabled": true
483
483
  },
484
484
  "expo-sharing": {
485
- "version": "1.99.410",
485
+ "version": "1.99.416",
486
486
  "hostApp": true,
487
487
  "cliPush": true,
488
488
  "agentOpenInYaver": true,
489
489
  "pluginEnabled": false
490
490
  },
491
491
  "expo-speech": {
492
- "version": "1.99.410",
492
+ "version": "1.99.416",
493
493
  "hostApp": true,
494
494
  "cliPush": true,
495
495
  "agentOpenInYaver": true,
496
496
  "pluginEnabled": false
497
497
  },
498
498
  "expo-splash-screen": {
499
- "version": "1.99.410",
499
+ "version": "1.99.416",
500
500
  "hostApp": true,
501
501
  "cliPush": true,
502
502
  "agentOpenInYaver": true,
503
503
  "pluginEnabled": true
504
504
  },
505
505
  "expo-sqlite": {
506
- "version": "1.99.410",
506
+ "version": "1.99.416",
507
507
  "hostApp": true,
508
508
  "cliPush": true,
509
509
  "agentOpenInYaver": true,
510
510
  "pluginEnabled": true
511
511
  },
512
512
  "expo-status-bar": {
513
- "version": "1.99.410",
513
+ "version": "1.99.416",
514
514
  "hostApp": true,
515
515
  "cliPush": true,
516
516
  "agentOpenInYaver": true,
517
517
  "pluginEnabled": false
518
518
  },
519
519
  "expo-system-ui": {
520
- "version": "1.99.410",
520
+ "version": "1.99.416",
521
521
  "hostApp": true,
522
522
  "cliPush": true,
523
523
  "agentOpenInYaver": true,
524
524
  "pluginEnabled": false
525
525
  },
526
526
  "expo-task-manager": {
527
- "version": "1.99.410",
527
+ "version": "1.99.416",
528
528
  "hostApp": true,
529
529
  "cliPush": true,
530
530
  "agentOpenInYaver": true,
531
531
  "pluginEnabled": false
532
532
  },
533
533
  "expo-updates": {
534
- "version": "1.99.410",
534
+ "version": "1.99.416",
535
535
  "hostApp": true,
536
536
  "cliPush": true,
537
537
  "agentOpenInYaver": true,
538
538
  "pluginEnabled": true
539
539
  },
540
540
  "expo-video": {
541
- "version": "1.99.410",
541
+ "version": "1.99.416",
542
542
  "hostApp": true,
543
543
  "cliPush": true,
544
544
  "agentOpenInYaver": true,
545
545
  "pluginEnabled": true
546
546
  },
547
547
  "expo-video-thumbnails": {
548
- "version": "1.99.410",
548
+ "version": "1.99.416",
549
549
  "hostApp": true,
550
550
  "cliPush": true,
551
551
  "agentOpenInYaver": true,
552
552
  "pluginEnabled": false
553
553
  },
554
554
  "expo-web-browser": {
555
- "version": "1.99.410",
555
+ "version": "1.99.416",
556
556
  "hostApp": true,
557
557
  "cliPush": true,
558
558
  "agentOpenInYaver": true,
559
559
  "pluginEnabled": false
560
560
  },
561
561
  "lottie-react-native": {
562
- "version": "1.99.410",
562
+ "version": "1.99.416",
563
563
  "hostApp": true,
564
564
  "cliPush": true,
565
565
  "agentOpenInYaver": true,
566
566
  "pluginEnabled": false
567
567
  },
568
568
  "react-native-audio-api": {
569
- "version": "1.99.410",
569
+ "version": "1.99.416",
570
570
  "hostApp": true,
571
571
  "cliPush": true,
572
572
  "agentOpenInYaver": true,
573
573
  "pluginEnabled": false
574
574
  },
575
575
  "react-native-ble-plx": {
576
- "version": "1.99.410",
576
+ "version": "1.99.416",
577
577
  "hostApp": true,
578
578
  "cliPush": true,
579
579
  "agentOpenInYaver": true,
580
580
  "pluginEnabled": false
581
581
  },
582
582
  "react-native-device-info": {
583
- "version": "1.99.410",
583
+ "version": "1.99.416",
584
584
  "hostApp": true,
585
585
  "cliPush": true,
586
586
  "agentOpenInYaver": true,
587
587
  "pluginEnabled": false
588
588
  },
589
589
  "react-native-gesture-handler": {
590
- "version": "1.99.410",
590
+ "version": "1.99.416",
591
591
  "hostApp": true,
592
592
  "cliPush": true,
593
593
  "agentOpenInYaver": true,
594
594
  "pluginEnabled": false
595
595
  },
596
596
  "react-native-get-random-values": {
597
- "version": "1.99.410",
597
+ "version": "1.99.416",
598
598
  "hostApp": true,
599
599
  "cliPush": true,
600
600
  "agentOpenInYaver": true,
601
601
  "pluginEnabled": false
602
602
  },
603
603
  "react-native-iap": {
604
- "version": "1.99.410",
604
+ "version": "1.99.416",
605
605
  "hostApp": true,
606
606
  "cliPush": true,
607
607
  "agentOpenInYaver": true,
608
608
  "pluginEnabled": false
609
609
  },
610
610
  "react-native-keyboard-controller": {
611
- "version": "1.99.410",
611
+ "version": "1.99.416",
612
612
  "hostApp": true,
613
613
  "cliPush": true,
614
614
  "agentOpenInYaver": true,
615
615
  "pluginEnabled": false
616
616
  },
617
617
  "react-native-maps": {
618
- "version": "1.99.410",
618
+ "version": "1.99.416",
619
619
  "hostApp": true,
620
620
  "cliPush": true,
621
621
  "agentOpenInYaver": true,
622
622
  "pluginEnabled": false
623
623
  },
624
624
  "react-native-mmkv": {
625
- "version": "1.99.410",
625
+ "version": "1.99.416",
626
626
  "hostApp": true,
627
627
  "cliPush": true,
628
628
  "agentOpenInYaver": true,
629
629
  "pluginEnabled": false
630
630
  },
631
631
  "react-native-nitro-image": {
632
- "version": "1.99.410",
632
+ "version": "1.99.416",
633
633
  "hostApp": true,
634
634
  "cliPush": true,
635
635
  "agentOpenInYaver": true,
636
636
  "pluginEnabled": false
637
637
  },
638
638
  "react-native-nitro-modules": {
639
- "version": "1.99.410",
639
+ "version": "1.99.416",
640
640
  "hostApp": true,
641
641
  "cliPush": true,
642
642
  "agentOpenInYaver": true,
643
643
  "pluginEnabled": false
644
644
  },
645
645
  "react-native-pager-view": {
646
- "version": "1.99.410",
646
+ "version": "1.99.416",
647
647
  "hostApp": true,
648
648
  "cliPush": true,
649
649
  "agentOpenInYaver": true,
650
650
  "pluginEnabled": false
651
651
  },
652
652
  "react-native-passkey": {
653
- "version": "1.99.410",
653
+ "version": "1.99.416",
654
654
  "hostApp": true,
655
655
  "cliPush": true,
656
656
  "agentOpenInYaver": true,
657
657
  "pluginEnabled": false
658
658
  },
659
659
  "react-native-pdf": {
660
- "version": "1.99.410",
660
+ "version": "1.99.416",
661
661
  "hostApp": true,
662
662
  "cliPush": true,
663
663
  "agentOpenInYaver": true,
664
664
  "pluginEnabled": false
665
665
  },
666
666
  "react-native-permissions": {
667
- "version": "1.99.410",
667
+ "version": "1.99.416",
668
668
  "hostApp": true,
669
669
  "cliPush": true,
670
670
  "agentOpenInYaver": true,
671
671
  "pluginEnabled": false
672
672
  },
673
673
  "react-native-purchases": {
674
- "version": "1.99.410",
674
+ "version": "1.99.416",
675
675
  "hostApp": true,
676
676
  "cliPush": true,
677
677
  "agentOpenInYaver": true,
678
678
  "pluginEnabled": false
679
679
  },
680
680
  "react-native-reanimated": {
681
- "version": "1.99.410",
681
+ "version": "1.99.416",
682
682
  "hostApp": true,
683
683
  "cliPush": true,
684
684
  "agentOpenInYaver": true,
685
685
  "pluginEnabled": false
686
686
  },
687
687
  "react-native-safe-area-context": {
688
- "version": "1.99.410",
688
+ "version": "1.99.416",
689
689
  "hostApp": true,
690
690
  "cliPush": true,
691
691
  "agentOpenInYaver": true,
692
692
  "pluginEnabled": false
693
693
  },
694
694
  "react-native-screens": {
695
- "version": "1.99.410",
695
+ "version": "1.99.416",
696
696
  "hostApp": true,
697
697
  "cliPush": true,
698
698
  "agentOpenInYaver": true,
699
699
  "pluginEnabled": false
700
700
  },
701
701
  "react-native-share": {
702
- "version": "1.99.410",
702
+ "version": "1.99.416",
703
703
  "hostApp": true,
704
704
  "cliPush": true,
705
705
  "agentOpenInYaver": true,
706
706
  "pluginEnabled": false
707
707
  },
708
708
  "react-native-svg": {
709
- "version": "1.99.410",
709
+ "version": "1.99.416",
710
710
  "hostApp": true,
711
711
  "cliPush": true,
712
712
  "agentOpenInYaver": true,
713
713
  "pluginEnabled": false
714
714
  },
715
715
  "react-native-udp": {
716
- "version": "1.99.410",
716
+ "version": "1.99.416",
717
717
  "hostApp": true,
718
718
  "cliPush": true,
719
719
  "agentOpenInYaver": true,
720
720
  "pluginEnabled": false
721
721
  },
722
722
  "react-native-video": {
723
- "version": "1.99.410",
723
+ "version": "1.99.416",
724
724
  "hostApp": true,
725
725
  "cliPush": true,
726
726
  "agentOpenInYaver": true,
727
727
  "pluginEnabled": false
728
728
  },
729
729
  "react-native-view-shot": {
730
- "version": "1.99.410",
730
+ "version": "1.99.416",
731
731
  "hostApp": true,
732
732
  "cliPush": true,
733
733
  "agentOpenInYaver": true,
734
734
  "pluginEnabled": false
735
735
  },
736
736
  "react-native-vision-camera": {
737
- "version": "1.99.410",
737
+ "version": "1.99.416",
738
738
  "hostApp": true,
739
739
  "cliPush": true,
740
740
  "agentOpenInYaver": true,
741
741
  "pluginEnabled": false
742
742
  },
743
743
  "react-native-webview": {
744
- "version": "1.99.410",
744
+ "version": "1.99.416",
745
745
  "hostApp": true,
746
746
  "cliPush": true,
747
747
  "agentOpenInYaver": true,
748
748
  "pluginEnabled": false
749
749
  },
750
750
  "react-native-worklets": {
751
- "version": "1.99.410",
751
+ "version": "1.99.416",
752
752
  "hostApp": true,
753
753
  "cliPush": true,
754
754
  "agentOpenInYaver": true,
755
755
  "pluginEnabled": false
756
756
  },
757
757
  "whisper.rn": {
758
- "version": "1.99.410",
758
+ "version": "1.99.416",
759
759
  "hostApp": true,
760
760
  "cliPush": true,
761
761
  "agentOpenInYaver": true,
@@ -13,7 +13,10 @@ const PACKAGE = require('../package.json');
13
13
  // stale owner ("release lookup failed (403) from kivanccakmak/yaver.io"),
14
14
  // so resolve releases from the canonical path directly.
15
15
  const DEFAULT_REPO = process.env.YAVER_AGENT_REPO || 'yaver-io/yaver.io';
16
- const WINDOWS_REPO = process.env.YAVER_WINDOWS_AGENT_REPO || 'kivanccakmak/yaver-cli';
16
+ // Windows is released beside every other agent build in the canonical repo.
17
+ // The historical yaver-cli repo stopped at v1.37.0; resolving from it made a
18
+ // current npm wrapper silently install a years-old Windows agent.
19
+ const WINDOWS_REPO = process.env.YAVER_WINDOWS_AGENT_REPO || DEFAULT_REPO;
17
20
  const CACHE_ROOT = process.env.YAVER_AGENT_CACHE_DIR || path.join(os.homedir(), '.yaver', 'bin');
18
21
  let resolvedAgentVersionPromise = null;
19
22
  const resolvedAssetPromiseByKey = new Map();
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Optional native desktop companion for the unified npm CLI.
5
+ *
6
+ * The npm package intentionally does not contain Electron itself. `yaver
7
+ * desktop install` downloads the architecture-specific canonical `electron/`
8
+ * release, verifies the release checksum, verifies the OS signature where the
9
+ * host provides one, and installs per-user. The Go agent remains independently
10
+ * usable through the console and an already-running agent is adopted by the
11
+ * GUI instead of duplicated.
12
+ */
13
+
14
+ const crypto = require("node:crypto");
15
+ const fs = require("node:fs");
16
+ const https = require("node:https");
17
+ const os = require("node:os");
18
+ const path = require("node:path");
19
+ const { spawn, spawnSync } = require("node:child_process");
20
+ const { pipeline } = require("node:stream/promises");
21
+
22
+ const DEFAULT_REPO = "yaver-io/yaver.io";
23
+ const WINDOWS_PUBLISHER_PATTERN = "Simkab";
24
+
25
+ const DESKTOP_HELP = `
26
+ yaver desktop — optional native Yaver GUI (the console remains available as \`yaver\`)
27
+
28
+ Commands:
29
+ yaver desktop Open the installed desktop app
30
+ yaver desktop install Download, verify, install per-user, and open
31
+ yaver desktop update Install the latest verified desktop release
32
+ yaver desktop status Show platform, installed path, and release state
33
+ yaver desktop path Print the installed application path
34
+ yaver desktop download [--format] Download a verified installer without running it
35
+
36
+ Options:
37
+ --no-open Install without launching (used by npm bootstrap)
38
+
39
+ Formats:
40
+ macOS: dmg (default)
41
+ Linux: appimage (default), deb, rpm
42
+ Windows: exe (default)
43
+
44
+ The GUI is downloaded as a separately signed, checksum-verified artifact; npm
45
+ does not embed Electron in the CLI tarball. Global installs bootstrap it on an
46
+ interactive desktop unless YAVER_SKIP_POSTINSTALL_DESKTOP=1 is set. Headless
47
+ Linux/CI stays console-only. Runner bootstrap can independently be disabled
48
+ with YAVER_SKIP_POSTINSTALL_RUNNERS=1.
49
+ `;
50
+
51
+ function normalizedArch(arch = process.arch) {
52
+ if (arch === "x64" || arch === "amd64") return "x64";
53
+ if (arch === "arm64" || arch === "aarch64") return "arm64";
54
+ throw new Error(`Yaver Desktop is not published for architecture ${arch}.`);
55
+ }
56
+
57
+ function defaultFormat(platform = process.platform) {
58
+ if (platform === "darwin") return "dmg";
59
+ if (platform === "linux") return "appimage";
60
+ if (platform === "win32") return "exe";
61
+ throw new Error(`Yaver Desktop is not published for platform ${platform}.`);
62
+ }
63
+
64
+ function assetName(version, platform = process.platform, arch = process.arch, format = defaultFormat(platform)) {
65
+ const cpu = normalizedArch(arch);
66
+ const ext = String(format).toLowerCase();
67
+ if (platform === "darwin" && ext === "dmg") return `yaver-gui-${version}-mac-${cpu}.dmg`;
68
+ if (platform === "linux" && ["appimage", "deb", "rpm"].includes(ext)) {
69
+ const suffix = ext === "appimage" ? "AppImage" : ext;
70
+ return `yaver-gui-${version}-linux-${cpu}.${suffix}`;
71
+ }
72
+ if (platform === "win32" && ext === "exe") return `yaver-gui-${version}-win-${cpu}-setup.exe`;
73
+ throw new Error(`Desktop format ${format} is not supported on ${platform}.`);
74
+ }
75
+
76
+ function parseGuiRelease(releases, requestedVersion = "") {
77
+ const rows = Array.isArray(releases) ? releases : [];
78
+ const wanted = String(requestedVersion || "").replace(/^gui\/v/, "").replace(/^v/, "");
79
+ const release = rows.find((row) => {
80
+ if (!row || row.draft || row.prerelease) return false;
81
+ const match = String(row.tag_name || "").match(/^gui\/v(\d+\.\d+\.\d+)$/);
82
+ return match && (!wanted || match[1] === wanted);
83
+ });
84
+ if (!release) throw new Error(wanted ? `No published GUI release exists for ${wanted}.` : "No published GUI release exists.");
85
+ return { ...release, version: String(release.tag_name).slice("gui/v".length) };
86
+ }
87
+
88
+ function checksumFor(text, filename) {
89
+ for (const line of String(text || "").split(/\r?\n/)) {
90
+ const match = line.trim().match(/^([a-fA-F0-9]{64})\s+\*?(.+)$/);
91
+ if (match && match[2] === filename) return match[1].toLowerCase();
92
+ }
93
+ throw new Error(`checksums.txt has no SHA-256 entry for ${filename}.`);
94
+ }
95
+
96
+ function installedDesktopCandidates(platform = process.platform, env = process.env, home = os.homedir()) {
97
+ if (platform === "darwin") {
98
+ return [path.join(home, "Applications", "Yaver.app"), "/Applications/Yaver.app"];
99
+ }
100
+ if (platform === "linux") {
101
+ return [
102
+ path.join(home, ".local", "opt", "yaver", "Yaver.AppImage"),
103
+ "/opt/Yaver/yaver-desktop",
104
+ "/usr/bin/yaver-desktop",
105
+ "/usr/local/bin/yaver-desktop",
106
+ ];
107
+ }
108
+ if (platform === "win32") {
109
+ const local = env.LOCALAPPDATA || path.join(home, "AppData", "Local");
110
+ return [
111
+ path.join(local, "Programs", "Yaver", "Yaver.exe"),
112
+ path.join(local, "Yaver", "Yaver.exe"),
113
+ ];
114
+ }
115
+ return [];
116
+ }
117
+
118
+ function installedDesktopPath(platform = process.platform) {
119
+ return installedDesktopCandidates(platform).find((candidate) => fs.existsSync(candidate)) || "";
120
+ }
121
+
122
+ function request(url, options = {}) {
123
+ return new Promise((resolve, reject) => {
124
+ const req = https.get(url, {
125
+ headers: { "User-Agent": "yaver-cli-desktop", Accept: "application/vnd.github+json", ...(options.headers || {}) },
126
+ }, (response) => {
127
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
128
+ response.resume();
129
+ resolve(request(response.headers.location, options));
130
+ return;
131
+ }
132
+ resolve(response);
133
+ });
134
+ req.setTimeout(30_000, () => req.destroy(new Error(`Desktop release request timed out: ${url}`)));
135
+ req.on("error", reject);
136
+ });
137
+ }
138
+
139
+ async function responseText(response) {
140
+ let body = "";
141
+ response.setEncoding("utf8");
142
+ for await (const chunk of response) body += chunk;
143
+ return body;
144
+ }
145
+
146
+ async function download(url, destination) {
147
+ const response = await request(url, { headers: { Accept: "application/octet-stream" } });
148
+ if (response.statusCode !== 200) {
149
+ const body = await responseText(response);
150
+ throw new Error(`Desktop download failed (HTTP ${response.statusCode}) from ${url}${body ? `: ${body.slice(0, 160)}` : ""}`);
151
+ }
152
+ await pipeline(response, fs.createWriteStream(destination, { mode: 0o700 }));
153
+ }
154
+
155
+ function sha256(file) {
156
+ const hash = crypto.createHash("sha256");
157
+ const fd = fs.openSync(file, "r");
158
+ const buffer = Buffer.allocUnsafe(1024 * 1024);
159
+ try {
160
+ let count = 0;
161
+ while ((count = fs.readSync(fd, buffer, 0, buffer.length, null)) > 0) hash.update(buffer.subarray(0, count));
162
+ } finally {
163
+ fs.closeSync(fd);
164
+ }
165
+ return hash.digest("hex");
166
+ }
167
+
168
+ async function resolveDownload({ platform, arch, format, version = "" }) {
169
+ const repo = process.env.YAVER_DESKTOP_REPO || DEFAULT_REPO;
170
+ const response = await request(`https://api.github.com/repos/${repo}/releases?per_page=100`);
171
+ if (response.statusCode !== 200) throw new Error(`Desktop release lookup failed (HTTP ${response.statusCode}).`);
172
+ const release = parseGuiRelease(JSON.parse(await responseText(response)), version || process.env.YAVER_DESKTOP_VERSION);
173
+ const filename = assetName(release.version, platform, arch, format);
174
+ const assets = new Map((release.assets || []).map((entry) => [entry.name, entry]));
175
+ const artifact = assets.get(filename);
176
+ const checksums = assets.get("checksums.txt");
177
+ if (!artifact) throw new Error(`Release ${release.tag_name} does not contain ${filename}.`);
178
+ if (!checksums) throw new Error(`Release ${release.tag_name} has no checksums.txt; refusing an unverified desktop download.`);
179
+ return { release, artifact, checksums, filename };
180
+ }
181
+
182
+ async function downloadVerified(options) {
183
+ const resolved = await resolveDownload(options);
184
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "yaver-desktop-"));
185
+ const artifactPath = path.join(dir, resolved.filename);
186
+ const checksumsPath = path.join(dir, "checksums.txt");
187
+ try {
188
+ await download(resolved.artifact.browser_download_url, artifactPath);
189
+ await download(resolved.checksums.browser_download_url, checksumsPath);
190
+ const expected = checksumFor(fs.readFileSync(checksumsPath, "utf8"), resolved.filename);
191
+ const actual = sha256(artifactPath);
192
+ if (actual !== expected) throw new Error(`SHA-256 mismatch for ${resolved.filename}: expected ${expected}, downloaded ${actual}.`);
193
+ return { ...resolved, artifactPath, tempDir: dir, sha256: actual };
194
+ } catch (error) {
195
+ fs.rmSync(dir, { recursive: true, force: true });
196
+ throw error;
197
+ }
198
+ }
199
+
200
+ function runChecked(command, args, message) {
201
+ const result = spawnSync(command, args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
202
+ if (result.status !== 0) throw new Error(`${message}: ${(result.stderr || result.stdout || `exit ${result.status}`).trim()}`);
203
+ return result.stdout || result.stderr || "";
204
+ }
205
+
206
+ function verifyMacApp(appPath) {
207
+ runChecked("codesign", ["--verify", "--deep", "--strict", "--verbose=2", appPath], "macOS code-sign verification failed");
208
+ const details = runChecked("codesign", ["-dv", "--verbose=4", appPath], "Could not inspect the macOS signature");
209
+ if (!details.includes("Identifier=io.yaver.gui")) throw new Error("The signed macOS app has an unexpected bundle identifier.");
210
+ runChecked("spctl", ["--assess", "--type", "exec", "--verbose=2", appPath], "macOS Gatekeeper rejected Yaver");
211
+ runChecked("xcrun", ["stapler", "validate", appPath], "The macOS notarization ticket is missing or invalid");
212
+ }
213
+
214
+ function installMac(downloaded) {
215
+ const mount = path.join(downloaded.tempDir, "mount");
216
+ fs.mkdirSync(mount);
217
+ runChecked("hdiutil", ["attach", "-nobrowse", "-readonly", "-mountpoint", mount, downloaded.artifactPath], "Could not mount the Yaver DMG");
218
+ try {
219
+ const source = path.join(mount, "Yaver.app");
220
+ if (!fs.existsSync(source)) throw new Error("The verified DMG does not contain Yaver.app.");
221
+ verifyMacApp(source);
222
+ const applications = path.join(os.homedir(), "Applications");
223
+ fs.mkdirSync(applications, { recursive: true });
224
+ const target = path.join(applications, "Yaver.app");
225
+ const staging = path.join(applications, `.Yaver.app.install-${process.pid}`);
226
+ const backup = path.join(applications, `.Yaver.app.backup-${process.pid}`);
227
+ fs.rmSync(staging, { recursive: true, force: true });
228
+ fs.cpSync(source, staging, { recursive: true, force: false, preserveTimestamps: true });
229
+ verifyMacApp(staging);
230
+ let backedUp = false;
231
+ try {
232
+ if (fs.existsSync(target)) { fs.renameSync(target, backup); backedUp = true; }
233
+ fs.renameSync(staging, target);
234
+ if (backedUp) fs.rmSync(backup, { recursive: true, force: true });
235
+ } catch (error) {
236
+ if (!fs.existsSync(target) && backedUp && fs.existsSync(backup)) fs.renameSync(backup, target);
237
+ throw error;
238
+ } finally {
239
+ fs.rmSync(staging, { recursive: true, force: true });
240
+ }
241
+ return target;
242
+ } finally {
243
+ spawnSync("hdiutil", ["detach", mount], { stdio: "ignore" });
244
+ }
245
+ }
246
+
247
+ function installLinuxAppImage(downloaded) {
248
+ const root = path.join(os.homedir(), ".local", "opt", "yaver");
249
+ const target = path.join(root, "Yaver.AppImage");
250
+ const staging = path.join(root, `.Yaver.AppImage.install-${process.pid}`);
251
+ fs.mkdirSync(root, { recursive: true });
252
+ fs.copyFileSync(downloaded.artifactPath, staging);
253
+ fs.chmodSync(staging, 0o755);
254
+ fs.renameSync(staging, target);
255
+
256
+ const applications = path.join(os.homedir(), ".local", "share", "applications");
257
+ fs.mkdirSync(applications, { recursive: true });
258
+ const execPath = `"${target.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/%/g, "%%")}"`;
259
+ fs.writeFileSync(path.join(applications, "io.yaver.gui.desktop"), [
260
+ "[Desktop Entry]", "Name=Yaver", "Comment=AI development workspace and remote node",
261
+ `Exec=${execPath} %U`, "Terminal=false", "Type=Application", "Categories=Development;Utility;",
262
+ "StartupWMClass=Yaver", "MimeType=x-scheme-handler/yaver;", "",
263
+ ].join("\n"));
264
+
265
+ const binDir = path.join(os.homedir(), ".local", "bin");
266
+ const link = path.join(binDir, "yaver-desktop");
267
+ fs.mkdirSync(binDir, { recursive: true });
268
+ try {
269
+ const stat = fs.lstatSync(link);
270
+ if (!stat.isSymbolicLink()) throw new Error(`${link} already exists and is not a Yaver-managed symlink.`);
271
+ const priorTarget = path.resolve(path.dirname(link), fs.readlinkSync(link));
272
+ if (!priorTarget.startsWith(root + path.sep) && priorTarget !== target) {
273
+ throw new Error(`${link} points outside the Yaver install directory; refusing to replace it.`);
274
+ }
275
+ fs.unlinkSync(link);
276
+ } catch (error) {
277
+ if (error.code !== "ENOENT") throw error;
278
+ }
279
+ fs.symlinkSync(target, link);
280
+ return target;
281
+ }
282
+
283
+ function verifyWindowsInstaller(installer) {
284
+ const escaped = installer.replace(/'/g, "''");
285
+ const script = `$s=Get-AuthenticodeSignature -LiteralPath '${escaped}'; if ($s.Status -ne 'Valid') { throw \"Authenticode status: $($s.Status) $($s.StatusMessage)\" }; if ($s.SignerCertificate.Subject -notmatch '(?i)${WINDOWS_PUBLISHER_PATTERN}') { throw \"Unexpected publisher: $($s.SignerCertificate.Subject)\" }`;
286
+ runChecked("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script], "Windows Authenticode verification failed");
287
+ }
288
+
289
+ function openDesktop(appPath, platform = process.platform) {
290
+ let command;
291
+ let args;
292
+ if (platform === "darwin") { command = "open"; args = [appPath]; }
293
+ else { command = appPath; args = []; }
294
+ const child = spawn(command, args, { detached: true, stdio: "ignore", env: process.env });
295
+ child.once("error", (error) => console.error(`Could not open Yaver Desktop: ${error.message}`));
296
+ child.unref();
297
+ }
298
+
299
+ function parseDesktopArgs(args) {
300
+ const command = !args[0] || args[0].startsWith("-") ? "open" : args[0];
301
+ let format = "";
302
+ let destination = "";
303
+ let noOpen = false;
304
+ for (let i = command === "open" && args[0]?.startsWith("-") ? 0 : 1; i < args.length; i++) {
305
+ if (args[i] === "--format" && args[i + 1]) format = args[++i].toLowerCase();
306
+ else if (args[i] === "--output" && args[i + 1]) destination = args[++i];
307
+ else if (args[i] === "--no-open") noOpen = true;
308
+ }
309
+ return { command, format: format || defaultFormat(), destination, noOpen };
310
+ }
311
+
312
+ async function desktop(args = []) {
313
+ if (args.includes("--help") || args.includes("-h") || args[0] === "help") {
314
+ console.log(DESKTOP_HELP);
315
+ return;
316
+ }
317
+ const options = parseDesktopArgs(args);
318
+ const existing = installedDesktopPath();
319
+ if (options.command === "status") {
320
+ console.log(JSON.stringify({ installed: Boolean(existing), path: existing || null, platform: process.platform, arch: normalizedArch() }, null, 2));
321
+ return;
322
+ }
323
+ if (options.command === "path") {
324
+ if (!existing) throw new Error("Yaver Desktop is not installed. Run `yaver desktop install`.");
325
+ console.log(existing);
326
+ return;
327
+ }
328
+ if (options.command === "open") {
329
+ if (!existing) throw new Error("Yaver Desktop is not installed. Run `yaver desktop install` (the console remains available as `yaver`).");
330
+ openDesktop(existing);
331
+ return;
332
+ }
333
+ if (!["install", "update", "download"].includes(options.command)) throw new Error(`Unknown desktop command: ${options.command}\n${DESKTOP_HELP}`);
334
+
335
+ const downloaded = await downloadVerified({ platform: process.platform, arch: process.arch, format: options.format });
336
+ if (options.command === "download" || (process.platform === "linux" && options.format !== "appimage")) {
337
+ const destination = path.resolve(options.destination || path.join(process.cwd(), downloaded.filename));
338
+ fs.copyFileSync(downloaded.artifactPath, destination);
339
+ fs.rmSync(downloaded.tempDir, { recursive: true, force: true });
340
+ console.log(`Verified ${downloaded.filename} → ${destination}`);
341
+ if (process.platform === "linux" && options.format === "deb") console.log(`Install with: sudo apt-get install ${JSON.stringify(destination)}`);
342
+ if (process.platform === "linux" && options.format === "rpm") console.log(`Install with: sudo dnf install ${JSON.stringify(destination)}`);
343
+ return;
344
+ }
345
+
346
+ let installed = "";
347
+ try {
348
+ if (process.platform === "darwin") installed = installMac(downloaded);
349
+ else if (process.platform === "linux") installed = installLinuxAppImage(downloaded);
350
+ else if (process.platform === "win32") {
351
+ verifyWindowsInstaller(downloaded.artifactPath);
352
+ const child = spawn(downloaded.artifactPath, options.noOpen ? ["/S"] : [], { detached: true, stdio: "ignore" });
353
+ child.once("error", (error) => console.error(`Could not open the verified Yaver installer: ${error.message}`));
354
+ child.unref();
355
+ console.log(options.noOpen
356
+ ? "Verified installer started in per-user silent mode."
357
+ : "Verified installer opened. Complete the per-user installation in the Yaver setup window.");
358
+ return;
359
+ }
360
+ } finally {
361
+ if (process.platform !== "win32") fs.rmSync(downloaded.tempDir, { recursive: true, force: true });
362
+ }
363
+ console.log(`Yaver Desktop ${downloaded.release.version} installed at ${installed}`);
364
+ if (!options.noOpen) openDesktop(installed);
365
+ }
366
+
367
+ module.exports = {
368
+ DESKTOP_HELP,
369
+ assetName,
370
+ checksumFor,
371
+ defaultFormat,
372
+ desktop,
373
+ installedDesktopCandidates,
374
+ normalizedArch,
375
+ parseDesktopArgs,
376
+ parseGuiRelease,
377
+ WINDOWS_PUBLISHER_PATTERN,
378
+ };
package/src/index.js CHANGED
@@ -8,6 +8,7 @@ const { modules } = require('./commands/modules');
8
8
  const { reset } = require('./commands/reset');
9
9
  const { status } = require('./commands/status');
10
10
  const { feedback } = require('./commands/feedback');
11
+ const { desktop } = require('./commands/desktop');
11
12
  const { deploy, isLocalDeployToken } = require('./commands/deploy');
12
13
  const { run, isLocalRunToken } = require('./commands/run');
13
14
  const { maybePromptUpdate } = require('./update-check');
@@ -51,6 +52,12 @@ Coding runner commands (wrapped, with the yaver MCP attached):
51
52
  yaver wrap codex Launch OpenAI Codex here (yolo + yaver MCP)
52
53
  yaver wrap opencode Launch opencode here (yolo + yaver MCP)
53
54
 
55
+ Optional desktop GUI (same account, agent, tasks, and remote-node state):
56
+ yaver desktop Open the installed native GUI
57
+ yaver desktop install Download, verify, and install it per-user
58
+ yaver desktop update Update from the latest verified GUI release
59
+ yaver desktop status Show whether and where the GUI is installed
60
+
54
61
  Push-to-device commands:
55
62
  yaver push Bundle + validate + push current RN/Expo project
56
63
  yaver push ios Discover iOS app in the repo, build IPA, upload to TestFlight
@@ -217,6 +224,11 @@ async function runUnified(args) {
217
224
  return;
218
225
  }
219
226
 
227
+ if (command === 'desktop' || command === 'gui') {
228
+ await desktop(args.slice(1));
229
+ return;
230
+ }
231
+
220
232
  if (command === 'run') {
221
233
  // Local-handle `yaver run dev[:target]`. Anything else (future
222
234
  // Go-agent `run` subcommands) falls through to the agent.
@@ -8,10 +8,12 @@
8
8
 
9
9
  const { ensureAgentBinary, runAgentCommand } = require("./agent-runtime");
10
10
  const { ensureHermesc } = require("./hermesc-runtime");
11
- const { execSync } = require("child_process");
11
+ const { execFileSync, execSync, spawnSync } = require("child_process");
12
12
  const fs = require("fs");
13
13
  const os = require("os");
14
14
  const path = require("path");
15
+ const { desktop, installedDesktopCandidates } = require("./commands/desktop");
16
+ const { codingRunnerBootstrapPlan } = require("./runner-bootstrap-policy");
15
17
 
16
18
  const CODING_RUNNER_BOOTSTRAP = [
17
19
  { command: "claude", pkg: "@anthropic-ai/claude-code", label: "Claude Code" },
@@ -45,18 +47,29 @@ function log(message) {
45
47
  }
46
48
 
47
49
  function commandExists(name) {
48
- try {
49
- execSync(`command -v ${name}`, { stdio: ["ignore", "pipe", "ignore"] });
50
- return true;
51
- } catch (_) {
52
- return false;
53
- }
50
+ const probe = process.platform === "win32"
51
+ ? spawnSync("where.exe", [name], { stdio: "ignore", windowsHide: true })
52
+ : spawnSync("/bin/sh", ["-c", `command -v ${name}`], { stdio: "ignore" });
53
+ return !probe.error && probe.status === 0;
54
54
  }
55
55
 
56
56
  function npmGlobalBinDir() {
57
57
  const prefix = (process.env.npm_config_prefix || "").trim();
58
58
  if (!prefix) return "";
59
- return path.join(prefix, "bin");
59
+ return process.platform === "win32" ? prefix : path.join(prefix, "bin");
60
+ }
61
+
62
+ function installGlobalNpmPackages(packages) {
63
+ const args = ["install", "-g", "--no-fund", "--no-audit", ...packages];
64
+ const npmExecPath = String(process.env.npm_execpath || "").trim();
65
+ if (npmExecPath && /\.[cm]?js$/i.test(npmExecPath)) {
66
+ execFileSync(process.execPath, [npmExecPath, ...args], { stdio: "inherit", windowsHide: true });
67
+ return;
68
+ }
69
+ execFileSync(process.platform === "win32" ? "npm.cmd" : "npm", args, {
70
+ stdio: "inherit",
71
+ windowsHide: true,
72
+ });
60
73
  }
61
74
 
62
75
  function addNpmGlobalBinToProcessPath() {
@@ -69,20 +82,17 @@ function addNpmGlobalBinToProcessPath() {
69
82
  }
70
83
 
71
84
  function installMissingCodingRunners() {
72
- const missing = CODING_RUNNER_BOOTSTRAP.filter((entry) => !commandExists(entry.command));
73
- if (missing.length === 0) {
74
- log("Claude Code, Codex, and OpenCode already exist on PATH.");
85
+ const plan = codingRunnerBootstrapPlan(CODING_RUNNER_BOOTSTRAP, commandExists);
86
+ if (plan.installed.length > 0) {
87
+ const labels = plan.installed.map((entry) => entry.label).join(", ");
88
+ log(`Using existing coding runner${plan.installed.length === 1 ? "" : "s"}: ${labels}. Other runners were not installed.`);
75
89
  return;
76
90
  }
77
91
 
78
- const npmCmd = (process.env.npm_execpath || "npm").trim() || "npm";
79
- const packages = missing.map((entry) => entry.pkg);
80
- const labels = missing.map((entry) => entry.label).join(", ");
92
+ const packages = plan.toInstall.map((entry) => entry.pkg);
93
+ const labels = plan.toInstall.map((entry) => entry.label).join(", ");
81
94
  try {
82
- execSync(
83
- `"${npmCmd}" install -g --no-fund --no-audit ${packages.join(" ")}`,
84
- { stdio: "inherit" },
85
- );
95
+ installGlobalNpmPackages(packages);
86
96
  addNpmGlobalBinToProcessPath();
87
97
  log(`Installed missing coding runners: ${labels}.`);
88
98
  } catch (error) {
@@ -111,6 +121,24 @@ async function setupMCPForInstalledRunners() {
111
121
  }
112
122
  }
113
123
 
124
+ function desktopBootstrapEligible() {
125
+ if (envEnabled("YAVER_SKIP_POSTINSTALL_DESKTOP")) return false;
126
+ if (envEnabled("CI") && !envEnabled("YAVER_FORCE_POSTINSTALL_DESKTOP")) return false;
127
+ if (installedDesktopCandidates().some((candidate) => fs.existsSync(candidate))) return false;
128
+ if (process.platform === "linux") return Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
129
+ return process.platform === "darwin" || process.platform === "win32";
130
+ }
131
+
132
+ async function installDesktopCompanion() {
133
+ if (!desktopBootstrapEligible()) return;
134
+ try {
135
+ await desktop(["install", "--no-open"]);
136
+ log("Installed the verified Yaver Desktop companion (set YAVER_SKIP_POSTINSTALL_DESKTOP=1 to opt out).");
137
+ } catch (error) {
138
+ log(`Skipping desktop companion bootstrap: ${error.message}`);
139
+ }
140
+ }
141
+
114
142
  // ensureLinuxHermescBuildDeps installs the apt packages required to
115
143
  // compile hermesc from facebook/hermes sources on linux/arm64 (no
116
144
  // upstream prebuilt exists for that arch). Best-effort; only runs as
@@ -514,6 +542,18 @@ async function main() {
514
542
  ensureLinuxRunnerSandboxSupport();
515
543
  reportLinuxRunnerSandboxStatus();
516
544
 
545
+ if (process.platform === "win32") {
546
+ // Windows is a first-class Yaver node. The mobile/remote-runtime bootstrap
547
+ // below still has Unix-only recipes, but the three supported coding
548
+ // runners are ordinary npm globals and must not disappear merely because
549
+ // the install came from PowerShell.
550
+ if (!envEnabled("YAVER_SKIP_POSTINSTALL_RUNNERS")) {
551
+ installMissingCodingRunners();
552
+ await setupMCPForInstalledRunners();
553
+ }
554
+ await installDesktopCompanion();
555
+ return;
556
+ }
517
557
  if (process.platform !== "linux" && process.platform !== "darwin") {
518
558
  return;
519
559
  }
@@ -522,6 +562,7 @@ async function main() {
522
562
  installMissingCodingRunners();
523
563
  await setupMCPForInstalledRunners();
524
564
  }
565
+ await installDesktopCompanion();
525
566
  return;
526
567
  }
527
568
 
@@ -550,6 +591,8 @@ async function main() {
550
591
  await setupMCPForInstalledRunners();
551
592
  }
552
593
 
594
+ await installDesktopCompanion();
595
+
553
596
  // Vibe Preview tool stack — best-effort provisioning so a fresh
554
597
  // global npm install gives the user a working chromium-based frame
555
598
  // capture + maestro-driven clip exercises out of the box. Opt out
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * A machine that already has a supported coding runner has made its choice.
5
+ * Yaver should wire that runner, not install competitors beside it. This is
6
+ * especially important for existing OpenCode/BYOK setups: provider and model
7
+ * configuration belong to OpenCode and must remain untouched.
8
+ *
9
+ * Fresh machines retain the existing bootstrap behaviour so the global npm
10
+ * install still produces a usable development node.
11
+ */
12
+ function codingRunnerBootstrapPlan(entries, commandExists) {
13
+ const installed = entries.filter((entry) => commandExists(entry.command));
14
+ return {
15
+ installed,
16
+ toInstall: installed.length > 0 ? [] : entries,
17
+ };
18
+ }
19
+
20
+ module.exports = { codingRunnerBootstrapPlan };