eve 0.12.0 → 0.12.2

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 (126) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/chunks/{use-eve-agent-D9ZhQhyV.js → use-eve-agent-DEm_Jg4k.js} +18 -4
  3. package/dist/src/chunks/{use-eve-agent-DFI0POM9.js → use-eve-agent-DsXOQMFZ.js} +18 -4
  4. package/dist/src/cli/commands/init.js +1 -1
  5. package/dist/src/cli/dev/tui/command-typeahead.d.ts +1 -1
  6. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  7. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  8. package/dist/src/cli/dev/tui/runner.d.ts +6 -2
  9. package/dist/src/cli/dev/tui/runner.js +1 -1
  10. package/dist/src/cli/dev/tui/setup-commands.d.ts +6 -2
  11. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  12. package/dist/src/cli/dev/tui/setup-issues.d.ts +16 -2
  13. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  14. package/dist/src/cli/dev/tui/setup-panel.js +2 -2
  15. package/dist/src/cli/dev/tui/target.d.ts +21 -0
  16. package/dist/src/cli/dev/tui/target.js +1 -0
  17. package/dist/src/cli/dev/tui/terminal-renderer.js +3 -3
  18. package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.d.ts +2 -0
  19. package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -0
  20. package/dist/src/cli/dev/tui/theme.d.ts +3 -1
  21. package/dist/src/cli/dev/tui/theme.js +1 -1
  22. package/dist/src/cli/dev/tui/tui.d.ts +4 -14
  23. package/dist/src/cli/dev/tui/tui.js +1 -1
  24. package/dist/src/cli/dev/url.js +1 -1
  25. package/dist/src/cli/run.d.ts +0 -12
  26. package/dist/src/cli/run.js +2 -2
  27. package/dist/src/client/client.js +1 -1
  28. package/dist/src/client/index.d.ts +1 -1
  29. package/dist/src/client/open-stream.d.ts +2 -0
  30. package/dist/src/client/open-stream.js +1 -1
  31. package/dist/src/client/session.d.ts +2 -1
  32. package/dist/src/client/session.js +1 -1
  33. package/dist/src/client/types.d.ts +9 -0
  34. package/dist/src/compiled/.vendor-stamp.json +1 -1
  35. package/dist/src/compiled/@vercel/sandbox/_async-retry.d.ts +8 -0
  36. package/dist/src/compiled/@vercel/sandbox/_workflow-serde.d.ts +5 -0
  37. package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +1442 -0
  38. package/dist/src/compiled/@vercel/sandbox/api-client/api-error.d.ts +29 -0
  39. package/dist/src/compiled/@vercel/sandbox/api-client/base-client.d.ts +39 -0
  40. package/dist/src/compiled/@vercel/sandbox/api-client/file-writer.d.ts +66 -0
  41. package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +2 -0
  42. package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +878 -0
  43. package/dist/src/compiled/@vercel/sandbox/api-client/with-retry.d.ts +10 -0
  44. package/dist/src/compiled/@vercel/sandbox/auth/error.d.ts +15 -0
  45. package/dist/src/compiled/@vercel/sandbox/auth/file.d.ts +18 -0
  46. package/dist/src/compiled/@vercel/sandbox/auth/index.d.ts +6 -0
  47. package/dist/src/compiled/@vercel/sandbox/auth/oauth.d.ts +111 -0
  48. package/dist/src/compiled/@vercel/sandbox/auth/poll-for-token.d.ts +28 -0
  49. package/dist/src/compiled/@vercel/sandbox/auth/project.d.ts +40 -0
  50. package/dist/src/compiled/@vercel/sandbox/command.d.ts +290 -0
  51. package/dist/src/compiled/@vercel/sandbox/constants.d.ts +5 -0
  52. package/dist/src/compiled/@vercel/sandbox/filesystem.d.ts +258 -0
  53. package/dist/src/compiled/@vercel/sandbox/index.d.ts +10 -129
  54. package/dist/src/compiled/@vercel/sandbox/proxy.d.ts +55 -0
  55. package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +1058 -0
  56. package/dist/src/compiled/@vercel/sandbox/session.d.ts +432 -0
  57. package/dist/src/compiled/@vercel/sandbox/snapshot.d.ts +229 -0
  58. package/dist/src/compiled/@vercel/sandbox/utils/get-credentials.d.ts +21 -0
  59. package/dist/src/compiled/@vercel/sandbox/utils/paginator.d.ts +16 -0
  60. package/dist/src/compiled/@vercel/sandbox/utils/resolveSignal.d.ts +15 -0
  61. package/dist/src/compiled/@vercel/sandbox/utils/sandbox-snapshot.d.ts +11 -0
  62. package/dist/src/compiled/@vercel/sandbox/utils/types.d.ts +11 -0
  63. package/dist/src/compiled/chat/_workflow-serde.d.ts +3 -0
  64. package/dist/src/compiled/chat/index.d.ts +1 -1
  65. package/dist/src/evals/cli/eval-client.d.ts +12 -16
  66. package/dist/src/evals/cli/eval-client.js +1 -1
  67. package/dist/src/evals/cli/eval.js +1 -1
  68. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.d.ts +3 -3
  69. package/dist/src/execution/sandbox/bindings/vercel-create-sdk.d.ts +8 -13
  70. package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +3 -3
  71. package/dist/src/execution/sandbox/bindings/vercel-lookup.d.ts +4 -5
  72. package/dist/src/execution/sandbox/bindings/vercel-read-stream.d.ts +5 -0
  73. package/dist/src/execution/sandbox/bindings/vercel-read-stream.js +1 -0
  74. package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +6 -0
  75. package/dist/src/execution/sandbox/bindings/vercel-sdk-types.js +1 -0
  76. package/dist/src/execution/sandbox/bindings/vercel.d.ts +4 -4
  77. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  78. package/dist/src/harness/compaction.d.ts +2 -3
  79. package/dist/src/harness/compaction.js +1 -1
  80. package/dist/src/harness/tool-loop.js +1 -1
  81. package/dist/src/internal/application/package.js +1 -1
  82. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  83. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  84. package/dist/src/public/sandbox/vercel-sandbox.d.ts +12 -9
  85. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  86. package/dist/src/services/dev-client/client-options.d.ts +9 -4
  87. package/dist/src/services/dev-client/client-options.js +1 -1
  88. package/dist/src/services/dev-client/credential-gate.d.ts +19 -0
  89. package/dist/src/services/dev-client/credential-gate.js +1 -0
  90. package/dist/src/services/dev-client/local-host.d.ts +4 -0
  91. package/dist/src/services/dev-client/local-host.js +1 -0
  92. package/dist/src/services/dev-client/request-headers.d.ts +38 -56
  93. package/dist/src/services/dev-client/request-headers.js +1 -1
  94. package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
  95. package/dist/src/services/dev-client/vercel-auth-error.d.ts +2 -0
  96. package/dist/src/services/dev-client/vercel-auth-error.js +2 -2
  97. package/dist/src/services/dev-client.js +1 -1
  98. package/dist/src/setup/cli/option-row.d.ts +11 -5
  99. package/dist/src/setup/cli/option-row.js +1 -1
  100. package/dist/src/setup/cli/prompt-ui.d.ts +6 -6
  101. package/dist/src/setup/cli/prompt-ui.js +2 -2
  102. package/dist/src/setup/flows/model.d.ts +2 -0
  103. package/dist/src/setup/flows/model.js +1 -1
  104. package/dist/src/setup/project-resolution.d.ts +13 -0
  105. package/dist/src/setup/project-resolution.js +1 -1
  106. package/dist/src/setup/scaffold/create/project.js +1 -1
  107. package/dist/src/setup/scaffold/index.d.ts +1 -1
  108. package/dist/src/setup/scaffold/index.js +1 -1
  109. package/dist/src/setup/scaffold/update/channels.d.ts +8 -1
  110. package/dist/src/setup/scaffold/update/channels.js +2 -2
  111. package/dist/src/setup/vercel-deployment.d.ts +53 -0
  112. package/dist/src/setup/vercel-deployment.js +1 -0
  113. package/dist/src/setup/vercel-project.js +1 -1
  114. package/dist/src/setup/verified-remote-client.d.ts +23 -0
  115. package/dist/src/setup/verified-remote-client.js +1 -0
  116. package/dist/src/shared/sandbox-network-policy.d.ts +2 -2
  117. package/dist/src/svelte/index.js +1 -1
  118. package/dist/src/svelte/use-eve-agent.js +1 -1
  119. package/dist/src/vue/index.js +1 -1
  120. package/dist/src/vue/use-eve-agent.js +1 -1
  121. package/docs/evals/targets.mdx +7 -5
  122. package/docs/guides/client/overview.mdx +3 -0
  123. package/docs/guides/dev-tui.md +5 -5
  124. package/package.json +1 -1
  125. package/dist/src/harness/tool-result-pruning.d.ts +0 -8
  126. package/dist/src/harness/tool-result-pruning.js +0 -1
@@ -1,4 +1,10 @@
1
- import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
1
+ import type * as Vercel from "#compiled/@vercel/sandbox/index.js";
2
+ type VercelCreateOptions = NonNullable<Parameters<typeof Vercel.Sandbox.create>[0]>;
3
+ type VercelUpdateOptions = Parameters<Vercel.Sandbox["update"]>[0];
4
+ type VercelSandboxInternalCreateOptions = {
5
+ readonly [key: `__${string}`]: unknown;
6
+ };
7
+ type VercelSandboxAuthorCreateOptions<T> = T extends unknown ? Omit<T, "name" | "onResume" | "persistent" | "signal"> & VercelSandboxInternalCreateOptions : never;
2
8
  /**
3
9
  * Options accepted by `vercel(opts)`. Forwarded to Vercel
4
10
  * Sandbox creation for every fresh sandbox the framework creates
@@ -25,13 +31,10 @@ import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@verc
25
31
  * snapshot, force a template rebuild (e.g. by changing the sandbox
26
32
  * definition so its template key changes).
27
33
  */
28
- export type VercelSandboxCreateOptions = Omit<NonNullable<Parameters<typeof SdkSandbox.create>[0]>, "name" | "onResume" | "persistent" | "signal"> & VercelSandboxInternalCreateOptions;
29
- type VercelSandboxInternalCreateOptions = {
30
- readonly [key: `__${string}`]: unknown;
31
- };
34
+ export type VercelSandboxCreateOptions = VercelSandboxAuthorCreateOptions<VercelCreateOptions>;
32
35
  /**
33
36
  * Options accepted by the Vercel backend's `bootstrap({ use })` hook.
34
- * Aliases the Vercel SDK's `SandboxUpdateParams` because bootstrap
37
+ * Tracks the Vercel SDK's `Sandbox.update(...)` parameter because bootstrap
35
38
  * applies its options to the template via `sandbox.update(...)` after
36
39
  * `Sandbox.create()` and before the snapshot is captured. The Vercel
37
40
  * SDK persists `update`-d settings on the sandbox so they survive into
@@ -41,11 +44,11 @@ type VercelSandboxInternalCreateOptions = {
41
44
  * {@link VercelSandboxSessionUseOptions}; both are exposed as separate
42
45
  * named aliases so future divergence is non-breaking.
43
46
  */
