@hype-stack/cli 0.5.21 → 0.6.0

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.
@@ -13,7 +13,7 @@ import { Prompt as O } from "@clack/core";
13
13
  import { styleText as k } from "node:util";
14
14
  import { downloadTemplate as ee } from "giget";
15
15
  //#region src/constants/constants.ts
16
- var A = "0.5.21", j = "gh:BetterTyped/hype-stack", M = "stack.json", te = "/schema/stack.json", N = "https://api.hype-stack.dev", P = "HYPE_STACK_API_URL", F = "https://www.hype-stack.dev", ne = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/, I = [
16
+ var A = "0.6.0", j = "gh:BetterTyped/hype-stack", M = "stack.json", te = "/schema/stack.json", N = "https://api.hype-stack.dev", P = "HYPE_STACK_API_URL", F = "https://www.hype-stack.dev", ne = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/, I = [
17
17
  {
18
18
  value: "cursor",
19
19
  label: "Cursor",
@@ -2957,13 +2957,46 @@ function yi(e, t) {
2957
2957
  return e.trim() === "" ? n + "\n" : e.trimEnd() + "\n" + n + "\n";
2958
2958
  }
2959
2959
  async function bi(e, t, n) {
2960
+ if (e.length === 0) return;
2961
+ let r = Z("{{enums.src}}", t), i = T.resolve(n, r, "permissions/subjects.ts"), a = T.resolve(n, r, "permissions/presets.ts");
2962
+ if (!await Y(i) || !await Y(a)) return;
2963
+ let o = await y.readFile(i, "utf-8");
2964
+ for (let t of e) o = xi(o, t);
2965
+ await y.writeFile(i, o, "utf-8");
2966
+ let s = await y.readFile(a, "utf-8");
2967
+ for (let t of e) if (t.grants?.length) for (let e of t.grants) s = Ci(s, e);
2968
+ await y.writeFile(a, s, "utf-8");
2969
+ }
2970
+ function xi(e, t) {
2971
+ if (e.includes(`${t.name} =`)) return e;
2972
+ let n = e.indexOf("export enum PermissionSubject {");
2973
+ if (n === -1) return e;
2974
+ let r = gi(e, e.indexOf("{", n) + 1 - 1);
2975
+ if (r === -1) return e;
2976
+ let i = ` ${t.name} = "${t.value}",\n`;
2977
+ return e.slice(0, r) + i + e.slice(r);
2978
+ }
2979
+ function Si(e) {
2980
+ return e === "admin" ? "OrganizationRole.ADMIN" : e === "member" ? "OrganizationRole.MEMBER" : e;
2981
+ }
2982
+ function Ci(e, t) {
2983
+ let { role: n, action: r, subject: i } = t, a = Si(n), o = `p(PermissionAction.${r}, PermissionSubject.${i})`;
2984
+ if (e.includes(o)) return e;
2985
+ let s = RegExp(`\\[${a.replace(".", "\\.")}\\]: \\[`), c = e.match(s);
2986
+ if (!c || c.index === void 0) return e;
2987
+ let l = c.index + c[0].length, u = Wi(e, l - 1);
2988
+ if (u === -1) return e;
2989
+ let d = e.slice(l, u), f = d.trim(), p = f !== "" && !f.endsWith(",") ? "," : "", m = f === "" ? `\n ${o},\n ` : d.includes("\n") ? `${d}${p}\n ${o},` : `\n ${f}${p}\n ${o},\n `;
2990
+ return e.slice(0, l) + m + e.slice(u);
2991
+ }
2992
+ async function wi(e, t, n) {
2960
2993
  let r = Z("{{backend.root}}", t), i = T.resolve(n, r, "src/sockets/index.ts");
2961
2994
  if (!await Y(i)) return;
2962
2995
  let a = await y.readFile(i, "utf-8");
2963
- for (let t of e) a.includes(`from "${t.from}"`) || (a = xi(a, t), a = Si(a, t));
2964
- await Y(T.resolve(n, r, "src/libs/websocket/ws-authenticate.ts")) && (a = Ci(a)), await y.writeFile(i, a, "utf-8");
2996
+ for (let t of e) a.includes(`from "${t.from}"`) || (a = Ti(a, t), a = Ei(a, t));
2997
+ await Y(T.resolve(n, r, "src/libs/websocket/ws-authenticate.ts")) && (a = Di(a)), await y.writeFile(i, a, "utf-8");
2965
2998
  }
2966
- function xi(e, t) {
2999
+ function Ti(e, t) {
2967
3000
  let n = `import { ${t.import} } from "${t.from}";`, r = e.lastIndexOf("from \"./");
2968
3001
  if (r !== -1) {
2969
3002
  let t = e.indexOf("\n", r);
@@ -2972,7 +3005,7 @@ function xi(e, t) {
2972
3005
  let i = e.indexOf("const sockets");
2973
3006
  return i === -1 ? e : e.slice(0, i) + n + "\n\n" + e.slice(i);
2974
3007
  }
2975
- function Si(e, t) {
3008
+ function Ei(e, t) {
2976
3009
  let n = `.socket("${t.prefix}", ${t.import})`, r = e.indexOf("const sockets");
2977
3010
  if (r === -1) return e;
2978
3011
  let i = e.indexOf("new SocketRouter", r);
@@ -2986,7 +3019,7 @@ function Si(e, t) {
2986
3019
  }
2987
3020
  return e;
2988
3021
  }
2989
- function Ci(e) {
3022
+ function Di(e) {
2990
3023
  if (e.includes("wsAuthenticate")) return e;
2991
3024
  let t = e.indexOf("from \"@backend/libs/websocket/socket-router\""), n = e;
2992
3025
  if (t !== -1) {
@@ -2995,14 +3028,14 @@ function Ci(e) {
2995
3028
  }
2996
3029
  return n.replace("new SocketRouter()", "new SocketRouter({ authenticate: wsAuthenticate })");
2997
3030
  }
2998
- async function wi(e, t, n) {
3031
+ async function Oi(e, t, n) {
2999
3032
  let r = Z("{{frontend.root}}", t), i = T.resolve(n, r, "src/api/sdk.ts");
3000
3033
  if (!await Y(i)) return;
3001
3034
  let a = await y.readFile(i, "utf-8");
3002
- for (let t of e) a.includes(`.$configure(${t.import})`) || (a = Ti(a, t), a = Ei(a, t));
3035
+ for (let t of e) a.includes(`.$configure(${t.import})`) || (a = ki(a, t), a = Ai(a, t));
3003
3036
  await y.writeFile(i, a, "utf-8");
3004
3037
  }
3005
- function Ti(e, t) {
3038
+ function ki(e, t) {
3006
3039
  let n = `import { ${t.import} } from "${t.from}";`;
3007
3040
  if (e.includes(n)) return e;
3008
3041
  let r = e.lastIndexOf("from \"./");
@@ -3013,20 +3046,20 @@ function Ti(e, t) {
3013
3046
  let i = e.indexOf("export const sdk");
3014
3047
  return i === -1 ? e : e.slice(0, i) + n + "\n\n" + e.slice(i);
3015
3048
  }
3016
- function Ei(e, t) {
3049
+ function Ai(e, t) {
3017
3050
  let n = `.$configure(${t.import})`, r = e.indexOf("export const sdk");
3018
3051
  if (r === -1) return e;
3019
3052
  let i = e.indexOf(";", r);
3020
3053
  return i === -1 ? e : e.slice(0, i) + "\n " + n + e.slice(i);
3021
3054
  }
3022
- async function Di(e, t, n) {
3055
+ async function ji(e, t, n) {
3023
3056
  let r = T.resolve(n, Z("{{backend.utils}}", t), "frontend-url/frontend-url.ts");
3024
3057
  if (!await Y(r)) return;
3025
3058
  let i = await y.readFile(r, "utf-8");
3026
- for (let t of e) i.includes(`"${t.path}"`) || (i = Oi(i, t));
3059
+ for (let t of e) i.includes(`"${t.path}"`) || (i = Mi(i, t));
3027
3060
  await y.writeFile(r, i, "utf-8");
3028
3061
  }
3029
- function Oi(e, t) {
3062
+ function Mi(e, t) {
3030
3063
  let n = ` "${t.path}": ${t.search};`, r = e.indexOf("type RouteDefinitions = {");
3031
3064
  if (r === -1) return e;
3032
3065
  let i = e.indexOf("{", r);
@@ -3042,22 +3075,22 @@ function Oi(e, t) {
3042
3075
  }
3043
3076
  return o === -1 ? e : e.slice(0, o) + n + "\n" + e.slice(o);
3044
3077
  }
3045
- var ki = "import { type LucideIcon } from \"lucide-react\";\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\nexport type NavItem = {\n label: string;\n icon: LucideIcon;\n to: string;\n params?: Record<string, string>;\n};\n\nexport type NavSection = {\n label: string;\n icon: LucideIcon;\n items: NavItem[];\n};\n\nexport type NavSectionLink = NavSection & { to: string; params?: Record<string, string> };\n\nexport type NavEntry = NavSection | NavSectionLink;\n\n/* -------------------------------------------------------------------------------------------------\n * Navigation\n * -----------------------------------------------------------------------------------------------*/\n\nexport const primaryNav: NavEntry[] = [];\n\nexport const secondaryNav: NavEntry[] = [];\n\nexport const tertiaryNav: NavEntry[] = [];\n\nexport const settingsNav: NavEntry[] = [];\n", Ai = {
3078
+ var Ni = "import { type LucideIcon } from \"lucide-react\";\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\nexport type NavPermission = {\n action: string;\n subject: string;\n};\n\nexport type NavItem = {\n label: string;\n icon: LucideIcon;\n to: string;\n params?: Record<string, string>;\n permission?: NavPermission;\n};\n\nexport type NavSection = {\n label: string;\n icon: LucideIcon;\n items: NavItem[];\n permission?: NavPermission;\n};\n\nexport type NavSectionLink = NavSection & { to: string; params?: Record<string, string> };\n\nexport type NavEntry = NavSection | NavSectionLink;\n\n/* -------------------------------------------------------------------------------------------------\n * Navigation\n * -----------------------------------------------------------------------------------------------*/\n\nexport const primaryNav: NavEntry[] = [];\n\nexport const secondaryNav: NavEntry[] = [];\n\nexport const tertiaryNav: NavEntry[] = [];\n\nexport const settingsNav: NavEntry[] = [];\n", Pi = {
3046
3079
  primary: "primaryNav",
3047
3080
  secondary: "secondaryNav",
3048
3081
  tertiary: "tertiaryNav",
3049
3082
  settings: "settingsNav"
3050
- }, ji = new Set(["primary", "secondary"]);
3051
- async function Mi(e) {
3083
+ }, Fi = new Set(["primary", "secondary"]);
3084
+ async function Ii(e) {
3052
3085
  let { entries: t, paths: n, projectRoot: r, slot: i = "frontend", override: a = !1 } = e, o = ni(i, n), s = T.resolve(r, o, "src/constants/nav.constants.ts"), c;
3053
- await Y(s) ? c = await y.readFile(s, "utf-8") : (await y.mkdir(T.dirname(s), { recursive: !0 }), c = ki);
3054
- for (let e of t) !a && c.includes(`label: "${e.label}"`) || (c = Fi(c, e));
3055
- if (a) for (let e of t) c.includes(`label: "${e.label}"`) && (c = zi(c, e));
3056
- for (let e of t) ji.has(e.group) && (c.includes(`label: "${e.label}"`) || (c = Li(c, e, "append")));
3057
- for (let e of t.toReversed()) ji.has(e.group) || c.includes(`label: "${e.label}"`) || (c = Li(c, e, "prepend"));
3086
+ await Y(s) ? c = await y.readFile(s, "utf-8") : (await y.mkdir(T.dirname(s), { recursive: !0 }), c = Ni);
3087
+ for (let e of t) !a && c.includes(`label: "${e.label}"`) || (c = zi(c, e), c = Vi(c, e));
3088
+ if (a) for (let e of t) c.includes(`label: "${e.label}"`) && (c = Gi(c, e));
3089
+ for (let e of t) Fi.has(e.group) && (c.includes(`label: "${e.label}"`) || (c = Ui(c, e, "append")));
3090
+ for (let e of t.toReversed()) Fi.has(e.group) || c.includes(`label: "${e.label}"`) || (c = Ui(c, e, "prepend"));
3058
3091
  await y.writeFile(s, c, "utf-8");
3059
3092
  }
3060
- async function Ni(e) {
3093
+ async function Li(e) {
3061
3094
  let { postLoginRedirect: t, paths: n, projectRoot: r, slot: i = "frontend" } = e, a = ni(i, n), o = T.resolve(r, a, "src/features/auth/constants/auth.constants.ts");
3062
3095
  if (!await Y(o)) return;
3063
3096
  let s = await y.readFile(o, "utf-8"), c = /export const POST_LOGIN_REDIRECT_PATH = "[^"]*";/;
@@ -3065,17 +3098,17 @@ async function Ni(e) {
3065
3098
  let l = s.replace(c, `export const POST_LOGIN_REDIRECT_PATH = "${t}";`);
3066
3099
  await y.writeFile(o, l, "utf-8");
3067
3100
  }
3068
- function Pi(e) {
3101
+ function Ri(e) {
3069
3102
  let t = [e.icon];
3070
3103
  if (e.items) for (let n of e.items) t.includes(n.icon) || t.push(n.icon);
3071
3104
  return t;
3072
3105
  }
3073
- function Fi(e, t) {
3074
- let n = Pi(t), r = e;
3075
- for (let e of n) r = Ii(r, e);
3106
+ function zi(e, t) {
3107
+ let n = Ri(t), r = e;
3108
+ for (let e of n) r = Bi(r, e);
3076
3109
  return r;
3077
3110
  }
3078
- function Ii(e, t) {
3111
+ function Bi(e, t) {
3079
3112
  let n = e.match(/import \{([^}]+)\} from "lucide-react";/);
3080
3113
  if (!n) return e;
3081
3114
  let r = n[1].split(",").map((e) => e.trim()).filter(Boolean);
@@ -3083,33 +3116,43 @@ function Ii(e, t) {
3083
3116
  let i = r.findIndex((e) => e.startsWith("type "));
3084
3117
  return i === -1 ? r.push(t) : r.splice(i, 0, t), e.replace(n[0], `import { ${r.join(", ")} } from "lucide-react";`);
3085
3118
  }
3086
- function Li(e, t, n) {
3087
- let r = Ai[t.group];
3119
+ function Vi(e, t) {
3120
+ if (!(t.permission || t.items?.some((e) => e.permission)) || e.includes("@hype-stack/enums\"")) return e;
3121
+ let n = e.match(/import \{([^}]+)\} from "lucide-react";/);
3122
+ if (!n) return `import { PermissionAction, PermissionSubject } from "@hype-stack/enums";\n\n${e}`;
3123
+ let r = "import { PermissionAction, PermissionSubject } from \"@hype-stack/enums\";\n", i = e.indexOf("\n", n.index ?? 0);
3124
+ return i === -1 ? r + e : e.slice(0, i + 1) + r + e.slice(i + 1);
3125
+ }
3126
+ function Hi(e) {
3127
+ return `{ action: PermissionAction.${e.action}, subject: PermissionSubject.${e.subject} }`;
3128
+ }
3129
+ function Ui(e, t, n) {
3130
+ let r = Pi[t.group];
3088
3131
  if (!r) return e;
3089
- let i = Bi(t), a = RegExp(`export const ${r}: NavEntry\\[\\] = \\[`), o = e.match(a);
3132
+ let i = Ki(t), a = RegExp(`export const ${r}: NavEntry\\[\\] = \\[`), o = e.match(a);
3090
3133
  if (!o) return e;
3091
- let s = e.indexOf(o[0]) + o[0].length, c = Ri(e, s - 1);
3134
+ let s = e.indexOf(o[0]) + o[0].length, c = Wi(e, s - 1);
3092
3135
  return c === -1 ? e : e.slice(s, c).trim() === "" ? e.slice(0, s) + "\n" + i + "\n" + e.slice(s) : n === "append" ? e.slice(0, c) + i + "\n" + e.slice(c) : e.slice(0, s) + "\n" + i + e.slice(s);
3093
3136
  }
3094
- function Ri(e, t) {
3137
+ function Wi(e, t) {
3095
3138
  let n = 0;
3096
3139
  for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
3097
3140
  else if (e[r] === "]" && (n--, n === 0)) return r;
3098
3141
  return -1;
3099
3142
  }
3100
- function zi(e, t) {
3143
+ function Gi(e, t) {
3101
3144
  let n = e.indexOf(`label: "${t.label}"`);
3102
3145
  if (n === -1) return e;
3103
3146
  let r = e.lastIndexOf("{", n);
3104
3147
  if (r === -1) return e;
3105
3148
  let i = gi(e, r);
3106
3149
  if (i === -1) return e;
3107
- let a = Bi(t).trimStart().replace(/,\s*$/, "");
3150
+ let a = Ki(t).trimStart().replace(/,\s*$/, "");
3108
3151
  return e.slice(0, r) + a + e.slice(i + 1);
3109
3152
  }
3110
- function Bi(e) {
3153
+ function Ki(e) {
3111
3154
  let t = [];
3112
- if (t.push(" {"), t.push(` label: "${e.label}",`), t.push(` icon: ${e.icon},`), e.to && t.push(` to: "${e.to}",`), e.params && t.push(` params: ${e.params},`), e.items && e.items.length > 0) {
3155
+ if (t.push(" {"), t.push(` label: "${e.label}",`), t.push(` icon: ${e.icon},`), e.to && t.push(` to: "${e.to}",`), e.params && t.push(` params: ${e.params},`), e.permission && t.push(` permission: ${Hi(e.permission)},`), e.items && e.items.length > 0) {
3113
3156
  t.push(" items: [");
3114
3157
  for (let n of e.items) {
3115
3158
  let e = [
@@ -3117,20 +3160,20 @@ function Bi(e) {
3117
3160
  `icon: ${n.icon}`,
3118
3161
  `to: "${n.to}"`
3119
3162
  ];
3120
- n.params && e.push(`params: ${n.params}`), t.push(` { ${e.join(", ")} },`);
3163
+ n.params && e.push(`params: ${n.params}`), n.permission && e.push(`permission: ${Hi(n.permission)}`), t.push(` { ${e.join(", ")} },`);
3121
3164
  }
3122
3165
  t.push(" ],");
3123
3166
  } else t.push(" items: [],");
3124
3167
  return t.push(" },"), t.join("\n");
3125
3168
  }
3126
- async function Vi(e, t, n) {
3169
+ async function qi(e, t, n) {
3127
3170
  let r = Z("{{backend.features}}", t), i = T.resolve(n, r, "organizations/modules/setup-organization/steps/index.ts");
3128
3171
  if (!await Y(i)) return;
3129
3172
  let a = await y.readFile(i, "utf-8");
3130
- for (let t of e) a.includes(`from "${t.from}"`) || (a = Hi(a, t), a = Ui(a, t));
3173
+ for (let t of e) a.includes(`from "${t.from}"`) || (a = Ji(a, t), a = Yi(a, t));
3131
3174
  await y.writeFile(i, a, "utf-8");
3132
3175
  }
3133
- function Hi(e, t) {
3176
+ function Ji(e, t) {
3134
3177
  let n = `import { ${t.import} } from "${t.from}";`, r = e.lastIndexOf("import ");
3135
3178
  if (r !== -1) {
3136
3179
  let t = e.indexOf("\n", e.indexOf(";", r));
@@ -3138,38 +3181,38 @@ function Hi(e, t) {
3138
3181
  }
3139
3182
  return e.indexOf("type "), n + "\n\n" + e;
3140
3183
  }
3141
- function Ui(e, t) {
3184
+ function Yi(e, t) {
3142
3185
  let n = ` { id: "${t.id}", execute: (ctx) => ${t.import}(ctx) },`, r = e.match(/export const steps:\s*Step\[\]\s*=\s*\[/);
3143
3186
  if (!r) return e;
3144
- let i = e.indexOf(r[0]) + r[0].length, a = Wi(e, i - 1);
3187
+ let i = e.indexOf(r[0]) + r[0].length, a = Xi(e, i - 1);
3145
3188
  return a === -1 ? e : e.slice(i, a).trim() === "" ? e.slice(0, a) + "\n" + n + "\n" + e.slice(a) : e.slice(0, a) + n + "\n" + e.slice(a);
3146
3189
  }
3147
- function Wi(e, t) {
3190
+ function Xi(e, t) {
3148
3191
  let n = 0;
3149
3192
  for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
3150
3193
  else if (e[r] === "]" && (n--, n === 0)) return r;
3151
3194
  return -1;
3152
3195
  }
3153
- var Gi = "import { type ComponentType } from \"react\";\n\nexport type NavbarAction = {\n id: string;\n component: ComponentType;\n};\n\nexport const navbarActions: NavbarAction[] = [];\n\nexport const userMenuActions: NavbarAction[] = [];\n";
3154
- async function Ki(e) {
3155
- await Ji({
3196
+ var Zi = "import { type ComponentType } from \"react\";\n\nexport type NavbarAction = {\n id: string;\n component: ComponentType;\n};\n\nexport const navbarActions: NavbarAction[] = [];\n\nexport const userMenuActions: NavbarAction[] = [];\n";
3197
+ async function Qi(e) {
3198
+ await ea({
3156
3199
  ...e,
3157
3200
  arrayName: "navbarActions"
3158
3201
  });
3159
3202
  }
3160
- async function qi(e) {
3161
- await Ji({
3203
+ async function $i(e) {
3204
+ await ea({
3162
3205
  ...e,
3163
3206
  arrayName: "userMenuActions"
3164
3207
  });
3165
3208
  }
3166
- async function Ji({ actions: e, arrayName: t, paths: n, projectRoot: r, slot: i }) {
3209
+ async function ea({ actions: e, arrayName: t, paths: n, projectRoot: r, slot: i }) {
3167
3210
  let a = ni(i, n), o = T.resolve(r, a, "src/constants/navbar-actions.tsx"), s;
3168
- await Y(o) ? s = await y.readFile(o, "utf-8") : (await y.mkdir(T.dirname(o), { recursive: !0 }), s = Gi);
3169
- for (let n of e) s = Yi(s, n), s = Xi(s, n, t);
3211
+ await Y(o) ? s = await y.readFile(o, "utf-8") : (await y.mkdir(T.dirname(o), { recursive: !0 }), s = Zi);
3212
+ for (let n of e) s = ta(s, n), s = na(s, n, t);
3170
3213
  await y.writeFile(o, s, "utf-8");
3171
3214
  }
3172
- function Yi(e, t) {
3215
+ function ta(e, t) {
3173
3216
  let n = `import { ${t.import} } from "${t.from}";`;
3174
3217
  if (e.includes(n)) return e;
3175
3218
  let r = e.lastIndexOf("import ");
@@ -3177,38 +3220,38 @@ function Yi(e, t) {
3177
3220
  let i = e.indexOf("\n", r);
3178
3221
  return i === -1 ? e + "\n" + n : e.slice(0, i + 1) + n + "\n" + e.slice(i + 1);
3179
3222
  }
3180
- function Xi(e, t, n) {
3223
+ function na(e, t, n) {
3181
3224
  let r = e.match(RegExp(`export const ${n}:\\s*NavbarAction\\[\\]\\s*=\\s*\\[`));
3182
3225
  if (!r) return e;
3183
- let i = e.indexOf(r[0]) + r[0].length, a = Zi(e, i - 1);
3226
+ let i = e.indexOf(r[0]) + r[0].length, a = ra(e, i - 1);
3184
3227
  if (a === -1) return e;
3185
3228
  let o = e.slice(i, a);
3186
3229
  if (o.includes(`id: "${t.id}"`)) return e;
3187
3230
  let s = ` { id: "${t.id}", component: ${t.import} },`;
3188
3231
  return o.trim() === "" ? e.slice(0, a) + "\n" + s + "\n" + e.slice(a) : e.slice(0, a) + s + "\n" + e.slice(a);
3189
3232
  }
3190
- function Zi(e, t) {
3233
+ function ra(e, t) {
3191
3234
  let n = 0;
3192
3235
  for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
3193
3236
  else if (e[r] === "]" && (n--, n === 0)) return r;
3194
3237
  return -1;
3195
3238
  }
3196
- var Qi = new Set([
3239
+ var ia = new Set([
3197
3240
  ".ts",
3198
3241
  ".tsx",
3199
3242
  ".js",
3200
3243
  ".jsx"
3201
3244
  ]);
3202
- async function $i(e) {
3245
+ async function aa(e) {
3203
3246
  let { files: t, paths: n, projectRoot: r, projectName: i } = e;
3204
3247
  if (i === "hype-stack") return;
3205
3248
  let a = `@${i}/`;
3206
3249
  await Promise.all(t.map(async (e) => {
3207
3250
  let t = Gr(e.target, n, r), i = await y.stat(t).catch(() => null);
3208
- i?.isDirectory() ? await ta(t, a) : i?.isFile() && Qi.has(T.extname(t)) && await na(t, a);
3251
+ i?.isDirectory() ? await sa(t, a) : i?.isFile() && ia.has(T.extname(t)) && await ca(t, a);
3209
3252
  }));
3210
3253
  }
3211
- var ea = new Set([
3254
+ var oa = new Set([
3212
3255
  ".git",
3213
3256
  "node_modules",
3214
3257
  "dist",
@@ -3217,23 +3260,23 @@ var ea = new Set([
3217
3260
  ".next",
3218
3261
  "coverage"
3219
3262
  ]);
3220
- async function ta(e, t) {
3263
+ async function sa(e, t) {
3221
3264
  let n = await y.readdir(e, { withFileTypes: !0 });
3222
3265
  await Promise.all(n.map(async (n) => {
3223
3266
  let r = T.join(e, n.name);
3224
3267
  if (n.isDirectory()) {
3225
- if (ea.has(n.name)) return;
3226
- await ta(r, t);
3227
- } else n.isFile() && Qi.has(T.extname(n.name)) && await na(r, t);
3268
+ if (oa.has(n.name)) return;
3269
+ await sa(r, t);
3270
+ } else n.isFile() && ia.has(T.extname(n.name)) && await ca(r, t);
3228
3271
  }));
3229
3272
  }
3230
- async function na(e, t) {
3273
+ async function ca(e, t) {
3231
3274
  let n = await y.readFile(e, "utf-8");
3232
3275
  if (!n.includes(Xr)) return;
3233
3276
  let r = ei(n, t);
3234
3277
  r !== n && await y.writeFile(e, r, "utf-8");
3235
3278
  }
3236
- var ra = new Set([
3279
+ var la = new Set([
3237
3280
  ".git",
3238
3281
  "node_modules",
3239
3282
  "dist",
@@ -3243,12 +3286,12 @@ var ra = new Set([
3243
3286
  ".turbo",
3244
3287
  ".cache",
3245
3288
  "coverage"
3246
- ]), ia = new Set([
3289
+ ]), ua = new Set([
3247
3290
  "pnpm-lock.yaml",
3248
3291
  "package-lock.json",
3249
3292
  "yarn.lock",
3250
3293
  "bun.lockb"
3251
- ]), aa = new Set([
3294
+ ]), da = new Set([
3252
3295
  ".png",
3253
3296
  ".jpg",
3254
3297
  ".jpeg",
@@ -3275,21 +3318,21 @@ var ra = new Set([
3275
3318
  ".mp3",
3276
3319
  ".wav"
3277
3320
  ]);
3278
- async function oa(e, t) {
3279
- t !== "hype-stack" && await sa(e, t);
3321
+ async function fa(e, t) {
3322
+ t !== "hype-stack" && await pa(e, t);
3280
3323
  }
3281
- async function sa(e, t) {
3324
+ async function pa(e, t) {
3282
3325
  let n = await y.readdir(e, { withFileTypes: !0 }).catch(() => []);
3283
3326
  await Promise.all(n.map(async (n) => {
3284
3327
  let r = T.join(e, n.name);
3285
3328
  if (n.isDirectory()) {
3286
- if (ra.has(n.name)) return;
3287
- await sa(r, t);
3288
- } else n.isFile() && await ca(r, t);
3329
+ if (la.has(n.name)) return;
3330
+ await pa(r, t);
3331
+ } else n.isFile() && await ma(r, t);
3289
3332
  }));
3290
3333
  }
3291
- async function ca(e, t) {
3292
- if (ia.has(T.basename(e)) || aa.has(T.extname(e).toLowerCase())) return;
3334
+ async function ma(e, t) {
3335
+ if (ua.has(T.basename(e)) || da.has(T.extname(e).toLowerCase())) return;
3293
3336
  let n = await y.readFile(e, "utf-8").catch(() => null);
3294
3337
  if (n === null || n.includes("\0") || !n.includes("hype-stack") && !n.includes(Qr)) return;
3295
3338
  let r = ti(n, t);
@@ -3297,22 +3340,22 @@ async function ca(e, t) {
3297
3340
  }
3298
3341
  //#endregion
3299
3342
  //#region src/core/installer.ts
3300
- function la(e, t) {
3343
+ function ha(e, t) {
3301
3344
  return e.slot ? t ? t.includes(e.slot) : e.slot === "frontend" : !0;
3302
3345
  }
3303
- async function ua(e, t) {
3346
+ async function ga(e, t) {
3304
3347
  if ((await y.stat(e)).isDirectory()) {
3305
3348
  await y.mkdir(t, { recursive: !0 });
3306
3349
  let n = await y.readdir(e, { withFileTypes: !0 });
3307
- for (let r of n) await ua(T.join(e, r.name), T.join(t, r.name));
3350
+ for (let r of n) await ga(T.join(e, r.name), T.join(t, r.name));
3308
3351
  } else await y.mkdir(T.dirname(t), { recursive: !0 }), await y.copyFile(e, t);
3309
3352
  }
3310
- async function da(e) {
3353
+ async function _a(e) {
3311
3354
  let { src: t, dest: n, projectRoot: r, skip: i } = e;
3312
3355
  if ((await y.stat(t)).isDirectory()) {
3313
3356
  await y.mkdir(n, { recursive: !0 });
3314
3357
  let e = await y.readdir(t, { withFileTypes: !0 });
3315
- return (await Promise.all(e.map((e) => da({
3358
+ return (await Promise.all(e.map((e) => _a({
3316
3359
  src: T.join(t, e.name),
3317
3360
  dest: T.join(n, e.name),
3318
3361
  projectRoot: r,
@@ -3321,7 +3364,7 @@ async function da(e) {
3321
3364
  }
3322
3365
  return i.has(t) ? [] : (await y.mkdir(T.dirname(n), { recursive: !0 }), await y.copyFile(t, n), [T.relative(r, n)]);
3323
3366
  }
3324
- async function fa(e) {
3367
+ async function va(e) {
3325
3368
  let { file: t, packDir: n, paths: r, projectRoot: i } = e, a = Kr(t.source, n), o = Gr(t.target, r, i);
3326
3369
  return {
3327
3370
  sourcePath: a,
@@ -3330,8 +3373,8 @@ async function fa(e) {
3330
3373
  targetExists: await Y(o) || await lr(o)
3331
3374
  };
3332
3375
  }
3333
- async function pa(e) {
3334
- let { file: t, packDir: n, paths: r, projectRoot: i } = e, { sourcePath: a, targetPath: o, sourceExists: s, targetExists: c } = await fa({
3376
+ async function ya(e) {
3377
+ let { file: t, packDir: n, paths: r, projectRoot: i } = e, { sourcePath: a, targetPath: o, sourceExists: s, targetExists: c } = await va({
3335
3378
  file: t,
3336
3379
  packDir: n,
3337
3380
  paths: r,
@@ -3346,8 +3389,8 @@ async function pa(e) {
3346
3389
  default: return `${t.target}: Unknown strategy: ${String(t.strategy)}`;
3347
3390
  }
3348
3391
  }
3349
- async function ma(e) {
3350
- let { file: t, packDir: n, paths: r, projectRoot: i, force: a, overwrite: o } = e, { sourcePath: s, targetPath: c, sourceExists: l, targetExists: u } = await fa({
3392
+ async function ba(e) {
3393
+ let { file: t, packDir: n, paths: r, projectRoot: i, force: a, overwrite: o } = e, { sourcePath: s, targetPath: c, sourceExists: l, targetExists: u } = await va({
3351
3394
  file: t,
3352
3395
  packDir: n,
3353
3396
  paths: r,
@@ -3365,7 +3408,7 @@ async function ma(e) {
3365
3408
  status: "skipped",
3366
3409
  path: t.target,
3367
3410
  reason: "Already exists"
3368
- } : (await ua(s, c), {
3411
+ } : (await ga(s, c), {
3369
3412
  status: "installed",
3370
3413
  path: t.target
3371
3414
  });
@@ -3374,16 +3417,16 @@ async function ma(e) {
3374
3417
  status: "skipped",
3375
3418
  path: t.target,
3376
3419
  reason: "Already exists (skip-if-exists)"
3377
- } : (await ua(s, c), {
3420
+ } : (await ga(s, c), {
3378
3421
  status: "installed",
3379
3422
  path: t.target
3380
3423
  });
3381
- case "override": return await ua(s, c), {
3424
+ case "override": return await ga(s, c), {
3382
3425
  status: "installed",
3383
3426
  path: t.target
3384
3427
  };
3385
3428
  case "merge": {
3386
- if (!u) return await ua(s, c), {
3429
+ if (!u) return await ga(s, c), {
3387
3430
  status: "installed",
3388
3431
  path: t.target
3389
3432
  };
@@ -3413,15 +3456,15 @@ async function ma(e) {
3413
3456
  };
3414
3457
  }
3415
3458
  }
3416
- async function ha(e) {
3459
+ async function xa(e) {
3417
3460
  let { packs: t, config: n, projectRoot: r, slotsByPack: i } = e, a = n.paths;
3418
3461
  if (!a) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
3419
3462
  let o = [], s = /* @__PURE__ */ new Set();
3420
3463
  for (let e of t) {
3421
3464
  let t = i?.get(e.manifest.name);
3422
3465
  for (let n of e.manifest.files) {
3423
- if (n.strategy !== "create" || !la(n, t)) continue;
3424
- let { targetPath: i, targetExists: c } = await fa({
3466
+ if (n.strategy !== "create" || !ha(n, t)) continue;
3467
+ let { targetPath: i, targetExists: c } = await va({
3425
3468
  file: n,
3426
3469
  packDir: e.packDir,
3427
3470
  paths: a,
@@ -3436,13 +3479,13 @@ async function ha(e) {
3436
3479
  }
3437
3480
  return o;
3438
3481
  }
3439
- async function ga(e) {
3482
+ async function Sa(e) {
3440
3483
  let { manifest: t, config: n, projectRoot: r, force: i, packDir: a, slots: o } = e, s = n.paths;
3441
3484
  if (!s) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
3442
3485
  let c = [];
3443
3486
  for (let e of t.files) {
3444
- if (!la(e, o)) continue;
3445
- let t = await pa({
3487
+ if (!ha(e, o)) continue;
3488
+ let t = await ya({
3446
3489
  file: e,
3447
3490
  packDir: a,
3448
3491
  paths: s,
@@ -3453,16 +3496,16 @@ async function ga(e) {
3453
3496
  }
3454
3497
  return c;
3455
3498
  }
3456
- async function _a(e) {
3499
+ async function Ca(e) {
3457
3500
  let { manifest: t, config: n, projectRoot: r, force: i, overwrite: a, packDir: o, slots: s } = e, c = n.paths;
3458
3501
  if (!c) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
3459
3502
  let l = {
3460
3503
  installed: [],
3461
3504
  skipped: [],
3462
3505
  errors: []
3463
- }, u = t.files.filter((e) => la(e, s));
3506
+ }, u = t.files.filter((e) => ha(e, s));
3464
3507
  for (let e of u) {
3465
- let t = await ma({
3508
+ let t = await ba({
3466
3509
  file: e,
3467
3510
  packDir: o,
3468
3511
  paths: c,
@@ -3482,40 +3525,40 @@ async function _a(e) {
3482
3525
  break;
3483
3526
  }
3484
3527
  }
3485
- await $i({
3528
+ await aa({
3486
3529
  files: u,
3487
3530
  paths: c,
3488
3531
  projectRoot: r,
3489
3532
  projectName: n.name
3490
- }), t.env && t.env.length > 0 && await ri(t.env, c, r), t.routes && t.routes.length > 0 && await li(t.routes, c, r), t.context && t.context.length > 0 && await fi(t.context, c, r), t.sockets && t.sockets.length > 0 && await bi(t.sockets, c, r), t.sdkConfigurations && t.sdkConfigurations.length > 0 && await wi(t.sdkConfigurations, c, r), t.enums && t.enums.length > 0 && await vi(t.enums, c, r), t.frontendRoutes && t.frontendRoutes.length > 0 && await Di(t.frontendRoutes, c, r);
3533
+ }), t.env && t.env.length > 0 && await ri(t.env, c, r), t.routes && t.routes.length > 0 && await li(t.routes, c, r), t.context && t.context.length > 0 && await fi(t.context, c, r), t.sockets && t.sockets.length > 0 && await wi(t.sockets, c, r), t.sdkConfigurations && t.sdkConfigurations.length > 0 && await Oi(t.sdkConfigurations, c, r), t.enums && t.enums.length > 0 && await vi(t.enums, c, r), t.permissions && t.permissions.length > 0 && await bi(t.permissions, c, r), t.frontendRoutes && t.frontendRoutes.length > 0 && await ji(t.frontendRoutes, c, r);
3491
3534
  let d = s && s.length > 0 ? s : ["frontend"];
3492
- for (let e of d) t.nav && t.nav.length > 0 && await Mi({
3535
+ for (let e of d) t.nav && t.nav.length > 0 && await Ii({
3493
3536
  entries: t.nav,
3494
3537
  paths: c,
3495
3538
  projectRoot: r,
3496
3539
  slot: e
3497
- }), t.navbarActions && t.navbarActions.length > 0 && await Ki({
3540
+ }), t.navbarActions && t.navbarActions.length > 0 && await Qi({
3498
3541
  actions: t.navbarActions,
3499
3542
  paths: c,
3500
3543
  projectRoot: r,
3501
3544
  slot: e
3502
- }), t.userMenuActions && t.userMenuActions.length > 0 && await qi({
3545
+ }), t.userMenuActions && t.userMenuActions.length > 0 && await $i({
3503
3546
  actions: t.userMenuActions,
3504
3547
  paths: c,
3505
3548
  projectRoot: r,
3506
3549
  slot: e
3507
3550
  });
3508
- return t.onboardingSteps && t.onboardingSteps.length > 0 && await Vi(t.onboardingSteps, c, r), t.postLoginRedirect && await Ni({
3551
+ return t.onboardingSteps && t.onboardingSteps.length > 0 && await qi(t.onboardingSteps, c, r), t.postLoginRedirect && await Li({
3509
3552
  postLoginRedirect: t.postLoginRedirect,
3510
3553
  paths: c,
3511
3554
  projectRoot: r,
3512
3555
  slot: d[0]
3513
3556
  }), l;
3514
3557
  }
3515
- async function va(e) {
3558
+ async function wa(e) {
3516
3559
  let { packs: t, config: n, projectRoot: r, force: i, overwrite: a, slotsByPack: o } = e, s = [];
3517
3560
  for (let e of t) {
3518
- let t = o?.get(e.manifest.name), a = await ga({
3561
+ let t = o?.get(e.manifest.name), a = await Sa({
3519
3562
  manifest: e.manifest,
3520
3563
  config: n,
3521
3564
  projectRoot: r,
@@ -3535,7 +3578,7 @@ async function va(e) {
3535
3578
  };
3536
3579
  let c = [], l = [], u = [], d = [], f = n;
3537
3580
  for (let e of t) {
3538
- let t = o?.get(e.manifest.name), n = await _a({
3581
+ let t = o?.get(e.manifest.name), n = await Ca({
3539
3582
  manifest: e.manifest,
3540
3583
  config: f,
3541
3584
  projectRoot: r,
@@ -3544,7 +3587,7 @@ async function va(e) {
3544
3587
  packDir: e.packDir,
3545
3588
  slots: t
3546
3589
  });
3547
- c.push(...n.installed), l.push(...n.skipped), u.push(...n.errors), f = await ya(f, e.manifest, r), d.push(e.manifest.name);
3590
+ c.push(...n.installed), l.push(...n.skipped), u.push(...n.errors), f = await Ta(f, e.manifest, r), d.push(e.manifest.name);
3548
3591
  }
3549
3592
  return {
3550
3593
  installed: c,
@@ -3555,7 +3598,7 @@ async function va(e) {
3555
3598
  config: f
3556
3599
  };
3557
3600
  }
3558
- async function ya(e, t, n) {
3601
+ async function Ta(e, t, n) {
3559
3602
  let r = typeof t == "string" ? t : t.name, i = typeof t == "string" ? [] : Mr(t.env), a = Nr([...e.onboarding?.envSections ?? [], ...i]), o = {
3560
3603
  ...e,
3561
3604
  installedPacks: [...e.installedPacks ?? [], r],
@@ -3566,7 +3609,7 @@ async function ya(e, t, n) {
3566
3609
  };
3567
3610
  return await Rr(n, o), o;
3568
3611
  }
3569
- async function ba(e) {
3612
+ async function Ea(e) {
3570
3613
  let { manifest: t, config: n, projectRoot: r, templateDir: i } = e, a = n.paths;
3571
3614
  if (!a) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
3572
3615
  let o = [], s = [], c = t.files.filter((e) => e.strategy === "merge"), l = new Set(c.map((e) => Kr(e.source, i))), u = T.join(i, "files");
@@ -3576,7 +3619,7 @@ async function ba(e) {
3576
3619
  if (!t.isDirectory()) continue;
3577
3620
  let e = a[t.name]?.root;
3578
3621
  if (!e) continue;
3579
- let n = await da({
3622
+ let n = await _a({
3580
3623
  src: T.join(u, t.name),
3581
3624
  dest: T.resolve(r, e),
3582
3625
  projectRoot: r,
@@ -3586,7 +3629,7 @@ async function ba(e) {
3586
3629
  }
3587
3630
  }
3588
3631
  for (let e of c) {
3589
- let t = await ma({
3632
+ let t = await ba({
3590
3633
  file: e,
3591
3634
  packDir: i,
3592
3635
  paths: a,
@@ -3597,12 +3640,12 @@ async function ba(e) {
3597
3640
  t.status === "installed" ? o.push(t.path) : t.status === "error" && s.push(`${t.path}: ${t.reason}`);
3598
3641
  }
3599
3642
  let d = T.join(Gr("{{frontend.root}}", a, r), "src", "routes"), f = T.join(d, "(public)", "index.tsx"), p = T.join(d, "(private)", "index.tsx");
3600
- return await Y(f) && await Y(p) && await y.rm(p, { force: !0 }), t.frontendRoutes && t.frontendRoutes.length > 0 && await Di(t.frontendRoutes, a, r), t.nav && t.nav.length > 0 && await Mi({
3643
+ return await Y(f) && await Y(p) && await y.rm(p, { force: !0 }), t.frontendRoutes && t.frontendRoutes.length > 0 && await ji(t.frontendRoutes, a, r), t.nav && t.nav.length > 0 && await Ii({
3601
3644
  entries: t.nav,
3602
3645
  paths: a,
3603
3646
  projectRoot: r,
3604
3647
  override: !0
3605
- }), t.postLoginRedirect && await Ni({
3648
+ }), t.postLoginRedirect && await Li({
3606
3649
  postLoginRedirect: t.postLoginRedirect,
3607
3650
  paths: a,
3608
3651
  projectRoot: r
@@ -3613,32 +3656,35 @@ async function ba(e) {
3613
3656
  }
3614
3657
  //#endregion
3615
3658
  //#region src/core/pack-categories.ts
3616
- var xa = [
3659
+ var Da = [
3617
3660
  "starter",
3618
3661
  "layout",
3619
3662
  "feature"
3620
- ], Sa = {
3663
+ ], Oa = {
3621
3664
  starter: "Starter",
3622
3665
  layout: "Layout",
3623
3666
  feature: "Features"
3624
- }, Ca = new Set(["starter", "layout"]), wa = "starter-saas-betterauth", Ta = "layout-basic";
3625
- function Ea(e, t = {}) {
3667
+ }, ka = new Set(["starter", "layout"]), Aa = "starter-saas-betterauth", ja = "layout-basic";
3668
+ function Ma(e, t = {}) {
3626
3669
  let n = [];
3627
- for (let r of xa) {
3670
+ for (let r of Da) {
3628
3671
  let i = e.filter((e) => e.category === r);
3629
3672
  if (i.length === 0) continue;
3630
- let a = Ca.has(r) ? "single" : "multiple";
3673
+ let a = ka.has(r) ? "single" : "multiple";
3631
3674
  if (r === "layout") {
3632
- n.push(Oa("frontend", i)), t.adminAvailable && n.push(Oa("admin", i));
3675
+ if (n.push(Pa("frontend", i)), t.adminAvailable) {
3676
+ let e = i.filter((e) => e.adminCompatible);
3677
+ e.length > 0 && n.push(Pa("admin", e));
3678
+ }
3633
3679
  continue;
3634
3680
  }
3635
3681
  if (r === "starter") {
3636
- n.push(Da(i));
3682
+ n.push(Na(i));
3637
3683
  continue;
3638
3684
  }
3639
3685
  n.push({
3640
3686
  category: r,
3641
- label: Sa[r],
3687
+ label: Oa[r],
3642
3688
  mode: a,
3643
3689
  packs: i,
3644
3690
  preselect: null
@@ -3646,36 +3692,36 @@ function Ea(e, t = {}) {
3646
3692
  }
3647
3693
  return n;
3648
3694
  }
3649
- function Da(e) {
3650
- let t = e.some((e) => e.name === wa);
3695
+ function Na(e) {
3696
+ let t = e.some((e) => e.name === Aa);
3651
3697
  return {
3652
3698
  category: "starter",
3653
- label: Sa.starter,
3699
+ label: Oa.starter,
3654
3700
  mode: "single",
3655
3701
  packs: e,
3656
- preselect: t ? wa : null
3702
+ preselect: t ? Aa : null
3657
3703
  };
3658
3704
  }
3659
- function Oa(e, t) {
3660
- let n = t.some((e) => e.name === Ta);
3705
+ function Pa(e, t) {
3706
+ let n = t.some((e) => e.name === ja);
3661
3707
  return {
3662
3708
  category: "layout",
3663
3709
  label: e === "admin" ? "Admin Layout" : "Layout",
3664
3710
  mode: "single",
3665
3711
  packs: t,
3666
- preselect: n ? Ta : null,
3712
+ preselect: n ? ja : null,
3667
3713
  slot: e
3668
3714
  };
3669
3715
  }
3670
3716
  //#endregion
3671
3717
  //#region src/core/post-setup.ts
3672
- async function ka() {
3718
+ async function Fa() {
3673
3719
  return (await J("docker", ["info"], { cwd: process.cwd() })).exitCode === 0;
3674
3720
  }
3675
- async function Aa(e) {
3721
+ async function Ia(e) {
3676
3722
  return Y(`${e}/apps/backend/.env`);
3677
3723
  }
3678
- async function ja(e, t, n) {
3724
+ async function La(e, t, n) {
3679
3725
  let r = n ? `Start services with ${R.command("docker compose up -d")}?` : `Docker is not running. Start services with ${R.command("docker compose up -d")}?`, i = t ? !0 : await s.confirm({
3680
3726
  message: r,
3681
3727
  initialValue: !0
@@ -3688,32 +3734,32 @@ async function ja(e, t, n) {
3688
3734
  "up",
3689
3735
  "-d"
3690
3736
  ], { cwd: `${e}/apps/backend` });
3691
- return o.exitCode === 0 ? (a.stop(R.success("Docker services started")), !0) : (a.error("Failed to start Docker services"), Ia(o), !1);
3737
+ return o.exitCode === 0 ? (a.stop(R.success("Docker services started")), !0) : (a.error("Failed to start Docker services"), Ha(o), !1);
3692
3738
  }
3693
- function Ma(e) {
3739
+ function Ra(e) {
3694
3740
  let t = (e.stderr || e.stdout).trim();
3695
3741
  t && s.log.warn(R.muted(t));
3696
3742
  }
3697
- function Na(e) {
3743
+ function za(e) {
3698
3744
  return /is already in use by container|Conflict\. The container name/i.test(e) ? "container" : /port is already allocated|address already in use|Bind for .+ failed|failed to (?:bind|set up) .*port/i.test(e) ? "port" : null;
3699
3745
  }
3700
- function Pa(e) {
3746
+ function Ba(e) {
3701
3747
  return e.match(/container name "\/?([^"]+)"/i)?.[1] ?? null;
3702
3748
  }
3703
- function Fa(e) {
3749
+ function Va(e) {
3704
3750
  return e.match(/Bind for [^:]*:(\d{2,5})/i)?.[1] ?? e.match(/:(\d{2,5})(?:->|\b)[^\n]*(?:already allocated|already in use)/i)?.[1] ?? null;
3705
3751
  }
3706
- function Ia(e) {
3707
- let t = (e.stderr || e.stdout).trim(), n = Na(t);
3752
+ function Ha(e) {
3753
+ let t = (e.stderr || e.stdout).trim(), n = za(t);
3708
3754
  if (!n) {
3709
3755
  t && s.log.warn(R.muted(t));
3710
3756
  return;
3711
3757
  }
3712
3758
  if (n === "container") {
3713
- let e = Pa(t);
3759
+ let e = Ba(t);
3714
3760
  s.log.warn(R.muted(`${e ? `Container ${R.command(e)}` : "One of this project's containers"} is already running, most likely from another Hype Stack project. The template uses fixed container names, so two projects can't run their services at the same time.`));
3715
3761
  } else {
3716
- let e = Fa(t);
3762
+ let e = Va(t);
3717
3763
  s.log.warn(R.muted(`${e ? `Host port ${R.command(e)}` : "A host port this project needs"} is already taken, most likely by another Hype Stack project. The template uses fixed ports, so two projects can't run their services at the same time.`));
3718
3764
  }
3719
3765
  B([
@@ -3722,7 +3768,7 @@ function Ia(e) {
3722
3768
  R.muted("then re-run this command and start Docker again")
3723
3769
  ].join("\n"), "Free up Docker, then retry"), t && s.log.warn(R.muted(t));
3724
3770
  }
3725
- async function La(e, t = 15, n = 2e3) {
3771
+ async function Ua(e, t = 15, n = 2e3) {
3726
3772
  for (let r = 0; r < t; r++) {
3727
3773
  if ((await J("docker", [
3728
3774
  "compose",
@@ -3737,8 +3783,8 @@ async function La(e, t = 15, n = 2e3) {
3737
3783
  }
3738
3784
  return !1;
3739
3785
  }
3740
- var Ra = "Database schema is up to date";
3741
- async function za(e) {
3786
+ var Wa = "Database schema is up to date";
3787
+ async function Ga(e) {
3742
3788
  let t = await J("pnpm", [
3743
3789
  "--filter",
3744
3790
  "@internal/backend",
@@ -3747,9 +3793,9 @@ async function za(e) {
3747
3793
  "migrate",
3748
3794
  "status"
3749
3795
  ], { cwd: e });
3750
- return t.exitCode === 0 ? `${t.stdout}\n${t.stderr}`.includes(Ra) : !1;
3796
+ return t.exitCode === 0 ? `${t.stdout}\n${t.stderr}`.includes(Wa) : !1;
3751
3797
  }
3752
- async function Ba(e) {
3798
+ async function Ka(e) {
3753
3799
  let t = s.spinner();
3754
3800
  t.start("Running database migrations...");
3755
3801
  let n = await J("pnpm", [
@@ -3757,15 +3803,15 @@ async function Ba(e) {
3757
3803
  "@internal/backend",
3758
3804
  "migration:latest"
3759
3805
  ], { cwd: e });
3760
- return n.exitCode === 0 ? (t.stop(R.success("Database migrations applied")), !0) : (t.error("Migrations failed"), Ma(n), s.log.warn(R.muted("Run `pnpm --filter @internal/backend migration:latest` manually to apply migrations.")), !1);
3806
+ return n.exitCode === 0 ? (t.stop(R.success("Database migrations applied")), !0) : (t.error("Migrations failed"), Ra(n), s.log.warn(R.muted("Run `pnpm --filter @internal/backend migration:latest` manually to apply migrations.")), !1);
3761
3807
  }
3762
- async function Va(e, t, n = {}) {
3763
- if (!await ja(e, t, await ka())) return !1;
3808
+ async function qa(e, t, n = {}) {
3809
+ if (!await La(e, t, await Fa())) return !1;
3764
3810
  let r = s.spinner();
3765
- return r.start("Waiting for Postgres to be ready..."), await La(e, n.postgresMaxAttempts ?? 15, n.postgresCheckIntervalMs ?? 2e3) ? (r.stop(R.success("Postgres is ready")), !0) : (r.error("Postgres health check timed out"), s.log.warn(R.muted("Run migrations manually once Postgres is ready: pnpm --filter @internal/backend migration:latest")), !1);
3811
+ return r.start("Waiting for Postgres to be ready..."), await Ua(e, n.postgresMaxAttempts ?? 15, n.postgresCheckIntervalMs ?? 2e3) ? (r.stop(R.success("Postgres is ready")), !0) : (r.error("Postgres health check timed out"), s.log.warn(R.muted("Run migrations manually once Postgres is ready: pnpm --filter @internal/backend migration:latest")), !1);
3766
3812
  }
3767
- async function Ha(e, t, n = {}) {
3768
- if (!await Va(e, t, n)) return;
3813
+ async function Ja(e, t, n = {}) {
3814
+ if (!await qa(e, t, n)) return;
3769
3815
  let r = t ? !0 : await s.confirm({
3770
3816
  message: `Run database migrations with ${R.command("prisma migrate deploy")}?`,
3771
3817
  initialValue: !0
@@ -3774,21 +3820,21 @@ async function Ha(e, t, n = {}) {
3774
3820
  s.log.info(R.muted("Skipping database migrations."));
3775
3821
  return;
3776
3822
  }
3777
- await Ba(e);
3823
+ await Ka(e);
3778
3824
  }
3779
- async function Ua(e, t, n = {}) {
3780
- if (!await Aa(e)) {
3825
+ async function Ya(e, t, n = {}) {
3826
+ if (!await Ia(e)) {
3781
3827
  s.log.warn(`${R.path(".env")} not found in ${R.path("apps/backend")}. Skipping Docker and migrations - configure it first.`);
3782
3828
  return;
3783
3829
  }
3784
- await Ha(e, t, n);
3830
+ await Ja(e, t, n);
3785
3831
  }
3786
- async function Wa(e, t, n = {}) {
3787
- return await Aa(e) ? Va(e, t, n) : (s.log.warn(`${R.path(".env")} not found in ${R.path("apps/backend")}. Skipping Docker - configure it first.`), !1);
3832
+ async function Xa(e, t, n = {}) {
3833
+ return await Ia(e) ? qa(e, t, n) : (s.log.warn(`${R.path(".env")} not found in ${R.path("apps/backend")}. Skipping Docker - configure it first.`), !1);
3788
3834
  }
3789
3835
  //#endregion
3790
3836
  //#region src/core/resolve.ts
3791
- function Ga(e) {
3837
+ function Za(e) {
3792
3838
  let t = /* @__PURE__ */ new Map();
3793
3839
  for (let n of e) t.set(n.name, {
3794
3840
  name: n.name,
@@ -3796,7 +3842,7 @@ function Ga(e) {
3796
3842
  });
3797
3843
  return t;
3798
3844
  }
3799
- function Ka(e, t, n = /* @__PURE__ */ new Set()) {
3845
+ function Qa(e, t, n = /* @__PURE__ */ new Set()) {
3800
3846
  let r = /* @__PURE__ */ new Set();
3801
3847
  function i(e) {
3802
3848
  if (n.has(e)) return [];
@@ -3810,10 +3856,10 @@ function Ka(e, t, n = /* @__PURE__ */ new Set()) {
3810
3856
  }
3811
3857
  return i(e);
3812
3858
  }
3813
- function qa(e, t, n = []) {
3859
+ function $a(e, t, n = []) {
3814
3860
  let r = new Set(n), i = new Set(n), a = [];
3815
3861
  for (let n of e) {
3816
- let e = Ka(n, t, new Set(i));
3862
+ let e = Qa(n, t, new Set(i));
3817
3863
  for (let t of e) i.has(t) || (i.add(t), a.push(t));
3818
3864
  }
3819
3865
  return {
@@ -3821,7 +3867,7 @@ function qa(e, t, n = []) {
3821
3867
  alreadyInstalled: e.filter((e) => r.has(e))
3822
3868
  };
3823
3869
  }
3824
- function Ja(e) {
3870
+ function eo(e) {
3825
3871
  let { order: t, graph: n, isLocked: r, installed: i = [] } = e, a = new Set(i), o = /* @__PURE__ */ new Set();
3826
3872
  for (let e of t) {
3827
3873
  let t = n.get(e)?.dependencies.some((e) => !a.has(e) && o.has(e)) ?? !1;
@@ -3834,7 +3880,7 @@ function Ja(e) {
3834
3880
  }
3835
3881
  //#endregion
3836
3882
  //#region src/core/variants.ts
3837
- function Ya(e, t = {}) {
3883
+ function to(e, t = {}) {
3838
3884
  let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
3839
3885
  for (let i of e) {
3840
3886
  let e = t[i.family] ?? i.default;
@@ -3846,18 +3892,18 @@ function Ya(e, t = {}) {
3846
3892
  familyOf: r
3847
3893
  };
3848
3894
  }
3849
- function Xa(e, t, n) {
3895
+ function no(e, t, n) {
3850
3896
  let r = e.map((e) => n.chosen.get(e.family) ?? e.default), i = new Set(e.map((e) => e.family)), a = t.filter((e) => {
3851
3897
  let t = n.familyOf.get(e);
3852
3898
  return !(t && i.has(t));
3853
3899
  });
3854
3900
  return [...r, ...a];
3855
3901
  }
3856
- function Za(e, t) {
3902
+ function ro(e, t) {
3857
3903
  let n = t.familyOf.get(e);
3858
3904
  return n ? t.chosen.get(n) ?? e : e;
3859
3905
  }
3860
- function Qa(e, t) {
3906
+ function io(e, t) {
3861
3907
  let n = /* @__PURE__ */ new Map();
3862
3908
  for (let t of e) t.family && n.set(t.name, t.family);
3863
3909
  let r = new Set(t), i = /* @__PURE__ */ new Map();
@@ -3873,65 +3919,65 @@ function Qa(e, t) {
3873
3919
  familyOf: n
3874
3920
  };
3875
3921
  }
3876
- function $a(e, t) {
3922
+ function ao(e, t) {
3877
3923
  return e.map((e) => ({
3878
3924
  ...e,
3879
- dependencies: e.dependencies.map((e) => Za(e, t))
3925
+ dependencies: e.dependencies.map((e) => ro(e, t))
3880
3926
  }));
3881
3927
  }
3882
3928
  //#endregion
3883
3929
  //#region src/ui/banner.ts
3884
- var eo = [
3930
+ var oo = [
3885
3931
  " ██╗ ██╗ ██╗ ██╗ ██████╗ ███████╗",
3886
3932
  " ██║ ██║ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝",
3887
3933
  " ███████║ ╚████╔╝ ██████╔╝ █████╗ ",
3888
3934
  " ██╔══██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ",
3889
3935
  " ██║ ██║ ██║ ██║ ███████╗",
3890
3936
  " ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝"
3891
- ], to = [
3937
+ ], so = [
3892
3938
  " ███████╗ ████████╗ █████╗ ██████╗ ██╗ ██╗",
3893
3939
  " ██╔════╝ ╚══██╔══╝ ██╔══██╗ ██╔════╝ ██║ ██╔╝",
3894
3940
  " ███████╗ ██║ ███████║ ██║ █████╔╝ ",
3895
3941
  " ╚════██║ ██║ ██╔══██║ ██║ ██╔═██╗ ",
3896
3942
  " ███████║ ██║ ██║ ██║ ╚██████╗ ██║ ██╗",
3897
3943
  " ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝"
3898
- ], no = [
3944
+ ], co = [
3899
3945
  253,
3900
3946
  176,
3901
3947
  21
3902
- ], ro = [
3948
+ ], lo = [
3903
3949
  245,
3904
3950
  76,
3905
3951
  2
3906
- ], io = 5, ao = [
3952
+ ], uo = 5, fo = [
3907
3953
  17,
3908
3954
  103,
3909
3955
  248
3910
- ], oo = [
3956
+ ], po = [
3911
3957
  42,
3912
3958
  160,
3913
3959
  250
3914
- ], so = .2;
3915
- function co() {
3960
+ ], mo = .2;
3961
+ function ho() {
3916
3962
  console.log();
3917
- for (let e of xe(eo, {
3918
- start: no,
3919
- end: ro,
3920
- angle: io
3963
+ for (let e of xe(oo, {
3964
+ start: co,
3965
+ end: lo,
3966
+ angle: uo
3921
3967
  })) console.log(b.bold(e));
3922
- for (let e of xe(to, {
3923
- start: ao,
3924
- end: oo,
3925
- angle: so
3968
+ for (let e of xe(so, {
3969
+ start: fo,
3970
+ end: po,
3971
+ angle: mo
3926
3972
  })) console.log(b.bold(e));
3927
3973
  console.log(), console.log(` ${z.spark} ${b.dim("v" + A)} ${b.dim("·")} ${ye("Ship web + desktop apps from one codebase")}`), console.log();
3928
3974
  }
3929
- function lo() {
3975
+ function go() {
3930
3976
  console.log(), console.log(` ${z.bolt} ${ge.orange("Hype")}${ge.skyBlue("Stack")} ${b.dim("v" + A)}`), console.log();
3931
3977
  }
3932
3978
  //#endregion
3933
3979
  //#region src/ui/pack-multiselect.ts
3934
- var uo = class extends O {
3980
+ var _o = class extends O {
3935
3981
  options;
3936
3982
  cursor = 0;
3937
3983
  selected;
@@ -4035,12 +4081,12 @@ var uo = class extends O {
4035
4081
  }
4036
4082
  }
4037
4083
  };
4038
- function fo(e) {
4039
- return new uo(e).prompt();
4084
+ function vo(e) {
4085
+ return new _o(e).prompt();
4040
4086
  }
4041
4087
  //#endregion
4042
4088
  //#region src/utils/validate.ts
4043
- function po(e) {
4089
+ function yo(e) {
4044
4090
  if (!e.trim()) return "Project name cannot be empty";
4045
4091
  if (e.length > 214) return "Project name is too long (max 214 characters)";
4046
4092
  let t = Sr(e);
@@ -4048,43 +4094,43 @@ function po(e) {
4048
4094
  }
4049
4095
  //#endregion
4050
4096
  //#region src/core/apply-mode.ts
4051
- var mo = "src/hooks/use-theme.ts", ho = /(\bexport\s+const\s+defaultTheme\s*=\s*)(["'])(?:light|dark)\2/;
4052
- function go(e, t) {
4053
- return e.replace(ho, (e, n, r) => `${n}${r}${t}${r}`);
4097
+ var bo = "src/hooks/use-theme.ts", xo = /(\bexport\s+const\s+defaultTheme\s*=\s*)(["'])(?:light|dark)\2/;
4098
+ function So(e, t) {
4099
+ return e.replace(xo, (e, n, r) => `${n}${r}${t}${r}`);
4054
4100
  }
4055
- async function _o(e, t) {
4056
- let n = T.resolve(e, mo), r;
4101
+ async function Co(e, t) {
4102
+ let n = T.resolve(e, bo), r;
4057
4103
  try {
4058
4104
  r = await y.readFile(n, "utf-8");
4059
4105
  } catch {
4060
4106
  return !1;
4061
4107
  }
4062
- let i = go(r, t);
4108
+ let i = So(r, t);
4063
4109
  return i === r || await y.writeFile(n, i, "utf-8"), !0;
4064
4110
  }
4065
4111
  //#endregion
4066
4112
  //#region src/core/apply-radius.ts
4067
- var vo = /(^[ \t]*--radius(?![\w-])[ \t]*:[ \t]*)([^;\n]*);/gm;
4068
- function yo(e) {
4113
+ var wo = /(^[ \t]*--radius(?![\w-])[ \t]*:[ \t]*)([^;\n]*);/gm;
4114
+ function To(e) {
4069
4115
  return /^[0-9]*\.?[0-9]+(rem|em|px)$/.test(e.trim());
4070
4116
  }
4071
- function bo(e, t) {
4072
- return e.replace(vo, (e, n) => `${n}${t};`);
4117
+ function Eo(e, t) {
4118
+ return e.replace(wo, (e, n) => `${n}${t};`);
4073
4119
  }
4074
- var xo = "assets/styles.css";
4075
- async function So(e, t) {
4076
- let n = T.resolve(e, xo), r;
4120
+ var Do = "assets/styles.css";
4121
+ async function Oo(e, t) {
4122
+ let n = T.resolve(e, Do), r;
4077
4123
  try {
4078
4124
  r = await y.readFile(n, "utf-8");
4079
4125
  } catch {
4080
4126
  return !1;
4081
4127
  }
4082
- let i = bo(r, t);
4128
+ let i = Eo(r, t);
4083
4129
  return i === r || await y.writeFile(n, i, "utf-8"), !0;
4084
4130
  }
4085
4131
  //#endregion
4086
4132
  //#region src/core/apply-theme.ts
4087
- function Co(e, t) {
4133
+ function ko(e, t) {
4088
4134
  let n = 0;
4089
4135
  for (; n < e.length;) {
4090
4136
  let r = e.indexOf(t, n);
@@ -4107,46 +4153,46 @@ function Co(e, t) {
4107
4153
  }
4108
4154
  return null;
4109
4155
  }
4110
- function wo(e, t) {
4156
+ function Ao(e, t) {
4111
4157
  let n = e;
4112
4158
  for (let [e, r] of Object.entries(t)) {
4113
- let t = RegExp(`(^[ \\t]*--${To(e)}[ \\t]*:[ \\t]*)([^;\\n]*);`, "m");
4159
+ let t = RegExp(`(^[ \\t]*--${jo(e)}[ \\t]*:[ \\t]*)([^;\\n]*);`, "m");
4114
4160
  n = n.replace(t, (e, t) => `${t}${r};`);
4115
4161
  }
4116
4162
  return n;
4117
4163
  }
4118
- function To(e) {
4164
+ function jo(e) {
4119
4165
  return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4120
4166
  }
4121
- function Eo(e, t) {
4122
- let n = Co(e, ":root"), r = Co(e, ".dark"), i = e;
4167
+ function Mo(e, t) {
4168
+ let n = ko(e, ":root"), r = ko(e, ".dark"), i = e;
4123
4169
  if (n) {
4124
4170
  let e = i.slice(0, n.bodyStart), r = i.slice(n.bodyStart, n.bodyEnd), a = i.slice(n.bodyEnd);
4125
- i = e + wo(r, t.light) + a;
4171
+ i = e + Ao(r, t.light) + a;
4126
4172
  }
4127
4173
  if (r) {
4128
- let e = Co(i, ".dark");
4174
+ let e = ko(i, ".dark");
4129
4175
  if (e) {
4130
4176
  let n = i.slice(0, e.bodyStart), r = i.slice(e.bodyStart, e.bodyEnd), a = i.slice(e.bodyEnd);
4131
- i = n + wo(r, t.dark) + a;
4177
+ i = n + Ao(r, t.dark) + a;
4132
4178
  }
4133
4179
  }
4134
4180
  return i;
4135
4181
  }
4136
- var Do = "assets/styles.css";
4137
- async function Oo(e, t) {
4138
- let n = T.resolve(e, Do), r;
4182
+ var No = "assets/styles.css";
4183
+ async function Po(e, t) {
4184
+ let n = T.resolve(e, No), r;
4139
4185
  try {
4140
4186
  r = await y.readFile(n, "utf-8");
4141
4187
  } catch {
4142
4188
  return !1;
4143
4189
  }
4144
- let i = Eo(r, t);
4190
+ let i = Mo(r, t);
4145
4191
  return i === r || await y.writeFile(n, i, "utf-8"), !0;
4146
4192
  }
4147
4193
  //#endregion
4148
4194
  //#region src/core/clone.ts
4149
- async function ko(e) {
4195
+ async function Fo(e) {
4150
4196
  let t = await ee(j, {
4151
4197
  dir: e,
4152
4198
  force: !0
@@ -4158,7 +4204,7 @@ async function ko(e) {
4158
4204
  }
4159
4205
  //#endregion
4160
4206
  //#region src/core/editor-config.ts
4161
- function Ao(e) {
4207
+ function Io(e) {
4162
4208
  let t = {
4163
4209
  globs: [],
4164
4210
  alwaysApply: !1
@@ -4193,10 +4239,10 @@ function Ao(e) {
4193
4239
  content: i
4194
4240
  };
4195
4241
  }
4196
- function jo(e) {
4242
+ function Lo(e) {
4197
4243
  return e.frontmatter.globs.length > 0 ? `---\npaths:\n${e.frontmatter.globs.map((e) => ` - "${e}"`).join("\n")}\n---\n\n${e.content}` : e.content;
4198
4244
  }
4199
- function Mo(e) {
4245
+ function Ro(e) {
4200
4246
  let t;
4201
4247
  t = e.frontmatter.alwaysApply ? "always_on" : e.frontmatter.globs.length > 0 ? "glob" : "model_decision";
4202
4248
  let n = [`trigger: ${t}`];
@@ -4206,30 +4252,30 @@ function Mo(e) {
4206
4252
  }
4207
4253
  return e.frontmatter.description && n.push(`description: ${e.frontmatter.description}`), `---\n${n.join("\n")}\n---\n\n${e.content}`;
4208
4254
  }
4209
- function No(e) {
4255
+ function zo(e) {
4210
4256
  return e.frontmatter.globs.length > 0 ? `---\napplyTo: "${e.frontmatter.globs.join(", ")}"\n---\n\n${e.content}` : e.content;
4211
4257
  }
4212
- var Po = {
4258
+ var Bo = {
4213
4259
  claude: {
4214
4260
  rulesDir: ".claude/rules",
4215
4261
  extension: ".md",
4216
- convert: jo
4262
+ convert: Lo
4217
4263
  },
4218
4264
  windsurf: {
4219
4265
  rulesDir: ".windsurf/rules",
4220
4266
  extension: ".md",
4221
- convert: Mo
4267
+ convert: Ro
4222
4268
  },
4223
4269
  copilot: {
4224
4270
  rulesDir: ".github/instructions",
4225
4271
  extension: ".instructions.md",
4226
- convert: No
4272
+ convert: zo
4227
4273
  }
4228
4274
  };
4229
- async function Fo(e) {
4275
+ async function Vo(e) {
4230
4276
  let t = T.join(e, ie), n = (await y.readdir(t, { withFileTypes: !0 }).catch(() => [])).filter((e) => e.isFile() && e.name.endsWith(".mdc"));
4231
4277
  return await Promise.all(n.map(async (e) => {
4232
- let n = T.join(t, e.name), { frontmatter: r, content: i } = Ao(await y.readFile(n, "utf-8"));
4278
+ let n = T.join(t, e.name), { frontmatter: r, content: i } = Io(await y.readFile(n, "utf-8"));
4233
4279
  return {
4234
4280
  frontmatter: r,
4235
4281
  content: i,
@@ -4237,9 +4283,9 @@ async function Fo(e) {
4237
4283
  };
4238
4284
  }));
4239
4285
  }
4240
- async function Io(e, t) {
4286
+ async function Ho(e, t) {
4241
4287
  if (t === "cursor") return;
4242
- let n = Po[t], r = await Fo(e), i = T.join(e, n.rulesDir);
4288
+ let n = Bo[t], r = await Vo(e), i = T.join(e, n.rulesDir);
4243
4289
  await y.mkdir(i, { recursive: !0 }), await Promise.all(r.map((e) => {
4244
4290
  let t = n.convert(e), r = e.filename.replace(/\.mdc$/, n.extension);
4245
4291
  return y.writeFile(T.join(i, r), t, "utf-8");
@@ -4247,21 +4293,21 @@ async function Io(e, t) {
4247
4293
  }
4248
4294
  //#endregion
4249
4295
  //#region src/core/env-files.ts
4250
- var Lo = [
4296
+ var Uo = [
4251
4297
  "apps",
4252
4298
  "packages",
4253
4299
  "libs",
4254
4300
  "shared"
4255
4301
  ];
4256
- async function Ro(e) {
4257
- let t = await zo(e);
4302
+ async function Wo(e) {
4303
+ let t = await Go(e);
4258
4304
  return (await Promise.all(t.map(async (t) => {
4259
4305
  let n = T.join(T.dirname(t), ".env");
4260
4306
  return await Y(n) ? null : (await y.copyFile(t, n), T.relative(e, n));
4261
4307
  }))).filter((e) => e !== null).sort();
4262
4308
  }
4263
- async function zo(e) {
4264
- let t = [T.join(e, ".env.example")], n = await Promise.all(Lo.map(async (t) => {
4309
+ async function Go(e) {
4310
+ let t = [T.join(e, ".env.example")], n = await Promise.all(Uo.map(async (t) => {
4265
4311
  let n = T.join(e, t);
4266
4312
  return (await y.readdir(n, { withFileTypes: !0 }).catch(() => [])).filter((e) => e.isDirectory()).map((e) => T.join(n, e.name, ".env.example"));
4267
4313
  }));
@@ -4269,11 +4315,11 @@ async function zo(e) {
4269
4315
  }
4270
4316
  //#endregion
4271
4317
  //#region src/core/post-clone.ts
4272
- var Q = "@hype-stack/", Bo = "hype-stack", Vo = "@hype-stack/cli";
4273
- async function Ho(e) {
4318
+ var Q = "@hype-stack/", Ko = "hype-stack", qo = "@hype-stack/cli";
4319
+ async function Jo(e) {
4274
4320
  await mr(T.join(e, ".git"));
4275
4321
  }
4276
- async function Uo(e) {
4322
+ async function Yo(e) {
4277
4323
  await J("git", ["init"], { cwd: e }), await J("git", ["add", "."], { cwd: e }), await J("git", [
4278
4324
  "-c",
4279
4325
  "user.name=Hype Stack CLI",
@@ -4284,19 +4330,19 @@ async function Uo(e) {
4284
4330
  "Initial commit from Hype Stack CLI"
4285
4331
  ], { cwd: e });
4286
4332
  }
4287
- async function Wo(e, t) {
4288
- let n = `@${t}/`, r = await Qo(e);
4333
+ async function Xo(e, t) {
4334
+ let n = `@${t}/`, r = await is(e);
4289
4335
  for (let e of r) {
4290
4336
  let t = await dr(e);
4291
4337
  if (!t) continue;
4292
4338
  let r = !1;
4293
- t.name?.startsWith(Q) && (t.name = t.name.replace(Q, n), r = !0), Yo(t.dependencies, n) && (r = !0), Yo(t.devDependencies, n) && (r = !0), t.nx && Xo(t.nx, n) && (r = !0);
4339
+ t.name?.startsWith(Q) && (t.name = t.name.replace(Q, n), r = !0), ts(t.dependencies, n) && (r = !0), ts(t.devDependencies, n) && (r = !0), t.nx && ns(t.nx, n) && (r = !0);
4294
4340
  let i = await y.readFile(e, "utf-8"), a = ei(i, n);
4295
4341
  a === i ? r && await fr(e, t) : await y.writeFile(e, a, "utf-8");
4296
4342
  }
4297
- await oa(e, t), await qo(e, t), await Zo(e, t);
4343
+ await fa(e, t), await $o(e, t), await rs(e, t);
4298
4344
  }
4299
- var Go = new Set([
4345
+ var Zo = new Set([
4300
4346
  ".git",
4301
4347
  "node_modules",
4302
4348
  "dist",
@@ -4304,10 +4350,10 @@ var Go = new Set([
4304
4350
  ".nx",
4305
4351
  ".next",
4306
4352
  "coverage"
4307
- ]), Ko = /^(docker-compose|compose)(\.[\w.-]+)?\.ya?ml$/;
4308
- async function qo(e, t) {
4309
- if (t === Bo) return;
4310
- let n = await Jo(e);
4353
+ ]), Qo = /^(docker-compose|compose)(\.[\w.-]+)?\.ya?ml$/;
4354
+ async function $o(e, t) {
4355
+ if (t === Ko) return;
4356
+ let n = await es(e);
4311
4357
  await Promise.all(n.map(async (e) => {
4312
4358
  let n = await y.readFile(e, "utf-8").catch(() => null);
4313
4359
  if (!n || !/^[ \t]*(?:name|container_name):[ \t]*hype-stack/m.test(n)) return;
@@ -4315,23 +4361,23 @@ async function qo(e, t) {
4315
4361
  await y.writeFile(e, r, "utf-8");
4316
4362
  }));
4317
4363
  }
4318
- async function Jo(e) {
4364
+ async function es(e) {
4319
4365
  let t = await y.readdir(e, { withFileTypes: !0 }).catch(() => []);
4320
4366
  return (await Promise.all(t.map(async (t) => {
4321
4367
  let n = T.join(e, t.name);
4322
- return t.isDirectory() ? Go.has(t.name) ? [] : Jo(n) : t.isFile() && Ko.test(t.name) ? [n] : [];
4368
+ return t.isDirectory() ? Zo.has(t.name) ? [] : es(n) : t.isFile() && Qo.test(t.name) ? [n] : [];
4323
4369
  }))).flat();
4324
4370
  }
4325
- function Yo(e, t) {
4371
+ function ts(e, t) {
4326
4372
  if (!e) return !1;
4327
4373
  let n = !1;
4328
- for (let r of Object.keys(e)) if (r !== Vo && r.startsWith(Q)) {
4374
+ for (let r of Object.keys(e)) if (r !== qo && r.startsWith(Q)) {
4329
4375
  let i = r.replace(Q, t);
4330
4376
  e[i] = e[r], delete e[r], n = !0;
4331
4377
  }
4332
4378
  return n;
4333
4379
  }
4334
- function Xo(e, t) {
4380
+ function ns(e, t) {
4335
4381
  if (!e) return !1;
4336
4382
  let n = !1;
4337
4383
  if (e.implicitDependencies &&= e.implicitDependencies.map((e) => e.startsWith(Q) ? (n = !0, e.replace(Q, t)) : e), e.targets) {
@@ -4339,13 +4385,13 @@ function Xo(e, t) {
4339
4385
  }
4340
4386
  return n;
4341
4387
  }
4342
- async function Zo(e, t) {
4388
+ async function rs(e, t) {
4343
4389
  let n = T.join(e, "packages/enums/src/app/index.ts"), r = await y.readFile(n, "utf-8").catch(() => null);
4344
4390
  if (!r) return;
4345
- let i = Cr(t), a = r.replaceAll(`id: "${Bo}"`, `id: "${t}"`).replaceAll(`name: "${Bo}"`, `name: "${t}"`).replace(/name: "Hype Stack"/, `name: "${i}"`).replace(/description: ".*?"/, `description: "${i} application"`);
4391
+ let i = Cr(t), a = r.replaceAll(`id: "${Ko}"`, `id: "${t}"`).replaceAll(`name: "${Ko}"`, `name: "${t}"`).replace(/name: "Hype Stack"/, `name: "${i}"`).replace(/description: ".*?"/, `description: "${i} application"`);
4346
4392
  await y.writeFile(n, a, "utf-8");
4347
4393
  }
4348
- async function Qo(e) {
4394
+ async function is(e) {
4349
4395
  let t = [], n = T.join(e, "package.json");
4350
4396
  (await y.stat(n).catch(() => null))?.isFile() && t.push(n);
4351
4397
  for (let n of [
@@ -4365,7 +4411,7 @@ async function Qo(e) {
4365
4411
  }
4366
4412
  //#endregion
4367
4413
  //#region src/core/readme.ts
4368
- var $o = {
4414
+ var as = {
4369
4415
  cursor: {
4370
4416
  label: "Cursor",
4371
4417
  rulesDir: ".cursor/rules"
@@ -4382,21 +4428,21 @@ var $o = {
4382
4428
  label: "GitHub Copilot",
4383
4429
  rulesDir: ".github/instructions"
4384
4430
  }
4385
- }, es = {
4431
+ }, os = {
4386
4432
  backend: "Hono API server (Postgres, Prisma, Kysely, Valkey cache, WorkOS auth)",
4387
4433
  frontend: "React + Vite app talking to the backend through the typed HyperFetch SDK"
4388
- }, ts = {
4434
+ }, ss = {
4389
4435
  enums: "Shared enums and app config used across apps",
4390
4436
  cli: "Project tooling and code generators"
4391
4437
  };
4392
- function ns(e, t) {
4438
+ function cs(e, t) {
4393
4439
  return Object.entries(e).toSorted(([e], [t]) => e.localeCompare(t)).map(([e, n]) => {
4394
4440
  let r = t[e];
4395
4441
  return r ? `- \`${n}\` - ${r}` : `- \`${n}\``;
4396
4442
  });
4397
4443
  }
4398
- function rs(e) {
4399
- let { projectName: t, editor: n, workspace: r } = e, i = Cr(t), a = $o[n], o = !!r.apps.backend, s = ns(r.apps, es), c = ns(r.packages, ts), l = [];
4444
+ function ls(e) {
4445
+ let { projectName: t, editor: n, workspace: r } = e, i = Cr(t), a = as[n], o = !!r.apps.backend, s = cs(r.apps, os), c = cs(r.packages, ss), l = [];
4400
4446
  s.length > 0 && l.push(...s), c.length > 0 && l.push(...c), l.push("- `stack.json` - Hype Stack workspace config (apps, paths, installed packs)");
4401
4447
  let u = [];
4402
4448
  u.push(`# ${i}`), u.push([
@@ -4499,13 +4545,13 @@ function rs(e) {
4499
4545
  "stays useful."
4500
4546
  ].join("\n")), u.join("\n\n") + "\n";
4501
4547
  }
4502
- async function is(e, t) {
4548
+ async function us(e, t) {
4503
4549
  let n = T.join(e, "README.md");
4504
- await y.writeFile(n, rs(t), "utf-8");
4550
+ await y.writeFile(n, ls(t), "utf-8");
4505
4551
  }
4506
4552
  //#endregion
4507
4553
  //#region src/core/tracking.ts
4508
- async function as(e) {
4554
+ async function ds(e) {
4509
4555
  try {
4510
4556
  let t = {
4511
4557
  "X-Device-Id": er(),
@@ -4519,7 +4565,7 @@ async function as(e) {
4519
4565
  }
4520
4566
  //#endregion
4521
4567
  //#region src/core/npm-deps.ts
4522
- function os(e, t) {
4568
+ function fs(e, t) {
4523
4569
  let n = [], r = [];
4524
4570
  if (!e) return {
4525
4571
  errors: n,
@@ -4550,7 +4596,7 @@ function os(e, t) {
4550
4596
  operations: r
4551
4597
  };
4552
4598
  }
4553
- function ss(e) {
4599
+ function ps(e) {
4554
4600
  let t = {};
4555
4601
  for (let n of e) if (n) for (let [e, r] of Object.entries(n)) t[e] = {
4556
4602
  ...t[e],
@@ -4558,7 +4604,7 @@ function ss(e) {
4558
4604
  };
4559
4605
  return t;
4560
4606
  }
4561
- async function cs(e, t, n = J) {
4607
+ async function ms(e, t, n = J) {
4562
4608
  let r = [];
4563
4609
  for (let i of e) {
4564
4610
  let e = T.join(t, i.relativeDir);
@@ -4594,14 +4640,14 @@ async function cs(e, t, n = J) {
4594
4640
  function $(e) {
4595
4641
  return e instanceof Error ? e.message : String(e);
4596
4642
  }
4597
- async function ls(e, t, n) {
4643
+ async function hs(e, t, n) {
4598
4644
  let r = e.filter((e) => e.tier === "paid" && !t.has(e.name)).map((e) => e.name);
4599
4645
  return r.length === 0 ? {} : Yr(r, n).catch(() => ({}));
4600
4646
  }
4601
- function us(e, t) {
4647
+ function gs(e, t) {
4602
4648
  return e === "free" ? R.success("free") : e === "owned" ? R.accent("owned") : `${R.highlight(`$${t}`)} ${R.muted("locked")}`;
4603
4649
  }
4604
- async function ds(e, t, n) {
4650
+ async function _s(e, t, n) {
4605
4651
  let r = e.filter((e) => t(e)), i = e.filter((e) => !t(e));
4606
4652
  i.length > 0 && s.log.warning(`Skipping ${i.join(", ")} because ${i.length === 1 ? "it depends" : "they depend"} on a pack you don't own yet.`), await sr(r.map((e) => n.get(e)).filter((e) => e !== void 0).map((e) => ({
4607
4653
  name: e.name,
@@ -4609,7 +4655,7 @@ async function ds(e, t, n) {
4609
4655
  price: e.price
4610
4656
  })));
4611
4657
  }
4612
- function fs(e, t) {
4658
+ function vs(e, t) {
4613
4659
  B([
4614
4660
  "These packs will be installed, in order:",
4615
4661
  "",
@@ -4619,7 +4665,7 @@ function fs(e, t) {
4619
4665
  })
4620
4666
  ].join("\n"), "Install Plan");
4621
4667
  }
4622
- async function ps(e, t) {
4668
+ async function ys(e, t) {
4623
4669
  let n = [];
4624
4670
  for (let r of e) {
4625
4671
  let e = await Ur(r), i = await Wr(r, t);
@@ -4631,18 +4677,18 @@ async function ps(e, t) {
4631
4677
  }
4632
4678
  return n;
4633
4679
  }
4634
- async function ms(e) {
4635
- let { prepared: t, paths: n, cwd: r, spinner: i } = e, a = os(ss(t.map((e) => e.manifest.dependencies_npm)), n);
4680
+ async function bs(e) {
4681
+ let { prepared: t, paths: n, cwd: r, spinner: i } = e, a = fs(ps(t.map((e) => e.manifest.dependencies_npm)), n);
4636
4682
  if (a.errors.length > 0) {
4637
4683
  for (let e of a.errors) s.log.error(e);
4638
4684
  return;
4639
4685
  }
4640
4686
  if (a.operations.length === 0) return;
4641
4687
  i.start("Installing npm dependencies...");
4642
- let o = await cs(a.operations, r);
4688
+ let o = await ms(a.operations, r);
4643
4689
  if (i.stop(o.ok ? "npm dependencies installed" : "npm dependency installation failed"), !o.ok) for (let e of o.errors) s.log.error(e);
4644
4690
  }
4645
- function hs() {
4691
+ function xs() {
4646
4692
  we([{
4647
4693
  command: "npx @hype-stack/cli onboard",
4648
4694
  hint: "(set up env vars + run migrations)"
@@ -4651,7 +4697,7 @@ function hs() {
4651
4697
  hint: "(start frontend + backend)"
4652
4698
  }]);
4653
4699
  }
4654
- function gs(e) {
4700
+ function Ss(e) {
4655
4701
  if (e.length === 0) return;
4656
4702
  let t = e.map((e) => {
4657
4703
  let t = e.replace(/^\{\{[^}]+\}\}\//, "");
@@ -4659,10 +4705,10 @@ function gs(e) {
4659
4705
  });
4660
4706
  s.note(t.join("\n"), "Skipped (already exist)");
4661
4707
  }
4662
- async function _s(e) {
4708
+ async function Cs(e) {
4663
4709
  let { prepared: t, config: n, cwd: r, force: i, yes: a, slotsByPack: o } = e, c = /* @__PURE__ */ new Set();
4664
4710
  if (i) return c;
4665
- let l = await ha({
4711
+ let l = await xa({
4666
4712
  packs: t,
4667
4713
  config: n,
4668
4714
  projectRoot: r,
@@ -4689,7 +4735,7 @@ async function _s(e) {
4689
4735
  }
4690
4736
  //#endregion
4691
4737
  //#region src/ui/swatch.ts
4692
- function vs(e) {
4738
+ function ws(e) {
4693
4739
  let t = e.trim().match(/^oklch\(([^)]+)\)$/i);
4694
4740
  if (!t) return null;
4695
4741
  let n = t[1].trim().split(/\s+/);
@@ -4708,54 +4754,54 @@ function vs(e) {
4708
4754
  h: a
4709
4755
  };
4710
4756
  }
4711
- function ys(e) {
4757
+ function Ts(e) {
4712
4758
  return Math.min(255, Math.max(0, Math.round(e)));
4713
4759
  }
4714
- function bs(e) {
4760
+ function Es(e) {
4715
4761
  return e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055;
4716
4762
  }
4717
- function xs({ l: e, c: t, h: n }) {
4763
+ function Ds({ l: e, c: t, h: n }) {
4718
4764
  let r = n * Math.PI / 180, i = t * Math.cos(r), a = t * Math.sin(r), o = e + .3963377774 * i + .2158037573 * a, s = e - .1055613458 * i - .0638541728 * a, c = e - .0894841775 * i - 1.291485548 * a, l = o ** 3, u = s ** 3, d = c ** 3, f = 4.0767416621 * l - 3.3077115913 * u + .2309699292 * d, p = -1.2684380042 * l + 2.6097570613 * u - .3413193965 * d, m = -.0041960863 * l - .7034186147 * u + 1.7076146937 * d;
4719
4765
  return [
4720
- ys(bs(f) * 255),
4721
- ys(bs(p) * 255),
4722
- ys(bs(m) * 255)
4766
+ Ts(Es(f) * 255),
4767
+ Ts(Es(p) * 255),
4768
+ Ts(Es(m) * 255)
4723
4769
  ];
4724
4770
  }
4725
- var Ss = "\x1B[49m";
4726
- function Cs(e, t) {
4771
+ var Os = "\x1B[49m";
4772
+ function ks(e, t) {
4727
4773
  let n = e[t];
4728
4774
  if (!n) return b.dim(" ");
4729
- let r = vs(n);
4775
+ let r = ws(n);
4730
4776
  if (!r) return b.dim(" ");
4731
- let [i, a, o] = xs(r);
4732
- return `\x1b[48;2;${i};${a};${o}m ${Ss}`;
4777
+ let [i, a, o] = Ds(r);
4778
+ return `\x1b[48;2;${i};${a};${o}m ${Os}`;
4733
4779
  }
4734
- var ws = [
4780
+ var As = [
4735
4781
  "primary",
4736
4782
  "secondary",
4737
4783
  "accent"
4738
4784
  ];
4739
- function Ts(e) {
4740
- return ws.map((t) => Cs(e, t)).join("");
4785
+ function js(e) {
4786
+ return As.map((t) => ks(e, t)).join("");
4741
4787
  }
4742
- function Es(e) {
4743
- return `${Ts(e.light)} ${b.dim("·")} ${Ts(e.dark)}`;
4788
+ function Ms(e) {
4789
+ return `${js(e.light)} ${b.dim("·")} ${js(e.dark)}`;
4744
4790
  }
4745
4791
  //#endregion
4746
4792
  //#region src/commands/create.ts
4747
- async function Ds(e) {
4748
- e.skipBanner || co(), s.intro(R.brandBold("Create a new Hype Stack project"));
4793
+ async function Ns(e) {
4794
+ e.skipBanner || ho(), s.intro(R.brandBold("Create a new Hype Stack project"));
4749
4795
  let o = e.yes === !0, c, l;
4750
4796
  if (o && e.name) {
4751
- let t = po(e.name);
4797
+ let t = yo(e.name);
4752
4798
  t && (s.log.error(t), V()), l = e.name, c = Sr(e.name);
4753
4799
  } else {
4754
4800
  let t = await s.text({
4755
4801
  message: "What is your project named?",
4756
4802
  placeholder: "my-app",
4757
4803
  initialValue: e.name ?? "",
4758
- validate: (e) => po(e ?? "")
4804
+ validate: (e) => yo(e ?? "")
4759
4805
  });
4760
4806
  s.isCancel(t) && V(), l = t, c = Sr(l);
4761
4807
  }
@@ -4801,7 +4847,7 @@ async function Ds(e) {
4801
4847
  message: "Pick a color theme",
4802
4848
  options: r.map((e) => ({
4803
4849
  value: e.name,
4804
- label: `${Es(e)} ${e.label}`
4850
+ label: `${Ms(e)} ${e.label}`
4805
4851
  })),
4806
4852
  initialValue: h
4807
4853
  });
@@ -4819,24 +4865,24 @@ async function Ds(e) {
4819
4865
  (s.isCancel(e) || !e) && V();
4820
4866
  }
4821
4867
  let _ = s.spinner();
4822
- _.start("Cloning Hype Stack template..."), await ko(d), _.stop(R.success("Template cloned"));
4868
+ _.start("Cloning Hype Stack template..."), await Fo(d), _.stop(R.success("Template cloned"));
4823
4869
  let v = s.spinner();
4824
- v.start("Setting up project..."), await Ho(d), await Wo(d, c), await Io(d, p);
4870
+ v.start("Setting up project..."), await Jo(d), await Xo(d, c), await Ho(d, p);
4825
4871
  let y = await zr(d), b = Vr(c, y);
4826
- await Rr(d, b), await is(d, {
4872
+ await Rr(d, b), await us(d, {
4827
4873
  projectName: c,
4828
4874
  editor: p,
4829
4875
  workspace: y
4830
4876
  });
4831
4877
  let x = T.resolve(d, b.paths?.frontend.root ?? "apps/frontend");
4832
- a(g) && (await Oo(x, i(g)) || s.log.warn(R.muted(`Could not find ${R.path("assets/styles.css")} to apply the ${g} theme`))), e.radius !== void 0 && yo(e.radius) && (await So(x, e.radius) || s.log.warn(R.muted(`Could not find ${R.path("assets/styles.css")} to set the corner radius`))), await _o(x, e.defaultMode === "dark" || e.defaultMode === "light" ? e.defaultMode : "light") || s.log.warn(R.muted(`Could not find ${R.path("src/hooks/use-theme.ts")} to set the default color mode`)), v.stop(R.success("Project configured"));
4878
+ a(g) && (await Po(x, i(g)) || s.log.warn(R.muted(`Could not find ${R.path("assets/styles.css")} to apply the ${g} theme`))), e.radius !== void 0 && To(e.radius) && (await Oo(x, e.radius) || s.log.warn(R.muted(`Could not find ${R.path("assets/styles.css")} to set the corner radius`))), await Co(x, e.defaultMode === "dark" || e.defaultMode === "light" ? e.defaultMode : "light") || s.log.warn(R.muted(`Could not find ${R.path("src/hooks/use-theme.ts")} to set the default color mode`)), v.stop(R.success("Project configured"));
4833
4879
  let S = s.spinner();
4834
4880
  S.start("Installing dependencies..."), (await J("pnpm", ["install"], { cwd: d })).exitCode === 0 ? S.stop(R.success("Dependencies installed")) : (S.stop(R.warning("Dependencies installed with warnings")), s.log.warn(R.muted("You may need to run `pnpm install` manually to resolve issues.")));
4835
4881
  let C = s.spinner();
4836
- C.start("Initializing git repository..."), await Uo(d), C.stop(R.success("Git repository initialized with clean history"));
4882
+ C.start("Initializing git repository..."), await Yo(d), C.stop(R.success("Git repository initialized with clean history"));
4837
4883
  let w = s.spinner();
4838
4884
  w.start("Creating .env files from examples...");
4839
- let E = await Ro(d);
4885
+ let E = await Wo(d);
4840
4886
  if (E.length > 0) {
4841
4887
  let e = E.length;
4842
4888
  w.stop(R.success(`Created ${e} .env file${e === 1 ? "" : "s"} from examples`));
@@ -4851,15 +4897,15 @@ async function Ds(e) {
4851
4897
  message: "Would you like to start Docker services and run database migrations now?",
4852
4898
  initialValue: !0
4853
4899
  }));
4854
- s.isCancel(e) && V(), e ? await Ua(d, o) : s.log.info(R.muted("Docker and migrations can run later via `npx @hype-stack/cli onboard`.")), hs();
4900
+ s.isCancel(e) && V(), e ? await Ya(d, o) : s.log.info(R.muted("Docker and migrations can run later via `npx @hype-stack/cli onboard`.")), xs();
4855
4901
  }
4856
- return await as("project_create"), s.outro(R.muted("Happy building!")), d;
4902
+ return await ds("project_create"), s.outro(R.muted("Happy building!")), d;
4857
4903
  }
4858
4904
  //#endregion
4859
4905
  //#region src/commands/init.ts
4860
- async function Os(e) {
4906
+ async function Ps(e) {
4861
4907
  let t = e.cwd ?? process.cwd(), n = e.silent ?? !1;
4862
- if (n || (lo(), s.intro(R.brandBold("Initialize Hype Stack configuration"))), !await Hr(t)) {
4908
+ if (n || (go(), s.intro(R.brandBold("Initialize Hype Stack configuration"))), !await Hr(t)) {
4863
4909
  s.log.error(`This doesn't look like a Hype Stack project. ${R.muted("Expected apps/ directory and package.json")}`), s.outro(R.muted(`Run ${R.command("npx @hype-stack/cli create")} to scaffold a new project.`));
4864
4910
  return;
4865
4911
  }
@@ -4896,21 +4942,21 @@ async function Os(e) {
4896
4942
  message: "Project name for stack.json?",
4897
4943
  placeholder: i,
4898
4944
  initialValue: i,
4899
- validate: (e) => po(e ?? "")
4945
+ validate: (e) => yo(e ?? "")
4900
4946
  });
4901
4947
  s.isCancel(e) && V(), a = Sr(e);
4902
4948
  }
4903
4949
  await Rr(t, Vr(a, r)), n || (s.log.success(`${R.path("stack.json")} written successfully`), s.outro(R.muted("Your project is mapped and ready for Hype Stack CLI commands.")));
4904
4950
  }
4905
- async function ks(e, t = {}, n) {
4951
+ async function Fs(e, t = {}, n) {
4906
4952
  if (await Lr(e)) return {
4907
4953
  projectRoot: e,
4908
4954
  scaffolded: !1
4909
4955
  };
4910
- let r = t.runInit ?? ((e) => Os({
4956
+ let r = t.runInit ?? ((e) => Ps({
4911
4957
  cwd: e,
4912
4958
  silent: !0
4913
- })), i = t.runCreate ?? ((e, t) => Ds({
4959
+ })), i = t.runCreate ?? ((e, t) => Ns({
4914
4960
  parentDirectory: e,
4915
4961
  deferSetup: !0,
4916
4962
  skipBanner: !0,
@@ -4951,10 +4997,10 @@ async function ks(e, t = {}, n) {
4951
4997
  }
4952
4998
  //#endregion
4953
4999
  //#region src/commands/compose.ts
4954
- async function As(e = {}) {
5000
+ async function Is(e = {}) {
4955
5001
  let t = e.cwd ?? process.cwd();
4956
- co();
4957
- let n = await ks(t), r = n?.projectRoot ?? null, i = n?.scaffolded ?? !1, a;
5002
+ ho();
5003
+ let n = await Fs(t), r = n?.projectRoot ?? null, i = n?.scaffolded ?? !1, a;
4958
5004
  try {
4959
5005
  a = await Ir(r ?? t);
4960
5006
  } catch (e) {
@@ -4972,13 +5018,13 @@ async function As(e = {}) {
4972
5018
  c.stop("Failed to load packs"), s.cancel(`Could not reach Hype Stack. Check your connection and try again.\n${$(e)}`), process.exit(1);
4973
5019
  }
4974
5020
  c.stop("Packs loaded");
4975
- let u = a.installedPacks ?? [], d = new Set(u), f = new Map(l.map((e) => [e.name, e])), p = e.licenseKey ?? a.licenseKey ?? null, m = (await Xn(L()))?.token ?? null, h = await ls(l, d, {
5021
+ let u = a.installedPacks ?? [], d = new Set(u), f = new Map(l.map((e) => [e.name, e])), p = e.licenseKey ?? a.licenseKey ?? null, m = (await Xn(L()))?.token ?? null, h = await hs(l, d, {
4976
5022
  token: m,
4977
5023
  key: p
4978
5024
  }), g = (e) => {
4979
5025
  let t = f.get(e);
4980
5026
  return !t || t.tier === "free" ? "free" : h[e]?.owned ? "owned" : "locked";
4981
- }, _ = (e) => !d.has(e) && g(e) === "locked", v = await js({
5027
+ }, _ = (e) => !d.has(e) && g(e) === "locked", v = await Ls({
4982
5028
  packs: l,
4983
5029
  installedSet: d,
4984
5030
  stateOf: g,
@@ -4989,9 +5035,9 @@ async function As(e = {}) {
4989
5035
  s.outro(R.muted("No packs selected. Nothing to do."));
4990
5036
  return;
4991
5037
  }
4992
- let b = Ps(v), x = Fs(v), S = Qa(l, b), C = Ga($a(l, S)), w;
5038
+ let b = Vs(v), x = Hs(v), S = io(l, b), C = Za(ao(l, S)), w;
4993
5039
  try {
4994
- w = qa(b, C, u);
5040
+ w = $a(b, C, u);
4995
5041
  } catch (e) {
4996
5042
  s.cancel($(e)), process.exit(1);
4997
5043
  }
@@ -4999,7 +5045,7 @@ async function As(e = {}) {
4999
5045
  B(`${w.alreadyInstalled.join(", ")} already installed.`, "Nothing to do"), s.outro(R.muted("Your selection is already part of the project."));
5000
5046
  return;
5001
5047
  }
5002
- let T = Ja({
5048
+ let T = eo({
5003
5049
  order: w.order,
5004
5050
  graph: C,
5005
5051
  isLocked: _,
@@ -5007,28 +5053,28 @@ async function As(e = {}) {
5007
5053
  });
5008
5054
  if (T.blocked.length > 0 && !m && !p) {
5009
5055
  let e = await or();
5010
- e && (m = e, h = await ls(l, d, {
5056
+ e && (m = e, h = await hs(l, d, {
5011
5057
  token: m,
5012
5058
  key: p
5013
- }), T = Ja({
5059
+ }), T = eo({
5014
5060
  order: w.order,
5015
5061
  graph: C,
5016
5062
  isLocked: _,
5017
5063
  installed: u
5018
5064
  }));
5019
5065
  }
5020
- if (T.blocked.length > 0 && await ds(T.blocked, _, f), T.installable.length === 0) {
5066
+ if (T.blocked.length > 0 && await _s(T.blocked, _, f), T.installable.length === 0) {
5021
5067
  s.outro(R.muted("Nothing left to install once locked packs are removed."));
5022
5068
  return;
5023
5069
  }
5024
- if (fs(T.installable, f), !e.yes) {
5070
+ if (vs(T.installable, f), !e.yes) {
5025
5071
  let e = await s.confirm({ message: `Install ${T.installable.length} pack${T.installable.length === 1 ? "" : "s"}?` });
5026
5072
  (s.isCancel(e) || !e) && (s.cancel("Installation cancelled."), process.exit(0));
5027
5073
  }
5028
5074
  c.start("Downloading packs...");
5029
5075
  let E;
5030
5076
  try {
5031
- E = await ps(T.installable, {
5077
+ E = await ys(T.installable, {
5032
5078
  token: m,
5033
5079
  key: p
5034
5080
  });
@@ -5036,7 +5082,7 @@ async function As(e = {}) {
5036
5082
  c.stop("Download failed"), s.cancel($(e)), process.exit(1);
5037
5083
  }
5038
5084
  c.stop(`Downloaded ${E.length} pack${E.length === 1 ? "" : "s"}`);
5039
- let D = await _s({
5085
+ let D = await Cs({
5040
5086
  prepared: E,
5041
5087
  config: a,
5042
5088
  cwd: o,
@@ -5046,7 +5092,7 @@ async function As(e = {}) {
5046
5092
  });
5047
5093
  try {
5048
5094
  c.start("Installing pack files...");
5049
- let t = await va({
5095
+ let t = await wa({
5050
5096
  packs: E,
5051
5097
  config: a,
5052
5098
  projectRoot: o,
@@ -5059,22 +5105,22 @@ async function As(e = {}) {
5059
5105
  for (let e of t.errors) s.log.error(e);
5060
5106
  s.cancel("No files were written. Fix the errors above (or pass --force for existing files) and try again."), process.exit(1);
5061
5107
  }
5062
- c.stop("Files installed"), t.installed.length > 0 && s.log.success(`${R.highlight(String(t.installed.length))} files installed`), t.skipped.length > 0 && (s.log.warning(`${t.skipped.length} files skipped (use --force to overwrite)`), gs(t.skipped));
5108
+ c.stop("Files installed"), t.installed.length > 0 && s.log.success(`${R.highlight(String(t.installed.length))} files installed`), t.skipped.length > 0 && (s.log.warning(`${t.skipped.length} files skipped (use --force to overwrite)`), Ss(t.skipped));
5063
5109
  for (let e of t.errors) s.log.error(e);
5064
- await oa(o, a.name), await ms({
5110
+ await fa(o, a.name), await bs({
5065
5111
  prepared: E,
5066
5112
  paths: a.paths,
5067
5113
  cwd: o,
5068
5114
  spinner: c
5069
5115
  });
5070
5116
  let n;
5071
- i && (n = await Wa(o, e.yes ?? !1)), await br({
5117
+ i && (n = await Xa(o, e.yes ?? !1)), await br({
5072
5118
  projectRoot: o,
5073
5119
  paths: a.paths,
5074
5120
  skipPrompts: e.yes ?? !1,
5075
5121
  dbReady: n,
5076
5122
  freshScaffold: i
5077
- }), hs(), s.outro(R.brand(`Installed ${t.appliedPacks.join(", ")}.`));
5123
+ }), xs(), s.outro(R.brand(`Installed ${t.appliedPacks.join(", ")}.`));
5078
5124
  } finally {
5079
5125
  await Promise.all(E.map((e) => y.rm(e.packDir, {
5080
5126
  recursive: !0,
@@ -5082,11 +5128,17 @@ async function As(e = {}) {
5082
5128
  })));
5083
5129
  }
5084
5130
  }
5085
- async function js(e) {
5131
+ async function Ls(e) {
5086
5132
  let { packs: t, installedSet: n, stateOf: r, options: i, adminAvailable: a } = e;
5087
5133
  if (i.packs && i.packs.length > 0) {
5088
- let e = i.packs.map(Ns), n = e.filter((e) => !t.some((t) => t.name === e.name));
5089
- return n.length > 0 && (s.cancel(`Unknown pack${n.length === 1 ? "" : "s"}: ${n.map((e) => e.name).join(", ")}`), process.exit(1)), e;
5134
+ let e = i.packs.map(Bs), n = e.filter((e) => !t.some((t) => t.name === e.name));
5135
+ n.length > 0 && (s.cancel(`Unknown pack${n.length === 1 ? "" : "s"}: ${n.map((e) => e.name).join(", ")}`), process.exit(1));
5136
+ let r = Rs(e, t);
5137
+ if (r.length > 0) {
5138
+ let e = t.filter((e) => e.category === "layout" && e.adminCompatible).map((e) => e.name), n = e.length > 0 ? ` Admin supports: ${e.join(", ")}.` : " No layout supports the admin app yet.";
5139
+ s.cancel(`Layout${r.length === 1 ? "" : "s"} not compatible with the admin app: ${r.join(", ")}.${n}`), process.exit(1);
5140
+ }
5141
+ return e;
5090
5142
  }
5091
5143
  let o = t.filter((e) => n.has(e.name));
5092
5144
  o.length > 0 && B(o.map((e) => ` ${R.success("✓")} ${e.displayName}`).join("\n"), "Already Installed");
@@ -5094,13 +5146,13 @@ async function js(e) {
5094
5146
  if (c.length === 0) return s.outro(R.muted("Every available pack is already installed.")), [];
5095
5147
  let l = se();
5096
5148
  B(c.map((e) => ` ${z.arrow} ${R.highlight(e.displayName)} ${_e(`${l}/packs/${e.name}`)}`).join("\n"), "Browse packs");
5097
- let u = Ea(c, { adminAvailable: a }), d = [];
5149
+ let u = Ma(c, { adminAvailable: a }), d = [];
5098
5150
  for (let e of u) {
5099
5151
  let t = e.packs.map((e) => {
5100
5152
  let t = r(e.name);
5101
5153
  return {
5102
5154
  value: e.name,
5103
- label: `${e.displayName} ${us(t, e.price)}`,
5155
+ label: `${e.displayName} ${gs(t, e.price)}`,
5104
5156
  hint: e.description
5105
5157
  };
5106
5158
  });
@@ -5117,7 +5169,7 @@ async function js(e) {
5117
5169
  });
5118
5170
  continue;
5119
5171
  }
5120
- let n = await fo({
5172
+ let n = await vo({
5121
5173
  message: `Select ${e.label.toLowerCase()} to add (optional)`,
5122
5174
  options: t,
5123
5175
  required: !1
@@ -5127,20 +5179,29 @@ async function js(e) {
5127
5179
  }
5128
5180
  return d;
5129
5181
  }
5130
- var Ms = /@(frontend|admin)$/;
5131
- function Ns(e) {
5132
- let t = e.match(Ms);
5182
+ function Rs(e, t) {
5183
+ let n = [];
5184
+ for (let r of e) {
5185
+ if (r.slot !== "admin") continue;
5186
+ let e = t.find((e) => e.name === r.name);
5187
+ e?.category === "layout" && !e.adminCompatible && n.push(r.name);
5188
+ }
5189
+ return n;
5190
+ }
5191
+ var zs = /@(frontend|admin)$/;
5192
+ function Bs(e) {
5193
+ let t = e.match(zs);
5133
5194
  return t ? {
5134
5195
  name: e.slice(0, -t[0].length),
5135
5196
  slot: t[1]
5136
5197
  } : { name: e };
5137
5198
  }
5138
- function Ps(e) {
5199
+ function Vs(e) {
5139
5200
  let t = /* @__PURE__ */ new Set(), n = [];
5140
5201
  for (let r of e) t.has(r.name) || (t.add(r.name), n.push(r.name));
5141
5202
  return n;
5142
5203
  }
5143
- function Fs(e) {
5204
+ function Hs(e) {
5144
5205
  let t = /* @__PURE__ */ new Map();
5145
5206
  for (let n of e) {
5146
5207
  if (!n.slot) continue;
@@ -5151,8 +5212,8 @@ function Fs(e) {
5151
5212
  }
5152
5213
  //#endregion
5153
5214
  //#region src/commands/login.ts
5154
- async function Is() {
5155
- lo(), s.intro(R.brandBold("Log in to Hype Stack")), s.log.step("Opening your browser to sign in...");
5215
+ async function Us() {
5216
+ go(), s.intro(R.brandBold("Log in to Hype Stack")), s.log.step("Opening your browser to sign in...");
5156
5217
  let e;
5157
5218
  try {
5158
5219
  e = await ar({ onUrl: (e) => {
@@ -5165,8 +5226,8 @@ async function Is() {
5165
5226
  }
5166
5227
  //#endregion
5167
5228
  //#region src/commands/logout.ts
5168
- async function Ls() {
5169
- lo(), s.intro(R.brandBold("Log out of Hype Stack"));
5229
+ async function Ws() {
5230
+ go(), s.intro(R.brandBold("Log out of Hype Stack"));
5170
5231
  let e = L(), t = await Xn(e);
5171
5232
  if (!t) {
5172
5233
  s.outro(R.muted("You're not logged in."));
@@ -5176,7 +5237,7 @@ async function Ls() {
5176
5237
  }
5177
5238
  //#endregion
5178
5239
  //#region src/core/onboard-env.ts
5179
- function Rs(e) {
5240
+ function Gs(e) {
5180
5241
  let t = [], n = "";
5181
5242
  for (let r of e.split(/\r?\n/)) {
5182
5243
  let e = r.trim();
@@ -5202,14 +5263,14 @@ function Rs(e) {
5202
5263
  }
5203
5264
  return t;
5204
5265
  }
5205
- function zs(e) {
5266
+ function Ks(e) {
5206
5267
  let t = e.trim();
5207
5268
  if (t === "") return "";
5208
5269
  if (t.length <= 4) return "•".repeat(t.length);
5209
5270
  let n = Math.min(t.length - 4, 8);
5210
5271
  return `${"•".repeat(n)}${t.slice(-4)}`;
5211
5272
  }
5212
- function Bs(e, t, n) {
5273
+ function qs(e, t, n) {
5213
5274
  let r = e.split(/\r?\n/), i = !1, a = r.map((e) => {
5214
5275
  if (i) return e;
5215
5276
  let r = e.trim();
@@ -5219,22 +5280,22 @@ function Bs(e, t, n) {
5219
5280
  });
5220
5281
  return i ? a.join("\n") : e + `${e.length > 0 && !e.endsWith("\n") ? "\n" : ""}${t}=${n}\n`;
5221
5282
  }
5222
- async function Vs(e) {
5283
+ async function Js(e) {
5223
5284
  return await Y(e) ? y.readFile(e, "utf-8") : "";
5224
5285
  }
5225
- async function Hs(e) {
5286
+ async function Ys(e) {
5226
5287
  let t = T.join(T.dirname(e), ".env");
5227
5288
  return await Y(t) || await y.copyFile(e, t), t;
5228
5289
  }
5229
- async function Us(e, t, n) {
5230
- let r = Bs(await Vs(e), t, n);
5290
+ async function Xs(e, t, n) {
5291
+ let r = qs(await Js(e), t, n);
5231
5292
  await y.writeFile(e, r, "utf-8");
5232
5293
  }
5233
5294
  //#endregion
5234
5295
  //#region src/commands/onboard.ts
5235
- async function Ws(e = {}) {
5296
+ async function Zs(e = {}) {
5236
5297
  let t = e.cwd ?? process.cwd();
5237
- co(), s.intro(R.brandBold("Onboard your stack"));
5298
+ ho(), s.intro(R.brandBold("Onboard your stack"));
5238
5299
  let n;
5239
5300
  try {
5240
5301
  n = await Ir(t);
@@ -5242,19 +5303,19 @@ async function Ws(e = {}) {
5242
5303
  n = null;
5243
5304
  }
5244
5305
  n || (s.cancel(`${R.path("stack.json")} not found. Run ${R.command("npx @hype-stack/cli init")} first.`), process.exit(1));
5245
- let r = n.installedPacks ?? [], i = n.onboarding?.envSections ?? [], a = await zo(t);
5306
+ let r = n.installedPacks ?? [], i = n.onboarding?.envSections ?? [], a = await Go(t);
5246
5307
  a.length === 0 && s.log.warn(R.muted("No .env.example files found; skipping env setup."));
5247
- for (let n of a) await Gs({
5308
+ for (let n of a) await Qs({
5248
5309
  examplePath: n,
5249
5310
  projectRoot: t,
5250
5311
  skipPrompts: e.yes ?? !1,
5251
5312
  installedEnvSections: i
5252
5313
  });
5253
5314
  let o = Fr(r);
5254
- o.length > 0 && B(o.map((e) => ` ${R.muted("·")} ${e}`).join("\n"), "Tips"), e.skipMigrations || await Js(t, e.yes ?? !1), s.outro(R.brand(`All set. Run ${R.command("pnpm dev")} to start your app.`));
5315
+ o.length > 0 && B(o.map((e) => ` ${R.muted("·")} ${e}`).join("\n"), "Tips"), e.skipMigrations || await tc(t, e.yes ?? !1), s.outro(R.brand(`All set. Run ${R.command("pnpm dev")} to start your app.`));
5255
5316
  }
5256
- async function Gs(e) {
5257
- let { examplePath: t, projectRoot: n, skipPrompts: r, installedEnvSections: i } = e, a = T.relative(n, t) || t, o = await Hs(t), c = await Vs(o), l = Rs(await y.readFile(t, "utf-8")), u = R.path(a);
5317
+ async function Qs(e) {
5318
+ let { examplePath: t, projectRoot: n, skipPrompts: r, installedEnvSections: i } = e, a = T.relative(n, t) || t, o = await Ys(t), c = await Js(o), l = Gs(await y.readFile(t, "utf-8")), u = R.path(a);
5258
5319
  s.log.step(`Env: ${u}`);
5259
5320
  for (let e of l) {
5260
5321
  if (e.vars.length === 0) continue;
@@ -5270,7 +5331,7 @@ async function Gs(e) {
5270
5331
  s.log.info(`${R.label(n.key)} ${R.muted("skipped (non-interactive)")}`);
5271
5332
  continue;
5272
5333
  }
5273
- let e = zs(Ks(c, n.key)), i = await s.text({
5334
+ let e = Ks($s(c, n.key)), i = await s.text({
5274
5335
  message: `${R.label(n.key)}`,
5275
5336
  placeholder: e ? `${e} ${R.muted("(Enter keeps this)")}` : t.hint
5276
5337
  });
@@ -5280,31 +5341,31 @@ async function Gs(e) {
5280
5341
  s.log.info(R.muted(`${n.key} unchanged.`));
5281
5342
  continue;
5282
5343
  }
5283
- await Us(o, n.key, a), s.log.success(`${n.key} saved`);
5344
+ await Xs(o, n.key, a), s.log.success(`${n.key} saved`);
5284
5345
  }
5285
5346
  }
5286
5347
  }
5287
- function Ks(e, t) {
5348
+ function $s(e, t) {
5288
5349
  for (let n of e.split(/\r?\n/)) {
5289
- let e = n.match(RegExp(`^${qs(t)}\\s*=\\s*(.*)$`));
5350
+ let e = n.match(RegExp(`^${ec(t)}\\s*=\\s*(.*)$`));
5290
5351
  if (e) return e[1].trim();
5291
5352
  }
5292
5353
  return "";
5293
5354
  }
5294
- function qs(e) {
5355
+ function ec(e) {
5295
5356
  return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5296
5357
  }
5297
- async function Js(e, t) {
5298
- if (!await ka() && !await ja(e, t, !1)) {
5358
+ async function tc(e, t) {
5359
+ if (!await Fa() && !await La(e, t, !1)) {
5299
5360
  s.log.info(R.muted(`Start services later with ${R.command("docker compose up -d")} (in apps/backend), then ${R.command("pnpm --filter @internal/backend migration:latest")}.`));
5300
5361
  return;
5301
5362
  }
5302
5363
  let n = s.spinner();
5303
- if (n.start("Waiting for Postgres to be ready..."), !await La(e)) {
5364
+ if (n.start("Waiting for Postgres to be ready..."), !await Ua(e)) {
5304
5365
  n.error("Postgres health check timed out"), s.log.warn(R.muted(`Run migrations manually once Postgres is ready: ${R.command("pnpm --filter @internal/backend migration:latest")}`));
5305
5366
  return;
5306
5367
  }
5307
- if (n.stop(R.success("Postgres is ready")), await za(e)) {
5368
+ if (n.stop(R.success("Postgres is ready")), await Ga(e)) {
5308
5369
  s.log.info(R.muted("Migrations already applied, skipping."));
5309
5370
  return;
5310
5371
  }
@@ -5316,20 +5377,20 @@ async function Js(e, t) {
5316
5377
  s.log.info(R.muted("Skipping database migrations."));
5317
5378
  return;
5318
5379
  }
5319
- await Ba(e);
5380
+ await Ka(e);
5320
5381
  }
5321
5382
  //#endregion
5322
5383
  //#region src/core/templates.ts
5323
- var Ys = q.createRequest()({
5384
+ var nc = q.createRequest()({
5324
5385
  endpoint: "/templates/list",
5325
5386
  method: "GET"
5326
5387
  });
5327
- async function Xs() {
5328
- let { data: e, error: t } = await Ys.send();
5388
+ async function rc() {
5389
+ let { data: e, error: t } = await nc.send();
5329
5390
  if (t || !e) throw Error(`Failed to fetch template list: ${String(t)}`);
5330
5391
  return e.templates;
5331
5392
  }
5332
- async function Zs(e) {
5393
+ async function ic(e) {
5333
5394
  let { data: t, error: n, status: r } = await q.createRequest()({
5334
5395
  endpoint: `/templates/${encodeURIComponent(e)}/manifest`,
5335
5396
  method: "GET"
@@ -5338,7 +5399,7 @@ async function Zs(e) {
5338
5399
  if (n || !t) throw Error(`Failed to load manifest for template "${e}": ${String(n)}`);
5339
5400
  return t;
5340
5401
  }
5341
- async function Qs(e, t = {}) {
5402
+ async function ac(e, t = {}) {
5342
5403
  let n = q.createRequest()({
5343
5404
  endpoint: `/templates/${encodeURIComponent(e)}/download`,
5344
5405
  method: "POST"
@@ -5366,9 +5427,9 @@ async function Qs(e, t = {}) {
5366
5427
  }
5367
5428
  //#endregion
5368
5429
  //#region src/commands/template.ts
5369
- async function $s(t = {}) {
5430
+ async function oc(t = {}) {
5370
5431
  let n = t.cwd ?? process.cwd();
5371
- co();
5432
+ ho();
5372
5433
  let r = s.spinner();
5373
5434
  r.start("Loading packs...");
5374
5435
  let o;
@@ -5380,7 +5441,7 @@ async function $s(t = {}) {
5380
5441
  r.stop("Packs loaded"), r.start("Loading templates...");
5381
5442
  let c;
5382
5443
  try {
5383
- c = await Xs();
5444
+ c = await rc();
5384
5445
  } catch (e) {
5385
5446
  r.stop("Failed to load templates"), s.cancel(`Could not reach Hype Stack. Check your connection and try again.\n${$(e)}`), process.exit(1);
5386
5447
  }
@@ -5403,11 +5464,11 @@ async function $s(t = {}) {
5403
5464
  u || (r.stop("Template not found"), s.cancel(`Template "${l}" not found. Available: ${c.map((e) => e.id).join(", ") || "(none)"}`), process.exit(1)), r.stop(`Template: ${u.name}`);
5404
5465
  let d;
5405
5466
  try {
5406
- d = await Zs(u.id);
5467
+ d = await ic(u.id);
5407
5468
  } catch (e) {
5408
5469
  s.cancel($(e)), process.exit(1);
5409
5470
  }
5410
- let f = await ks(n, {}, {
5471
+ let f = await Fs(n, {}, {
5411
5472
  defaultTheme: d.theme,
5412
5473
  defaultMode: d.defaultMode,
5413
5474
  radius: d.radius
@@ -5420,16 +5481,16 @@ async function $s(t = {}) {
5420
5481
  h || (s.cancel(p ? `Could not read ${R.path("stack.json")}. Run 'npx @hype-stack/cli init' to regenerate it, then run 'npx @hype-stack/cli template' again.` : `No ${R.path("stack.json")}. Run 'npx @hype-stack/cli init' first, then 'npx @hype-stack/cli template'.`), process.exit(1)), h.paths || (s.cancel(`${R.path("stack.json")} is missing ${R.path("paths")}. Run 'npx @hype-stack/cli init' again to regenerate it.`), process.exit(1));
5421
5482
  let g = p ?? n;
5422
5483
  s.intro(R.brandBold("Install a template"));
5423
- let _ = h.installedPacks ?? [], v = new Set(_), b = new Map(o.map((e) => [e.name, e])), x = t.licenseKey ?? h.licenseKey ?? null, S = (await Xn(L()))?.token ?? null, C = await ec(u, t.variants, t.yes ?? !1), w = Ya(u.slots, C), E = Xa(u.slots, u.packs, w), D = await tc({
5484
+ let _ = h.installedPacks ?? [], v = new Set(_), b = new Map(o.map((e) => [e.name, e])), x = t.licenseKey ?? h.licenseKey ?? null, S = (await Xn(L()))?.token ?? null, C = await sc(u, t.variants, t.yes ?? !1), w = to(u.slots, C), E = no(u.slots, u.packs, w), D = await cc({
5424
5485
  packs: o,
5425
5486
  templatePacks: E,
5426
5487
  installedSet: v,
5427
5488
  options: t
5428
5489
  }), O = [...E, ...D.filter((e) => !E.includes(e))], k = O.filter((e) => !b.has(e));
5429
5490
  k.length > 0 && (s.cancel(`Unknown pack${k.length === 1 ? "" : "s"}: ${k.join(", ")}`), process.exit(1));
5430
- let ee = $a(o, w), A = Ga(ee), j;
5491
+ let ee = ao(o, w), A = Za(ee), j;
5431
5492
  try {
5432
- j = qa(O, A, _);
5493
+ j = $a(O, A, _);
5433
5494
  } catch (e) {
5434
5495
  s.cancel($(e)), process.exit(1);
5435
5496
  }
@@ -5437,13 +5498,13 @@ async function $s(t = {}) {
5437
5498
  s.outro(R.muted("Every pack in this template is already installed."));
5438
5499
  return;
5439
5500
  }
5440
- let M = await ls(ee, v, {
5501
+ let M = await hs(ee, v, {
5441
5502
  token: S,
5442
5503
  key: x
5443
5504
  }), te = (e) => {
5444
5505
  let t = b.get(e);
5445
5506
  return !t || t.tier === "free" ? "free" : M[e]?.owned ? "owned" : "locked";
5446
- }, N = (e) => !v.has(e) && te(e) === "locked", P = Ja({
5507
+ }, N = (e) => !v.has(e) && te(e) === "locked", P = eo({
5447
5508
  order: j.order,
5448
5509
  graph: A,
5449
5510
  isLocked: N,
@@ -5451,28 +5512,28 @@ async function $s(t = {}) {
5451
5512
  });
5452
5513
  if (P.blocked.length > 0 && !S && !x) {
5453
5514
  let e = await or();
5454
- e && (S = e, M = await ls(ee, v, {
5515
+ e && (S = e, M = await hs(ee, v, {
5455
5516
  token: S,
5456
5517
  key: x
5457
- }), P = Ja({
5518
+ }), P = eo({
5458
5519
  order: j.order,
5459
5520
  graph: A,
5460
5521
  isLocked: N,
5461
5522
  installed: _
5462
5523
  }));
5463
5524
  }
5464
- if (P.blocked.length > 0 && await ds(P.blocked, N, b), P.installable.length === 0) {
5525
+ if (P.blocked.length > 0 && await _s(P.blocked, N, b), P.installable.length === 0) {
5465
5526
  s.outro(R.muted("Nothing left to install once locked packs are removed."));
5466
5527
  return;
5467
5528
  }
5468
- if (fs(P.installable, b), !t.yes) {
5529
+ if (vs(P.installable, b), !t.yes) {
5469
5530
  let e = await s.confirm({ message: `Install template ${R.brandBold(u.name)} (${P.installable.length} pack${P.installable.length === 1 ? "" : "s"})?` });
5470
5531
  (s.isCancel(e) || !e) && (s.cancel("Installation cancelled."), process.exit(0));
5471
5532
  }
5472
5533
  r.start("Downloading packs...");
5473
5534
  let F;
5474
5535
  try {
5475
- F = await ps(P.installable, {
5536
+ F = await ys(P.installable, {
5476
5537
  token: S,
5477
5538
  key: x
5478
5539
  });
@@ -5480,7 +5541,7 @@ async function $s(t = {}) {
5480
5541
  r.stop("Download failed"), s.cancel($(e)), process.exit(1);
5481
5542
  }
5482
5543
  r.stop(`Downloaded ${F.length} pack${F.length === 1 ? "" : "s"}`);
5483
- let ne = await _s({
5544
+ let ne = await Cs({
5484
5545
  prepared: F,
5485
5546
  config: h,
5486
5547
  cwd: g,
@@ -5489,7 +5550,7 @@ async function $s(t = {}) {
5489
5550
  }), I = null;
5490
5551
  try {
5491
5552
  r.start("Installing pack files...");
5492
- let n = await va({
5553
+ let n = await wa({
5493
5554
  packs: F,
5494
5555
  config: h,
5495
5556
  projectRoot: g,
@@ -5501,15 +5562,15 @@ async function $s(t = {}) {
5501
5562
  for (let e of n.errors) s.log.error(e);
5502
5563
  s.cancel("No files were written. Fix the errors above (or pass --force for existing files) and try again."), process.exit(1);
5503
5564
  }
5504
- r.stop("Files installed"), n.installed.length > 0 && s.log.success(`${R.highlight(String(n.installed.length))} files installed`), n.skipped.length > 0 && (s.log.warning(`${n.skipped.length} files skipped (use --force to overwrite)`), gs(n.skipped));
5565
+ r.stop("Files installed"), n.installed.length > 0 && s.log.success(`${R.highlight(String(n.installed.length))} files installed`), n.skipped.length > 0 && (s.log.warning(`${n.skipped.length} files skipped (use --force to overwrite)`), Ss(n.skipped));
5505
5566
  for (let e of n.errors) s.log.error(e);
5506
5567
  r.start("Applying template overrides...");
5507
- let o = await Qs(u.id, {
5568
+ let o = await ac(u.id, {
5508
5569
  token: S,
5509
5570
  licenseKey: x
5510
5571
  });
5511
5572
  o.status === "denied" && (r.stop("Template download denied"), s.cancel(`Access to template "${u.id}" was denied (${o.reason}). Try 'npx @hype-stack/cli login' or check your license.`), process.exit(1)), I = o.templateDir;
5512
- let c = await ba({
5573
+ let c = await Ea({
5513
5574
  manifest: d,
5514
5575
  config: h,
5515
5576
  projectRoot: g,
@@ -5517,13 +5578,13 @@ async function $s(t = {}) {
5517
5578
  });
5518
5579
  r.stop("Template overrides applied"), c.installed.length > 0 && s.log.success(`${c.installed.length} template file${c.installed.length === 1 ? "" : "s"} applied`);
5519
5580
  for (let e of c.errors) s.log.error(e);
5520
- if (await oa(g, h.name), !m) {
5581
+ if (await fa(g, h.name), !m) {
5521
5582
  let t = T.resolve(g, h.paths?.frontend.root ?? "apps/frontend"), n = d.theme ?? "zinc-mono";
5522
- a(n) && (await Oo(t, i(n)) ? s.log.success(`Applied the ${i(n).label} theme`) : s.log.warning(R.muted(`Could not find ${R.path("assets/styles.css")} to apply the theme`))), d.radius !== void 0 && yo(d.radius) && (await So(t, d.radius) ? s.log.success(`Set the corner radius to ${d.radius}`) : s.log.warning(R.muted(`Could not find ${R.path("assets/styles.css")} to set the corner radius`)));
5583
+ a(n) && (await Po(t, i(n)) ? s.log.success(`Applied the ${i(n).label} theme`) : s.log.warning(R.muted(`Could not find ${R.path("assets/styles.css")} to apply the theme`))), d.radius !== void 0 && To(d.radius) && (await Oo(t, d.radius) ? s.log.success(`Set the corner radius to ${d.radius}`) : s.log.warning(R.muted(`Could not find ${R.path("assets/styles.css")} to set the corner radius`)));
5523
5584
  let r = d.defaultMode === "dark" || d.defaultMode === "light" ? d.defaultMode : e;
5524
- await _o(t, r) ? s.log.success(`Default color mode set to ${r}`) : s.log.warning(R.muted(`Could not find ${R.path("src/hooks/use-theme.ts")} to set the default color mode`));
5585
+ await Co(t, r) ? s.log.success(`Default color mode set to ${r}`) : s.log.warning(R.muted(`Could not find ${R.path("src/hooks/use-theme.ts")} to set the default color mode`));
5525
5586
  }
5526
- await nc({
5587
+ await lc({
5527
5588
  prepared: F,
5528
5589
  templateNpm: d.dependencies_npm,
5529
5590
  paths: h.paths,
@@ -5531,13 +5592,13 @@ async function $s(t = {}) {
5531
5592
  spinner: r
5532
5593
  });
5533
5594
  let l;
5534
- m && (l = await Wa(g, t.yes ?? !1)), await br({
5595
+ m && (l = await Xa(g, t.yes ?? !1)), await br({
5535
5596
  projectRoot: g,
5536
5597
  paths: h.paths,
5537
5598
  skipPrompts: t.yes ?? !1,
5538
5599
  dbReady: l,
5539
5600
  freshScaffold: m
5540
- }), hs(), s.outro(R.brand(`Installed template ${u.name}.`));
5601
+ }), xs(), s.outro(R.brand(`Installed template ${u.name}.`));
5541
5602
  } finally {
5542
5603
  await Promise.all(F.map((e) => y.rm(e.packDir, {
5543
5604
  recursive: !0,
@@ -5548,7 +5609,7 @@ async function $s(t = {}) {
5548
5609
  });
5549
5610
  }
5550
5611
  }
5551
- async function ec(e, t, n) {
5612
+ async function sc(e, t, n) {
5552
5613
  let r = {};
5553
5614
  for (let i of e.slots) {
5554
5615
  if (t?.[i.family]) {
@@ -5572,7 +5633,7 @@ async function ec(e, t, n) {
5572
5633
  }
5573
5634
  return r;
5574
5635
  }
5575
- async function tc(e) {
5636
+ async function cc(e) {
5576
5637
  let { packs: t, templatePacks: n, installedSet: r, options: i } = e, a = new Set(n);
5577
5638
  if (i.packs && i.packs.length > 0) {
5578
5639
  let e = i.packs.filter((e) => !t.some((t) => t.name === e));
@@ -5583,7 +5644,7 @@ async function tc(e) {
5583
5644
  if (o.length === 0) return [];
5584
5645
  let c = se();
5585
5646
  B(o.map((e) => ` ${z.arrow} ${R.highlight(e.displayName)} ${_e(`${c}/packs/${e.name}`)}`).join("\n"), "Browse packs");
5586
- let l = await fo({
5647
+ let l = await vo({
5587
5648
  message: "Add extra packs on top of the template (optional)",
5588
5649
  options: o.map((e) => ({
5589
5650
  value: e.name,
@@ -5594,25 +5655,25 @@ async function tc(e) {
5594
5655
  });
5595
5656
  return m(l) && (s.cancel("Cancelled."), process.exit(0)), l;
5596
5657
  }
5597
- async function nc(e) {
5598
- let { prepared: t, templateNpm: n, paths: r, cwd: i, spinner: a } = e, o = ss(t.map((e) => e.manifest.dependencies_npm)), c = os(n ? ss([o, n]) : o, r);
5658
+ async function lc(e) {
5659
+ let { prepared: t, templateNpm: n, paths: r, cwd: i, spinner: a } = e, o = ps(t.map((e) => e.manifest.dependencies_npm)), c = fs(n ? ps([o, n]) : o, r);
5599
5660
  if (c.errors.length > 0) {
5600
5661
  for (let e of c.errors) s.log.error(e);
5601
5662
  return;
5602
5663
  }
5603
5664
  if (c.operations.length === 0) return;
5604
5665
  a.start("Installing npm dependencies...");
5605
- let l = await cs(c.operations, i);
5666
+ let l = await ms(c.operations, i);
5606
5667
  if (a.stop(l.ok ? "npm dependencies installed" : "npm dependency installation failed"), !l.ok) for (let e of l.errors) s.log.error(e);
5607
5668
  }
5608
5669
  //#endregion
5609
5670
  //#region src/cli.ts
5610
- function rc(e) {
5671
+ function uc(e) {
5611
5672
  if (!e) return;
5612
5673
  let t = e.split(",").map((e) => e.trim()).filter((e) => e.length > 0);
5613
5674
  return t.length > 0 ? t : void 0;
5614
5675
  }
5615
- function ic(e) {
5676
+ function dc(e) {
5616
5677
  if (!e) return;
5617
5678
  let t = {};
5618
5679
  for (let n of e.split(",")) {
@@ -5621,10 +5682,10 @@ function ic(e) {
5621
5682
  }
5622
5683
  return Object.keys(t).length > 0 ? t : void 0;
5623
5684
  }
5624
- function ac() {
5685
+ function fc() {
5625
5686
  let e = new o();
5626
5687
  return e.name("hype-stack").description("Build with Hype Stack -- templates, components, modules, and more").version(A, "-v, --version"), e.command("create").description("Create a new Hype Stack project").option("-n, --name <name>", "Project name").option("-d, --directory <path>", "Target directory").option("-e, --editor <editor>", "Code editor (cursor, claude, windsurf, copilot)").option("-t, --theme <theme>", "Color theme (default, slate, rose, emerald, violet, amber, ocean, zinc-mono, crimson, midnight)").option("--no-install", "Skip dependency installation").option("--no-setup", "Skip Docker services and database migrations after create").option("-y, --yes", "Skip confirmation prompts (requires --name)").action(async (e) => {
5627
- await Ds({
5688
+ await Ns({
5628
5689
  name: e.name,
5629
5690
  directory: e.directory,
5630
5691
  install: e.install,
@@ -5634,38 +5695,38 @@ function ac() {
5634
5695
  setup: e.setup
5635
5696
  });
5636
5697
  }), e.command("init").description("Initialize stack.json in the current project").action(async () => {
5637
- await Os({});
5698
+ await Ps({});
5638
5699
  }), e.command("onboard").description("Set up env vars, run migrations, and get the start command").option("-y, --yes", "Skip prompts, accept defaults").option("--skip-migrations", "Skip Docker services and database migrations").option("--cwd <path>", "Working directory").action(async (e) => {
5639
- await Ws({
5700
+ await Zs({
5640
5701
  cwd: e.cwd,
5641
5702
  yes: e.yes,
5642
5703
  skipMigrations: e.skipMigrations
5643
5704
  });
5644
5705
  }), e.command("compose").description("Choose feature packs to add to your project").option("--packs <list>", "Comma-separated pack names (non-interactive). Append @frontend or @admin to a layout pack to target that app shell, e.g. layout-basic@frontend,layout-native-app-shell@admin").option("--force", "Overwrite existing files").option("-y, --yes", "Skip confirmation prompts").option("-k, --key <key>", "License key").option("--license-key <key>", "License key (alias for --key)").option("--cwd <path>", "Working directory").action(async (e) => {
5645
- await As({
5646
- packs: rc(e.packs),
5706
+ await Is({
5707
+ packs: uc(e.packs),
5647
5708
  force: e.force,
5648
5709
  yes: e.yes,
5649
5710
  licenseKey: e.key ?? e.licenseKey,
5650
5711
  cwd: e.cwd
5651
5712
  });
5652
5713
  }), e.command("template").description("Install a template by id, with starter/layout variant swaps and extra packs on top").argument("[id]", "Template id (omit to pick interactively)").option("--variants <map>", "Preselect slot variants, e.g. starter-saas=starter-saas-better-auth,layout=layout-basic").option("--packs <list>", "Extra packs to add on top of the template (comma-separated)").option("--force", "Overwrite existing files").option("-y, --yes", "Skip confirmation prompts (requires <id>)").option("-k, --key <key>", "License key").option("--license-key <key>", "License key (alias for --key)").option("--cwd <path>", "Working directory").action(async (e, t) => {
5653
- await $s({
5714
+ await oc({
5654
5715
  templateId: e,
5655
- variants: ic(t.variants),
5656
- packs: rc(t.packs),
5716
+ variants: dc(t.variants),
5717
+ packs: uc(t.packs),
5657
5718
  force: t.force,
5658
5719
  yes: t.yes,
5659
5720
  licenseKey: t.key ?? t.licenseKey,
5660
5721
  cwd: t.cwd
5661
5722
  });
5662
5723
  }), e.command("login").description("Log in via your browser to install packs your organization owns").action(async () => {
5663
- await Is();
5724
+ await Us();
5664
5725
  }), e.command("logout").description("Log out and remove the saved CLI token").action(async () => {
5665
- await Ls();
5726
+ await Ws();
5666
5727
  }), e.command("auth").description("Alias for `login`").action(async () => {
5667
- await Is();
5728
+ await Us();
5668
5729
  }), e;
5669
5730
  }
5670
5731
  //#endregion
5671
- export { ks as a, As as i, Ls as n, Os as o, Is as r, Ds as s, ac as t };
5732
+ export { Fs as a, Is as i, Ws as n, Ps as o, Us as r, Ns as s, fc as t };