deepspace 0.6.0 → 0.6.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # deepspace
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Make silent failures visible. `RecordProvider` now accepts an `onWriteError` prop (`(error: WriteError) => void`, where `WriteError` is `{ kind: 'permission' | 'validation', title, detail }`) — previously the friendly-error pipeline (server rejection → `parseServerError` → callback) was unreachable from the public API, so a denied or invalid optimistic write looked like a success with no signal anywhere. Unhandled rejections fall back to a loud `console.error` explaining how to wire real UI (note: this fires in production too — existing apps that never wired a handler will start logging rejected writes to the console; each unique error logs once, repeats are suppressed), and the starter template routes `onWriteError` to its toast system out of the box (permission → warning toast, validation → error toast). On localhost, a signed-out `RecordProvider` without `allowAnonymous` renders a visible diagnostic instead of a blank page (production still renders nothing), and passing `schemas` alongside `roomId` (where it's ignored) warns once; both diagnostics can be forced on or off via `globalThis.DEEPSPACE_DEV = true | false` (LAN/tunnel previews, consumer test suites). `deepspace dev` and `deepspace deploy` now run schema lint up front and print findings (e.g. a `visibilityField` no role enforces) in the terminal, capped at 5 with an overflow count — previously these only appeared in the worker console after a client connected.
8
+
3
9
  ## 0.6.0
4
10
 
5
11
  ### Minor Changes
package/dist/cli.js CHANGED
@@ -3,8 +3,8 @@
3
3
  // src/cli/cli.ts
4
4
  import { defineCommand as defineCommand22, runMain } from "citty";
5
5
  import { spawnSync as spawnSync6 } from "child_process";
6
- import { readFileSync as readFileSync17, existsSync as existsSync14 } from "fs";
7
- import { dirname as dirname5, join as join15 } from "path";
6
+ import { readFileSync as readFileSync17, existsSync as existsSync15 } from "fs";
7
+ import { dirname as dirname5, join as join16 } from "path";
8
8
  import { fileURLToPath as fileURLToPath3 } from "url";
9
9
 
10
10
  // src/cli/lib/cli-errors.ts
@@ -1342,7 +1342,7 @@ var logout_default = defineCommand2({
1342
1342
 
1343
1343
  // src/cli/commands/dev.ts
1344
1344
  import { defineCommand as defineCommand3 } from "citty";
1345
- import { resolve as resolve4, basename as basename2, join as join9 } from "path";
1345
+ import { resolve as resolve4, basename as basename2, join as join10 } from "path";
1346
1346
  import spawn from "cross-spawn";
1347
1347
 
1348
1348
  // src/cli/auth.ts
@@ -1788,6 +1788,112 @@ function removeMacosJunk(dir) {
1788
1788
  return removed;
1789
1789
  }
1790
1790
 
1791
+ // src/cli/lib/schema-lint.ts
1792
+ import { existsSync as existsSync9 } from "fs";
1793
+ import { join as join9 } from "path";
1794
+ import { pathToFileURL } from "url";
1795
+
1796
+ // src/server/schemas/registry.ts
1797
+ var USERS_COLUMNS = [
1798
+ { name: "email", storage: "text", interpretation: "plain" },
1799
+ { name: "name", storage: "text", interpretation: "plain" },
1800
+ { name: "imageUrl", storage: "text", interpretation: "plain" },
1801
+ { name: "role", storage: "text", interpretation: "plain" },
1802
+ { name: "createdAt", storage: "text", interpretation: { kind: "datetime" } },
1803
+ { name: "lastSeenAt", storage: "text", interpretation: { kind: "datetime" } }
1804
+ ];
1805
+ var BASE_USERS_SCHEMA = {
1806
+ name: "users",
1807
+ columns: [...USERS_COLUMNS],
1808
+ permissions: {
1809
+ "*": { read: "own", create: false, update: false, delete: false },
1810
+ admin: { read: true, create: false, update: true, delete: true }
1811
+ }
1812
+ };
1813
+ function lintSchema(schema) {
1814
+ const warnings = [];
1815
+ const VISIBILITY_AWARE = ["published", "shared"];
1816
+ if (schema.visibilityField) {
1817
+ const offendingRoles = Object.entries(schema.permissions).filter(([, perms]) => perms.read === true).map(([role]) => role);
1818
+ if (offendingRoles.length > 0) {
1819
+ const usesAware = Object.values(schema.permissions).some(
1820
+ (p10) => typeof p10.read === "string" && VISIBILITY_AWARE.includes(p10.read)
1821
+ );
1822
+ if (!usesAware) {
1823
+ warnings.push(
1824
+ `[${schema.name}] visibilityField is declared but no role uses read: 'published' or 'shared'. Roles with read: true (${offendingRoles.join(", ")}) will see every row regardless of visibility. Change those to read: 'published' (owner OR public) or 'shared' (owner OR collaborator OR public) to actually enforce the filter, or remove visibilityField if you don't intend to gate reads by it.`
1825
+ );
1826
+ }
1827
+ }
1828
+ }
1829
+ if (schema.ownerField) {
1830
+ const col = schema.columns.find((c) => c.name === schema.ownerField);
1831
+ if (col && !col.userBound) {
1832
+ warnings.push(
1833
+ `[${schema.name}] ownerField is '${schema.ownerField}' but that column is not marked userBound: true. A client can create a row with someone else's id in this field, bypassing 'own' permission checks. Add userBound: true (and ideally immutable: true) to the column.`
1834
+ );
1835
+ }
1836
+ }
1837
+ for (const col of schema.columns) {
1838
+ if (col.userBound && col.storage !== "text") {
1839
+ warnings.push(
1840
+ `[${schema.name}] column '${col.name}' is userBound but storage is '${col.storage}'. userBound stamps the user id (a string); use storage: 'text'.`
1841
+ );
1842
+ }
1843
+ }
1844
+ return warnings;
1845
+ }
1846
+
1847
+ // src/cli/lib/schema-lint.ts
1848
+ async function lintProjectSchemas(appDir) {
1849
+ const schemasPath = join9(appDir, "src", "schemas.ts");
1850
+ if (!existsSync9(schemasPath)) return null;
1851
+ let schemas;
1852
+ try {
1853
+ const esbuild = await import("esbuild");
1854
+ const outFile = join9(appDir, ".wrangler", "deploy", "schemas.lint.bundle.mjs");
1855
+ await esbuild.build({
1856
+ entryPoints: [schemasPath],
1857
+ bundle: true,
1858
+ format: "esm",
1859
+ platform: "node",
1860
+ target: "node18",
1861
+ outfile: outFile,
1862
+ logLevel: "silent",
1863
+ write: true
1864
+ });
1865
+ const mod = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
1866
+ schemas = mod.schemas;
1867
+ } catch {
1868
+ console.warn(
1869
+ "Schema lint skipped: could not bundle src/schemas.ts (the worker still lints at runtime)."
1870
+ );
1871
+ return null;
1872
+ }
1873
+ if (!Array.isArray(schemas)) return null;
1874
+ const findings = [];
1875
+ for (const schema of schemas) {
1876
+ if (!schema || typeof schema !== "object") continue;
1877
+ try {
1878
+ findings.push(...lintSchema(schema));
1879
+ } catch {
1880
+ }
1881
+ }
1882
+ return findings;
1883
+ }
1884
+ var MAX_PRINTED_FINDINGS = 5;
1885
+ function formatSchemaLintFindings(findings) {
1886
+ if (findings.length === 0) return [];
1887
+ const n = findings.length;
1888
+ const shown = findings.slice(0, MAX_PRINTED_FINDINGS);
1889
+ const hidden = n - shown.length;
1890
+ return [
1891
+ `Schema lint: ${n} warning${n === 1 ? "" : "s"} in src/schemas.ts \u2014 ${n === 1 ? "this ships" : "these ship"} as permission/privacy bugs:`,
1892
+ ...shown.map((f) => ` \u2022 ${f}`),
1893
+ ...hidden > 0 ? [` \u2026and ${hidden} more \u2014 fix the above and re-run to see the rest.`] : []
1894
+ ];
1895
+ }
1896
+
1791
1897
  // src/cli/lib/port.ts
1792
1898
  import { createServer } from "net";
1793
1899
  var DEFAULT_PORT = 5173;
@@ -1874,7 +1980,7 @@ var dev_default = defineCommand3({
1874
1980
  );
1875
1981
  } else {
1876
1982
  console.warn(
1877
- `Warning: could not update ${join9(worktree.mainRepoRoot, ".claude", "launch.json")} (malformed or unwritable) \u2014 the Claude preview tool may serve the main repo's code instead of this worktree.`
1983
+ `Warning: could not update ${join10(worktree.mainRepoRoot, ".claude", "launch.json")} (malformed or unwritable) \u2014 the Claude preview tool may serve the main repo's code instead of this worktree.`
1878
1984
  );
1879
1985
  }
1880
1986
  if (!explicitPort && process.env.DEEPSPACE_PORT) {
@@ -1887,6 +1993,10 @@ var dev_default = defineCommand3({
1887
1993
  updatePort: explicitPort
1888
1994
  });
1889
1995
  ensureInstallReady(appDir);
1996
+ const lintFindings = await lintProjectSchemas(appDir);
1997
+ if (lintFindings && lintFindings.length > 0) {
1998
+ for (const line of formatSchemaLintFindings(lintFindings)) console.warn(line);
1999
+ }
1890
2000
  let token;
1891
2001
  try {
1892
2002
  token = await ensureToken();
@@ -2474,15 +2584,15 @@ var screenshot_default = defineCommand6({
2474
2584
  // src/cli/commands/test-accounts.ts
2475
2585
  import { defineCommand as defineCommand7 } from "citty";
2476
2586
  import * as p3 from "@clack/prompts";
2477
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
2478
- import { join as join10 } from "path";
2587
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
2588
+ import { join as join11 } from "path";
2479
2589
  import { homedir as homedir4 } from "os";
2480
2590
  var SESSION_COOKIE2 = "__Secure-better-auth.session_token";
2481
2591
  var AUTH_URL4 = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth;
2482
- var DIR3 = join10(homedir4(), ".deepspace");
2483
- var ACCOUNTS_PATH = join10(DIR3, "test-accounts.json");
2592
+ var DIR3 = join11(homedir4(), ".deepspace");
2593
+ var ACCOUNTS_PATH = join11(DIR3, "test-accounts.json");
2484
2594
  function loadAccounts() {
2485
- if (!existsSync9(ACCOUNTS_PATH)) return [];
2595
+ if (!existsSync10(ACCOUNTS_PATH)) return [];
2486
2596
  try {
2487
2597
  return JSON.parse(readFileSync10(ACCOUNTS_PATH, "utf-8"));
2488
2598
  } catch {
@@ -2764,9 +2874,9 @@ var test_accounts_default = defineCommand7({
2764
2874
  import { defineCommand as defineCommand8 } from "citty";
2765
2875
  import { execSync as execSync2 } from "child_process";
2766
2876
  import { randomUUID } from "crypto";
2767
- import { readFileSync as readFileSync11, readdirSync as readdirSync4, existsSync as existsSync10 } from "fs";
2768
- import { join as join11, resolve as resolve7, dirname as dirname2 } from "path";
2769
- import { pathToFileURL } from "url";
2877
+ import { readFileSync as readFileSync11, readdirSync as readdirSync4, existsSync as existsSync11 } from "fs";
2878
+ import { join as join12, resolve as resolve7, dirname as dirname2 } from "path";
2879
+ import { pathToFileURL as pathToFileURL2 } from "url";
2770
2880
  import * as p4 from "@clack/prompts";
2771
2881
  var DEPLOY_URL3 = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy;
2772
2882
  var API_URL2 = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api;
@@ -2978,7 +3088,7 @@ var deploy_default = defineCommand8({
2978
3088
  }
2979
3089
  p4.log.info(`Id: ${appId}`);
2980
3090
  const readCustomDevVarsAt = (path) => {
2981
- if (!existsSync10(path)) return {};
3091
+ if (!existsSync11(path)) return {};
2982
3092
  const section = extractCustomDevVars(stripGeneratedSecretsCache(readFileSync11(path, "utf-8")));
2983
3093
  if (!section) return {};
2984
3094
  try {
@@ -3017,6 +3127,10 @@ var deploy_default = defineCommand8({
3017
3127
  }
3018
3128
  const junk = removeMacosJunk(appDir);
3019
3129
  if (junk > 0) p4.log.info(`Removed ${junk} macOS metadata file(s) (._*, .DS_Store)`);
3130
+ const lintFindings = await lintProjectSchemas(appDir);
3131
+ if (lintFindings && lintFindings.length > 0) {
3132
+ p4.log.warn(formatSchemaLintFindings(lintFindings).join("\n"));
3133
+ }
3020
3134
  const s = createSpinner();
3021
3135
  s.start("Building...");
3022
3136
  let preparedWranglerConfig;
@@ -3039,14 +3153,14 @@ var deploy_default = defineCommand8({
3039
3153
  preparedWranglerConfig?.cleanup();
3040
3154
  }
3041
3155
  s.stop("Built");
3042
- const deployConfigPath = join11(appDir, ".wrangler", "deploy", "config.json");
3043
- if (!existsSync10(deployConfigPath)) {
3156
+ const deployConfigPath = join12(appDir, ".wrangler", "deploy", "config.json");
3157
+ if (!existsSync11(deployConfigPath)) {
3044
3158
  p4.cancel("Build output config not found at .wrangler/deploy/config.json");
3045
3159
  process.exit(1);
3046
3160
  }
3047
3161
  const deployConfig = JSON.parse(readFileSync11(deployConfigPath, "utf-8"));
3048
3162
  const outputWranglerPath = resolve7(dirname2(deployConfigPath), deployConfig.configPath);
3049
- if (!existsSync10(outputWranglerPath)) {
3163
+ if (!existsSync11(outputWranglerPath)) {
3050
3164
  p4.cancel(`Output wrangler.json not found at ${outputWranglerPath}`);
3051
3165
  process.exit(1);
3052
3166
  }
@@ -3059,13 +3173,13 @@ var deploy_default = defineCommand8({
3059
3173
  process.exit(1);
3060
3174
  }
3061
3175
  const workerDir = dirname2(outputWranglerPath);
3062
- const workerBundlePath = join11(workerDir, outputConfig.main);
3176
+ const workerBundlePath = join12(workerDir, outputConfig.main);
3063
3177
  const clientDir = outputConfig.assets?.directory ? resolve7(workerDir, outputConfig.assets.directory) : null;
3064
- if (!existsSync10(workerBundlePath)) {
3178
+ if (!existsSync11(workerBundlePath)) {
3065
3179
  p4.cancel(`Worker bundle not found at ${workerBundlePath}`);
3066
3180
  process.exit(1);
3067
3181
  }
3068
- if (!clientDir || !existsSync10(clientDir)) {
3182
+ if (!clientDir || !existsSync11(clientDir)) {
3069
3183
  p4.cancel(`Client assets not found at ${clientDir}`);
3070
3184
  process.exit(1);
3071
3185
  }
@@ -3300,13 +3414,13 @@ then redeploy. (Pass --allow-missing-secrets to deploy without them.)`
3300
3414
  }
3301
3415
  });
3302
3416
  async function syncSubscriptionPlans(appDir, appName, token) {
3303
- const subsPath = join11(appDir, "src", "subscriptions.ts");
3304
- if (!existsSync10(subsPath)) return;
3417
+ const subsPath = join12(appDir, "src", "subscriptions.ts");
3418
+ if (!existsSync11(subsPath)) return;
3305
3419
  let plans;
3306
3420
  try {
3307
3421
  const esbuild = await import("esbuild");
3308
- const outDir = join11(appDir, ".wrangler", "deploy");
3309
- const outFile = join11(outDir, "subscriptions.bundle.mjs");
3422
+ const outDir = join12(appDir, ".wrangler", "deploy");
3423
+ const outFile = join12(outDir, "subscriptions.bundle.mjs");
3310
3424
  await esbuild.build({
3311
3425
  entryPoints: [subsPath],
3312
3426
  bundle: true,
@@ -3317,7 +3431,7 @@ async function syncSubscriptionPlans(appDir, appName, token) {
3317
3431
  logLevel: "silent",
3318
3432
  write: true
3319
3433
  });
3320
- const mod = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
3434
+ const mod = await import(`${pathToFileURL2(outFile).href}?t=${Date.now()}`);
3321
3435
  plans = mod.subscriptionPlans;
3322
3436
  } catch (err) {
3323
3437
  p4.log.warn(`Could not load src/subscriptions.ts: ${errMessage(err)}`);
@@ -3448,13 +3562,13 @@ current billing period? (Skip to leave them grandfathered.)`
3448
3562
  }
3449
3563
  }
3450
3564
  async function syncOneTimeProducts(appDir, appName, token) {
3451
- const productsPath = join11(appDir, "src", "products.ts");
3452
- if (!existsSync10(productsPath)) return;
3565
+ const productsPath = join12(appDir, "src", "products.ts");
3566
+ if (!existsSync11(productsPath)) return;
3453
3567
  let products;
3454
3568
  try {
3455
3569
  const esbuild = await import("esbuild");
3456
- const outDir = join11(appDir, ".wrangler", "deploy");
3457
- const outFile = join11(outDir, "products.bundle.mjs");
3570
+ const outDir = join12(appDir, ".wrangler", "deploy");
3571
+ const outFile = join12(outDir, "products.bundle.mjs");
3458
3572
  await esbuild.build({
3459
3573
  entryPoints: [productsPath],
3460
3574
  bundle: true,
@@ -3465,7 +3579,7 @@ async function syncOneTimeProducts(appDir, appName, token) {
3465
3579
  logLevel: "silent",
3466
3580
  write: true
3467
3581
  });
3468
- const mod = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
3582
+ const mod = await import(`${pathToFileURL2(outFile).href}?t=${Date.now()}`);
3469
3583
  products = mod.oneTimeProducts;
3470
3584
  } catch (err) {
3471
3585
  p4.log.warn(`Could not load src/products.ts: ${errMessage(err)}`);
@@ -3529,7 +3643,7 @@ function collectAssets(dir) {
3529
3643
  function walk(d, prefix) {
3530
3644
  for (const entry of readdirSync4(d, { withFileTypes: true })) {
3531
3645
  if (entry.name === ".assetsignore") continue;
3532
- const full = join11(d, entry.name);
3646
+ const full = join12(d, entry.name);
3533
3647
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
3534
3648
  if (entry.isDirectory()) {
3535
3649
  walk(full, rel);
@@ -3710,26 +3824,26 @@ var apps_default = defineCommand11({
3710
3824
 
3711
3825
  // src/cli/commands/add.ts
3712
3826
  import { defineCommand as defineCommand12 } from "citty";
3713
- import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
3714
- import { resolve as resolve8, join as join12, dirname as dirname3 } from "path";
3827
+ import { existsSync as existsSync12, readFileSync as readFileSync12 } from "fs";
3828
+ import { resolve as resolve8, join as join13, dirname as dirname3 } from "path";
3715
3829
  import { fileURLToPath } from "url";
3716
3830
  import { spawnSync as spawnSync5 } from "child_process";
3717
3831
  function findScript(from) {
3718
- const inNodeModules = join12(from, "node_modules", "deepspace", "scripts", "add-feature.cjs");
3719
- if (existsSync11(inNodeModules)) return inNodeModules;
3720
- const inDotDeepspace = join12(from, ".deepspace", "scripts", "add-feature.cjs");
3721
- if (existsSync11(inDotDeepspace)) return inDotDeepspace;
3832
+ const inNodeModules = join13(from, "node_modules", "deepspace", "scripts", "add-feature.cjs");
3833
+ if (existsSync12(inNodeModules)) return inNodeModules;
3834
+ const inDotDeepspace = join13(from, ".deepspace", "scripts", "add-feature.cjs");
3835
+ if (existsSync12(inDotDeepspace)) return inDotDeepspace;
3722
3836
  return null;
3723
3837
  }
3724
3838
  function runningScript() {
3725
3839
  const here = dirname3(fileURLToPath(import.meta.url));
3726
- const script = join12(here, "..", "scripts", "add-feature.cjs");
3727
- return existsSync11(script) ? script : null;
3840
+ const script = join13(here, "..", "scripts", "add-feature.cjs");
3841
+ return existsSync12(script) ? script : null;
3728
3842
  }
3729
3843
  function isDeepSpaceApp(dir) {
3730
- if (existsSync11(join12(dir, "wrangler.toml"))) return true;
3731
- const pkgPath = join12(dir, "package.json");
3732
- if (!existsSync11(pkgPath)) return false;
3844
+ if (existsSync12(join13(dir, "wrangler.toml"))) return true;
3845
+ const pkgPath = join13(dir, "package.json");
3846
+ if (!existsSync12(pkgPath)) return false;
3733
3847
  try {
3734
3848
  const pkg2 = JSON.parse(readFileSync12(pkgPath, "utf-8"));
3735
3849
  return Boolean(pkg2.dependencies?.deepspace || pkg2.devDependencies?.deepspace);
@@ -3790,7 +3904,7 @@ var add_default = defineCommand12({
3790
3904
  const passArgs2 = args.list ? ["--list"] : args.info ? ["--info", String(args.info)] : ["--help"];
3791
3905
  runInstaller(script2, passArgs2, process.cwd());
3792
3906
  }
3793
- if (!existsSync11(appDir)) {
3907
+ if (!existsSync12(appDir)) {
3794
3908
  console.error(`Target directory not found: ${appDir}`);
3795
3909
  console.error("Create a new app first: deepspace create <name>");
3796
3910
  process.exit(1);
@@ -3806,8 +3920,8 @@ var add_default = defineCommand12({
3806
3920
  if (!script) {
3807
3921
  console.error("Could not find the deepspace feature installer.");
3808
3922
  console.error("Looked in:");
3809
- console.error(` ${join12(appDir, "node_modules", "deepspace", "scripts", "add-feature.cjs")}`);
3810
- console.error(` ${join12(appDir, ".deepspace", "scripts", "add-feature.cjs")}`);
3923
+ console.error(` ${join13(appDir, "node_modules", "deepspace", "scripts", "add-feature.cjs")}`);
3924
+ console.error(` ${join13(appDir, ".deepspace", "scripts", "add-feature.cjs")}`);
3811
3925
  console.error("Are you in a DeepSpace app directory? Try `npm install` first.");
3812
3926
  process.exit(1);
3813
3927
  }
@@ -4833,8 +4947,8 @@ var invoke_default = defineCommand17({
4833
4947
 
4834
4948
  // src/cli/commands/library.ts
4835
4949
  import { defineCommand as defineCommand18 } from "citty";
4836
- import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
4837
- import { join as join13, resolve as resolve9 } from "path";
4950
+ import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
4951
+ import { join as join14, resolve as resolve9 } from "path";
4838
4952
  import { parse as parseToml4 } from "smol-toml";
4839
4953
  import * as p8 from "@clack/prompts";
4840
4954
  var DEFAULT_LIBRARY_APP = "deepdotspace-site";
@@ -4912,8 +5026,8 @@ var publish = defineCommand18({
4912
5026
  let appName = typeof args.app === "string" && args.app.trim() ? args.app.trim() : void 0;
4913
5027
  if (!appName) {
4914
5028
  const appDir = resolve9(typeof args.dir === "string" && args.dir ? args.dir : ".");
4915
- const wranglerPath = join13(appDir, "wrangler.toml");
4916
- if (!existsSync12(wranglerPath)) {
5029
+ const wranglerPath = join14(appDir, "wrangler.toml");
5030
+ if (!existsSync13(wranglerPath)) {
4917
5031
  return die("No --app provided and no wrangler.toml found. Either pass --app <name> or run from your app's directory.");
4918
5032
  }
4919
5033
  const cfg = parseToml4(readFileSync14(wranglerPath, "utf-8"));
@@ -5050,8 +5164,8 @@ var library_default = defineCommand18({
5050
5164
  // src/cli/commands/feedback.ts
5051
5165
  import { defineCommand as defineCommand19 } from "citty";
5052
5166
  import * as p9 from "@clack/prompts";
5053
- import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
5054
- import { dirname as dirname4, join as join14 } from "path";
5167
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
5168
+ import { dirname as dirname4, join as join15 } from "path";
5055
5169
  import { fileURLToPath as fileURLToPath2 } from "url";
5056
5170
  import { release } from "os";
5057
5171
  var API_URL7 = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api;
@@ -5074,11 +5188,11 @@ function readCliVersion() {
5074
5188
  try {
5075
5189
  const here = dirname4(fileURLToPath2(import.meta.url));
5076
5190
  const candidates = [
5077
- join14(here, "..", "package.json"),
5078
- join14(here, "..", "..", "..", "package.json")
5191
+ join15(here, "..", "package.json"),
5192
+ join15(here, "..", "..", "..", "package.json")
5079
5193
  ];
5080
5194
  for (const path of candidates) {
5081
- if (!existsSync13(path)) continue;
5195
+ if (!existsSync14(path)) continue;
5082
5196
  const pkg2 = JSON.parse(readFileSync15(path, "utf-8"));
5083
5197
  if (pkg2.name === "deepspace" && pkg2.version) return pkg2.version;
5084
5198
  }
@@ -5696,8 +5810,8 @@ var init_default = defineCommand21({
5696
5810
 
5697
5811
  // src/cli/cli.ts
5698
5812
  var __dirname = dirname5(fileURLToPath3(import.meta.url));
5699
- var pkg = JSON.parse(readFileSync17(join15(__dirname, "..", "package.json"), "utf-8"));
5700
- if (process.platform === "linux" && !process.env.SSL_CERT_FILE && existsSync14("/etc/ssl/certs/ca-certificates.crt")) {
5813
+ var pkg = JSON.parse(readFileSync17(join16(__dirname, "..", "package.json"), "utf-8"));
5814
+ if (process.platform === "linux" && !process.env.SSL_CERT_FILE && existsSync15("/etc/ssl/certs/ca-certificates.crt")) {
5701
5815
  process.env.SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
5702
5816
  }
5703
5817
  var create2 = defineCommand22({