44
- export type VercelSandboxBootstrapUseOptions = SandboxUpdateParams;
47
+ export type VercelSandboxBootstrapUseOptions = VercelUpdateOptions;
45
48
  /**
46
49
  * Options accepted by the Vercel backend's `onSession({ use })` hook.
47
- * Aliases the Vercel SDK's `SandboxUpdateParams`; passed values are
50
+ * Tracks the Vercel SDK's `Sandbox.update(...)` parameter; passed values are
48
51
  * applied to the live session via the SDK's `update`.
49
52
  */
50
- export type VercelSandboxSessionUseOptions = SandboxUpdateParams;
53
+ export type VercelSandboxSessionUseOptions = VercelUpdateOptions;
51
54
  export {};
@@ -1 +1 @@
1
- import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{getRuntimeCompiledArtifactsCacheKey}from"#runtime/compiled-artifacts-source.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{pathToFileURL}from"node:url";import{loadCompiledModuleMap}from"#runtime/loaders/module-map.js";import{getActiveRuntimeSession}from"#runtime/sessions/runtime-session.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{createRuntimeAdapterRegistry}from"#runtime/channels/registry.js";const isCacheDisabled=process.env.EVE_DISABLE_AGENT_CACHE===`1`;async function loadFullBundle(e){let[t,i]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:e}),loadRuntimeCompiledModuleMap(e)]),a=await resolveRuntimeAgentGraph({manifest:t,moduleMap:i}),o=a.root;return{adapterRegistry:createRuntimeAdapterRegistry({channels:collectResolvedChannels(a)}),compiledArtifactsSource:e,graph:a,hookRegistry:o.hookRegistry,moduleMap:i,resolvedAgent:o.agent,subagentRegistry:o.subagentRegistry,toolRegistry:o.toolRegistry,turnAgent:o.turnAgent}}async function loadRuntimeCompiledModuleMap(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0?await loadAuthoredSourceCompiledModuleMap(e):await loadCompiledModuleMap({compiledArtifactsSource:e})}async function loadAuthoredSourceCompiledModuleMap(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(pathToFileURL(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function getOrLoadFullBundle(e){if(isCacheDisabled)return loadFullBundle(e);let n=getActiveRuntimeSession(),r=getRuntimeCompiledArtifactsCacheKey(e),i=await resolveRuntimeCompiledArtifactsVersionedCacheKey(e),a=n.bundleCacheKeyBySourceKey.get(r);a!==void 0&&a!==i&&n.bundleCache.delete(a),n.bundleCacheKeyBySourceKey.set(r,i);let s=n.bundleCache.get(i);if(s!==void 0)return s;let c=loadFullBundle(e).catch(e=>{throw n.bundleCache.delete(i),n.bundleCacheKeyBySourceKey.get(r)===i&&n.bundleCacheKeyBySourceKey.delete(r),e});return n.bundleCache.set(i,c),c}async function getCompiledRuntimeAgentBundle(t){let n=await getOrLoadFullBundle(t.compiledArtifactsSource);if(t.nodeId===void 0)return n;let r=getResolvedRuntimeAgentNode(n.graph,t.nodeId);return{adapterRegistry:n.adapterRegistry,compiledArtifactsSource:n.compiledArtifactsSource,graph:{nodesByNodeId:n.graph.nodesByNodeId,root:r},hookRegistry:r.hookRegistry,moduleMap:n.moduleMap,nodeId:t.nodeId,resolvedAgent:r.agent,subagentRegistry:r.subagentRegistry,toolRegistry:r.toolRegistry,turnAgent:r.turnAgent}}function clearCompiledRuntimeAgentBundleCache(){let e=getActiveRuntimeSession();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function collectResolvedChannels(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}export{clearCompiledRuntimeAgentBundleCache,getCompiledRuntimeAgentBundle};
1
+ import{resolvePackageSourceFilePath}from"#internal/application/package.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{getRuntimeCompiledArtifactsCacheKey}from"#runtime/compiled-artifacts-source.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{pathToFileURL}from"node:url";import{loadCompiledModuleMap}from"#runtime/loaders/module-map.js";import{getActiveRuntimeSession}from"#runtime/sessions/runtime-session.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{createRuntimeAdapterRegistry}from"#runtime/channels/registry.js";const isCacheDisabled=process.env.EVE_DISABLE_AGENT_CACHE===`1`;function isDevelopmentRuntimeSnapshotRoot(e){return e.replaceAll(`\\`,`/`).includes(`/.eve/dev-runtime/snapshots/`)}function normalizeCompiledArtifactsSource(t){return t.kind!==`disk`||t.moduleMapLoaderPath!==void 0||!isDevelopmentRuntimeSnapshotRoot(t.appRoot)?t:{...t,moduleMapLoaderPath:resolvePackageSourceFilePath(`src/internal/authored-module-map-loader.ts`)}}async function loadFullBundle(e){let t=normalizeCompiledArtifactsSource(e),[n,a]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:t}),loadRuntimeCompiledModuleMap(t)]),o=await resolveRuntimeAgentGraph({manifest:n,moduleMap:a}),s=o.root;return{adapterRegistry:createRuntimeAdapterRegistry({channels:collectResolvedChannels(o)}),compiledArtifactsSource:t,graph:o,hookRegistry:s.hookRegistry,moduleMap:a,resolvedAgent:s.agent,subagentRegistry:s.subagentRegistry,toolRegistry:s.toolRegistry,turnAgent:s.turnAgent}}async function loadRuntimeCompiledModuleMap(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0?await loadAuthoredSourceCompiledModuleMap(e):await loadCompiledModuleMap({compiledArtifactsSource:e})}async function loadAuthoredSourceCompiledModuleMap(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(pathToFileURL(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function getOrLoadFullBundle(e){let t=normalizeCompiledArtifactsSource(e);if(isCacheDisabled)return loadFullBundle(t);let r=getActiveRuntimeSession(),i=getRuntimeCompiledArtifactsCacheKey(t),a=await resolveRuntimeCompiledArtifactsVersionedCacheKey(t),o=r.bundleCacheKeyBySourceKey.get(i);o!==void 0&&o!==a&&r.bundleCache.delete(o),r.bundleCacheKeyBySourceKey.set(i,a);let c=r.bundleCache.get(a);if(c!==void 0)return c;let l=loadFullBundle(t).catch(e=>{throw r.bundleCache.delete(a),r.bundleCacheKeyBySourceKey.get(i)===a&&r.bundleCacheKeyBySourceKey.delete(i),e});return r.bundleCache.set(a,l),l}async function getCompiledRuntimeAgentBundle(e){let n=await getOrLoadFullBundle(e.compiledArtifactsSource);if(e.nodeId===void 0)return n;let r=getResolvedRuntimeAgentNode(n.graph,e.nodeId);return{adapterRegistry:n.adapterRegistry,compiledArtifactsSource:n.compiledArtifactsSource,graph:{nodesByNodeId:n.graph.nodesByNodeId,root:r},hookRegistry:r.hookRegistry,moduleMap:n.moduleMap,nodeId:e.nodeId,resolvedAgent:r.agent,subagentRegistry:r.subagentRegistry,toolRegistry:r.toolRegistry,turnAgent:r.turnAgent}}function clearCompiledRuntimeAgentBundleCache(){let e=getActiveRuntimeSession();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function collectResolvedChannels(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}export{clearCompiledRuntimeAgentBundleCache,getCompiledRuntimeAgentBundle};
@@ -1,8 +1,13 @@
1
1
  import type { ClientOptions } from "#client/index.js";
2
+ import type { DevelopmentCredentialGate } from "./credential-gate.js";
2
3
  /**
3
- * Builds the {@link ClientOptions} every development client connects with:
4
- * local hosts skip the Vercel OIDC bearer (the framework's `localDev()`
5
- * channel auth accepts unauthenticated calls); remote hosts attach it
6
- * alongside any protection-bypass headers resolved per request.
4
+ * Builds anonymous {@link ClientOptions} for a development target. Locality is
5
+ * not an authorization decision, so remote URLs receive no ambient Vercel
6
+ * credentials through this default path.
7
7
  */
8
8
  export declare function resolveDevelopmentClientOptions(serverUrl: string): ClientOptions;
