veryfront 0.1.1276-rc.24311 → 0.1.1276

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.
Files changed (97) hide show
  1. package/esm/cli/auth/login.d.ts +2 -2
  2. package/esm/cli/auth/login.d.ts.map +1 -1
  3. package/esm/cli/auth/login.js +23 -12
  4. package/esm/cli/commands/dev/command-help.d.ts.map +1 -1
  5. package/esm/cli/commands/dev/command-help.js +5 -0
  6. package/esm/cli/commands/dev/command.d.ts +10 -0
  7. package/esm/cli/commands/dev/command.d.ts.map +1 -1
  8. package/esm/cli/commands/dev/command.js +154 -34
  9. package/esm/cli/commands/dev/connected-dev.d.ts +32 -0
  10. package/esm/cli/commands/dev/connected-dev.d.ts.map +1 -0
  11. package/esm/cli/commands/dev/connected-dev.js +81 -0
  12. package/esm/cli/commands/dev/display-options.d.ts +6 -0
  13. package/esm/cli/commands/dev/display-options.d.ts.map +1 -0
  14. package/esm/cli/commands/dev/display-options.js +11 -0
  15. package/esm/cli/commands/dev/handler.d.ts +1 -0
  16. package/esm/cli/commands/dev/handler.d.ts.map +1 -1
  17. package/esm/cli/commands/dev/handler.js +3 -0
  18. package/esm/cli/commands/dev/readiness-output.d.ts +15 -0
  19. package/esm/cli/commands/dev/readiness-output.d.ts.map +1 -0
  20. package/esm/cli/commands/dev/readiness-output.js +22 -0
  21. package/esm/cli/commands/dev/worker-name.d.ts +4 -0
  22. package/esm/cli/commands/dev/worker-name.d.ts.map +1 -0
  23. package/esm/cli/commands/dev/worker-name.js +25 -0
  24. package/esm/cli/commands/init/command-help.d.ts.map +1 -1
  25. package/esm/cli/commands/init/command-help.js +3 -1
  26. package/esm/cli/commands/init/config-generator.d.ts +1 -0
  27. package/esm/cli/commands/init/config-generator.d.ts.map +1 -1
  28. package/esm/cli/commands/init/config-generator.js +5 -3
  29. package/esm/cli/commands/init/init-command.d.ts +0 -4
  30. package/esm/cli/commands/init/init-command.d.ts.map +1 -1
  31. package/esm/cli/commands/init/init-command.js +16 -0
  32. package/esm/cli/commands/pull/command.d.ts +2 -0
  33. package/esm/cli/commands/pull/command.d.ts.map +1 -1
  34. package/esm/cli/commands/pull/command.js +7 -5
  35. package/esm/cli/commands/pull/project-bootstrap.d.ts +2 -0
  36. package/esm/cli/commands/pull/project-bootstrap.d.ts.map +1 -1
  37. package/esm/cli/commands/pull/project-bootstrap.js +60 -7
  38. package/esm/cli/commands/push/command.d.ts +2 -0
  39. package/esm/cli/commands/push/command.d.ts.map +1 -1
  40. package/esm/cli/commands/push/command.js +11 -5
  41. package/esm/cli/commands/up/command.d.ts.map +1 -1
  42. package/esm/cli/commands/up/command.js +3 -0
  43. package/esm/cli/mcp/tools/catalog-tools.d.ts +1 -1
  44. package/esm/cli/shared/cloud-onboarding-transport.d.ts +3 -0
  45. package/esm/cli/shared/cloud-onboarding-transport.d.ts.map +1 -0
  46. package/esm/cli/shared/cloud-onboarding-transport.js +6 -0
  47. package/esm/cli/shared/cloud-project.d.ts +6 -0
  48. package/esm/cli/shared/cloud-project.d.ts.map +1 -0
  49. package/esm/cli/shared/cloud-project.js +67 -0
  50. package/esm/cli/shared/config.d.ts +16 -6
  51. package/esm/cli/shared/config.d.ts.map +1 -1
  52. package/esm/cli/shared/config.js +41 -22
  53. package/esm/cli/shared/onboarding-fetch.d.ts +3 -0
  54. package/esm/cli/shared/onboarding-fetch.d.ts.map +1 -0
  55. package/esm/cli/shared/onboarding-fetch.js +107 -0
  56. package/esm/cli/shared/project-creation.d.ts +2 -0
  57. package/esm/cli/shared/project-creation.d.ts.map +1 -1
  58. package/esm/cli/shared/project-creation.js +1 -0
  59. package/esm/cli/shared/project-link.d.ts +6 -0
  60. package/esm/cli/shared/project-link.d.ts.map +1 -1
  61. package/esm/cli/shared/project-link.js +54 -1
  62. package/esm/cli/shared/reserve-slug.d.ts +1 -0
  63. package/esm/cli/shared/reserve-slug.d.ts.map +1 -1
  64. package/esm/cli/shared/reserve-slug.js +3 -3
  65. package/esm/cli/sync/project-discovery.d.ts.map +1 -1
  66. package/esm/cli/sync/project-discovery.js +17 -13
  67. package/esm/deno.js +1 -1
  68. package/esm/src/agent/ag-ui/connected-local-model.d.ts +4 -0
  69. package/esm/src/agent/ag-ui/connected-local-model.d.ts.map +1 -0
  70. package/esm/src/agent/ag-ui/connected-local-model.js +33 -0
  71. package/esm/src/agent/ag-ui/connected-local-runtime.d.ts +70 -0
  72. package/esm/src/agent/ag-ui/connected-local-runtime.d.ts.map +1 -0
  73. package/esm/src/agent/ag-ui/connected-local-runtime.js +564 -0
  74. package/esm/src/agent/ag-ui/handler.d.ts.map +1 -1
  75. package/esm/src/agent/ag-ui/handler.js +36 -7
  76. package/esm/src/agent/ag-ui/tool-shared.d.ts +2 -0
  77. package/esm/src/agent/ag-ui/tool-shared.d.ts.map +1 -1
  78. package/esm/src/agent/ag-ui/tool-shared.js +21 -17
  79. package/esm/src/agent/service/external-worker-client.d.ts +11 -0
  80. package/esm/src/agent/service/external-worker-client.d.ts.map +1 -1
  81. package/esm/src/agent/service/external-worker-client.js +23 -5
  82. package/esm/src/agent/streaming/data-stream.d.ts +2 -2
  83. package/esm/src/agent/streaming/data-stream.d.ts.map +1 -1
  84. package/esm/src/agent/streaming/data-stream.js +11 -2
  85. package/esm/src/cache/distributed-cache-init.js +2 -2
  86. package/esm/src/html/hydration-script-builder/hydration-runtime.generated.d.ts.map +1 -1
  87. package/esm/src/html/hydration-script-builder/hydration-runtime.generated.js +1 -1
  88. package/esm/src/platform/compat/http/pinned-fetch.d.ts +1 -1
  89. package/esm/src/platform/compat/http/pinned-fetch.d.ts.map +1 -1
  90. package/esm/src/provider/veryfront-cloud/catalog-client.d.ts.map +1 -1
  91. package/esm/src/provider/veryfront-cloud/catalog-client.js +12 -4
  92. package/esm/src/security/sandbox/worker-egress-guard.d.ts.map +1 -1
  93. package/esm/src/security/sandbox/worker-egress-guard.js +33 -0
  94. package/esm/src/utils/version-constant.d.ts +1 -1
  95. package/esm/src/utils/version-constant.d.ts.map +1 -1
  96. package/esm/src/utils/version-constant.js +1 -1
  97. package/package.json +9 -9
