@rightkit/release 0.6.2 → 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.
Files changed (44) hide show
  1. package/README.md +37 -5
  2. package/bin/darwin/rightkit-swap +0 -0
  3. package/bin/rightkit-gate.mjs +4 -4
  4. package/build-release.mjs +2 -2
  5. package/cli/right-release.mjs +3 -2
  6. package/deterministic-scans.mjs +21 -10
  7. package/development.mjs +3 -2
  8. package/hosted-workflow-policy.mjs +111 -0
  9. package/ios-dev.mjs +2 -2
  10. package/ios-host.mjs +7 -7
  11. package/ios-package-recipe.mjs +2 -2
  12. package/local-publish.mjs +1 -1
  13. package/local-qualify.mjs +3 -3
  14. package/local-runtime.mjs +1 -1
  15. package/ownership-scope.mjs +9 -0
  16. package/package.json +1 -1
  17. package/pipeline-admission.mjs +5 -4
  18. package/pipeline-receipts.mjs +302 -302
  19. package/pipeline-scan.mjs +3 -3
  20. package/pipeline-tools.mjs +175 -171
  21. package/prebuild-gates.mjs +187 -0
  22. package/preflight.mjs +5 -1
  23. package/progress-control.mjs +1 -1
  24. package/publish-update.mjs +4 -3
  25. package/qa-admission-policy.json +5 -0
  26. package/release-config.mjs +353 -330
  27. package/release-qa-audit.mjs +37 -11
  28. package/release-qa-command.mjs +46 -5
  29. package/release-qa-fixtures.mjs +127 -0
  30. package/release-qa-floor.json +6 -1
  31. package/release-qa-hardening.mjs +173 -0
  32. package/release-qa-policy.mjs +168 -0
  33. package/release-qa-receipt.mjs +21 -1
  34. package/release-switch-scan.mjs +137 -6
  35. package/release.mjs +256 -198
  36. package/rightapps-register.mjs +3 -1
  37. package/rightkit-drift.mjs +1 -1
  38. package/rightkit-ownership.json +15 -5
  39. package/rightkit-versions.json +52 -38
  40. package/stage-sidecar.mjs +17 -15
  41. package/suite-api-literal.mjs +109 -0
  42. package/suite-api.generated.mjs +78 -0
  43. package/swap-helper-bundle.mjs +2 -2
  44. package/win-package-recipe.mjs +7 -4
@@ -1,4 +1,6 @@
1
- const DEFAULT_API_BASE = "https://api.spoares.com";
1
+ import { RIGHT_SUITE_API_ORIGIN } from "./suite-api.generated.mjs";
2
+
3
+ const DEFAULT_API_BASE = RIGHT_SUITE_API_ORIGIN;
2
4
  const REGISTRATION_ROUTES = new Set([
3
5
  "/v1/admin/apps/patches",
4
6
  "/v1/admin/apps/releases",
@@ -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("rightkit", ["cargo", "metadata", "--format-version", "1", "--manifest-path", path.join(appRoot, file)], dir);
94
+ else run("rustright", ["cargo", "metadata", "--format-version", "1", "--manifest-path", path.join(appRoot, file)], dir);
95
95
  }
96
96
  }
97
97
  return drift;
@@ -1023,7 +1023,7 @@
1023
1023
  "fingerprints": [],
1024
1024
  "detection": "declaration-only",
1025
1025
  "policyNotes": [
1026
- "Discovery alias so `rightkit owns docx` resolves to the document-io owner; carries no fingerprints of its own."
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 `rightkit owns xlsx` resolves to the document-io owner; carries no fingerprints of its own."
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 `rightkit owns document` resolves to the document-io owner; carries no fingerprints of its own."
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 `rightkit owns spreadsheet` resolves to the document-io owner; carries no fingerprints of its own."
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 `rightkit owns pdf` resolves to the PDF owner; carries no fingerprints of its own."
2482
+ "Discovery alias so `rustright owns pdf` resolves to the PDF owner; carries no fingerprints of its own."
2473
2483
  ]
2474
2484
  },
2475
2485
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": 2,
3
- "packageManager": "pnpm@11.24.0",
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.1",
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.2",
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.2",
38
+ "@rightkit/tauri-shell": "0.1.3",
39
39
  "@rightkit/theme": "0.3.1"
40
40
  },
