@rightkit/release 0.2.109 → 0.2.111

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/build-release.mjs CHANGED
@@ -33,7 +33,7 @@ import { resolveTargetRoot } from "./cargo-target.mjs";
33
33
  import { assertNsisInPlaceUpgradeContract } from "./nsis-upgrade-contract.mjs";
34
34
  import { buildPathPrefix, collectPreflight, formatPreflight, preflightFailures } from "./preflight.mjs";
35
35
  import { assertCleanSource } from "./source-gate.mjs";
36
- import { acquireHeavyWorkSlot, heavyCommandEnvironment, terminateProcessTree } from "./heavy-command.mjs";
36
+ import { acquireHeavyWorkSlot, heavyCommandEnvironment, summarizePreBrokerWaits, terminateProcessTree } from "./heavy-command.mjs";
37
37
  import { processGroupCpuSeconds } from "./process-liveness.mjs";
38
38
  import { cancelAndReapManagedRequest, firstManagedRequestId, releaseProgressLimits } from "./progress-control.mjs";
39
39
 
@@ -268,6 +268,9 @@ try {
268
268
  suiteSlot = acquireSuiteBuildSlot({ layout: sharedLayout, pid: process.pid, argv: process.argv, waitMs: Number(process.env.BUILD_GUARD_WAIT_SECS ?? 900) * 1000 });
269
269
  cacheLease = acquireCacheLease({ layout: sharedLayout, pid: process.pid, argv: process.argv });
270
270
  }
271
+ // Pre-broker wait attribution: every layer, ms, and blocker identity (Step 1 instrumentation).
272
+ const preBrokerWaits = summarizePreBrokerWaits({ heavySlot, suiteSlot, heavyOwnerInherited: process.env.RIGHTSUITE_HEAVY_WORK_OWNER === "1" });
273
+ console.error(`[right-release] pre-broker waits: ${preBrokerWaits.summary}`);
271
274
  throwIfInterrupted();
272
275
  const releaseId = `${config.app}-${config.version}-${shortCommit}`;
273
276
  const platformDir = platform === "win" ? "windows" : "mac";
