veryfront 0.1.1021 → 0.1.1023

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.
@@ -1 +1 @@
1
- {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/open/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WAgBtB,CAAC"}
1
+ {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/open/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WAqBtB,CAAC"}
@@ -4,12 +4,17 @@ export const openHelp = {
4
4
  description: "Open project URLs in the browser",
5
5
  usage: "veryfront open [options]",
6
6
  options: [
7
+ {
8
+ flag: "-p, --project-slug <slug>",
9
+ description: "Project slug to open (overrides inferred project)",
10
+ },
7
11
  { flag: "--env <name>", description: "Open a specific environment URL" },
8
12
  { flag: "--studio", description: "Open Veryfront Studio" },
9
13
  { flag: "--json", description: "Output URL as JSON instead of opening" },
10
14
  ],
11
15
  examples: [
12
16
  "veryfront open",
17
+ "veryfront open -p my-project",
13
18
  "veryfront open --env staging",
14
19
  "veryfront open --studio",
15
20
  "veryfront open --json",
@@ -1 +1 @@
1
- {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WAqDtB,CAAC"}
1
+ {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WA2DtB,CAAC"}
@@ -2,8 +2,12 @@ export const pullHelp = {
2
2
  name: "pull",
3
3
  category: "deploy",
4
4
  description: "Download project files from Veryfront remote",
5
- usage: "veryfront pull [options]",
5
+ usage: "veryfront pull [project-slug] [options]",
6
6
  options: [
7
+ {
8
+ flag: "-p, --project-slug <slug>",
9
+ description: "Project slug to pull (overrides inferred project)",
10
+ },
7
11
  {
8
12
  flag: "--projects <slugs>",
9
13
  description: "Comma-separated list of project slugs to pull",
@@ -35,6 +39,8 @@ export const pullHelp = {
35
39
  ],
36
40
  examples: [
37
41
  "veryfront pull",
42
+ "veryfront pull veryfront-based-38c7d03a",
43
+ "veryfront pull -p veryfront-based-38c7d03a --dir ./veryfront-based",
38
44
  "veryfront pull --dir ./my-project",
39
45
  "veryfront pull --branch feature-header",
40
46
  "veryfront pull --env production",
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAM3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAOhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;GAY7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;GAUxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA2CD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAQjB;AA8ID;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuGpE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAM3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAgBhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;GAY7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;GAUxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAwND;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8IpE"}
@@ -13,9 +13,11 @@ import { resolveCliApiUrl } from "../../shared/constants.js";
13
13
  import { cwd } from "../../../src/platform/index.js";
14
14
  import { createFileSystem } from "../../../src/platform/index.js";
15
15
  import { createApiClient, readConfigFile, resolveConfigWithAuth, } from "../../shared/config.js";
16
- import { confirmPrompt, logInfo, logSuccess, logWarning } from "../../utils/index.js";
16
+ import { confirmPrompt, isTTY, logInfo, logSuccess, logWarning } from "../../utils/index.js";
17
17
  import { createNoopSpinner, createSpinner } from "../../ui/index.js";
18
+ import { isInteractive } from "../../shared/interactive.js";
18
19
  import { getApiTokenEnv, getEnvironmentConfig } from "../../../src/config/index.js";
20
+ import { ERROR_REGISTRY, getErrorBySlug, INVALID_ARGUMENT, RESOURCE_NOT_FOUND, VeryfrontError, } from "../../../src/errors/index.js";
19
21
  import { withSpan } from "../../../src/observability/tracing/otlp-setup.js";
20
22
  import { CommonArgs, createArgParser } from "../../shared/args.js";
21
23
  /**
@@ -195,6 +197,41 @@ function formatPullSource(source) {
195
197
  return "main";
196
198
  }
197
199
  }
200
+ function describeError(error) {
201
+ return error instanceof Error ? error.message : String(error);
202
+ }
203
+ function errorStatus(error) {
204
+ const status = error?.status;
205
+ return typeof status === "number" ? status : undefined;
206
+ }
207
+ function errorSlug(error) {
208
+ const slug = error?.slug;
209
+ return typeof slug === "string" ? slug : undefined;
210
+ }
211
+ function pullProjectListError(projectSlug, sourceLabel, error) {
212
+ const message = [
213
+ `Failed to list files for project "${projectSlug}" from ${sourceLabel}: ${describeError(error)}.`,
214
+ "Check that the project slug is exact, the selected branch/env/release exists, and your token has access.",
215
+ ].join(" ");
216
+ const status = errorStatus(error);
217
+ if (status === 404) {
218
+ return RESOURCE_NOT_FOUND.create({ detail: message, cause: error, status });
219
+ }
220
+ const wrapped = new Error(message, { cause: error });
221
+ if (typeof status === "number") {
222
+ wrapped.status = status;
223
+ }
224
+ return wrapped;
225
+ }
226
+ async function confirmPullWrite(projectDir) {
227
+ if (isInteractive() && !isTTY()) {
228
+ throw INVALID_ARGUMENT.create({
229
+ detail: `Pull requires confirmation before writing files, but no interactive prompt is available. ` +
230
+ `Re-run with --force to write into ${projectDir} without prompting.`,
231
+ });
232
+ }
233
+ return await confirmPrompt(`This will overwrite local files in ${projectDir}. Continue?`, false);
234
+ }
198
235
  async function pullSingleProject(projectSlug, projectDir, source, force, dryRun, config, quiet = false) {
199
236
  const sourceLabel = formatPullSource(source);
200
237
  let spinner = quiet
@@ -205,13 +242,16 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
205
242
  try {
206
243
  files = await listAllFiles(client, projectSlug, source);
207
244
  }
245
+ catch (error) {
246
+ throw pullProjectListError(projectSlug, sourceLabel, error);
247
+ }
208
248
  finally {
209
249
  spinner.stop();
210
250
  }
211
251
  if (files.length === 0) {
212
252
  if (!quiet)
213
253
  logInfo(`No files to pull from ${projectSlug}.`);
214
- return { written: 0, skipped: 0 };
254
+ return { written: 0, skipped: 0, cancelled: false };
215
255
  }
216
256
  const writeOps = [];
217
257
  for (const file of files) {
@@ -227,10 +267,10 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
227
267
  cliLogger.info(`\nFound ${files.length} files to ${dryRun ? "pull" : "write"} from ${projectSlug}.`);
228
268
  }
229
269
  if (!force && !dryRun) {
230
- const confirmed = await confirmPrompt(`This will overwrite local files in ${projectDir}. Continue?`, false);
270
+ const confirmed = await confirmPullWrite(projectDir);
231
271
  if (!confirmed) {
232
272
  cliLogger.info("Pull cancelled.");
233
- return { written: 0, skipped: 0 };
273
+ return { written: 0, skipped: 0, cancelled: true };
234
274
  }
235
275
  }
236
276
  spinner = quiet ? createNoopSpinner() : createSpinner(`Writing files to ${projectDir}...`);
@@ -246,7 +286,31 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
246
286
  logWarning(`Skipped ${result.skipped} files due to errors.`);
247
287
  }
248
288
  }
249
- return result;
289
+ return { ...result, cancelled: false };
290
+ }
291
+ function formatProjectCount(count) {
292
+ return `${count} project${count === 1 ? "" : "s"}`;
293
+ }
294
+ function failedProjectsDetail(failedProjects) {
295
+ const names = failedProjects.map(({ project }) => project).join(", ");
296
+ const details = failedProjects.map(({ project, message }) => `${project}: ${message}`).join(" ");
297
+ return `Failed to pull ${formatProjectCount(failedProjects.length)}: ${names}. ${details}`;
298
+ }
299
+ function isErrorSlug(slug) {
300
+ return typeof slug === "string" && slug in ERROR_REGISTRY;
301
+ }
302
+ function structuredFailureAggregate(failedProjects, detail) {
303
+ if (failedProjects.length === 1) {
304
+ const error = failedProjects[0]?.error;
305
+ if (error instanceof VeryfrontError)
306
+ return error;
307
+ }
308
+ const slug = failedProjects[0]?.slug;
309
+ if (!isErrorSlug(slug))
310
+ return null;
311
+ if (!failedProjects.every((failure) => failure.slug === slug))
312
+ return null;
313
+ return getErrorBySlug(slug).create({ detail });
250
314
  }
251
315
  /**
252
316
  * Pull files from Veryfront API
@@ -285,23 +349,30 @@ export function pullCommand(options = {}) {
285
349
  await pullSingleProject(config.projectSlug, projectDir, source, force, dryRun, config, quiet);
286
350
  return;
287
351
  }
288
- const fs = createFileSystem();
289
352
  let totalWritten = 0;
290
- let totalSkipped = 0;
353
+ let totalSkippedFiles = 0;
354
+ const failedProjects = [];
355
+ const cancelledProjects = [];
291
356
  for (const project of projects) {
292
357
  const targetDir = join(projectDir, project);
293
- if (!dryRun)
294
- await fs.mkdir(targetDir, { recursive: true });
295
358
  if (!quiet)
296
359
  cliLogger.info(`\n--- Pulling ${project} into ${targetDir} ---`);
297
360
  try {
298
361
  const result = await pullSingleProject(project, targetDir, source, force, dryRun, config, quiet);
299
362
  totalWritten += result.written;
300
- totalSkipped += result.skipped;
363
+ totalSkippedFiles += result.skipped;
364
+ if (result.cancelled)
365
+ cancelledProjects.push(project);
301
366
  }
302
367
  catch (error) {
303
- cliLogger.error(`Failed to pull ${project}:`, error);
304
- totalSkipped++;
368
+ cliLogger.error(`Failed to pull ${project}: ${describeError(error)}`);
369
+ failedProjects.push({
370
+ project,
371
+ message: describeError(error),
372
+ status: errorStatus(error),
373
+ slug: errorSlug(error),
374
+ error,
375
+ });
305
376
  }
306
377
  }
307
378
  if (!quiet) {
@@ -309,11 +380,31 @@ export function pullCommand(options = {}) {
309
380
  if (dryRun) {
310
381
  logInfo(`Dry run complete. Would write ${totalWritten} files total across ${projects.length} projects.`);
311
382
  }
312
- else {
383
+ else if (totalWritten > 0) {
313
384
  logSuccess(`Pulled ${totalWritten} files total across ${projects.length} projects.`);
314
- if (totalSkipped > 0)
315
- logWarning(`Skipped ${totalSkipped} files due to errors.`);
316
385
  }
386
+ else {
387
+ logInfo(`No files were pulled across ${projects.length} projects.`);
388
+ }
389
+ if (cancelledProjects.length > 0) {
390
+ logWarning(`Cancelled ${formatProjectCount(cancelledProjects.length)}: ${cancelledProjects.join(", ")}.`);
391
+ }
392
+ if (failedProjects.length > 0) {
393
+ logWarning(`Failed to pull ${formatProjectCount(failedProjects.length)}: ${failedProjects.map(({ project }) => project).join(", ")}.`);
394
+ }
395
+ if (totalSkippedFiles > 0) {
396
+ logWarning(`Skipped ${totalSkippedFiles} files due to write errors.`);
397
+ }
398
+ }
399
+ if (failedProjects.length > 0) {
400
+ const detail = failedProjectsDetail(failedProjects);
401
+ if (failedProjects.every((failure) => failure.slug === "resource-not-found" || failure.status === 404)) {
402
+ throw RESOURCE_NOT_FOUND.create({ detail });
403
+ }
404
+ const structuredError = structuredFailureAggregate(failedProjects, detail);
405
+ if (structuredError)
406
+ throw structuredError;
407
+ throw new Error(detail);
317
408
  }
318
409
  }, { "cli.dryRun": options.dryRun ?? false, "cli.source_type": source.type });
319
410
  }
@@ -1 +1 @@
1
- {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/push/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WAoCtB,CAAC"}
1
+ {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/push/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,QAAQ,EAAE,WAyCtB,CAAC"}
@@ -8,6 +8,10 @@ export const pushHelp = {
8
8
  flag: "-d, --dir <path>",
9
9
  description: "Source directory (default: current directory)",
10
10
  },
11
+ {
12
+ flag: "-p, --project-slug <slug>",
13
+ description: "Project slug to push to (overrides inferred project)",
14
+ },
11
15
  {
12
16
  flag: "-b, --branch <name>",
13
17
  description: "Branch name (default: cli/push-<timestamp>, use 'main' for direct push)",
@@ -23,6 +27,7 @@ export const pushHelp = {
23
27
  ],
24
28
  examples: [
25
29
  "veryfront push",
30
+ "veryfront push -p my-project",
26
31
  "veryfront push --dir ./my-project",
27
32
  "veryfront push --branch feature-header",
28
33
  "veryfront push --branch main # Push directly to main",
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,gFAAgF;AAChF,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GACzC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,GAAG;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,oEAAoE;IACpE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAChD,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;KACrB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO;CACzB,CAAC;AAmBF;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAclD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWzB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,CAAC,IAAI,EAAE,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,CAU1C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,EAChD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,UAAU,GACf,CAAC,CAQH;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAaY,CAAC;AAqFpC,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgBvD"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,gFAAgF;AAChF,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GACzC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,GAAG;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,oEAAoE;IACpE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAChD,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;KACrB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO;CACzB,CAAC;AAmBF;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAclD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWzB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,CAAC,IAAI,EAAE,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,CAU1C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,EAChD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,UAAU,GACf,CAAC,CAQH;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAaY,CAAC;AAuFpC,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgBvD"}
@@ -168,10 +168,14 @@ function parse(args, options = {}) {
168
168
  const next = args[i + 1];
169
169
  if (isValue(next)) {
170
170
  setValue(key, next);
171
+ if (key !== short)
172
+ setValue(short, next);
171
173
  i++;
172
174
  continue;
173
175
  }
174
176
  setValue(key, true);
177
+ if (key !== short)
178
+ setValue(short, true);
175
179
  continue;
176
180
  }
177
181
  result._.push(arg);
@@ -5,7 +5,7 @@ export type ServerMode = InferSchema<ReturnType<typeof getServerModeSchema>>;
5
5
  export interface ParsedArgs {
6
6
  _: (string | number)[];
7
7
  port?: number;
8
- p?: number;
8
+ p?: number | string;
9
9
  __explicit?: Record<string, true>;
10
10
  help?: boolean;
11
11
  h?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAExE,eAAO,MAAM,mBAAmB,oEAAmE,CAAC;AACpG,eAAO,MAAM,gBAAgB,8DAAkC,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IACb,4DAA4D;IAC5D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,CAAC,CAAC,EAAE,UAAU,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAExE,eAAO,MAAM,mBAAmB,oEAAmE,CAAC;AACpG,eAAO,MAAM,gBAAgB,8DAAkC,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IACb,4DAA4D;IAC5D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,CAAC,CAAC,EAAE,UAAU,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
@@ -28,6 +28,10 @@ export declare function promptUser(message: string): Promise<string>;
28
28
  */
29
29
  export declare function promptPassword(message: string): string;
30
30
  export declare function confirmPrompt(message: string, defaultValue?: boolean): Promise<boolean>;
31
+ export declare function ensureConfirmPromptAvailable(options: {
32
+ interactive: boolean;
33
+ stdoutTTY: boolean;
34
+ }): void;
31
35
  /** Exit the process with the given code. */
32
36
  export declare function exitProcess(code: number): void;
33
37
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/index.ts"],"names":[],"mappings":"AAuBA,KAAK,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAMjD,eAAO,MAAM,SAAS,EAAE;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,SAAS,CAAC;IAC/D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,SAAS,CAAC;CAYhD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAwE,CAAC;AAC7F,eAAO,MAAM,uBAAuB,OAAmB,CAAC;AAExD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqBjD;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAa/B;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC9D,IAAI,CAmBN;AAKD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGrD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGnD;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3D;AAOD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuCtD;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,YAAY,UAAQ,GACnB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/index.ts"],"names":[],"mappings":"AAwBA,KAAK,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAMjD,eAAO,MAAM,SAAS,EAAE;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,SAAS,CAAC;IAC/D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,SAAS,CAAC;CAYhD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAwE,CAAC;AAC7F,eAAO,MAAM,uBAAuB,OAAmB,CAAC;AAExD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqBjD;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAa/B;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC9D,IAAI,CAmBN;AAKD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGrD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGnD;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3D;AAOD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuCtD;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,YAAY,UAAQ,GACnB,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,IAAI,CAOP;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9C"}
@@ -1,4 +1,5 @@
1
1
  import denoConfig from "../../deno.js";
2
+ import { INVALID_ARGUMENT } from "../../src/errors/index.js";
2
3
  import { exit, getEnv, isStdoutTTY, onSignal, promptSync, readStdinByteSync, setRawMode, writeStdout, } from "../../src/platform/index.js";
3
4
  import { DEFAULT_DEV_PORT } from "../shared/constants.js";
4
5
  import { bold, brand, dim, error as errorColor, muted, shouldUseColor, success as successColor, warning as warningColor, } from "../ui/colors.js";
@@ -154,10 +155,10 @@ export function promptPassword(message) {
154
155
  }
155
156
  export async function confirmPrompt(message, defaultValue = false) {
156
157
  const { isInteractive } = await import("../shared/interactive.js");
157
- if (!isInteractive())
158
+ const interactive = isInteractive();
159
+ if (!interactive)
158
160
  return true;
159
- if (!isTTY())
160
- return defaultValue;
161
+ ensureConfirmPromptAvailable({ interactive, stdoutTTY: isTTY() });
161
162
  const hint = defaultValue ? "[Y/n]" : "[y/N]";
162
163
  const response = await promptUser(`${message} ${hint} `);
163
164
  if (!response)
@@ -165,6 +166,13 @@ export async function confirmPrompt(message, defaultValue = false) {
165
166
  const normalized = response.toLowerCase().trim();
166
167
  return normalized === "y" || normalized === "yes";
167
168
  }
169
+ export function ensureConfirmPromptAvailable(options) {
170
+ if (!options.interactive || options.stdoutTTY)
171
+ return;
172
+ throw INVALID_ARGUMENT.create({
173
+ detail: "Confirmation required but no interactive prompt is available. Re-run with --yes to confirm without prompting, or use --force when the command supports it.",
174
+ });
175
+ }
168
176
  /** Exit the process with the given code. */
169
177
  export function exitProcess(code) {
170
178
  exit(code);
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1021",
3
+ "version": "0.1.1023",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -15,6 +15,10 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
15
15
  /** Single-flight background rewarm when the file list cache disappears */
16
16
  private fileListWarmupPromise;
17
17
  private fileListWarmupKey;
18
+ /** Single-flight foreground refresh when a branch preview read misses a newly pushed file. */
19
+ private branchMissRecoveryPromise;
20
+ private branchMissRecoveryGeneration;
21
+ private readonly branchMissRecoveryFailures;
18
22
  private projectData?;
19
23
  private apiBaseUrl;
20
24
  private apiToken;
@@ -38,6 +42,12 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
38
42
  initialize(): Promise<void>;
39
43
  private isPersistentCacheInvalidated;
40
44
  private shouldBackgroundPregenerateStyles;
45
+ private getBranchMissRecoveryKey;
46
+ private hasRecentBranchMissRecoveryFailure;
47
+ private shouldRecoverBranchMiss;
48
+ private shouldRecoverBranchMissResult;
49
+ private refreshBranchSnapshotAfterMiss;
50
+ private withBranchSnapshotRecovery;
41
51
  private scheduleFileListWarmup;
42
52
  refreshSourceSnapshot(reason?: string): Promise<void>;
43
53
  getPokeMetrics(): {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
@@ -6,14 +6,16 @@ import { PathNormalizer } from "./path-normalizer.js";
6
6
  import { ReadOperations } from "./read-operations.js";
7
7
  import { DirectoryOperations } from "./directory-operations.js";
8
8
  import { StatOperations } from "./stat-operations.js";
9
- import { buildFileCacheKeyPrefix, buildFileListCacheKey } from "./cache-keys.js";
9
+ import { buildDirCacheKeyPrefix, buildFileCacheKeyPrefix, buildFileListCacheKey, buildStatCacheKeyPrefix, } from "./cache-keys.js";
10
10
  import { isPrefixBeingInvalidated } from "./invalidation-state.js";
11
11
  import { WebSocketManager } from "./websocket-manager.js";
12
12
  import { fetchFileListForContext, hasContentContextChanged, resolveContentContext, summarizeFileList, toClientContext, } from "./adapter-content-context.js";
13
13
  import { buildFileCacheOptions, buildRetryConfig, shouldBackgroundPregenerateStyles, } from "./adapter-helpers.js";
14
+ import { isNotFoundLikeError } from "./read-operations-helpers.js";
14
15
  import { clearCachedReleaseAssetManifests, registerManifestFetcherForRelease, unregisterManifestFetcherForRelease, } from "../../../../release-assets/manifest-cache.js";
15
16
  import { parseReleaseAssetManifest } from "../../../../release-assets/manifest-schema.js";
16
17
  const logger = baseLogger.component("veryfront-fs-adapter");
18
+ const BRANCH_MISS_RECOVERY_FAILURE_TTL_MS = 5_000;
17
19
  /**
18
20
  * Build a project-scoped manifest fetcher backed by the given API client.
19
21
  *
@@ -43,6 +45,10 @@ export class VeryfrontFSAdapter {
43
45
  /** Single-flight background rewarm when the file list cache disappears */
44
46
  fileListWarmupPromise = null;
45
47
  fileListWarmupKey = null;
48
+ /** Single-flight foreground refresh when a branch preview read misses a newly pushed file. */
49
+ branchMissRecoveryPromise = null;
50
+ branchMissRecoveryGeneration = 0;
51
+ branchMissRecoveryFailures = new Map();
46
52
  projectData;
47
53
  apiBaseUrl;
48
54
  apiToken;
@@ -312,6 +318,113 @@ export class VeryfrontFSAdapter {
312
318
  // pregenerate through the WebSocket path after branch content changes.
313
319
  return shouldBackgroundPregenerateStyles(this.contentContext);
314
320
  }
321
+ getBranchMissRecoveryKey(path) {
322
+ const normalizedPath = this.normalizer.normalize(path);
323
+ const branch = this.requestBranch ?? this.contentContext?.branch ?? "main";
324
+ return `${this.projectSlug}:${branch}:${normalizedPath}`;
325
+ }
326
+ hasRecentBranchMissRecoveryFailure(key) {
327
+ const failedAt = this.branchMissRecoveryFailures.get(key);
328
+ if (!failedAt)
329
+ return false;
330
+ if (Date.now() - failedAt < BRANCH_MISS_RECOVERY_FAILURE_TTL_MS)
331
+ return true;
332
+ this.branchMissRecoveryFailures.delete(key);
333
+ return false;
334
+ }
335
+ shouldRecoverBranchMiss(path, error) {
336
+ if (this.contentContext?.sourceType !== "branch")
337
+ return false;
338
+ if (!isNotFoundLikeError(error))
339
+ return false;
340
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
341
+ return !this.hasRecentBranchMissRecoveryFailure(recoveryKey);
342
+ }
343
+ shouldRecoverBranchMissResult(path, result, options) {
344
+ if (this.contentContext?.sourceType !== "branch")
345
+ return false;
346
+ if (!options?.isRecoverableMissResult?.(result))
347
+ return false;
348
+ if (options.requirePendingSourceInvalidation &&
349
+ !this.isPersistentCacheInvalidated(buildFileCacheKeyPrefix(this.contentContext))) {
350
+ return false;
351
+ }
352
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
353
+ return !this.hasRecentBranchMissRecoveryFailure(recoveryKey);
354
+ }
355
+ async refreshBranchSnapshotAfterMiss(path) {
356
+ let recoveryPromise = this.branchMissRecoveryPromise;
357
+ let ownsRecovery = false;
358
+ let recoveryGeneration = this.branchMissRecoveryGeneration;
359
+ if (!recoveryPromise) {
360
+ const normalizedPath = this.normalizer.normalize(path);
361
+ recoveryPromise = this.refreshSourceSnapshot(`branch-miss:${normalizedPath}`);
362
+ this.branchMissRecoveryPromise = recoveryPromise;
363
+ recoveryGeneration = ++this.branchMissRecoveryGeneration;
364
+ ownsRecovery = true;
365
+ }
366
+ try {
367
+ await recoveryPromise;
368
+ }
369
+ finally {
370
+ if (ownsRecovery && this.branchMissRecoveryGeneration === recoveryGeneration) {
371
+ this.branchMissRecoveryPromise = null;
372
+ }
373
+ }
374
+ }
375
+ async withBranchSnapshotRecovery(path, operation, options) {
376
+ try {
377
+ const result = await operation();
378
+ if (!this.shouldRecoverBranchMissResult(path, result, options))
379
+ return result;
380
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
381
+ try {
382
+ await this.refreshBranchSnapshotAfterMiss(path);
383
+ }
384
+ catch (refreshError) {
385
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
386
+ logger.warn("Branch snapshot recovery failed after result miss", {
387
+ path: this.normalizer.normalize(path),
388
+ projectSlug: this.projectSlug,
389
+ branch: this.requestBranch ?? this.contentContext?.branch,
390
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
391
+ });
392
+ return result;
393
+ }
394
+ const retryResult = await operation();
395
+ if (options?.isRecoverableMissResult?.(retryResult)) {
396
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
397
+ }
398
+ return retryResult;
399
+ }
400
+ catch (error) {
401
+ if (!this.shouldRecoverBranchMiss(path, error))
402
+ throw error;
403
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
404
+ try {
405
+ await this.refreshBranchSnapshotAfterMiss(path);
406
+ }
407
+ catch (refreshError) {
408
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
409
+ logger.warn("Branch snapshot recovery failed after not-found miss", {
410
+ path: this.normalizer.normalize(path),
411
+ projectSlug: this.projectSlug,
412
+ branch: this.requestBranch ?? this.contentContext?.branch,
413
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
414
+ });
415
+ throw error;
416
+ }
417
+ try {
418
+ return await operation();
419
+ }
420
+ catch (retryError) {
421
+ if (isNotFoundLikeError(retryError)) {
422
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
423
+ }
424
+ throw retryError;
425
+ }
426
+ }
427
+ }
315
428
  scheduleFileListWarmup(reason, cacheKey) {
316
429
  if (!this.initialized || !this.contentContext)
317
430
  return;
@@ -393,10 +506,16 @@ export class VeryfrontFSAdapter {
393
506
  this.readOps.clearFileListIndex();
394
507
  this.statOps.clearIndex();
395
508
  this.dirOps.clearTree();
396
- await this.cache.deleteAsync(cacheKey);
509
+ await Promise.all([
510
+ this.cache.deleteByPrefixAsync(buildFileCacheKeyPrefix(refreshContext)),
511
+ this.cache.deleteByPrefixAsync(buildStatCacheKeyPrefix(refreshContext)),
512
+ this.cache.deleteByPrefixAsync(buildDirCacheKeyPrefix(refreshContext)),
513
+ this.cache.deleteAsync(cacheKey),
514
+ ]);
397
515
  const files = await fetchFileListForContext(this.client, refreshContext);
398
516
  await this.cache.setAsync(cacheKey, files);
399
517
  const fileSummary = summarizeFileList(files);
518
+ this.branchMissRecoveryFailures.clear();
400
519
  if (fileSummary.sourceFilesWithContent > 0 && this.shouldBackgroundPregenerateStyles()) {
401
520
  this.triggerCSSPregeneration(files).catch(() => {
402
521
  // Error already logged in triggerCSSPregeneration
@@ -419,31 +538,43 @@ export class VeryfrontFSAdapter {
419
538
  }
420
539
  async readFile(path) {
421
540
  await this.ensureInitialized();
422
- return this.readOps.readTextFile(path);
541
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readTextFile(path));
423
542
  }
424
543
  async readFileBytes(path) {
425
544
  await this.ensureInitialized();
426
- return this.readOps.readFile(path);
545
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readFile(path));
427
546
  }
428
547
  async readTextFile(path) {
429
548
  await this.ensureInitialized();
430
- return this.readOps.readTextFile(path);
549
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readTextFile(path));
431
550
  }
432
551
  async readdir(path) {
433
552
  await this.ensureInitialized();
434
- return this.dirOps.readdir(path);
553
+ return this.withBranchSnapshotRecovery(path, () => this.dirOps.readdir(path), {
554
+ isRecoverableMissResult: (entries) => entries.length === 0,
555
+ requirePendingSourceInvalidation: true,
556
+ });
435
557
  }
436
558
  async stat(path) {
437
559
  await this.ensureInitialized();
438
- return this.statOps.stat(path);
560
+ return this.withBranchSnapshotRecovery(path, () => this.statOps.stat(path));
439
561
  }
440
562
  async exists(path) {
441
563
  await this.ensureInitialized();
442
- return this.statOps.exists(path);
564
+ try {
565
+ await this.withBranchSnapshotRecovery(path, () => this.statOps.stat(path));
566
+ return true;
567
+ }
568
+ catch (_) {
569
+ return false;
570
+ }
443
571
  }
444
572
  async resolveFile(basePath, options) {
445
573
  await this.ensureInitialized();
446
- return this.statOps.resolveFile(basePath, options);
574
+ return this.withBranchSnapshotRecovery(basePath, () => this.statOps.resolveFile(basePath, options), {
575
+ isRecoverableMissResult: (resolvedPath) => resolvedPath === null,
576
+ requirePendingSourceInvalidation: true,
577
+ });
447
578
  }
448
579
  dispose() {
449
580
  this.wsManager.dispose();
@@ -453,6 +584,9 @@ export class VeryfrontFSAdapter {
453
584
  this.initialized = false;
454
585
  this.fileListWarmupPromise = null;
455
586
  this.fileListWarmupKey = null;
587
+ this.branchMissRecoveryPromise = null;
588
+ this.branchMissRecoveryGeneration++;
589
+ this.branchMissRecoveryFailures.clear();
456
590
  logger.debug("Disposed");
457
591
  }
458
592
  getCacheStats() {
@@ -576,6 +710,9 @@ export class VeryfrontFSAdapter {
576
710
  this.dirOps.clearTree();
577
711
  this.fileListWarmupPromise = null;
578
712
  this.fileListWarmupKey = null;
713
+ this.branchMissRecoveryPromise = null;
714
+ this.branchMissRecoveryGeneration++;
715
+ this.branchMissRecoveryFailures.clear();
579
716
  logger.debug("Cleared index and dirTree due to context change", {
580
717
  oldContext,
581
718
  newContext: context,
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1021";
2
+ export declare const VERSION = "0.1.1023";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1021";
4
+ export const VERSION = "0.1.1023";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1021",
3
+ "version": "0.1.1023",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -326,7 +326,9 @@
326
326
  "@types/react": "19.2.14",
327
327
  "@types/react-dom": "19.2.3",
328
328
  "ws": "8.21.0",
329
- "@veryfront/ext-bundler-esbuild": "0.1.1021"
329
+ "@veryfront/ext-bundler-esbuild": "0.1.1023",
330
+ "@veryfront/ext-content-mdx": "0.1.1023",
331
+ "@veryfront/ext-css-tailwind": "0.1.1023"
330
332
  },
331
333
  "devDependencies": {
332
334
  "@types/node": "20.9.0"