41
41
  "legacyNpm": {
@@ -228,7 +228,9 @@
228
228
  "0.5.0",
229
229
  "0.5.1",
230
230
  "0.6.0",
231
- "0.6.1"
231
+ "0.6.1",
232
+ "0.6.2",
233
+ "0.6.3"
232
234
  ],
233
235
  "@rightkit/qa": [
234
236
  "0.1.0",
@@ -406,14 +408,16 @@
406
408
  "@rightkit/app-update": [
407
409
  "0.2.5",
408
410
  "0.3.0",
409
- "0.4.0"
411
+ "0.4.0",
412
+ "0.4.1"
410
413
  ],
411
414
  "@rightkit/logs": [
412
415
  "0.1.4",
413
416
  "0.1.5"
414
417
  ],
415
418
  "@rightkit/tauri-shell": [
416
- "0.1.1"
419
+ "0.1.1",
420
+ "0.1.2"
417
421
  ]
418
422
  },
419
423
  "cargo": {
@@ -440,32 +444,32 @@
440
444
  "rightkit-app-settings": "0.3.0",
441
445
  "rightkit-asr": "0.3.0",
442
446
  "rightkit-audio": "0.3.1",
443
- "rightkit-automation": "0.6.0",
444
- "rightkit-browser": "0.3.5",
447
+ "rightkit-automation": "0.6.1",
448
+ "rightkit-browser": "0.3.6",
445
449
  "rightkit-cache": "0.2.3",
446
450
  "rightkit-channel-memory": "0.2.1",
447
- "rightkit-child-process": "0.5.5",
451
+ "rightkit-child-process": "0.5.6",
448
452
  "rightkit-compose": "0.2.0",
449
453
  "rightkit-contracts": "0.1.7",
450
454
  "rightkit-crash": "0.3.6",
451
455
  "rightkit-credentials": "0.4.2",
452
456
  "rightkit-crypto": "0.1.0",
453
457
  "rightkit-daemon": "0.4.0",
454
- "rightkit-db": "0.5.1",
458
+ "rightkit-db": "0.5.2",
455
459
  "rightkit-device": "0.4.0",
456
460
  "rightkit-docs": "0.1.2",
457
461
  "rightkit-embed": "0.6.1",
458
462
  "rightkit-ffmpeg": "0.2.10",
459
463
  "rightkit-file-watch": "0.4.1",
460
- "rightkit-fs": "0.4.6",
464
+ "rightkit-fs": "0.4.7",
461
465
  "rightkit-fsindex": "0.5.0",
462
466
  "rightkit-google-identity": "0.2.0",
463
467
  "rightkit-hooks": "0.2.0",
464
468
  "rightkit-hotkeys": "0.1.2",
465
469
  "rightkit-http": "0.3.8",
466
470
  "rightkit-identity": "0.1.0",
467
- "rightkit-job-queue": "0.5.0",
468
- "rightkit-license": "0.2.4",
471
+ "rightkit-job-queue": "0.5.1",
472
+ "rightkit-license": "0.2.5",
469
473
  "rightkit-llm": "0.3.1",
470
474
  "rightkit-logs": "0.3.5",
471
475
  "rightkit-mcp": "0.7.0",
@@ -476,11 +480,11 @@
476
480
  "rightkit-onnx": "0.2.7",
477
481
  "rightkit-overlay": "0.2.0",
478
482
  "rightkit-overlay-win": "0.1.0",
479
- "rightkit-ownership": "0.4.1",
483
+ "rightkit-ownership": "0.4.2",
480
484
  "rightkit-pdf": "0.3.3",
481
485
  "rightkit-platform-rules": "0.1.0",
482
486
  "rightkit-playback": "0.3.0",
483
- "rightkit-qa": "0.8.0",
487
+ "rightkit-qa": "0.9.0",
484
488
  "rightkit-qa-driver": "0.7.0",
485
489
  "rightkit-record": "0.3.3",
486
490
  "rightkit-review": "0.4.0",
@@ -491,7 +495,7 @@
491
495
  "rightkit-speech-client": "0.4.0",
492
496
  "rightkit-spend": "0.2.0",
493
497
  "rightkit-sync": "0.2.2",
494
- "rightkit-tauri-shell": "0.5.1",
498
+ "rightkit-tauri-shell": "0.6.0",
495
499
  "rightkit-time": "0.1.0",
496
500
  "rightkit-transcript": "0.4.0",
497
501
  "rightkit-tts": "0.2.3",
@@ -523,8 +527,8 @@
523
527
  "rightkit-app-settings": "0.3.0",
524
528
  "rightkit-asr": "0.3.0",
525
529
  "rightkit-audio": "0.3.1",
526
- "rightkit-automation": "0.6.0",
527
- "rightkit-browser": "0.3.5",
530
+ "rightkit-automation": "0.6.1",
531
+ "rightkit-browser": "0.3.6",
528
532
  "rightkit-cache": "0.2.3",
529
533
  "rightkit-channel-memory": "0.2.1",
530
534
  "rightkit-child-process": "0.5.5",
@@ -535,23 +539,23 @@
535
539
  "rightkit-credentials": "0.4.2",
536
540
  "rightkit-crypto": "0.1.0",
537
541
  "rightkit-daemon": "0.4.0",
538
- "rightkit-db": "0.5.1",
542
+ "rightkit-db": "0.5.2",
539
543
  "rightkit-device": "0.4.0",
540
544
  "rightkit-docs": "0.1.2",
541
545
  "rightkit-embed": "0.6.1",
542
546
  "rightkit-ffmpeg": "0.2.10",
543
547
  "rightkit-file-watch": "0.4.1",
544
548
  "rightkit-framed-sidecar": "0.2.0",
545
- "rightkit-fs": "0.4.6",
549
+ "rightkit-fs": "0.4.7",
546
550
  "rightkit-fsindex": "0.5.0",
547
551
  "rightkit-google-identity": "0.2.0",
548
552
  "rightkit-hooks": "0.2.0",
549
553
  "rightkit-hotkeys": "0.1.2",
550
554
  "rightkit-http": "0.3.8",
551
555
  "rightkit-identity": "0.1.0",
552
- "rightkit-job-queue": "0.5.0",
556
+ "rightkit-job-queue": "0.5.1",
553
557
  "rightkit-jobs": "0.3.0",
554
- "rightkit-license": "0.2.4",
558
+ "rightkit-license": "0.2.5",
555
559
  "rightkit-llm": "0.3.1",
556
560
  "rightkit-logs": "0.3.5",
557
561
  "rightkit-mcp": "0.7.0",
@@ -564,7 +568,7 @@
564
568
  "rightkit-ort": "0.2.3",
565
569
  "rightkit-overlay": "0.2.0",
566
570
  "rightkit-overlay-win": "0.1.0",
567
- "rightkit-ownership": "0.4.1",
571
+ "rightkit-ownership": "0.4.2",
568
572
  "rightkit-pdf": "0.3.3",
569
573
  "rightkit-platform-rules": "0.1.0",
570
574
  "rightkit-playback": "0.3.0",
@@ -588,7 +592,7 @@
588
592
  "rightkit-spend": "0.2.0",
589
593
  "rightkit-sync": "0.2.2",
590
594
  "rightkit-tauri": "0.1.3",
591
- "rightkit-tauri-shell": "0.5.1",
595
+ "rightkit-tauri-shell": "0.6.0",
592
596
  "rightkit-time": "0.1.0",
593
597
  "rightkit-transcript": "0.4.0",
594
598
  "rightkit-tts": "0.2.3",
@@ -602,7 +606,7 @@
602
606
  },