@@ -323,6 +326,7 @@ try {
323
326
  for (const command of target.preflight?.commands ?? []) runChecked(command.cmd, command.args ?? [], path.resolve(appRoot, command.cwd ?? "."), env);
324
327
  if (buildRoot) mkdirSync(buildRoot, { recursive: true });
325
328
  mkdirSync(stateRoot, { recursive: true });
329
+ writeJson(path.join(stateRoot, "release-waits.json"), { schema: 1, recordedAt: new Date().toISOString(), ...preBrokerWaits });
326
330
  if (buildRoot) writeJson(path.join(buildRoot, "release-inputs.lock.json"), lockPayload);
327
331
  writeJson(path.join(stateRoot, "release-inputs.lock.json"), lockPayload);
328
332
  checkpoint(stateRoot, "preflight_complete");
package/cache-policy.mjs CHANGED
@@ -213,12 +213,15 @@ export function acquireSuiteBuildSlot({ layout, pid = process.pid, argv = proces
213
213
  requireLayout(layout);
214
214
  const started = Date.now();
215
215
  const payload = { schema: CACHE_SCHEMA, pid: Number(pid), argv: [...argv], createdAt: iso(now) };
216
+ const waits = { layer: "suite-build-slot", waitMs: 0, blockers: [] };
216
217
  for (;;) {
217
218
  try {
218
219
  acquireAtomicLock(layout.suiteSlotPath, payload, "suite build slot", new Date());
219
- return releaseFor(layout.suiteSlotPath, payload);
220
+ waits.waitMs = Date.now() - started;
221
+ return Object.assign(releaseFor(layout.suiteSlotPath, payload), { waits });
220
222
  } catch (error) {
221
223
  if (!/active/i.test(error.message)) throw error;
224
+ if (!waits.blockers.includes(error.message)) waits.blockers.push(error.message);
222
225
  if (Date.now() - started >= waitMs) throw new Error(`${error.message}; suite build slot timed out after ${waitMs}ms without alternate-target fallback`);
223
226
  sleep(Math.min(250, Math.max(1, waitMs - (Date.now() - started))));
224
227
  }
package/development.mjs CHANGED
@@ -5,7 +5,8 @@ import path from "node:path";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { assertPrimaryReleaseCheckout } from "./release-invocation.mjs";
7
7
  import { assertReleaseExecutionAllowed } from "./execution-policy.mjs";
8
- import { managedRuntimeClient, runCargoSync } from "./managed-cargo.mjs";
8
+ import { acquireManagedRunLease, managedRuntimeClient, runCargoSync } from "./managed-cargo.mjs";
9
+ import { BUNDLE_MARKERS, bundleMarkerBuffer, readTauriBundleMarkers } from "./tauri-bundle-marker.mjs";
9
10
  import { installPortableDevelopment } from "./portable-development.mjs";
10
11
 
11
12
  export const DEVELOPMENT_PROFILE = "release-iterate";
@@ -64,25 +65,34 @@ export function runDevelopment({ root, platform, config, buildOnly = false, dryR
64
65
  if (dryRun) return { built: false, installed: false, plan: { build: target.build, install: buildOnly ? null : target.install ?? null, profile: DEVELOPMENT_PROFILE } };
65
66
  assertReleaseExecutionAllowed({ cwd: repoRoot, environment: env, command: `right-release dev --platform ${platform}` });
66
67
  const childEnv = developmentEnvironment(env);
67
- for (const command of target.build) execute(command, { root, env: childEnv, dryRun, run, label: "build" });
68
- if (buildOnly || !target.install) return { built: true, installed: false };
69
- install(target.install, { root, platform, env: childEnv, run });
70
- return { built: true, installed: true };
68
+ // One lease spans every managed request this run makes, so a broker cutover cannot land between them.
69
+ const lease = acquireManagedRunLease({ command: `right-release dev --platform ${platform}`, env });
70
+ try {
71
+ const startedMs = Date.now();
72
+ for (const command of target.build) execute(command, { root, env: childEnv, dryRun, run, label: "build" });
73
+ if (buildOnly || !target.install) return { built: true, installed: false };
74
+ install(target.install, { root, platform, env: childEnv, run, sinceMs: startedMs });
75
+ return { built: true, installed: true };
76
+ } finally { lease.release(); }
71
77
  }
72
78
 
73
79
  export function assertNativeDevelopmentHost(platform, host = process.platform) {
74
80
  if ((platform === "win" && host !== "win32") || (platform === "mac" && host !== "darwin")) throw new Error(`development target ${platform} requires its native host`);
75
81
  }
76
82
 
77
- function install(descriptor, { root, platform, env, run }) {
83
+ function install(descriptor, { root, platform, env, run, sinceMs = null }) {
78
84
  if (descriptor.kind === "command") return execute(descriptor, { root, env, run, label: "install" });
79
85
  if (descriptor.kind === "portable") return installPortableDevelopment(descriptor, { root, platform: platform === "win" ? "win32" : "darwin", env });
80
86
  if (platform === "win") {
81
87
  if (!descriptor.expectedInstalledPath) throw new Error("Windows Tauri installer requires expectedInstalledPath for installed verification");
82
- const { bundleRoot, installer: app } = resolveTauriBundleDirectory(descriptor, { root, platform, env });
88
+ const { bundleRoot, installer: app } = resolveTauriBundleDirectory(descriptor, { root, platform, env, sinceMs });
83
89
  const built = path.resolve(bundleRoot, "..", "..", path.basename(descriptor.expectedInstalledPath));
84
90
  assertNonEmptyExecutable(built);
85
- const result = run(app, ["/S"], { cwd: root, env, stdio: "inherit", windowsHide: true, shell: false });
91
+ // Tauri's silent installer force-kills a running copy of the app (utils.nsh: IfSilent kill). When it
92
+ // was running, pass /R so the installer relaunches it as the user (RunAsUser, outside this process tree).
93
+ const running = isWindowsProcessRunning(path.basename(descriptor.expectedInstalledPath), { run });
94
+ if (running) console.log(`right-release dev: ${descriptor.productName} is running; the installer will close it and relaunch it`);
95
+ const result = run(app, windowsInstallerArguments({ running }), { cwd: root, env, stdio: "inherit", windowsHide: true, shell: false });
86
96
  if (result.status !== 0) throw new Error(`development installer failed (${result.status}): ${app}`);
87
97
  const installed = path.resolve(root, descriptor.expectedInstalledPath);
88
98
  assertInstalledExecutableMatches(built, installed);
@@ -119,7 +129,7 @@ export function resolveTauriArtifact(descriptor, { root, platform, env = process
119
129
  return resolveTauriBundleDirectory(descriptor, { root, platform, env, runCargo }).installer;
120
130
  }
121
131
 
122
- export function resolveTauriBundleDirectory(descriptor, { root, platform, env = process.env, runCargo = runCargoSync }) {
132
+ export function resolveTauriBundleDirectory(descriptor, { root, platform, env = process.env, runCargo = runCargoSync, sinceMs = null }) {
123
133
  const bundleRoot = descriptor.bundleDirectory
124
134
  ? path.resolve(root, descriptor.bundleDirectory)
125
135
  : resolveBundleRoot(descriptor, { root, env, runCargo });
@@ -127,18 +137,37 @@ export function resolveTauriBundleDirectory(descriptor, { root, platform, env =
127
137
  const entries = readdirSync(bundleRoot, { withFileTypes: true });
128
138
  const candidates = platform === "mac"
129
139
  ? entries.filter((entry) => entry.isDirectory() && entry.name === `${descriptor.productName}.app`).map((entry) => path.join(bundleRoot, entry.name))
130
- : entries.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".exe") && entry.name.toLowerCase().includes("setup")).map((entry) => path.join(bundleRoot, entry.name));
131
- if (candidates.length !== 1) throw new Error(`expected exactly one ${platform} Tauri installer for ${descriptor.productName} in ${bundleRoot}; found ${candidates.length}`);
140
+ // Older installers are kept for history: select this product's installer written by this run.
141
+ : entries.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".exe") && entry.name.toLowerCase().includes("setup") && entry.name.startsWith(`${descriptor.productName}_`))
142
+ .map((entry) => path.join(bundleRoot, entry.name))
143
+ .filter((file) => sinceMs === null || statSync(file).mtimeMs >= sinceMs);
144
+ if (candidates.length !== 1) throw new Error(`expected exactly one ${platform} Tauri installer for ${descriptor.productName} in ${bundleRoot}${sinceMs === null ? "" : " written by this run"}; found ${candidates.length}`);
132
145
  if (!statSync(candidates[0]).isFile() && platform === "win") throw new Error(`installer is not a file: ${candidates[0]}`);
133
146
  return { bundleRoot, installer: candidates[0] };
134
147
  }
135
148
 
149
+ export function windowsInstallerArguments({ running = false } = {}) { return running ? ["/S", "/R"] : ["/S"]; }
150
+
151
+ export function isWindowsProcessRunning(imageName, { run = spawnSync, systemRoot = process.env.SystemRoot ?? "C:\\Windows" } = {}) {
152
+ const result = run(path.join(systemRoot, "System32", "tasklist.exe"), ["/FI", `IMAGENAME eq ${imageName}`, "/FO", "CSV", "/NH"], { encoding: "utf8", windowsHide: true, shell: false });
153
+ if (result.status !== 0 || typeof result.stdout !== "string") return false;
154
+ return result.stdout.toLowerCase().includes(`"${imageName.toLowerCase()}"`);
155
+ }
156
+
136
157
  export function assertInstalledExecutableMatches(built, installed, read = readFileSync) {
137
158
  assertNonEmptyExecutable(built);
138
159
  assertNonEmptyExecutable(installed);
139
- const digest = (file) => createHash("sha256").update(read(file)).digest("hex");
160
+ const digest = (file) => createHash("sha256").update(withUnknownBundleMarker(file, read)).digest("hex");
140
161
  if (digest(built) !== digest(installed)) throw new Error(`installed executable does not match this dev build: ${installed}`);
141
162
  }
163
+ // Tauri's NSIS bundler rewrites the packaged copy's bundle marker UNK -> NSS; compare both copies as UNK.
164
+ function withUnknownBundleMarker(file, read) {
165
+ const bytes = Buffer.from(read(file));
166
+ const nsis = readTauriBundleMarkers(file, { read: () => bytes }).markers.nsis ?? [];
167
+ if (nsis.length > 1) throw new Error(`installed executable verification failed: ${nsis.length} NSIS bundle markers in ${file}`);
168
+ if (nsis.length === 1) bundleMarkerBuffer(BUNDLE_MARKERS.unknown).copy(bytes, nsis[0]);
169
+ return bytes;
170
+ }
142
171
  function assertNonEmptyExecutable(file) { if (!existsSync(file) || !statSync(file).isFile() || statSync(file).size === 0) throw new Error(`installed executable verification failed: missing or empty file ${file}`); }
143
172
 
144
173
  function resolveBundleRoot(descriptor, { root, env, runCargo }) {
@@ -195,6 +224,13 @@ export function resolvePnpmCli({ root, env = process.env } = {}) {
195
224
  const parent = path.dirname(dir);
196
225
  if (parent === dir) break;
197
226
  }
227
+ // A global pnpm (no Corepack in Node >= 25) exposes its JS entry only through its PATH shim.
228
+ for (const dir of String(env.PATH ?? env.Path ?? "").split(path.delimiter).filter(Boolean)) {
229
+ const shim = path.join(dir, "pnpm.CMD");
230
+ if (!existsSync(shim)) continue;
231
+ const match = /"%~dp0\\([^"]*pnpm\.(?:mjs|cjs|js))"/i.exec(readFileSync(shim, "utf8"));
232
+ if (match) candidates.push(path.resolve(dir, match[1]));
233
+ }
198
234
  const selected = candidates.find((candidate) => existsSync(candidate));
199
235
  if (!selected) throw new Error("could not resolve pnpm JavaScript CLI entrypoint; install/pin pnpm through Corepack");
200
236
  return selected;
package/heavy-command.mjs CHANGED
@@ -220,6 +220,19 @@ function spawnOwnerWatcher(details) {
220
220
  watcher.unref();
221
221
  }
222
222
 
223
+ export function summarizePreBrokerWaits({ heavySlot, suiteSlot, heavyOwnerInherited = false } = {}) {
224
+ const heavy = heavySlot?.waits ?? null;
225
+ const suite = suiteSlot?.waits ?? null;
226
+ const layers = [
227
+ heavy ? { layer: "heavy-work-slot", ms: (heavy.slotWaitMs ?? 0) + (heavy.resourceWaitMs ?? 0), slotWaitMs: heavy.slotWaitMs ?? 0, resourceWaitMs: heavy.resourceWaitMs ?? 0, blockers: heavy.slotBlockers ?? [], resourceBlockers: heavy.resourceBlockers ?? [] }
228
+ : { layer: "heavy-work-slot", ms: 0, skipped: heavyOwnerInherited ? "slot owned by parent heavy-command" : "not acquired" },
229
+ suite ? { layer: "suite-build-slot", ms: suite.waitMs ?? 0, blockers: suite.blockers ?? [] } : { layer: "suite-build-slot", ms: 0, skipped: "inactive (non-shared cache mode)" },
230
+ ];
231
+ const totalMs = layers.reduce((sum, layer) => sum + layer.ms, 0);
232
+ const summary = `${layers.map((layer) => `${layer.layer}=${layer.ms}ms${layer.skipped ? ` (${layer.skipped})` : ""}${layer.blockers?.length ? ` blocked-by ${layer.blockers.map((b) => typeof b === "string" ? b : `pid ${b.pid ?? "starting"}`).join(",")}` : ""}`).join("; ")}; total=${totalMs}ms`;
233
+ return { layers, totalMs, summary, brokerQueue: "see broker receipt waits.brokerQueue (queueMs + blockers)" };
234
+ }
235
+
223
236
  export function acquireHeavyWorkSlot({
224
237
  root = heavyWorkRoot(), pid = process.pid, argv = process.argv, waitMs = Number(process.env.BUILD_GUARD_WAIT_SECS ?? 900) * 1000,
225
238
  pollMs = 1000, alive = processAlive, pause = sleep, snapshot = systemResourceSnapshot,
@@ -232,16 +245,24 @@ export function acquireHeavyWorkSlot({
232
245
  const token = randomUUID();
233
246
  const started = Date.now();
234
247
  let lastReport = 0;
248
+ // Wait attribution: who held the slot, and how long each layer made us wait.
249
+ const waits = { layer: "heavy-work-slot", slotWaitMs: 0, slotBlockers: [], resourceWaitMs: 0, resourceBlockers: [], totalMs: 0 };
250
+ const noteSlotBlocker = (owner) => {
251
+ const identity = owner ? { pid: owner.pid ?? null, argv: Array.isArray(owner.argv) ? owner.argv.slice(0, 8).join(" ").slice(0, 200) : null, since: owner.createdAt ?? null } : { pid: null, argv: null, since: null, starting: true };
252
+ if (!waits.slotBlockers.some((entry) => entry.pid === identity.pid && entry.since === identity.since)) waits.slotBlockers.push(identity);
253
+ };
235
254
  for (;;) {
236
255
  try {
237
256
  mkdirSync(lockDir);
238
257
  const fd = openSync(path.join(lockDir, "owner.json"), "wx");
239
258
  writeFileSync(fd, `${JSON.stringify({ schema: 1, pid: Number(pid), ownerStartedAtMs: startedAt(pid), token, argv: [...argv], createdAt: new Date().toISOString() })}\n`);
240
259
  closeSync(fd);
260
+ waits.slotWaitMs = Date.now() - started;
241
261
  break;
242
262
  } catch (error) {
243
263
  if (error.code !== "EEXIST") throw error;
244
264
  const owner = readOwner(lockDir);
265
+ noteSlotBlocker(owner);
245
266
  const incompleteAge = (() => { try { return Date.now() - statSync(lockDir).mtimeMs; } catch { return 0; } })();
246
267
  if (owner ? sweepTrackedHeavyWorkOrphan({ root, alive, startedAt, terminate, log }) : incompleteAge > 10_000) {
247
268
  if (!owner) rmSync(lockDir, { recursive: true, force: true });
@@ -253,11 +274,14 @@ export function acquireHeavyWorkSlot({
253
274
  }
254
275
  }
255
276
 
277
+ const resourceStarted = Date.now();
256
278
  for (;;) {
257
279
  const current = snapshot();
258
280
  const blockers = resourceBlockers(current, { minFreePercent, maxCpuLoadPercent });
281
+ for (const blocker of blockers) if (!waits.resourceBlockers.includes(blocker)) waits.resourceBlockers.push(blocker);
259
282
  if (blockers.length === 0) {
260
- log(`admitted ${formatResourceSnapshot(current)} jobs=${heavyCommandEnvironment().CARGO_BUILD_JOBS}`);
283
+ waits.resourceWaitMs = Date.now() - resourceStarted; waits.totalMs = Date.now() - started;
284
+ log(`admitted ${formatResourceSnapshot(current)} jobs=${heavyCommandEnvironment().CARGO_BUILD_JOBS} waited slot=${waits.slotWaitMs}ms resource=${waits.resourceWaitMs}ms${waits.slotBlockers.length ? ` blockers=${waits.slotBlockers.map((entry) => `pid ${entry.pid ?? "starting"}`).join(",")}` : ""}`);
261
285
  break;
262
286
  }
263
287
  if (Date.now() - started >= waitMs) {
@@ -269,6 +293,7 @@ export function acquireHeavyWorkSlot({
269
293
  }
270
294
  return {
271
295
  root,
296
+ waits,
272
297
  trackChild(childPid, childCommand = "") {
273
298
  const owner = readOwner(lockDir);
274
299
  if (owner?.token !== token) throw new Error("heavy-work slot ownership changed before child tracking");
package/managed-cargo.mjs CHANGED
@@ -1,29 +1,47 @@
1
- import { existsSync } from "node:fs";
2
- import path from "node:path";
3
- import { spawnSync } from "./background-process.mjs";
4
-
5
- export function managedRuntimeClient(env = process.env, platform = process.platform, exists = existsSync) {
6
- const roots = [env.RIGHTKIT_MANAGED_ROOT, env.RIGHTKIT_EXTERNAL_ROOT,
7
- platform === "win32" ? "D:\\.rightkit-managed" : platform === "darwin" ? "/Volumes/D/.rightkit-managed" : undefined]
8
- .filter((root) => typeof root === "string" && root.length > 0);
9
- for (const root of roots) {
10
- const client = path.join(root, "runtime-current", "build-control-clients", "src", "rightkit.mjs");
11
- if (exists(client)) return client;
12
- }
13
- return undefined;
14
- }
15
-
16
- function managedHost(env) {
17
- return Boolean(env.RIGHTKIT_BUILD_BROKER_SOCKET)
18
- || /(?:^|[;:])[^;:]*[/\\](?:\.rightkit-managed|rightkitmanagedagent)[/\\]agent-bin(?:[;:]|$)/i.test(String(env.PATH ?? ""));
19
- }
20
-
21
- export function runCargoSync(args, options = {}) {
22
- const env = options.env ?? process.env;
23
- const client = managedRuntimeClient(env);
24
- if (client) return spawnSync(process.execPath, [client, "cargo", ...args], { ...options, cwd: process.cwd() });
25
- if (managedHost(env) && process.platform === "win32") {
26
- return { status: null, stdout: "", stderr: "", error: new Error("installed RightKit runtime client is unavailable for managed Cargo metadata") };
27
- }
28
- return spawnSync("cargo", args, options);
29
- }
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { spawnSync } from "./background-process.mjs";
5
+
6
+ export function managedRuntimeClient(env = process.env, platform = process.platform, exists = existsSync) {
7
+ const roots = [env.RIGHTKIT_MANAGED_ROOT, env.RIGHTKIT_EXTERNAL_ROOT,
8
+ platform === "win32" ? "D:\\.rightkit-managed" : platform === "darwin" ? "/Volumes/D/.rightkit-managed" : undefined]
9
+ .filter((root) => typeof root === "string" && root.length > 0);
10
+ for (const root of roots) {
11
+ const client = path.join(root, "runtime-current", "build-control-clients", "src", "rightkit.mjs");
12
+ if (exists(client)) return client;
13
+ }
14
+ return undefined;
15
+ }
16
+
17
+ /** Hold a client-run lease that blocks broker runtime cutover until release() (see
18
+ * proveDevelopmentRunsDrained). No managed runtime → no lease; lease I/O failure warns and proceeds. */
19
+ export function acquireManagedRunLease({ command, env = process.env, platform = process.platform, exists = existsSync, pid = process.pid } = {}) {
20
+ const client = managedRuntimeClient(env, platform, exists);
21
+ if (!client) return { path: null, release() {} };
22
+ const runs = path.join(path.dirname(path.dirname(path.dirname(path.dirname(client)))), "rightkit-build-control", "global", "runs");
23
+ const file = path.join(runs, `${pid}-${randomUUID()}.json`);
24
+ try {
25
+ mkdirSync(runs, { recursive: true });
26
+ writeFileSync(file, `${JSON.stringify({ pid, command, startedAt: new Date().toISOString() })}\n`, { flag: "wx" });
27
+ } catch (error) {
28
+ console.warn(`right-release: could not record managed run lease (${error.message}); runtime cutover is not blocked for this run`);
29
+ return { path: null, release() {} };
30
+ }
31
+ return { path: file, release() { rmSync(file, { force: true }); } };
32
+ }
33
+
34
+ function managedHost(env) {
35
+ return Boolean(env.RIGHTKIT_BUILD_BROKER_SOCKET)
36
+ || /(?:^|[;:])[^;:]*[/\\](?:\.rightkit-managed|rightkitmanagedagent)[/\\]agent-bin(?:[;:]|$)/i.test(String(env.PATH ?? ""));
37
+ }
38
+
39
+ export function runCargoSync(args, options = {}) {
40
+ const env = options.env ?? process.env;
41
+ const client = managedRuntimeClient(env);
42
+ if (client) return spawnSync(process.execPath, [client, "cargo", ...args], { ...options, cwd: process.cwd() });
43
+ if (managedHost(env) && process.platform === "win32") {
44
+ return { status: null, stdout: "", stderr: "", error: new Error("installed RightKit runtime client is unavailable for managed Cargo metadata") };
45
+ }
46
+ return spawnSync("cargo", args, options);
47
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rightkit/release",
3
- "version": "0.2.109",
3
+ "version": "0.2.111",
4
4
  "description": "Portable release CLI/SDK with fail-closed public GitHub Releases and private R2 + RightApps distribution.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -1,144 +1,147 @@
1
- {
2
- "schema": 2,
3
- "packageManager": "pnpm@11.24.0",
4
- "npm": {
5
- "@rightkit/git": "0.2.0",
6
- "@rightkit/legal": "0.2.0",
7
- "@rightkit/license": "0.1.5",
8
- "@rightkit/logs": "0.1.3",
9
- "@rightkit/platform-ui": "0.1.0",
10
- "@rightkit/qa": "0.1.0",
11
- "@rightkit/release": "0.2.47",
12
- "@rightkit/tauri": "0.1.0",
13
- "@rightkit/updates": "0.2.3"
14
- },
15
- "stagedNpm": {
16
- "@rightkit/ax": "0.2.4",
17
- "@rightkit/git": "0.2.25",
18
- "@rightkit/hooks": "0.1.1",
19
- "@rightkit/legal": "0.3.1",
20
- "@rightkit/legal-ui": "0.1.1",
21
- "@rightkit/license": "0.1.7",
22
- "@rightkit/logs": "0.1.4",
23
- "@rightkit/platform-ui": "0.1.1",
24
- "@rightkit/qa": "0.2.1",
25
- "@rightkit/release": "0.2.109",
26
- "@rightkit/tauri": "0.1.1",
27
- "@rightkit/updates": "0.2.4"
28
- },
29
- "legacyNpm": {
30
- "@rightkit/ax": [
31
- "0.2.0",
32
- "0.2.1",
33
- "0.2.2",
34
- "0.2.3"
35
- ],
36
- "@rightkit/git": [
37
- "0.2.1",
38
- "0.2.2",
39
- "0.2.3",
40
- "0.2.4",
41
- "0.2.5",
42
- "0.2.6",
43
- "0.2.7",
44
- "0.2.8",
45
- "0.2.9",
46
- "0.2.10",
47
- "0.2.11",
48
- "0.2.12",
49
- "0.2.13",
50
- "0.2.14",
51
- "0.2.15",
52
- "0.2.16",
53
- "0.2.18",
54
- "0.2.19",
55
- "0.2.20",
56
- "0.2.21",
57
- "0.2.22",
58
- "0.2.23",
59
- "0.2.24"
60
- ],
61
- "@rightkit/legal-ui": [
62
- "0.1.0"
63
- ],
64
- "@rightkit/hooks": [
65
- "0.1.0"
66
- ],
67
- "@rightkit/legal": [
68
- "0.3.0"
69
- ],
70
- "@rightkit/license": [
71
- "0.1.6"
72
- ],
73
- "@rightkit/release": [
74
- "0.2.22",
75
- "0.2.29",
76
- "0.2.30",
77
- "0.2.31",
78
- "0.2.41",
79
- "0.2.42",
80
- "0.2.43",
81
- "0.2.44",
82
- "0.2.45",
83
- "0.2.46",
84
- "0.2.49",
85
- "0.2.50",
86
- "0.2.51",
87
- "0.2.53",
88
- "0.2.54",
89
- "0.2.55",
90
- "0.2.56",
91
- "0.2.61",
92
- "0.2.62",
93
- "0.2.63",
94
- "0.2.64",
95
- "0.2.65",
96
- "0.2.66",
97
- "0.2.67",
98
- "0.2.68",
99
- "0.2.69",
100
- "0.2.70",
101
- "0.2.71",
102
- "0.2.72",
103
- "0.2.73",
104
- "0.2.74",
105
- "0.2.75",
106
- "0.2.76",
107
- "0.2.82",
108
- "0.2.83",
109
- "0.2.91",
110
- "0.2.92",
111
- "0.2.94",
112
- "0.2.95",
113
- "0.2.96",
114
- "0.2.97",
115
- "0.2.98",
116
- "0.2.99",
117
- "0.2.104",
118
- "0.2.105",
119
- "0.2.106",
120
- "0.2.107",
121
- "0.2.108"
122
- ],
123
- "@rightkit/qa": [
124
- "0.1.0",
125
- "0.2.0"
126
- ]
127
- },
128
- "cargo": {
129
- "rightkit-license": "0.1.2",
130
- "rightkit-logs": "0.1.0",
131
- "rightkit-process": "0.1.0",
132
- "rightkit-tauri": "0.1.0"
133
- },
134
- "stagedCargo": {
135
- "rightkit-license": "0.1.3",
136
- "rightkit-tauri": "0.1.1"
137
- },
138
- "swift": {
139
- "rightkit-swift": {
140
- "url": "https://github.com/bogusyogi/rightkit-swift.git",
141
- "version": "0.1.1"
142
- }
143
- }
144
- }
1
+ {
2
+ "schema": 2,
3
+ "packageManager": "pnpm@11.24.0",
4
+ "npm": {
5
+ "@rightkit/git": "0.2.0",
6
+ "@rightkit/legal": "0.2.0",
7
+ "@rightkit/license": "0.1.5",
8
+ "@rightkit/logs": "0.1.3",
9
+ "@rightkit/platform-ui": "0.1.0",
10
+ "@rightkit/qa": "0.1.0",
11
+ "@rightkit/release": "0.2.47",
12
+ "@rightkit/tauri": "0.1.0",
13
+ "@rightkit/updates": "0.2.3"
14
+ },
15
+ "stagedNpm": {
16
+ "@rightkit/ax": "0.2.4",
17
+ "@rightkit/git": "0.2.25",
18
+ "@rightkit/hooks": "0.1.1",
19
+ "@rightkit/legal": "0.3.1",
20
+ "@rightkit/legal-ui": "0.1.1",
21
+ "@rightkit/license": "0.1.8",
22
+ "@rightkit/logs": "0.1.4",
23
+ "@rightkit/platform-ui": "0.1.1",
24
+ "@rightkit/qa": "0.2.1",
25
+ "@rightkit/release": "0.2.111",
26
+ "@rightkit/tauri": "0.1.1",
27
+ "@rightkit/updates": "0.2.4"
28
+ },
29
+ "legacyNpm": {
30
+ "@rightkit/ax": [
31
+ "0.2.0",
32
+ "0.2.1",
33
+ "0.2.2",
34
+ "0.2.3"
35
+ ],
36
+ "@rightkit/git": [
37
+ "0.2.1",
38
+ "0.2.2",
39
+ "0.2.3",
40
+ "0.2.4",
41
+ "0.2.5",
42
+ "0.2.6",
43
+ "0.2.7",
44
+ "0.2.8",
45
+ "0.2.9",
46
+ "0.2.10",
47
+ "0.2.11",
48
+ "0.2.12",
49
+ "0.2.13",
50
+ "0.2.14",
51
+ "0.2.15",
52
+ "0.2.16",
53
+ "0.2.18",
54
+ "0.2.19",
55
+ "0.2.20",
56
+ "0.2.21",
57
+ "0.2.22",
58
+ "0.2.23",
59
+ "0.2.24"
60
+ ],
61
+ "@rightkit/legal-ui": [
62
+ "0.1.0"
63
+ ],
64
+ "@rightkit/hooks": [
65
+ "0.1.0"
66
+ ],
67
+ "@rightkit/legal": [
68
+ "0.3.0"
69
+ ],
70
+ "@rightkit/license": [
71
+ "0.1.6",
72
+ "0.1.7"
73
+ ],
74
+ "@rightkit/release": [
75
+ "0.2.22",
76
+ "0.2.29",
77
+ "0.2.30",
78
+ "0.2.31",
79
+ "0.2.41",
80
+ "0.2.42",
81
+ "0.2.43",
82
+ "0.2.44",
83
+ "0.2.45",
84
+ "0.2.46",
85
+ "0.2.49",
86
+ "0.2.50",
87
+ "0.2.51",
88
+ "0.2.53",
89
+ "0.2.54",
90
+ "0.2.55",
91
+ "0.2.56",
92
+ "0.2.61",
93
+ "0.2.62",
94
+ "0.2.63",
95
+ "0.2.64",
96
+ "0.2.65",
97
+ "0.2.66",
98
+ "0.2.67",
99
+ "0.2.68",
100
+ "0.2.69",
101
+ "0.2.70",
102
+ "0.2.71",
103
+ "0.2.72",
104
+ "0.2.73",
105
+ "0.2.74",
106
+ "0.2.75",
107
+ "0.2.76",
108
+ "0.2.82",
109
+ "0.2.83",
110
+ "0.2.91",
111
+ "0.2.92",
112
+ "0.2.94",
113
+ "0.2.95",
114
+ "0.2.96",
115
+ "0.2.97",
116
+ "0.2.98",
117
+ "0.2.99",
118
+ "0.2.104",
119
+ "0.2.105",
120
+ "0.2.106",
121
+ "0.2.107",
122
+ "0.2.108",
123
+ "0.2.109",
124
+ "0.2.110"
125
+ ],
126
+ "@rightkit/qa": [
127
+ "0.1.0",
128
+ "0.2.0"
129
+ ]
130
+ },
131
+ "cargo": {
132
+ "rightkit-license": "0.1.2",
133
+ "rightkit-logs": "0.1.0",
134
+ "rightkit-process": "0.1.0",
135
+ "rightkit-tauri": "0.1.0"
136
+ },
137
+ "stagedCargo": {
138
+ "rightkit-license": "0.1.3",
139
+ "rightkit-tauri": "0.1.1"
140
+ },
141
+ "swift": {
142
+ "rightkit-swift": {
143
+ "url": "https://github.com/bogusyogi/rightkit-swift.git",
144
+ "version": "0.1.1"
145
+ }
146
+ }
147
+ }