9
+ /** Builds non-redirecting client options backed by one verified credential gate. */
10
+ export declare function resolveRemoteDevelopmentClientOptions(input: {
11
+ readonly credentials: DevelopmentCredentialGate;
12
+ readonly serverUrl: string;
13
+ }): ClientOptions;
@@ -1 +1 @@
1
- import{isLocalDevelopmentServerUrl,resolveDevelopmentClientHeaders,resolveDevelopmentOidcToken}from"./request-headers.js";function resolveDevelopmentClientOptions(e){let t={headers:()=>resolveDevelopmentClientHeaders({serverUrl:e}),host:e};return isLocalDevelopmentServerUrl(e)?t:{...t,auth:{bearer:resolveDevelopmentOidcToken}}}export{resolveDevelopmentClientOptions};
1
+ function resolveDevelopmentClientOptions(e){return{host:e}}function resolveRemoteDevelopmentClientOptions(e){let t=new URL(e.serverUrl).origin;if(e.credentials.serverOrigin!==t)throw Error(`Credential gate origin ${e.credentials.serverOrigin} does not match client origin ${t}.`);return{headers:e.credentials.resolveHeaders,host:e.serverUrl,redirect:`manual`}}export{resolveDevelopmentClientOptions,resolveRemoteDevelopmentClientOptions};
@@ -0,0 +1,19 @@
1
+ import type { VerifiedVercelTarget } from "#setup/vercel-deployment.js";
2
+ import { type DevelopmentOidcTokenFailure, type DevelopmentOidcTokenResolution } from "./request-headers.js";
3
+ export interface DevelopmentCredentialGrant {
4
+ readonly target: VerifiedVercelTarget;
5
+ readonly resolveToken: () => Promise<DevelopmentOidcTokenResolution>;
6
+ }
7
+ /** Per-client authority for resolving and emitting remote Vercel credentials. */
8
+ export interface DevelopmentCredentialGate {
9
+ /** The origin this gate is permanently bound to. */
10
+ readonly serverOrigin: string;
11
+ /** Installs authority after Vercel verifies the exact origin. */
12
+ authorize(grant: DevelopmentCredentialGrant): void;
13
+ /** Resolves headers for one request. */
14
+ resolveHeaders(): Promise<Readonly<Record<string, string>>>;
15
+ /** Token failure from the most recent {@link resolveHeaders}, or `undefined` if it resolved one. */
16
+ lastTokenFailure(): DevelopmentOidcTokenFailure | undefined;
17
+ }
18
+ /** Creates an anonymous credential gate bound to one client origin. */
19
+ export declare function createDevelopmentCredentialGate(serverUrl: string): DevelopmentCredentialGate;
@@ -0,0 +1 @@
1
+ import{VERCEL_PROTECTION_BYPASS_HEADER,VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER}from"./request-headers.js";function createDevelopmentCredentialGate(t){let n=new URL(t).origin,r={kind:`anonymous`},i;return{authorize:e=>{if(e.target.origin!==n)throw Error(`Verified Vercel origin ${e.target.origin} does not match client origin ${n}.`);r={kind:`vercel`,resolveToken:e.resolveToken}},resolveHeaders:async()=>{let t=r;if(t.kind===`anonymous`)return{};let n={},a=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();a&&(n[VERCEL_PROTECTION_BYPASS_HEADER]=a);let o=await t.resolveToken();if(i=o.kind===`resolved`?void 0:o,o.kind!==`resolved`)return n;let s=o.token.trim();return s.length>0&&(n.authorization=`Bearer ${s}`,n[VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER]=s),n},serverOrigin:n,lastTokenFailure:()=>i}}export{createDevelopmentCredentialGate};
@@ -0,0 +1,4 @@
1
+ /** Returns whether `url` targets a recognized local development host. */
2
+ export declare function isLocalEveServerUrl(url: URL): boolean;
3
+ /** Whether `serverUrl` is a local dev host. Invalid URLs count as remote. */
4
+ export declare function isLocalDevelopmentServerUrl(serverUrl: string): boolean;
@@ -0,0 +1 @@
1
+ const LOCAL_HOSTNAMES=new Set([`localhost`,`127.0.0.1`,`0.0.0.0`,`::1`,`[::1]`]);function isLocalEveServerUrl(t){return LOCAL_HOSTNAMES.has(t.hostname)}function isLocalDevelopmentServerUrl(e){try{return isLocalEveServerUrl(new URL(e))}catch{return!1}}export{isLocalDevelopmentServerUrl,isLocalEveServerUrl};
@@ -1,18 +1,40 @@
1
- /**
2
- * Returns whether `serverUrl` targets one of the recognized local
3
- * development hostnames. Invalid URLs return `false` so callers can
4
- * always proceed as if the target is remote.
5
- */
6
- export declare function isLocalDevelopmentServerUrl(serverUrl: string): boolean;
7
- /**
8
- * Resolves a Vercel OIDC token for the development client.
9
- *
10
- * Tries the `@vercel/oidc` SDK first (refreshes a freshly-issued token
11
- * when the CLI is linked to a Vercel project), then falls back to the
12
- * `VERCEL_OIDC_TOKEN` environment variable. Returns an empty string
13
- * when no token is available so callers can proceed without auth.
14
- */
15
- export declare function resolveDevelopmentOidcToken(): Promise<string>;
1
+ import { z } from "zod";
2
+ declare const VercelOidcClaimsSchema: z.ZodObject<{
3
+ owner_id: z.ZodString;
4
+ project_id: z.ZodString;
5
+ }, z.core.$strip>;
6
+ /** Vercel owner and project expected to have minted an OIDC token. */
7
+ export interface DevelopmentOidcTarget {
8
+ readonly ownerId: string;
9
+ readonly projectId: string;
10
+ }
11
+ type VercelOidcClaimName = keyof z.infer<typeof VercelOidcClaimsSchema>;
12
+ type InvalidVercelOidcClaim = VercelOidcClaimName | "claims";
13
+ /** Why eve could not use a locally resolved Vercel OIDC token. */
14
+ export type DevelopmentOidcTokenFailure = {
15
+ readonly kind: "resolution-failed";
16
+ readonly message: string;
17
+ } | {
18
+ readonly kind: "malformed-token";
19
+ readonly reason: "missing-payload" | "invalid-json-payload";
20
+ } | {
21
+ readonly kind: "invalid-claims";
22
+ readonly invalidClaims: readonly InvalidVercelOidcClaim[];
23
+ } | {
24
+ readonly kind: "target-mismatch";
25
+ readonly mismatchedClaims: readonly VercelOidcClaimName[];
26
+ };
27
+ /** Result of resolving and checking a Vercel OIDC token for one target. */
28
+ export type DevelopmentOidcTokenResolution = {
29
+ readonly kind: "resolved";
30
+ readonly token: string;
31
+ } | DevelopmentOidcTokenFailure;
32
+ /**
33
+ * Resolves and claim-checks the local Vercel OIDC token for a verified target.
34
+ * It does not authorize a destination; callers must verify the exact origin
35
+ * first and install the result in a `DevelopmentCredentialGate`.
36
+ */
37
+ export declare function resolveDevelopmentOidcToken(input: DevelopmentOidcTarget): Promise<DevelopmentOidcTokenResolution>;
16
38
  /**
17
39
  * Vercel header used to bypass preview protection for framework-owned routes
18
40
  * during local CLI development. Paired with a Protection Bypass for
@@ -31,44 +53,4 @@ export declare const VERCEL_PROTECTION_BYPASS_HEADER = "x-vercel-protection-bypa
31
53
  * `@vercel/oidc`.
32
54
  */
33
55
  export declare const VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER = "x-vercel-trusted-oidc-idp-token";
34
- /**
35
- * Vercel request header that carries the runtime OIDC token on function
36
- * invocations.
37
- */
38
- export declare const VERCEL_OIDC_TOKEN_HEADER = "x-vercel-oidc-token";
39
- /**
40
- * Header values accepted by eve's development client helpers.
41
- */
42
- export type DevelopmentRequestHeaders = Headers | ReadonlyArray<readonly [string, string]> | Record<string, string>;
43
- /**
44
- * Creates request headers for one service-issued development request and
45
- * opportunistically refreshes a linked local Vercel OIDC token for eve-owned
46
- * routes when no explicit authorization header is present.
47
- */
48
- export declare function createDevelopmentRequestHeadersAsync(input: {
49
- headers?: DevelopmentRequestHeaders;
50
- resourceUrl: URL;
51
- }): Promise<Headers>;
52
- /**
53
- * Resolves the per-request custom headers used by the development client
54
- * when constructing requests against a configured server URL.
55
- *
56
- * - {@link VERCEL_PROTECTION_BYPASS_HEADER} is attached when
57
- * `VERCEL_AUTOMATION_BYPASS_SECRET` is set.
58
- * - {@link VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER} is attached when a Vercel
59
- * OIDC token is available locally (either via `vercel link` +
60
- * `@vercel/oidc` or via the `VERCEL_OIDC_TOKEN` environment variable).
61
- * This lets the CLI bypass Vercel Deployment Protection without the user
62
- * creating a project-scoped Bypass for Automation token first.
63
- *
64
- * Both headers are sent when both sources are available; the platform
65
- * accepts whichever it can validate.
66
- *
67
- * Local dev servers skip the OIDC token entirely — the framework's
68
- * default channel auth chain is `[localDev(), vercelOidc()]`, and
69
- * `localDev()` accepts off Vercel infrastructure, so attaching the
70
- * bypass token would be wasted work.
71
- */
72
- export declare function resolveDevelopmentClientHeaders(input: {
73
- readonly serverUrl: string;
74
- }): Promise<Record<string, string>>;
56
+ export {};
@@ -1 +1 @@
1
- import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";const EVE_ROUTE_PREFIX_WITH_SEPARATOR=`${EVE_ROUTE_PREFIX}/`,LOCAL_HOSTNAMES=new Set([`localhost`,`127.0.0.1`,`0.0.0.0`,`::1`,`[::1]`]);function isLocalEveServerUrl(e){return LOCAL_HOSTNAMES.has(e.hostname)}function isLocalDevelopmentServerUrl(e){try{return isLocalEveServerUrl(new URL(e))}catch{return!1}}async function resolveDevelopmentOidcToken(){try{let e=(await getVercelOidcToken()).trim();if(e.length>0)return e}catch{}return process.env.VERCEL_OIDC_TOKEN?.trim()??``}const VERCEL_PROTECTION_BYPASS_HEADER=`x-vercel-protection-bypass`,VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER=`x-vercel-trusted-oidc-idp-token`,VERCEL_OIDC_TOKEN_HEADER=`x-vercel-oidc-token`;function isEveRouteUrl(t){return t.pathname.endsWith(EVE_ROUTE_PREFIX)||t.pathname.includes(EVE_ROUTE_PREFIX_WITH_SEPARATOR)}async function createDevelopmentRequestHeadersAsync(e){let t=createBaseDevelopmentRequestHeaders(e),n=await resolveEveRouteOidcToken(t,e.resourceUrl);return n!==null&&attachEveRouteOidcHeaders(t,n),t}function createBaseDevelopmentRequestHeaders(e){let t=new Headers(resolveDevelopmentHeadersInit(e.headers)),n=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return n&&isEveRouteUrl(e.resourceUrl)&&t.set(VERCEL_PROTECTION_BYPASS_HEADER,n),t}function attachEveRouteOidcHeaders(e,t){e.has(`authorization`)||e.set(`authorization`,`Bearer ${t}`),e.set(VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER,t)}async function resolveEveRouteOidcToken(e,t){return shouldResolveEveRouteOidcToken(t)?e.get(VERCEL_OIDC_TOKEN_HEADER)?.trim()||await resolveLocalDevelopmentOidcToken():null}function shouldResolveEveRouteOidcToken(e){return!(!isEveRouteUrl(e)||isLocalEveServerUrl(e))}async function resolveLocalDevelopmentOidcToken(){let e=await resolveDevelopmentOidcToken();return e.length>0?e:null}function resolveDevelopmentHeadersInit(e){if(e!==void 0)return e instanceof Headers?e:Array.isArray(e)?e.map(([e,t])=>[e,t]):e}async function resolveDevelopmentClientHeaders(e){let t={},n=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();if(n&&(t[VERCEL_PROTECTION_BYPASS_HEADER]=n),!isLocalDevelopmentServerUrl(e.serverUrl)){let e=await resolveDevelopmentOidcToken();e.length>0&&(t[VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER]=e)}return t}export{VERCEL_OIDC_TOKEN_HEADER,VERCEL_PROTECTION_BYPASS_HEADER,VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER,createDevelopmentRequestHeadersAsync,isLocalDevelopmentServerUrl,resolveDevelopmentClientHeaders,resolveDevelopmentOidcToken};
1
+ import{object,string}from"../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";const VercelOidcClaimsSchema=object({owner_id:string().min(1),project_id:string().min(1)});async function resolveDevelopmentOidcToken(e){try{return validateDevelopmentOidcToken((await getVercelOidcToken({team:e.ownerId,project:e.projectId})).trim(),e)}catch(e){return{kind:`resolution-failed`,message:toErrorMessage(e)}}}function validateDevelopmentOidcToken(e,t){let n=e.split(`.`)[1];if(!n)return{kind:`malformed-token`,reason:`missing-payload`};let r;try{r=JSON.parse(Buffer.from(n,`base64url`).toString(`utf8`))}catch{return{kind:`malformed-token`,reason:`invalid-json-payload`}}let i=VercelOidcClaimsSchema.safeParse(r);if(!i.success)return{kind:`invalid-claims`,invalidClaims:i.error.issues.map(e=>{let t=e.path[0];return t===`owner_id`||t===`project_id`?t:`claims`})};let a=[];return i.data.owner_id!==t.ownerId&&a.push(`owner_id`),i.data.project_id!==t.projectId&&a.push(`project_id`),a.length>0?{kind:`target-mismatch`,mismatchedClaims:a}:{kind:`resolved`,token:e}}const VERCEL_PROTECTION_BYPASS_HEADER=`x-vercel-protection-bypass`,VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER=`x-vercel-trusted-oidc-idp-token`;export{VERCEL_PROTECTION_BYPASS_HEADER,VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER,resolveDevelopmentOidcToken};
@@ -1 +1 @@
1
- import{resolveDevelopmentClientHeaders}from"./request-headers.js";import{EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}from"#protocol/routes.js";async function readDevelopmentRuntimeArtifactsRevision(t){try{let r=new URL(EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,t.serverUrl);return await parseDevelopmentRuntimeArtifactsRevision(await fetch(r,{headers:await resolveDevelopmentClientHeaders({serverUrl:t.serverUrl})}))}catch{return}}async function rebuildDevelopmentRuntimeArtifacts(n){try{let r=new URL(EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,n.serverUrl);return await parseDevelopmentRuntimeArtifactsRevision(await fetch(r,{headers:await resolveDevelopmentClientHeaders({serverUrl:n.serverUrl}),method:`POST`}))}catch{return}}async function parseDevelopmentRuntimeArtifactsRevision(e){if(!e.ok)return;let t=await e.json();return typeof t.revision==`string`&&t.revision.length>0?t.revision:void 0}export{readDevelopmentRuntimeArtifactsRevision,rebuildDevelopmentRuntimeArtifacts};
1
+ import{EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}from"#protocol/routes.js";async function readDevelopmentRuntimeArtifactsRevision(e){try{let n=new URL(EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,e.serverUrl);return await parseDevelopmentRuntimeArtifactsRevision(await fetch(n))}catch{return}}async function rebuildDevelopmentRuntimeArtifacts(t){try{let n=new URL(EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,t.serverUrl);return await parseDevelopmentRuntimeArtifactsRevision(await fetch(n,{method:`POST`}))}catch{return}}async function parseDevelopmentRuntimeArtifactsRevision(e){if(!e.ok)return;let t=await e.json();return typeof t.revision==`string`&&t.revision.length>0?t.revision:void 0}export{readDevelopmentRuntimeArtifactsRevision,rebuildDevelopmentRuntimeArtifacts};
@@ -13,6 +13,7 @@
13
13
  * These helpers let the REPL detect the challenge and render a focused,