603
607
  "npm": {
604
608
  "@rightkit/app-shell": "0.6.2",
605
- "@rightkit/app-update": "0.4.1",
609
+ "@rightkit/app-update": "0.4.2",
606
610
  "@rightkit/ax": "0.3.2",
607
611
  "@rightkit/ci": "0.3.0",
608
612
  "@rightkit/doc-render": "0.2.1",
@@ -622,11 +626,11 @@
622
626
  "@rightkit/qa": "0.6.1",
623
627
  "@rightkit/qa-chrome": "0.1.11",
624
628
  "@rightkit/react-shell": "0.7.2",
625
- "@rightkit/release": "0.6.1",
629
+ "@rightkit/release": "0.6.3",
626
630
  "@rightkit/settings-ui": "0.7.0",
627
631
  "@rightkit/shell": "0.1.1",
628
632
  "@rightkit/tauri": "0.3.0",
629
- "@rightkit/tauri-shell": "0.1.2",
633
+ "@rightkit/tauri-shell": "0.1.3",
630
634
  "@rightkit/theme": "0.3.1",
631
635
  "@rightkit/updates": "0.2.5"
632
636
  }
@@ -636,7 +640,8 @@
636
640
  "0.2.0",
637
641
  "0.2.1",
638
642
  "0.3.1",
639
- "0.4.0"
643
+ "0.4.0",
644
+ "0.4.1"
640
645
  ],
