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.
- package/esm/cli/auth/login.d.ts +2 -2
- package/esm/cli/auth/login.d.ts.map +1 -1
- package/esm/cli/auth/login.js +23 -12
- package/esm/cli/commands/dev/command-help.d.ts.map +1 -1
- package/esm/cli/commands/dev/command-help.js +5 -0
- package/esm/cli/commands/dev/command.d.ts +10 -0
- package/esm/cli/commands/dev/command.d.ts.map +1 -1
- package/esm/cli/commands/dev/command.js +154 -34
- package/esm/cli/commands/dev/connected-dev.d.ts +32 -0
- package/esm/cli/commands/dev/connected-dev.d.ts.map +1 -0
- package/esm/cli/commands/dev/connected-dev.js +81 -0
- package/esm/cli/commands/dev/display-options.d.ts +6 -0
- package/esm/cli/commands/dev/display-options.d.ts.map +1 -0
- package/esm/cli/commands/dev/display-options.js +11 -0
- package/esm/cli/commands/dev/handler.d.ts +1 -0
- package/esm/cli/commands/dev/handler.d.ts.map +1 -1
- package/esm/cli/commands/dev/handler.js +3 -0
- package/esm/cli/commands/dev/readiness-output.d.ts +15 -0
- package/esm/cli/commands/dev/readiness-output.d.ts.map +1 -0
- package/esm/cli/commands/dev/readiness-output.js +22 -0
- package/esm/cli/commands/dev/worker-name.d.ts +4 -0
- package/esm/cli/commands/dev/worker-name.d.ts.map +1 -0
- package/esm/cli/commands/dev/worker-name.js +25 -0
- package/esm/cli/commands/init/command-help.d.ts.map +1 -1
- package/esm/cli/commands/init/command-help.js +3 -1
- package/esm/cli/commands/init/config-generator.d.ts +1 -0
- package/esm/cli/commands/init/config-generator.d.ts.map +1 -1
- package/esm/cli/commands/init/config-generator.js +5 -3
- package/esm/cli/commands/init/init-command.d.ts +0 -4
- package/esm/cli/commands/init/init-command.d.ts.map +1 -1
- package/esm/cli/commands/init/init-command.js +16 -0
- package/esm/cli/commands/pull/command.d.ts +2 -0
- package/esm/cli/commands/pull/command.d.ts.map +1 -1
- package/esm/cli/commands/pull/command.js +7 -5
- package/esm/cli/commands/pull/project-bootstrap.d.ts +2 -0
- package/esm/cli/commands/pull/project-bootstrap.d.ts.map +1 -1
- package/esm/cli/commands/pull/project-bootstrap.js +60 -7
- package/esm/cli/commands/push/command.d.ts +2 -0
- package/esm/cli/commands/push/command.d.ts.map +1 -1
- package/esm/cli/commands/push/command.js +11 -5
- package/esm/cli/commands/up/command.d.ts.map +1 -1
- package/esm/cli/commands/up/command.js +3 -0
- package/esm/cli/mcp/tools/catalog-tools.d.ts +1 -1
- package/esm/cli/shared/cloud-onboarding-transport.d.ts +3 -0
- package/esm/cli/shared/cloud-onboarding-transport.d.ts.map +1 -0
- package/esm/cli/shared/cloud-onboarding-transport.js +6 -0
- package/esm/cli/shared/cloud-project.d.ts +6 -0
- package/esm/cli/shared/cloud-project.d.ts.map +1 -0
- package/esm/cli/shared/cloud-project.js +67 -0
- package/esm/cli/shared/config.d.ts +16 -6
- package/esm/cli/shared/config.d.ts.map +1 -1
- package/esm/cli/shared/config.js +41 -22
- package/esm/cli/shared/onboarding-fetch.d.ts +3 -0
- package/esm/cli/shared/onboarding-fetch.d.ts.map +1 -0
- package/esm/cli/shared/onboarding-fetch.js +107 -0
- package/esm/cli/shared/project-creation.d.ts +2 -0
- package/esm/cli/shared/project-creation.d.ts.map +1 -1
- package/esm/cli/shared/project-creation.js +1 -0
- package/esm/cli/shared/project-link.d.ts +6 -0
- package/esm/cli/shared/project-link.d.ts.map +1 -1
- package/esm/cli/shared/project-link.js +54 -1
- package/esm/cli/shared/reserve-slug.d.ts +1 -0
- package/esm/cli/shared/reserve-slug.d.ts.map +1 -1
- package/esm/cli/shared/reserve-slug.js +3 -3
- package/esm/cli/sync/project-discovery.d.ts.map +1 -1
- package/esm/cli/sync/project-discovery.js +17 -13
- package/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui/connected-local-model.d.ts +4 -0
- package/esm/src/agent/ag-ui/connected-local-model.d.ts.map +1 -0
- package/esm/src/agent/ag-ui/connected-local-model.js +33 -0
- package/esm/src/agent/ag-ui/connected-local-runtime.d.ts +70 -0
- package/esm/src/agent/ag-ui/connected-local-runtime.d.ts.map +1 -0
- package/esm/src/agent/ag-ui/connected-local-runtime.js +564 -0
- package/esm/src/agent/ag-ui/handler.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/handler.js +36 -7
- package/esm/src/agent/ag-ui/tool-shared.d.ts +2 -0
- package/esm/src/agent/ag-ui/tool-shared.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/tool-shared.js +21 -17
- package/esm/src/agent/service/external-worker-client.d.ts +11 -0
- package/esm/src/agent/service/external-worker-client.d.ts.map +1 -1
- package/esm/src/agent/service/external-worker-client.js +23 -5
- package/esm/src/agent/streaming/data-stream.d.ts +2 -2
- package/esm/src/agent/streaming/data-stream.d.ts.map +1 -1
- package/esm/src/agent/streaming/data-stream.js +11 -2
- package/esm/src/cache/distributed-cache-init.js +2 -2
- package/esm/src/html/hydration-script-builder/hydration-runtime.generated.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/hydration-runtime.generated.js +1 -1
- package/esm/src/platform/compat/http/pinned-fetch.d.ts +1 -1
- package/esm/src/platform/compat/http/pinned-fetch.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/catalog-client.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/catalog-client.js +12 -4
- package/esm/src/security/sandbox/worker-egress-guard.d.ts.map +1 -1
- package/esm/src/security/sandbox/worker-egress-guard.js +33 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.d.ts.map +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +9 -9
package/esm/cli/auth/login.d.ts
CHANGED
|
@@ -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":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,WAAW,EAAoB,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EAAE,KAAK,oBAAoB,EAA+B,MAAM,cAAc,CAAC;AAGtF,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAqC1E;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAQ,GAAG,MAAM,CAgBtF;AAWD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,IAAI,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,cAAc,CAAC;AAErD,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sCAAsC,CAAC,EAAE,OAAO,CAAC;IACjD,gFAAgF;IAChF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/login.ts"],"names":[],"mappings":"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"}
|
package/esm/cli/auth/login.js
CHANGED
|
@@ -94,7 +94,7 @@ class CredentialValidationUnavailableError extends Error {
|
|
|
94
94
|
status;
|
|
95
95
|
name = "CredentialValidationUnavailableError";
|
|
96
96
|
constructor(kind, status) {
|
|
97
|
-
super("
|
|
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, {
|
|
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, {
|
|
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,
|
|
667
|
-
|
|
668
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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 {
|
|
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
|
|
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
|
-
|
|
182
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
360
|
+
let shutdownExitCode = 0;
|
|
272
361
|
try {
|
|
273
362
|
keyboardHandler?.stop();
|
|
274
363
|
shutdownController.abort();
|
|
275
|
-
await
|
|
276
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
304
|
-
|
|
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
|
-
|
|
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({
|
|
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(
|
|
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 @@
|
|
|
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>;
|