14
14
  * actionable message instead.
15
15
  */
16
+ import type { DevelopmentOidcTokenFailure } from "#services/dev-client/request-headers.js";
16
17
  /**
17
18
  * Returns `true` when the thrown error is the Vercel Deployment
18
19
  * Protection SSO challenge.
@@ -39,4 +40,5 @@ export declare function isVercelAuthChallenge(error: unknown): boolean;
39
40
  */
40
41
  export declare function formatVercelAuthChallengeMessage(input: {
41
42
  readonly serverUrl: string;
43
+ readonly oidcTokenFailure?: DevelopmentOidcTokenFailure;
42
44
  }): string;
@@ -1,2 +1,2 @@
1
- import{ClientError}from"#client/client-error.js";const VERCEL_AUTH_CHALLENGE_MARKERS=[`vercel.com/sso-api`,`<title>Authentication Required</title>`,`Vercel Authentication`];function bodyLooksLikeVercelAuthChallenge(e){if(e.length===0)return!1;for(let n of VERCEL_AUTH_CHALLENGE_MARKERS)if(e.includes(n))return!0;return!1}function isVercelAuthChallenge(t){return t instanceof ClientError||typeof t==`object`&&t&&`body`in t&&typeof t.body==`string`?bodyLooksLikeVercelAuthChallenge(t.body):!1}function formatVercelAuthChallengeMessage(e){return[`Vercel Deployment Protection blocked the request to ${e.serverUrl}.`,``,"To access the deployment from `eve dev`, do one of:"," • Run `vercel link` in this project so the CLI can mint an OIDC",` token for the deployment automatically.`,` • Set VERCEL_AUTOMATION_BYPASS_SECRET to a Protection Bypass for`,` Automation token (Project Settings → Deployment Protection).`,` • Disable Deployment Protection on the target deployment.`,``,`Docs: https://vercel.com/docs/deployment-protection`].join(`
2
- `)}export{formatVercelAuthChallengeMessage,isVercelAuthChallenge};
1
+ import{ClientError}from"#client/client-error.js";const VERCEL_AUTH_CHALLENGE_MARKERS=[`vercel.com/sso-api`,`<title>Authentication Required</title>`,`Vercel Authentication`];function bodyLooksLikeVercelAuthChallenge(e){if(e.length===0)return!1;for(let n of VERCEL_AUTH_CHALLENGE_MARKERS)if(e.includes(n))return!0;return!1}function isVercelAuthChallenge(t){return t instanceof ClientError||typeof t==`object`&&t&&`body`in t&&typeof t.body==`string`?bodyLooksLikeVercelAuthChallenge(t.body):!1}function formatVercelAuthChallengeMessage(e){let t=[`Vercel Deployment Protection blocked the request to ${e.serverUrl}.`];return e.oidcTokenFailure!==void 0&&t.push(``,formatOidcTokenFailure(e.oidcTokenFailure)),t.push(``,"To access the deployment from `eve dev`, do one of:"," • Run `vercel link` in this project so the CLI can mint an OIDC",` token for the deployment automatically.`,` • Set VERCEL_AUTOMATION_BYPASS_SECRET to a Protection Bypass for`,` Automation token (Project Settings → Deployment Protection).`,` • Disable Deployment Protection on the target deployment.`,``,`Docs: https://vercel.com/docs/deployment-protection`),t.join(`
2
+ `)}function formatOidcTokenFailure(e){switch(e.kind){case`resolution-failed`:return`The local Vercel OIDC token could not be resolved: ${e.message}`;case`malformed-token`:return e.reason===`missing-payload`?`Vercel returned a local OIDC token without a JWT payload.`:`Vercel returned a local OIDC token whose payload is not valid JSON.`;case`invalid-claims`:return`The local Vercel OIDC token has invalid claims: ${e.invalidClaims.join(`, `)}.`;case`target-mismatch`:return`The local Vercel OIDC token does not match the resolved deployment: ${e.mismatchedClaims.join(`, `)}.`;default:return e}}export{formatVercelAuthChallengeMessage,isVercelAuthChallenge};
@@ -1 +1 @@
1
- import{isLocalDevelopmentServerUrl}from"#services/dev-client/request-headers.js";import{readDevelopmentRuntimeArtifactsRevision,rebuildDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";var LocalDevelopmentRuntimeArtifactSessionRefresher=class{#e;#t;#n;constructor(t){this.#e=isLocalDevelopmentServerUrl(t.serverUrl),this.#t=t.serverUrl}clear(){this.#n=void 0}async refresh(e){return shouldRefreshRuntimeArtifactsForTurn(e)?await this.#r({...e,rebuild:!0}):e.session}async refreshIdle(e){return await this.#r({...e,rebuild:!1})}async#r(e){if(!this.#e)return e.session;let n=(e.rebuild?await rebuildDevelopmentRuntimeArtifacts({serverUrl:this.#t}):void 0)??await readDevelopmentRuntimeArtifactsRevision({serverUrl:this.#t});if(n===void 0)return e.session;let r=e.session,i=this.#n;return i!==void 0&&i!==n&&(r.state.continuationToken!==void 0&&(r=e.createSession()),await e.onRuntimeArtifactsChanged?.({previousRevision:i,revision:n})),this.#n=n,r}};function shouldRefreshRuntimeArtifactsForTurn(e){return e.message!==void 0&&(e.inputResponses?.length??0)===0}function createDevelopmentRuntimeArtifactSessionRefresher(e){return new LocalDevelopmentRuntimeArtifactSessionRefresher(e)}export{createDevelopmentRuntimeArtifactSessionRefresher};
1
+ import{isLocalDevelopmentServerUrl}from"#services/dev-client/local-host.js";import{readDevelopmentRuntimeArtifactsRevision,rebuildDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";var LocalDevelopmentRuntimeArtifactSessionRefresher=class{#e;#t;#n;constructor(t){this.#e=isLocalDevelopmentServerUrl(t.serverUrl),this.#t=t.serverUrl}clear(){this.#n=void 0}async refresh(e){return shouldRefreshRuntimeArtifactsForTurn(e)?await this.#r({...e,rebuild:!0}):e.session}async refreshIdle(e){return await this.#r({...e,rebuild:!1})}async#r(e){if(!this.#e)return e.session;let n=(e.rebuild?await rebuildDevelopmentRuntimeArtifacts({serverUrl:this.#t}):void 0)??await readDevelopmentRuntimeArtifactsRevision({serverUrl:this.#t});if(n===void 0)return e.session;let r=e.session,i=this.#n;return i!==void 0&&i!==n&&(r.state.continuationToken!==void 0&&(r=e.createSession()),await e.onRuntimeArtifactsChanged?.({previousRevision:i,revision:n})),this.#n=n,r}};function shouldRefreshRuntimeArtifactsForTurn(e){return e.message!==void 0&&(e.inputResponses?.length??0)===0}function createDevelopmentRuntimeArtifactSessionRefresher(e){return new LocalDevelopmentRuntimeArtifactSessionRefresher(e)}export{createDevelopmentRuntimeArtifactSessionRefresher};
@@ -12,15 +12,18 @@
12
12
  */
13
13
  /** The color primitives the row painter needs; satisfied by both the TUI theme and the CLI palette. */
14
14
  export interface RowColors {
15
+ blue(text: string): string;
15
16
  dim(text: string): string;
16
17
  green(text: string): string;
17
- cyan(text: string): string;
18
+ inverse(text: string): string;
18
19
  yellow(text: string): string;
19
20
  }
20
21
  /** The glyphs the row painter draws; the TUI passes theme-derived values, the CLI the unicode set. */
21
22
  export interface RowGlyphs {
22
- /** Hover marker the icon a row changes to under the cursor. */
23
+ /** Hollow cursor marker for an inert row. */
23
24
  pointer: string;
25
+ /** Filled cursor marker for an actionable row. */
26
+ selectedPointer: string;
24
27
  /** Completed / checked marker. */
25
28
  success: string;
26
29
  /** Available, un-hovered marker. */
@@ -58,9 +61,8 @@ interface OptionRowInput {
58
61
  /** Spaces inserted before the hint's dot so hints tab-align to a shared column. */
59
62
  hintPadding?: number;
60
63
  /**
61
- * Accent for the cursor pointer and active label. Defaults to cyan; "warning"
62
- * makes them yellow so the pointer matches an attention row (e.g. a required,
63
- * yellow-labelled action).
64
+ * Accent for an available row. "warning" keeps an attention row yellow at
65
+ * rest and under the cursor highlight.
64
66
  */
65
67
  accent?: "warning";
66
68
  }
@@ -78,6 +80,10 @@ export declare function resolveOptionRowState(option: {
78
80
  locked?: boolean;
79
81
  lockedReason?: string;
80
82
  }, checked: boolean): OptionRowState;
83
+ /** Paints a row with the shared leading cell and optional cursor highlight. */
84
+ export declare function renderCursorRow(text: string, selected: boolean, colors: Pick<RowColors, "blue" | "inverse" | "yellow">, accent?: "warning"): string;
85
+ /** Prefixes a continuation line so its text starts in the option label column. */
86
+ export declare function renderOptionRowContinuation(text: string): string;
81
87
  /**
82
88
  * Paints one option row as `glyph label · hint`. The glyph reflects state with
83
89
  * hover taking precedence for focusable rows: available rows use the active
@@ -1 +1 @@
1
- const UNICODE_ROW_GLYPHS={pointer:`▷`,success:`✓`,placeholder:`◦`,dot:`·`};function resolveOptionRowState(e,t){if(Number(e.disabled===!0)+Number(e.completed===!0)+Number(e.locked===!0)>1)throw Error(`An option row cannot combine disabled, completed, or locked states.`);if(e.disabled===!0){let t={kind:`disabled`};return e.disabledReason!==void 0&&(t.reason=e.disabledReason),e.disabledReasonTone!==void 0&&(t.reasonTone=e.disabledReasonTone),t}if(e.completed===!0)return{kind:`completed`};if(e.locked===!0){let t={kind:`locked`};return e.lockedReason!==void 0&&(t.reason=e.lockedReason),t}return{kind:`available`,checked:t}}function parenthetical(e){return e===void 0?``:` (${e})`}function unfocusedGlyph(e){return e.placeholder?e.colors.dim(e.glyphs.placeholder):` `}function disabledLabel(e,t,n){let r=parenthetical(t.reason);return t.reasonTone===`warning`?`${n.dim(e)}${n.yellow(r)}`:n.dim(`${e}${r}`)}function optionRowPresentation(e){let{colors:t,glyphs:n,state:r}=e,i=e.accent===`warning`?t.yellow:t.cyan;switch(r.kind){case`available`:return e.isCursor?{glyph:i(n.pointer),label:i(e.label)}:{glyph:r.checked?t.green(n.success):unfocusedGlyph(e),label:e.label};case`completed`:return{glyph:e.isCursor?t.dim(n.pointer):t.green(n.success),label:t.dim(e.label)};case`disabled`:return{glyph:e.isCursor?t.dim(n.pointer):unfocusedGlyph(e),label:disabledLabel(e.label,r,t)};case`locked`:return{glyph:t.dim(t.green(n.success)),label:t.dim(`${e.label}${parenthetical(r.reason)}`)}}return r}function renderOptionRow(e){let{colors:t,glyphs:n}=e,{glyph:r,label:i}=optionRowPresentation(e),a=e.hint;e.isCursor&&e.focusHint!==void 0&&(a=e.focusHint);let o=``;return a!==void 0&&(o=t.dim(`${` `.repeat((e.hintPadding??0)+1)}${n.dot} ${a}`)),`${r} ${i}${o}`}export{UNICODE_ROW_GLYPHS,renderOptionRow,resolveOptionRowState};
1
+ const UNICODE_ROW_GLYPHS={pointer:`▷`,selectedPointer:`▶`,success:`✓`,placeholder:`◦`,dot:`·`};function resolveOptionRowState(e,t){if(Number(e.disabled===!0)+Number(e.completed===!0)+Number(e.locked===!0)>1)throw Error(`An option row cannot combine disabled, completed, or locked states.`);if(e.disabled===!0){let t={kind:`disabled`};return e.disabledReason!==void 0&&(t.reason=e.disabledReason),e.disabledReasonTone!==void 0&&(t.reasonTone=e.disabledReasonTone),t}if(e.completed===!0)return{kind:`completed`};if(e.locked===!0){let t={kind:`locked`};return e.lockedReason!==void 0&&(t.reason=e.lockedReason),t}return{kind:`available`,checked:t}}function parenthetical(e){return e===void 0?``:` (${e})`}function unfocusedGlyph(e){return e.placeholder?e.colors.dim(e.glyphs.placeholder):` `}function disabledLabel(e,t,n){let r=parenthetical(t.reason);return t.reasonTone===`warning`?`${n.dim(e)}${n.yellow(r)}`:n.dim(`${e}${r}`)}function optionRowPresentation(e){let{colors:t,glyphs:n,state:r}=e;switch(r.kind){case`available`:return e.isCursor?{glyph:n.selectedPointer,label:e.label}:{glyph:r.checked?t.green(n.success):unfocusedGlyph(e),label:e.accent===`warning`?t.yellow(e.label):e.label};case`completed`:return{glyph:e.isCursor?t.dim(n.pointer):t.green(n.success),label:t.dim(e.label)};case`disabled`:return{glyph:e.isCursor?t.dim(n.pointer):unfocusedGlyph(e),label:disabledLabel(e.label,r,t)};case`locked`:return{glyph:t.dim(t.green(n.success)),label:t.dim(`${e.label}${parenthetical(r.reason)}`)}}return r}function renderCursorRow(e,t,n,r){if(!t)return` ${e}`;let i=r===`warning`?n.yellow:n.blue;return n.inverse(i(` ${e} `))}function renderOptionRowContinuation(e){return` ${e}`}function renderOptionRow(e){let{colors:t,glyphs:n}=e,{glyph:r,label:i}=optionRowPresentation(e),a=e.isCursor&&e.state.kind===`available`,o=e.hint;e.isCursor&&e.focusHint!==void 0&&(o=e.focusHint);let s=``;if(o!==void 0){let r=Math.max(0,(e.hintPadding??0)+1-Number(a));s=t.dim(`${` `.repeat(r)}${n.dot} ${o}`)}return`${renderCursorRow(`${r} ${i}`,a,t,e.accent)}${s}`}export{UNICODE_ROW_GLYPHS,renderCursorRow,renderOptionRow,renderOptionRowContinuation,resolveOptionRowState};
@@ -5,6 +5,7 @@ export type PromptState = "initial" | "active" | "submit" | "cancel" | "error";
5
5
  export type PromptValue = string | number | boolean;
6
6
  /** Coloring operations used by prompt rendering without coupling to a color library. */
7
7
  export interface PromptColors {
8
+ blue(text: string): string;
8
9
  bold(text: string): string;
9
10
  cyan(text: string): string;
10
11
  dim(text: string): string;
@@ -20,17 +21,16 @@ export interface PromptColors {
20
21
  export interface PromptOption<T extends PromptValue> {
21
22
  value: T;
22
23
  label: string;
23
- /** Short inline annotation shown in parentheses while the option is highlighted. */
24
+ /** Supporting copy; stacked prompts render newline-separated text on separate rows. */
24
25
  hint?: string;
25
26
  /** Short inline annotation shown dimmed only while the cursor is on this row. */
26
27
  focusHint?: string;
27
28
  /**
28
- * Longer, display-only explanation shown dimmed on the line below the option
29
- * while it is highlighted during navigation. It is navigation-only: once a
30
- * choice is submitted only the label remains.
29
+ * Longer, display-only explanation for the highlighted option. Its prompt
30
+ * chooses the placement; it is hidden once a choice is submitted.
31
31
  */
32
32
  description?: string;
33
- /** Cursor-pointer/active-label accent; "warning" turns them yellow for an attention row. */
33
+ /** Row accent; "warning" stays yellow both at rest and under the cursor. */
34
34
  accent?: "warning";
35
35
  disabled?: boolean;
36
36
  disabledReason?: string;
@@ -125,7 +125,7 @@ export declare function renderSelectPrompt<T extends PromptValue>(input: {
125
125
  /**
126
126
  * Renders the virtual Submit row that closes every multi-select list. It has
127
127
  * no checkbox — its bold label sits in the checkbox column, trails a green
128
- * check, and brightens under the cursor; enter confirms the checklist only
128
+ * check, and uses the shared cursor highlight; enter confirms the checklist only
129
129
  * from here. The label reads "Skip" while an optional checklist has nothing
130
130
  * picked (the caller computes that), so an empty confirm is honest about what
131
131
  * it does. Callers put a blank rail line above it to set it apart from the
@@ -1,5 +1,5 @@
1
- import{W}from"../../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{UNICODE_ROW_GLYPHS,renderOptionRow,resolveOptionRowState}from"./option-row.js";const RAIL=`│`,CORNER=`└`;function bulletFor(e,t){switch(e){case`initial`:case`active`:return t.green(`△`);case`submit`:return t.green(`▲`);case`cancel`:return t.gray(`▲`);case`error`:return t.red(`▲`)}}function railFor(e,t){switch(e){case`initial`:case`active`:return t.white(`│`);case`submit`:return t.green(`│`);case`cancel`:return t.gray(`│`);case`error`:return t.red(`│`)}}function cornerFor(e,t){switch(e){case`initial`:case`active`:return t.white(`└`);case`submit`:return t.green(`└`);case`cancel`:return t.gray(`└`);case`error`:return t.red(`└`)}}function formatPromptHeader(e,t,n){return`${n.leadingRail===`green`?n.colors.green(`│`):n.colors.white(`│`)}\n${bulletFor(e,n.colors)} ${t}\n`}function formatPromptSubmission(e,t,n,r){let i=r.leadingRail===`green`?r.colors.green(`│`):r.colors.white(`│`),a=n===``?``:` ${n}`;return`${i}\n${bulletFor(e,r.colors)} ${r.colors.dim(t)}${a}`}function formatPromptOpener(e,t,n){return`\n${n.bold(n.white(`▲`))} ${n.bold(e)}\n ${n.dim(t)}\n${n.white(`│`)}\n`}function formatPromptOutro(e,t){let n=e.replace(/\n/g,`
1
+ import{W}from"../../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{UNICODE_ROW_GLYPHS,renderCursorRow,renderOptionRow,resolveOptionRowState}from"./option-row.js";const RAIL=`│`,CORNER=`└`;function bulletFor(e,t){switch(e){case`initial`:case`active`:return t.green(`△`);case`submit`:return t.green(`▲`);case`cancel`:return t.gray(`▲`);case`error`:return t.red(`▲`)}}function railFor(e,t){switch(e){case`initial`:case`active`:return t.white(`│`);case`submit`:return t.green(`│`);case`cancel`:return t.gray(`│`);case`error`:return t.red(`│`)}}function cornerFor(e,t){switch(e){case`initial`:case`active`:return t.white(`└`);case`submit`:return t.green(`└`);case`cancel`:return t.gray(`└`);case`error`:return t.red(`└`)}}function formatPromptHeader(e,t,n){return`${n.leadingRail===`green`?n.colors.green(`│`):n.colors.white(`│`)}\n${bulletFor(e,n.colors)} ${t}\n`}function formatPromptSubmission(e,t,n,r){let i=r.leadingRail===`green`?r.colors.green(`│`):r.colors.white(`│`),a=n===``?``:` ${n}`;return`${i}\n${bulletFor(e,r.colors)} ${r.colors.dim(t)}${a}`}function formatPromptOpener(e,t,n){return`\n${n.bold(n.white(`▲`))} ${n.bold(e)}\n ${n.dim(t)}\n${n.white(`│`)}\n`}function formatPromptOutro(e,t){let n=e.replace(/\n/g,`
2
2
  `);return`${t.green(`│`)}\n${t.green(`●`)} ${n}\n`}function formatPromptCancellation(e,t){let n=e.replace(/\n/g,`
3
3
  `);return`${t.red(`│`)}\n${t.red(`●`)} ${t.red(n)}\n`}function formatRailLine(t,n,r){if(t===``)return`${n.green(`│`)}\n`;let i=`${n.green(`│`)} `;return`${t.split(`
4
4
  `).map(t=>t===``?n.green(`│`):W(r,t,i)).join(`
5
- `)}\n`}function renderMultiselectPrompt(e){let t=railFor(e.state,e.colors),n=formatPromptHeader(e.state,e.message,{colors:e.colors,leadingRail:e.leadingRail}),r=new Set(e.selectedValues),i=e.options.some(e=>!e.disabled)?``:`\n${t}\n${t} ${e.colors.dim(`(no channels available to add)`)}`;switch(e.state){case`submit`:{let t=r.size===0?e.colors.dim(`(none selected)`):e.options.filter(e=>r.has(e.value)).map(e=>e.label).join(`, `);return formatPromptSubmission(e.state,e.message,t,{colors:e.colors,leadingRail:e.leadingRail})}case`cancel`:return`${n}${t} ${e.colors.strikethrough(e.colors.dim(`cancelled`))}\n${t}`;case`error`:{let r=renderMultiselectRows({...e,rail:t});return`${n.trim()}\n${t} ${r}${i}\n${cornerFor(e.state,e.colors)} ${e.colors.red(e.error??``)}\n`}case`initial`:case`active`:return`${n}${t} ${renderMultiselectRows({...e,rail:t})}${i}\n${cornerWithNote(cornerFor(e.state,e.colors),e.footerNote)}\n`}}function cornerWithNote(e,t){return t?`${e} ${t}`:e}function renderSelectPrompt(e){let t=railFor(e.state,e.colors),n=formatPromptHeader(e.state,e.message,{colors:e.colors,leadingRail:e.leadingRail}),r=e.options[e.cursor];switch(e.state){case`submit`:{let t=r?r.label:``;return formatPromptSubmission(e.state,e.message,t,{colors:e.colors,leadingRail:e.leadingRail})}case`cancel`:return`${n}${t} ${r?e.colors.strikethrough(e.colors.dim(r.label)):``}\n${t}`;case`initial`:case`active`:case`error`:{let r=labelColumnWidth(e.options);return`${n}${t} ${e.options.map((n,i)=>{let a=i===e.cursor;return`${optionRow(n,{colors:e.colors,isCursor:a,isChecked:!1,placeholder:!1,hintPadding:r-n.label.length})}${descriptionLine(n,a,t,e.colors)}`}).join(`\n${t} `)}\n${cornerWithNote(cornerFor(e.state,e.colors),e.footerNote)}\n`}}}function labelColumnWidth(e){return e.reduce((e,t)=>Math.max(e,t.label.length),0)}function optionRow(e,i){return renderOptionRow({colors:i.colors,glyphs:UNICODE_ROW_GLYPHS,label:e.label,hint:e.hint,focusHint:e.focusHint,accent:e.accent,isCursor:i.isCursor,state:resolveOptionRowState(e,i.isChecked),placeholder:i.placeholder,hintPadding:i.hintPadding})}function descriptionLine(e,t,n,r){return t&&e.description&&!e.disabled?`\n${n} ${r.dim(e.description)}`:``}function renderSubmitRow(e,n,r=`Submit`){let i=e?n.cyan(UNICODE_ROW_GLYPHS.pointer):` `,a=n.bold(r);return`${i} ${e?a:n.dim(a)} ${n.green(UNICODE_ROW_GLYPHS.success)}`}function renderMultiselectRows(e){let t=new Set(e.selectedValues),n=labelColumnWidth(e.options),r=e.options.map((r,i)=>{let a=i===e.cursor;return`${optionRow(r,{colors:e.colors,isCursor:a,isChecked:t.has(r.value),placeholder:!0,hintPadding:n-r.label.length})}${descriptionLine(r,a,e.rail,e.colors)}`}).join(`\n${e.rail} `),i=renderSubmitRow(e.cursor===e.options.length,e.colors,e.submitLabel);return`${r}\n${e.rail}\n${e.rail} ${i}`}function searchableHelpLine(e,t,n){let r=(n?[[t.cyan(`type`),`to filter`]]:[[t.cyan(`type`),`to filter`],[t.cyan(`enter`),`to select`]]).map(([e,n])=>`${e}${t.dim(` ${n}`)}`).join(t.dim(` · `));return`\n${e} ${t.dim(`(`)}${r}${t.dim(`)`)}`}function renderSearchableSelect(e){let{colors:t}=e,n=railFor(e.state,t),r=formatPromptHeader(e.state,e.message,{colors:t,leadingRail:e.leadingRail});if(e.state===`submit`)return formatPromptSubmission(e.state,e.message,e.submitDisplay,{colors:t,leadingRail:e.leadingRail});if(e.state===`cancel`)return`${r}${n} ${t.strikethrough(t.dim(e.filter))}${e.filter.trim()?`\n${n}`:``}`;let i=new Set(e.selectedValues),a=0;for(;e.options[a]?.featured;)a+=1;let o=e.viewSize??8,s=e.filter===``&&a>0?Math.min(a,o):o,c=e.multiple&&e.cursor>=e.options.length,l=!c&&e.cursor>=e.options.length?0:e.cursor,u=t.inverse(` `);e.filter.length>0?u=e.filter+t.inverse(` `):e.placeholder&&(u=t.dim(e.placeholder));let d=Math.max(0,Math.min(l-Math.floor(s/2),Math.max(0,e.options.length-s))),f=Math.min(d+s,e.options.length),p=e.options.slice(d,f),m=labelColumnWidth(p),h=p.length===0?t.dim(`(no matches)`):p.map((r,a)=>{let o=!c&&a+d===l;return`${optionRow(r,{colors:t,isCursor:o,isChecked:e.multiple&&i.has(r.value),placeholder:!1,hintPadding:m-r.label.length})}${descriptionLine(r,o,n,t)}`}).join(`\n${n} `),g=e.multiple?`\n${n}\n${n} ${renderSubmitRow(c,t,e.submitLabel)}`:``,_=e.options.length>p.length?`\n${n} ${t.dim(`↑↓ ${e.options.length} options, showing ${d+1}–${f}`)}`:``,v=searchableHelpLine(n,t,e.multiple),y=`${n} ${t.dim(` `)} ${u}\n${n} ${h}${g}${_}${v}`;return e.state===`error`?`${r.trim()}\n${y}\n${cornerFor(e.state,t)} ${t.red(e.error??``)}\n`:`${r}${y}\n${cornerWithNote(cornerFor(e.state,t),e.footerNote)}\n`}export{CORNER,RAIL,bulletFor,cornerFor,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,renderMultiselectPrompt,renderSearchableSelect,renderSelectPrompt,renderSubmitRow};
5
+ `)}\n`}function renderMultiselectPrompt(e){let t=railFor(e.state,e.colors),n=formatPromptHeader(e.state,e.message,{colors:e.colors,leadingRail:e.leadingRail}),r=new Set(e.selectedValues),i=e.options.some(e=>!e.disabled)?``:`\n${t}\n${t} ${e.colors.dim(`(no channels available to add)`)}`;switch(e.state){case`submit`:{let t=r.size===0?e.colors.dim(`(none selected)`):e.options.filter(e=>r.has(e.value)).map(e=>e.label).join(`, `);return formatPromptSubmission(e.state,e.message,t,{colors:e.colors,leadingRail:e.leadingRail})}case`cancel`:return`${n}${t} ${e.colors.strikethrough(e.colors.dim(`cancelled`))}\n${t}`;case`error`:{let r=renderMultiselectRows({...e,rail:t});return`${n.trim()}\n${t} ${r}${i}\n${cornerFor(e.state,e.colors)} ${e.colors.red(e.error??``)}\n`}case`initial`:case`active`:return`${n}${t} ${renderMultiselectRows({...e,rail:t})}${i}\n${cornerWithNote(cornerFor(e.state,e.colors),e.footerNote)}\n`}}function cornerWithNote(e,t){return t?`${e} ${t}`:e}function renderSelectPrompt(e){let t=railFor(e.state,e.colors),n=formatPromptHeader(e.state,e.message,{colors:e.colors,leadingRail:e.leadingRail}),r=e.options[e.cursor];switch(e.state){case`submit`:{let t=r?r.label:``;return formatPromptSubmission(e.state,e.message,t,{colors:e.colors,leadingRail:e.leadingRail})}case`cancel`:return`${n}${t} ${r?e.colors.strikethrough(e.colors.dim(r.label)):``}\n${t}`;case`initial`:case`active`:case`error`:{let r=labelColumnWidth(e.options);return`${n}${t} ${e.options.map((n,i)=>{let a=i===e.cursor;return`${optionRow(n,{colors:e.colors,isCursor:a,isChecked:!1,placeholder:!1,hintPadding:r-n.label.length})}${descriptionLine(n,a,t,e.colors)}`}).join(`\n${t} `)}\n${cornerWithNote(cornerFor(e.state,e.colors),e.footerNote)}\n`}}}function labelColumnWidth(e){return e.reduce((e,t)=>Math.max(e,t.label.length),0)}function optionRow(e,n){return renderOptionRow({colors:n.colors,glyphs:UNICODE_ROW_GLYPHS,label:e.label,hint:e.hint,focusHint:e.focusHint,accent:e.accent,isCursor:n.isCursor,state:resolveOptionRowState(e,n.isChecked),placeholder:n.placeholder,hintPadding:n.hintPadding})}function descriptionLine(e,t,n,r){return t&&e.description&&!e.disabled?`\n${n} ${r.dim(e.description)}`:``}function renderSubmitRow(e,r,i=`Submit`){let a=r.bold(i),o=e?`${UNICODE_ROW_GLYPHS.selectedPointer} ${a}`:` ${r.dim(a)}`,s=e?``:` `;return`${renderCursorRow(o,e,r)}${s}${r.green(UNICODE_ROW_GLYPHS.success)}`}function renderMultiselectRows(e){let t=new Set(e.selectedValues),n=labelColumnWidth(e.options),r=e.options.map((r,i)=>{let a=i===e.cursor;return`${optionRow(r,{colors:e.colors,isCursor:a,isChecked:t.has(r.value),placeholder:!0,hintPadding:n-r.label.length})}${descriptionLine(r,a,e.rail,e.colors)}`}).join(`\n${e.rail} `),i=renderSubmitRow(e.cursor===e.options.length,e.colors,e.submitLabel);return`${r}\n${e.rail}\n${e.rail} ${i}`}function searchableHelpLine(e,t,n){let r=(n?[[t.cyan(`type`),`to filter`]]:[[t.cyan(`type`),`to filter`],[t.cyan(`enter`),`to select`]]).map(([e,n])=>`${e}${t.dim(` ${n}`)}`).join(t.dim(` · `));return`\n${e} ${t.dim(`(`)}${r}${t.dim(`)`)}`}function renderSearchableSelect(e){let{colors:t}=e,n=railFor(e.state,t),r=formatPromptHeader(e.state,e.message,{colors:t,leadingRail:e.leadingRail});if(e.state===`submit`)return formatPromptSubmission(e.state,e.message,e.submitDisplay,{colors:t,leadingRail:e.leadingRail});if(e.state===`cancel`)return`${r}${n} ${t.strikethrough(t.dim(e.filter))}${e.filter.trim()?`\n${n}`:``}`;let i=new Set(e.selectedValues),a=0;for(;e.options[a]?.featured;)a+=1;let o=e.viewSize??8,s=e.filter===``&&a>0?Math.min(a,o):o,c=e.multiple&&e.cursor>=e.options.length,l=!c&&e.cursor>=e.options.length?0:e.cursor,u=t.inverse(` `);e.filter.length>0?u=e.filter+t.inverse(` `):e.placeholder&&(u=t.dim(e.placeholder));let d=Math.max(0,Math.min(l-Math.floor(s/2),Math.max(0,e.options.length-s))),f=Math.min(d+s,e.options.length),p=e.options.slice(d,f),m=labelColumnWidth(p),h=p.length===0?t.dim(`(no matches)`):p.map((r,a)=>{let o=!c&&a+d===l;return`${optionRow(r,{colors:t,isCursor:o,isChecked:e.multiple&&i.has(r.value),placeholder:!1,hintPadding:m-r.label.length})}${descriptionLine(r,o,n,t)}`}).join(`\n${n} `),g=e.multiple?`\n${n}\n${n} ${renderSubmitRow(c,t,e.submitLabel)}`:``,_=e.options.length>p.length?`\n${n} ${t.dim(`↑↓ ${e.options.length} options, showing ${d+1}–${f}`)}`:``,v=searchableHelpLine(n,t,e.multiple),y=`${n} ${t.dim(` `)} ${u}\n${n} ${h}${g}${_}${v}`;return e.state===`error`?`${r.trim()}\n${y}\n${cornerFor(e.state,t)} ${t.red(e.error??``)}\n`:`${r}${y}\n${cornerWithNote(cornerFor(e.state,t),e.footerNote)}\n`}export{CORNER,RAIL,bulletFor,cornerFor,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,renderMultiselectPrompt,renderSearchableSelect,renderSelectPrompt,renderSubmitRow};
@@ -94,6 +94,8 @@ export declare function detectModelProviderStatus(appRoot: string, options?: Pro
94
94
  export declare function runModelFlow(input: {
95
95
  appRoot: string;
96
96
  prompter: Prompter;
97
+ /** Opens provider setup before the root menu when runtime evidence requires it. */
98
+ initialStep?: "provider";
97
99
  signal?: AbortSignal;
98
100
  deps?: Partial<ModelFlowDeps>;
99
101
  }): Promise<ModelFlowResult>;
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runVercelFlow}from"./vercel.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const MODEL_MENU_MESSAGE=``;function providerStatusHint(e,t=e=>e){return e.kind===`gateway-project`?`AI Gateway (Linked to ${e.teamName===void 0?t(e.projectName):`${t(e.projectName)} in ${t(e.teamName)}`})`:`AI Gateway (${e.envKey} in ${e.envFile})`}function modelMenuRows(e,t,n,r){let i;r?(i={value:`model`,label:`Change model`},e!==null&&(i.hint=e)):i={value:`model`,label:`Change model`,disabled:!0,description:`Set via an SDK model call in agent.ts; edit the source to change it`};let a;return a=n?.kind===`external`?{value:`provider`,label:`Change provider`,disabled:!0,description:`Disabled in external endpoint mode`}:t.kind===`unset`?{value:`provider`,label:import_picocolors.default.bold(import_picocolors.default.yellow(`Configure provider`)),hint:`Required to enable the agent`,accent:`warning`}:{value:`provider`,label:`Change provider`,hint:providerStatusHint(t,import_picocolors.default.bold)},[i,a,{value:`done`,label:`Done`}]}async function detectModelProviderStatus(e,t={}){let[n,i,a]=await Promise.all([detectProjectIdentity(e,t),findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(n!==void 0){let e={kind:`gateway-project`,projectName:n.projectName};return n.teamName!==void 0&&(e.teamName=n.teamName),e}return i===void 0?a===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:a}:{kind:`gateway-key`,envKey:`AI_GATEWAY_API_KEY`,envFile:i}}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps};async function checkProject(e){let t=n.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let detectProvider=()=>i.detectProviderStatus(t,{signal:r}),[{id:o,routing:s,editable:c},l]=await checkProject(()=>Promise.all([i.readCurrentModel(t),detectProvider()]));r?.throwIfAborted();let u,d,p=s?.kind===`external`?{tone:`warning`,text:"`agent.ts` specifies a model provider directly. In-TUI configuration is restricted to AI Gateway endpoints."}:void 0,m=l.kind===`unset`&&s?.kind!==`external`?`provider`:c?`model`:s?.kind===`external`?`done`:`provider`;for(;;){let e;try{e=await n.select({message:``,options:modelMenuRows(o,l,s,c),hintLayout:`stacked`,initialValue:m,notices:p===void 0?[]:[p]})}catch(e){if(!(e instanceof WizardCancelledError))throw e;break}if(e===`done`)break;if(e===`model`){let e=await pickModelFromCatalog({appRoot:t,prompter:n,current:o,signal:r,deps:i.selectModel});if(e===void 0){m=`model`;continue}r?.throwIfAborted(),u=await i.applyModel({appRoot:t,slug:e}),r?.throwIfAborted();break}let f=await i.runVercelFlow({appRoot:t,prompter:n,signal:r});if(r?.throwIfAborted(),f.kind===`cancelled`){m=`provider`;continue}if(`outcome`in f){m=`done`;continue}l=await checkProject(detectProvider),r?.throwIfAborted(),d={status:l},f.credential!==void 0&&(d.credential=f.credential);break}if(u===void 0&&d===void 0)return{kind:`cancelled`};let h={kind:`done`};return u!==void 0&&(h.modelMessage=formatApplyModelOutcome(u)),d!==void 0&&(h.providerOutcome=d),h}async function pickModelFromCatalog(e){let{appRoot:t,prompter:r,current:a,signal:o}=e,f=e.deps?.fetchModels??fetchGatewayCatalog,p={asker:interactiveAsker(r),deps:{fetchModels:async e=>{let t=r.log.spinner?.(`Loading the model catalog...`);try{return await f(e)}finally{t?.stop()}}}};a!==null&&(p.defaultModel=a);let m=await runInteractive([selectModel(p)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(r),{snapshot:snapshotSetupState,signal:o});return m.kind===`cancelled`?void 0:m.state.modelId}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model changed to ${import_picocolors.default.bold(e.to)}. Live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return{kind:`rejected`,message:r};let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`}:a.from===a.to?{kind:`unchanged`,model:a.to}:{kind:`changed`,to:a.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e),n=t?.manifest.config.model;return{id:n?.id??null,routing:n?.routing??null,editable:n!==void 0&&n.source===void 0}}catch{return{id:null,routing:null,editable:!1}}}async function modelChangeRefusalForUneditableModel(e){let{editable:t,routing:n}=await readCurrentAgentModel(e);return t?null:`Model is set via ${n?.kind===`external`?`the external provider \`${n.provider}\``:`an SDK model call`} in agent.ts, not a string literal; /model can't rewrite it. Edit \`model\` in agent.ts.`}export{MODEL_MENU_MESSAGE,changeAgentModel,detectModelProviderStatus,formatApplyModelOutcome,modelChangeRefusalForUneditableModel,runModelFlow};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runVercelFlow}from"./vercel.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const MODEL_MENU_MESSAGE=``;function providerStatusHint(e,t=e=>e){return e.kind===`gateway-project`?`AI Gateway (Linked to ${e.teamName===void 0?t(e.projectName):`${t(e.projectName)} in ${t(e.teamName)}`})`:`AI Gateway (${e.envKey} in ${e.envFile})`}function modelMenuRows(e,t,n,r){let i;r?(i={value:`model`,label:`Change model`},e!==null&&(i.hint=e)):i={value:`model`,label:`Change model`,disabled:!0,description:`Set via an SDK model call in agent.ts; edit the source to change it`};let a;return a=n?.kind===`external`?{value:`provider`,label:`Change provider`,disabled:!0,description:`Disabled in external endpoint mode`}:t.kind===`unset`?{value:`provider`,label:import_picocolors.default.bold(import_picocolors.default.yellow(`Configure provider`)),hint:`Required to enable the agent`,accent:`warning`}:{value:`provider`,label:`Change provider`,hint:providerStatusHint(t,import_picocolors.default.bold)},[i,a,{value:`done`,label:`Done`}]}async function detectModelProviderStatus(e,t={}){let[n,i,a]=await Promise.all([detectProjectIdentity(e,t),findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(n!==void 0){let e={kind:`gateway-project`,projectName:n.projectName};return n.teamName!==void 0&&(e.teamName=n.teamName),e}return i===void 0?a===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:a}:{kind:`gateway-key`,envKey:`AI_GATEWAY_API_KEY`,envFile:i}}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps};async function checkProject(e){let t=n.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let detectProvider=()=>i.detectProviderStatus(t,{signal:r}),[{id:o,routing:s,editable:c},l]=await checkProject(()=>Promise.all([i.readCurrentModel(t),detectProvider()]));r?.throwIfAborted();let u,d,p=s?.kind===`external`?{tone:`warning`,text:"`agent.ts` specifies a model provider directly. In-TUI configuration is restricted to AI Gateway endpoints."}:void 0,m=l.kind===`unset`&&s?.kind!==`external`?`provider`:c?`model`:s?.kind===`external`?`done`:`provider`,h=s?.kind!==`external`&&(e.initialStep===`provider`||l.kind===`unset`);for(;;){let e;if(h)h=!1,e=`provider`;else try{e=await n.select({message:``,options:modelMenuRows(o,l,s,c),hintLayout:`stacked`,initialValue:m,notices:p===void 0?[]:[p]})}catch(e){if(!(e instanceof WizardCancelledError))throw e;break}if(e===`done`)break;if(e===`model`){let e=await pickModelFromCatalog({appRoot:t,prompter:n,current:o,signal:r,deps:i.selectModel});if(e===void 0){m=`model`;continue}r?.throwIfAborted(),u=await i.applyModel({appRoot:t,slug:e}),r?.throwIfAborted();break}let f=await i.runVercelFlow({appRoot:t,prompter:n,signal:r});if(r?.throwIfAborted(),f.kind===`cancelled`){m=`provider`;continue}if(`outcome`in f){m=`done`;continue}l=await checkProject(detectProvider),r?.throwIfAborted(),d={status:l},f.credential!==void 0&&(d.credential=f.credential);break}if(u===void 0&&d===void 0)return{kind:`cancelled`};let g={kind:`done`};return u!==void 0&&(g.modelMessage=formatApplyModelOutcome(u)),d!==void 0&&(g.providerOutcome=d),g}async function pickModelFromCatalog(e){let{appRoot:t,prompter:r,current:a,signal:o}=e,f=e.deps?.fetchModels??fetchGatewayCatalog,p={asker:interactiveAsker(r),deps:{fetchModels:async e=>{let t=r.log.spinner?.(`Loading the model catalog...`);try{return await f(e)}finally{t?.stop()}}}};a!==null&&(p.defaultModel=a);let m=await runInteractive([selectModel(p)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(r),{snapshot:snapshotSetupState,signal:o});return m.kind===`cancelled`?void 0:m.state.modelId}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model changed to ${import_picocolors.default.bold(e.to)}. Live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return{kind:`rejected`,message:r};let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`}:a.from===a.to?{kind:`unchanged`,model:a.to}:{kind:`changed`,to:a.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e),n=t?.manifest.config.model;return{id:n?.id??null,routing:n?.routing??null,editable:n!==void 0&&n.source===void 0}}catch{return{id:null,routing:null,editable:!1}}}async function modelChangeRefusalForUneditableModel(e){let{editable:t,routing:n}=await readCurrentAgentModel(e);return t?null:`Model is set via ${n?.kind===`external`?`the external provider \`${n.provider}\``:`an SDK model call`} in agent.ts, not a string literal; /model can't rewrite it. Edit \`model\` in agent.ts.`}export{MODEL_MENU_MESSAGE,changeAgentModel,detectModelProviderStatus,formatApplyModelOutcome,modelChangeRefusalForUneditableModel,runModelFlow};
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  /** Link and production-deployment status for a Vercel project directory. */
2
3
  export type DeploymentState = "unlinked" | "linked" | "deployed";
3
4
  /** Vercel project data resolved from local link metadata and the API. */
@@ -7,6 +8,17 @@ export interface DeploymentInfo {
7
8
  orgId?: string;
8
9
  productionUrl?: string;
9
10
  }
11
+ declare const VercelProjectReferenceSchema: z.ZodObject<{
12
+ projectId: z.ZodString;
13
+ orgId: z.ZodString;
14
+ projectName: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ /** Validated Vercel owner and project identifiers. */
17
+ export type VercelProjectReference = z.infer<typeof VercelProjectReferenceSchema>;
18
+ /** Parses the complete Vercel owner and project environment pair. */
19
+ export declare function projectReferenceFromEnvironment(environment: Readonly<Record<string, string | undefined>>): VercelProjectReference | undefined;
20
+ /** Reads a validated Vercel project reference from `.vercel/project.json`. */
21
+ export declare function readProjectLink(projectPath: string): Promise<VercelProjectReference | undefined>;
10
22
  export interface ProjectDetectionOptions {
11
23
  signal?: AbortSignal;
12
24
  }
@@ -55,3 +67,4 @@ export declare function projectResolutionFromDeployResult(project: ProjectResolu
55
67
  }): ProjectResolution;
56
68
  export declare function isProjectResolved(project: ProjectResolution): boolean;
57
69
  export declare function projectProductionUrlFromResolution(project: ProjectResolution): string | undefined;
70
+ export {};
@@ -1 +1 @@
1
- import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(t,n,r,i){let a=await captureVercel([`api`,`/v9/projects/${t}?teamId=${n}`,`--scope`,n],{cwd:r,signal:i.signal});if(a.ok)try{let e=pickShortestAlias(JSON.parse(a.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e,r={}){r.signal?.throwIfAborted();let i;try{i=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return{state:`unlinked`}}let a;try{a=JSON.parse(i)}catch{return{state:`unlinked`}}let o=typeof a.projectId==`string`?a.projectId:void 0,s=typeof a.orgId==`string`?a.orgId:void 0;if(!o||!s)return{state:`unlinked`};let c=await fetchProductionAlias(o,s,e,r);return r.signal?.throwIfAborted(),{state:c?`deployed`:`linked`,projectId:o,orgId:s,productionUrl:c}}async function fetchVercelName(t,n,r,i){let a=await captureVercel([`api`,t,`--scope`,n],{cwd:r,signal:i.signal});if(a.ok)try{let e=JSON.parse(a.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e,r={}){r.signal?.throwIfAborted();let i;try{i=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return}let a;try{a=JSON.parse(i)}catch{return}let o=typeof a.projectId==`string`?a.projectId:void 0,s=typeof a.orgId==`string`?a.orgId:void 0;if(!o||!s)return;let[c,l]=await Promise.all([fetchVercelName(`/v9/projects/${o}?teamId=${s}`,s,e,r).then(e=>e??o),s.startsWith(`team_`)?fetchVercelName(`/v2/teams/${s}`,s,e,r):Promise.resolve(void 0)]);return r.signal?.throwIfAborted(),{projectName:c,teamName:l}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e,t={}){return projectResolutionFromDeployment(await detectDeployment(e,t))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment};
1
+ import{object,string}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const VercelProjectReferenceSchema=object({projectId:string().min(1),orgId:string().min(1),projectName:string().min(1).optional()}),VercelProjectEnvironmentSchema=object({VERCEL_ORG_ID:VercelProjectReferenceSchema.shape.orgId,VERCEL_PROJECT_ID:VercelProjectReferenceSchema.shape.projectId});function projectReferenceFromEnvironment(e){let t=VercelProjectEnvironmentSchema.safeParse(e);if(t.success)return{orgId:t.data.VERCEL_ORG_ID,projectId:t.data.VERCEL_PROJECT_ID}}async function readProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectReferenceSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(e,t,r,i){let a=await captureVercel([`api`,`/v9/projects/${e}?teamId=${t}`,`--scope`,t],{cwd:r,signal:i.signal});if(a.ok)try{let e=pickShortestAlias(JSON.parse(a.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e,t={}){t.signal?.throwIfAborted();let n=await readProjectLink(e);if(n===void 0)return{state:`unlinked`};let r=await fetchProductionAlias(n.projectId,n.orgId,e,t);return t.signal?.throwIfAborted(),{state:r?`deployed`:`linked`,projectId:n.projectId,orgId:n.orgId,productionUrl:r}}async function fetchVercelName(e,t,r,i){let a=await captureVercel([`api`,e,`--scope`,t],{cwd:r,signal:i.signal});if(a.ok)try{let e=JSON.parse(a.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e,t={}){t.signal?.throwIfAborted();let n=await readProjectLink(e);if(n===void 0)return;let[r,i]=await Promise.all([fetchVercelName(`/v9/projects/${n.projectId}?teamId=${n.orgId}`,n.orgId,e,t).then(e=>e??n.projectId),n.orgId.startsWith(`team_`)?fetchVercelName(`/v2/teams/${n.orgId}`,n.orgId,e,t):Promise.resolve(void 0)]);return t.signal?.throwIfAborted(),{projectName:r,teamName:i}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e,t={}){return projectResolutionFromDeployment(await detectDeployment(e,t))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectReferenceFromEnvironment,projectResolutionFromDeployResult,projectResolutionFromDeployment,readProjectLink};
@@ -1,4 +1,4 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.12.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.12.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -1,5 +1,5 @@
1
1
  export { byokProviderEnvVar, CURRENT_DIRECTORY_PROJECT_NAME, isEveProject, scaffoldBaseProject, type EvePackageContract, type ScaffoldBaseProjectOptions, } from "./create/project.js";
2
- export { DEFAULT_SLACK_CONNECTOR_SLUG, SLACK_CHANNEL_DEFAULT_ROUTE, deriveSlackConnectorSlug, ensureChannel, isNextJsProject, listAuthoredChannels, normalizeSlackConnectorSlug, type ChannelKind, type ChannelMutationResult, type EnsureChannelOptions, type SlackConnectorSlug, type WebPackageVersions, } from "./update/channels.js";
2
+ export { DEFAULT_SLACK_CONNECTOR_SLUG, SLACK_CHANNEL_DEFAULT_ROUTE, deriveSlackConnectorSlug, ensureChannel, hasVercelHostFramework, isNextJsProject, listAuthoredChannels, normalizeSlackConnectorSlug, type ChannelKind, type ChannelMutationResult, type EnsureChannelOptions, type SlackConnectorSlug, type WebPackageVersions, } from "./update/channels.js";
3
3
  export { SCAFFOLDABLE_CHANNELS, type ScaffoldableChannel } from "./channels-catalog.js";
4
4
  export { ensureConnection, listAuthoredConnections, type ConnectionInput, type ConnectionMutationAction, type ConnectionMutationResult, type EnsureConnectionOptions, } from "./update/connections.js";
5
5
  export { catalogSlugs, CONNECTION_CATALOG, CUSTOM_CONNECTION_SLUG, effectiveProtocols, endpointForProtocol, getCatalogEntry, isValidConnectionSlug, SUPPORTED_PROTOCOLS, type ConnectionAuthSpec, type ConnectionCatalogEntry, type ConnectionProtocol, type CustomConnectionInput, type EnvHeader, type McpEndpoint, type OpenApiEndpoint, } from "./connections/catalog.js";
@@ -1 +1 @@
1
- import{HumanActionRequiredError}from"../human-action.js";import{SCAFFOLDABLE_CHANNELS}from"./channels-catalog.js";import{CONNECTION_CATALOG,CUSTOM_CONNECTION_SLUG,SUPPORTED_PROTOCOLS,catalogSlugs,effectiveProtocols,endpointForProtocol,getCatalogEntry,isValidConnectionSlug}from"./connections/catalog.js";import{WriteFileExistsError}from"./files.js";import{CURRENT_DIRECTORY_PROJECT_NAME,byokProviderEnvVar,isEveProject,scaffoldBaseProject}from"./create/project.js";import{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug}from"./update/channels.js";import{ensureConnection,listAuthoredConnections}from"./update/connections.js";export{CONNECTION_CATALOG,CURRENT_DIRECTORY_PROJECT_NAME,CUSTOM_CONNECTION_SLUG,DEFAULT_SLACK_CONNECTOR_SLUG,HumanActionRequiredError,SCAFFOLDABLE_CHANNELS,SLACK_CHANNEL_DEFAULT_ROUTE,SUPPORTED_PROTOCOLS,WriteFileExistsError,byokProviderEnvVar,catalogSlugs,deriveSlackConnectorSlug,effectiveProtocols,endpointForProtocol,ensureChannel,ensureConnection,getCatalogEntry,isEveProject,isNextJsProject,isValidConnectionSlug,listAuthoredChannels,listAuthoredConnections,normalizeSlackConnectorSlug,scaffoldBaseProject};
1
+ import{HumanActionRequiredError}from"../human-action.js";import{SCAFFOLDABLE_CHANNELS}from"./channels-catalog.js";import{CONNECTION_CATALOG,CUSTOM_CONNECTION_SLUG,SUPPORTED_PROTOCOLS,catalogSlugs,effectiveProtocols,endpointForProtocol,getCatalogEntry,isValidConnectionSlug}from"./connections/catalog.js";import{WriteFileExistsError}from"./files.js";import{CURRENT_DIRECTORY_PROJECT_NAME,byokProviderEnvVar,isEveProject,scaffoldBaseProject}from"./create/project.js";import{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug}from"./update/channels.js";import{ensureConnection,listAuthoredConnections}from"./update/connections.js";export{CONNECTION_CATALOG,CURRENT_DIRECTORY_PROJECT_NAME,CUSTOM_CONNECTION_SLUG,DEFAULT_SLACK_CONNECTOR_SLUG,HumanActionRequiredError,SCAFFOLDABLE_CHANNELS,SLACK_CHANNEL_DEFAULT_ROUTE,SUPPORTED_PROTOCOLS,WriteFileExistsError,byokProviderEnvVar,catalogSlugs,deriveSlackConnectorSlug,effectiveProtocols,endpointForProtocol,ensureChannel,ensureConnection,getCatalogEntry,hasVercelHostFramework,isEveProject,isNextJsProject,isValidConnectionSlug,listAuthoredChannels,listAuthoredConnections,normalizeSlackConnectorSlug,scaffoldBaseProject};
@@ -56,12 +56,19 @@ interface WebChannelSkippedResult {
56
56
  type WebChannelMutationResult = WebChannelWrittenResult | WebChannelSkippedResult;
57
57
  /**
58
58
  * Whether the project already carries a Next.js app: `package.json` declares a
59
- * `next` dependency in any dependency field. This is the exact predicate the
59
+ * `next` dependency in the same dependency fields Vercel framework detection
60
+ * checks. This is the exact predicate the
60
61
  * web scaffold skips on (`skipReason: "nextjs-project"`), so pickers can mark
61
62
  * Web Chat as already present precisely when scaffolding would be a no-op.
62
63
  * A missing `package.json` reads as "no app".
63
64
  */
64
65
  export declare function isNextJsProject(projectRoot: string): Promise<boolean>;
66
+ /**
67
+ * Whether the root app declares a Vercel framework that should own the
68
+ * top-level deployment while eve runs as a sibling service. These match Eve's
69
+ * current framework integrations: Next.js, Nuxt, and SvelteKit.
70
+ */
71
+ export declare function hasVercelHostFramework(projectRoot: string): Promise<boolean>;
65
72
  export declare function normalizeSlackConnectorSlug(input: string): SlackConnectorSlug;
66
73
  export declare function deriveSlackConnectorSlug(projectRoot: string, projectNameHint?: string): Promise<SlackConnectorSlug>;
67
74
  export interface EnsureChannelOptions {