@tapi-dev/sdk 0.1.26 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts CHANGED
@@ -126,6 +126,7 @@ export declare function chooseStudioPort(preferred?: number, options?: {
126
126
  portAvailable?: StudioPortAvailable;
127
127
  reapBlockedPorts?: StudioPortReaper;
128
128
  }): Promise<number>;
129
+ export declare function downloadAndVerify(url: string, destination: string, expectedSha256: string, label?: string): Promise<void>;
129
130
  export declare function studioInstanceRecordPathForOptions(options: StudioCliOptions): string;
130
131
  export declare function findPortableStudioServerExe(releaseDir: string, manifest: StudioReleaseManifest): string | undefined;
131
132
  export declare function estimateRequiredExtractionBytes(zipBytes: number): number;
package/dist/cli.js CHANGED
@@ -2183,6 +2183,7 @@ export async function tryOpenExistingPortableStudioServer(options, manifest, fet
2183
2183
  return { opened: false, reason: "identity_mismatch" };
2184
2184
  }
2185
2185
  const launchUrl = studioLaunchUrl(record.baseUrl, options);
2186
+ await requestExistingStudioRuntimeCleanup(record.baseUrl, fetchImpl);
2186
2187
  openBrowserImpl(launchUrl);
2187
2188
  console.log(`Opened existing Tapi Studio ${record.manifestVersion || manifest.version}: ${launchUrl}`);
2188
2189
  return { opened: true, baseUrl: record.baseUrl };
@@ -2192,6 +2193,25 @@ export async function tryOpenExistingPortableStudioServer(options, manifest, fet
2192
2193
  return { opened: false, reason: formatError(error) };
2193
2194
  }
2194
2195
  }
2196
+ async function requestExistingStudioRuntimeCleanup(baseUrl, fetchImpl = fetch) {
2197
+ const url = `${baseUrl.replace(/\/+$/, "")}/api/studio/control/cleanup-runtime-session`;
2198
+ try {
2199
+ const response = await fetchWithTimeout(url, {
2200
+ method: "POST",
2201
+ headers: {
2202
+ Accept: "application/json",
2203
+ "Content-Type": "application/json",
2204
+ },
2205
+ body: JSON.stringify({ reason: "tapi_studio_reopen" }),
2206
+ }, 5_000, fetchImpl);
2207
+ if (!response.ok && response.status !== 404) {
2208
+ console.warn(`Tapi Studio runtime cleanup returned HTTP ${response.status}; opening Studio anyway.`);
2209
+ }
2210
+ }
2211
+ catch (error) {
2212
+ console.warn(`Tapi Studio runtime cleanup failed: ${formatError(error)}. Opening Studio anyway.`);
2213
+ }
2214
+ }
2195
2215
  async function ensurePortableStudioServer(options) {
2196
2216
  const event = await createCliWideEvent("tapi_cli.studio_server_ensure", {
2197
2217
  sdk_version: sdkVersion,
@@ -2590,16 +2610,22 @@ async function requestStudioInstallToken(apiBaseUrl, channel, firebaseIdToken, f
2590
2610
  expiresAt: typeof payload?.expiresAt === "string" ? payload.expiresAt : undefined,
2591
2611
  };
2592
2612
  }
2593
- async function downloadAndVerify(url, destination, expectedSha256, label = "Studio installer") {
2613
+ export async function downloadAndVerify(url, destination, expectedSha256, label = "Studio installer") {
2594
2614
  const partialPath = `${destination}.partial`;
2595
- await downloadFile(url, partialPath, label);
2596
- const actualSha256 = await sha256File(partialPath);
2597
- if (actualSha256 !== expectedSha256.toLowerCase()) {
2615
+ await unlinkIfExists(partialPath);
2616
+ try {
2617
+ await downloadFile(url, partialPath, label);
2618
+ const actualSha256 = await sha256File(partialPath);
2619
+ if (actualSha256 !== expectedSha256.toLowerCase()) {
2620
+ throw new Error(`${label} checksum mismatch. Expected ${expectedSha256}, got ${actualSha256}.`);
2621
+ }
2622
+ await rename(partialPath, destination);
2623
+ console.log(`Verified SHA256: ${actualSha256}`);
2624
+ }
2625
+ catch (error) {
2598
2626
  await unlinkIfExists(partialPath);
2599
- throw new Error(`${label} checksum mismatch. Expected ${expectedSha256}, got ${actualSha256}.`);
2627
+ throw error;
2600
2628
  }
2601
- await rename(partialPath, destination);
2602
- console.log(`Verified SHA256: ${actualSha256}`);
2603
2629
  }
2604
2630
  async function downloadFile(url, destination, label = "download") {
2605
2631
  const response = await fetch(url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapi-dev/sdk",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",