@trops/dash-core 0.1.349 → 0.1.351

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.
@@ -26706,6 +26706,334 @@ function parsePackageId(id) {
26706
26706
 
26707
26707
  var packageId = { toPackageId: toPackageId$1, parsePackageId };
26708
26708
 
26709
+ /**
26710
+ * registryAuthController.js
26711
+ *
26712
+ * Manages authentication with the Dash registry service.
26713
+ * Uses OAuth device code flow for desktop app authentication.
26714
+ *
26715
+ * Flow:
26716
+ * 1. App calls initiateDeviceFlow() — gets device code + verification URL
26717
+ * 2. User opens verification URL in browser, signs in, enters code
26718
+ * 3. App polls pollForToken() until authorized
26719
+ * 4. Token stored securely via electron-store (encrypted)
26720
+ */
26721
+
26722
+ const REGISTRY_BASE_URL$1 =
26723
+ process.env.DASH_REGISTRY_API_URL ||
26724
+ "https://main.d919rwhuzp7rj.amplifyapp.com";
26725
+
26726
+ // Lazy-load electron-store to avoid issues when not installed
26727
+ let store$3 = null;
26728
+ function getStore$1() {
26729
+ if (!store$3) {
26730
+ const Store = require$$1$1;
26731
+ store$3 = new Store({
26732
+ name: "dash-registry-auth",
26733
+ encryptionKey: "dash-registry-v1",
26734
+ });
26735
+ }
26736
+ return store$3;
26737
+ }
26738
+
26739
+ /**
26740
+ * Initiate the OAuth device code flow.
26741
+ * Returns the device code, user code, and verification URL.
26742
+ *
26743
+ * @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
26744
+ */
26745
+ async function initiateDeviceFlow$1() {
26746
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/device`, {
26747
+ method: "POST",
26748
+ headers: { "Content-Type": "application/json" },
26749
+ });
26750
+
26751
+ if (!response.ok) {
26752
+ throw new Error(`Device flow initiation failed: ${response.status}`);
26753
+ }
26754
+
26755
+ const data = await response.json();
26756
+
26757
+ return {
26758
+ deviceCode: data.device_code,
26759
+ userCode: data.user_code,
26760
+ verificationUrl: data.verification_uri,
26761
+ verificationUrlComplete: data.verification_uri_complete,
26762
+ expiresIn: data.expires_in,
26763
+ interval: data.interval,
26764
+ };
26765
+ }
26766
+
26767
+ /**
26768
+ * Poll the registry for token after user completes browser auth.
26769
+ *
26770
+ * @param {string} deviceCode - The device code from initiateDeviceFlow()
26771
+ * @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
26772
+ */
26773
+ async function pollForToken$1(deviceCode) {
26774
+ const response = await fetch(
26775
+ `${REGISTRY_BASE_URL$1}/api/auth/device?device_code=${encodeURIComponent(deviceCode)}`,
26776
+ );
26777
+
26778
+ if (response.status === 428) {
26779
+ return { status: "pending" };
26780
+ }
26781
+
26782
+ if (response.status === 400) {
26783
+ const data = await response.json();
26784
+ if (data.error === "expired_token") {
26785
+ return { status: "expired" };
26786
+ }
26787
+ return { status: "pending" };
26788
+ }
26789
+
26790
+ if (response.ok) {
26791
+ const data = await response.json();
26792
+
26793
+ // Store the token securely
26794
+ const s = getStore$1();
26795
+ s.set("accessToken", data.access_token);
26796
+ s.set("userId", data.user_id);
26797
+ s.set("tokenType", data.token_type);
26798
+ s.set("authenticatedAt", new Date().toISOString());
26799
+
26800
+ return {
26801
+ status: "authorized",
26802
+ token: data.access_token,
26803
+ userId: data.user_id,
26804
+ };
26805
+ }
26806
+
26807
+ throw new Error(`Unexpected response: ${response.status}`);
26808
+ }
26809
+
26810
+ /**
26811
+ * Get the stored auth token.
26812
+ *
26813
+ * @returns {Object|null} { token, userId, authenticatedAt } or null if not authenticated
26814
+ */
26815
+ function getStoredToken$4() {
26816
+ try {
26817
+ const s = getStore$1();
26818
+ const token = s.get("accessToken");
26819
+ if (!token) return null;
26820
+
26821
+ return {
26822
+ token,
26823
+ userId: s.get("userId"),
26824
+ authenticatedAt: s.get("authenticatedAt"),
26825
+ };
26826
+ } catch {
26827
+ return null;
26828
+ }
26829
+ }
26830
+
26831
+ /**
26832
+ * Check if the user is authenticated with the registry.
26833
+ *
26834
+ * @returns {Object} { authenticated: boolean, userId?: string }
26835
+ */
26836
+ function getAuthStatus$1() {
26837
+ const stored = getStoredToken$4();
26838
+ if (!stored) {
26839
+ return { authenticated: false };
26840
+ }
26841
+
26842
+ return {
26843
+ authenticated: true,
26844
+ userId: stored.userId,
26845
+ authenticatedAt: stored.authenticatedAt,
26846
+ };
26847
+ }
26848
+
26849
+ /**
26850
+ * Get the user's registry profile.
26851
+ *
26852
+ * @returns {Promise<Object|null>} User profile or null
26853
+ */
26854
+ async function getRegistryProfile$2() {
26855
+ const stored = getStoredToken$4();
26856
+ if (!stored) return null;
26857
+
26858
+ try {
26859
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
26860
+ headers: {
26861
+ Authorization: `Bearer ${stored.token}`,
26862
+ },
26863
+ });
26864
+
26865
+ if (response.status === 401) {
26866
+ // Token expired or invalid — clear stored credentials
26867
+ clearToken$2();
26868
+ return null;
26869
+ }
26870
+ if (!response.ok) return null;
26871
+
26872
+ const data = await response.json();
26873
+ return data.user || null;
26874
+ } catch {
26875
+ return null;
26876
+ }
26877
+ }
26878
+
26879
+ /**
26880
+ * Clear stored auth token (logout).
26881
+ */
26882
+ function clearToken$2() {
26883
+ try {
26884
+ const s = getStore$1();
26885
+ s.clear();
26886
+ console.log("[RegistryAuthController] Token cleared");
26887
+ } catch (err) {
26888
+ console.error("[RegistryAuthController] Error clearing token:", err);
26889
+ }
26890
+ }
26891
+
26892
+ /**
26893
+ * Update the authenticated user's registry profile.
26894
+ *
26895
+ * @param {Object} updates - Fields to update (e.g. { displayName })
26896
+ * @returns {Promise<Object|null>} Updated user or null on 401
26897
+ */
26898
+ async function updateRegistryProfile$1(updates) {
26899
+ const stored = getStoredToken$4();
26900
+ if (!stored) return null;
26901
+
26902
+ try {
26903
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
26904
+ method: "PATCH",
26905
+ headers: {
26906
+ Authorization: `Bearer ${stored.token}`,
26907
+ "Content-Type": "application/json",
26908
+ },
26909
+ body: JSON.stringify(updates),
26910
+ });
26911
+
26912
+ if (response.status === 401) {
26913
+ clearToken$2();
26914
+ return null;
26915
+ }
26916
+ if (!response.ok) return null;
26917
+
26918
+ const data = await response.json();
26919
+ return data.user || null;
26920
+ } catch {
26921
+ return null;
26922
+ }
26923
+ }
26924
+
26925
+ /**
26926
+ * Get the authenticated user's published packages.
26927
+ *
26928
+ * @returns {Promise<Object|null>} { packages: [...] } or null
26929
+ */
26930
+ async function getRegistryPackages$1() {
26931
+ const stored = getStoredToken$4();
26932
+ if (!stored) return null;
26933
+
26934
+ try {
26935
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me/packages`, {
26936
+ headers: {
26937
+ Authorization: `Bearer ${stored.token}`,
26938
+ },
26939
+ });
26940
+
26941
+ if (response.status === 401) {
26942
+ clearToken$2();
26943
+ return null;
26944
+ }
26945
+ if (!response.ok) return null;
26946
+
26947
+ return await response.json();
26948
+ } catch {
26949
+ return null;
26950
+ }
26951
+ }
26952
+
26953
+ /**
26954
+ * Update a published package's metadata.
26955
+ *
26956
+ * @param {string} scope - Package scope (e.g. "@trops")
26957
+ * @param {string} name - Package name
26958
+ * @param {Object} updates - Fields to update (displayName, description, category, tags, visibility)
26959
+ * @returns {Promise<Object|null>} Updated package or null
26960
+ */
26961
+ async function updateRegistryPackage$1(scope, name, updates) {
26962
+ const stored = getStoredToken$4();
26963
+ if (!stored) return null;
26964
+
26965
+ try {
26966
+ const response = await fetch(
26967
+ `${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
26968
+ {
26969
+ method: "PATCH",
26970
+ headers: {
26971
+ Authorization: `Bearer ${stored.token}`,
26972
+ "Content-Type": "application/json",
26973
+ },
26974
+ body: JSON.stringify(updates),
26975
+ },
26976
+ );
26977
+
26978
+ if (response.status === 401) {
26979
+ clearToken$2();
26980
+ return null;
26981
+ }
26982
+ if (!response.ok) return null;
26983
+
26984
+ return await response.json();
26985
+ } catch {
26986
+ return null;
26987
+ }
26988
+ }
26989
+
26990
+ /**
26991
+ * Delete a published package from the registry.
26992
+ *
26993
+ * @param {string} scope - Package scope (e.g. "@trops")
26994
+ * @param {string} name - Package name
26995
+ * @returns {Promise<Object|null>} Response or null
26996
+ */
26997
+ async function deleteRegistryPackage(scope, name) {
26998
+ const stored = getStoredToken$4();
26999
+ if (!stored) return null;
27000
+
27001
+ try {
27002
+ const response = await fetch(
27003
+ `${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
27004
+ {
27005
+ method: "DELETE",
27006
+ headers: {
27007
+ Authorization: `Bearer ${stored.token}`,
27008
+ },
27009
+ },
27010
+ );
27011
+
27012
+ if (response.status === 401) {
27013
+ clearToken$2();
27014
+ return null;
27015
+ }
27016
+ if (!response.ok) return null;
27017
+
27018
+ return await response.json();
27019
+ } catch {
27020
+ return null;
27021
+ }
27022
+ }
27023
+
27024
+ var registryAuthController$2 = {
27025
+ initiateDeviceFlow: initiateDeviceFlow$1,
27026
+ pollForToken: pollForToken$1,
27027
+ getStoredToken: getStoredToken$4,
27028
+ getAuthStatus: getAuthStatus$1,
27029
+ getRegistryProfile: getRegistryProfile$2,
27030
+ updateRegistryProfile: updateRegistryProfile$1,
27031
+ getRegistryPackages: getRegistryPackages$1,
27032
+ updateRegistryPackage: updateRegistryPackage$1,
27033
+ deleteRegistryPackage,
27034
+ clearToken: clearToken$2,
27035
+ };
27036
+
26709
27037
  /**
26710
27038
  * registryController.js
26711
27039
  *
@@ -26721,6 +27049,18 @@ var packageId = { toPackageId: toPackageId$1, parsePackageId };
26721
27049
  const path$a = require$$1$2;
26722
27050
  const fs$6 = require$$0$2;
26723
27051
  const { toPackageId } = packageId;
27052
+ const { getStoredToken: getStoredToken$3 } = registryAuthController$2;
27053
+
27054
+ /**
27055
+ * Build request headers for the registry. When the user is signed in, we
27056
+ * include the Bearer token so the server returns private packages that
27057
+ * the user owns or has been granted entitlements for. Anonymous fetches
27058
+ * still work and simply return only public packages.
27059
+ */
27060
+ function buildAuthHeaders() {
27061
+ const stored = getStoredToken$3();
27062
+ return stored?.token ? { Authorization: `Bearer ${stored.token}` } : {};
27063
+ }
26724
27064
 
26725
27065
  // Default registry API base URL
26726
27066
  const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
@@ -26728,8 +27068,15 @@ const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
26728
27068
  // Cache TTL: 5 minutes
26729
27069
  const CACHE_TTL_MS = 5 * 60 * 1000;
26730
27070
 
26731
- let cachedIndex = null;
26732
- let cacheTimestamp = 0;
27071
+ // Cache is keyed by userId so anonymous + authenticated results don't mix.
27072
+ // When a user signs in, their cache entry is empty and gets populated with
27073
+ // their owned/entitled private packages alongside the public set.
27074
+ const caches = new Map(); // userId | "anon" -> { data, timestamp }
27075
+
27076
+ function getCacheKey() {
27077
+ const stored = getStoredToken$3();
27078
+ return stored?.userId || "anon";
27079
+ }
26733
27080
 
26734
27081
  /**
26735
27082
  * Get the local test registry path for dev mode
@@ -26758,11 +27105,15 @@ function isDev() {
26758
27105
  */
26759
27106
  async function fetchRegistryIndex(forceRefresh = false) {
26760
27107
  const now = Date.now();
27108
+ const cacheKey = getCacheKey();
27109
+ const cached = caches.get(cacheKey);
26761
27110
 
26762
27111
  // Return cached data if still valid
26763
- if (!forceRefresh && cachedIndex && now - cacheTimestamp < CACHE_TTL_MS) {
26764
- console.log("[RegistryController] Returning cached registry index");
26765
- return cachedIndex;
27112
+ if (!forceRefresh && cached && now - cached.timestamp < CACHE_TTL_MS) {
27113
+ console.log(
27114
+ `[RegistryController] Returning cached registry index (key=${cacheKey})`,
27115
+ );
27116
+ return cached.data;
26766
27117
  }
26767
27118
 
26768
27119
  try {
@@ -26787,7 +27138,9 @@ async function fetchRegistryIndex(forceRefresh = false) {
26787
27138
  "[RegistryController] Fetching registry from:",
26788
27139
  registryUrl,
26789
27140
  );
26790
- const response = await fetch(registryUrl);
27141
+ const response = await fetch(registryUrl, {
27142
+ headers: buildAuthHeaders(),
27143
+ });
26791
27144
  if (!response.ok) {
26792
27145
  throw new Error(
26793
27146
  `Failed to fetch registry: ${response.status} ${response.statusText}`,
@@ -26802,7 +27155,9 @@ async function fetchRegistryIndex(forceRefresh = false) {
26802
27155
  `${process.env.DASH_REGISTRY_API_URL || DEFAULT_REGISTRY_API_URL}/api/packages`;
26803
27156
  console.log("[RegistryController] Fetching registry from:", registryUrl);
26804
27157
 
26805
- const response = await fetch(registryUrl);
27158
+ const response = await fetch(registryUrl, {
27159
+ headers: buildAuthHeaders(),
27160
+ });
26806
27161
  if (!response.ok) {
26807
27162
  throw new Error(
26808
27163
  `Failed to fetch registry: ${response.status} ${response.statusText}`,
@@ -26820,22 +27175,22 @@ async function fetchRegistryIndex(forceRefresh = false) {
26820
27175
  }
26821
27176
 
26822
27177
  // Cache the result
26823
- cachedIndex = indexData;
26824
- cacheTimestamp = now;
27178
+ caches.set(cacheKey, { data: indexData, timestamp: now });
26825
27179
 
26826
27180
  console.log(
26827
- `[RegistryController] Loaded ${indexData.packages?.length || 0} packages`,
27181
+ `[RegistryController] Loaded ${indexData.packages?.length || 0} packages (key=${cacheKey})`,
26828
27182
  );
26829
27183
  return indexData;
26830
27184
  } catch (error) {
26831
27185
  console.error("[RegistryController] Error fetching registry:", error);
26832
27186
 
26833
27187
  // Return stale cache if available
26834
- if (cachedIndex) {
27188
+ const stale = caches.get(cacheKey);
27189
+ if (stale) {
26835
27190
  console.log(
26836
27191
  "[RegistryController] Returning stale cache after fetch error",
26837
27192
  );
26838
- return cachedIndex;
27193
+ return stale.data;
26839
27194
  }
26840
27195
 
26841
27196
  throw error;
@@ -49316,334 +49671,6 @@ const mcpDashServerController$4 = {
49316
49671
 
49317
49672
  var mcpDashServerController_1 = mcpDashServerController$4;
49318
49673
 
49319
- /**
49320
- * registryAuthController.js
49321
- *
49322
- * Manages authentication with the Dash registry service.
49323
- * Uses OAuth device code flow for desktop app authentication.
49324
- *
49325
- * Flow:
49326
- * 1. App calls initiateDeviceFlow() — gets device code + verification URL
49327
- * 2. User opens verification URL in browser, signs in, enters code
49328
- * 3. App polls pollForToken() until authorized
49329
- * 4. Token stored securely via electron-store (encrypted)
49330
- */
49331
-
49332
- const REGISTRY_BASE_URL$1 =
49333
- process.env.DASH_REGISTRY_API_URL ||
49334
- "https://main.d919rwhuzp7rj.amplifyapp.com";
49335
-
49336
- // Lazy-load electron-store to avoid issues when not installed
49337
- let store$3 = null;
49338
- function getStore$1() {
49339
- if (!store$3) {
49340
- const Store = require$$1$1;
49341
- store$3 = new Store({
49342
- name: "dash-registry-auth",
49343
- encryptionKey: "dash-registry-v1",
49344
- });
49345
- }
49346
- return store$3;
49347
- }
49348
-
49349
- /**
49350
- * Initiate the OAuth device code flow.
49351
- * Returns the device code, user code, and verification URL.
49352
- *
49353
- * @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
49354
- */
49355
- async function initiateDeviceFlow$1() {
49356
- const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/device`, {
49357
- method: "POST",
49358
- headers: { "Content-Type": "application/json" },
49359
- });
49360
-
49361
- if (!response.ok) {
49362
- throw new Error(`Device flow initiation failed: ${response.status}`);
49363
- }
49364
-
49365
- const data = await response.json();
49366
-
49367
- return {
49368
- deviceCode: data.device_code,
49369
- userCode: data.user_code,
49370
- verificationUrl: data.verification_uri,
49371
- verificationUrlComplete: data.verification_uri_complete,
49372
- expiresIn: data.expires_in,
49373
- interval: data.interval,
49374
- };
49375
- }
49376
-
49377
- /**
49378
- * Poll the registry for token after user completes browser auth.
49379
- *
49380
- * @param {string} deviceCode - The device code from initiateDeviceFlow()
49381
- * @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
49382
- */
49383
- async function pollForToken$1(deviceCode) {
49384
- const response = await fetch(
49385
- `${REGISTRY_BASE_URL$1}/api/auth/device?device_code=${encodeURIComponent(deviceCode)}`,
49386
- );
49387
-
49388
- if (response.status === 428) {
49389
- return { status: "pending" };
49390
- }
49391
-
49392
- if (response.status === 400) {
49393
- const data = await response.json();
49394
- if (data.error === "expired_token") {
49395
- return { status: "expired" };
49396
- }
49397
- return { status: "pending" };
49398
- }
49399
-
49400
- if (response.ok) {
49401
- const data = await response.json();
49402
-
49403
- // Store the token securely
49404
- const s = getStore$1();
49405
- s.set("accessToken", data.access_token);
49406
- s.set("userId", data.user_id);
49407
- s.set("tokenType", data.token_type);
49408
- s.set("authenticatedAt", new Date().toISOString());
49409
-
49410
- return {
49411
- status: "authorized",
49412
- token: data.access_token,
49413
- userId: data.user_id,
49414
- };
49415
- }
49416
-
49417
- throw new Error(`Unexpected response: ${response.status}`);
49418
- }
49419
-
49420
- /**
49421
- * Get the stored auth token.
49422
- *
49423
- * @returns {Object|null} { token, userId, authenticatedAt } or null if not authenticated
49424
- */
49425
- function getStoredToken$3() {
49426
- try {
49427
- const s = getStore$1();
49428
- const token = s.get("accessToken");
49429
- if (!token) return null;
49430
-
49431
- return {
49432
- token,
49433
- userId: s.get("userId"),
49434
- authenticatedAt: s.get("authenticatedAt"),
49435
- };
49436
- } catch {
49437
- return null;
49438
- }
49439
- }
49440
-
49441
- /**
49442
- * Check if the user is authenticated with the registry.
49443
- *
49444
- * @returns {Object} { authenticated: boolean, userId?: string }
49445
- */
49446
- function getAuthStatus$1() {
49447
- const stored = getStoredToken$3();
49448
- if (!stored) {
49449
- return { authenticated: false };
49450
- }
49451
-
49452
- return {
49453
- authenticated: true,
49454
- userId: stored.userId,
49455
- authenticatedAt: stored.authenticatedAt,
49456
- };
49457
- }
49458
-
49459
- /**
49460
- * Get the user's registry profile.
49461
- *
49462
- * @returns {Promise<Object|null>} User profile or null
49463
- */
49464
- async function getRegistryProfile$2() {
49465
- const stored = getStoredToken$3();
49466
- if (!stored) return null;
49467
-
49468
- try {
49469
- const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
49470
- headers: {
49471
- Authorization: `Bearer ${stored.token}`,
49472
- },
49473
- });
49474
-
49475
- if (response.status === 401) {
49476
- // Token expired or invalid — clear stored credentials
49477
- clearToken$2();
49478
- return null;
49479
- }
49480
- if (!response.ok) return null;
49481
-
49482
- const data = await response.json();
49483
- return data.user || null;
49484
- } catch {
49485
- return null;
49486
- }
49487
- }
49488
-
49489
- /**
49490
- * Clear stored auth token (logout).
49491
- */
49492
- function clearToken$2() {
49493
- try {
49494
- const s = getStore$1();
49495
- s.clear();
49496
- console.log("[RegistryAuthController] Token cleared");
49497
- } catch (err) {
49498
- console.error("[RegistryAuthController] Error clearing token:", err);
49499
- }
49500
- }
49501
-
49502
- /**
49503
- * Update the authenticated user's registry profile.
49504
- *
49505
- * @param {Object} updates - Fields to update (e.g. { displayName })
49506
- * @returns {Promise<Object|null>} Updated user or null on 401
49507
- */
49508
- async function updateRegistryProfile$1(updates) {
49509
- const stored = getStoredToken$3();
49510
- if (!stored) return null;
49511
-
49512
- try {
49513
- const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
49514
- method: "PATCH",
49515
- headers: {
49516
- Authorization: `Bearer ${stored.token}`,
49517
- "Content-Type": "application/json",
49518
- },
49519
- body: JSON.stringify(updates),
49520
- });
49521
-
49522
- if (response.status === 401) {
49523
- clearToken$2();
49524
- return null;
49525
- }
49526
- if (!response.ok) return null;
49527
-
49528
- const data = await response.json();
49529
- return data.user || null;
49530
- } catch {
49531
- return null;
49532
- }
49533
- }
49534
-
49535
- /**
49536
- * Get the authenticated user's published packages.
49537
- *
49538
- * @returns {Promise<Object|null>} { packages: [...] } or null
49539
- */
49540
- async function getRegistryPackages$1() {
49541
- const stored = getStoredToken$3();
49542
- if (!stored) return null;
49543
-
49544
- try {
49545
- const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me/packages`, {
49546
- headers: {
49547
- Authorization: `Bearer ${stored.token}`,
49548
- },
49549
- });
49550
-
49551
- if (response.status === 401) {
49552
- clearToken$2();
49553
- return null;
49554
- }
49555
- if (!response.ok) return null;
49556
-
49557
- return await response.json();
49558
- } catch {
49559
- return null;
49560
- }
49561
- }
49562
-
49563
- /**
49564
- * Update a published package's metadata.
49565
- *
49566
- * @param {string} scope - Package scope (e.g. "@trops")
49567
- * @param {string} name - Package name
49568
- * @param {Object} updates - Fields to update (displayName, description, category, tags, visibility)
49569
- * @returns {Promise<Object|null>} Updated package or null
49570
- */
49571
- async function updateRegistryPackage$1(scope, name, updates) {
49572
- const stored = getStoredToken$3();
49573
- if (!stored) return null;
49574
-
49575
- try {
49576
- const response = await fetch(
49577
- `${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
49578
- {
49579
- method: "PATCH",
49580
- headers: {
49581
- Authorization: `Bearer ${stored.token}`,
49582
- "Content-Type": "application/json",
49583
- },
49584
- body: JSON.stringify(updates),
49585
- },
49586
- );
49587
-
49588
- if (response.status === 401) {
49589
- clearToken$2();
49590
- return null;
49591
- }
49592
- if (!response.ok) return null;
49593
-
49594
- return await response.json();
49595
- } catch {
49596
- return null;
49597
- }
49598
- }
49599
-
49600
- /**
49601
- * Delete a published package from the registry.
49602
- *
49603
- * @param {string} scope - Package scope (e.g. "@trops")
49604
- * @param {string} name - Package name
49605
- * @returns {Promise<Object|null>} Response or null
49606
- */
49607
- async function deleteRegistryPackage(scope, name) {
49608
- const stored = getStoredToken$3();
49609
- if (!stored) return null;
49610
-
49611
- try {
49612
- const response = await fetch(
49613
- `${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
49614
- {
49615
- method: "DELETE",
49616
- headers: {
49617
- Authorization: `Bearer ${stored.token}`,
49618
- },
49619
- },
49620
- );
49621
-
49622
- if (response.status === 401) {
49623
- clearToken$2();
49624
- return null;
49625
- }
49626
- if (!response.ok) return null;
49627
-
49628
- return await response.json();
49629
- } catch {
49630
- return null;
49631
- }
49632
- }
49633
-
49634
- var registryAuthController$2 = {
49635
- initiateDeviceFlow: initiateDeviceFlow$1,
49636
- pollForToken: pollForToken$1,
49637
- getStoredToken: getStoredToken$3,
49638
- getAuthStatus: getAuthStatus$1,
49639
- getRegistryProfile: getRegistryProfile$2,
49640
- updateRegistryProfile: updateRegistryProfile$1,
49641
- getRegistryPackages: getRegistryPackages$1,
49642
- updateRegistryPackage: updateRegistryPackage$1,
49643
- deleteRegistryPackage,
49644
- clearToken: clearToken$2,
49645
- };
49646
-
49647
49674
  var widgetRegistry$1 = {exports: {}};
49648
49675
 
49649
49676
  var dynamicWidgetLoader$2 = {exports: {}};
@@ -62711,6 +62738,7 @@ const { toDisplayColor: toDisplayColor$1 } = require$$8;
62711
62738
  * @param {string} options.category - Registry category (default: "general")
62712
62739
  * @param {string} options.repository - Repository URL (optional)
62713
62740
  * @param {string} options.appOrigin - Originating app package name (optional)
62741
+ * @param {"public"|"private"} options.visibility - Initial visibility (default: "public")
62714
62742
  * @returns {Object} Registry manifest object
62715
62743
  */
62716
62744
  function generateRegistryManifest(dashboardConfig, options = {}) {
@@ -62721,6 +62749,7 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
62721
62749
 
62722
62750
  const githubUser = options.githubUser || "";
62723
62751
  const version = "1.0.0";
62752
+ const visibility = options.visibility === "private" ? "private" : "public";
62724
62753
 
62725
62754
  const manifest = {
62726
62755
  githubUser,
@@ -62729,6 +62758,7 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
62729
62758
  author: dashboardConfig.author?.name || "",
62730
62759
  description: dashboardConfig.description || "",
62731
62760
  version,
62761
+ visibility,
62732
62762
  type: "dashboard",
62733
62763
  category: options.category || "general",
62734
62764
  tags: dashboardConfig.tags || [],
@@ -63117,13 +63147,14 @@ function sanitizeName(name) {
63117
63147
  *
63118
63148
  * @param {Object} themeData - The raw theme object
63119
63149
  * @param {string} themeKey - The theme key/name
63120
- * @param {Object} options - Publish options { authorName, description, tags, scope }
63150
+ * @param {Object} options - Publish options { authorName, description, tags, scope, visibility }
63121
63151
  * @returns {Object} Registry manifest
63122
63152
  */
63123
63153
  function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
63124
63154
  const humanName = themeData.name || themeKey;
63125
63155
  const sanitizedName = sanitizeName(humanName);
63126
63156
  const colors = extractColors(themeData);
63157
+ const visibility = options.visibility === "private" ? "private" : "public";
63127
63158
 
63128
63159
  return {
63129
63160
  scope: options.scope || "",
@@ -63132,6 +63163,7 @@ function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
63132
63163
  author: options.authorName || "",
63133
63164
  description: options.description || "",
63134
63165
  version: "1.0.0",
63166
+ visibility,
63135
63167
  type: "theme",
63136
63168
  category: "general",
63137
63169
  tags: options.tags || [],
@@ -64888,6 +64920,7 @@ async function prepareDashboardForPublish$1(
64888
64920
  category: options.category || "general",
64889
64921
  repository: options.repository || "",
64890
64922
  appOrigin: appId,
64923
+ visibility: options.visibility || "public",
64891
64924
  });
64892
64925
 
64893
64926
  // 9. Show save dialog for the publish package