eve 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/src/cli/commands/agent-instructions.d.ts +15 -3
- package/dist/src/cli/commands/agent-instructions.js +3 -1
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +33 -0
- package/dist/src/cli/commands/agent-prompt/collect-intent.md +18 -0
- package/dist/src/cli/commands/agent-prompt/intro-handoff.md +4 -0
- package/dist/src/cli/commands/agent-prompt/intro-setup.md +5 -0
- package/dist/src/cli/commands/agent-prompt/scaffold.md +19 -0
- package/dist/src/cli/commands/agent-prompt/vercel-connect.md +3 -0
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/init-repl.d.ts +79 -0
- package/dist/src/cli/commands/init-repl.js +1 -0
- package/dist/src/cli/commands/init.d.ts +6 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/link.d.ts +2 -2
- package/dist/src/cli/commands/link.js +1 -1
- package/dist/src/cli/dev/tui/line-editor.d.ts +2 -0
- package/dist/src/cli/dev/tui/line-editor.js +2 -2
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +26 -7
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +10 -3
- package/dist/src/cli/dev/tui/setup-panel.d.ts +16 -8
- package/dist/src/cli/dev/tui/setup-panel.js +3 -3
- package/dist/src/cli/dev/tui/setup-selection-input.d.ts +2 -1
- package/dist/src/cli/dev/tui/setup-selection-input.js +2 -2
- package/dist/src/cli/dev/tui/terminal-renderer.js +10 -10
- package/dist/src/cli/dev/tui/terminal-text.d.ts +11 -0
- package/dist/src/cli/dev/tui/terminal-text.js +1 -1
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/run.d.ts +1 -0
- package/dist/src/cli/run.js +2 -2
- package/dist/src/cli/ui/live-row.js +1 -1
- package/dist/src/cli/ui/progress-pulse.d.ts +10 -0
- package/dist/src/cli/ui/progress-pulse.js +1 -0
- package/dist/src/discover/discover-agent.js +1 -1
- package/dist/src/evals/target.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +0 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/multiplexed-command.d.ts +22 -0
- package/dist/src/execution/sandbox/multiplexed-command.js +1 -0
- package/dist/src/execution/tool-auth.d.ts +17 -30
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-module-loader.js +2 -2
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/public/channels/github/api.d.ts +5 -0
- package/dist/src/public/channels/github/api.js +1 -1
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/pr-context.d.ts +10 -0
- package/dist/src/public/channels/github/pr-context.js +2 -2
- package/dist/src/public/channels/slack/connections.d.ts +16 -18
- package/dist/src/public/channels/slack/defaults.d.ts +1 -1
- package/dist/src/public/channels/slack/defaults.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +6 -7
- package/dist/src/public/definitions/tool.d.ts +40 -41
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/runtime/connections/validate-authorization.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/types.d.ts +0 -10
- package/dist/src/setup/ai-gateway-api-key.d.ts +15 -0
- package/dist/src/setup/ai-gateway-api-key.js +1 -0
- package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
- package/dist/src/setup/boxes/detect-ai-gateway.js +2 -2
- package/dist/src/setup/boxes/link-project.d.ts +8 -14
- package/dist/src/setup/boxes/link-project.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.d.ts +2 -1
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/cli/select-component.d.ts +7 -1
- package/dist/src/setup/cli/select-component.js +1 -1
- package/dist/src/setup/cli/select-option-codec.d.ts +1 -0
- package/dist/src/setup/cli/select-option-codec.js +1 -1
- package/dist/src/setup/cli/select-state.d.ts +14 -1
- package/dist/src/setup/cli/select-state.js +1 -1
- package/dist/src/setup/flows/channels.js +1 -1
- package/dist/src/setup/flows/deploy.js +1 -1
- package/dist/src/setup/flows/install-vercel-cli.js +1 -1
- package/dist/src/setup/flows/link.d.ts +2 -1
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model.d.ts +5 -4
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/vercel.js +2 -2
- package/dist/src/setup/index.d.ts +1 -1
- package/dist/src/setup/package-manager.d.ts +2 -1
- package/dist/src/setup/package-manager.js +1 -1
- package/dist/src/setup/primitives/pm/index.d.ts +1 -1
- package/dist/src/setup/primitives/pm/pnpm.d.ts +11 -1
- package/dist/src/setup/primitives/pm/pnpm.js +5 -2
- package/dist/src/setup/primitives/pm/types.d.ts +10 -1
- package/dist/src/setup/project-resolution.d.ts +9 -6
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/prompter.d.ts +13 -0
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.d.ts +8 -0
- package/dist/src/setup/scaffold/create/project.js +8 -7
- package/dist/src/setup/scaffold/update/channels.d.ts +8 -0
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/scaffold/update/package-json.d.ts +3 -0
- package/dist/src/setup/scaffold/update/package-json.js +1 -1
- package/dist/src/setup/scaffold/workspace-glob.d.ts +5 -0
- package/dist/src/setup/scaffold/workspace-glob.js +1 -0
- package/dist/src/setup/scaffold/workspace-root.d.ts +29 -0
- package/dist/src/setup/scaffold/workspace-root.js +1 -0
- package/dist/src/setup/state.d.ts +7 -2
- package/dist/src/setup/vercel-api-failure.d.ts +9 -0
- package/dist/src/setup/vercel-api-failure.js +1 -0
- package/dist/src/setup/vercel-deployment.js +1 -1
- package/dist/src/setup/vercel-project-api.d.ts +25 -0
- package/dist/src/setup/vercel-project-api.js +1 -0
- package/dist/src/setup/vercel-project.d.ts +11 -57
- package/dist/src/setup/vercel-project.js +1 -1
- package/dist/src/setup/with-spinner.d.ts +3 -0
- package/dist/src/setup/with-spinner.js +1 -0
- package/dist/src/shared/package-name.d.ts +4 -0
- package/dist/src/shared/package-name.js +1 -0
- package/docs/channels/slack.mdx +1 -1
- package/docs/connections.mdx +9 -6
- package/docs/getting-started.mdx +8 -3
- package/docs/guides/auth-and-route-protection.md +57 -10
- package/docs/guides/dev-tui.md +3 -3
- package/docs/reference/cli.md +3 -3
- package/docs/reference/typescript-api.md +7 -7
- package/package.json +1 -1
- package/dist/src/cli/commands/init-agent-handoff.md +0 -12
- package/dist/src/cli/commands/init-agent-instructions.md +0 -16
|
@@ -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{m,q}from"../../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{renderMultiselectPrompt,renderSearchableSelect,renderSelectPrompt}from"./prompt-ui.js";import{createSelectOptionCodec}from"./select-option-codec.js";import{filterOptions,initialSelectState,orderedSelection,reduceSelect,selectValueAtCursor,submitRowIndex}from"./select-state.js";var import_picocolors=__toESM(require_picocolors(),1);function toPromptState(e){return e}var SelectComponent=class extends m{options;multiple;search;required;filter=``;optionCursor=0;selectedSet=new Set;constructor(e){super({render:e.render,validate:()=>this.submitError()},!1),this.options=e.options,this.multiple=e.multiple,this.search=e.search,this.required=e.required,this.filter=e.initial.filter,this.optionCursor=e.initial.cursor,this.selectedSet=e.initial.selected,this.refreshValue(),this.on(`key`,(e,t)=>{if(this.multiple&&t?.name===`space`){this.apply({type:`toggle`});return}if(this.search){if(t?.name===`backspace`||e===``||e===`\b`){this.apply({type:`backspace`});return}e!==void 0&&e.length===1&&e>=` `&&e!==``&&this.apply({type:`char`,char:e})}}),this.on(`cursor`,e=>{e===`up`||e===`left`?this.apply({type:`up`}):(e===`down`||e===`right`)&&this.apply({type:`down`})})}visibleOptions(){return filterOptions(this.options,this.filter)}onSubmitRow(){return this.multiple&&this.optionCursor===submitRowIndex(this.visibleOptions())}submitLabel(){if(this.required)return`Submit`;let e=new Set(this.options.filter(e=>e.locked).map(e=>e.value));return[...this.selectedSet].some(t=>!e.has(t))?`Submit`:`Skip`}_shouldSubmit(){return this.multiple?this.onSubmitRow()?!0:(this.apply({type:`toggle`}),!1):this.visibleOptions()[this.optionCursor]?.completed!==!0}selectedValues(){if(this.multiple)return orderedSelection(this.options,this.selectedSet);let e=selectValueAtCursor(this.visibleOptions(),this.optionCursor);return e===void 0?[]:[e]}submitDisplay(){if(this.multiple){let e=this.options.filter(e=>this.selectedSet.has(e.value)).map(e=>e.label);return e.length>0?e.join(`, `):import_picocolors.default.dim(`(none selected)`)}let e=selectValueAtCursor(this.visibleOptions(),this.optionCursor);return e===void 0?``:this.labelForValue(e)}labelForValue(e){return this.options.find(t=>t.value===e)?.label??e}submitError(){return this.multiple?this.required&&this.selectedSet.size===0?`Select at least one option, then press enter.`:void 0:selectValueAtCursor(this.visibleOptions(),this.optionCursor)===void 0?`Type to match an option, then press enter.`:void 0}apply(e){let t=reduceSelect({filter:this.filter,cursor:this.optionCursor,selected:this.selectedSet},e,{options:this.options,submitRow:this.multiple});this.filter=t.filter,this.optionCursor=t.cursor,this.selectedSet=t.selected,this.refreshValue()}refreshValue(){this.value=this.multiple?orderedSelection(this.options,this.selectedSet):selectValueAtCursor(this.visibleOptions(),this.optionCursor)}};function renderSelectComponent(e,t,n,r){let s=toPromptState(e.state);return e.search?renderSearchableSelect({colors:import_picocolors.default,state:s,leadingRail:n,message:t.message,multiple:e.multiple,filter:e.filter,placeholder:t.placeholder,options:e.visibleOptions(),cursor:e.optionCursor,selectedValues:e.selectedValues(),submitDisplay:e.submitDisplay(),footerNote:r,error:e.error,submitLabel:e.submitLabel()}):e.multiple?renderMultiselectPrompt({colors:import_picocolors.default,cursor:e.optionCursor,error:e.error,footerNote:r,leadingRail:n,message:t.message,options:e.options,selectedValues:e.selectedValues(),state:s,submitLabel:e.submitLabel()}):renderSelectPrompt({colors:import_picocolors.default,cursor:e.optionCursor,footerNote:r,leadingRail:n,message:t.message,options:e.options,state:s})}async function runSelectComponent(e){let t=createSelectOptionCodec(e.options),n=initialSelectState({options:t.options,defaultValue:e.defaultValue===void 0?void 0:t.encode(e.defaultValue),initialValues:e.initialValues?.map(e=>t.encode(e)),submitRow:e.multiple}),i,a,o=new SelectComponent({options:t.options,multiple:e.multiple,search:e.search,required:e.required,initial:n,render(){return i?renderSelectComponent(i,{message:e.message,placeholder:e.placeholder},e.leadingRail,a?.note()):``}});i=o,a=e.attachGuard?.(o);let c=await o.prompt();if(q(c))return c;if(c===void 0)throw Error(`Select prompt returned no value.`);
|
|
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{m,q}from"../../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{renderMultiselectPrompt,renderSearchableSelect,renderSelectPrompt}from"./prompt-ui.js";import{createSelectOptionCodec}from"./select-option-codec.js";import{filterOptions,initialSelectState,orderedSelection,reduceSelect,searchActionQuery,selectValueAtCursor,submitRowIndex}from"./select-state.js";var import_picocolors=__toESM(require_picocolors(),1);function toPromptState(e){return e}var SelectComponent=class extends m{options;multiple;search;searchAction;required;filter=``;optionCursor=0;selectedSet=new Set;constructor(e){super({render:e.render,validate:()=>this.submitError()},!1),this.options=e.options,this.multiple=e.multiple,this.search=e.search,this.searchAction=e.searchAction,this.required=e.required,this.filter=e.initial.filter,this.optionCursor=e.initial.cursor,this.selectedSet=e.initial.selected,this.refreshValue(),this.on(`key`,(e,t)=>{if(this.multiple&&t?.name===`space`){this.apply({type:`toggle`});return}if(this.search){if(t?.name===`backspace`||e===``||e===`\b`){this.apply({type:`backspace`});return}e!==void 0&&e.length===1&&e>=` `&&e!==``&&this.apply({type:`char`,char:e})}}),this.on(`cursor`,e=>{e===`up`||e===`left`?this.apply({type:`up`}):(e===`down`||e===`right`)&&this.apply({type:`down`})})}visibleOptions(){return filterOptions(this.options,this.filter,this.searchAction)}onSubmitRow(){return this.multiple&&this.optionCursor===submitRowIndex(this.visibleOptions())}submitLabel(){if(this.required)return`Submit`;let e=new Set(this.options.filter(e=>e.locked).map(e=>e.value));return[...this.selectedSet].some(t=>!e.has(t))?`Submit`:`Skip`}_shouldSubmit(){return this.multiple?this.onSubmitRow()?!0:(this.apply({type:`toggle`}),!1):this.visibleOptions()[this.optionCursor]?.completed!==!0}selectedValues(){if(this.multiple)return orderedSelection(this.options,this.selectedSet);let e=selectValueAtCursor(this.visibleOptions(),this.optionCursor);return e===void 0?[]:[e]}submitDisplay(){if(this.multiple){let e=this.options.filter(e=>this.selectedSet.has(e.value)).map(e=>e.label);return e.length>0?e.join(`, `):import_picocolors.default.dim(`(none selected)`)}let e=selectValueAtCursor(this.visibleOptions(),this.optionCursor);return e===void 0?``:this.labelForValue(e)}labelForValue(e){let t=searchActionQuery(e);return t!==void 0&&this.searchAction!==void 0?this.searchAction.label(t):this.options.find(t=>t.value===e)?.label??e}submitError(){return this.multiple?this.required&&this.selectedSet.size===0?`Select at least one option, then press enter.`:void 0:selectValueAtCursor(this.visibleOptions(),this.optionCursor)===void 0?`Type to match an option, then press enter.`:void 0}apply(e){let t=reduceSelect({filter:this.filter,cursor:this.optionCursor,selected:this.selectedSet},e,{options:this.options,searchAction:this.searchAction,submitRow:this.multiple});this.filter=t.filter,this.optionCursor=t.cursor,this.selectedSet=t.selected,this.refreshValue()}refreshValue(){this.value=this.multiple?orderedSelection(this.options,this.selectedSet):selectValueAtCursor(this.visibleOptions(),this.optionCursor)}};function renderSelectComponent(e,t,n,r){let s=toPromptState(e.state);return e.search?renderSearchableSelect({colors:import_picocolors.default,state:s,leadingRail:n,message:t.message,multiple:e.multiple,filter:e.filter,placeholder:t.placeholder,options:e.visibleOptions(),cursor:e.optionCursor,selectedValues:e.selectedValues(),submitDisplay:e.submitDisplay(),footerNote:r,error:e.error,submitLabel:e.submitLabel()}):e.multiple?renderMultiselectPrompt({colors:import_picocolors.default,cursor:e.optionCursor,error:e.error,footerNote:r,leadingRail:n,message:t.message,options:e.options,selectedValues:e.selectedValues(),state:s,submitLabel:e.submitLabel()}):renderSelectPrompt({colors:import_picocolors.default,cursor:e.optionCursor,footerNote:r,leadingRail:n,message:t.message,options:e.options,state:s})}async function runSelectComponent(e){let t=createSelectOptionCodec(e.options),n=initialSelectState({options:t.options,defaultValue:e.defaultValue===void 0?void 0:t.encode(e.defaultValue),initialValues:e.initialValues?.map(e=>t.encode(e)),submitRow:e.multiple}),i,a,o=new SelectComponent({options:t.options,multiple:e.multiple,search:e.search,searchAction:e.searchAction===void 0?void 0:{label:e.searchAction.label},required:e.required,initial:n,render(){return i?renderSelectComponent(i,{message:e.message,placeholder:e.placeholder},e.leadingRail,a?.note()):``}});i=o,a=e.attachGuard?.(o);let c=await o.prompt();if(q(c))return c;if(c===void 0)throw Error(`Select prompt returned no value.`);if(Array.isArray(c))return c.map(e=>t.decode(e));let l=searchActionQuery(c);return l!==void 0&&e.searchAction!==void 0?e.searchAction.value(l):t.decode(c)}export{SelectComponent,runSelectComponent};
|
|
@@ -2,6 +2,7 @@ import type { PromptOption, PromptValue } from "./prompt-ui.js";
|
|
|
2
2
|
export interface SelectOptionCodec<T extends PromptValue> {
|
|
3
3
|
readonly options: PromptOption<string>[];
|
|
4
4
|
encode(value: T): string;
|
|
5
|
+
encodeOptions(options: readonly PromptOption<T>[]): PromptOption<string>[];
|
|
5
6
|
decode(key: string): T;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function createSelectOptionCodec(e){let t=new Map,n=new Map;return
|
|
1
|
+
function createSelectOptionCodec(e){let t=new Map,n=new Map,r=0,encodeOptions=e=>{let i=new Set;return e.map((e,a)=>{if(i.has(e.value))throw Error(`Select option values must be unique; duplicate at index ${a}.`);i.add(e.value);let o=n.get(e.value);return o===void 0&&(o=`option-${r}`,r+=1,n.set(e.value,o),t.set(o,e.value)),{...e,value:o}})};return{options:encodeOptions(e),encode(e){let t=n.get(e);if(t===void 0)throw Error(`Select initial value does not match an option.`);return t},encodeOptions,decode(e){let n=t.get(e);if(n===void 0)throw Error(`Select returned an unknown option key: ${e}`);return n}}}export{createSelectOptionCodec};
|
|
@@ -9,12 +9,22 @@ export interface SelectState {
|
|
|
9
9
|
cursor: number;
|
|
10
10
|
selected: Set<string>;
|
|
11
11
|
}
|
|
12
|
+
/** A virtual row appended to local matches for a non-empty type-ahead query. */
|
|
13
|
+
export interface SearchActionOption {
|
|
14
|
+
label(query: string): string;
|
|
15
|
+
}
|
|
16
|
+
/** Encodes the query behind a virtual search action for picker transport. */
|
|
17
|
+
export declare function searchActionValue(query: string): string;
|
|
18
|
+
/** Reads a query from a virtual search action value. */
|
|
19
|
+
export declare function searchActionQuery(value: string): string | undefined;
|
|
12
20
|
/** Keyboard intents the select reducer understands. */
|
|
13
21
|
export type SelectEvent = {
|
|
14
22
|
type: "char";
|
|
15
23
|
char: string;
|
|
16
24
|
} | {
|
|
17
25
|
type: "backspace";
|
|
26
|
+
} | {
|
|
27
|
+
type: "clear";
|
|
18
28
|
} | {
|
|
19
29
|
type: "up";
|
|
20
30
|
} | {
|
|
@@ -26,6 +36,8 @@ export type SelectEvent = {
|
|
|
26
36
|
export interface SelectContext {
|
|
27
37
|
/** Selectable entries, including any disabled ones (the cursor skips them). */
|
|
28
38
|
options: readonly PromptOption<string>[];
|
|
39
|
+
/** Optional virtual row appended to local matches for a non-empty query. */
|
|
40
|
+
searchAction?: SearchActionOption;
|
|
29
41
|
/**
|
|
30
42
|
* Appends a virtual Submit row after the visible options. The cursor can
|
|
31
43
|
* land on it (index `visible.length`, see {@link submitRowIndex}) but it
|
|
@@ -42,7 +54,7 @@ export declare function submitRowIndex(visible: readonly PromptOption<string>[])
|
|
|
42
54
|
* full list; `featured` only shapes the searchable picker's default viewport,
|
|
43
55
|
* not which rows exist.
|
|
44
56
|
*/
|
|
45
|
-
export declare function filterOptions(options: readonly PromptOption<string>[], filter: string): PromptOption<string>[];
|
|
57
|
+
export declare function filterOptions(options: readonly PromptOption<string>[], filter: string, searchAction?: SearchActionOption): PromptOption<string>[];
|
|
46
58
|
/**
|
|
47
59
|
* Advances the interaction state for a single keypress.
|
|
48
60
|
*
|
|
@@ -64,6 +76,7 @@ export declare function initialSelectState(input: {
|
|
|
64
76
|
filter?: string;
|
|
65
77
|
defaultValue?: string;
|
|
66
78
|
initialValues?: readonly string[];
|
|
79
|
+
searchAction?: SearchActionOption;
|
|
67
80
|
submitRow?: boolean;
|
|
68
81
|
}): SelectState;
|
|
69
82
|
/** Value of the highlighted actionable entry, or `undefined` otherwise. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{previousGraphemeBoundary}from"#shared/text-boundaries.js";function submitRowIndex(e){return e.length}function filterOptions(e,t){let
|
|
1
|
+
import{previousGraphemeBoundary}from"#shared/text-boundaries.js";const SEARCH_ACTION_PREFIX=`\0search-action:`;function searchActionValue(e){return`${SEARCH_ACTION_PREFIX}${e}`}function searchActionQuery(e){return e.startsWith(SEARCH_ACTION_PREFIX)?e.slice(15):void 0}function submitRowIndex(e){return e.length}function filterOptions(e,t,n){let r=t.trim();if(r===``)return[...e];let i=r.toLowerCase(),a=e.filter(e=>e.label.toLowerCase().includes(i)||e.value.toLowerCase().includes(i)||(e.hint?.toLowerCase().includes(i)??!1)||(e.focusHint?.toLowerCase().includes(i)??!1));return n===void 0?a:[...a,{value:searchActionValue(r),label:n.label(r)}]}function isFocusable(e){return!e.disabled&&!e.locked}function isActionable(e){return isFocusable(e)&&!e.completed}function firstFocusableIndex(e,t){let n=e.findIndex(isFocusable);return n>=0?n:t?submitRowIndex(e):0}function stepCursor(e,t,n,r){let i=e.length+ +!!r;if(i===0)return t;let a=t;for(let t=0;t<i;t+=1){if(a=(a+n+i)%i,r&&a===submitRowIndex(e))return a;let t=e[a];if(t&&isFocusable(t))return a}return t}function reduceSelect(t,n,r){let i=r.submitRow===!0;switch(n.type){case`char`:{let e=t.filter+n.char;return{...t,filter:e,cursor:firstFocusableIndex(filterOptions(r.options,e,r.searchAction),i)}}case`backspace`:{if(t.filter.length===0)return t;let n=t.filter.slice(0,previousGraphemeBoundary(t.filter,t.filter.length));return{...t,filter:n,cursor:firstFocusableIndex(filterOptions(r.options,n,r.searchAction),i)}}case`clear`:return t.filter.length===0?t:{...t,filter:``,cursor:firstFocusableIndex(filterOptions(r.options,``,r.searchAction),i)};case`up`:case`down`:{let e=filterOptions(r.options,t.filter,r.searchAction),a=n.type===`up`?-1:1,o=stepCursor(e,t.cursor,a,i);return o===t.cursor?t:{...t,cursor:o}}case`toggle`:{let e=filterOptions(r.options,t.filter,r.searchAction)[t.cursor];if(e===void 0||!isActionable(e))return t;let n=new Set(t.selected);return n.has(e.value)?n.delete(e.value):n.add(e.value),{...t,selected:n}}}}function initialSelectState(e){let t=e.filter??``,n=filterOptions(e.options,t,e.searchAction),r=firstFocusableIndex(n,e.submitRow===!0);if(e.defaultValue!==void 0){let t=n.findIndex(t=>isFocusable(t)&&t.value===e.defaultValue);t>=0&&(r=t)}let i=e.options.filter(e=>e.locked).map(e=>e.value);return{filter:t,cursor:r,selected:new Set([...e.initialValues??[],...i])}}function selectValueAtCursor(e,t){let n=e[t];return n&&isActionable(n)?n.value:void 0}function orderedSelection(e,t){return e.filter(e=>t.has(e.value)).map(e=>e.value)}export{filterOptions,initialSelectState,orderedSelection,reduceSelect,searchActionQuery,searchActionValue,selectValueAtCursor,submitRowIndex};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{interactiveAsker}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{addChannels}from"../boxes/add-channels.js";import{getVercelAuthStatus}from"../vercel-project.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";import{toErrorMessage}from"#shared/errors.js";const SEE_IT_LIVE_MESSAGE=`See it live`;async function promptSeeItLive(e){try{return await e.select({message:SEE_IT_LIVE_MESSAGE,options:[{value:`deploy`,label:`Deploy and chat`},{value:`later`,label:`Later`}]})}catch(e){if(e instanceof WizardCancelledError)return`later`;throw e}}function channelAlreadyAdded(e,t){return t===`web`?e.webAppPresent:e.slackOwners.length>0}function appendChannel(e,t){return e.includes(t)?[...e]:[...e,t]}async function pickChannel(e,t,n,r){let i=channelListRows(t,n,r),a=!i.some(e=>e.value!==`done`&&e.completed!==!0&&e.disabled!==!0),s={message:CHANNELS_PROMPT_MESSAGE,options:i,hintLayout:`inline`};a&&(s.initialValue=`done`);try{return{kind:`picked`,value:await e.select(s)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}function channelLandedDuringSubflow(e,t,n){return!channelAlreadyAdded(e,n)&&channelAlreadyAdded(t,n)}function deployAndChatDetails(e){let t={};return e.slackChatUrl!==void 0&&(t.chatUrl=e.slackChatUrl),e.slackWorkspaceName!==void 0&&(t.workspaceName=e.slackWorkspaceName),t}function vercelChannelBlocker(e,t){
|
|
1
|
+
import{interactiveAsker}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{addChannels}from"../boxes/add-channels.js";import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus,vercelAuthBlockerReason}from"../vercel-project.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";import{toErrorMessage}from"#shared/errors.js";const SEE_IT_LIVE_MESSAGE=`See it live`;async function promptSeeItLive(e){try{return await e.select({message:SEE_IT_LIVE_MESSAGE,options:[{value:`deploy`,label:`Deploy and chat`},{value:`later`,label:`Later`}]})}catch(e){if(e instanceof WizardCancelledError)return`later`;throw e}}function channelAlreadyAdded(e,t){return t===`web`?e.webAppPresent:e.slackOwners.length>0}function appendChannel(e,t){return e.includes(t)?[...e]:[...e,t]}async function pickChannel(e,t,n,r){let i=channelListRows(t,n,r),a=!i.some(e=>e.value!==`done`&&e.completed!==!0&&e.disabled!==!0),s={message:CHANNELS_PROMPT_MESSAGE,options:i,hintLayout:`inline`};a&&(s.initialValue=`done`);try{return{kind:`picked`,value:await e.select(s)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}function channelLandedDuringSubflow(e,t,n){return!channelAlreadyAdded(e,n)&&channelAlreadyAdded(t,n)}function deployAndChatDetails(e){let t={};return e.slackChatUrl!==void 0&&(t.chatUrl=e.slackChatUrl),e.slackWorkspaceName!==void 0&&(t.workspaceName=e.slackWorkspaceName),t}function vercelChannelBlocker(e,t){let n=vercelAuthBlockerReason(e);if(n!==void 0)return n;if(!t)return`Requires Vercel account, see /model`}function channelListRows(e,t,n){let r=[{value:`repl`,label:`Terminal UI`,completed:!0,focusHint:`Already installed`}];for(let i of SCAFFOLDABLE_CHANNELS){if(channelAlreadyAdded(e,i.kind)){r.push({value:i.kind,label:i.label,completed:!0,focusHint:`Already installed`});continue}let a=e.disabledChannelReasons[i.kind];if(a!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:a});continue}if(i.requiresVercelProject===!0){let e=vercelChannelBlocker(n,t);if(e!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:e,disabledReasonTone:`warning`});continue}}let o={value:i.kind,label:i.label};i.hint!==void 0&&(o.hint=i.hint),r.push(o)}return r.push({value:`done`,label:`Done`}),r}async function runChannelsFlow(o){let{appRoot:c,prompter:l,signal:u}=o,d={detectDeployment,inspectExistingChannelRegistrations,getVercelAuthStatus,...o.deps},[f,p,m]=await withSpinner(l,`Checking the project…`,()=>Promise.all([d.detectDeployment(c,{signal:u}),d.inspectExistingChannelRegistrations(c),d.getVercelAuthStatus(c,{signal:u})]));u?.throwIfAborted();let h=p,g={...createDefaultSetupState(),project:projectResolutionFromDeployment(f),projectPath:{kind:`resolved`,inPlace:!0,path:c}},_;for(;;){let t=await pickChannel(l,h,isProjectResolved(g.project),m);if(t.kind===`cancelled`){if(g.channels.length===0)return{kind:`cancelled`};break}let r=t.value;if(r===`done`)break;if(r===`repl`||channelAlreadyAdded(h,r))continue;let i=[selectChannels({asker:interactiveAsker(l),variant:`channels-add`,presetChannels:[r],validateSelection:e=>assertCanAddSelectedChannels(e,h)}),addChannels({asker:interactiveAsker(l),prompter:l,configureVercelServices:!0,deps:d.addChannels})],o;try{o=await runInteractive(i,g,prompterSink(l),{snapshot:snapshotSetupState,signal:u})}catch(e){let t=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,t,r)){if(g={...g,channels:appendChannel(g.channels,r)},h=t,_=toErrorMessage(e),u?.aborted===!0)break;continue}throw e}if(o.kind===`done`){if(g=o.state,h=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c)),u?.throwIfAborted(),r===`slack`&&g.slackbotAttached&&await promptSeeItLive(l)===`deploy`)return{kind:`deploy-and-chat`,addedChannels:g.channels,chat:deployAndChatDetails(g)}}else{let e=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,e,r))return{kind:`done`,addedChannels:appendChannel(g.channels,r)};h=e}}return _===void 0?{kind:`done`,addedChannels:g.channels}:{kind:`failed`,addedChannels:g.channels,message:_}}export{SEE_IT_LIVE_MESSAGE,runChannelsFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=r
|
|
1
|
+
import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{withSpinner}from"../with-spinner.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=await withSpinner(r,`Checking the current Vercel link...`,async()=>{let e=await o.detectDeployment(n,{signal:a});return a?.throwIfAborted(),projectResolutionFromDeployment(e)}),c=isProjectResolved(s);if(!c&&!i)return{kind:`needs-link`};let l=inProjectSetupState(n,s,{deploymentPending:!0}),u=c?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],d=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(u,l,d,{snapshot:snapshotSetupState,signal:a})).project)};let f=await runInteractive(u,l,d,{snapshot:snapshotSetupState,signal:a});return f.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(f.state.project)}}export{runDeployFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{detectPackageManager}from"#setup/package-manager.js";import{spawnPackageManager}from"#setup/primitives/index.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";const defaultDeps={getVercelAuthStatus,detectPackageManager,spawnPackageManager};function globalInstallArguments(e){switch(e){case`npm`:return[`install`,`-g`,`vercel@latest`];case`yarn`:return[`global`,`add`,`vercel@latest`];case`pnpm`:case`bun`:return[`add`,`-g`,`vercel@latest`]}}async function
|
|
1
|
+
import{withSpinner}from"../with-spinner.js";import{detectPackageManager}from"#setup/package-manager.js";import{spawnPackageManager}from"#setup/primitives/index.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";const defaultDeps={getVercelAuthStatus,detectPackageManager,spawnPackageManager};function globalInstallArguments(e){switch(e){case`npm`:return[`install`,`-g`,`vercel@latest`];case`yarn`:return[`global`,`add`,`vercel@latest`];case`pnpm`:case`bun`:return[`add`,`-g`,`vercel@latest`]}}async function runInstallVercelCliFlow(t){let{appRoot:n,prompter:r,signal:i}=t,a={...defaultDeps,...t.deps},o=createPromptCommandOutput(r.log),probe=async()=>await a.getVercelAuthStatus(n,{signal:i})!==`cli-missing`;if(await withSpinner(r,`Checking for the Vercel CLI…`,probe))return i?.throwIfAborted(),{kind:`already`};i?.throwIfAborted();let s=await a.detectPackageManager(n),c=await withSpinner(r,`Installing the Vercel CLI with ${s.kind}…`,()=>a.spawnPackageManager(s.kind,n,globalInstallArguments(s.kind),{onOutput:o,signal:i,nonInteractive:!0}));if(i?.aborted===!0)return{kind:`cancelled`};if(!c)return{kind:`failed`};let l=await withSpinner(r,`Verifying the Vercel CLI…`,probe);return i?.throwIfAborted(),l?{kind:`installed`}:{kind:`failed`}}export{runInstallVercelCliFlow};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AI_GATEWAY_API_KEY_ENV_VAR } from "../ai-gateway-api-key.js";
|
|
1
2
|
import { type ApplyAiGatewayCredentialDeps } from "../boxes/apply-ai-gateway-credential.js";
|
|
2
3
|
import { findEnvFileWithKey } from "../boxes/detect-ai-gateway.js";
|
|
3
4
|
import { type LinkProjectDeps } from "../boxes/link-project.js";
|
|
@@ -15,7 +16,7 @@ export interface LinkFlowDeps {
|
|
|
15
16
|
export type LinkFlowResult = {
|
|
16
17
|
kind: "done";
|
|
17
18
|
/** The model credential verified in an env file, when one landed. */
|
|
18
|
-
credential?: "VERCEL_OIDC_TOKEN" |
|
|
19
|
+
credential?: "VERCEL_OIDC_TOKEN" | typeof AI_GATEWAY_API_KEY_ENV_VAR;
|
|
19
20
|
} | {
|
|
20
21
|
kind: "cancelled";
|
|
21
22
|
};
|
|
@@ -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,withAnswers}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{detectAiGateway,findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{applyAiGatewayCredential}from"../boxes/apply-ai-gateway-credential.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";var import_picocolors=__toESM(require_picocolors(),1);async function runLinkFlow(e){let{appRoot:t,prompter:i,signal:a,projectSelection:o=`existing-only`}=e,s={detectProjectIdentity,findEnvFileWithKey,...e.deps},c=i
|
|
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{AI_GATEWAY_API_KEY_ENV_VAR}from"../ai-gateway-api-key.js";import{interactiveAsker,withAnswers}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{withSpinner}from"../with-spinner.js";import{detectAiGateway,findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{applyAiGatewayCredential}from"../boxes/apply-ai-gateway-credential.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";var import_picocolors=__toESM(require_picocolors(),1);async function runLinkFlow(e){let{appRoot:t,prompter:i,signal:a,projectSelection:o=`existing-only`}=e,s={detectProjectIdentity,findEnvFileWithKey,...e.deps},c=await withSpinner(i,`Checking the current Vercel link...`,async()=>{let e=await s.detectProjectIdentity(t,{signal:a});return a?.throwIfAborted(),e});if(c===void 0){let[e,n]=await Promise.all([s.findEnvFileWithKey(t,AI_GATEWAY_API_KEY_ENV_VAR),s.findEnvFileWithKey(t,`VERCEL_OIDC_TOKEN`)]),r=e??n;r!==void 0&&i.log.message(`This directory is not linked to a Vercel project yet — the model currently runs on credentials from ${r}.`)}else{let e=c.teamName===void 0?import_picocolors.default.bold(c.projectName):`${import_picocolors.default.bold(c.projectName)} in ${import_picocolors.default.bold(c.teamName)}`;try{if(await i.select({message:`This directory is already linked to\n${e}`,options:[{value:`relink`,label:`Link to another project`},{value:`dismiss`,label:`Dismiss`}]})===`dismiss`)return{kind:`cancelled`}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}let l=inProjectSetupState(t,{kind:`unresolved`});if((await runInteractive([resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(i)),prompter:i,targetDirectory:t,mode:{headless:!1},adoptExistingLink:!1,projectSelection:o,deps:s.resolveProvisioning}),linkVercelProject({prompter:i,deps:s.linkProject}),detectAiGateway(),applyAiGatewayCredential({prompter:i,deps:s.applyAiGatewayCredential})],l,prompterSink(i),{snapshot:snapshotSetupState,signal:a})).kind===`cancelled`)return{kind:`cancelled`};let[u,d]=await Promise.all([s.findEnvFileWithKey(t,`VERCEL_OIDC_TOKEN`),s.findEnvFileWithKey(t,AI_GATEWAY_API_KEY_ENV_VAR)]);a?.throwIfAborted(),u===void 0&&d===void 0&&i.log.warning("Linked, but no model credential landed in an env file (VERCEL_OIDC_TOKEN or AI_GATEWAY_API_KEY). Run `vercel env pull` once the project has AI Gateway access.");let f={kind:`done`};return u===void 0?d!==void 0&&(f.credential=AI_GATEWAY_API_KEY_ENV_VAR):f.credential=`VERCEL_OIDC_TOKEN`,f}export{runLinkFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";import{runVercel}from"#setup/primitives/run-vercel.js";const defaultDeps={getVercelAuthStatus,runVercelLogin:({cwd:e,onOutput:t,signal:
|
|
1
|
+
import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";import{runVercel}from"#setup/primitives/run-vercel.js";const defaultDeps={getVercelAuthStatus,runVercelLogin:({cwd:e,onOutput:t,signal:n})=>runVercel([`login`],{cwd:e,nonInteractive:!0,onOutput:t,timeoutMs:3e5,signal:n})};async function runVercelLoginWithControls(t,n,r,i,a){if(i.awaitChoice===void 0)return withSpinner(i,`Opening Vercel login in your browser…`,()=>t.runVercelLogin({cwd:n,onOutput:r,signal:a}));let o=new AbortController,s=a?AbortSignal.any([a,o.signal]):o.signal,c=i.awaitChoice({status:`Logging in to Vercel…`,context:`Complete the login in your browser`,actions:[{value:`cancel`,label:`Cancel`}]}),l=t.runVercelLogin({cwd:n,onOutput:r,signal:s});try{let e=await Promise.race([l.then(e=>({via:`work`,ok:e})),c.choice.then(()=>({via:`choice`}))]);return e.via===`work`?e.ok:(o.abort(),await l.catch(()=>{}),`cancelled`)}finally{c.close()}}async function runLoginFlow(t){let{appRoot:r,prompter:a,signal:o}=t,s={...defaultDeps,...t.deps},c=createPromptCommandOutput(a.log),probeAuth=()=>s.getVercelAuthStatus(r,{signal:o}),l=await withSpinner(a,`Checking your Vercel login…`,probeAuth);switch(o?.throwIfAborted(),l){case`authenticated`:return{kind:`already`};case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};case`logged-out`:break;default:return l}let u=await runVercelLoginWithControls(s,r,c,a,o);if(u===`cancelled`)return{kind:`cancelled`};if(!u)return{kind:`failed`};let d=await withSpinner(a,`Confirming your Vercel login…`,probeAuth);switch(o?.throwIfAborted(),d){case`authenticated`:return{kind:`logged-in`};case`logged-out`:return{kind:`failed`};case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};default:return d}}export{runLoginFlow};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { AI_GATEWAY_API_KEY_ENV_VAR } from "../ai-gateway-api-key.js";
|
|
1
2
|
import { type SelectModelDeps } from "../boxes/select-model.js";
|
|
2
|
-
import { type
|
|
3
|
+
import { type VercelProjectOperationOptions } from "../project-resolution.js";
|
|
3
4
|
import type { ModelRouting } from "#shared/agent-definition.js";
|
|
4
5
|
import type { Prompter } from "../prompter.js";
|
|
5
6
|
import { runVercelFlow } from "./vercel.js";
|
|
@@ -47,7 +48,7 @@ export type ModelProviderStatus = {
|
|
|
47
48
|
teamName?: string;
|
|
48
49
|
} | {
|
|
49
50
|
kind: "gateway-key";
|
|
50
|
-
envKey:
|
|
51
|
+
envKey: typeof AI_GATEWAY_API_KEY_ENV_VAR | "VERCEL_OIDC_TOKEN";
|
|
51
52
|
envFile: string;
|
|
52
53
|
};
|
|
53
54
|
/**
|
|
@@ -59,7 +60,7 @@ export type ModelProviderStatus = {
|
|
|
59
60
|
* disk — so it never surfaces as an outcome.
|
|
60
61
|
*/
|
|
61
62
|
export interface ModelProviderOutcome {
|
|
62
|
-
credential?: "VERCEL_OIDC_TOKEN" |
|
|
63
|
+
credential?: "VERCEL_OIDC_TOKEN" | typeof AI_GATEWAY_API_KEY_ENV_VAR;
|
|
63
64
|
status: ModelProviderStatus;
|
|
64
65
|
}
|
|
65
66
|
export type ModelFlowResult = {
|
|
@@ -78,7 +79,7 @@ export declare const MODEL_MENU_MESSAGE = "";
|
|
|
78
79
|
* and `AI_GATEWAY_API_KEY` outranks `VERCEL_OIDC_TOKEN` because it is the one
|
|
79
80
|
* the provider sub-flow's own-key branch writes.
|
|
80
81
|
*/
|
|
81
|
-
export declare function detectModelProviderStatus(appRoot: string, options?:
|
|
82
|
+
export declare function detectModelProviderStatus(appRoot: string, options?: VercelProjectOperationOptions): Promise<ModelProviderStatus>;
|
|
82
83
|
/**
|
|
83
84
|
* THE MODEL FLOW for the dev TUI's `/model`: a two-row action menu that
|
|
84
85
|
* loops, uniting the model pick and the provider setup behind one entry
|
|
@@ -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[
|
|
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{AI_GATEWAY_API_KEY_ENV_VAR}from"../ai-gateway-api-key.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{withSpinner}from"../with-spinner.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[r,a,o]=await Promise.all([detectProjectIdentity(e,t),findEnvFileWithKey(e,AI_GATEWAY_API_KEY_ENV_VAR),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(r!==void 0){let e={kind:`gateway-project`,projectName:r.projectName};return r.teamName!==void 0&&(e.teamName=r.teamName),e}return a===void 0?o===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:o}:{kind:`gateway-key`,envKey:AI_GATEWAY_API_KEY_ENV_VAR,envFile:a}}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps},detectProvider=()=>i.detectProviderStatus(t,{signal:r}),[{id:a,routing:s,editable:c},l]=await withSpinner(n,`Checking the project…`,()=>Promise.all([i.readCurrentModel(t),detectProvider()]));r?.throwIfAborted();let u,d,f=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(a,l,s,c),hintLayout:`stacked`,initialValue:m,notices:f===void 0?[]:[f]})}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:a,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 p=await i.runVercelFlow({appRoot:t,prompter:n,signal:r});if(r?.throwIfAborted(),p.kind===`cancelled`){m=`provider`;continue}if(`outcome`in p){m=`done`;continue}l=await withSpinner(n,`Checking the project…`,detectProvider),r?.throwIfAborted(),d={status:l},p.credential!==void 0&&(d.credential=p.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:n,current:i,signal:o}=e,s=e.deps?.fetchModels??fetchGatewayCatalog,p={asker:interactiveAsker(n),deps:{fetchModels:e=>withSpinner(n,`Loading the model catalog...`,()=>s(e))}};i!==null&&(p.defaultModel=i);let m=await runInteractive([selectModel(p)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(n),{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,2 +1,2 @@
|
|
|
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{appendEnv}from"../append-env.js";import{WizardCancelledError}from"../step.js";import{getVercelAuthStatus}from"../vercel-project.js";import{runLinkFlow}from"./link.js";import{validateGatewayApiKey}from"../validate-gateway-key.js";
|
|
2
|
-
`),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`done`,outcome:`external-provider`};if(l===`own-key`)for(;;){let e;try{e=await
|
|
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{appendEnv}from"../append-env.js";import{AI_GATEWAY_API_KEY_ENV_FILE,AI_GATEWAY_API_KEY_ENV_VAR,writeAiGatewayApiKey}from"../ai-gateway-api-key.js";import{WizardCancelledError}from"../step.js";import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus}from"../vercel-project.js";import{runLinkFlow}from"./link.js";import{validateGatewayApiKey}from"../validate-gateway-key.js";var import_picocolors=__toESM(require_picocolors(),1);const PROVIDER_QUESTION=`Which model provider do you want to use?`,CONNECTION_QUESTION=`How do you want to connect to AI Gateway?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${AI_GATEWAY_API_KEY_ENV_FILE} — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.`,'In agent/agent.ts, set `model` to a provider-authored model — e.g. `anthropic("claude-opus-4.8")` from `@ai-sdk/anthropic`.',`See https://eve.dev/docs/agent-config for details.`,"A running `eve dev` reloads env files automatically — no restart needed."];function projectConnectionOption(e){let t={value:`project`,label:`Connect via a project`,hint:`vercel link + env pull`};switch(e){case`authenticated`:return t;case`cli-missing`:return{...t,disabled:!0,disabledReason:`Vercel CLI not found, see /vc`,disabledReasonTone:`warning`};case`logged-out`:return{...t,disabled:!0,disabledReason:`Log in to Vercel first, see /login`,disabledReasonTone:`warning`};case`unavailable`:return{...t,disabled:!0,disabledReason:`Couldn't reach Vercel, check your connection`,disabledReasonTone:`warning`};default:return e}}async function runVercelFlow(e){let{appRoot:t,prompter:r,signal:o}=e,s={getVercelAuthStatus,runLinkFlow,appendEnv,validateGatewayApiKey,...e.deps},c,l;try{if(c=await r.select({message:PROVIDER_QUESTION,options:[{value:`gateway`,label:`Vercel AI Gateway`,hint:`one key, every model`},{value:`other`,label:`Something else`,hint:`use your own provider credentials`}],hintLayout:`stacked`}),c===`gateway`){let e=await withSpinner(r,`Checking your Vercel login…`,async()=>{let e=await s.getVercelAuthStatus(t,{signal:o});return o?.throwIfAborted(),e});l=await r.select({message:CONNECTION_QUESTION,options:[projectConnectionOption(e),{value:`own-key`,label:`Use my own key`,hint:`paste an ${AI_GATEWAY_API_KEY_ENV_VAR}`}],hintLayout:`stacked`})}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}if(c===`other`)return r.acknowledge?await r.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):r.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
|
|
2
|
+
`),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`done`,outcome:`external-provider`};if(l===`own-key`)for(;;){let e;try{e=await r.password({message:`Enter your ${AI_GATEWAY_API_KEY_ENV_VAR}`,validate:e=>e.trim().length===0?`API key cannot be empty.`:void 0})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}o?.throwIfAborted();let n=e.trim(),i=await withSpinner(r,`Validating…`,()=>s.validateGatewayApiKey(n,o));if(o?.throwIfAborted(),i.kind===`invalid`){r.log.error(`${i.message} Check the key and try again, or Esc to cancel.`);continue}i.kind===`inconclusive`?r.log.warning(`Couldn't reach the gateway to validate (${i.message}). Saving the key anyway.`):r.log.success(`${import_picocolors.default.green(`✓`)} ${import_picocolors.default.bold(`Valid key`)}`);let a=await writeAiGatewayApiKey({projectRoot:t,apiKey:n,appendEnv:s.appendEnv});return o?.throwIfAborted(),r.log.success(`Saved ${a.envKey} to ${a.envFile}.`),{kind:`done`,credential:AI_GATEWAY_API_KEY_ENV_VAR}}else return await s.runLinkFlow({appRoot:t,prompter:r,signal:o,projectSelection:`create-or-link`})}export{CONNECTION_QUESTION,EXTERNAL_PROVIDER_INSTRUCTIONS,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,PROVIDER_QUESTION,runVercelFlow};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { type OutputSink, type SetupBox, WizardCancelledError } from "./step.js";
|
|
2
2
|
export { InteractionRequired } from "./ask.js";
|
|
3
|
-
export { type AiGatewayEnvFile, type ArgsHeadlessAiGateway, type ArgsHeadlessProject, type ChannelKind, type ChatPreference, createDefaultSetupState, requireProjectPath, type ResolvedAiGateway, type ResolvedAiGatewayCredentials, type ResolvedProjectPath, type ResolvedVercelProject, type ResolvedVercelProjectSpec, type SetupMode, type SetupState, snapshotSetupState, type WiringMode, } from "./state.js";
|
|
3
|
+
export { type AiGatewayEnvFile, type ArgsHeadlessAiGateway, type ArgsHeadlessProject, type ChannelKind, type ChatPreference, createDefaultSetupState, requireProjectPath, type ResolvedAiGateway, type ResolvedAiGatewayCredentials, type ResolvedProjectPath, type ResolvedVercelProject, type ResolvedVercelProjectSpec, type SetupMode, type SetupState, snapshotSetupState, type VercelProjectIdentity, type WiringMode, } from "./state.js";
|
|
4
4
|
export { type AnySetupBox, runHeadless, runInteractive, type RunnerOptions, type RunResult, } from "./runner.js";
|
|
5
5
|
export { createPrompter, type MultiSelectOptions, type NoteTone, type Prompter, type PrompterValue, type SelectCommonOptions, type SelectOption, type SingleSelectOptions, } from "./prompter.js";
|
|
6
6
|
export { createHeadlessPrompter, formatHeadlessEvent, type HeadlessEvent, type HeadlessLogSink, type HeadlessNextStep, HeadlessPromptError, } from "./headless.js";
|
|
@@ -7,7 +7,8 @@ export interface DetectedPackageManager {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Resolves a project's package manager from gathered facts: an explicit
|
|
10
|
-
* `packageManager` field wins, then the first known
|
|
10
|
+
* `packageManager` field wins, then the first known package-manager marker,
|
|
11
|
+
* then pnpm.
|
|
11
12
|
*/
|
|
12
13
|
export declare function resolvePackageManager(input: {
|
|
13
14
|
packageManagerField?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pathExists}from"./path-exists.js";import{dirname,join,resolve}from"node:path";import{readFile}from"node:fs/promises";const LOCKFILE_MANAGERS=[[`pnpm-lock.yaml`,`pnpm`],[`package-lock.json`,`npm`],[`yarn.lock`,`yarn`],[`bun.lock`,`bun`],[`bun.lockb`,`bun`]];function isPackageManagerKind(e){return e===`bun`||e===`npm`||e===`pnpm`||e===`yarn`}function resolvePackageManager(e){let t=e.packageManagerField?.split(`@`,1)[0]?.trim();if(t!==void 0&&isPackageManagerKind(t))return{kind:t,source:`package-manager-field`};for(let[t,n]of LOCKFILE_MANAGERS)if(e.lockfiles.includes(t))return{kind:n,source:`lockfile`};return{kind:`pnpm`,source:`default`}}function packageManagerFromUserAgent(e){let t=e?.split(`/`,1)[0];return t!==void 0&&isPackageManagerKind(t)?t:void 0}function detectInvokingPackageManager(){return packageManagerFromUserAgent(process.env.npm_config_user_agent)}async function detectPackageManagerInDirectory(t){let r;try{let e=JSON.parse(await readFile(join(t,`package.json`),`utf8`));typeof e==`object`&&e&&`packageManager`in e&&typeof e.packageManager==`string`&&(r=e.packageManager)}catch{}let i=[];for(let[r]of LOCKFILE_MANAGERS)await pathExists(join(t,r))&&i.push(r);let a=resolvePackageManager({packageManagerField:r,lockfiles:i});return a.source==="default"?void 0:a}async function detectAncestorPackageManager(e){let n=dirname(resolve(e));for(;;){let e=await detectPackageManagerInDirectory(n);if(e!==void 0)return e;let r=dirname(n);if(r===n)return;n=r}}async function detectPackageManager(e){return await detectPackageManagerInDirectory(resolve(e))??await detectAncestorPackageManager(e)??{kind:`pnpm`,source:`default`}}export{detectInvokingPackageManager,detectPackageManager,packageManagerFromUserAgent,resolvePackageManager};
|
|
1
|
+
import{pathExists}from"./path-exists.js";import{dirname,join,resolve}from"node:path";import{readFile}from"node:fs/promises";const LOCKFILE_MANAGERS=[[`pnpm-lock.yaml`,`pnpm`],[`pnpm-workspace.yaml`,`pnpm`],[`package-lock.json`,`npm`],[`yarn.lock`,`yarn`],[`bun.lock`,`bun`],[`bun.lockb`,`bun`]];function isPackageManagerKind(e){return e===`bun`||e===`npm`||e===`pnpm`||e===`yarn`}function resolvePackageManager(e){let t=e.packageManagerField?.split(`@`,1)[0]?.trim();if(t!==void 0&&isPackageManagerKind(t))return{kind:t,source:`package-manager-field`};for(let[t,n]of LOCKFILE_MANAGERS)if(e.lockfiles.includes(t))return{kind:n,source:`lockfile`};return{kind:`pnpm`,source:`default`}}function packageManagerFromUserAgent(e){let t=e?.split(`/`,1)[0];return t!==void 0&&isPackageManagerKind(t)?t:void 0}function detectInvokingPackageManager(){return packageManagerFromUserAgent(process.env.npm_config_user_agent)}async function detectPackageManagerInDirectory(t){let r;try{let e=JSON.parse(await readFile(join(t,`package.json`),`utf8`));typeof e==`object`&&e&&`packageManager`in e&&typeof e.packageManager==`string`&&(r=e.packageManager)}catch{}let i=[];for(let[r]of LOCKFILE_MANAGERS)await pathExists(join(t,r))&&i.push(r);let a=resolvePackageManager({packageManagerField:r,lockfiles:i});return a.source==="default"?void 0:a}async function detectAncestorPackageManager(e){let n=dirname(resolve(e));for(;;){let e=await detectPackageManagerInDirectory(n);if(e!==void 0)return e;let r=dirname(n);if(r===n)return;n=r}}async function detectPackageManager(e){return await detectPackageManagerInDirectory(resolve(e))??await detectAncestorPackageManager(e)??{kind:`pnpm`,source:`default`}}export{detectInvokingPackageManager,detectPackageManager,packageManagerFromUserAgent,resolvePackageManager};
|
|
@@ -8,4 +8,4 @@ import { yarnPackageManager } from "./yarn.js";
|
|
|
8
8
|
export declare function getPackageManagerStrategy(kind: PackageManagerKind): PackageManagerStrategy;
|
|
9
9
|
export { bunPackageManager, npmPackageManager, pnpmPackageManager, yarnPackageManager };
|
|
10
10
|
export { PNPM_WORKSPACE_CONTENT, PNPM_WORKSPACE_PATH } from "./pnpm.js";
|
|
11
|
-
export type { PackageManagerConfigurationResult, PackageManagerInstallOptions, PackageManagerInvocation, PackageManagerStrategy, } from "./types.js";
|
|
11
|
+
export type { PackageManagerConfigurationResult, PackageManagerConfigurationOptions, PackageManagerInstallOptions, PackageManagerInvocation, PackageManagerStrategy, } from "./types.js";
|
|
@@ -2,7 +2,17 @@ export declare const PNPM_WORKSPACE_PATH = "pnpm-workspace.yaml";
|
|
|
2
2
|
export declare const PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS: readonly ["list", "--depth", "-1", "--json"];
|
|
3
3
|
export declare const PNPM_WORKSPACE_CONTENT: string;
|
|
4
4
|
/** Whether pnpm can walk from this project into a parent-owned workspace. */
|
|
5
|
+
export declare function findAncestorPnpmWorkspaceRoot(projectRoot: string): string | undefined;
|
|
6
|
+
/** Whether pnpm can walk from this project into a parent-owned workspace. */
|
|
5
7
|
export declare function hasAncestorPnpmWorkspace(projectRoot: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the ancestor workspace root only when the workspace manifest's
|
|
10
|
+
* package candidates include `projectRoot`. If the manifest cannot be parsed,
|
|
11
|
+
* it is treated as a workspace owner so setup does not silently create nested
|
|
12
|
+
* standalone package-manager state in an ambiguous monorepo.
|
|
13
|
+
*/
|
|
14
|
+
export declare function findClaimingAncestorPnpmWorkspaceRoot(projectRoot: string): string | undefined;
|
|
15
|
+
export declare function ensurePnpmWorkspaceIncludesProject(projectRoot: string): Promise<"skipped" | "written">;
|
|
6
16
|
/**
|
|
7
17
|
* Reads `pnpm list --depth -1 --json` and answers whether the ancestor
|
|
8
18
|
* workspace explicitly includes `projectRoot`. `undefined` means the output
|
|
@@ -14,7 +24,7 @@ export declare const pnpmPackageManager: {
|
|
|
14
24
|
scaffoldFiles: {
|
|
15
25
|
"pnpm-workspace.yaml": string;
|
|
16
26
|
};
|
|
17
|
-
applyProjectConfiguration(projectRoot: string): Promise<{
|
|
27
|
+
applyProjectConfiguration(projectRoot: string, options: import("./types.js").PackageManagerConfigurationOptions | undefined): Promise<{
|
|
18
28
|
filesSkipped: never[];
|
|
19
29
|
filesWritten: string[];
|
|
20
30
|
} | {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import{pathExists}from"../../path-exists.js";import{existsSync,realpathSync}from"node:fs";import{dirname,extname,join,resolve}from"node:path";import{readFile,writeFile}from"node:fs/promises";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS=[`list`,`--depth`,`-1`,`--json`],PNPM_WORKSPACE_CONTENT=[`minimumReleaseAgeExclude:`,` - eve`,`allowBuilds:`,` sharp: false`,`# Compatibility for eve releases with an incomplete runtime manifest.`,`packageExtensions:`,` "eve@>=0.6.0-beta.13 <=0.7.0":`,` dependencies:`,` oxc-parser: 0.134.0`,``].join(`
|
|
1
|
+
import{pathExists}from"../../path-exists.js";import{workspacePatternForProject,workspacePatternsClaimProject}from"../../scaffold/workspace-glob.js";import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,extname,join,resolve}from"node:path";import{readFile,writeFile}from"node:fs/promises";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS=[`list`,`--depth`,`-1`,`--json`],PNPM_WORKSPACE_CONTENT=[`minimumReleaseAgeExclude:`,` - eve`,`allowBuilds:`,` sharp: false`,`# Compatibility for eve releases with an incomplete runtime manifest.`,`packageExtensions:`,` "eve@>=0.6.0-beta.13 <=0.7.0":`,` dependencies:`,` oxc-parser: 0.134.0`,``].join(`
|
|
2
2
|
`),EVE_RELEASE_AGE_EXCLUSION=` - eve`,SHARP_BUILD_POLICY=` sharp: false`;function findYamlBlockEnd(e,t){let n=t+1;for(;n<e.length;){let t=e[n]??``;if(t.length>0&&!t.startsWith(` `)&&!t.startsWith(` `))break;n+=1}return n}function withSharpBuildPolicy(e){let t=e.endsWith(`
|
|
3
3
|
`)?e:`${e}\n`,n=t.split(`
|
|
4
4
|
`),r=n.findIndex(e=>e===`allowBuilds:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}allowBuilds:\n${SHARP_BUILD_POLICY}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>/^\s+sharp:/.test(e)))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,SHARP_BUILD_POLICY),n.join(`
|
|
5
5
|
`)}function withExperimentalEveReleaseAgeExclusion(e){let t=e.endsWith(`
|
|
6
6
|
`)?e:`${e}\n`,n=t.split(`
|
|
7
7
|
`),r=n.findIndex(e=>e===`minimumReleaseAgeExclude:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}minimumReleaseAgeExclude:\n${EVE_RELEASE_AGE_EXCLUSION}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>e.trim()===`- eve`))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,EVE_RELEASE_AGE_EXCLUSION),n.join(`
|
|
8
|
-
`)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),r=withExperimentalEveReleaseAgeExclusion(withSharpBuildPolicy(n));return r===n?`skipped`:(await writeFile(t,r,`utf8`),`written`)}function
|
|
8
|
+
`)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),r=withExperimentalEveReleaseAgeExclusion(withSharpBuildPolicy(n));return r===n?`skipped`:(await writeFile(t,r,`utf8`),`written`)}function findAncestorPnpmWorkspaceRoot(e){let t=dirname(resolve(e));for(;;){if(existsSync(join(t,`pnpm-workspace.yaml`)))return t;let e=dirname(t);if(e===t)return;t=e}}function hasAncestorPnpmWorkspace(e){return findAncestorPnpmWorkspaceRoot(e)!==void 0}function parsePnpmWorkspacePackagePatterns(e){let t=e.split(/\r?\n/u),n=t.findIndex(e=>/^\s*packages:/u.test(e));if(n<0)return;let r=/^\s*packages:\s*\[(.*)\]\s*(?:#.*)?$/u.exec(t[n]??``);if(r!==null){let e=r[1].trim();return e.length===0?[]:e.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/gu,``)).filter(e=>e.length>0)}if(t[n]?.trim()!==`packages:`)return;let i=[];for(let e of t.slice(n+1)){if(/^\S/u.test(e))break;let t=/^\s*-\s*(.+?)\s*$/u.exec(e);t!==null&&i.push(t[1].replace(/^['"]|['"]$/gu,``))}return i}function findClaimingAncestorPnpmWorkspaceRoot(e){let t=findAncestorPnpmWorkspaceRoot(e);if(t===void 0)return;let r;try{r=parsePnpmWorkspacePackagePatterns(readFileSync(join(t,PNPM_WORKSPACE_PATH),`utf8`))}catch{return t}return r===void 0||workspacePatternsClaimProject(r,t,e)?t:void 0}function withPnpmWorkspacePackagePattern(e,t){let n=e.endsWith(`
|
|
9
|
+
`)?e:`${e}\n`,r=n.split(`
|
|
10
|
+
`),i=r.findIndex(e=>e.trim()===`packages:`);if(i<0)return`${n.trim().length===0?``:`${n}\n`}packages:\n - ${t}\n`;let a=findYamlBlockEnd(r,i);for(;a>i+1&&r[a-1]===``;)--a;return r.splice(a,0,` - ${t}`),r.join(`
|
|
11
|
+
`)}async function ensurePnpmWorkspaceIncludesProject(e){let n=findAncestorPnpmWorkspaceRoot(e);if(n===void 0||resolve(n)===resolve(e)||findClaimingAncestorPnpmWorkspaceRoot(e)===n)return`skipped`;let r=join(n,PNPM_WORKSPACE_PATH),i=await readFile(r,`utf8`),a=withPnpmWorkspacePackagePattern(i,workspacePatternForProject(n,e));return a===i?`skipped`:(await writeFile(r,a,`utf8`),`written`)}function pnpmWorkspaceClaimsProject(e,t){let n;try{n=JSON.parse(e)}catch{return}if(!Array.isArray(n)||n.length===0)return;let canonicalPath=e=>{let t=resolve(e);try{return realpathSync.native(t)}catch{return t}},r=canonicalPath(t),i=!1;for(let e of n){if(typeof e!=`object`||!e)continue;let t=e.path;if(typeof t==`string`&&(i=!0,canonicalPath(t)===r))return!0}return i?!1:void 0}const pnpmPackageManager={kind:`pnpm`,scaffoldFiles:{[PNPM_WORKSPACE_PATH]:PNPM_WORKSPACE_CONTENT},async applyProjectConfiguration(e,t){let n=t?.workspaceProbeRoot??e,r=await ensurePnpmWorkspaceIncludesProject(n),i=join(findClaimingAncestorPnpmWorkspaceRoot(n)??e,PNPM_WORKSPACE_PATH),a=await ensurePnpmWorkspacePolicy(i);return(r===`written`||a===`written`?`written`:`skipped`)==`written`?{filesSkipped:[],filesWritten:[i]}:{filesSkipped:[i],filesWritten:[]}},devArguments:()=>[`exec`,`eve`,`dev`],installArguments:e=>[`install`,`--no-frozen-lockfile`,...e.bypassMinimumReleaseAge===!0?[`--config.minimum-release-age=0`]:[],...e.ignoreWorkspace===!0?[`--ignore-workspace`]:[]],prepareArguments:(e,t)=>[`--dir`,e,...t],resolveInvocation(e){let t=process.env.npm_execpath;if(t!==void 0&&t.toLowerCase().includes(`pnpm`)){let n=extname(t).toLowerCase();return n===`.cjs`||n===`.js`?{args:[t,...e],command:process.execPath}:{args:e,command:t,shell:process.platform===`win32`}}if(process.env.npm_config_user_agent?.toLowerCase().startsWith(`pnpm/`))return{args:e,command:`pnpm`,shell:process.platform===`win32`};let n=process.env.PNPM_HOME;if(n!==void 0){let t=join(n,process.platform===`win32`?`pnpm.CMD`:`pnpm`);if(existsSync(t))return{args:e,command:t,shell:process.platform===`win32`}}return{args:e,command:`pnpm`}}};export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,PNPM_WORKSPACE_PATH,ensurePnpmWorkspaceIncludesProject,findAncestorPnpmWorkspaceRoot,findClaimingAncestorPnpmWorkspaceRoot,hasAncestorPnpmWorkspace,pnpmPackageManager,pnpmWorkspaceClaimsProject};
|
|
@@ -10,6 +10,15 @@ export interface PackageManagerConfigurationResult {
|
|
|
10
10
|
readonly filesSkipped: readonly string[];
|
|
11
11
|
readonly filesWritten: readonly string[];
|
|
12
12
|
}
|
|
13
|
+
/** Context for manager-owned project configuration. */
|
|
14
|
+
export interface PackageManagerConfigurationOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Final project path used to discover ancestor workspaces. This differs from
|
|
17
|
+
* `projectRoot` only when a scaffold is staged in a temporary directory
|
|
18
|
+
* before being moved into place.
|
|
19
|
+
*/
|
|
20
|
+
readonly workspaceProbeRoot?: string;
|
|
21
|
+
}
|
|
13
22
|
export interface PackageManagerInstallOptions {
|
|
14
23
|
/** Disables the manager's minimum-release-age cooldown for this run when supported. */
|
|
15
24
|
readonly bypassMinimumReleaseAge?: boolean;
|
|
@@ -30,7 +39,7 @@ export interface PackageManagerStrategy {
|
|
|
30
39
|
/** Manager-owned files included when creating a fresh project. */
|
|
31
40
|
readonly scaffoldFiles: Readonly<Record<string, string>>;
|
|
32
41
|
/** Adds or reconciles manager-owned configuration in an existing project. */
|
|
33
|
-
applyProjectConfiguration(projectRoot: string): Promise<PackageManagerConfigurationResult>;
|
|
42
|
+
applyProjectConfiguration(projectRoot: string, options?: PackageManagerConfigurationOptions): Promise<PackageManagerConfigurationResult>;
|
|
34
43
|
/** Arguments that run the project-local eve development command. */
|
|
35
44
|
devArguments(): readonly string[];
|
|
36
45
|
/** Arguments that install project dependencies. */
|
|
@@ -17,15 +17,18 @@ declare const VercelProjectReferenceSchema: z.ZodObject<{
|
|
|
17
17
|
export type VercelProjectReference = z.infer<typeof VercelProjectReferenceSchema>;
|
|
18
18
|
/** Parses the complete Vercel owner and project environment pair. */
|
|
19
19
|
export declare function projectReferenceFromEnvironment(environment: Readonly<Record<string, string | undefined>>): VercelProjectReference | undefined;
|
|
20
|
-
/**
|
|
20
|
+
/** Rejects Vercel's unsupported legacy link directory before link mutation. */
|
|
21
|
+
export declare function assertNoLegacyProjectLinkDirectory(projectRoot: string): Promise<void>;
|
|
22
|
+
/** Reads a validated project reference from Vercel's link metadata directory. */
|
|
21
23
|
export declare function readProjectLink(projectPath: string): Promise<VercelProjectReference | undefined>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
/** Cancellation options shared by Vercel project read/operation helpers. */
|
|
25
|
+
export interface VercelProjectOperationOptions {
|
|
26
|
+
readonly signal?: AbortSignal;
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
26
29
|
* Reads local Vercel link metadata and checks whether the linked project has a production alias.
|
|
27
30
|
*/
|
|
28
|
-
export declare function detectDeployment(projectPath: string, options?:
|
|
31
|
+
export declare function detectDeployment(projectPath: string, options?: VercelProjectOperationOptions): Promise<DeploymentInfo>;
|
|
29
32
|
/** Human-readable identity of a linked Vercel project, for the dashboard status bar. */
|
|
30
33
|
export interface ProjectIdentity {
|
|
31
34
|
projectName: string;
|
|
@@ -43,7 +46,7 @@ export interface ProjectIdentity {
|
|
|
43
46
|
*
|
|
44
47
|
* @param projectPath Absolute path of the linked project directory.
|
|
45
48
|
*/
|
|
46
|
-
export declare function detectProjectIdentity(projectPath: string, options?:
|
|
49
|
+
export declare function detectProjectIdentity(projectPath: string, options?: VercelProjectOperationOptions): Promise<ProjectIdentity | undefined>;
|
|
47
50
|
export type ProjectResolution = {
|
|
48
51
|
kind: "unresolved";
|
|
49
52
|
} | {
|
|
@@ -59,7 +62,7 @@ export declare function projectResolutionFromDeployment(deployment: DeploymentIn
|
|
|
59
62
|
* Side-effect-free fact gathering after a link: reads `.vercel/project.json`
|
|
60
63
|
* to resolve the project. The on-disk link is the single source of truth.
|
|
61
64
|
*/
|
|
62
|
-
export declare function detectProjectResolution(projectRoot: string, options?:
|
|
65
|
+
export declare function detectProjectResolution(projectRoot: string, options?: VercelProjectOperationOptions): Promise<ProjectResolution>;
|
|
63
66
|
export declare function mergeProjectResolution(current: ProjectResolution, next: ProjectResolution): ProjectResolution;
|
|
64
67
|
export declare function projectResolutionFromDeployResult(project: ProjectResolution, deploy: {
|
|
65
68
|
deployed: boolean;
|
|
@@ -1 +1 @@
|
|
|
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
|
+
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,stat}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 assertNoLegacyProjectLinkDirectory(e){try{if(!(await stat(join(e,`.now`))).isDirectory())return}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}throw Error("Legacy Vercel link directory `.now` is not supported. Remove `.now` before linking this project.")}async function readProjectLink(e){await assertNoLegacyProjectLinkDirectory(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{assertNoLegacyProjectLinkDirectory,detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectReferenceFromEnvironment,projectResolutionFromDeployResult,projectResolutionFromDeployment,readProjectLink};
|
|
@@ -88,11 +88,24 @@ export interface SelectCommonOptions<T extends PrompterValue> {
|
|
|
88
88
|
/** Outcome lines from earlier laps of a looping menu. */
|
|
89
89
|
notices?: readonly SelectNotice[];
|
|
90
90
|
}
|
|
91
|
+
/** A selectable action appended after local matches for a non-empty query. */
|
|
92
|
+
export interface SearchAction<T extends PrompterValue> {
|
|
93
|
+
label(query: string): string;
|
|
94
|
+
value(query: string): T;
|
|
95
|
+
/**
|
|
96
|
+
* Loads replacement rows without closing a repainting picker. Plain CLI
|
|
97
|
+
* prompts still return {@link value}; the TUI keeps the search input open
|
|
98
|
+
* and shows the wait beside it.
|
|
99
|
+
*/
|
|
100
|
+
load?(query: string): Promise<readonly SelectOption<T>[]>;
|
|
101
|
+
}
|
|
91
102
|
/** Single-select form: navigate, then enter picks the highlighted option. */
|
|
92
103
|
export interface SingleSelectOptions<T extends PrompterValue> extends SelectCommonOptions<T> {
|
|
93
104
|
multiple?: false;
|
|
94
105
|
/** Pre-position the cursor on the option whose value matches. */
|
|
95
106
|
initialValue?: T;
|
|
107
|
+
/** Appended after local matches for each non-empty query. Requires `search: true`. */
|
|
108
|
+
searchAction?: SearchAction<T>;
|
|
96
109
|
}
|
|
97
110
|
/** Multi-select form: space or enter toggles rows; enter on the trailing Submit row confirms the marked set. */
|
|
98
111
|
export interface MultiSelectOptions<T extends PrompterValue> extends SelectCommonOptions<T> {
|
|
@@ -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{WizardCancelledError}from"./step.js";import{h,ht,q}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let n,r=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let r=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=i;switch(t.mask?o=a:this.value&&(o=this.userInputWithCursor),this.state){case`error`:return`${r.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=this.value||t.placeholder||``;return t.mask&&(n=this.value?REDACTED_DISPLAY:t.placeholder??``),formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${r}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${r}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(n?.note())}\n`}}});return n=attachQuitGuard(r),r.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});function printNotices(e){for(let n of e??[])n.tone===`success`?t.success(n.text):n.tone===`warning`?t.warning(n.text):n.tone===`error`?t.error(n.text):t.message(n.text)}return{async text(n){t.settle(),printNotices(n.notices);let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle(),printNotices(n.notices);let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
|
|
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{WizardCancelledError}from"./step.js";import{h,ht,q}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let n,r=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let r=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=i;switch(t.mask?o=a:this.value&&(o=this.userInputWithCursor),this.state){case`error`:return`${r.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=this.value||t.placeholder||``;return t.mask&&(n=this.value?REDACTED_DISPLAY:t.placeholder??``),formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${r}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${r}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(n?.note())}\n`}}});return n=attachQuitGuard(r),r.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});function printNotices(e){for(let n of e??[])n.tone===`success`?t.success(n.text):n.tone===`warning`?t.warning(n.text):n.tone===`error`?t.error(n.text):t.message(n.text)}return{async text(n){t.settle(),printNotices(n.notices);let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle(),printNotices(n.notices);let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,searchAction:n.multiple===!0?void 0:n.searchAction,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"../update/package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`7.0.0-beta.178`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.2.2`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PackageManagerKind } from "../../package-manager.js";
|
|
2
|
+
import { type WorkspaceRootMutation } from "../workspace-root.js";
|
|
2
3
|
export declare const CURRENT_DIRECTORY_PROJECT_NAME = ".";
|
|
3
4
|
export declare const DEFAULT_AI_PACKAGE_VERSION = "__AI_SDK_VERSION__";
|
|
4
5
|
export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "__VERCEL_CONNECT_VERSION__";
|
|
@@ -58,6 +59,13 @@ export interface ScaffoldBaseProjectOptions {
|
|
|
58
59
|
connectPackageVersion?: string;
|
|
59
60
|
zodPackageVersion?: string;
|
|
60
61
|
typescriptPackageVersion?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Final project path used to discover ancestor workspaces. This differs from
|
|
64
|
+
* the write target only when the CLI stages a scaffold before moving it into
|
|
65
|
+
* place.
|
|
66
|
+
*/
|
|
67
|
+
workspaceProbeDirectory?: string;
|
|
68
|
+
onWorkspaceRootMutation?: (mutation: WorkspaceRootMutation) => void | Promise<void>;
|
|
61
69
|
/**
|
|
62
70
|
* Scaffold an inline provider `byok` block in `agent.ts` that reads the
|
|
63
71
|
* provider key from `process.env` instead of relying on the managed Vercel
|