@@ -52,8 +52,8 @@ type OAuthBrowserLauncher = (url: string, options?: BrowserLaunchOptions) => Pro
52
52
  /** Test seam for the OAuth default opener. */
53
53
  export declare function __setOAuthBrowserLauncherForTests(launcher?: OAuthBrowserLauncher): void;
54
54
  export declare function openOAuthLogin(authUrl: string, spinner: SpinnerController, opener?: (url: string) => Promise<void>): Promise<boolean>;
55
- export declare function login(method?: AuthMethod, env?: EnvironmentConfig, projectDir?: string): Promise<AuthIdentity | null>;
56
- export declare function ensureAuthenticated(env?: EnvironmentConfig, projectDir?: string): Promise<AuthIdentity | null>;
55
+ export declare function login(method?: AuthMethod, env?: EnvironmentConfig, projectDir?: string, validationOptions?: CredentialValidationOptions): Promise<AuthIdentity | null>;
56
+ export declare function ensureAuthenticated(env?: EnvironmentConfig, projectDir?: string, validationOptions?: CredentialValidationOptions): Promise<AuthIdentity | null>;
57
57
  export declare function logout(env?: EnvironmentConfig): Promise<void>;
58
58
  export declare function whoami(env?: EnvironmentConfig): Promise<AuthIdentity | null>;
