@rightkit/release 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -5
- package/bin/darwin/rightkit-swap +0 -0
- package/bin/rightkit-gate.mjs +4 -4
- package/cli/right-release.mjs +3 -2
- package/deterministic-scans.mjs +21 -10
- package/development.mjs +3 -2
- package/hosted-workflow-policy.mjs +111 -0
- package/ios-dev.mjs +2 -2
- package/ios-host.mjs +7 -7
- package/ios-package-recipe.mjs +2 -2
- package/local-publish.mjs +1 -1
- package/local-qualify.mjs +3 -3
- package/local-runtime.mjs +1 -1
- package/package.json +1 -1
- package/pipeline-admission.mjs +5 -4
- package/pipeline-receipts.mjs +302 -302
- package/pipeline-scan.mjs +3 -3
- package/pipeline-tools.mjs +175 -171
- package/prebuild-gates.mjs +187 -0
- package/progress-control.mjs +1 -1
- package/publish-update.mjs +4 -3
- package/qa-admission-policy.json +5 -0
- package/release-config.mjs +353 -330
- package/release-qa-audit.mjs +37 -11
- package/release-qa-command.mjs +46 -5
- package/release-qa-fixtures.mjs +127 -0
- package/release-qa-floor.json +6 -1
- package/release-qa-hardening.mjs +173 -0
- package/release-qa-policy.mjs +168 -0
- package/release-qa-receipt.mjs +21 -1
- package/release-switch-scan.mjs +137 -6
- package/release.mjs +244 -197
- package/rightapps-register.mjs +3 -1
- package/rightkit-drift.mjs +1 -1
- package/rightkit-ownership.json +15 -5
- package/rightkit-versions.json +43 -32
- package/stage-sidecar.mjs +17 -15
- package/suite-api-literal.mjs +109 -0
- package/suite-api.generated.mjs +78 -0
- package/swap-helper-bundle.mjs +2 -2
- package/win-package-recipe.mjs +7 -4
package/rightkit-drift.mjs
CHANGED
|
@@ -91,7 +91,7 @@ export function applyRightkitAdoption(appRoot, versions = loadRightkitVersions()
|
|
|
91
91
|
for (const file of byFile.keys()) {
|
|
92
92
|
const dir = path.join(appRoot, path.dirname(file));
|
|
93
93
|
if (file.endsWith("package.json")) run("pnpm", ["install", "--lockfile-only", "--ignore-scripts"], dir);
|
|
94
|
-
else run("
|
|
94
|
+
else run("rustright", ["cargo", "metadata", "--format-version", "1", "--manifest-path", path.join(appRoot, file)], dir);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
return drift;
|
package/rightkit-ownership.json
CHANGED
|
@@ -1023,7 +1023,7 @@
|
|
|
1023
1023
|
"fingerprints": [],
|
|
1024
1024
|
"detection": "declaration-only",
|
|
1025
1025
|
"policyNotes": [
|
|
1026
|
-
"Discovery alias so `
|
|
1026
|
+
"Discovery alias so `rustright owns docx` resolves to the document-io owner; carries no fingerprints of its own."
|
|
1027
1027
|
]
|
|
1028
1028
|
},
|
|
1029
1029
|
{
|
|
@@ -1033,7 +1033,7 @@
|
|
|
1033
1033
|
"fingerprints": [],
|
|
1034
1034
|
"detection": "declaration-only",
|
|
1035
1035
|
"policyNotes": [
|
|
1036
|
-
"Discovery alias so `
|
|
1036
|
+
"Discovery alias so `rustright owns xlsx` resolves to the document-io owner; carries no fingerprints of its own."
|
|
1037
1037
|
]
|
|
1038
1038
|
},
|
|
1039
1039
|
{
|
|
@@ -1043,7 +1043,7 @@
|
|
|
1043
1043
|
"fingerprints": [],
|
|
1044
1044
|
"detection": "declaration-only",
|
|
1045
1045
|
"policyNotes": [
|
|
1046
|
-
"Discovery alias so `
|
|
1046
|
+
"Discovery alias so `rustright owns document` resolves to the document-io owner; carries no fingerprints of its own."
|
|
1047
1047
|
]
|
|
1048
1048
|
},
|
|
1049
1049
|
{
|
|
@@ -1053,7 +1053,7 @@
|
|
|
1053
1053
|
"fingerprints": [],
|
|
1054
1054
|
"detection": "declaration-only",
|
|
1055
1055
|
"policyNotes": [
|
|
1056
|
-
"Discovery alias so `
|
|
1056
|
+
"Discovery alias so `rustright owns spreadsheet` resolves to the document-io owner; carries no fingerprints of its own."
|
|
1057
1057
|
]
|
|
1058
1058
|
},
|
|
1059
1059
|
{
|
|
@@ -1661,6 +1661,16 @@
|
|
|
1661
1661
|
"Fingerprints identify review candidates (competing dependencies and distinctive implementation code); published two-host replacement qualification is not recorded."
|
|
1662
1662
|
]
|
|
1663
1663
|
},
|
|
1664
|
+
{
|
|
1665
|
+
"package": "rightkit-license",
|
|
1666
|
+
"capability": "right-suite-api",
|
|
1667
|
+
"summary": "The Right Suite API host and endpoint contract (contracts/right-suite-api.v1.json): canonical API host, updater and release-status paths, per-app artifact hosts. Rust projection rightkit_license::suite_api, TS @rightkit/app-update/suite-api; apps never write the host.",
|
|
1668
|
+
"fingerprints": [],
|
|
1669
|
+
"detection": "declaration-only",
|
|
1670
|
+
"policyNotes": [
|
|
1671
|
+
"Enforcement: the @rightkit/release pre-build gate suite-api-literal ships with this contract and is wired into the build after the app migrations (L1-L5); no ownership fingerprint."
|
|
1672
|
+
]
|
|
1673
|
+
},
|
|
1664
1674
|
{
|
|
1665
1675
|
"package": "rightkit-llm",
|
|
1666
1676
|
"capability": "llm-providers",
|
|
@@ -2469,7 +2479,7 @@
|
|
|
2469
2479
|
"fingerprints": [],
|
|
2470
2480
|
"detection": "declaration-only",
|
|
2471
2481
|
"policyNotes": [
|
|
2472
|
-
"Discovery alias so `
|
|
2482
|
+
"Discovery alias so `rustright owns pdf` resolves to the PDF owner; carries no fingerprints of its own."
|
|
2473
2483
|
]
|
|
2474
2484
|
},
|
|
2475
2485
|
{
|
package/rightkit-versions.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 2,
|
|
3
|
-
"packageManager": "pnpm@11.
|
|
3
|
+
"packageManager": "pnpm@11.25.0",
|
|
4
4
|
"npm": {
|
|
5
5
|
"@rightkit/git": "0.2.0",
|
|
6
6
|
"@rightkit/legal": "0.2.0",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"@rightkit/updates": "0.2.3"
|
|
14
14
|
},
|
|
15
15
|
"stagedNpm": {
|
|
16
|
-
"@rightkit/app-update": "0.4.
|
|
16
|
+
"@rightkit/app-update": "0.4.2",
|
|
17
17
|
"@rightkit/ax": "0.3.2",
|
|
18
18
|
"@rightkit/ci": "0.3.0",
|
|
19
19
|
"@rightkit/doc-render": "0.2.1",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"@rightkit/qa": "0.6.1",
|
|
33
33
|
"@rightkit/qa-chrome": "0.1.11",
|
|
34
34
|
"@rightkit/react-shell": "0.7.2",
|
|
35
|
-
"@rightkit/release": "0.6.
|
|
35
|
+
"@rightkit/release": "0.6.4",
|
|
36
36
|
"@rightkit/settings-ui": "0.7.0",
|
|
37
37
|
"@rightkit/tauri": "0.3.0",
|
|
38
|
-
"@rightkit/tauri-shell": "0.1.
|
|
38
|
+
"@rightkit/tauri-shell": "0.1.3",
|
|
39
39
|
"@rightkit/theme": "0.3.1"
|
|
40
40
|
},
|
|
41
41
|
"legacyNpm": {
|
|
@@ -229,7 +229,8 @@
|
|
|
229
229
|
"0.5.1",
|
|
230
230
|
"0.6.0",
|
|
231
231
|
"0.6.1",
|
|
232
|
-
"0.6.2"
|
|
232
|
+
"0.6.2",
|
|
233
|
+
"0.6.3"
|
|
233
234
|
],
|
|
234
235
|
"@rightkit/qa": [
|
|
235
236
|
"0.1.0",
|
|
@@ -407,14 +408,16 @@
|
|
|
407
408
|
"@rightkit/app-update": [
|
|
408
409
|
"0.2.5",
|
|
409
410
|
"0.3.0",
|
|
410
|
-
"0.4.0"
|
|
411
|
+
"0.4.0",
|
|
412
|
+
"0.4.1"
|
|
411
413
|
],
|
|
412
414
|
"@rightkit/logs": [
|
|
413
415
|
"0.1.4",
|
|
414
416
|
"0.1.5"
|
|
415
417
|
],
|
|
416
418
|
"@rightkit/tauri-shell": [
|
|
417
|
-
"0.1.1"
|
|
419
|
+
"0.1.1",
|
|
420
|
+
"0.1.2"
|
|
418
421
|
]
|
|
419
422
|
},
|
|
420
423
|
"cargo": {
|
|
@@ -441,11 +444,11 @@
|
|
|
441
444
|
"rightkit-app-settings": "0.3.0",
|
|
442
445
|
"rightkit-asr": "0.3.0",
|
|
443
446
|
"rightkit-audio": "0.3.1",
|
|
444
|
-
"rightkit-automation": "0.6.
|
|
447
|
+
"rightkit-automation": "0.6.1",
|
|
445
448
|
"rightkit-browser": "0.3.6",
|
|
446
449
|
"rightkit-cache": "0.2.3",
|
|
447
450
|
"rightkit-channel-memory": "0.2.1",
|
|
448
|
-
"rightkit-child-process": "0.5.
|
|
451
|
+
"rightkit-child-process": "0.5.6",
|
|
449
452
|
"rightkit-compose": "0.2.0",
|
|
450
453
|
"rightkit-contracts": "0.1.7",
|
|
451
454
|
"rightkit-crash": "0.3.6",
|
|
@@ -458,15 +461,15 @@
|
|
|
458
461
|
"rightkit-embed": "0.6.1",
|
|
459
462
|
"rightkit-ffmpeg": "0.2.10",
|
|
460
463
|
"rightkit-file-watch": "0.4.1",
|
|
461
|
-
"rightkit-fs": "0.4.
|
|
464
|
+
"rightkit-fs": "0.4.7",
|
|
462
465
|
"rightkit-fsindex": "0.5.0",
|
|
463
466
|
"rightkit-google-identity": "0.2.0",
|
|
464
467
|
"rightkit-hooks": "0.2.0",
|
|
465
468
|
"rightkit-hotkeys": "0.1.2",
|
|
466
469
|
"rightkit-http": "0.3.8",
|
|
467
470
|
"rightkit-identity": "0.1.0",
|
|
468
|
-
"rightkit-job-queue": "0.5.
|
|
469
|
-
"rightkit-license": "0.2.
|
|
471
|
+
"rightkit-job-queue": "0.5.1",
|
|
472
|
+
"rightkit-license": "0.2.5",
|
|
470
473
|
"rightkit-llm": "0.3.1",
|
|
471
474
|
"rightkit-logs": "0.3.5",
|
|
472
475
|
"rightkit-mcp": "0.7.0",
|
|
@@ -477,11 +480,11 @@
|
|
|
477
480
|
"rightkit-onnx": "0.2.7",
|
|
478
481
|
"rightkit-overlay": "0.2.0",
|
|
479
482
|
"rightkit-overlay-win": "0.1.0",
|
|
480
|
-
"rightkit-ownership": "0.4.
|
|
483
|
+
"rightkit-ownership": "0.4.2",
|
|
481
484
|
"rightkit-pdf": "0.3.3",
|
|
482
485
|
"rightkit-platform-rules": "0.1.0",
|
|
483
486
|
"rightkit-playback": "0.3.0",
|
|
484
|
-
"rightkit-qa": "0.
|
|
487
|
+
"rightkit-qa": "0.9.0",
|
|
485
488
|
"rightkit-qa-driver": "0.7.0",
|
|
486
489
|
"rightkit-record": "0.3.3",
|
|
487
490
|
"rightkit-review": "0.4.0",
|
|
@@ -492,7 +495,7 @@
|
|
|
492
495
|
"rightkit-speech-client": "0.4.0",
|
|
493
496
|
"rightkit-spend": "0.2.0",
|
|
494
497
|
"rightkit-sync": "0.2.2",
|
|
495
|
-
"rightkit-tauri-shell": "0.
|
|
498
|
+
"rightkit-tauri-shell": "0.6.0",
|
|
496
499
|
"rightkit-time": "0.1.0",
|
|
497
500
|
"rightkit-transcript": "0.4.0",
|
|
498
501
|
"rightkit-tts": "0.2.3",
|
|
@@ -524,7 +527,7 @@
|
|
|
524
527
|
"rightkit-app-settings": "0.3.0",
|
|
525
528
|
"rightkit-asr": "0.3.0",
|
|
526
529
|
"rightkit-audio": "0.3.1",
|
|
527
|
-
"rightkit-automation": "0.6.
|
|
530
|
+
"rightkit-automation": "0.6.1",
|
|
528
531
|
"rightkit-browser": "0.3.6",
|
|
529
532
|
"rightkit-cache": "0.2.3",
|
|
530
533
|
"rightkit-channel-memory": "0.2.1",
|
|
@@ -543,16 +546,16 @@
|
|
|
543
546
|
"rightkit-ffmpeg": "0.2.10",
|
|
544
547
|
"rightkit-file-watch": "0.4.1",
|
|
545
548
|
"rightkit-framed-sidecar": "0.2.0",
|
|
546
|
-
"rightkit-fs": "0.4.
|
|
549
|
+
"rightkit-fs": "0.4.7",
|
|
547
550
|
"rightkit-fsindex": "0.5.0",
|
|
548
551
|
"rightkit-google-identity": "0.2.0",
|
|
549
552
|
"rightkit-hooks": "0.2.0",
|
|
550
553
|
"rightkit-hotkeys": "0.1.2",
|
|
551
554
|
"rightkit-http": "0.3.8",
|
|
552
555
|
"rightkit-identity": "0.1.0",
|
|
553
|
-
"rightkit-job-queue": "0.5.
|
|
556
|
+
"rightkit-job-queue": "0.5.1",
|
|
554
557
|
"rightkit-jobs": "0.3.0",
|
|
555
|
-
"rightkit-license": "0.2.
|
|
558
|
+
"rightkit-license": "0.2.5",
|
|
556
559
|
"rightkit-llm": "0.3.1",
|
|
557
560
|
"rightkit-logs": "0.3.5",
|
|
558
561
|
"rightkit-mcp": "0.7.0",
|
|
@@ -565,7 +568,7 @@
|
|
|
565
568
|
"rightkit-ort": "0.2.3",
|
|
566
569
|
"rightkit-overlay": "0.2.0",
|
|
567
570
|
"rightkit-overlay-win": "0.1.0",
|
|
568
|
-
"rightkit-ownership": "0.4.
|
|
571
|
+
"rightkit-ownership": "0.4.2",
|
|
569
572
|
"rightkit-pdf": "0.3.3",
|
|
570
573
|
"rightkit-platform-rules": "0.1.0",
|
|
571
574
|
"rightkit-playback": "0.3.0",
|
|
@@ -589,7 +592,7 @@
|
|
|
589
592
|
"rightkit-spend": "0.2.0",
|
|
590
593
|
"rightkit-sync": "0.2.2",
|
|
591
594
|
"rightkit-tauri": "0.1.3",
|
|
592
|
-
"rightkit-tauri-shell": "0.
|
|
595
|
+
"rightkit-tauri-shell": "0.6.0",
|
|
593
596
|
"rightkit-time": "0.1.0",
|
|
594
597
|
"rightkit-transcript": "0.4.0",
|
|
595
598
|
"rightkit-tts": "0.2.3",
|
|
@@ -603,7 +606,7 @@
|
|
|
603
606
|
},
|
|
604
607
|
"npm": {
|
|
605
608
|
"@rightkit/app-shell": "0.6.2",
|
|
606
|
-
"@rightkit/app-update": "0.4.
|
|
609
|
+
"@rightkit/app-update": "0.4.2",
|
|
607
610
|
"@rightkit/ax": "0.3.2",
|
|
608
611
|
"@rightkit/ci": "0.3.0",
|
|
609
612
|
"@rightkit/doc-render": "0.2.1",
|
|
@@ -623,11 +626,11 @@
|
|
|
623
626
|
"@rightkit/qa": "0.6.1",
|
|
624
627
|
"@rightkit/qa-chrome": "0.1.11",
|
|
625
628
|
"@rightkit/react-shell": "0.7.2",
|
|
626
|
-
"@rightkit/release": "0.6.
|
|
629
|
+
"@rightkit/release": "0.6.3",
|
|
627
630
|
"@rightkit/settings-ui": "0.7.0",
|
|
628
631
|
"@rightkit/shell": "0.1.1",
|
|
629
632
|
"@rightkit/tauri": "0.3.0",
|
|
630
|
-
"@rightkit/tauri-shell": "0.1.
|
|
633
|
+
"@rightkit/tauri-shell": "0.1.3",
|
|
631
634
|
"@rightkit/theme": "0.3.1",
|
|
632
635
|
"@rightkit/updates": "0.2.5"
|
|
633
636
|
}
|
|
@@ -637,7 +640,8 @@
|
|
|
637
640
|
"0.2.0",
|
|
638
641
|
"0.2.1",
|
|
639
642
|
"0.3.1",
|
|
640
|
-
"0.4.0"
|
|
643
|
+
"0.4.0",
|
|
644
|
+
"0.4.1"
|
|
641
645
|
],
|
|
642
646
|
"rightkit-browser": [
|
|
643
647
|
"0.2.0",
|
|
@@ -755,7 +759,8 @@
|
|
|
755
759
|
"0.6.1",
|
|
756
760
|
"0.6.4",
|
|
757
761
|
"0.7.0",
|
|
758
|
-
"0.7.1"
|
|
762
|
+
"0.7.1",
|
|
763
|
+
"0.8.0"
|
|
759
764
|
],
|
|
760
765
|
"rightkit-sandbox": [
|
|
761
766
|
"0.1.0",
|
|
@@ -828,7 +833,8 @@
|
|
|
828
833
|
"0.4.1",
|
|
829
834
|
"0.4.3",
|
|
830
835
|
"0.4.4",
|
|
831
|
-
"0.4.5"
|
|
836
|
+
"0.4.5",
|
|
837
|
+
"0.4.6"
|
|
832
838
|
],
|
|
833
839
|
"rightkit-service": [
|
|
834
840
|
"0.1.0",
|
|
@@ -936,7 +942,8 @@
|
|
|
936
942
|
"0.3.0",
|
|
937
943
|
"0.3.1",
|
|
938
944
|
"0.3.2",
|
|
939
|
-
"0.4.0"
|
|
945
|
+
"0.4.0",
|
|
946
|
+
"0.5.0"
|
|
940
947
|
],
|
|
941
948
|
"rightkit-qa-driver": [
|
|
942
949
|
"0.3.0",
|
|
@@ -958,7 +965,8 @@
|
|
|
958
965
|
"0.4.0",
|
|
959
966
|
"0.4.1",
|
|
960
967
|
"0.4.4",
|
|
961
|
-
"0.5.0"
|
|
968
|
+
"0.5.0",
|
|
969
|
+
"0.6.0"
|
|
962
970
|
],
|
|
963
971
|
"rightkit-child-process": [
|
|
964
972
|
"0.4.0",
|
|
@@ -968,7 +976,8 @@
|
|
|
968
976
|
"0.5.1",
|
|
969
977
|
"0.5.2",
|
|
970
978
|
"0.5.3",
|
|
971
|
-
"0.5.4"
|
|
979
|
+
"0.5.4",
|
|
980
|
+
"0.5.5"
|
|
972
981
|
],
|
|
973
982
|
"rightkit-hotkeys": [
|
|
974
983
|
"0.1.0",
|
|
@@ -1007,7 +1016,8 @@
|
|
|
1007
1016
|
"rightkit-license": [
|
|
1008
1017
|
"0.2.0",
|
|
1009
1018
|
"0.2.2",
|
|
1010
|
-
"0.2.3"
|
|
1019
|
+
"0.2.3",
|
|
1020
|
+
"0.2.4"
|
|
1011
1021
|
],
|
|
1012
1022
|
"rightkit-credentials": [
|
|
1013
1023
|
"0.2.0",
|
|
@@ -1065,7 +1075,8 @@
|
|
|
1065
1075
|
"0.3.2",
|
|
1066
1076
|
"0.3.3",
|
|
1067
1077
|
"0.4.0",
|
|
1068
|
-
"0.5.0"
|
|
1078
|
+
"0.5.0",
|
|
1079
|
+
"0.5.1"
|
|
1069
1080
|
],
|
|
1070
1081
|
"rightkit-android": [
|
|
1071
1082
|
"0.2.0"
|
package/stage-sidecar.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Declarative engine and sidecar staging for Tauri externalBin (bogusyogi/rightkit#345).
|
|
2
2
|
//
|
|
3
|
-
// Eight apps hand-rolled the same script: build an engine through `
|
|
3
|
+
// Eight apps hand-rolled the same script: build an engine through `rustright cargo`, find the executable, copy it to
|
|
4
4
|
// src-tauri/binaries/<name>-<target-triple>[.exe], stage ffmpeg, stage onnxruntime, copy model resources. This module is
|
|
5
5
|
// that script, driven by a `sidecars` list in right-release.config.mjs:
|
|
6
6
|
//
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// then not an externalBin. `clean: true` removes a stale file at the destination before staging. The wrapper key
|
|
20
20
|
// `wipeStageDir: true` removes stale files named exactly `<name>-<current triple>[.exe]` for a declared name this run no longer produces.
|
|
21
21
|
//
|
|
22
|
-
// `catalog` is a relative path, an absolute path, { crate: "rightkit-ffmpeg", file? } (resolved through `
|
|
22
|
+
// `catalog` is a relative path, an absolute path, { crate: "rightkit-ffmpeg", file? } (resolved through `rustright cargo
|
|
23
23
|
// metadata`) or { npm: "<pkg>/<file>" }. The wrapper form { sidecars, profiles: { dev, release } } sets the default cargo
|
|
24
24
|
// profile pair; RIGHTKIT_BUILD_MODE (dev|release, default release) selects. The target `universal-apple-darwin` builds
|
|
25
25
|
// both slices of a cargo-bin and lipo-creates `<name>-universal-apple-darwin`. `ffmpeg` and `onnxruntime` do the same from their
|
|
@@ -122,13 +122,13 @@ export function parseTargetTriple(target) {
|
|
|
122
122
|
return { triple: target, ...row };
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
/** `--target`, then TAURI_ENV_TARGET_TRIPLE, then the host triple from `
|
|
125
|
+
/** `--target`, then TAURI_ENV_TARGET_TRIPLE, then the host triple from `rustright rustc -vV`. */
|
|
126
126
|
export function resolveTargetTriple({ target, env = process.env, run = defaultRun, cwd = process.cwd() } = {}) {
|
|
127
127
|
if (target) return target;
|
|
128
128
|
if (env.TAURI_ENV_TARGET_TRIPLE) return env.TAURI_ENV_TARGET_TRIPLE;
|
|
129
|
-
const result = run("
|
|
129
|
+
const result = run("rustright", ["rustc", "-vV"], { cwd, env });
|
|
130
130
|
const host = result?.stdout?.match(/^host:\s*(.+)$/m)?.[1]?.trim();
|
|
131
|
-
if (!host || result.status !== 0) fail("STAGE_SIDECAR_TARGET_UNKNOWN", "cannot determine the host triple (
|
|
131
|
+
if (!host || result.status !== 0) fail("STAGE_SIDECAR_TARGET_UNKNOWN", "cannot determine the host triple (rustright rustc -vV failed); pass a target");
|
|
132
132
|
return host;
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -354,7 +354,8 @@ export function validateSidecarManifest(raw, { target, mode = "release" } = {})
|
|
|
354
354
|
Object.assign(entry, { package: item.package, bin, name, profile, features: [...features], ...(manifestPath ? { manifestPath } : {}), ...(item.sha256 ? { sha256: item.sha256 } : {}), ...(dest ? { dest } : {}), ...(clean ? { clean } : {}) });
|
|
355
355
|
} else if (item.kind === "ffmpeg") {
|
|
356
356
|
const { kind: _kind, platforms: _platforms, catalog: rawCatalog, sources: rawSources, probe: rawProbe, ...rest } = item;
|
|
357
|
-
if (rest.stage !== undefined && isObject(rest.stage) && rest.stage.cmd === "cargo") errors.push(`${where}: stage.cmd must not be bare cargo; use { cmd: "
|
|
357
|
+
if (rest.stage !== undefined && isObject(rest.stage) && rest.stage.cmd === "cargo") errors.push(`${where}: stage.cmd must not be bare cargo; use { cmd: "rustright", args: ["cargo", ...] }`);
|
|
358
|
+
if (rest.stage !== undefined && isObject(rest.stage) && rest.stage.cmd === "rightkit") errors.push(`${where}: stage.cmd "rightkit" is the retired name of the RustRight client (rustright#91); use { cmd: "rustright", args: ["cargo", ...] }`);
|
|
358
359
|
const catalogSpec = parseCatalogSpec(rawCatalog, `${where}: catalog`, errors, "ffmpeg");
|
|
359
360
|
if (catalogSpec) entry.catalogSpec = catalogSpec;
|
|
360
361
|
if (rawProbe !== undefined && typeof rawProbe !== "boolean") errors.push(`${where}: probe must be a boolean`);
|
|
@@ -513,9 +514,10 @@ function catalogContentDigest(bytes, arch) {
|
|
|
513
514
|
const profileDirectory = (profile) => (profile === "dev" || profile === "test" ? "debug" : profile === "bench" ? "release" : profile);
|
|
514
515
|
const tail = (text, lines = 12) => String(text ?? "").trim().split("\n").slice(-lines).join("\n");
|
|
515
516
|
|
|
516
|
-
/** Default process runner: `
|
|
517
|
+
/** Default process runner: `rustright` resolves through the installed runtime client (its Windows shim is rustright.cmd). */
|
|
517
518
|
export function defaultRun(command, args, { cwd, env = process.env } = {}) {
|
|
518
|
-
|
|
519
|
+
if (command === "rightkit") throw new Error("`rightkit` is the retired name of the RustRight client (rustright#91); use rustright (stage: { cmd: \"rustright\" })");
|
|
520
|
+
const launch = command === "rustright" ? resolveCommand(command, args, { root: cwd, env }) : { command, args };
|
|
519
521
|
return nodeSpawnSync(launch.command, launch.args, {
|
|
520
522
|
cwd, env: { ...env, ...(launch.env ?? {}) }, encoding: "utf8", maxBuffer: 512 * 1024 * 1024, shell: false, windowsHide: true, stdio: ["inherit", "pipe", "inherit"],
|
|
521
523
|
});
|
|
@@ -561,7 +563,7 @@ function resolveCatalogFile(spec, ctx, kind) {
|
|
|
561
563
|
if (spec.via === "absolute") return spec.file;
|
|
562
564
|
if (spec.via === "path") return path.resolve(ctx.appRoot, spec.file);
|
|
563
565
|
if (spec.via === "crate") {
|
|
564
|
-
const meta = ctx.run("
|
|
566
|
+
const meta = ctx.run("rustright", ["cargo", "metadata", "--format-version", "1"], { cwd: ctx.appRoot, env: ctx.env });
|
|
565
567
|
let packages;
|
|
566
568
|
try { packages = JSON.parse(meta.stdout).packages; } catch { /* refused below */ }
|
|
567
569
|
if (meta?.status !== 0 || !Array.isArray(packages)) fail("STAGE_SIDECAR_CATALOG_UNREADABLE", `the ${label} catalog crate ${spec.crate} cannot be located: the workspace metadata query failed`, { crate: spec.crate });
|
|
@@ -737,18 +739,18 @@ function stageCargoSlice(entry, ctx, triple, { dest }) {
|
|
|
737
739
|
return [{ kind: "cargo-bin", name: entry.name, path: rel(ctx, dest), ...copied, sourceSha256, package: entry.package, bin: entry.bin, profile: entry.profile, features: entry.features, externalBin: !entry.dest }];
|
|
738
740
|
}
|
|
739
741
|
|
|
740
|
-
/** Build one slice through `
|
|
742
|
+
/** Build one slice through `rustright cargo` and locate the executable. Returns { source, sourceSha256 }. */
|
|
741
743
|
function stageCargoBuild(entry, ctx, triple) {
|
|
742
744
|
const { run, appRoot, env, fs } = ctx;
|
|
743
745
|
const args = ["cargo", "build", "--locked", ...(entry.manifestPath ? ["--manifest-path", path.resolve(appRoot, entry.manifestPath)] : []),
|
|
744
746
|
"-p", entry.package, "--bin", entry.bin, "--target", triple, "--profile", entry.profile,
|
|
745
747
|
...(entry.features.length ? ["--features", entry.features.join(",")] : []), "--message-format=json-render-diagnostics"];
|
|
746
748
|
ctx.log(`stage-sidecar: rightkit ${args.join(" ")}`);
|
|
747
|
-
const built = run("
|
|
748
|
-
if (built?.error || built?.status !== 0) fail("STAGE_SIDECAR_BUILD_FAILED", `
|
|
749
|
+
const built = run("rustright", args, { cwd: appRoot, env });
|
|
750
|
+
if (built?.error || built?.status !== 0) fail("STAGE_SIDECAR_BUILD_FAILED", `rustright cargo build of ${entry.package} failed (${built?.error?.message ?? `exit ${built?.status}`})`, { package: entry.package, stderr: tail(built?.stderr) });
|
|
749
751
|
let source = artifactFromStream(built.stdout, entry.bin);
|
|
750
752
|
if (!source || !fs.existsSync(source)) {
|
|
751
|
-
const meta = run("
|
|
753
|
+
const meta = run("rustright", ["cargo", "metadata", "--format-version", "1", "--no-deps", ...(entry.manifestPath ? ["--manifest-path", path.resolve(appRoot, entry.manifestPath)] : [])], { cwd: appRoot, env });
|
|
752
754
|
let targetDir;
|
|
753
755
|
try { targetDir = JSON.parse(meta.stdout).target_directory; } catch { /* refused below */ }
|
|
754
756
|
if (meta?.status !== 0 || typeof targetDir !== "string" || !path.isAbsolute(targetDir)) targetDir = undefined;
|
|
@@ -1378,12 +1380,12 @@ export function isNestedBrokerContext(env = process.env) {
|
|
|
1378
1380
|
return insideTauri && (managedHost(env ?? {}) || env?.RIGHTSUITE_HEAVY_WORK_OWNER === "1");
|
|
1379
1381
|
}
|
|
1380
1382
|
|
|
1381
|
-
/** True when staging would call `
|
|
1383
|
+
/** True when staging would call `rustright cargo` for a non-skipped entry. */
|
|
1382
1384
|
const needsBroker = (plan) => plan.entries.some((entry) => !entry.skipped && (entry.kind === "cargo-bin" || entry.catalogSpec?.via === "crate"));
|
|
1383
1385
|
|
|
1384
1386
|
function assertNotNested(plan, env) {
|
|
1385
1387
|
if (needsBroker(plan) && isNestedBrokerContext(env)) {
|
|
1386
|
-
fail(NESTED_BROKER_CODE, "stage-sidecar needs `
|
|
1388
|
+
fail(NESTED_BROKER_CODE, "stage-sidecar needs `rustright cargo`, but it is running inside an outer broker build (a Tauri beforeBuildCommand/beforeDevCommand on a managed host), where a nested broker call exits 125. Run stage-sidecar in the recipe `prepare` step, before the Tauri build (or call it from your own script before `tauri build`), not from beforeBuildCommand.");
|
|
1387
1389
|
}
|
|
1388
1390
|
}
|
|
1389
1391
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Pre-build gate `suite-api-literal`: an app must not carry a Right Suite API host literal. The owner (RightKit) supplies
|
|
2
|
+
// the host, the updater endpoint and the artifact allowlists through @rightkit/app-update/suite-api and the native shell.
|
|
3
|
+
// Source of truth: contracts/right-suite-api.v1.json, read here through its generated projection.
|
|
4
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { spawnSync } from "./background-process.mjs";
|
|
7
|
+
import {
|
|
8
|
+
RIGHT_SUITE_API_CONTRACT,
|
|
9
|
+
RIGHT_SUITE_API_HOST,
|
|
10
|
+
RIGHT_SUITE_API_ORIGIN,
|
|
11
|
+
RIGHT_SUITE_GATED_ARTIFACT_HOST,
|
|
12
|
+
RIGHT_SUITE_LEGACY_HOSTS,
|
|
13
|
+
RIGHT_SUITE_PUBLIC_ARTIFACT_HOST,
|
|
14
|
+
RIGHT_SUITE_UPDATER_MANIFEST_PATH,
|
|
15
|
+
} from "./suite-api.generated.mjs";
|
|
16
|
+
|
|
17
|
+
/** Every host the contract names: the API host, its legacy hosts, and both artifact hosts. */
|
|
18
|
+
export const SUITE_API_CONTRACT_HOSTS = Object.freeze([
|
|
19
|
+
RIGHT_SUITE_API_HOST,
|
|
20
|
+
...RIGHT_SUITE_LEGACY_HOSTS,
|
|
21
|
+
RIGHT_SUITE_GATED_ARTIFACT_HOST,
|
|
22
|
+
RIGHT_SUITE_PUBLIC_ARTIFACT_HOST,
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
26
|
+
// A host literal is refused as a whole name: a neighbouring label or hyphen does not make a different host.
|
|
27
|
+
const HOST_PATTERNS = SUITE_API_CONTRACT_HOSTS.map((host) => ({
|
|
28
|
+
host,
|
|
29
|
+
pattern: new RegExp(`(?<![A-Za-z0-9-])${escapeRegExp(host)}(?![A-Za-z0-9-])`, "giu"),
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
/** The one updater endpoint a pending app may keep in its tauri conf (contract pendingNativeUpdater). */
|
|
33
|
+
export function pendingUpdaterEndpoint(appKey) {
|
|
34
|
+
return `${RIGHT_SUITE_API_ORIGIN}${RIGHT_SUITE_UPDATER_MANIFEST_PATH.split("{app}").join(appKey)}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function trackedFiles(root) {
|
|
38
|
+
const result = spawnSync("git", ["ls-files", "-z"], { cwd: root, encoding: "utf8", windowsHide: true });
|
|
39
|
+
if (result.status !== 0) throw new Error(`suite-api-literal: cannot list tracked files under ${root}: ${(result.stderr ?? "").trim()}`);
|
|
40
|
+
return result.stdout.split("\0").filter(Boolean).map((file) => file.split(path.sep).join("/"));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const isExcluded = (file) => /\.md$/iu.test(file) || file === "docs" || file.startsWith("docs/");
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Scan the app's tracked, non-Markdown files for Right Suite API host literals.
|
|
47
|
+
* `appKey` is the app's identity (right-release config `app`). Returns findings `{ file, line, host, kind, detail }`;
|
|
48
|
+
* `file` is relative to `root` with forward slashes. Empty array means the app carries no literal.
|
|
49
|
+
*
|
|
50
|
+
* Refused: (a) any contract host in any tracked file; (b) `plugins.updater.endpoints` in a `tauri*.conf.json` of an app the
|
|
51
|
+
* contract lists under `apps`; (c) a host in a Tauri capability JSON scope (`capabilities/*.json`).
|
|
52
|
+
* Exception: for an app in `pendingNativeUpdater`, its conf may keep `plugins.updater.endpoints` when that array is exactly
|
|
53
|
+
* the one contract updater endpoint for the app. Only that exact string is exempt from the host scan.
|
|
54
|
+
*/
|
|
55
|
+
export function suiteApiLiteralFindings({ root, appKey, contract = RIGHT_SUITE_API_CONTRACT }) {
|
|
56
|
+
const findings = [];
|
|
57
|
+
const inContract = typeof appKey === "string" && Object.hasOwn(contract.apps ?? {}, appKey);
|
|
58
|
+
const pending = typeof appKey === "string" && (contract.pendingNativeUpdater ?? []).includes(appKey);
|
|
59
|
+
const allowedEndpoint = typeof appKey === "string" ? pendingUpdaterEndpoint(appKey) : null;
|
|
60
|
+
|
|
61
|
+
for (const file of trackedFiles(root)) {
|
|
62
|
+
if (isExcluded(file)) continue;
|
|
63
|
+
const absolute = path.join(root, file);
|
|
64
|
+
if (!existsSync(absolute) || !statSync(absolute).isFile()) continue;
|
|
65
|
+
const buffer = readFileSync(absolute);
|
|
66
|
+
if (buffer.includes(0)) continue;
|
|
67
|
+
let text = buffer.toString("utf8");
|
|
68
|
+
const base = path.posix.basename(file);
|
|
69
|
+
const isTauriConf = /^tauri.*\.conf\.json$/iu.test(base);
|
|
70
|
+
const isCapability = /(^|\/)capabilities\/[^/]+\.json$/iu.test(file);
|
|
71
|
+
|
|
72
|
+
if (isTauriConf && inContract && text.includes("endpoints")) {
|
|
73
|
+
let endpoints;
|
|
74
|
+
let parsed = true;
|
|
75
|
+
try { endpoints = JSON.parse(text)?.plugins?.updater?.endpoints; } catch { parsed = false; }
|
|
76
|
+
if (!parsed) {
|
|
77
|
+
findings.push({ file, line: 1, host: "(unparseable)", kind: "updater-endpoints", detail: "tauri conf cannot be parsed, so its updater endpoints cannot be verified" });
|
|
78
|
+
} else if (endpoints !== undefined) {
|
|
79
|
+
const exact = pending && Array.isArray(endpoints) && endpoints.length === 1 && endpoints[0] === allowedEndpoint;
|
|
80
|
+
if (exact) {
|
|
81
|
+
// Remove only the exact contract string; line count is unchanged because the string has no newline.
|
|
82
|
+
text = text.split(allowedEndpoint).join("");
|
|
83
|
+
} else {
|
|
84
|
+
const line = text.split("\n").findIndex((candidate) => candidate.includes("endpoints")) + 1 || 1;
|
|
85
|
+
findings.push({ file, line, host: "plugins.updater.endpoints", kind: "updater-endpoints", detail: "updater endpoints must be absent; the shell supplies the endpoint from @rightkit/app-update/suite-api" });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const lines = text.split("\n");
|
|
91
|
+
lines.forEach((content, index) => {
|
|
92
|
+
for (const { host, pattern } of HOST_PATTERNS) {
|
|
93
|
+
pattern.lastIndex = 0;
|
|
94
|
+
if (!pattern.test(content)) continue;
|
|
95
|
+
pattern.lastIndex = 0;
|
|
96
|
+
const kind = isCapability && file.endsWith(".json") ? "capability-scope" : "host-literal";
|
|
97
|
+
findings.push({ file, line: index + 1, host, kind, detail: kind === "capability-scope" ? "capability scope names a Right Suite API host" : "Right Suite API host literal" });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return findings;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The gate's refusal text: one line per finding, `file:line` and the host, so the author can fix each site. */
|
|
105
|
+
export function suiteApiLiteralDetail(appKey, findings) {
|
|
106
|
+
return `${appKey ?? "app"} carries Right Suite API host literals (contract right-suite-api.v1); use @rightkit/app-update/suite-api or the native update host:\n${findings
|
|
107
|
+
.map((finding) => `- ${finding.file}:${finding.line}: ${finding.host} (${finding.kind})`)
|
|
108
|
+
.join("\n")}`;
|
|
109
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// GENERATED by scripts/gen-suite-api.mjs from contracts/right-suite-api.v1.json; do not edit.
|
|
2
|
+
// Right Suite API host constants (contract right-suite-api.v1) for @rightkit/release.
|
|
3
|
+
|
|
4
|
+
export const RIGHT_SUITE_API_HOST = "api.orthiclabs.com";
|
|
5
|
+
export const RIGHT_SUITE_API_ORIGIN = "https://api.orthiclabs.com";
|
|
6
|
+
export const RIGHT_SUITE_LEGACY_HOSTS = ["api.spoares.com"];
|
|
7
|
+
export const RIGHT_SUITE_UPDATER_MANIFEST_PATH = "/v1/apps/{app}/releases/latest.json?platform={{target}}";
|
|
8
|
+
export const RIGHT_SUITE_RELEASE_STATUS_PATH = "/v1/apps/{app}/releases/status.json";
|
|
9
|
+
export const RIGHT_SUITE_ADMIN_PATCHES_PATH = "/v1/admin/apps/patches";
|
|
10
|
+
export const RIGHT_SUITE_ADMIN_RELEASES_PATH = "/v1/admin/apps/releases";
|
|
11
|
+
export const RIGHT_SUITE_ADMIN_RUNTIME_ARTIFACTS_PATH = "/v1/admin/apps/runtime-artifacts";
|
|
12
|
+
export const RIGHT_SUITE_GATED_ARTIFACT_HOST = "rightapps-license-gate.adrdsouza.workers.dev";
|
|
13
|
+
export const RIGHT_SUITE_PUBLIC_ARTIFACT_HOST = "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev";
|
|
14
|
+
export const RIGHT_SUITE_PUBLIC_INSTALLER_BASE = "https://pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev";
|
|
15
|
+
export const RIGHT_SUITE_ARTIFACT_PATH_PREFIX = "/{app}";
|
|
16
|
+
export const APP_ARTIFACT_HOSTS = {
|
|
17
|
+
"coderight": [
|
|
18
|
+
"rightapps-license-gate.adrdsouza.workers.dev",
|
|
19
|
+
"pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
|
|
20
|
+
],
|
|
21
|
+
"heardright": [
|
|
22
|
+
"rightapps-license-gate.adrdsouza.workers.dev",
|
|
23
|
+
"pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
|
|
24
|
+
],
|
|
25
|
+
"mailright": [
|
|
26
|
+
"rightapps-license-gate.adrdsouza.workers.dev",
|
|
27
|
+
"pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
|
|
28
|
+
],
|
|
29
|
+
"viewright": [
|
|
30
|
+
"pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
|
|
31
|
+
]
|
|
32
|
+
};
|
|
33
|
+
export const RIGHT_SUITE_API_CONTRACT = {
|
|
34
|
+
"apps": {
|
|
35
|
+
"coderight": {
|
|
36
|
+
"artifactHosts": [
|
|
37
|
+
"gated",
|
|
38
|
+
"public"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"heardright": {
|
|
42
|
+
"artifactHosts": [
|
|
43
|
+
"gated",
|
|
44
|
+
"public"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"mailright": {
|
|
48
|
+
"artifactHosts": [
|
|
49
|
+
"gated",
|
|
50
|
+
"public"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"viewright": {
|
|
54
|
+
"artifactHosts": [
|
|
55
|
+
"public"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"artifactHostSets": {
|
|
60
|
+
"gated": "rightapps-license-gate.adrdsouza.workers.dev",
|
|
61
|
+
"public": "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
|
|
62
|
+
},
|
|
63
|
+
"artifactPathPrefix": "/{app}",
|
|
64
|
+
"host": "api.orthiclabs.com",
|
|
65
|
+
"origin": "https://api.orthiclabs.com",
|
|
66
|
+
"paths": {
|
|
67
|
+
"adminPatches": "/v1/admin/apps/patches",
|
|
68
|
+
"adminReleases": "/v1/admin/apps/releases",
|
|
69
|
+
"adminRuntimeArtifacts": "/v1/admin/apps/runtime-artifacts",
|
|
70
|
+
"releaseStatus": "/v1/apps/{app}/releases/status.json",
|
|
71
|
+
"updaterManifest": "/v1/apps/{app}/releases/latest.json?platform={{target}}"
|
|
72
|
+
},
|
|
73
|
+
"pendingNativeUpdater": [
|
|
74
|
+
"heardright"
|
|
75
|
+
],
|
|
76
|
+
"publicInstallerBase": "https://pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev",
|
|
77
|
+
"schema": "right-suite-api.v1"
|
|
78
|
+
};
|
package/swap-helper-bundle.mjs
CHANGED
|
@@ -37,7 +37,7 @@ export function isSwapHelperSigned(file, { execFileSync = nodeExecFileSync } = {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Local-pack step. darwin: build through the managed cargo wrapper (`run("cargo", ...)` is `
|
|
40
|
+
* Local-pack step. darwin: build through the managed cargo wrapper (`run("cargo", ...)` is `rustright cargo` in
|
|
41
41
|
* local-publish), copy to <packageDir>/bin/darwin/rightkit-swap, Developer ID sign with the shared identity
|
|
42
42
|
* resolver and `macCodesignArgs` (--options runtime --timestamp), verify strictly, write a sha256 receipt.
|
|
43
43
|
* Anywhere else: refuse unless the helper is present and its receipt matches its bytes. Fails closed with SwapHelperError.
|
|
@@ -66,7 +66,7 @@ export function prepareSwapHelper({
|
|
|
66
66
|
}
|
|
67
67
|
const fail = (code, message) => { throw new SwapHelperError(code, message); };
|
|
68
68
|
const built = run("cargo", SWAP_HELPER_CARGO_ARGS, { cwd: workspaceRoot, env });
|
|
69
|
-
if (built.error || built.status !== 0) fail("SWAP_HELPER_BUILD_FAILED", `
|
|
69
|
+
if (built.error || built.status !== 0) fail("SWAP_HELPER_BUILD_FAILED", `rustright cargo ${SWAP_HELPER_CARGO_ARGS.join(" ")} failed (${built.error?.message ?? `exit ${built.status}`})\n${tail(`${built.stdout ?? ""}\n${built.stderr ?? ""}`)}`);
|
|
70
70
|
const meta = run("cargo", ["metadata", "--format-version", "1", "--no-deps"], { cwd: workspaceRoot, env });
|
|
71
71
|
let targetDir;
|
|
72
72
|
try { targetDir = JSON.parse(meta.stdout).target_directory; } catch { /* refused below */ }
|