641
646
  "rightkit-browser": [
642
647
  "0.2.0",
@@ -644,7 +649,8 @@
644
649
  "0.2.2",
645
650
  "0.3.0",
646
651
  "0.3.1",
647
- "0.3.4"
652
+ "0.3.4",
653
+ "0.3.5"
648
654
  ],
649
655
  "rightkit-models": [
650
656
  "0.2.1",
@@ -672,7 +678,8 @@
672
678
  "0.3.0",
673
679
  "0.3.1",
674
680
  "0.4.0",
675
- "0.4.3"
681
+ "0.4.3",
682
+ "0.5.1"
676
683
  ],
677
684
  "rightkit-embed": [
678
685
  "0.2.1",
@@ -752,7 +759,8 @@
752
759
  "0.6.1",
753
760
  "0.6.4",
754
761
  "0.7.0",
755
- "0.7.1"
762
+ "0.7.1",
763
+ "0.8.0"
756
764
  ],
757
765
  "rightkit-sandbox": [
758
766
  "0.1.0",
@@ -825,7 +833,8 @@
825
833
  "0.4.1",
826
834
  "0.4.3",
827
835
  "0.4.4",
828
- "0.4.5"
836
+ "0.4.5",
837
+ "0.4.6"
829
838
  ],
830
839
  "rightkit-service": [
831
840
  "0.1.0",
@@ -933,7 +942,8 @@
933
942
  "0.3.0",
934
943
  "0.3.1",
935
944
  "0.3.2",
936
- "0.4.0"
945
+ "0.4.0",
946
+ "0.5.0"
937
947
  ],
938
948
  "rightkit-qa-driver": [
939
949
  "0.3.0",
@@ -955,7 +965,8 @@
955
965
  "0.4.0",
956
966
  "0.4.1",
957
967
  "0.4.4",
958
- "0.5.0"
968
+ "0.5.0",
969
+ "0.6.0"
959
970
  ],
960
971
  "rightkit-child-process": [
961
972
  "0.4.0",
@@ -965,7 +976,8 @@
965
976
  "0.5.1",
966
977
  "0.5.2",
967
978
  "0.5.3",
968
- "0.5.4"
979
+ "0.5.4",
980
+ "0.5.5"
969
981
  ],
970
982
  "rightkit-hotkeys": [
971
983
  "0.1.0",
@@ -1004,7 +1016,8 @@
1004
1016
  "rightkit-license": [
1005
1017
  "0.2.0",
1006
1018
  "0.2.2",
1007
- "0.2.3"
1019
+ "0.2.3",
1020
+ "0.2.4"
1008
1021
  ],
1009
1022
  "rightkit-credentials": [
1010
1023
  "0.2.0",
@@ -1062,7 +1075,8 @@
1062
1075
  "0.3.2",
1063
1076
  "0.3.3",
1064
1077
  "0.4.0",
1065
- "0.5.0"
1078
+ "0.5.0",
1079
+ "0.5.1"
1066
1080
  ],
1067
1081
  "rightkit-android": [
1068
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 `rightkit cargo`, find the executable, copy it to
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 `rightkit cargo
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 `rightkit rustc -vV`. */
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("rightkit", ["rustc", "-vV"], { cwd, env });
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 (rightkit rustc -vV failed); pass a target");
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: "rightkit", args: ["cargo", ...] }`);
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: `rightkit` resolves through the installed runtime client (as the apps' scripts did). */
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
- const launch = command === "rightkit" ? resolveCommand("rightkit", args, { root: cwd, env }) : { command, args };
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("rightkit", ["cargo", "metadata", "--format-version", "1"], { cwd: ctx.appRoot, env: ctx.env });
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 `rightkit cargo` and locate the executable. Returns { source, sourceSha256 }. */
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("rightkit", args, { cwd: appRoot, env });
748
- if (built?.error || built?.status !== 0) fail("STAGE_SIDECAR_BUILD_FAILED", `rightkit cargo build of ${entry.package} failed (${built?.error?.message ?? `exit ${built?.status}`})`, { package: entry.package, stderr: tail(built?.stderr) });
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("rightkit", ["cargo", "metadata", "--format-version", "1", "--no-deps", ...(entry.manifestPath ? ["--manifest-path", path.resolve(appRoot, entry.manifestPath)] : [])], { cwd: appRoot, env });
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 `rightkit cargo` for a non-skipped entry. */
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 `rightkit 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.");
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
+ }