59
59
  export { deleteToken, hasToken, readToken, saveToken };
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/login.ts"],"names":[],"mappings":"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"}
@@ -94,7 +94,7 @@ class CredentialValidationUnavailableError extends Error {
94
94
  status;
95
95
  name = "CredentialValidationUnavailableError";
96
96
  constructor(kind, status) {
97
- super("Could not validate existing login credentials");
97
+ super(`Veryfront API is unavailable (${kind}${status ? `, HTTP ${status}` : ""}). Check the API URL and service, then retry. Your login was retained.`);
98
98
  this.kind = kind;
99
99
  this.status = status;
100
100
  }
@@ -467,7 +467,7 @@ function writeAuthoritativeCredentialUnavailableMessage(source, failure, hasConf
467
467
  * must stop instead of falling through to lower-priority credentials or a new
468
468
  * login that later commands will not use.
469
469
  */
470
- async function describeExistingSession(env, projectDir = cwd()) {
470
+ async function describeExistingSession(env, projectDir = cwd(), validationOptions = {}) {
471
471
  const candidates = await resolveApiCredentialCandidatesForAuth(env, projectDir);
472
472
  if (candidates.length === 0)
473
473
  return null;
@@ -488,6 +488,7 @@ async function describeExistingSession(env, projectDir = cwd()) {
488
488
  // checked must still stop, because later commands will resolve it ahead
489
489
  // of any replacement login.
490
490
  identity = await validateCredential(apiToken, validationEnv, {
491
+ ...validationOptions,
491
492
  signal,
492
493
  throwOnCredentialValidationUnavailable: true,
493
494
  });
@@ -565,7 +566,7 @@ async function describeExistingSession(env, projectDir = cwd()) {
565
566
  }
566
567
  return null;
567
568
  }
568
- export async function login(method, env = getEnvironmentConfig(), projectDir = cwd()) {
569
+ export async function login(method, env = getEnvironmentConfig(), projectDir = cwd(), validationOptions = {}) {
569
570
  if (isJsonMode() && method !== undefined) {
570
571
  await outputLoginExplicitMethodJson();
571
572
  return null;
@@ -576,7 +577,7 @@ export async function login(method, env = getEnvironmentConfig(), projectDir = c
576
577
  // intent to sign in again, so account switching still works — and a session
577
578
  // that no longer validates falls through to the normal flow.
578
579
  if (method === undefined) {
579
- const existing = await describeExistingSession(env, projectDir);
580
+ const existing = await describeExistingSession(env, projectDir, validationOptions);
580
581
  if (existing === "failure-output")
581
582
  return null;
582
583
  if (existing)
@@ -605,7 +606,10 @@ export async function login(method, env = getEnvironmentConfig(), projectDir = c
605
606
  spinner.update("Validating token...");
606
607
  let identity;
607
608
  try {
608
- identity = await validateCredential(token, env, { throwOnNetworkError: true });
609
+ identity = await validateCredential(token, env, {
610
+ ...validationOptions,
611
+ throwOnNetworkError: true,
612
+ });
609
613
  }
610
614
  catch (e) {
611
615
  if (e instanceof NetworkError) {
@@ -634,7 +638,10 @@ export async function login(method, env = getEnvironmentConfig(), projectDir = c
634
638
  console.log(" " + dim("Validating token..."));
635
639
  let identity;
636
640
  try {
637
- identity = await validateCredential(token, env, { throwOnNetworkError: true });
641
+ identity = await validateCredential(token, env, {
642
+ ...validationOptions,
643
+ throwOnNetworkError: true,
644
+ });
638
645
  }
639
646
  catch (e) {
640
647
  if (e instanceof NetworkError) {
@@ -657,19 +664,23 @@ export async function login(method, env = getEnvironmentConfig(), projectDir = c
657
664
  : " ✓ Logged in as " + brand(identity.email));
658
665
  return identity;
659
666
  }
660
- export async function ensureAuthenticated(env = getEnvironmentConfig(), projectDir = cwd()) {
667
+ export async function ensureAuthenticated(env = getEnvironmentConfig(), projectDir = cwd(), validationOptions = {}) {
661
668
  const humanOutput = !isJsonMode();
662
669
  const candidates = await resolveApiCredentialCandidatesForAuth(env, projectDir);
663
670
  for (const candidate of candidates) {
664
671
  let credential;
665
672
  try {
666
- credential = await validateCredential(candidate.apiToken, candidate.validationEnv, candidate.apiTokenSource === "token-store"
667
- ? { throwOnCredentialValidationUnavailable: true }
668
- : undefined);
673
+ credential = await validateCredential(candidate.apiToken, candidate.validationEnv, {
674
+ ...(candidate.apiTokenSource === "token-store"
675
+ ? { throwOnCredentialValidationUnavailable: true }
676
+ : {}),
677
+ ...validationOptions,
678
+ });
669
679
  }
670
680
  catch (error) {
671
681
  if (candidate.apiTokenSource === "token-store" &&
672
- error instanceof CredentialValidationUnavailableError) {
682
+ error instanceof CredentialValidationUnavailableError &&
683
+ !validationOptions.throwOnCredentialValidationUnavailable) {
673
684
  return null;
674
685
  }
675
686
  throw error;
@@ -697,7 +708,7 @@ export async function ensureAuthenticated(env = getEnvironmentConfig(), projectD
697
708
  cliLogger.error("Not logged in. Set VERYFRONT_API_TOKEN or run in interactive mode.");
698
709
  return null;
699
710
  }
700
- return login(undefined, env, projectDir);
711
+ return login(undefined, env, projectDir, validationOptions);
701
712
  }
702
713
  const CREDENTIAL_VALIDATION_UNAVAILABLE = Symbol("credential-validation-unavailable");
703
714
  export async function logout(env = getEnvironmentConfig()) {
@@ -1 +1 @@
1
- {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,OAAO,EAAE,WA0CrB,CAAC"}
1
+ {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,OAAO,EAAE,WA+CrB,CAAC"}
@@ -13,6 +13,10 @@ export const devHelp = {
13
13
  flag: "--project <directory>",
14
14
  description: "Run a local project directory (defaults to the current directory)",
15
15
  },
16
+ {
17
+ flag: "--env <name>",
18
+ description: "Shared Cloud environment for local execution (default: preview)",
19
+ },
16
20
  {
17
21
  flag: "--no-hmr",
18
22
  description: "Disable hot module replacement",
@@ -28,6 +32,7 @@ export const devHelp = {
28
32
  "veryfront dev --project ./my-app",
29
33
  "PORT=3001 veryfront dev",
30
34
  "veryfront dev --open",
35
+ "veryfront dev --env preview",
31
36
  "veryfront dev --no-hmr",
32
37
  ],
33
38
  notes: [
@@ -15,6 +15,8 @@ export interface DevOptions {
15
15
  */
16
16
  portExplicit?: boolean;
17
17
  projectDir: string;
18
+ /** Shared Cloud environment used by this local runtime. */
19
+ environment?: string;
18
20
  hmr?: boolean;
19
21
  open?: boolean;
20
22
  /** Demo mode: don't exit process on shutdown, resolve done promise instead */
@@ -40,6 +42,14 @@ export interface DevCommandResult {
40
42
  /** Stop the dev server programmatically (for demo mode) */
41
43
  stop: () => Promise<void>;
42
44
  }
45
+ /** Authentication options used after executable project configuration has loaded. */
46
+ export declare function createConnectedDevAuthenticationOptions(apiBaseUrl: string, timeoutMs?: number): {
47
+ throwOnCredentialValidationUnavailable: boolean;
48
+ transport: typeof fetch;
49
+ timeoutMs: number;
50
+ };
51
+ /** Host transport for source sync; responses remain streaming for large files. */
52
+ export declare function createConnectedDevSyncTransport(apiBaseUrl: string): typeof fetch;
43
53
  export declare function preloadDevAuth(apiToken?: string, projectDir?: string): Promise<{
44
54
  identity: AuthIdentity | null;
45
55
  projects: RemoteProject[];
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,OAAO,EAAE,KAAK,YAAY,EAA2B,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAS1F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAQD,wBAAsB,cAAc,CAClC,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CA4BvE;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,GAAE,MAAM,OAAO,CAAC,YAAY,GAAG,IAAI,CAAS,GACvD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,GACrB,WAAW,CAEb;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAClC,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBtC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,0BAA0B,CAC9C,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,OAAO,CAAC,IAAI,CAAuB,EAChD,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAmB,EAC3D,QAAQ,GAAE,MAAM,OAAuC,GACtD,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8TzE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAgC1F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAYD,qFAAqF;AACrF,wBAAgB,uCAAuC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,SAAS;;;;EAM7F;AAED,kFAAkF;AAClF,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,KAAK,CAEhF;AAED,wBAAsB,cAAc,CAClC,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CA4BvE;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,GAAE,MAAM,OAAO,CAAC,YAAY,GAAG,IAAI,CAAS,GACvD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,GACrB,WAAW,CAEb;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAClC,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBtC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,0BAA0B,CAC9C,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,OAAO,CAAC,IAAI,CAAuB,EAChD,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAmB,EAC3D,QAAQ,GAAE,MAAM,OAAuC,GACtD,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmdzE"}
@@ -12,7 +12,7 @@ import { startDevServer } from "../../../src/server/index.js";
12
12
  import { clearAllLocalCaches } from "../../../src/transforms/mdx/esm-module-loader/cache/index.js";
13
13
  import { isPersistentLocalCacheEnabled } from "../../../src/cache/index.js";
14
14
  import { validateProviderConfig } from "../../../src/discovery/index.js";
15
- import { brand, devShortcuts, dim, error as errorColor, formatDuration, warning } from "../../ui/index.js";
15
+ import { brand, dim, error as errorColor, warning } from "../../ui/index.js";
16
16
  import { exitProcess, isTTY, isVerbose, registerTerminationSignals } from "../../utils/index.js";
17
17
  import { DEV_SHORTCUTS, shortcutsBlock } from "../../ui/components/shortcuts.js";
18
18
  import { applyQualifiedRuntimeAuth, resolveLinkedProjectSlug } from "../../shared/runtime-auth.js";
@@ -20,7 +20,7 @@ import { createKeyboardHandler } from "../../ui/keyboard.js";
20
20
  import { openBrowser } from "../../auth/browser.js";
21
21
  import { createMCPServer } from "../../mcp/server.js";
22
22
  import { withSpan } from "../../../src/observability/tracing/otlp-setup.js";
23
- import { isApiKeyIdentity, login } from "../../auth/login.js";
23
+ import { ensureAuthenticated, isApiKeyIdentity, login, } from "../../auth/login.js";
24
24
  import { fetchRemoteProjects } from "../../sync/index.js";
25
25
  import { pullCommand } from "../pull/index.js";
26
26
  import { createStagedPushOptions, pushCommand } from "../push/index.js";
@@ -30,12 +30,36 @@ import { findAvailablePort, isPortAvailable, isPortInUseError } from "./port-fal
30
30
  import { advertisesCloudGateway, listInferenceOptions } from "./inference-status.js";
31
31
  import { captureHostApiEnvironment } from "../../../src/platform/compat/process/env.js";
32
32
  import { resolveApiCredentialCandidatesForAuth, resolveApiUrlTrust } from "../../shared/config.js";
33
- import { trustOperatorConfiguredVeryfrontApiOrigins } from "../../../src/security/http/outbound-fetch.js";
33
+ import { captureDevDisplayOptions } from "./display-options.js";
34
+ import { captureLocalWorkerName } from "./worker-name.js";
35
+ import { devReadinessLines, veryfrontServiceName } from "./readiness-output.js";
36
+ import { applyConnectedDevProjectSlug, connectedDevApiBaseUrl, connectedDevStudioBaseUrl, createConnectedDevControlPlane, prepareConnectedDev, resolveConnectedDevProject, stopDevServices, } from "./connected-dev.js";
37
+ import { saveSharedProjectAssociation } from "../../shared/project-link.js";
38
+ import { chooseCloudProject } from "../../shared/cloud-project.js";
39
+ import { createCloudOnboardingTransport } from "../../shared/cloud-onboarding-transport.js";
40
+ import { isInteractive } from "../../shared/interactive.js";
41
+ import { getConnectedLocalRuntime, installConnectedLocalRuntime, } from "../../../src/agent/ag-ui/connected-local-runtime.js";
42
+ import { createVeryfrontApiOriginBoundOutboundFetch, trustOperatorConfiguredVeryfrontApiOrigins, } from "../../../src/security/http/outbound-fetch.js";
43
+ function authDisplayName(identity) {
44
+ return isApiKeyIdentity(identity) ? "API key" : identity.email;
45
+ }
34
46
  function authStatus(identity) {
35
47
  return isApiKeyIdentity(identity)
36
48
  ? "Authenticated with an API key"
37
49
  : `Logged in as ${identity.email}`;
38
50
  }
51
+ /** Authentication options used after executable project configuration has loaded. */
52
+ export function createConnectedDevAuthenticationOptions(apiBaseUrl, timeoutMs = 10_000) {
53
+ return {
54
+ throwOnCredentialValidationUnavailable: true,
55
+ transport: createCloudOnboardingTransport(apiBaseUrl, timeoutMs),
56
+ timeoutMs,
57
+ };
58
+ }
59
+ /** Host transport for source sync; responses remain streaming for large files. */
60
+ export function createConnectedDevSyncTransport(apiBaseUrl) {
61
+ return createVeryfrontApiOriginBoundOutboundFetch(apiBaseUrl);
62
+ }
39
63
  export async function preloadDevAuth(apiToken, projectDir) {
40
64
  const env = getEnvironmentConfig();
41
65
  const trust = resolveApiUrlTrust(env, null);
@@ -143,7 +167,8 @@ export async function clearLocalCachesIfPortFree(requestedPort, clear = clearAll
143
167
  export function devCommand(options) {
144
168
  return withSpan("cli.command.dev", async () => {
145
169
  const { port, portExplicit, projectDir, hmr = true, open = false, demoMode = false, clearLocalCaches = false, } = options;
146
- const startTime = Date.now();
170
+ const displayOptions = captureDevDisplayOptions();
171
+ const workerDisplayName = captureLocalWorkerName();
147
172
  captureHostApiEnvironment();
148
173
  trustOperatorConfiguredVeryfrontApiOrigins();
149
174
  let doneResolve;
@@ -178,8 +203,63 @@ export function devCommand(options) {
178
203
  await clearLocalCachesIfPortFree(finalPort);
179
204
  const env = getEnvironmentConfig();
180
205
  const isProxyMode = config?.fs?.veryfront?.proxyMode === true;
181
- const linkedProjectSlug = await resolveLinkedProjectSlug(projectDir, config?.projectSlug ?? config?.fs?.veryfront?.projectSlug ?? env.projectSlug);
182
- const runtimeAuth = await applyQualifiedRuntimeAuth(projectDir, linkedProjectSlug);
206
+ let linkedProjectSlug = await resolveLinkedProjectSlug(projectDir, config?.projectSlug ?? config?.fs?.veryfront?.projectSlug ?? env.projectSlug);
207
+ if (!linkedProjectSlug && !isProxyMode && isTTY() && isInteractive()) {
208
+ await chooseCloudProject(projectDir);
209
+ linkedProjectSlug = await resolveLinkedProjectSlug(projectDir);
210
+ }
211
+ let preflightIdentity = null;
212
+ let runtimeAuth = await applyQualifiedRuntimeAuth(projectDir, linkedProjectSlug);
213
+ const connectedTarget = await prepareConnectedDev(linkedProjectSlug, options.environment ?? "preview", {
214
+ authenticate: async () => {
215
+ preflightIdentity = await ensureAuthenticated(getEnvironmentConfig(), projectDir, createConnectedDevAuthenticationOptions(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl)));
216
+ return Boolean(preflightIdentity);
217
+ },
218
+ resolve: async (projectSlug, environmentName) => {
219
+ runtimeAuth = await applyQualifiedRuntimeAuth(projectDir, projectSlug);
220
+ runtimeAuth.apiBaseUrl = connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl);
221
+ if (!runtimeAuth.apiToken || !runtimeAuth.apiBaseUrl) {
222
+ throw new Error("Veryfront Cloud credentials are unavailable. Run veryfront login and retry.");
223
+ }
224
+ const controlPlane = createConnectedDevControlPlane({
225
+ apiUrl: runtimeAuth.apiBaseUrl,
226
+ apiToken: runtimeAuth.apiToken,
227
+ apiTokenSource: runtimeAuth.apiTokenSource,
228
+ projectSlug,
229
+ });
230
+ const project = await resolveConnectedDevProject(controlPlane, projectDir, {
231
+ apiUrl: runtimeAuth.apiBaseUrl,
232
+ apiToken: runtimeAuth.apiToken,
233
+ apiTokenSource: runtimeAuth.apiTokenSource,
234
+ projectSlug,
235
+ });
236
+ const environment = await controlPlane.getEnvironment(project.id, environmentName);
237
+ if (!environment) {
238
+ throw new Error(`Environment "${environmentName}" does not exist in project "${project.slug}". Choose an existing environment with --env <name>.`);
239
+ }
240
+ await saveSharedProjectAssociation(projectDir, project.slug, runtimeAuth.apiBaseUrl);
241
+ runtimeAuth = applyConnectedDevProjectSlug(runtimeAuth, project.slug);
242
+ linkedProjectSlug = project.slug;
243
+ return {
244
+ projectId: project.id,
245
+ projectSlug: project.slug,
246
+ environmentId: environment.id,
247
+ environmentName: environment.name,
248
+ };
249
+ },
250
+ }, isProxyMode);
251
+ const studioBase = connectedTarget
252
+ ? connectedDevStudioBaseUrl(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl), displayOptions.studioUrl)
253
+ : "";
254
+ const disposeConnectedRuntime = connectedTarget && runtimeAuth.apiToken && runtimeAuth.apiBaseUrl
255
+ ? installConnectedLocalRuntime({
256
+ ...connectedTarget,
257
+ workerDisplayName,
258
+ apiToken: runtimeAuth.apiToken,
259
+ apiBaseUrl: runtimeAuth.apiBaseUrl,
260
+ studioUrl: studioBase,
261
+ })
262
+ : undefined;
183
263
  const initialAuthPromise = preloadDevAuth(runtimeAuth.apiToken, projectDir).catch(() => ({
184
264
  identity: null,
185
265
  projects: [],
@@ -210,13 +290,20 @@ export function devCommand(options) {
210
290
  let identity = null;
211
291
  let projects = [];
212
292
  let selectedProject = null;
213
- const started = await startDevServerOnFreePort(finalPort, (port) => startDevServer({
214
- port,
215
- projectDir,
216
- enableHMR,
217
- enableFastRefresh: true,
218
- signal: shutdownController.signal,
219
- }));
293
+ let started;
294
+ try {
295
+ started = await startDevServerOnFreePort(finalPort, (port) => startDevServer({
296
+ port,
297
+ projectDir,
298
+ enableHMR,
299
+ enableFastRefresh: true,
300
+ signal: shutdownController.signal,
301
+ }));
302
+ }
303
+ catch (error) {
304
+ await disposeConnectedRuntime?.();
305
+ throw error;
306
+ }
220
307
  devServer = started.server;
221
308
  const boundPort = started.port;
222
309
  const DEV_MCP_PORT_OFFSET = 2;
@@ -263,30 +350,38 @@ export function devCommand(options) {
263
350
  }
264
351
  async function shutdown() {
265
352
  if (shuttingDown) {
266
- if (!demoMode)
267
- exitProcess(0);
353
+ if (!demoMode) {
354
+ console.log(" ! Stopping immediately. Run cancellation may not have been saved.");
355
+ exitProcess(1);
356
+ }
268
357
  return;
269
358
  }
270
359
  shuttingDown = true;
271
- const timeout = demoMode ? null : setTimeout(() => exitProcess(0), 3000);
360
+ let shutdownExitCode = 0;
272
361
  try {
273
362
  keyboardHandler?.stop();
274
363
  shutdownController.abort();
275
- await mcpServer?.stop();
276
- await devServer?.stop();
364
+ await stopDevServices([
365
+ () => disposeConnectedRuntime?.(),
366
+ () => mcpServer?.stop(),
367
+ () => devServer?.stop(),
368
+ ], demoMode ? undefined : {
369
+ connected: Boolean(disposeConnectedRuntime),
370
+ forceExit: () => {
371
+ console.log(" ! Shutdown timed out. Run cancellation may not have been saved.");
372
+ exitProcess(1);
373
+ },
374
+ });
277
375
  }
278
376
  catch {
279
- // ignore
280
- }
281
- finally {
282
- if (timeout)
283
- clearTimeout(timeout);
377
+ shutdownExitCode = 1;
378
+ console.log(" ! Cleanup failed. Run cancellation may not have been saved.");
284
379
  }
285
380
  if (demoMode) {
286
381
  doneResolve?.();
287
382
  return;
288
383
  }
289
- exitProcess(0);
384
+ exitProcess(shutdownExitCode);
290
385
  }
291
386
  registerTerminationSignals(() => void shutdown());
292
387
  if (isProxyMode) {
@@ -298,10 +393,25 @@ export function devCommand(options) {
298
393
  };
299
394
  }
300
395
  const serverUrl = `http://localhost:${boundPort}`;
301
- const elapsed = Date.now() - startTime;
302
396
  console.log();
303
- console.log(` ✓ Ready in ${formatDuration(elapsed)}`);
304
- console.log(` ${brand(serverUrl)}`);
397
+ for (const line of devReadinessLines({
398
+ appUrl: serverUrl,
399
+ connection: connectedTarget
400
+ ? {
401
+ apiUrl: connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl),
402
+ project: connectedTarget.projectSlug,
403
+ environment: connectedTarget.environmentName,
404
+ signedIn: preflightIdentity ? authDisplayName(preflightIdentity) : undefined,
405
+ studioUrl: `${studioBase.replace(/\/$/, "")}/projects/${encodeURIComponent(connectedTarget.projectSlug)}?panels=runs`,
406
+ }
407
+ : undefined,
408
+ }))
409
+ console.log(line);
410
+ if (isVerbose()) {
411
+ const runtimeId = getConnectedLocalRuntime()?.runtimeId;
412
+ if (runtimeId)
413
+ console.log(` ${dim("Runtime")} ${runtimeId}`);
414
+ }
305
415
  const inferenceOptions = listInferenceOptions({
306
416
  apiToken: runtimeAuth.apiToken,
307
417
  projectSlug: runtimeAuth.projectSlug,
@@ -312,7 +422,10 @@ export function devCommand(options) {
312
422
  mistralApiKey: getEnv("MISTRAL_API_KEY"),
313
423
  });
314
424
  if (inferenceOptions.length > 0) {
315
- console.log(` ${dim("Inference")} ${brand(inferenceOptions.join(", "))}`);
425
+ console.log(` ${dim("Inference")} ${brand(inferenceOptions.map((option) => option.replace("Veryfront Cloud AI Gateway", `${veryfrontServiceName(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl))} AI Gateway`)).join(", "))}`);
426
+ if (displayOptions.defaultModel) {
427
+ console.log(` ${dim("Default model")} ${brand(displayOptions.defaultModel)} (configured)`);
428
+ }
316
429
  }
317
430
  // The banner reports configured paths, and it must not block Ready on a
318
431
  // network round-trip (see `void authReady` above). But an expired stored
@@ -330,9 +443,7 @@ export function devCommand(options) {
330
443
  if (mcpServer && isVerbose()) {
331
444
  console.log(` ${dim("MCP")} ${brand(`http://localhost:${mcpPort}/mcp`)}`);
332
445
  }
333
- if (isTTY()) {
334
- console.log(devShortcuts());
335
- }
446
+ console.log(` Waiting for requests…${isTTY() ? " Press ? for shortcuts." : ""}`);
336
447
  console.log();
337
448
  if (open) {
338
449
  try {
@@ -364,7 +475,7 @@ export function devCommand(options) {
364
475
  return;
365
476
  }
366
477
  console.log(` ${dim("Opening browser...")}`);
367
- const result = await loginForDevShortcut();
478
+ const result = await loginForDevShortcut(() => login(undefined, getEnvironmentConfig(), projectDir, createConnectedDevAuthenticationOptions(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl))));
368
479
  if (!result)
369
480
  return;
370
481
  identity = result;
@@ -380,7 +491,13 @@ export function devCommand(options) {
380
491
  return;
381
492
  }
382
493
  console.log(` ${dim("Pulling...")}`);
383
- await runSyncAction(() => pullCommand({ projectSlug: project.slug, projectDir, force: true, quiet: true }), "Pulled");
494
+ await runSyncAction(() => pullCommand({
495
+ projectSlug: project.slug,
496
+ projectDir,
497
+ force: true,
498
+ quiet: true,
499
+ transport: createConnectedDevSyncTransport(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl)),
500
+ }), "Pulled");
384
501
  },
385
502
  onPush: async () => {
386
503
  const project = selectedProject;
@@ -390,7 +507,10 @@ export function devCommand(options) {
390
507
  }
391
508
  console.log(` ${dim("Pushing...")}`);
392
509
  const pushOptions = createSelectedProjectPushOptions(projectDir, project);
393
- await runSyncAction(() => pushCommand(pushOptions), `Pushed to ${pushOptions.branch} ${dim("- merge in Studio")}`);
510
+ await runSyncAction(() => pushCommand({
511
+ ...pushOptions,
512
+ transport: createConnectedDevSyncTransport(connectedDevApiBaseUrl(runtimeAuth.apiBaseUrl)),
513
+ }), `Pushed to ${pushOptions.branch} ${dim("- merge in Studio")}`);
394
514
  },
395
515
  });
396
516
  keyboardHandler.start();
@@ -0,0 +1,32 @@
1
+ import type { DeployControlPlane } from "../../shared/deployment/control-plane.js";
2
+ import { type ResolvedConfig } from "../../shared/config.js";
3
+ /** Admission preflight for a directory that explicitly names a Cloud project. */
4
+ export interface ConnectedDevTarget {
5
+ projectId: string;
6
+ projectSlug: string;
7
+ environmentId: string;
8
+ environmentName: string;
9
+ }
10
+ export declare function prepareConnectedDev(projectSlug: string | undefined, environmentName: string, dependencies: {
11
+ authenticate(): Promise<boolean>;
12
+ resolve(projectSlug: string, environmentName: string): Promise<ConnectedDevTarget>;
13
+ }, proxyMode?: boolean): Promise<ConnectedDevTarget | undefined>;
14
+ /** Qualified credentials without an override target the official API. */
15
+ export declare function connectedDevApiBaseUrl(apiBaseUrl?: string): string;
16
+ /** Release every owned service even if one cleanup fails. */
17
+ export declare function stopDevServices(cleanups: Array<() => void | Promise<void>>, shutdown?: {
18
+ connected: boolean;
19
+ forceExit(): void;
20
+ }): Promise<void>;
21
+ /** Keep connected preflight on the host transport after project config executes. */
22
+ export declare function createConnectedDevControlPlane(config: ResolvedConfig, options?: {
23
+ timeoutMs?: number;
24
+ }): DeployControlPlane;
25
+ /** Keep the local runtime and readiness link on the connected API's Studio. */
26
+ export declare function connectedDevStudioBaseUrl(apiBaseUrl: string, studioUrl?: string): string;
27
+ /** Resolve directory-owned identity before accepting a mutable Cloud slug. */
28
+ export declare function resolveConnectedDevProject(controlPlane: Pick<DeployControlPlane, "getProject">, projectDir: string, config: ResolvedConfig): Promise<import("../../shared/deployment/control-plane.js").DeployProjectRecord>;
29
+ export declare function applyConnectedDevProjectSlug<T extends {
30
+ projectSlug?: string;
31
+ }>(context: T, projectSlug: string): T;
32
+ //# sourceMappingURL=connected-dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connected-dev.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/connected-dev.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAInF,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAK9E,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE;IACZ,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACpF,EACD,SAAS,UAAQ,GAChB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAQzC;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,6DAA6D;AAC7D,wBAAsB,eAAe,CACnC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAC3C,QAAQ,CAAC,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,IAAI,IAAI,CAAA;CAAE,GACnD,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,oFAAoF;AACpF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,sBAMrC;AAED,+EAA+E;AAC/E,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAWxF;AAED,8EAA8E;AAC9E,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,EACpD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,mFAgBvB;AAED,wBAAgB,4BAA4B,CAAC,CAAC,SAAS;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7E,OAAO,EAAE,CAAC,EACV,WAAW,EAAE,MAAM,GAClB,CAAC,CAIH"}
@@ -0,0 +1,81 @@
1
+ import { setEnv } from "../../../src/platform/compat/process/env.js";
2
+ import { refreshEnvironmentConfig } from "../../../src/config/environment-config.js";
3
+ import { readProjectLinkForControlPlane, writeProjectLink } from "../../shared/project-link.js";
4
+ import { projectApiReference } from "../../shared/project-resolution.js";
5
+ import { createHttpDeployControlPlane } from "../../shared/deployment/control-plane.js";
6
+ import { createApiClient } from "../../shared/config.js";
7
+ import { createCloudOnboardingTransport } from "../../shared/cloud-onboarding-transport.js";
8
+ import { DEFAULT_API_URL } from "../../shared/constants.js";
9
+ const CONNECTED_DEV_SHUTDOWN_TIMEOUT_MS = 75_000;
10
+ export async function prepareConnectedDev(projectSlug, environmentName, dependencies, proxyMode = false) {
11
+ if (proxyMode || !projectSlug)
12
+ return undefined;
13
+ if (!await dependencies.authenticate()) {
14
+ throw new Error("Veryfront Cloud login is required for this linked project. Run veryfront login, then npm run dev again.");
15
+ }
16
+ return await dependencies.resolve(projectSlug, environmentName);
17
+ }
18
+ /** Qualified credentials without an override target the official API. */
19
+ export function connectedDevApiBaseUrl(apiBaseUrl) {
20
+ return apiBaseUrl ?? DEFAULT_API_URL;
21
+ }
22
+ /** Release every owned service even if one cleanup fails. */
23
+ export async function stopDevServices(cleanups, shutdown) {
24
+ // Connected cleanup drains pending admission/events before terminal persistence;
25
+ // renewal, pending append, final flush and completion can each take 15 seconds.
26
+ // Leave additional time for scheduling before reporting an incomplete shutdown.
27
+ const timeout = shutdown
28
+ ? setTimeout(() => shutdown.forceExit(), shutdown.connected ? CONNECTED_DEV_SHUTDOWN_TIMEOUT_MS : 3_000)
29
+ : undefined;
30
+ try {
31
+ const results = await Promise.allSettled(cleanups.map((cleanup) => Promise.resolve().then(cleanup)));
32
+ const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
33
+ if (errors.length) {
34
+ throw new AggregateError(errors, "Some local development services could not stop cleanly.");
35
+ }
36
+ }
37
+ finally {
38
+ if (timeout !== undefined)
39
+ clearTimeout(timeout);
40
+ }
41
+ }
42
+ /** Keep connected preflight on the host transport after project config executes. */
43
+ export function createConnectedDevControlPlane(config, options = {}) {
44
+ return createHttpDeployControlPlane(config, createApiClient(config, createCloudOnboardingTransport(config.apiUrl, options.timeoutMs)));
45
+ }
46
+ /** Keep the local runtime and readiness link on the connected API's Studio. */
47
+ export function connectedDevStudioBaseUrl(apiBaseUrl, studioUrl) {
48
+ if (studioUrl)
49
+ return studioUrl;
50
+ const hostname = new URL(apiBaseUrl).hostname;
51
+ if (["localhost", "127.0.0.1", "[::1]"].includes(hostname)) {
52
+ return "http://localhost:3000";
53
+ }
54
+ if (hostname === "api.veryfront.com")
55
+ return "https://veryfront.com";
56
+ if (hostname === "api.veryfront.org")
57
+ return "https://veryfront.org";
58
+ throw new Error(`Cannot determine Studio for connected API "${apiBaseUrl}". Set STUDIO_URL to your Studio origin and run npm run dev again.`);
59
+ }
60
+ /** Resolve directory-owned identity before accepting a mutable Cloud slug. */
61
+ export async function resolveConnectedDevProject(controlPlane, projectDir, config) {
62
+ const link = await readProjectLinkForControlPlane(projectDir, config.apiUrl);
63
+ const matchesLink = link && (link.projectSlug === config.projectSlug ||
64
+ link.previousProjectSlugs?.includes(config.projectSlug));
65
+ const projectId = matchesLink ? link.projectId : config.projectId;
66
+ const project = await controlPlane.getProject(projectApiReference({ ...config, projectId }));
67
+ if (matchesLink && link.projectSlug !== project.slug) {
68
+ await writeProjectLink(projectDir, {
69
+ controlPlane: link.controlPlane,
70
+ projectId: link.projectId,
71
+ projectSlug: project.slug,
72
+ previousProjectSlugs: [...new Set([...(link.previousProjectSlugs ?? []), link.projectSlug])],
73
+ });
74
+ }
75
+ return project;
76
+ }
77
+ export function applyConnectedDevProjectSlug(context, projectSlug) {
78
+ setEnv("VERYFRONT_PROJECT_SLUG", projectSlug);
79
+ refreshEnvironmentConfig();
80
+ return { ...context, projectSlug };
81
+ }
@@ -0,0 +1,6 @@
1
+ /** Capture operator display choices before importing the local project. */
2
+ export declare function captureDevDisplayOptions(): {
3
+ studioUrl?: string;
4
+ defaultModel?: string;
5
+ };
6
+ //# sourceMappingURL=display-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-options.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/dev/display-options.ts"],"names":[],"mappings":"AAGA,2EAA2E;AAC3E,wBAAgB,wBAAwB,IAAI;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAQxF"}
@@ -0,0 +1,11 @@
1
+ import { getHostEnvExcludingEnvFile } from "../../../src/platform/compat/process.js";
2
+ import { getEnvSource } from "../../../src/utils/env-loader.js";
3
+ /** Capture operator display choices before importing the local project. */
4
+ export function captureDevDisplayOptions() {
5
+ const processValue = (key) => getEnvSource(key).source === "process"
6
+ ? getHostEnvExcludingEnvFile(key)?.trim() || undefined
7
+ : undefined;
8
+ const studioUrl = processValue("STUDIO_URL");
9
+ const defaultModel = processValue("VERYFRONT_DEFAULT_MODEL");
10
+ return { ...(studioUrl ? { studioUrl } : {}), ...(defaultModel ? { defaultModel } : {}) };
11
+ }
@@ -6,6 +6,7 @@ import type { ParsedArgs } from "../../shared/types.js";
6
6
  declare const parseDevArgsBase: (args: ParsedArgs) => import("../../shared/args.js").SafeParseResult<import("../../../src/extensions/schema/schema-validator.js").InferShape<{
7
7
  port: import("../../../src/internal-agents/schema.js").Schema<number>;
8
8
  project: import("../../../src/internal-agents/schema.js").Schema<string | undefined>;
9
+ env: import("../../../src/internal-agents/schema.js").Schema<string | undefined>;
9
10
  hmr: import("../../../src/internal-agents/schema.js").Schema<boolean>;
10
11
  noHmr: import("../../../src/internal-agents/schema.js").Schema<boolean>;
11
12
  open: import("../../../src/internal-agents/schema.js").Schema<boolean>;