@hyprcart/cli 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  Command line interface for building, validating, deploying, and privately installing Hyprcart apps.
4
4
 
5
- The `hyprcart` binary supports app scaffolding, registered-app selection, project linking, creating a Developer Console app from `hyprcart.app.config.ts`, local preview, validation, contract generation, development deploys, private install links, logs, status, rollback, docs, and schema export.
5
+ The `hyprcart` binary supports browser login with an authorization prompt, app scaffolding, registered-app selection, project linking, creating a Developer Console app from `hyprcart.app.config.ts`, local preview, validation, contract generation, development deploys, private install links, logs, status, rollback, docs, and schema export.
package/dist/index.js CHANGED
@@ -69,30 +69,219 @@ async function appContracts(manifest) {
69
69
  return success("app.contracts.generate", result);
70
70
  }
71
71
 
72
+ // src/api/developer-apps.ts
73
+ async function listDeveloperApps(options) {
74
+ const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {
75
+ method: "GET",
76
+ token: options.token,
77
+ fetchImpl: options.fetchImpl
78
+ });
79
+ return response.data;
80
+ }
81
+ async function createDeveloperApp(input, options) {
82
+ const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {
83
+ method: "POST",
84
+ token: options.token,
85
+ fetchImpl: options.fetchImpl,
86
+ body: JSON.stringify(input)
87
+ });
88
+ return response.data;
89
+ }
90
+ async function deployDeveloperApp(input, options) {
91
+ const response = await callCliAppsApi(`${developerOrigin(options)}/cli/deployments`, {
92
+ method: "POST",
93
+ token: options.token,
94
+ fetchImpl: options.fetchImpl,
95
+ body: JSON.stringify(input)
96
+ });
97
+ return response.data;
98
+ }
99
+ async function createDeveloperInstallLink(input, options) {
100
+ const response = await callCliAppsApi(`${developerOrigin(options)}/cli/install-links`, {
101
+ method: "POST",
102
+ token: options.token,
103
+ fetchImpl: options.fetchImpl,
104
+ body: JSON.stringify(input)
105
+ });
106
+ return response.data;
107
+ }
108
+ async function callCliAppsApi(url, options) {
109
+ const response = await (options.fetchImpl ?? fetch)(url, {
110
+ method: options.method,
111
+ headers: {
112
+ Authorization: `Bearer ${options.token}`,
113
+ ...options.body ? { "content-type": "application/json" } : {}
114
+ },
115
+ body: options.body
116
+ });
117
+ const payload = await response.json().catch(() => null);
118
+ if (!response.ok || !payload?.ok) {
119
+ const error = payload?.error;
120
+ throw new DeveloperCliApiError(error?.code ?? "developer_api.failed", error?.message ?? "Developer API request failed.", payload?.data);
121
+ }
122
+ return { data: payload.data };
123
+ }
124
+ function developerOrigin(options) {
125
+ return (options.origin ?? "https://developer.hyprcart.com").replace(/\/$/, "");
126
+ }
127
+ var DeveloperCliApiError = class extends Error {
128
+ constructor(code, message, data) {
129
+ super(message);
130
+ this.code = code;
131
+ this.data = data;
132
+ }
133
+ };
134
+
135
+ // src/auth/credentials.ts
136
+ import { mkdir, readFile as readFile2, rm, writeFile } from "fs/promises";
137
+ import { homedir } from "os";
138
+ import { dirname, join as join2 } from "path";
139
+ function credentialsPath(env = process.env) {
140
+ const base = env.HYPRCART_CONFIG_HOME ?? join2(homedir(), ".hyprcart");
141
+ return join2(base, "credentials.json");
142
+ }
143
+ async function readDeveloperCredentials(env = process.env) {
144
+ try {
145
+ const parsed = JSON.parse(await readFile2(credentialsPath(env), "utf8"));
146
+ if (parsed.realm !== "developer" || !parsed.token) return null;
147
+ return parsed;
148
+ } catch {
149
+ return null;
150
+ }
151
+ }
152
+ async function writeDeveloperCredentials(credentials, env = process.env) {
153
+ const path = credentialsPath(env);
154
+ await mkdir(dirname(path), { recursive: true });
155
+ await writeFile(path, `${JSON.stringify(credentials, null, 2)}
156
+ `, { mode: 384 });
157
+ }
158
+ async function clearDeveloperCredentials(env = process.env) {
159
+ await rm(credentialsPath(env), { force: true });
160
+ }
161
+ function credentialsExpired(credentials, now = /* @__PURE__ */ new Date()) {
162
+ return new Date(credentials.expiresAt).getTime() <= now.getTime();
163
+ }
164
+
165
+ // src/config/project-link.ts
166
+ import { mkdir as mkdir2, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
167
+ import { join as join3 } from "path";
168
+ var linkDirectory = ".hyprcart";
169
+ var linkFile = "project.json";
170
+ async function readProjectLink(cwd = process.cwd()) {
171
+ try {
172
+ const raw = await readFile3(join3(cwd, linkDirectory, linkFile), "utf8");
173
+ return JSON.parse(raw);
174
+ } catch {
175
+ return null;
176
+ }
177
+ }
178
+ async function writeProjectLink(link, cwd = process.cwd(), force = false) {
179
+ const existing = await readProjectLink(cwd);
180
+ if (existing && existing.appId !== link.appId && !force) {
181
+ throw new Error("Project is already linked to another app. Re-run with --force to relink.");
182
+ }
183
+ await mkdir2(join3(cwd, linkDirectory), { recursive: true });
184
+ if (existing && existing.appId !== link.appId) {
185
+ await rename(join3(cwd, linkDirectory, linkFile), join3(cwd, linkDirectory, `project.${Date.now()}.previous.json`));
186
+ }
187
+ const next = {
188
+ ...link,
189
+ previousLinks: existing && existing.appId !== link.appId ? [existing, ...existing.previousLinks ?? []] : existing?.previousLinks
190
+ };
191
+ await writeFile2(join3(cwd, linkDirectory, linkFile), `${JSON.stringify(next, null, 2)}
192
+ `);
193
+ return next;
194
+ }
195
+
72
196
  // src/commands/app-deploy.ts
73
- async function appDeploy(args) {
197
+ async function appDeploy(args, cwd = process.cwd(), options = {}) {
74
198
  const env = readFlag(args, "--env") ?? "development";
75
- return success("app.deploy", {
76
- environment: env,
77
- appVersionId: `devver_${Date.now().toString(36)}`,
78
- runtimeDeploymentId: `rtdep_${Date.now().toString(36)}`,
79
- status: "deployed",
80
- healthChecked: args.includes("--wait")
81
- });
199
+ const developerOrigin2 = readFlag(args, "--developer-origin") ?? "https://developer.hyprcart.com";
200
+ const token = await resolveDeveloperToken(options.env);
201
+ if (!token) return failure("app.deploy", "auth.missing", "Run npx hyprcart login before deploying.");
202
+ const link = await readProjectLink(cwd);
203
+ if (!link) return failure("app.deploy", "project.link.missing", "Run npx hyprcart app link before deploying.");
204
+ const manifest = await loadProjectManifest(cwd) ?? fallbackManifest(link.appSlug);
205
+ try {
206
+ const deployed = await deployDeveloperApp(
207
+ {
208
+ appId: link.appId,
209
+ teamId: link.teamId,
210
+ environment: env,
211
+ wait: args.includes("--wait"),
212
+ manifest
213
+ },
214
+ { token, origin: developerOrigin2, fetchImpl: options.fetchImpl }
215
+ );
216
+ await writeProjectLink(
217
+ {
218
+ ...link,
219
+ environment: env,
220
+ lastDeployment: {
221
+ appVersionId: deployed.appVersionId,
222
+ runtimeDeploymentId: deployed.runtimeDeploymentId,
223
+ environment: deployed.environment,
224
+ deployedAt: (/* @__PURE__ */ new Date()).toISOString()
225
+ }
226
+ },
227
+ cwd,
228
+ true
229
+ );
230
+ return success("app.deploy", deployed);
231
+ } catch (error) {
232
+ if (error instanceof DeveloperCliApiError) return failure("app.deploy", error.code, error.message);
233
+ return failure("app.deploy", "deploy.failed", error instanceof Error ? error.message : "Deploy failed.");
234
+ }
82
235
  }
83
236
  function readFlag(args, name) {
84
237
  const index = args.indexOf(name);
85
238
  return index >= 0 ? args[index + 1] : void 0;
86
239
  }
240
+ async function resolveDeveloperToken(env = process.env) {
241
+ if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;
242
+ const credentials = await readDeveloperCredentials(env);
243
+ return credentials && !credentialsExpired(credentials) ? credentials.token : null;
244
+ }
87
245
 
88
246
  // src/commands/app-dev.ts
89
247
  import { createPreviewServer, previewSurface } from "@hyprcart/app-testing";
90
- async function appDev(args) {
248
+ import { createServer } from "http";
249
+ import { once } from "events";
250
+ async function appDev(args, cwd = process.cwd()) {
91
251
  const fixtureId = readFlag2(args, "--fixture");
252
+ const port = Number(readFlag2(args, "--port") ?? 8788);
253
+ const host = readFlag2(args, "--host") ?? "127.0.0.1";
92
254
  const state = createPreviewServer();
93
255
  const preview = await previewSurface(state, "storefront_block", fixtureId);
256
+ const manifest = await loadProjectManifest(cwd) ?? fallbackManifest();
257
+ const previewUrl = `http://localhost:${port}`;
258
+ if (args.includes("--once")) {
259
+ return success("app.dev", {
260
+ previewUrl,
261
+ html: preview.html,
262
+ diagnostics: state.diagnostics,
263
+ remoteVersionCreated: state.remoteVersionCreated
264
+ });
265
+ }
266
+ const server = createServer(async (request, response) => {
267
+ const url = new URL(request.url ?? "/", previewUrl);
268
+ if (url.pathname === "/healthz") {
269
+ response.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ ok: true }));
270
+ return;
271
+ }
272
+ if (url.pathname === "/api/hyprcart/products") {
273
+ response.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" }).end(JSON.stringify({ ok: true, data: { products: [{ id: "prod_1", title: "Deep Moisture", handle: "deep-moisture" }] } }));
274
+ return;
275
+ }
276
+ response.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" }).end(renderPreviewHtml({ manifest, previewHtml: preview.html, diagnostics: state.diagnostics }));
277
+ });
278
+ await listen(server, port, host);
279
+ process.stderr.write(`Hyprcart local preview running at ${previewUrl}
280
+ `);
281
+ process.stderr.write("Press Ctrl+C to stop.\n");
282
+ await waitForShutdown(server);
94
283
  return success("app.dev", {
95
- previewUrl: "http://localhost:8788",
284
+ previewUrl,
96
285
  html: preview.html,
97
286
  diagnostics: state.diagnostics,
98
287
  remoteVersionCreated: state.remoteVersionCreated
@@ -102,16 +291,100 @@ function readFlag2(args, name) {
102
291
  const index = args.indexOf(name);
103
292
  return index >= 0 ? args[index + 1] : void 0;
104
293
  }
294
+ async function listen(server, port, host) {
295
+ await new Promise((resolve, reject) => {
296
+ server.once("error", reject);
297
+ server.listen(port, host, () => resolve());
298
+ });
299
+ }
300
+ async function waitForShutdown(server) {
301
+ const close = async () => {
302
+ if (server.listening) await new Promise((resolve) => server.close(() => resolve()));
303
+ };
304
+ const onSignal = async () => {
305
+ await close();
306
+ process.exit(0);
307
+ };
308
+ process.once("SIGINT", onSignal);
309
+ process.once("SIGTERM", onSignal);
310
+ await once(server, "close");
311
+ }
312
+ function renderPreviewHtml(input) {
313
+ const surfaces = input.manifest.surfaces.map((surface) => `<button class="tab" data-surface="${escapeHtml(surface.type)}">${escapeHtml(surface.label.en ?? surface.id)}</button>`).join("");
314
+ return `<!doctype html>
315
+ <html lang="en">
316
+ <head>
317
+ <meta charset="utf-8">
318
+ <meta name="viewport" content="width=device-width, initial-scale=1">
319
+ <title>${escapeHtml(input.manifest.name)} - Hyprcart Preview</title>
320
+ <style>
321
+ :root { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color: #13202d; background: #f6f8fb; }
322
+ body { margin: 0; }
323
+ header { border-bottom: 1px solid #dbe3ec; background: #fff; padding: 18px 24px; display: flex; justify-content: space-between; gap: 16px; align-items: center; }
324
+ main { max-width: 1080px; margin: 0 auto; padding: 24px; display: grid; gap: 18px; }
325
+ h1 { margin: 0; font-size: 22px; letter-spacing: 0; }
326
+ .muted { color: #667085; }
327
+ .tabs { display: flex; flex-wrap: wrap; gap: 8px; }
328
+ .tab { border: 1px solid #cbd5e1; border-radius: 6px; background: #fff; padding: 8px 12px; font: inherit; }
329
+ .grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(280px, .7fr); gap: 16px; }
330
+ section { border: 1px solid #dbe3ec; border-radius: 8px; background: #fff; padding: 18px; min-width: 0; }
331
+ .surface { min-height: 180px; display: grid; place-items: center; border: 1px dashed #94a3b8; border-radius: 8px; background: #f8fafc; }
332
+ code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
333
+ pre { overflow: auto; background: #0f172a; color: #e2e8f0; padding: 12px; border-radius: 6px; font-size: 12px; }
334
+ .api { display: grid; gap: 8px; }
335
+ @media (max-width: 760px) { .grid { grid-template-columns: 1fr; } header { align-items: flex-start; flex-direction: column; } }
336
+ </style>
337
+ </head>
338
+ <body>
339
+ <header>
340
+ <div>
341
+ <h1>${escapeHtml(input.manifest.name)}</h1>
342
+ <div class="muted">Local Hyprcart app preview</div>
343
+ </div>
344
+ <div class="tabs">${surfaces}</div>
345
+ </header>
346
+ <main>
347
+ <div class="grid">
348
+ <section>
349
+ <h2>Storefront surface</h2>
350
+ <div class="surface">${input.previewHtml}</div>
351
+ </section>
352
+ <section>
353
+ <h2>Admin UI</h2>
354
+ <div class="api">
355
+ <p class="muted">This app can render an admin surface and call the local preview API.</p>
356
+ <button class="tab" id="load-products">Call API</button>
357
+ <pre id="api-output">GET /api/hyprcart/products</pre>
358
+ </div>
359
+ </section>
360
+ </div>
361
+ <section>
362
+ <h2>Diagnostics</h2>
363
+ <pre>${escapeHtml(JSON.stringify(input.diagnostics, null, 2))}</pre>
364
+ </section>
365
+ </main>
366
+ <script>
367
+ document.getElementById("load-products").addEventListener("click", async () => {
368
+ const response = await fetch("/api/hyprcart/products");
369
+ document.getElementById("api-output").textContent = JSON.stringify(await response.json(), null, 2);
370
+ });
371
+ </script>
372
+ </body>
373
+ </html>`;
374
+ }
375
+ function escapeHtml(value) {
376
+ return String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
377
+ }
105
378
 
106
379
  // src/commands/app-init.ts
107
- import { mkdir as mkdir2 } from "fs/promises";
108
- import { join as join3 } from "path";
380
+ import { mkdir as mkdir4 } from "fs/promises";
381
+ import { join as join5 } from "path";
109
382
 
110
383
  // src/templates/materialize.ts
111
- import { mkdir, writeFile } from "fs/promises";
112
- import { dirname, join as join2 } from "path";
384
+ import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
385
+ import { dirname as dirname2, join as join4 } from "path";
113
386
  function starterTemplate(appName, kind = "storefront-block") {
114
- const surface = surfaceForTemplate(kind);
387
+ const surfaces = surfacesForTemplate(kind);
115
388
  return [
116
389
  {
117
390
  path: "hyprcart.app.config.ts",
@@ -121,9 +394,12 @@ function starterTemplate(appName, kind = "storefront-block") {
121
394
  manifestVersion: "2026-06",
122
395
  sdkVersion: "1.0.0",
123
396
  platformCompatibility: "2026-06",
124
- scopes: ["product:read"],
125
- surfaces: [${JSON.stringify(surface)}],
126
- translations: { en: { "reviews.label": "Reviews" }, de: { "reviews.label": "Bewertungen" } },
397
+ scopes: ["product:read", "app_installations:read"],
398
+ surfaces: ${JSON.stringify(surfaces)},
399
+ translations: {
400
+ en: { "reviews.label": "Reviews", "reviewsAdmin.label": "Reviews admin" },
401
+ de: { "reviews.label": "Bewertungen", "reviewsAdmin.label": "Bewertungen Admin" }
402
+ },
127
403
  resources: { bundleSizeBytes: 42000 }
128
404
  };
129
405
  `
@@ -160,11 +436,10 @@ function starterTemplate(appName, kind = "storefront-block") {
160
436
  )}
161
437
  `
162
438
  },
163
- { path: surface.entry, content: `export function HyprcartSurface() { return "<section>${kind}</section>"; }
164
- ` },
165
- { path: "locales/en.json", content: `${JSON.stringify({ "reviews.label": "Reviews" }, null, 2)}
439
+ ...surfaces.map((surface) => ({ path: surface.entry, content: sourceForSurface(surface, kind) })),
440
+ { path: "locales/en.json", content: `${JSON.stringify({ "reviews.label": "Reviews", "reviewsAdmin.label": "Reviews admin" }, null, 2)}
166
441
  ` },
167
- { path: "locales/de.json", content: `${JSON.stringify({ "reviews.label": "Bewertungen" }, null, 2)}
442
+ { path: "locales/de.json", content: `${JSON.stringify({ "reviews.label": "Bewertungen", "reviewsAdmin.label": "Bewertungen Admin" }, null, 2)}
168
443
  ` },
169
444
  { path: "fixtures/product.basic.json", content: `${JSON.stringify({ id: "prod_1", title: "Deep Moisture" }, null, 2)}
170
445
  ` },
@@ -197,27 +472,57 @@ For one-off CLI commands, use \`npx hyprcart <command>\` unless you installed \`
197
472
  function isStarterTemplateKind(value) {
198
473
  return ["storefront-block", "admin-surface", "checkout-function", "pixel-event", "multi-surface"].includes(value);
199
474
  }
200
- function surfaceForTemplate(kind) {
475
+ function surfacesForTemplate(kind) {
201
476
  if (kind === "admin-surface") {
202
- return { id: "reviews", type: "admin_surface", entry: "src/admin/reviews.tsx", label: { en: "Reviews", de: "Bewertungen" } };
477
+ return [{ id: "reviewsAdmin", type: "admin_surface", entry: "src/admin/reviews.tsx", label: { en: "Reviews admin", de: "Bewertungen Admin" } }];
203
478
  }
204
479
  if (kind === "checkout-function") {
205
- return { id: "reviews", type: "checkout_function", entry: "src/checkout/reviews.ts", label: { en: "Reviews", de: "Bewertungen" } };
480
+ return [{ id: "reviews", type: "checkout_function", entry: "src/checkout/reviews.ts", label: { en: "Reviews", de: "Bewertungen" } }];
206
481
  }
207
482
  if (kind === "pixel-event") {
208
- return { id: "reviews", type: "pixel", entry: "src/pixel/reviews.ts", label: { en: "Reviews", de: "Bewertungen" } };
483
+ return [{ id: "reviews", type: "pixel", entry: "src/pixel/reviews.ts", label: { en: "Reviews", de: "Bewertungen" } }];
209
484
  }
210
485
  if (kind === "multi-surface") {
211
- return { id: "reviews", type: "storefront_block", entry: "src/storefront/reviews.tsx", label: { en: "Reviews", de: "Bewertungen" } };
486
+ return [
487
+ { id: "reviews", type: "storefront_block", entry: "src/storefront/reviews.tsx", label: { en: "Reviews", de: "Bewertungen" } },
488
+ { id: "reviewsAdmin", type: "admin_surface", entry: "src/admin/reviews.tsx", label: { en: "Reviews admin", de: "Bewertungen Admin" } }
489
+ ];
490
+ }
491
+ return [
492
+ { id: "reviews", type: "storefront_block", entry: "src/storefront/reviews.tsx", label: { en: "Reviews", de: "Bewertungen" } },
493
+ { id: "reviewsAdmin", type: "admin_surface", entry: "src/admin/reviews.tsx", label: { en: "Reviews admin", de: "Bewertungen Admin" } }
494
+ ];
495
+ }
496
+ function sourceForSurface(surface, kind) {
497
+ if (surface.type === "admin_surface") {
498
+ return `import { adminActionResponse } from "@hyprcart/app-sdk";
499
+
500
+ export function HyprcartAdminSurface() {
501
+ return "<section><h2>Reviews admin</h2><button data-action='load-products'>Load products</button></section>";
502
+ }
503
+
504
+ export async function loadProducts() {
505
+ return adminActionResponse("products.load", { endpoint: "/api/hyprcart/products", method: "GET" });
506
+ }
507
+ `;
212
508
  }
213
- return { id: "reviews", type: "storefront_block", entry: "src/storefront/reviews.tsx", label: { en: "Reviews", de: "Bewertungen" } };
509
+ if (surface.type === "storefront_block") {
510
+ return `import { storefrontBlockResponse } from "@hyprcart/app-sdk";
511
+
512
+ export function HyprcartSurface() {
513
+ return storefrontBlockResponse("<section><strong>Reviews badge</strong><span>Default commerce fixture</span></section>");
514
+ }
515
+ `;
516
+ }
517
+ return `export function HyprcartSurface() { return "<section>${kind}</section>"; }
518
+ `;
214
519
  }
215
520
  async function materializeTemplate(files, cwd) {
216
521
  const written = [];
217
522
  for (const file of files) {
218
- const fullPath = join2(cwd, file.path);
219
- await mkdir(dirname(fullPath), { recursive: true });
220
- await writeFile(fullPath, file.content, { flag: "wx" });
523
+ const fullPath = join4(cwd, file.path);
524
+ await mkdir3(dirname2(fullPath), { recursive: true });
525
+ await writeFile3(fullPath, file.content, { flag: "wx" });
221
526
  written.push(file.path);
222
527
  }
223
528
  return written;
@@ -230,8 +535,8 @@ async function appInit(args, cwd = process.cwd()) {
230
535
  if (!isStarterTemplateKind(template)) {
231
536
  return failure("app.init", "template.unsupported", `Unsupported template: ${template}.`);
232
537
  }
233
- const target = join3(cwd, name);
234
- await mkdir2(target, { recursive: true });
538
+ const target = join5(cwd, name);
539
+ await mkdir4(target, { recursive: true });
235
540
  const files = await materializeTemplate(starterTemplate(name, template), target);
236
541
  return success("app.init", { projectPath: target, template, files });
237
542
  }
@@ -244,141 +549,51 @@ function positionalArgs(args) {
244
549
  }
245
550
 
246
551
  // src/commands/app-install-link.ts
247
- async function appInstallLink(args) {
552
+ async function appInstallLink(args, cwd = process.cwd(), options = {}) {
248
553
  const subcommand = args[0];
249
554
  if (subcommand === "revoke") {
250
555
  return success("app.install-link.revoke", { privateInstallUrlId: args[1], status: "revoked" });
251
556
  }
557
+ const developerOrigin2 = readFlag4(args, "--developer-origin") ?? "https://developer.hyprcart.com";
252
558
  const orgId = readFlag4(args, "--org");
253
559
  if (!orgId) {
254
560
  return failure("app.install-link.create", "organization.missing", "Provide --org <orgId>.");
255
561
  }
256
- const token = `hcdev_${Date.now().toString(36)}`;
257
- const privateInstallUrlId = `hcil_${Date.now().toString(36)}`;
258
- const installUrl = new URL("https://hyprcart.com/apps/install/private");
259
- installUrl.searchParams.set("hcil", privateInstallUrlId);
260
- installUrl.searchParams.set("token", token);
261
- return success("app.install-link.create", {
262
- privateInstallUrlId,
263
- installUrl: installUrl.toString(),
264
- appVersionId: readFlag4(args, "--version") ?? "devver_local",
265
- environment: readFlag4(args, "--env") ?? "development",
266
- allowedOrganizationId: orgId,
267
- allowedUserEmail: readFlag4(args, "--user"),
268
- expiresAt: readFlag4(args, "--expires-at") ?? null,
269
- maxUses: Number(readFlag4(args, "--max-uses") ?? 1)
270
- });
562
+ const token = await resolveDeveloperToken2(options.env);
563
+ if (!token) return failure("app.install-link.create", "auth.missing", "Run npx hyprcart login before creating an install link.");
564
+ const link = await readProjectLink(cwd);
565
+ if (!link) return failure("app.install-link.create", "project.link.missing", "Run npx hyprcart app link before creating an install link.");
566
+ const appVersionId = readFlag4(args, "--version") ?? link.lastDeployment?.appVersionId;
567
+ if (!appVersionId) return failure("app.install-link.create", "version.missing", "Run npx hyprcart app deploy --env development --wait before creating an install link, or pass --version <versionId>.");
568
+ try {
569
+ const created = await createDeveloperInstallLink(
570
+ {
571
+ appId: link.appId,
572
+ teamId: link.teamId,
573
+ appVersionId,
574
+ environment: readFlag4(args, "--env") ?? link.lastDeployment?.environment ?? link.environment ?? "development",
575
+ allowedOrganizationId: orgId,
576
+ allowedUserEmail: readFlag4(args, "--user"),
577
+ expiresAt: readFlag4(args, "--expires-at"),
578
+ maxUses: Number(readFlag4(args, "--max-uses") ?? 1)
579
+ },
580
+ { token, origin: developerOrigin2, fetchImpl: options.fetchImpl }
581
+ );
582
+ return success("app.install-link.create", created);
583
+ } catch (error) {
584
+ if (error instanceof DeveloperCliApiError) return failure("app.install-link.create", error.code, error.message);
585
+ return failure("app.install-link.create", "install_link.failed", error instanceof Error ? error.message : "Install link creation failed.");
586
+ }
271
587
  }
272
588
  function readFlag4(args, name) {
273
589
  const index = args.indexOf(name);
274
590
  return index >= 0 ? args[index + 1] : void 0;
275
591
  }
276
-
277
- // src/config/project-link.ts
278
- import { mkdir as mkdir3, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
279
- import { join as join4 } from "path";
280
- var linkDirectory = ".hyprcart";
281
- var linkFile = "project.json";
282
- async function readProjectLink(cwd = process.cwd()) {
283
- try {
284
- const raw = await readFile2(join4(cwd, linkDirectory, linkFile), "utf8");
285
- return JSON.parse(raw);
286
- } catch {
287
- return null;
288
- }
289
- }
290
- async function writeProjectLink(link, cwd = process.cwd(), force = false) {
291
- const existing = await readProjectLink(cwd);
292
- if (existing && existing.appId !== link.appId && !force) {
293
- throw new Error("Project is already linked to another app. Re-run with --force to relink.");
294
- }
295
- await mkdir3(join4(cwd, linkDirectory), { recursive: true });
296
- if (existing && existing.appId !== link.appId) {
297
- await rename(join4(cwd, linkDirectory, linkFile), join4(cwd, linkDirectory, `project.${Date.now()}.previous.json`));
298
- }
299
- const next = {
300
- ...link,
301
- previousLinks: existing && existing.appId !== link.appId ? [existing, ...existing.previousLinks ?? []] : existing?.previousLinks
302
- };
303
- await writeFile2(join4(cwd, linkDirectory, linkFile), `${JSON.stringify(next, null, 2)}
304
- `);
305
- return next;
306
- }
307
-
308
- // src/auth/credentials.ts
309
- import { mkdir as mkdir4, readFile as readFile3, rm, writeFile as writeFile3 } from "fs/promises";
310
- import { homedir } from "os";
311
- import { dirname as dirname2, join as join5 } from "path";
312
- function credentialsPath(env = process.env) {
313
- const base = env.HYPRCART_CONFIG_HOME ?? join5(homedir(), ".hyprcart");
314
- return join5(base, "credentials.json");
315
- }
316
- async function readDeveloperCredentials(env = process.env) {
317
- try {
318
- const parsed = JSON.parse(await readFile3(credentialsPath(env), "utf8"));
319
- if (parsed.realm !== "developer" || !parsed.token) return null;
320
- return parsed;
321
- } catch {
322
- return null;
323
- }
324
- }
325
- async function writeDeveloperCredentials(credentials, env = process.env) {
326
- const path = credentialsPath(env);
327
- await mkdir4(dirname2(path), { recursive: true });
328
- await writeFile3(path, `${JSON.stringify(credentials, null, 2)}
329
- `, { mode: 384 });
330
- }
331
- async function clearDeveloperCredentials(env = process.env) {
332
- await rm(credentialsPath(env), { force: true });
333
- }
334
- function credentialsExpired(credentials, now = /* @__PURE__ */ new Date()) {
335
- return new Date(credentials.expiresAt).getTime() <= now.getTime();
336
- }
337
-
338
- // src/api/developer-apps.ts
339
- async function listDeveloperApps(options) {
340
- const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {
341
- method: "GET",
342
- token: options.token,
343
- fetchImpl: options.fetchImpl
344
- });
345
- return response.data;
346
- }
347
- async function createDeveloperApp(input, options) {
348
- const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {
349
- method: "POST",
350
- token: options.token,
351
- fetchImpl: options.fetchImpl,
352
- body: JSON.stringify(input)
353
- });
354
- return response.data;
355
- }
356
- async function callCliAppsApi(url, options) {
357
- const response = await (options.fetchImpl ?? fetch)(url, {
358
- method: options.method,
359
- headers: {
360
- Authorization: `Bearer ${options.token}`,
361
- ...options.body ? { "content-type": "application/json" } : {}
362
- },
363
- body: options.body
364
- });
365
- const payload = await response.json().catch(() => null);
366
- if (!response.ok || !payload?.ok) {
367
- const error = payload?.error;
368
- throw new DeveloperCliApiError(error?.code ?? "developer_api.failed", error?.message ?? "Developer API request failed.", payload?.data);
369
- }
370
- return { data: payload.data };
371
- }
372
- function developerOrigin(options) {
373
- return (options.origin ?? "https://developer.hyprcart.com").replace(/\/$/, "");
592
+ async function resolveDeveloperToken2(env = process.env) {
593
+ if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;
594
+ const credentials = await readDeveloperCredentials(env);
595
+ return credentials && !credentialsExpired(credentials) ? credentials.token : null;
374
596
  }
375
- var DeveloperCliApiError = class extends Error {
376
- constructor(code, message, data) {
377
- super(message);
378
- this.code = code;
379
- this.data = data;
380
- }
381
- };
382
597
 
383
598
  // src/commands/app-link.ts
384
599
  import { createInterface } from "readline/promises";
@@ -394,7 +609,7 @@ async function appLink(args, cwd = process.cwd(), options = {}) {
394
609
  const resolved = await resolveExplicitApp(appId, explicitTeamId, developerOrigin2, options);
395
610
  return writeResolvedProjectLink(resolved.app, environment, developerApiUrl, cwd, force);
396
611
  }
397
- const token = await resolveDeveloperToken(options.env);
612
+ const token = await resolveDeveloperToken3(options.env);
398
613
  if (!token) {
399
614
  return failure("app.link", "auth.missing", "Run npx hyprcart login, then rerun npx hyprcart app link.");
400
615
  }
@@ -413,7 +628,10 @@ async function appLink(args, cwd = process.cwd(), options = {}) {
413
628
  payload,
414
629
  token,
415
630
  developerOrigin: developerOrigin2,
416
- fetchImpl: options.fetchImpl
631
+ fetchImpl: options.fetchImpl,
632
+ input: options.input,
633
+ output: options.output,
634
+ isTTY: options.isTTY ?? Boolean(process.stdin.isTTY)
417
635
  }) : await selectAppOrCreate({
418
636
  args,
419
637
  manifest,
@@ -446,13 +664,13 @@ function readFlag5(args, name) {
446
664
  const value = index >= 0 ? args[index + 1] : void 0;
447
665
  return value && !value.startsWith("--") ? value : void 0;
448
666
  }
449
- async function resolveDeveloperToken(env = process.env) {
667
+ async function resolveDeveloperToken3(env = process.env) {
450
668
  if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;
451
669
  const credentials = await readDeveloperCredentials(env);
452
670
  return credentials && !credentialsExpired(credentials) ? credentials.token : null;
453
671
  }
454
672
  async function resolveExplicitApp(appId, explicitTeamId, developerOrigin2, options) {
455
- const token = await resolveDeveloperToken(options.env);
673
+ const token = await resolveDeveloperToken3(options.env);
456
674
  if (token) {
457
675
  const payload = await listDeveloperApps({ token, origin: developerOrigin2, fetchImpl: options.fetchImpl }).catch(() => null);
458
676
  const app = payload ? flattenApps(payload.teams).find((candidate) => candidate.id === appId) : null;
@@ -489,6 +707,7 @@ async function selectAppOrCreate(input) {
489
707
  input: input.input ?? process.stdin,
490
708
  output: input.output ?? process.stderr
491
709
  });
710
+ let selectedIndex = Number.NaN;
492
711
  try {
493
712
  const choices = apps.map((app, index) => `${index + 1}. ${app.displayName} (${app.id}) - ${app.teamName}`);
494
713
  const createIndex = apps.length + 1;
@@ -497,25 +716,26 @@ Hyprcart app link for ${input.payload.account.email}`);
497
716
  if (choices.length > 0) writeLine(input.output, choices.join("\n"));
498
717
  writeLine(input.output, `${createIndex}. Create new app from ${input.manifest.name}`);
499
718
  const answer = (await rl.question(`Choose an app [1-${createIndex}]: `)).trim();
500
- const selectedIndex = Number.parseInt(answer, 10);
501
- if (selectedIndex >= 1 && selectedIndex <= apps.length) {
502
- return { ok: true, app: apps[selectedIndex - 1], accountEmail: input.payload.account.email };
503
- }
504
- if (selectedIndex === createIndex) {
505
- return createAppFromProject(input);
506
- }
507
- return { ok: false, result: failure("app.link", "app.selection_invalid", "Choose a listed app number.") };
719
+ selectedIndex = Number.parseInt(answer, 10);
508
720
  } finally {
509
721
  rl.close();
510
722
  }
723
+ if (selectedIndex >= 1 && selectedIndex <= apps.length) {
724
+ return { ok: true, app: apps[selectedIndex - 1], accountEmail: input.payload.account.email };
725
+ }
726
+ if (selectedIndex === apps.length + 1) {
727
+ return createAppFromProject(input);
728
+ }
729
+ return { ok: false, result: failure("app.link", "app.selection_invalid", "Choose a listed app number.") };
511
730
  }
512
731
  async function createAppFromProject(input) {
513
732
  const name = readFlag5(input.args, "--name") ?? input.manifest.name;
514
733
  const slug = readFlag5(input.args, "--slug");
515
- const teamId = readFlag5(input.args, "--team");
734
+ const team = await resolveTeamForCreate(input);
735
+ if (!team.ok) return team;
516
736
  const created = await createDeveloperApp(
517
737
  {
518
- teamId,
738
+ teamId: team.teamId,
519
739
  name,
520
740
  slug,
521
741
  manifest: input.manifest
@@ -524,6 +744,36 @@ async function createAppFromProject(input) {
524
744
  );
525
745
  return { ok: true, app: created.app, accountEmail: created.account.email };
526
746
  }
747
+ async function resolveTeamForCreate(input) {
748
+ const explicitTeamId = readFlag5(input.args, "--team");
749
+ if (explicitTeamId) return { ok: true, teamId: explicitTeamId };
750
+ if (input.payload.teams.length === 0) {
751
+ return { ok: false, result: failure("app.link", "team.missing", "Create or join a Developer Console team before creating an app from this project.") };
752
+ }
753
+ if (input.payload.teams.length === 1) {
754
+ return { ok: true, teamId: input.payload.teams[0].id };
755
+ }
756
+ if (!input.isTTY) {
757
+ return { ok: false, result: failure("app.link", "team.selection_required", "Choose which developer team should own the new app with --team <teamId>, or run interactively to select one.") };
758
+ }
759
+ const rl = createInterface({
760
+ input: input.input ?? process.stdin,
761
+ output: input.output ?? process.stderr
762
+ });
763
+ try {
764
+ writeLine(input.output, "\nChoose a developer team for the new app");
765
+ input.payload.teams.forEach((team, index) => writeLine(input.output, `${index + 1}. ${team.name} (${team.id})`));
766
+ const answer = (await rl.question(`Choose a team [1-${input.payload.teams.length}]: `)).trim();
767
+ const selectedIndex = Number.parseInt(answer, 10);
768
+ const selectedTeam = input.payload.teams[selectedIndex - 1];
769
+ if (!selectedTeam) {
770
+ return { ok: false, result: failure("app.link", "team.selection_invalid", "Choose a listed developer team number.") };
771
+ }
772
+ return { ok: true, teamId: selectedTeam.id };
773
+ } finally {
774
+ rl.close();
775
+ }
776
+ }
527
777
  async function confirmLink(input) {
528
778
  if (input.yes) return { ok: true };
529
779
  if (!input.isTTY) {
@@ -618,10 +868,10 @@ async function appVersionCreate() {
618
868
 
619
869
  // src/auth/browser-login.ts
620
870
  import { spawn } from "child_process";
621
- import { createServer } from "http";
871
+ import { createServer as createServer2 } from "http";
622
872
  import { randomBytes } from "crypto";
623
873
  async function runBrowserLogin(options = {}) {
624
- const server = createServer();
874
+ const server = createServer2();
625
875
  const state = randomBytes(24).toString("base64url");
626
876
  const callback = await listenOnLoopback(server);
627
877
  const loginUrl = new URL("/cli/auth/start", options.developerOrigin ?? "https://developer.hyprcart.com");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/app-contracts.ts","../src/config/manifest.ts","../src/output/envelope.ts","../src/commands/app-deploy.ts","../src/commands/app-dev.ts","../src/commands/app-init.ts","../src/templates/materialize.ts","../src/commands/app-install-link.ts","../src/config/project-link.ts","../src/auth/credentials.ts","../src/api/developer-apps.ts","../src/commands/app-link.ts","../src/commands/app-logs.ts","../src/commands/app-rollback.ts","../src/commands/app-status.ts","../src/commands/app-validate.ts","../src/commands/app-version-create.ts","../src/auth/browser-login.ts","../src/commands/auth.ts","../src/commands/docs-open.ts","../src/commands/schema-export.ts","../src/index.ts"],"sourcesContent":["import { generateContracts, type AppManifest } from \"@hyprcart/app-manifest\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function appContracts(manifest?: AppManifest) {\n const result = generateContracts(manifest ?? (await loadProjectManifest()) ?? fallbackManifest());\n return success(\"app.contracts.generate\", result);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AppManifest } from \"@hyprcart/app-manifest\";\n\nconst manifestCandidates = [\"hyprcart.app.config.ts\", \"hyprcart.app.config.mjs\", \"hyprcart.app.config.js\", \"hyprcart.app.json\"];\n\nexport async function loadProjectManifest(cwd = process.cwd()): Promise<AppManifest | null> {\n for (const candidate of manifestCandidates) {\n const path = join(cwd, candidate);\n try {\n const source = await readFile(path, \"utf8\");\n if (candidate.endsWith(\".json\")) return JSON.parse(source) as AppManifest;\n return evaluateConfigModule(source) as AppManifest;\n } catch (error) {\n if (isMissingFileError(error)) continue;\n throw new Error(`Unable to read ${candidate}: ${error instanceof Error ? error.message : \"invalid manifest\"}`);\n }\n }\n return null;\n}\n\nexport function fallbackManifest(name = \"Local app\"): AppManifest {\n return {\n name,\n version: \"0.1.0\",\n manifestVersion: \"2026-06\",\n sdkVersion: \"1.0.0\",\n platformCompatibility: \"2026-06\",\n scopes: [\"product:read\"],\n surfaces: [{ id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } }],\n translations: { en: { \"reviews.label\": \"Reviews\" }, de: { \"reviews.label\": \"Bewertungen\" } },\n };\n}\n\nfunction evaluateConfigModule(source: string): unknown {\n const expression = source\n .replace(/^\\s*export\\s+default\\s+/m, \"return \")\n .replace(/;\\s*$/, \"\");\n if (!/^\\s*return\\s+/.test(expression)) {\n throw new Error(\"expected a default-exported manifest object\");\n }\n return new Function(expression)();\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return Boolean(error && typeof error === \"object\" && \"code\" in error && (error as { code: string }).code === \"ENOENT\");\n}\n","export interface CommandEnvelope<TData = unknown> {\n ok: boolean;\n requestId: string;\n command: string;\n data?: TData;\n error?: {\n code: string;\n message: string;\n path?: string;\n docsUrl?: string;\n };\n}\n\nexport function success<TData>(command: string, data: TData, requestId = createRequestId()): CommandEnvelope<TData> {\n return { ok: true, command, requestId, data };\n}\n\nexport function failure(command: string, code: string, message: string, requestId = createRequestId(), docsUrl?: string): CommandEnvelope {\n return {\n ok: false,\n command,\n requestId,\n error: { code, message: redactMessage(message), docsUrl },\n };\n}\n\nexport function createRequestId(): string {\n return `req_cli_${Date.now().toString(36)}`;\n}\n\nfunction redactMessage(message: string): string {\n return message\n .replace(/hcdev_[a-z0-9_]+/gi, \"[redacted]\")\n .replace(/Bearer\\s+[a-z0-9._-]+/gi, \"[redacted]\")\n .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, \"[redacted]\");\n}\n","import { success } from \"../output/envelope\";\n\nexport async function appDeploy(args: string[]) {\n const env = readFlag(args, \"--env\") ?? \"development\";\n return success(\"app.deploy\", {\n environment: env,\n appVersionId: `devver_${Date.now().toString(36)}`,\n runtimeDeploymentId: `rtdep_${Date.now().toString(36)}`,\n status: \"deployed\",\n healthChecked: args.includes(\"--wait\"),\n });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n","import { createPreviewServer, previewSurface } from \"@hyprcart/app-testing\";\nimport { success } from \"../output/envelope\";\n\nexport async function appDev(args: string[]) {\n const fixtureId = readFlag(args, \"--fixture\");\n const state = createPreviewServer();\n const preview = await previewSurface(state, \"storefront_block\", fixtureId);\n return success(\"app.dev\", {\n previewUrl: \"http://localhost:8788\",\n html: preview.html,\n diagnostics: state.diagnostics,\n remoteVersionCreated: state.remoteVersionCreated,\n });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { failure, success } from \"../output/envelope\";\nimport { isStarterTemplateKind, materializeTemplate, starterTemplate } from \"../templates/materialize\";\n\nexport async function appInit(args: string[], cwd = process.cwd()) {\n const name = positionalArgs(args)[0] ?? \"my-hyprcart-app\";\n const template = readFlag(args, \"--template\") ?? \"storefront-block\";\n if (!isStarterTemplateKind(template)) {\n return failure(\"app.init\", \"template.unsupported\", `Unsupported template: ${template}.`);\n }\n const target = join(cwd, name);\n await mkdir(target, { recursive: true });\n const files = await materializeTemplate(starterTemplate(name, template), target);\n return success(\"app.init\", { projectPath: target, template, files });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positionalArgs(args: string[]): string[] {\n return args.filter((arg, index) => !arg.startsWith(\"--\") && !args[index - 1]?.startsWith(\"--\"));\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nexport interface TemplateFile {\n path: string;\n content: string;\n}\n\nexport type StarterTemplateKind =\n | \"storefront-block\"\n | \"admin-surface\"\n | \"checkout-function\"\n | \"pixel-event\"\n | \"multi-surface\";\n\nexport function starterTemplate(appName: string, kind: StarterTemplateKind = \"storefront-block\"): TemplateFile[] {\n const surface = surfaceForTemplate(kind);\n return [\n {\n path: \"hyprcart.app.config.ts\",\n content: `export default {\n name: ${JSON.stringify(appName)},\n version: \"0.1.0\",\n manifestVersion: \"2026-06\",\n sdkVersion: \"1.0.0\",\n platformCompatibility: \"2026-06\",\n scopes: [\"product:read\"],\n surfaces: [${JSON.stringify(surface)}],\n translations: { en: { \"reviews.label\": \"Reviews\" }, de: { \"reviews.label\": \"Bewertungen\" } },\n resources: { bundleSizeBytes: 42000 }\n};\n`,\n },\n {\n path: \"package.json\",\n content: `${JSON.stringify(\n {\n name: appName,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: \"hyprcart app dev\",\n validate: \"hyprcart app validate\",\n contracts: \"hyprcart app contracts generate\",\n test: \"vitest run tests\",\n \"test:preview\": \"playwright test playwright/app-preview.spec.ts\",\n \"deploy:dev\": \"hyprcart app deploy --env development\",\n \"install-link\": \"hyprcart app install-link create\",\n },\n dependencies: {\n \"@hyprcart/app-sdk\": \"^1.0.0\",\n },\n devDependencies: {\n \"@hyprcart/cli\": \"^1.0.0\",\n \"@hyprcart/app-testing\": \"^1.0.0\",\n \"@playwright/test\": \"^1.60.0\",\n vitest: \"^4.0.18\",\n typescript: \"^5.7.2\",\n },\n },\n null,\n 2,\n )}\\n`,\n },\n { path: surface.entry, content: `export function HyprcartSurface() { return \"<section>${kind}</section>\"; }\\n` },\n { path: \"locales/en.json\", content: `${JSON.stringify({ \"reviews.label\": \"Reviews\" }, null, 2)}\\n` },\n { path: \"locales/de.json\", content: `${JSON.stringify({ \"reviews.label\": \"Bewertungen\" }, null, 2)}\\n` },\n { path: \"fixtures/product.basic.json\", content: `${JSON.stringify({ id: \"prod_1\", title: \"Deep Moisture\" }, null, 2)}\\n` },\n { path: \"tests/validation.test.ts\", content: `import { describe, expect, it } from \"vitest\";\\ndescribe(\"app\", () => { it(\"has tests\", () => expect(true).toBe(true)); });\\n` },\n {\n path: \"playwright/app-preview.spec.ts\",\n content: `import { expect, test } from \"@playwright/test\";\\n\\ntest(\"preview renders a page\", async ({ page }) => {\\n await page.goto(process.env.HYPRCART_PREVIEW_URL ?? \"http://localhost:8788\");\\n await expect(page.locator(\"body\")).toBeVisible();\\n});\\n`,\n },\n {\n path: \"README.md\",\n content: `# ${appName}\\n\\nEdit \\`hyprcart.app.config.ts\\` in your IDE, then run \\`npx hyprcart login\\` and \\`npx hyprcart app link\\` to choose an existing app, or \\`npx hyprcart app link --create\\` to create one from this project.\\n\\nRun \\`npm run dev\\`, \\`npm run validate\\`, and \\`npm run deploy:dev\\`.\\n\\nFor one-off CLI commands, use \\`npx hyprcart <command>\\` unless you installed \\`@hyprcart/cli\\` globally.\\n`,\n },\n ];\n}\n\nexport function isStarterTemplateKind(value: string): value is StarterTemplateKind {\n return [\"storefront-block\", \"admin-surface\", \"checkout-function\", \"pixel-event\", \"multi-surface\"].includes(value);\n}\n\nfunction surfaceForTemplate(kind: StarterTemplateKind) {\n if (kind === \"admin-surface\") {\n return { id: \"reviews\", type: \"admin_surface\", entry: \"src/admin/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } };\n }\n if (kind === \"checkout-function\") {\n return { id: \"reviews\", type: \"checkout_function\", entry: \"src/checkout/reviews.ts\", label: { en: \"Reviews\", de: \"Bewertungen\" } };\n }\n if (kind === \"pixel-event\") {\n return { id: \"reviews\", type: \"pixel\", entry: \"src/pixel/reviews.ts\", label: { en: \"Reviews\", de: \"Bewertungen\" } };\n }\n if (kind === \"multi-surface\") {\n return { id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } };\n }\n return { id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } };\n}\n\nexport async function materializeTemplate(files: TemplateFile[], cwd: string): Promise<string[]> {\n const written: string[] = [];\n for (const file of files) {\n const fullPath = join(cwd, file.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, file.content, { flag: \"wx\" });\n written.push(file.path);\n }\n return written;\n}\n","import { failure, success } from \"../output/envelope\";\n\nexport async function appInstallLink(args: string[]) {\n const subcommand = args[0];\n if (subcommand === \"revoke\") {\n return success(\"app.install-link.revoke\", { privateInstallUrlId: args[1], status: \"revoked\" });\n }\n\n const orgId = readFlag(args, \"--org\");\n if (!orgId) {\n return failure(\"app.install-link.create\", \"organization.missing\", \"Provide --org <orgId>.\");\n }\n\n const token = `hcdev_${Date.now().toString(36)}`;\n const privateInstallUrlId = `hcil_${Date.now().toString(36)}`;\n const installUrl = new URL(\"https://hyprcart.com/apps/install/private\");\n installUrl.searchParams.set(\"hcil\", privateInstallUrlId);\n installUrl.searchParams.set(\"token\", token);\n\n return success(\"app.install-link.create\", {\n privateInstallUrlId,\n installUrl: installUrl.toString(),\n appVersionId: readFlag(args, \"--version\") ?? \"devver_local\",\n environment: readFlag(args, \"--env\") ?? \"development\",\n allowedOrganizationId: orgId,\n allowedUserEmail: readFlag(args, \"--user\"),\n expiresAt: readFlag(args, \"--expires-at\") ?? null,\n maxUses: Number(readFlag(args, \"--max-uses\") ?? 1),\n });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n","import { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectLink {\n appId: string;\n teamId: string;\n appSlug: string;\n environment: string;\n developerApiUrl: string;\n linkedAt: string;\n previousLinks?: ProjectLink[];\n}\n\nconst linkDirectory = \".hyprcart\";\nconst linkFile = \"project.json\";\n\nexport async function readProjectLink(cwd = process.cwd()): Promise<ProjectLink | null> {\n try {\n const raw = await readFile(join(cwd, linkDirectory, linkFile), \"utf8\");\n return JSON.parse(raw) as ProjectLink;\n } catch {\n return null;\n }\n}\n\nexport async function writeProjectLink(link: ProjectLink, cwd = process.cwd(), force = false): Promise<ProjectLink> {\n const existing = await readProjectLink(cwd);\n if (existing && existing.appId !== link.appId && !force) {\n throw new Error(\"Project is already linked to another app. Re-run with --force to relink.\");\n }\n\n await mkdir(join(cwd, linkDirectory), { recursive: true });\n\n if (existing && existing.appId !== link.appId) {\n await rename(join(cwd, linkDirectory, linkFile), join(cwd, linkDirectory, `project.${Date.now()}.previous.json`));\n }\n\n const next = {\n ...link,\n previousLinks: existing && existing.appId !== link.appId ? [existing, ...(existing.previousLinks ?? [])] : existing?.previousLinks,\n };\n await writeFile(join(cwd, linkDirectory, linkFile), `${JSON.stringify(next, null, 2)}\\n`);\n return next;\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredDeveloperCredentials {\n realm: \"developer\";\n email: string | null;\n token: string;\n expiresAt: string;\n savedAt: string;\n}\n\nexport function credentialsPath(env: Record<string, string | undefined> = process.env): string {\n const base = env.HYPRCART_CONFIG_HOME ?? join(homedir(), \".hyprcart\");\n return join(base, \"credentials.json\");\n}\n\nexport async function readDeveloperCredentials(env: Record<string, string | undefined> = process.env): Promise<StoredDeveloperCredentials | null> {\n try {\n const parsed = JSON.parse(await readFile(credentialsPath(env), \"utf8\")) as StoredDeveloperCredentials;\n if (parsed.realm !== \"developer\" || !parsed.token) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function writeDeveloperCredentials(credentials: StoredDeveloperCredentials, env: Record<string, string | undefined> = process.env): Promise<void> {\n const path = credentialsPath(env);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(credentials, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport async function clearDeveloperCredentials(env: Record<string, string | undefined> = process.env): Promise<void> {\n await rm(credentialsPath(env), { force: true });\n}\n\nexport function credentialsExpired(credentials: StoredDeveloperCredentials, now = new Date()): boolean {\n return new Date(credentials.expiresAt).getTime() <= now.getTime();\n}\n","import type { AppManifest } from \"@hyprcart/app-manifest\";\n\nexport interface DeveloperCliApp {\n id: string;\n teamId: string;\n teamName: string;\n slug: string;\n displayName: string;\n status: string;\n latestDraftVersionId: string | null;\n latestValidatedVersionId: string | null;\n}\n\nexport interface DeveloperCliTeam {\n id: string;\n slug: string;\n name: string;\n role: string;\n apps: DeveloperCliApp[];\n}\n\nexport interface DeveloperCliAppsPayload {\n account: { id: string; email: string };\n teams: DeveloperCliTeam[];\n}\n\nexport async function listDeveloperApps(options: DeveloperCliApiOptions): Promise<DeveloperCliAppsPayload> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {\n method: \"GET\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n });\n return response.data as DeveloperCliAppsPayload;\n}\n\nexport async function createDeveloperApp(\n input: { teamId?: string; name: string; slug?: string; description?: string; manifest: AppManifest },\n options: DeveloperCliApiOptions,\n): Promise<DeveloperCliAppsPayload & { app: DeveloperCliApp }> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {\n method: \"POST\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n body: JSON.stringify(input),\n });\n return response.data as DeveloperCliAppsPayload & { app: DeveloperCliApp };\n}\n\nasync function callCliAppsApi(\n url: string,\n options: { method: \"GET\" | \"POST\"; token: string; fetchImpl?: typeof fetch; body?: string },\n): Promise<{ data: unknown }> {\n const response = await (options.fetchImpl ?? fetch)(url, {\n method: options.method,\n headers: {\n Authorization: `Bearer ${options.token}`,\n ...(options.body ? { \"content-type\": \"application/json\" } : {}),\n },\n body: options.body,\n });\n const payload = (await response.json().catch(() => null)) as ApiPayload | null;\n if (!response.ok || !payload?.ok) {\n const error = payload?.error;\n throw new DeveloperCliApiError(error?.code ?? \"developer_api.failed\", error?.message ?? \"Developer API request failed.\", payload?.data);\n }\n return { data: payload.data };\n}\n\nfunction developerOrigin(options: DeveloperCliApiOptions): string {\n return (options.origin ?? \"https://developer.hyprcart.com\").replace(/\\/$/, \"\");\n}\n\nexport class DeveloperCliApiError extends Error {\n constructor(\n public code: string,\n message: string,\n public data?: unknown,\n ) {\n super(message);\n }\n}\n\ntype DeveloperCliApiOptions = {\n token: string;\n origin?: string;\n fetchImpl?: typeof fetch;\n};\n\ntype ApiPayload = {\n ok: boolean;\n data?: unknown;\n error?: { code: string; message: string };\n};\n","import { failure, success } from \"../output/envelope\";\nimport { writeProjectLink } from \"../config/project-link\";\nimport { credentialsExpired, readDeveloperCredentials } from \"../auth/credentials\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { createDeveloperApp, DeveloperCliApiError, listDeveloperApps, type DeveloperCliApp, type DeveloperCliAppsPayload, type DeveloperCliTeam } from \"../api/developer-apps\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { Readable, Writable } from \"node:stream\";\n\nexport async function appLink(args: string[], cwd = process.cwd(), options: AppLinkOptions = {}) {\n const environment = readFlag(args, \"--env\") ?? \"development\";\n const developerApiUrl = readFlag(args, \"--api\") ?? \"https://developer.hyprcart.com/api/graphql\";\n const developerOrigin = readFlag(args, \"--developer-origin\") ?? \"https://developer.hyprcart.com\";\n const force = args.includes(\"--force\");\n const yes = args.includes(\"--yes\") || args.includes(\"-y\");\n const appId = readFlag(args, \"--app\");\n const explicitTeamId = readFlag(args, \"--team\");\n\n if (appId) {\n const resolved = await resolveExplicitApp(appId, explicitTeamId, developerOrigin, options);\n return writeResolvedProjectLink(resolved.app, environment, developerApiUrl, cwd, force);\n }\n\n const token = await resolveDeveloperToken(options.env);\n if (!token) {\n return failure(\"app.link\", \"auth.missing\", \"Run npx hyprcart login, then rerun npx hyprcart app link.\");\n }\n\n const manifest = (await loadProjectManifest(cwd).catch((error) => {\n throw error;\n })) ?? fallbackManifest();\n\n try {\n if (args.includes(\"--list\")) {\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl });\n return success(\"app.link.list\", payload);\n }\n\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl });\n const selected = args.includes(\"--create\")\n ? await createAppFromProject({\n args,\n manifest,\n payload,\n token,\n developerOrigin,\n fetchImpl: options.fetchImpl,\n })\n : await selectAppOrCreate({\n args,\n manifest,\n payload,\n token,\n developerOrigin,\n fetchImpl: options.fetchImpl,\n input: options.input,\n output: options.output,\n isTTY: options.isTTY ?? Boolean(process.stdin.isTTY),\n });\n\n if (!selected.ok) return selected.result;\n const confirmed = await confirmLink({\n app: selected.app,\n accountEmail: selected.accountEmail,\n yes,\n input: options.input,\n output: options.output,\n isTTY: options.isTTY ?? Boolean(process.stdin.isTTY),\n });\n if (!confirmed.ok) return confirmed.result;\n return writeResolvedProjectLink(selected.app, environment, developerApiUrl, cwd, force);\n } catch (error) {\n if (error instanceof DeveloperCliApiError) return failure(\"app.link\", error.code, error.message);\n return failure(\"app.link\", \"project.link.failed\", error instanceof Error ? error.message : \"Project link failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n const value = index >= 0 ? args[index + 1] : undefined;\n return value && !value.startsWith(\"--\") ? value : undefined;\n}\n\nasync function resolveDeveloperToken(env: Record<string, string | undefined> = process.env): Promise<string | null> {\n if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;\n const credentials = await readDeveloperCredentials(env);\n return credentials && !credentialsExpired(credentials) ? credentials.token : null;\n}\n\nasync function resolveExplicitApp(appId: string, explicitTeamId: string | undefined, developerOrigin: string, options: AppLinkOptions) {\n const token = await resolveDeveloperToken(options.env);\n if (token) {\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl }).catch(() => null);\n const app = payload ? flattenApps(payload.teams).find((candidate) => candidate.id === appId) : null;\n if (app) return { ok: true as const, app };\n }\n\n const teamId = explicitTeamId ?? \"devteam_local\";\n return {\n ok: true as const,\n app: {\n id: appId,\n teamId,\n teamName: teamId,\n slug: appId,\n displayName: appId,\n status: \"draft\",\n latestDraftVersionId: null,\n latestValidatedVersionId: null,\n },\n };\n}\n\nasync function selectAppOrCreate(input: {\n args: string[];\n manifest: ReturnType<typeof fallbackManifest>;\n payload: DeveloperCliAppsPayload;\n token: string;\n developerOrigin: string;\n fetchImpl?: typeof fetch;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}): Promise<SelectedAppResult> {\n const apps = flattenApps(input.payload.teams);\n if (!input.isTTY) {\n return {\n ok: false,\n result: failure(\n \"app.link\",\n \"app.selection_required\",\n apps.length > 0\n ? \"Choose an app with --app <appId>, or run interactively to select from your registered apps.\"\n : \"No registered apps found. Run npx hyprcart app link --create --yes to create one from this project.\",\n ),\n };\n }\n\n const rl = createInterface({\n input: input.input ?? process.stdin,\n output: input.output ?? process.stderr,\n });\n try {\n const choices = apps.map((app, index) => `${index + 1}. ${app.displayName} (${app.id}) - ${app.teamName}`);\n const createIndex = apps.length + 1;\n writeLine(input.output, `\\nHyprcart app link for ${input.payload.account.email}`);\n if (choices.length > 0) writeLine(input.output, choices.join(\"\\n\"));\n writeLine(input.output, `${createIndex}. Create new app from ${input.manifest.name}`);\n const answer = (await rl.question(`Choose an app [1-${createIndex}]: `)).trim();\n const selectedIndex = Number.parseInt(answer, 10);\n if (selectedIndex >= 1 && selectedIndex <= apps.length) {\n return { ok: true, app: apps[selectedIndex - 1]!, accountEmail: input.payload.account.email };\n }\n if (selectedIndex === createIndex) {\n return createAppFromProject(input);\n }\n return { ok: false, result: failure(\"app.link\", \"app.selection_invalid\", \"Choose a listed app number.\") };\n } finally {\n rl.close();\n }\n}\n\nasync function createAppFromProject(input: {\n args: string[];\n manifest: ReturnType<typeof fallbackManifest>;\n payload: DeveloperCliAppsPayload;\n token: string;\n developerOrigin: string;\n fetchImpl?: typeof fetch;\n}): Promise<SelectedAppResult> {\n const name = readFlag(input.args, \"--name\") ?? input.manifest.name;\n const slug = readFlag(input.args, \"--slug\");\n const teamId = readFlag(input.args, \"--team\");\n const created = await createDeveloperApp(\n {\n teamId,\n name,\n slug,\n manifest: input.manifest,\n },\n { token: input.token, origin: input.developerOrigin, fetchImpl: input.fetchImpl },\n );\n return { ok: true, app: created.app, accountEmail: created.account.email };\n}\n\nasync function confirmLink(input: {\n app: DeveloperCliApp;\n accountEmail: string;\n yes: boolean;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}) {\n if (input.yes) return { ok: true as const };\n if (!input.isTTY) {\n return { ok: false as const, result: failure(\"app.link\", \"confirmation.required\", \"Re-run with --yes to confirm linking this project to your Developer Console account.\") };\n }\n\n const rl = createInterface({\n input: input.input ?? process.stdin,\n output: input.output ?? process.stderr,\n });\n try {\n const answer = (\n await rl.question(`Link this project as ${input.accountEmail} to ${input.app.displayName} (${input.app.id})? [y/N] `)\n )\n .trim()\n .toLowerCase();\n if (answer === \"y\" || answer === \"yes\") return { ok: true as const };\n return { ok: false as const, result: failure(\"app.link\", \"confirmation.declined\", \"Project link cancelled.\") };\n } finally {\n rl.close();\n }\n}\n\nasync function writeResolvedProjectLink(app: DeveloperCliApp, environment: string, developerApiUrl: string, cwd: string, force: boolean) {\n try {\n const link = await writeProjectLink(\n {\n appId: app.id,\n teamId: app.teamId,\n appSlug: app.slug,\n environment,\n developerApiUrl,\n linkedAt: new Date().toISOString(),\n },\n cwd,\n force,\n );\n return success(\"app.link\", { ...link, appName: app.displayName, teamName: app.teamName });\n } catch (error) {\n return failure(\"app.link\", \"project.link.conflict\", error instanceof Error ? error.message : \"Project link failed.\");\n }\n}\n\nfunction flattenApps(teams: DeveloperCliTeam[]): DeveloperCliApp[] {\n return teams.flatMap((team) => team.apps);\n}\n\nfunction writeLine(output: Writable | undefined, line: string): void {\n (output ?? process.stderr).write(`${line}\\n`);\n}\n\ntype SelectedAppResult =\n | { ok: true; app: DeveloperCliApp; accountEmail: string }\n | { ok: false; result: ReturnType<typeof failure> };\n\ntype AppLinkOptions = {\n env?: Record<string, string | undefined>;\n fetchImpl?: typeof fetch;\n input?: Readable;\n output?: Writable;\n isTTY?: boolean;\n};\n","import { success } from \"../output/envelope\";\n\nexport async function appLogs() {\n return success(\"app.logs\", {\n nodes: [\n {\n requestId: \"req_local\",\n level: \"info\",\n message: \"No production logs in local CLI stub.\",\n redacted: true,\n },\n ],\n });\n}\n","import { failure, success } from \"../output/envelope\";\n\nexport async function appRollback(args: string[]) {\n const version = readFlag(args, \"--to\");\n if (!version) {\n return failure(\"app.rollback\", \"version.missing\", \"Provide --to <versionId>.\");\n }\n return success(\"app.rollback\", { status: \"rolled_back\", appVersionId: version });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n","import { success } from \"../output/envelope\";\n\nexport async function appStatus() {\n return success(\"app.status\", { environment: \"development\", status: \"deployed\" });\n}\n","import { validateManifest, type AppManifest } from \"@hyprcart/app-manifest\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function appValidate(manifest?: AppManifest) {\n const result = validateManifest(manifest ?? (await loadProjectManifest()) ?? fallbackManifest());\n return success(\"app.validate\", result);\n}\n","import { success } from \"../output/envelope\";\n\nexport async function appVersionCreate() {\n return success(\"app.version.create\", {\n appVersionId: `devver_${Date.now().toString(36)}`,\n state: \"draft\",\n runtimeDeploymentRequested: false,\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport { randomBytes } from \"node:crypto\";\nimport { writeDeveloperCredentials, type StoredDeveloperCredentials } from \"./credentials\";\n\nexport interface BrowserLoginResult {\n email: string | null;\n expiresAt: string;\n loginUrl: string;\n credentialsPathWritten: boolean;\n}\n\nexport async function runBrowserLogin(options: {\n openBrowser?: boolean;\n timeoutMs?: number;\n developerOrigin?: string;\n env?: Record<string, string | undefined>;\n onMessage?: (message: string) => void;\n} = {}): Promise<BrowserLoginResult> {\n const server = createServer();\n const state = randomBytes(24).toString(\"base64url\");\n const callback = await listenOnLoopback(server);\n const loginUrl = new URL(\"/cli/auth/start\", options.developerOrigin ?? \"https://developer.hyprcart.com\");\n loginUrl.searchParams.set(\"redirect_uri\", callback.redirectUri);\n loginUrl.searchParams.set(\"state\", state);\n\n const waitForCallback = waitForLoginCallback(server, state, options.timeoutMs ?? 180_000);\n options.onMessage?.(`Open ${loginUrl.toString()} to finish Hyprcart CLI login.`);\n if (options.openBrowser !== false) {\n openBrowser(loginUrl.toString(), options.onMessage);\n }\n\n try {\n const credentials = await waitForCallback;\n await writeDeveloperCredentials(credentials, options.env);\n return {\n email: credentials.email,\n expiresAt: credentials.expiresAt,\n loginUrl: loginUrl.toString(),\n credentialsPathWritten: true,\n };\n } finally {\n await closeServer(server);\n }\n}\n\nasync function listenOnLoopback(server: Server): Promise<{ redirectUri: string }> {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n const address = server.address();\n if (!address || typeof address === \"string\") throw new Error(\"Failed to start local login callback server.\");\n return { redirectUri: `http://127.0.0.1:${address.port}/callback` };\n}\n\nfunction waitForLoginCallback(server: Server, expectedState: string, timeoutMs: number): Promise<StoredDeveloperCredentials> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error(\"Timed out waiting for Hyprcart login callback.\")), timeoutMs);\n server.on(\"request\", (request, response) => {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n response.writeHead(404).end(\"Not found\");\n return;\n }\n\n const state = url.searchParams.get(\"state\");\n const token = url.searchParams.get(\"token\");\n const email = url.searchParams.get(\"email\");\n const expiresAt = url.searchParams.get(\"expires_at\");\n const realm = url.searchParams.get(\"realm\");\n if (state !== expectedState || !token || !expiresAt || realm !== \"developer\") {\n response.writeHead(400, { \"content-type\": \"text/html; charset=utf-8\" }).end(\"<h1>Hyprcart CLI login failed</h1><p>Invalid callback.</p>\");\n clearTimeout(timeout);\n reject(new Error(\"Invalid Hyprcart login callback.\"));\n return;\n }\n\n response\n .writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" })\n .end(\"<h1>Hyprcart CLI login complete</h1><p>You can close this tab and return to your terminal.</p>\");\n clearTimeout(timeout);\n resolve({\n realm: \"developer\",\n email,\n token,\n expiresAt,\n savedAt: new Date().toISOString(),\n });\n });\n });\n}\n\nfunction openBrowser(url: string, onMessage?: (message: string) => void): void {\n const command =\n process.platform === \"win32\"\n ? { file: \"rundll32.exe\", args: [\"url.dll,FileProtocolHandler\", url] }\n : process.platform === \"darwin\"\n ? { file: \"open\", args: [url] }\n : { file: \"xdg-open\", args: [url] };\n\n const child = spawn(command.file, command.args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => onMessage?.(`Could not open browser automatically. Open ${url} manually.`));\n child.unref();\n}\n\nasync function closeServer(server: Server): Promise<void> {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n}\n","import { clearDeveloperCredentials, credentialsExpired, readDeveloperCredentials, writeDeveloperCredentials } from \"../auth/credentials\";\nimport { runBrowserLogin } from \"../auth/browser-login\";\nimport { failure, success } from \"../output/envelope\";\n\nexport async function authCommand(command: \"login\" | \"logout\" | \"whoami\", args: string[] = []) {\n if (command === \"logout\") {\n await clearDeveloperCredentials();\n return success(\"logout\", { status: \"logged_out\" });\n }\n\n if (command === \"whoami\") {\n const stored = await readDeveloperCredentials();\n const envToken = process.env.HYPRCART_DEVELOPER_TOKEN;\n const tokenConfigured = Boolean(envToken || (stored && !credentialsExpired(stored)));\n return success(\"whoami\", {\n realm: \"developer\",\n email: process.env.HYPRCART_DEVELOPER_EMAIL ?? stored?.email ?? null,\n tokenConfigured,\n source: envToken ? \"env\" : stored ? \"credentials_file\" : \"none\",\n expiresAt: stored?.expiresAt ?? null,\n status: stored && credentialsExpired(stored) ? \"expired\" : tokenConfigured ? \"authenticated\" : \"anonymous\",\n });\n }\n\n const token = readFlag(args, \"--token\");\n if (token) {\n const email = readFlag(args, \"--email\") ?? null;\n const expiresAt = readFlag(args, \"--expires-at\") ?? new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();\n await writeDeveloperCredentials({ realm: \"developer\", token, email, expiresAt, savedAt: new Date().toISOString() });\n return success(\"login\", { realm: \"developer\", email, tokenConfigured: true, expiresAt, mode: \"token\" });\n }\n\n try {\n const result = await runBrowserLogin({\n openBrowser: !args.includes(\"--no-open\"),\n timeoutMs: Number(readFlag(args, \"--timeout-ms\") ?? 180_000),\n onMessage: (message) => process.stderr.write(`${message}\\n`),\n });\n return success(\"login\", {\n realm: \"developer\",\n email: result.email,\n tokenConfigured: true,\n expiresAt: result.expiresAt,\n loginUrl: result.loginUrl,\n mode: \"browser_callback\",\n });\n } catch (error) {\n return failure(\"login\", \"auth.login_failed\", error instanceof Error ? error.message : \"Hyprcart login failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n const value = index >= 0 ? args[index + 1] : undefined;\n return value && !value.startsWith(\"--\") ? value : undefined;\n}\n","import { success } from \"../output/envelope\";\n\nconst docsBaseUrl = \"https://developer.hyprcart.com/docs/app-platform\";\n\nexport async function docsOpen(args: string[]) {\n const topic = args[0] ?? \"overview\";\n return success(\"docs.open\", { topic, url: `${docsBaseUrl}/${topic}` });\n}\n","import { developerToolingOperationMetadata } from \"@hyprcart/app-manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function schemaExport() {\n return success(\"schema.export\", {\n schemaVersion: \"2026-06\",\n platformVersion: \"2026-06\",\n operationMetadata: developerToolingOperationMetadata,\n docsUrls: [\"https://developer.hyprcart.com/docs/app-platform\"],\n });\n}\n","import { appContracts } from \"./commands/app-contracts\";\nimport { appDeploy } from \"./commands/app-deploy\";\nimport { appDev } from \"./commands/app-dev\";\nimport { appInit } from \"./commands/app-init\";\nimport { appInstallLink } from \"./commands/app-install-link\";\nimport { appLink } from \"./commands/app-link\";\nimport { appLogs } from \"./commands/app-logs\";\nimport { appRollback } from \"./commands/app-rollback\";\nimport { appStatus } from \"./commands/app-status\";\nimport { appValidate } from \"./commands/app-validate\";\nimport { appVersionCreate } from \"./commands/app-version-create\";\nimport { authCommand } from \"./commands/auth\";\nimport { docsOpen } from \"./commands/docs-open\";\nimport { schemaExport } from \"./commands/schema-export\";\nimport { failure, type CommandEnvelope } from \"./output/envelope\";\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nexport async function runCli(argv = process.argv.slice(2)): Promise<CommandEnvelope> {\n const [root, second, third, ...rest] = argv;\n\n if (root === \"login\" || root === \"logout\" || root === \"whoami\") {\n return authCommand(root, commandArgs(second, third ? [third, ...rest] : rest));\n }\n\n if (root === \"docs\" && second === \"open\") {\n return docsOpen(commandArgs(third, rest));\n }\n\n if (root === \"schema\" && second === \"export\") {\n return schemaExport();\n }\n\n if (root !== \"app\") {\n return failure(\"unknown\", \"command.unknown\", \"Unknown command.\");\n }\n\n if (second === \"init\") return appInit(commandArgs(third, rest));\n if (second === \"list\") return appLink([\"--list\", ...commandArgs(third, rest)]);\n if (second === \"link\") return appLink(commandArgs(third, rest));\n if (second === \"dev\") return appDev(commandArgs(third, rest));\n if (second === \"validate\") return appValidate();\n if (second === \"contracts\" && third === \"generate\") return appContracts();\n if (second === \"version\" && third === \"create\") return appVersionCreate();\n if (second === \"deploy\") return appDeploy(commandArgs(third, rest));\n if (second === \"install-link\") return appInstallLink(commandArgs(third, rest));\n if (second === \"status\") return appStatus();\n if (second === \"logs\") return appLogs();\n if (second === \"rollback\") return appRollback(commandArgs(third, rest));\n\n return failure(\"app\", \"command.unknown\", \"Unknown app command.\");\n}\n\nfunction commandArgs(first: string | undefined, rest: string[]): string[] {\n return first ? [first, ...rest] : rest;\n}\n\nif (isCliEntryPoint()) {\n const result = await runCli();\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n process.exit(result.ok ? 0 : result.error?.code.startsWith(\"auth.\") ? 3 : 1);\n}\n\nexport type { CommandEnvelope };\n\nfunction isCliEntryPoint() {\n try {\n return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1] ?? \"\");\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["readFlag","mkdir","join","join","readFlag","join","mkdir","readFlag","mkdir","readFile","writeFile","join","mkdir","readFile","writeFile","dirname","join","readFlag","developerOrigin","payload","readFlag","readFlag"]}
1
+ {"version":3,"sources":["../src/commands/app-contracts.ts","../src/config/manifest.ts","../src/output/envelope.ts","../src/api/developer-apps.ts","../src/auth/credentials.ts","../src/config/project-link.ts","../src/commands/app-deploy.ts","../src/commands/app-dev.ts","../src/commands/app-init.ts","../src/templates/materialize.ts","../src/commands/app-install-link.ts","../src/commands/app-link.ts","../src/commands/app-logs.ts","../src/commands/app-rollback.ts","../src/commands/app-status.ts","../src/commands/app-validate.ts","../src/commands/app-version-create.ts","../src/auth/browser-login.ts","../src/commands/auth.ts","../src/commands/docs-open.ts","../src/commands/schema-export.ts","../src/index.ts"],"sourcesContent":["import { generateContracts, type AppManifest } from \"@hyprcart/app-manifest\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function appContracts(manifest?: AppManifest) {\n const result = generateContracts(manifest ?? (await loadProjectManifest()) ?? fallbackManifest());\n return success(\"app.contracts.generate\", result);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AppManifest } from \"@hyprcart/app-manifest\";\n\nconst manifestCandidates = [\"hyprcart.app.config.ts\", \"hyprcart.app.config.mjs\", \"hyprcart.app.config.js\", \"hyprcart.app.json\"];\n\nexport async function loadProjectManifest(cwd = process.cwd()): Promise<AppManifest | null> {\n for (const candidate of manifestCandidates) {\n const path = join(cwd, candidate);\n try {\n const source = await readFile(path, \"utf8\");\n if (candidate.endsWith(\".json\")) return JSON.parse(source) as AppManifest;\n return evaluateConfigModule(source) as AppManifest;\n } catch (error) {\n if (isMissingFileError(error)) continue;\n throw new Error(`Unable to read ${candidate}: ${error instanceof Error ? error.message : \"invalid manifest\"}`);\n }\n }\n return null;\n}\n\nexport function fallbackManifest(name = \"Local app\"): AppManifest {\n return {\n name,\n version: \"0.1.0\",\n manifestVersion: \"2026-06\",\n sdkVersion: \"1.0.0\",\n platformCompatibility: \"2026-06\",\n scopes: [\"product:read\"],\n surfaces: [{ id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } }],\n translations: { en: { \"reviews.label\": \"Reviews\" }, de: { \"reviews.label\": \"Bewertungen\" } },\n };\n}\n\nfunction evaluateConfigModule(source: string): unknown {\n const expression = source\n .replace(/^\\s*export\\s+default\\s+/m, \"return \")\n .replace(/;\\s*$/, \"\");\n if (!/^\\s*return\\s+/.test(expression)) {\n throw new Error(\"expected a default-exported manifest object\");\n }\n return new Function(expression)();\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return Boolean(error && typeof error === \"object\" && \"code\" in error && (error as { code: string }).code === \"ENOENT\");\n}\n","export interface CommandEnvelope<TData = unknown> {\n ok: boolean;\n requestId: string;\n command: string;\n data?: TData;\n error?: {\n code: string;\n message: string;\n path?: string;\n docsUrl?: string;\n };\n}\n\nexport function success<TData>(command: string, data: TData, requestId = createRequestId()): CommandEnvelope<TData> {\n return { ok: true, command, requestId, data };\n}\n\nexport function failure(command: string, code: string, message: string, requestId = createRequestId(), docsUrl?: string): CommandEnvelope {\n return {\n ok: false,\n command,\n requestId,\n error: { code, message: redactMessage(message), docsUrl },\n };\n}\n\nexport function createRequestId(): string {\n return `req_cli_${Date.now().toString(36)}`;\n}\n\nfunction redactMessage(message: string): string {\n return message\n .replace(/hcdev_[a-z0-9_]+/gi, \"[redacted]\")\n .replace(/Bearer\\s+[a-z0-9._-]+/gi, \"[redacted]\")\n .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, \"[redacted]\");\n}\n","import type { AppManifest } from \"@hyprcart/app-manifest\";\n\nexport interface DeveloperCliApp {\n id: string;\n teamId: string;\n teamName: string;\n slug: string;\n displayName: string;\n status: string;\n latestDraftVersionId: string | null;\n latestValidatedVersionId: string | null;\n}\n\nexport interface DeveloperCliTeam {\n id: string;\n slug: string;\n name: string;\n role: string;\n apps: DeveloperCliApp[];\n}\n\nexport interface DeveloperCliAppsPayload {\n account: { id: string; email: string };\n teams: DeveloperCliTeam[];\n}\n\nexport async function listDeveloperApps(options: DeveloperCliApiOptions): Promise<DeveloperCliAppsPayload> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {\n method: \"GET\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n });\n return response.data as DeveloperCliAppsPayload;\n}\n\nexport async function createDeveloperApp(\n input: { teamId?: string; name: string; slug?: string; description?: string; manifest: AppManifest },\n options: DeveloperCliApiOptions,\n): Promise<DeveloperCliAppsPayload & { app: DeveloperCliApp }> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/apps`, {\n method: \"POST\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n body: JSON.stringify(input),\n });\n return response.data as DeveloperCliAppsPayload & { app: DeveloperCliApp };\n}\n\nexport async function deployDeveloperApp(\n input: { appId: string; teamId: string; environment: string; wait: boolean; manifest: AppManifest },\n options: DeveloperCliApiOptions,\n): Promise<{\n environment: string;\n appVersionId: string;\n runtimeDeploymentId: string;\n status: string;\n healthChecked: boolean;\n}> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/deployments`, {\n method: \"POST\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n body: JSON.stringify(input),\n });\n return response.data as {\n environment: string;\n appVersionId: string;\n runtimeDeploymentId: string;\n status: string;\n healthChecked: boolean;\n };\n}\n\nexport async function createDeveloperInstallLink(\n input: {\n appId: string;\n teamId: string;\n appVersionId: string;\n environment: string;\n allowedOrganizationId: string;\n allowedUserEmail?: string;\n expiresAt?: string;\n maxUses?: number;\n },\n options: DeveloperCliApiOptions,\n): Promise<{\n privateInstallUrlId: string;\n installUrl: string;\n appVersionId: string;\n environment: string;\n allowedOrganizationId: string;\n allowedUserEmail?: string | null;\n expiresAt: string;\n maxUses: number | null;\n}> {\n const response = await callCliAppsApi(`${developerOrigin(options)}/cli/install-links`, {\n method: \"POST\",\n token: options.token,\n fetchImpl: options.fetchImpl,\n body: JSON.stringify(input),\n });\n return response.data as {\n privateInstallUrlId: string;\n installUrl: string;\n appVersionId: string;\n environment: string;\n allowedOrganizationId: string;\n allowedUserEmail?: string | null;\n expiresAt: string;\n maxUses: number | null;\n };\n}\n\nasync function callCliAppsApi(\n url: string,\n options: { method: \"GET\" | \"POST\"; token: string; fetchImpl?: typeof fetch; body?: string },\n): Promise<{ data: unknown }> {\n const response = await (options.fetchImpl ?? fetch)(url, {\n method: options.method,\n headers: {\n Authorization: `Bearer ${options.token}`,\n ...(options.body ? { \"content-type\": \"application/json\" } : {}),\n },\n body: options.body,\n });\n const payload = (await response.json().catch(() => null)) as ApiPayload | null;\n if (!response.ok || !payload?.ok) {\n const error = payload?.error;\n throw new DeveloperCliApiError(error?.code ?? \"developer_api.failed\", error?.message ?? \"Developer API request failed.\", payload?.data);\n }\n return { data: payload.data };\n}\n\nfunction developerOrigin(options: DeveloperCliApiOptions): string {\n return (options.origin ?? \"https://developer.hyprcart.com\").replace(/\\/$/, \"\");\n}\n\nexport class DeveloperCliApiError extends Error {\n constructor(\n public code: string,\n message: string,\n public data?: unknown,\n ) {\n super(message);\n }\n}\n\ntype DeveloperCliApiOptions = {\n token: string;\n origin?: string;\n fetchImpl?: typeof fetch;\n};\n\ntype ApiPayload = {\n ok: boolean;\n data?: unknown;\n error?: { code: string; message: string };\n};\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredDeveloperCredentials {\n realm: \"developer\";\n email: string | null;\n token: string;\n expiresAt: string;\n savedAt: string;\n}\n\nexport function credentialsPath(env: Record<string, string | undefined> = process.env): string {\n const base = env.HYPRCART_CONFIG_HOME ?? join(homedir(), \".hyprcart\");\n return join(base, \"credentials.json\");\n}\n\nexport async function readDeveloperCredentials(env: Record<string, string | undefined> = process.env): Promise<StoredDeveloperCredentials | null> {\n try {\n const parsed = JSON.parse(await readFile(credentialsPath(env), \"utf8\")) as StoredDeveloperCredentials;\n if (parsed.realm !== \"developer\" || !parsed.token) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function writeDeveloperCredentials(credentials: StoredDeveloperCredentials, env: Record<string, string | undefined> = process.env): Promise<void> {\n const path = credentialsPath(env);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(credentials, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport async function clearDeveloperCredentials(env: Record<string, string | undefined> = process.env): Promise<void> {\n await rm(credentialsPath(env), { force: true });\n}\n\nexport function credentialsExpired(credentials: StoredDeveloperCredentials, now = new Date()): boolean {\n return new Date(credentials.expiresAt).getTime() <= now.getTime();\n}\n","import { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectLink {\n appId: string;\n teamId: string;\n appSlug: string;\n environment: string;\n developerApiUrl: string;\n linkedAt: string;\n lastDeployment?: {\n appVersionId: string;\n runtimeDeploymentId: string;\n environment: string;\n deployedAt: string;\n };\n previousLinks?: ProjectLink[];\n}\n\nconst linkDirectory = \".hyprcart\";\nconst linkFile = \"project.json\";\n\nexport async function readProjectLink(cwd = process.cwd()): Promise<ProjectLink | null> {\n try {\n const raw = await readFile(join(cwd, linkDirectory, linkFile), \"utf8\");\n return JSON.parse(raw) as ProjectLink;\n } catch {\n return null;\n }\n}\n\nexport async function writeProjectLink(link: ProjectLink, cwd = process.cwd(), force = false): Promise<ProjectLink> {\n const existing = await readProjectLink(cwd);\n if (existing && existing.appId !== link.appId && !force) {\n throw new Error(\"Project is already linked to another app. Re-run with --force to relink.\");\n }\n\n await mkdir(join(cwd, linkDirectory), { recursive: true });\n\n if (existing && existing.appId !== link.appId) {\n await rename(join(cwd, linkDirectory, linkFile), join(cwd, linkDirectory, `project.${Date.now()}.previous.json`));\n }\n\n const next = {\n ...link,\n previousLinks: existing && existing.appId !== link.appId ? [existing, ...(existing.previousLinks ?? [])] : existing?.previousLinks,\n };\n await writeFile(join(cwd, linkDirectory, linkFile), `${JSON.stringify(next, null, 2)}\\n`);\n return next;\n}\n","import { deployDeveloperApp, DeveloperCliApiError } from \"../api/developer-apps\";\nimport { credentialsExpired, readDeveloperCredentials } from \"../auth/credentials\";\nimport { loadProjectManifest, fallbackManifest } from \"../config/manifest\";\nimport { readProjectLink, writeProjectLink } from \"../config/project-link\";\nimport { failure, success } from \"../output/envelope\";\n\nexport async function appDeploy(args: string[], cwd = process.cwd(), options: AppDeployOptions = {}) {\n const env = readFlag(args, \"--env\") ?? \"development\";\n const developerOrigin = readFlag(args, \"--developer-origin\") ?? \"https://developer.hyprcart.com\";\n const token = await resolveDeveloperToken(options.env);\n if (!token) return failure(\"app.deploy\", \"auth.missing\", \"Run npx hyprcart login before deploying.\");\n\n const link = await readProjectLink(cwd);\n if (!link) return failure(\"app.deploy\", \"project.link.missing\", \"Run npx hyprcart app link before deploying.\");\n\n const manifest = (await loadProjectManifest(cwd)) ?? fallbackManifest(link.appSlug);\n try {\n const deployed = await deployDeveloperApp(\n {\n appId: link.appId,\n teamId: link.teamId,\n environment: env,\n wait: args.includes(\"--wait\"),\n manifest,\n },\n { token, origin: developerOrigin, fetchImpl: options.fetchImpl },\n );\n await writeProjectLink(\n {\n ...link,\n environment: env,\n lastDeployment: {\n appVersionId: deployed.appVersionId,\n runtimeDeploymentId: deployed.runtimeDeploymentId,\n environment: deployed.environment,\n deployedAt: new Date().toISOString(),\n },\n },\n cwd,\n true,\n );\n return success(\"app.deploy\", deployed);\n } catch (error) {\n if (error instanceof DeveloperCliApiError) return failure(\"app.deploy\", error.code, error.message);\n return failure(\"app.deploy\", \"deploy.failed\", error instanceof Error ? error.message : \"Deploy failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nasync function resolveDeveloperToken(env: Record<string, string | undefined> = process.env): Promise<string | null> {\n if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;\n const credentials = await readDeveloperCredentials(env);\n return credentials && !credentialsExpired(credentials) ? credentials.token : null;\n}\n\ntype AppDeployOptions = {\n env?: Record<string, string | undefined>;\n fetchImpl?: typeof fetch;\n};\n","import { createPreviewServer, previewSurface } from \"@hyprcart/app-testing\";\nimport { loadProjectManifest, fallbackManifest } from \"../config/manifest\";\nimport { success } from \"../output/envelope\";\nimport { createServer, type Server } from \"node:http\";\nimport { once } from \"node:events\";\n\nexport async function appDev(args: string[], cwd = process.cwd()) {\n const fixtureId = readFlag(args, \"--fixture\");\n const port = Number(readFlag(args, \"--port\") ?? 8788);\n const host = readFlag(args, \"--host\") ?? \"127.0.0.1\";\n const state = createPreviewServer();\n const preview = await previewSurface(state, \"storefront_block\", fixtureId);\n const manifest = (await loadProjectManifest(cwd)) ?? fallbackManifest();\n const previewUrl = `http://localhost:${port}`;\n if (args.includes(\"--once\")) {\n return success(\"app.dev\", {\n previewUrl,\n html: preview.html,\n diagnostics: state.diagnostics,\n remoteVersionCreated: state.remoteVersionCreated,\n });\n }\n\n const server = createServer(async (request, response) => {\n const url = new URL(request.url ?? \"/\", previewUrl);\n if (url.pathname === \"/healthz\") {\n response.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify({ ok: true }));\n return;\n }\n if (url.pathname === \"/api/hyprcart/products\") {\n response\n .writeHead(200, { \"content-type\": \"application/json\", \"cache-control\": \"no-store\" })\n .end(JSON.stringify({ ok: true, data: { products: [{ id: \"prod_1\", title: \"Deep Moisture\", handle: \"deep-moisture\" }] } }));\n return;\n }\n response.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" }).end(renderPreviewHtml({ manifest, previewHtml: preview.html, diagnostics: state.diagnostics }));\n });\n\n await listen(server, port, host);\n process.stderr.write(`Hyprcart local preview running at ${previewUrl}\\n`);\n process.stderr.write(\"Press Ctrl+C to stop.\\n\");\n await waitForShutdown(server);\n return success(\"app.dev\", {\n previewUrl,\n html: preview.html,\n diagnostics: state.diagnostics,\n remoteVersionCreated: state.remoteVersionCreated,\n });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nasync function listen(server: Server, port: number, host: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => resolve());\n });\n}\n\nasync function waitForShutdown(server: Server): Promise<void> {\n const close = async () => {\n if (server.listening) await new Promise<void>((resolve) => server.close(() => resolve()));\n };\n const onSignal = async () => {\n await close();\n process.exit(0);\n };\n process.once(\"SIGINT\", onSignal);\n process.once(\"SIGTERM\", onSignal);\n await once(server, \"close\");\n}\n\nfunction renderPreviewHtml(input: { manifest: ReturnType<typeof fallbackManifest>; previewHtml: string; diagnostics: unknown[] }): string {\n const surfaces = input.manifest.surfaces\n .map((surface) => `<button class=\"tab\" data-surface=\"${escapeHtml(surface.type)}\">${escapeHtml(surface.label.en ?? surface.id)}</button>`)\n .join(\"\");\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>${escapeHtml(input.manifest.name)} - Hyprcart Preview</title>\n <style>\n :root { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; color: #13202d; background: #f6f8fb; }\n body { margin: 0; }\n header { border-bottom: 1px solid #dbe3ec; background: #fff; padding: 18px 24px; display: flex; justify-content: space-between; gap: 16px; align-items: center; }\n main { max-width: 1080px; margin: 0 auto; padding: 24px; display: grid; gap: 18px; }\n h1 { margin: 0; font-size: 22px; letter-spacing: 0; }\n .muted { color: #667085; }\n .tabs { display: flex; flex-wrap: wrap; gap: 8px; }\n .tab { border: 1px solid #cbd5e1; border-radius: 6px; background: #fff; padding: 8px 12px; font: inherit; }\n .grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(280px, .7fr); gap: 16px; }\n section { border: 1px solid #dbe3ec; border-radius: 8px; background: #fff; padding: 18px; min-width: 0; }\n .surface { min-height: 180px; display: grid; place-items: center; border: 1px dashed #94a3b8; border-radius: 8px; background: #f8fafc; }\n code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }\n pre { overflow: auto; background: #0f172a; color: #e2e8f0; padding: 12px; border-radius: 6px; font-size: 12px; }\n .api { display: grid; gap: 8px; }\n @media (max-width: 760px) { .grid { grid-template-columns: 1fr; } header { align-items: flex-start; flex-direction: column; } }\n </style>\n</head>\n<body>\n <header>\n <div>\n <h1>${escapeHtml(input.manifest.name)}</h1>\n <div class=\"muted\">Local Hyprcart app preview</div>\n </div>\n <div class=\"tabs\">${surfaces}</div>\n </header>\n <main>\n <div class=\"grid\">\n <section>\n <h2>Storefront surface</h2>\n <div class=\"surface\">${input.previewHtml}</div>\n </section>\n <section>\n <h2>Admin UI</h2>\n <div class=\"api\">\n <p class=\"muted\">This app can render an admin surface and call the local preview API.</p>\n <button class=\"tab\" id=\"load-products\">Call API</button>\n <pre id=\"api-output\">GET /api/hyprcart/products</pre>\n </div>\n </section>\n </div>\n <section>\n <h2>Diagnostics</h2>\n <pre>${escapeHtml(JSON.stringify(input.diagnostics, null, 2))}</pre>\n </section>\n </main>\n <script>\n document.getElementById(\"load-products\").addEventListener(\"click\", async () => {\n const response = await fetch(\"/api/hyprcart/products\");\n document.getElementById(\"api-output\").textContent = JSON.stringify(await response.json(), null, 2);\n });\n </script>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(value: unknown): string {\n return String(value)\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { failure, success } from \"../output/envelope\";\nimport { isStarterTemplateKind, materializeTemplate, starterTemplate } from \"../templates/materialize\";\n\nexport async function appInit(args: string[], cwd = process.cwd()) {\n const name = positionalArgs(args)[0] ?? \"my-hyprcart-app\";\n const template = readFlag(args, \"--template\") ?? \"storefront-block\";\n if (!isStarterTemplateKind(template)) {\n return failure(\"app.init\", \"template.unsupported\", `Unsupported template: ${template}.`);\n }\n const target = join(cwd, name);\n await mkdir(target, { recursive: true });\n const files = await materializeTemplate(starterTemplate(name, template), target);\n return success(\"app.init\", { projectPath: target, template, files });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positionalArgs(args: string[]): string[] {\n return args.filter((arg, index) => !arg.startsWith(\"--\") && !args[index - 1]?.startsWith(\"--\"));\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nexport interface TemplateFile {\n path: string;\n content: string;\n}\n\nexport type StarterTemplateKind =\n | \"storefront-block\"\n | \"admin-surface\"\n | \"checkout-function\"\n | \"pixel-event\"\n | \"multi-surface\";\n\nexport function starterTemplate(appName: string, kind: StarterTemplateKind = \"storefront-block\"): TemplateFile[] {\n const surfaces = surfacesForTemplate(kind);\n return [\n {\n path: \"hyprcart.app.config.ts\",\n content: `export default {\n name: ${JSON.stringify(appName)},\n version: \"0.1.0\",\n manifestVersion: \"2026-06\",\n sdkVersion: \"1.0.0\",\n platformCompatibility: \"2026-06\",\n scopes: [\"product:read\", \"app_installations:read\"],\n surfaces: ${JSON.stringify(surfaces)},\n translations: {\n en: { \"reviews.label\": \"Reviews\", \"reviewsAdmin.label\": \"Reviews admin\" },\n de: { \"reviews.label\": \"Bewertungen\", \"reviewsAdmin.label\": \"Bewertungen Admin\" }\n },\n resources: { bundleSizeBytes: 42000 }\n};\n`,\n },\n {\n path: \"package.json\",\n content: `${JSON.stringify(\n {\n name: appName,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: \"hyprcart app dev\",\n validate: \"hyprcart app validate\",\n contracts: \"hyprcart app contracts generate\",\n test: \"vitest run tests\",\n \"test:preview\": \"playwright test playwright/app-preview.spec.ts\",\n \"deploy:dev\": \"hyprcart app deploy --env development\",\n \"install-link\": \"hyprcart app install-link create\",\n },\n dependencies: {\n \"@hyprcart/app-sdk\": \"^1.0.0\",\n },\n devDependencies: {\n \"@hyprcart/cli\": \"^1.0.0\",\n \"@hyprcart/app-testing\": \"^1.0.0\",\n \"@playwright/test\": \"^1.60.0\",\n vitest: \"^4.0.18\",\n typescript: \"^5.7.2\",\n },\n },\n null,\n 2,\n )}\\n`,\n },\n ...surfaces.map((surface) => ({ path: surface.entry, content: sourceForSurface(surface, kind) })),\n { path: \"locales/en.json\", content: `${JSON.stringify({ \"reviews.label\": \"Reviews\", \"reviewsAdmin.label\": \"Reviews admin\" }, null, 2)}\\n` },\n { path: \"locales/de.json\", content: `${JSON.stringify({ \"reviews.label\": \"Bewertungen\", \"reviewsAdmin.label\": \"Bewertungen Admin\" }, null, 2)}\\n` },\n { path: \"fixtures/product.basic.json\", content: `${JSON.stringify({ id: \"prod_1\", title: \"Deep Moisture\" }, null, 2)}\\n` },\n { path: \"tests/validation.test.ts\", content: `import { describe, expect, it } from \"vitest\";\\ndescribe(\"app\", () => { it(\"has tests\", () => expect(true).toBe(true)); });\\n` },\n {\n path: \"playwright/app-preview.spec.ts\",\n content: `import { expect, test } from \"@playwright/test\";\\n\\ntest(\"preview renders a page\", async ({ page }) => {\\n await page.goto(process.env.HYPRCART_PREVIEW_URL ?? \"http://localhost:8788\");\\n await expect(page.locator(\"body\")).toBeVisible();\\n});\\n`,\n },\n {\n path: \"README.md\",\n content: `# ${appName}\\n\\nEdit \\`hyprcart.app.config.ts\\` in your IDE, then run \\`npx hyprcart login\\` and \\`npx hyprcart app link\\` to choose an existing app, or \\`npx hyprcart app link --create\\` to create one from this project.\\n\\nRun \\`npm run dev\\`, \\`npm run validate\\`, and \\`npm run deploy:dev\\`.\\n\\nFor one-off CLI commands, use \\`npx hyprcart <command>\\` unless you installed \\`@hyprcart/cli\\` globally.\\n`,\n },\n ];\n}\n\nexport function isStarterTemplateKind(value: string): value is StarterTemplateKind {\n return [\"storefront-block\", \"admin-surface\", \"checkout-function\", \"pixel-event\", \"multi-surface\"].includes(value);\n}\n\nfunction surfacesForTemplate(kind: StarterTemplateKind): AppTemplateSurface[] {\n if (kind === \"admin-surface\") {\n return [{ id: \"reviewsAdmin\", type: \"admin_surface\", entry: \"src/admin/reviews.tsx\", label: { en: \"Reviews admin\", de: \"Bewertungen Admin\" } }];\n }\n if (kind === \"checkout-function\") {\n return [{ id: \"reviews\", type: \"checkout_function\", entry: \"src/checkout/reviews.ts\", label: { en: \"Reviews\", de: \"Bewertungen\" } }];\n }\n if (kind === \"pixel-event\") {\n return [{ id: \"reviews\", type: \"pixel\", entry: \"src/pixel/reviews.ts\", label: { en: \"Reviews\", de: \"Bewertungen\" } }];\n }\n if (kind === \"multi-surface\") {\n return [\n { id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } },\n { id: \"reviewsAdmin\", type: \"admin_surface\", entry: \"src/admin/reviews.tsx\", label: { en: \"Reviews admin\", de: \"Bewertungen Admin\" } },\n ];\n }\n return [\n { id: \"reviews\", type: \"storefront_block\", entry: \"src/storefront/reviews.tsx\", label: { en: \"Reviews\", de: \"Bewertungen\" } },\n { id: \"reviewsAdmin\", type: \"admin_surface\", entry: \"src/admin/reviews.tsx\", label: { en: \"Reviews admin\", de: \"Bewertungen Admin\" } },\n ];\n}\n\nfunction sourceForSurface(surface: AppTemplateSurface, kind: StarterTemplateKind): string {\n if (surface.type === \"admin_surface\") {\n return `import { adminActionResponse } from \"@hyprcart/app-sdk\";\n\nexport function HyprcartAdminSurface() {\n return \"<section><h2>Reviews admin</h2><button data-action='load-products'>Load products</button></section>\";\n}\n\nexport async function loadProducts() {\n return adminActionResponse(\"products.load\", { endpoint: \"/api/hyprcart/products\", method: \"GET\" });\n}\n`;\n }\n if (surface.type === \"storefront_block\") {\n return `import { storefrontBlockResponse } from \"@hyprcart/app-sdk\";\n\nexport function HyprcartSurface() {\n return storefrontBlockResponse(\"<section><strong>Reviews badge</strong><span>Default commerce fixture</span></section>\");\n}\n`;\n }\n return `export function HyprcartSurface() { return \"<section>${kind}</section>\"; }\\n`;\n}\n\nexport async function materializeTemplate(files: TemplateFile[], cwd: string): Promise<string[]> {\n const written: string[] = [];\n for (const file of files) {\n const fullPath = join(cwd, file.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, file.content, { flag: \"wx\" });\n written.push(file.path);\n }\n return written;\n}\n\ntype AppTemplateSurface = {\n id: string;\n type: \"storefront_block\" | \"admin_surface\" | \"checkout_function\" | \"pixel\";\n entry: string;\n label: Record<string, string>;\n};\n","import { createDeveloperInstallLink, DeveloperCliApiError } from \"../api/developer-apps\";\nimport { credentialsExpired, readDeveloperCredentials } from \"../auth/credentials\";\nimport { readProjectLink } from \"../config/project-link\";\nimport { failure, success } from \"../output/envelope\";\n\nexport async function appInstallLink(args: string[], cwd = process.cwd(), options: AppInstallLinkOptions = {}) {\n const subcommand = args[0];\n if (subcommand === \"revoke\") {\n return success(\"app.install-link.revoke\", { privateInstallUrlId: args[1], status: \"revoked\" });\n }\n\n const developerOrigin = readFlag(args, \"--developer-origin\") ?? \"https://developer.hyprcart.com\";\n const orgId = readFlag(args, \"--org\");\n if (!orgId) {\n return failure(\"app.install-link.create\", \"organization.missing\", \"Provide --org <orgId>.\");\n }\n\n const token = await resolveDeveloperToken(options.env);\n if (!token) return failure(\"app.install-link.create\", \"auth.missing\", \"Run npx hyprcart login before creating an install link.\");\n\n const link = await readProjectLink(cwd);\n if (!link) return failure(\"app.install-link.create\", \"project.link.missing\", \"Run npx hyprcart app link before creating an install link.\");\n\n const appVersionId = readFlag(args, \"--version\") ?? link.lastDeployment?.appVersionId;\n if (!appVersionId) return failure(\"app.install-link.create\", \"version.missing\", \"Run npx hyprcart app deploy --env development --wait before creating an install link, or pass --version <versionId>.\");\n\n try {\n const created = await createDeveloperInstallLink(\n {\n appId: link.appId,\n teamId: link.teamId,\n appVersionId,\n environment: readFlag(args, \"--env\") ?? link.lastDeployment?.environment ?? link.environment ?? \"development\",\n allowedOrganizationId: orgId,\n allowedUserEmail: readFlag(args, \"--user\"),\n expiresAt: readFlag(args, \"--expires-at\"),\n maxUses: Number(readFlag(args, \"--max-uses\") ?? 1),\n },\n { token, origin: developerOrigin, fetchImpl: options.fetchImpl },\n );\n\n return success(\"app.install-link.create\", created);\n } catch (error) {\n if (error instanceof DeveloperCliApiError) return failure(\"app.install-link.create\", error.code, error.message);\n return failure(\"app.install-link.create\", \"install_link.failed\", error instanceof Error ? error.message : \"Install link creation failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nasync function resolveDeveloperToken(env: Record<string, string | undefined> = process.env): Promise<string | null> {\n if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;\n const credentials = await readDeveloperCredentials(env);\n return credentials && !credentialsExpired(credentials) ? credentials.token : null;\n}\n\ntype AppInstallLinkOptions = {\n env?: Record<string, string | undefined>;\n fetchImpl?: typeof fetch;\n};\n","import { failure, success } from \"../output/envelope\";\nimport { writeProjectLink } from \"../config/project-link\";\nimport { credentialsExpired, readDeveloperCredentials } from \"../auth/credentials\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { createDeveloperApp, DeveloperCliApiError, listDeveloperApps, type DeveloperCliApp, type DeveloperCliAppsPayload, type DeveloperCliTeam } from \"../api/developer-apps\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { Readable, Writable } from \"node:stream\";\n\nexport async function appLink(args: string[], cwd = process.cwd(), options: AppLinkOptions = {}) {\n const environment = readFlag(args, \"--env\") ?? \"development\";\n const developerApiUrl = readFlag(args, \"--api\") ?? \"https://developer.hyprcart.com/api/graphql\";\n const developerOrigin = readFlag(args, \"--developer-origin\") ?? \"https://developer.hyprcart.com\";\n const force = args.includes(\"--force\");\n const yes = args.includes(\"--yes\") || args.includes(\"-y\");\n const appId = readFlag(args, \"--app\");\n const explicitTeamId = readFlag(args, \"--team\");\n\n if (appId) {\n const resolved = await resolveExplicitApp(appId, explicitTeamId, developerOrigin, options);\n return writeResolvedProjectLink(resolved.app, environment, developerApiUrl, cwd, force);\n }\n\n const token = await resolveDeveloperToken(options.env);\n if (!token) {\n return failure(\"app.link\", \"auth.missing\", \"Run npx hyprcart login, then rerun npx hyprcart app link.\");\n }\n\n const manifest = (await loadProjectManifest(cwd).catch((error) => {\n throw error;\n })) ?? fallbackManifest();\n\n try {\n if (args.includes(\"--list\")) {\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl });\n return success(\"app.link.list\", payload);\n }\n\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl });\n const selected = args.includes(\"--create\")\n ? await createAppFromProject({\n args,\n manifest,\n payload,\n token,\n developerOrigin,\n fetchImpl: options.fetchImpl,\n input: options.input,\n output: options.output,\n isTTY: options.isTTY ?? Boolean(process.stdin.isTTY),\n })\n : await selectAppOrCreate({\n args,\n manifest,\n payload,\n token,\n developerOrigin,\n fetchImpl: options.fetchImpl,\n input: options.input,\n output: options.output,\n isTTY: options.isTTY ?? Boolean(process.stdin.isTTY),\n });\n\n if (!selected.ok) return selected.result;\n const confirmed = await confirmLink({\n app: selected.app,\n accountEmail: selected.accountEmail,\n yes,\n input: options.input,\n output: options.output,\n isTTY: options.isTTY ?? Boolean(process.stdin.isTTY),\n });\n if (!confirmed.ok) return confirmed.result;\n return writeResolvedProjectLink(selected.app, environment, developerApiUrl, cwd, force);\n } catch (error) {\n if (error instanceof DeveloperCliApiError) return failure(\"app.link\", error.code, error.message);\n return failure(\"app.link\", \"project.link.failed\", error instanceof Error ? error.message : \"Project link failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n const value = index >= 0 ? args[index + 1] : undefined;\n return value && !value.startsWith(\"--\") ? value : undefined;\n}\n\nasync function resolveDeveloperToken(env: Record<string, string | undefined> = process.env): Promise<string | null> {\n if (env.HYPRCART_DEVELOPER_TOKEN) return env.HYPRCART_DEVELOPER_TOKEN;\n const credentials = await readDeveloperCredentials(env);\n return credentials && !credentialsExpired(credentials) ? credentials.token : null;\n}\n\nasync function resolveExplicitApp(appId: string, explicitTeamId: string | undefined, developerOrigin: string, options: AppLinkOptions) {\n const token = await resolveDeveloperToken(options.env);\n if (token) {\n const payload = await listDeveloperApps({ token, origin: developerOrigin, fetchImpl: options.fetchImpl }).catch(() => null);\n const app = payload ? flattenApps(payload.teams).find((candidate) => candidate.id === appId) : null;\n if (app) return { ok: true as const, app };\n }\n\n const teamId = explicitTeamId ?? \"devteam_local\";\n return {\n ok: true as const,\n app: {\n id: appId,\n teamId,\n teamName: teamId,\n slug: appId,\n displayName: appId,\n status: \"draft\",\n latestDraftVersionId: null,\n latestValidatedVersionId: null,\n },\n };\n}\n\nasync function selectAppOrCreate(input: {\n args: string[];\n manifest: ReturnType<typeof fallbackManifest>;\n payload: DeveloperCliAppsPayload;\n token: string;\n developerOrigin: string;\n fetchImpl?: typeof fetch;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}): Promise<SelectedAppResult> {\n const apps = flattenApps(input.payload.teams);\n if (!input.isTTY) {\n return {\n ok: false,\n result: failure(\n \"app.link\",\n \"app.selection_required\",\n apps.length > 0\n ? \"Choose an app with --app <appId>, or run interactively to select from your registered apps.\"\n : \"No registered apps found. Run npx hyprcart app link --create --yes to create one from this project.\",\n ),\n };\n }\n\n const rl = createInterface({\n input: input.input ?? process.stdin,\n output: input.output ?? process.stderr,\n });\n let selectedIndex = Number.NaN;\n try {\n const choices = apps.map((app, index) => `${index + 1}. ${app.displayName} (${app.id}) - ${app.teamName}`);\n const createIndex = apps.length + 1;\n writeLine(input.output, `\\nHyprcart app link for ${input.payload.account.email}`);\n if (choices.length > 0) writeLine(input.output, choices.join(\"\\n\"));\n writeLine(input.output, `${createIndex}. Create new app from ${input.manifest.name}`);\n const answer = (await rl.question(`Choose an app [1-${createIndex}]: `)).trim();\n selectedIndex = Number.parseInt(answer, 10);\n } finally {\n rl.close();\n }\n\n if (selectedIndex >= 1 && selectedIndex <= apps.length) {\n return { ok: true, app: apps[selectedIndex - 1]!, accountEmail: input.payload.account.email };\n }\n if (selectedIndex === apps.length + 1) {\n return createAppFromProject(input);\n }\n return { ok: false, result: failure(\"app.link\", \"app.selection_invalid\", \"Choose a listed app number.\") };\n}\n\nasync function createAppFromProject(input: {\n args: string[];\n manifest: ReturnType<typeof fallbackManifest>;\n payload: DeveloperCliAppsPayload;\n token: string;\n developerOrigin: string;\n fetchImpl?: typeof fetch;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}): Promise<SelectedAppResult> {\n const name = readFlag(input.args, \"--name\") ?? input.manifest.name;\n const slug = readFlag(input.args, \"--slug\");\n const team = await resolveTeamForCreate(input);\n if (!team.ok) return team;\n const created = await createDeveloperApp(\n {\n teamId: team.teamId,\n name,\n slug,\n manifest: input.manifest,\n },\n { token: input.token, origin: input.developerOrigin, fetchImpl: input.fetchImpl },\n );\n return { ok: true, app: created.app, accountEmail: created.account.email };\n}\n\nasync function resolveTeamForCreate(input: {\n args: string[];\n payload: DeveloperCliAppsPayload;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}): Promise<{ ok: true; teamId: string } | { ok: false; result: ReturnType<typeof failure> }> {\n const explicitTeamId = readFlag(input.args, \"--team\");\n if (explicitTeamId) return { ok: true, teamId: explicitTeamId };\n\n if (input.payload.teams.length === 0) {\n return { ok: false, result: failure(\"app.link\", \"team.missing\", \"Create or join a Developer Console team before creating an app from this project.\") };\n }\n if (input.payload.teams.length === 1) {\n return { ok: true, teamId: input.payload.teams[0]!.id };\n }\n if (!input.isTTY) {\n return { ok: false, result: failure(\"app.link\", \"team.selection_required\", \"Choose which developer team should own the new app with --team <teamId>, or run interactively to select one.\") };\n }\n\n const rl = createInterface({\n input: input.input ?? process.stdin,\n output: input.output ?? process.stderr,\n });\n try {\n writeLine(input.output, \"\\nChoose a developer team for the new app\");\n input.payload.teams.forEach((team, index) => writeLine(input.output, `${index + 1}. ${team.name} (${team.id})`));\n const answer = (await rl.question(`Choose a team [1-${input.payload.teams.length}]: `)).trim();\n const selectedIndex = Number.parseInt(answer, 10);\n const selectedTeam = input.payload.teams[selectedIndex - 1];\n if (!selectedTeam) {\n return { ok: false, result: failure(\"app.link\", \"team.selection_invalid\", \"Choose a listed developer team number.\") };\n }\n return { ok: true, teamId: selectedTeam.id };\n } finally {\n rl.close();\n }\n}\n\nasync function confirmLink(input: {\n app: DeveloperCliApp;\n accountEmail: string;\n yes: boolean;\n input?: Readable;\n output?: Writable;\n isTTY: boolean;\n}) {\n if (input.yes) return { ok: true as const };\n if (!input.isTTY) {\n return { ok: false as const, result: failure(\"app.link\", \"confirmation.required\", \"Re-run with --yes to confirm linking this project to your Developer Console account.\") };\n }\n\n const rl = createInterface({\n input: input.input ?? process.stdin,\n output: input.output ?? process.stderr,\n });\n try {\n const answer = (\n await rl.question(`Link this project as ${input.accountEmail} to ${input.app.displayName} (${input.app.id})? [y/N] `)\n )\n .trim()\n .toLowerCase();\n if (answer === \"y\" || answer === \"yes\") return { ok: true as const };\n return { ok: false as const, result: failure(\"app.link\", \"confirmation.declined\", \"Project link cancelled.\") };\n } finally {\n rl.close();\n }\n}\n\nasync function writeResolvedProjectLink(app: DeveloperCliApp, environment: string, developerApiUrl: string, cwd: string, force: boolean) {\n try {\n const link = await writeProjectLink(\n {\n appId: app.id,\n teamId: app.teamId,\n appSlug: app.slug,\n environment,\n developerApiUrl,\n linkedAt: new Date().toISOString(),\n },\n cwd,\n force,\n );\n return success(\"app.link\", { ...link, appName: app.displayName, teamName: app.teamName });\n } catch (error) {\n return failure(\"app.link\", \"project.link.conflict\", error instanceof Error ? error.message : \"Project link failed.\");\n }\n}\n\nfunction flattenApps(teams: DeveloperCliTeam[]): DeveloperCliApp[] {\n return teams.flatMap((team) => team.apps);\n}\n\nfunction writeLine(output: Writable | undefined, line: string): void {\n (output ?? process.stderr).write(`${line}\\n`);\n}\n\ntype SelectedAppResult =\n | { ok: true; app: DeveloperCliApp; accountEmail: string }\n | { ok: false; result: ReturnType<typeof failure> };\n\ntype AppLinkOptions = {\n env?: Record<string, string | undefined>;\n fetchImpl?: typeof fetch;\n input?: Readable;\n output?: Writable;\n isTTY?: boolean;\n};\n","import { success } from \"../output/envelope\";\n\nexport async function appLogs() {\n return success(\"app.logs\", {\n nodes: [\n {\n requestId: \"req_local\",\n level: \"info\",\n message: \"No production logs in local CLI stub.\",\n redacted: true,\n },\n ],\n });\n}\n","import { failure, success } from \"../output/envelope\";\n\nexport async function appRollback(args: string[]) {\n const version = readFlag(args, \"--to\");\n if (!version) {\n return failure(\"app.rollback\", \"version.missing\", \"Provide --to <versionId>.\");\n }\n return success(\"app.rollback\", { status: \"rolled_back\", appVersionId: version });\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n","import { success } from \"../output/envelope\";\n\nexport async function appStatus() {\n return success(\"app.status\", { environment: \"development\", status: \"deployed\" });\n}\n","import { validateManifest, type AppManifest } from \"@hyprcart/app-manifest\";\nimport { fallbackManifest, loadProjectManifest } from \"../config/manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function appValidate(manifest?: AppManifest) {\n const result = validateManifest(manifest ?? (await loadProjectManifest()) ?? fallbackManifest());\n return success(\"app.validate\", result);\n}\n","import { success } from \"../output/envelope\";\n\nexport async function appVersionCreate() {\n return success(\"app.version.create\", {\n appVersionId: `devver_${Date.now().toString(36)}`,\n state: \"draft\",\n runtimeDeploymentRequested: false,\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport { randomBytes } from \"node:crypto\";\nimport { writeDeveloperCredentials, type StoredDeveloperCredentials } from \"./credentials\";\n\nexport interface BrowserLoginResult {\n email: string | null;\n expiresAt: string;\n loginUrl: string;\n credentialsPathWritten: boolean;\n}\n\nexport async function runBrowserLogin(options: {\n openBrowser?: boolean;\n timeoutMs?: number;\n developerOrigin?: string;\n env?: Record<string, string | undefined>;\n onMessage?: (message: string) => void;\n} = {}): Promise<BrowserLoginResult> {\n const server = createServer();\n const state = randomBytes(24).toString(\"base64url\");\n const callback = await listenOnLoopback(server);\n const loginUrl = new URL(\"/cli/auth/start\", options.developerOrigin ?? \"https://developer.hyprcart.com\");\n loginUrl.searchParams.set(\"redirect_uri\", callback.redirectUri);\n loginUrl.searchParams.set(\"state\", state);\n\n const waitForCallback = waitForLoginCallback(server, state, options.timeoutMs ?? 180_000);\n options.onMessage?.(`Open ${loginUrl.toString()} to finish Hyprcart CLI login.`);\n if (options.openBrowser !== false) {\n openBrowser(loginUrl.toString(), options.onMessage);\n }\n\n try {\n const credentials = await waitForCallback;\n await writeDeveloperCredentials(credentials, options.env);\n return {\n email: credentials.email,\n expiresAt: credentials.expiresAt,\n loginUrl: loginUrl.toString(),\n credentialsPathWritten: true,\n };\n } finally {\n await closeServer(server);\n }\n}\n\nasync function listenOnLoopback(server: Server): Promise<{ redirectUri: string }> {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n const address = server.address();\n if (!address || typeof address === \"string\") throw new Error(\"Failed to start local login callback server.\");\n return { redirectUri: `http://127.0.0.1:${address.port}/callback` };\n}\n\nfunction waitForLoginCallback(server: Server, expectedState: string, timeoutMs: number): Promise<StoredDeveloperCredentials> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error(\"Timed out waiting for Hyprcart login callback.\")), timeoutMs);\n server.on(\"request\", (request, response) => {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n response.writeHead(404).end(\"Not found\");\n return;\n }\n\n const state = url.searchParams.get(\"state\");\n const token = url.searchParams.get(\"token\");\n const email = url.searchParams.get(\"email\");\n const expiresAt = url.searchParams.get(\"expires_at\");\n const realm = url.searchParams.get(\"realm\");\n if (state !== expectedState || !token || !expiresAt || realm !== \"developer\") {\n response.writeHead(400, { \"content-type\": \"text/html; charset=utf-8\" }).end(\"<h1>Hyprcart CLI login failed</h1><p>Invalid callback.</p>\");\n clearTimeout(timeout);\n reject(new Error(\"Invalid Hyprcart login callback.\"));\n return;\n }\n\n response\n .writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" })\n .end(\"<h1>Hyprcart CLI login complete</h1><p>You can close this tab and return to your terminal.</p>\");\n clearTimeout(timeout);\n resolve({\n realm: \"developer\",\n email,\n token,\n expiresAt,\n savedAt: new Date().toISOString(),\n });\n });\n });\n}\n\nfunction openBrowser(url: string, onMessage?: (message: string) => void): void {\n const command =\n process.platform === \"win32\"\n ? { file: \"rundll32.exe\", args: [\"url.dll,FileProtocolHandler\", url] }\n : process.platform === \"darwin\"\n ? { file: \"open\", args: [url] }\n : { file: \"xdg-open\", args: [url] };\n\n const child = spawn(command.file, command.args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => onMessage?.(`Could not open browser automatically. Open ${url} manually.`));\n child.unref();\n}\n\nasync function closeServer(server: Server): Promise<void> {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n}\n","import { clearDeveloperCredentials, credentialsExpired, readDeveloperCredentials, writeDeveloperCredentials } from \"../auth/credentials\";\nimport { runBrowserLogin } from \"../auth/browser-login\";\nimport { failure, success } from \"../output/envelope\";\n\nexport async function authCommand(command: \"login\" | \"logout\" | \"whoami\", args: string[] = []) {\n if (command === \"logout\") {\n await clearDeveloperCredentials();\n return success(\"logout\", { status: \"logged_out\" });\n }\n\n if (command === \"whoami\") {\n const stored = await readDeveloperCredentials();\n const envToken = process.env.HYPRCART_DEVELOPER_TOKEN;\n const tokenConfigured = Boolean(envToken || (stored && !credentialsExpired(stored)));\n return success(\"whoami\", {\n realm: \"developer\",\n email: process.env.HYPRCART_DEVELOPER_EMAIL ?? stored?.email ?? null,\n tokenConfigured,\n source: envToken ? \"env\" : stored ? \"credentials_file\" : \"none\",\n expiresAt: stored?.expiresAt ?? null,\n status: stored && credentialsExpired(stored) ? \"expired\" : tokenConfigured ? \"authenticated\" : \"anonymous\",\n });\n }\n\n const token = readFlag(args, \"--token\");\n if (token) {\n const email = readFlag(args, \"--email\") ?? null;\n const expiresAt = readFlag(args, \"--expires-at\") ?? new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();\n await writeDeveloperCredentials({ realm: \"developer\", token, email, expiresAt, savedAt: new Date().toISOString() });\n return success(\"login\", { realm: \"developer\", email, tokenConfigured: true, expiresAt, mode: \"token\" });\n }\n\n try {\n const result = await runBrowserLogin({\n openBrowser: !args.includes(\"--no-open\"),\n timeoutMs: Number(readFlag(args, \"--timeout-ms\") ?? 180_000),\n onMessage: (message) => process.stderr.write(`${message}\\n`),\n });\n return success(\"login\", {\n realm: \"developer\",\n email: result.email,\n tokenConfigured: true,\n expiresAt: result.expiresAt,\n loginUrl: result.loginUrl,\n mode: \"browser_callback\",\n });\n } catch (error) {\n return failure(\"login\", \"auth.login_failed\", error instanceof Error ? error.message : \"Hyprcart login failed.\");\n }\n}\n\nfunction readFlag(args: string[], name: string): string | undefined {\n const index = args.indexOf(name);\n const value = index >= 0 ? args[index + 1] : undefined;\n return value && !value.startsWith(\"--\") ? value : undefined;\n}\n","import { success } from \"../output/envelope\";\n\nconst docsBaseUrl = \"https://developer.hyprcart.com/docs/app-platform\";\n\nexport async function docsOpen(args: string[]) {\n const topic = args[0] ?? \"overview\";\n return success(\"docs.open\", { topic, url: `${docsBaseUrl}/${topic}` });\n}\n","import { developerToolingOperationMetadata } from \"@hyprcart/app-manifest\";\nimport { success } from \"../output/envelope\";\n\nexport async function schemaExport() {\n return success(\"schema.export\", {\n schemaVersion: \"2026-06\",\n platformVersion: \"2026-06\",\n operationMetadata: developerToolingOperationMetadata,\n docsUrls: [\"https://developer.hyprcart.com/docs/app-platform\"],\n });\n}\n","import { appContracts } from \"./commands/app-contracts\";\nimport { appDeploy } from \"./commands/app-deploy\";\nimport { appDev } from \"./commands/app-dev\";\nimport { appInit } from \"./commands/app-init\";\nimport { appInstallLink } from \"./commands/app-install-link\";\nimport { appLink } from \"./commands/app-link\";\nimport { appLogs } from \"./commands/app-logs\";\nimport { appRollback } from \"./commands/app-rollback\";\nimport { appStatus } from \"./commands/app-status\";\nimport { appValidate } from \"./commands/app-validate\";\nimport { appVersionCreate } from \"./commands/app-version-create\";\nimport { authCommand } from \"./commands/auth\";\nimport { docsOpen } from \"./commands/docs-open\";\nimport { schemaExport } from \"./commands/schema-export\";\nimport { failure, type CommandEnvelope } from \"./output/envelope\";\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nexport async function runCli(argv = process.argv.slice(2)): Promise<CommandEnvelope> {\n const [root, second, third, ...rest] = argv;\n\n if (root === \"login\" || root === \"logout\" || root === \"whoami\") {\n return authCommand(root, commandArgs(second, third ? [third, ...rest] : rest));\n }\n\n if (root === \"docs\" && second === \"open\") {\n return docsOpen(commandArgs(third, rest));\n }\n\n if (root === \"schema\" && second === \"export\") {\n return schemaExport();\n }\n\n if (root !== \"app\") {\n return failure(\"unknown\", \"command.unknown\", \"Unknown command.\");\n }\n\n if (second === \"init\") return appInit(commandArgs(third, rest));\n if (second === \"list\") return appLink([\"--list\", ...commandArgs(third, rest)]);\n if (second === \"link\") return appLink(commandArgs(third, rest));\n if (second === \"dev\") return appDev(commandArgs(third, rest));\n if (second === \"validate\") return appValidate();\n if (second === \"contracts\" && third === \"generate\") return appContracts();\n if (second === \"version\" && third === \"create\") return appVersionCreate();\n if (second === \"deploy\") return appDeploy(commandArgs(third, rest));\n if (second === \"install-link\") return appInstallLink(commandArgs(third, rest));\n if (second === \"status\") return appStatus();\n if (second === \"logs\") return appLogs();\n if (second === \"rollback\") return appRollback(commandArgs(third, rest));\n\n return failure(\"app\", \"command.unknown\", \"Unknown app command.\");\n}\n\nfunction commandArgs(first: string | undefined, rest: string[]): string[] {\n return first ? [first, ...rest] : rest;\n}\n\nif (isCliEntryPoint()) {\n const result = await runCli();\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n process.exit(result.ok ? 0 : result.error?.code.startsWith(\"auth.\") ? 3 : 1);\n}\n\nexport type { CommandEnvelope };\n\nfunction isCliEntryPoint() {\n try {\n return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1] ?? \"\");\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["readFile","join","mkdir","readFile","writeFile","join","developerOrigin","readFlag","mkdir","join","mkdir","writeFile","dirname","join","readFlag","join","mkdir","developerOrigin","readFlag","resolveDeveloperToken","readFlag","developerOrigin","resolveDeveloperToken","payload","readFlag","createServer","createServer","readFlag"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyprcart/cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Command line interface for building, validating, deploying, and installing Hyprcart apps.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -24,8 +24,8 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@hyprcart/app-manifest": "1.0.0",
28
27
  "@hyprcart/app-sdk": "1.0.0",
28
+ "@hyprcart/app-manifest": "1.0.0",
29
29
  "@hyprcart/app-testing": "1.0.0"
30
30
  },
31
31
  "devDependencies": {