eve 0.12.3 → 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 +11 -0
- package/dist/src/cli/commands/deploy.js +1 -1
- 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/setup-flow.d.ts +5 -0
- package/dist/src/cli/dev/tui/setup-panel.d.ts +4 -1
- package/dist/src/cli/dev/tui/setup-panel.js +1 -1
- 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 +2 -2
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/tool-auth.d.ts +16 -39
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/internal/application/package.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/definitions/tool.d.ts +3 -48
- package/dist/src/public/definitions/tool.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/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/model.d.ts +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 +9 -51
- package/dist/src/setup/vercel-project.js +1 -1
- package/docs/guides/auth-and-route-protection.md +2 -4
- package/docs/guides/dev-tui.md +1 -1
- package/docs/reference/cli.md +1 -1
- package/docs/reference/typescript-api.md +0 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{extractGitHubCommentTrigger,formatGitHubContextBlock,prependGitHubContext}from"#public/channels/github/inbound.js";import{buildGitHubBinding}from"#public/channels/github/binding.js";import{buildGitHubPullRequestContext,mergeGitHubContext}from"#public/channels/github/pr-context.js";import{continuationTokenFromState,stateFromIssueCommentEvent,stateFromIssueEvent,stateFromPullRequestEvent,stateFromPullRequestReviewCommentEvent}from"#public/channels/github/state.js";const log=createLogger(`github.dispatch`);async function dispatchIssueComment(e){if(isIgnoredInboundComment(e.event.comment.body,e.event.comment.author,e.botName))return;let t=buildInboundContext(e.config,e.event);await dispatchCommentTurn({body:e.event.comment.body,botName:e.botName,commentUrl:e.event.comment.htmlUrl,event:e.event,handlerResult:()=>e.handler(t,toGitHubComment(e.event.comment)),config:e.config,send:e.send,state:stateFromIssueCommentEvent(e.event)})}async function dispatchPullRequestReviewComment(e){if(isIgnoredInboundComment(e.event.comment.body,e.event.comment.author,e.botName))return;let t=buildInboundContext(e.config,e.event);await dispatchCommentTurn({body:e.event.comment.body,botName:e.botName,commentUrl:e.event.comment.htmlUrl,event:e.event,handlerResult:()=>e.handler(t,toGitHubComment(e.event.comment)),config:e.config,send:e.send,state:stateFromPullRequestReviewCommentEvent(e.event)})}async function dispatchIssue(e){let t=buildInboundContext(e.config,e.event);await dispatchWebhookEventTurn({config:e.config,event:e.event,handlerResult:()=>e.handler(t,e.event.issue),message:formatIssueEventMessage(e.event),send:e.send,state:stateFromIssueEvent(e.event)})}async function dispatchPullRequest(e){let t=buildInboundContext(e.config,e.event);await dispatchWebhookEventTurn({config:e.config,event:e.event,handlerResult:()=>e.handler(t,e.event.pullRequest),message:formatPullRequestEventMessage(e.event),send:e.send,state:stateFromPullRequestEvent(e.event)})}async function dispatchWebhookEventTurn(e){let t=await runInboundHandler({event:e.event,handlerResult:e.handlerResult});t!=null&&await sendGitHubTurn({auth:t.auth,event:e.event,message:e.message,context:mergeGitHubContext({github:await buildPullRequestContext(e.config,e.state,e.event.delivery.id),hook:t.context}),send:e.send,state:e.state})}async function dispatchCommentTurn(e){let t=await runInboundHandler({event:e.event,handlerResult:e.handlerResult});if(t==null)return;let r=extractGitHubCommentTrigger({body:e.body,botName:e.botName})?.message??e.body.trim();await sendGitHubTurn({auth:t.auth,commentUrl:e.commentUrl,event:e.event,message:r,context:mergeGitHubContext({github:await buildPullRequestContext(e.config,e.state,e.event.delivery.id),hook:t.context}),send:e.send,state:e.state})}async function runInboundHandler(e){try{return await e.handlerResult()}catch(n){logError(log,`GitHub inbound handler failed`,n,{deliveryId:e.event.delivery.id});return}}async function sendGitHubTurn(e){let n=formatGitHubContextBlock({deliveryId:e.event.delivery.id,commentUrl:e.commentUrl,headSha:e.state.headSha,issueNumber:e.state.issueNumber,pullRequestNumber:e.state.pullRequestNumber,repository:e.event.repository,sender:e.event.sender}),i=prependGitHubContext(e.message,n);try{await e.send({message:i,context:e.context},{auth:e.auth,continuationToken:continuationTokenFromState(e.state),state:e.state})}catch(n){logError(log,e.logMessage??`GitHub delivery failed`,n,{deliveryId:e.event.delivery.id})}}async function buildPullRequestContext(e,n,r){try{return await buildGitHubPullRequestContext({api:e.api,config:e.pullRequestContext,credentials:e.credentials,installationId:n.installationId??void 0,owner:n.owner,pullRequestNumber:n.pullRequestNumber,repo:n.repo})}catch(e){logError(log,`GitHub pull-request context failed — swallowed`,e,{deliveryId:r});return}}function buildInboundContext(e,t){let n=buildGitHubBinding({config:e,state:t.kind===`issue_comment`?stateFromIssueCommentEvent(t):t.kind===`issues`?stateFromIssueEvent(t):t.kind===`pull_request`?stateFromPullRequestEvent(t):stateFromPullRequestReviewCommentEvent(t)});return{conversation:t.conversation,delivery:t.delivery,github:n.github,repository:t.repository,sender:t.sender,thread:n.thread}}function toGitHubComment(e){return{author:e.author,body:e.body,htmlUrl:e.htmlUrl,id:e.id,raw:e.raw,url:e.url}}function formatIssueEventMessage(e){let t=readString(e.issue.raw.title);return`Issue ${e.issue.action}: #${e.issue.issueNumber}${t?` ${t}`:``}`}function formatPullRequestEventMessage(e){let t=readString(e.pullRequest.raw.title);return`Pull request ${e.pullRequest.action}: #${e.pullRequest.pullRequestNumber}${t?` ${t}`:``}`}function isIgnoredInboundComment(e,t,n){if(e.includes(`<!-- eve:github:`)||t?.type===`Bot`)return!0;let r=n?`${n}[bot]`.toLowerCase():``;return r.length>0&&t?.login.toLowerCase()===r}function readString(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{dispatchIssue,dispatchIssueComment,dispatchPullRequest,dispatchPullRequestReviewComment};
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{extractGitHubCommentTrigger,formatGitHubContextBlock,prependGitHubContext}from"#public/channels/github/inbound.js";import{buildGitHubBinding}from"#public/channels/github/binding.js";import{buildGitHubPullRequestContext,mergeGitHubContext}from"#public/channels/github/pr-context.js";import{continuationTokenFromState,stateFromIssueCommentEvent,stateFromIssueEvent,stateFromPullRequestEvent,stateFromPullRequestReviewCommentEvent}from"#public/channels/github/state.js";const log=createLogger(`github.dispatch`);async function dispatchIssueComment(e){if(isIgnoredInboundComment(e.event.comment.body,e.event.comment.author,e.botName))return;let t=buildInboundContext(e.config,e.event);await dispatchCommentTurn({body:e.event.comment.body,botName:e.botName,commentUrl:e.event.comment.htmlUrl,event:e.event,handlerResult:()=>e.handler(t,toGitHubComment(e.event.comment)),config:e.config,send:e.send,state:stateFromIssueCommentEvent(e.event)})}async function dispatchPullRequestReviewComment(e){if(isIgnoredInboundComment(e.event.comment.body,e.event.comment.author,e.botName))return;let t=buildInboundContext(e.config,e.event);await dispatchCommentTurn({body:e.event.comment.body,botName:e.botName,commentUrl:e.event.comment.htmlUrl,event:e.event,handlerResult:()=>e.handler(t,toGitHubComment(e.event.comment)),config:e.config,send:e.send,state:stateFromPullRequestReviewCommentEvent(e.event)})}async function dispatchIssue(e){let t=buildInboundContext(e.config,e.event);await dispatchWebhookEventTurn({config:e.config,event:e.event,handlerResult:()=>e.handler(t,e.event.issue),message:formatIssueEventMessage(e.event),send:e.send,state:stateFromIssueEvent(e.event)})}async function dispatchPullRequest(e){let t=buildInboundContext(e.config,e.event);await dispatchWebhookEventTurn({config:e.config,event:e.event,handlerResult:()=>e.handler(t,e.event.pullRequest),message:formatPullRequestEventMessage(e.event),send:e.send,state:stateFromPullRequestEvent(e.event)})}async function dispatchWebhookEventTurn(e){let t=await runInboundHandler({event:e.event,handlerResult:e.handlerResult});t!=null&&await sendGitHubTurn({auth:t.auth,event:e.event,message:e.message,context:mergeGitHubContext({github:await buildPullRequestContext(e.config,e.state,e.event.delivery.id),hook:t.context}),send:e.send,state:e.state})}async function dispatchCommentTurn(e){let t=await runInboundHandler({event:e.event,handlerResult:e.handlerResult});if(t==null)return;let r=extractGitHubCommentTrigger({body:e.body,botName:e.botName})?.message??e.body.trim();await sendGitHubTurn({auth:t.auth,commentUrl:e.commentUrl,event:e.event,message:r,context:mergeGitHubContext({github:await buildPullRequestContext(e.config,e.state,e.event.delivery.id),hook:t.context}),send:e.send,state:e.state})}async function runInboundHandler(e){try{return await e.handlerResult()}catch(n){logError(log,`GitHub inbound handler failed`,n,{deliveryId:e.event.delivery.id});return}}async function sendGitHubTurn(e){let n=formatGitHubContextBlock({deliveryId:e.event.delivery.id,commentUrl:e.commentUrl,headSha:e.state.headSha,issueNumber:e.state.issueNumber,pullRequestNumber:e.state.pullRequestNumber,repository:e.event.repository,sender:e.event.sender}),i=prependGitHubContext(e.message,n);try{await e.send({message:i,context:e.context},{auth:e.auth,continuationToken:continuationTokenFromState(e.state),state:e.state})}catch(n){logError(log,e.logMessage??`GitHub delivery failed`,n,{deliveryId:e.event.delivery.id})}}async function buildPullRequestContext(e,n,r){try{return await buildGitHubPullRequestContext({api:e.api,baseSha:n.baseSha,config:e.pullRequestContext,credentials:e.credentials,headSha:n.headSha,installationId:n.installationId??void 0,owner:n.owner,pullRequestNumber:n.pullRequestNumber,repo:n.repo})}catch(e){logError(log,`GitHub pull-request context failed — swallowed`,e,{deliveryId:r});return}}function buildInboundContext(e,t){let n=buildGitHubBinding({config:e,state:t.kind===`issue_comment`?stateFromIssueCommentEvent(t):t.kind===`issues`?stateFromIssueEvent(t):t.kind===`pull_request`?stateFromPullRequestEvent(t):stateFromPullRequestReviewCommentEvent(t)});return{conversation:t.conversation,delivery:t.delivery,github:n.github,repository:t.repository,sender:t.sender,thread:n.thread}}function toGitHubComment(e){return{author:e.author,body:e.body,htmlUrl:e.htmlUrl,id:e.id,raw:e.raw,url:e.url}}function formatIssueEventMessage(e){let t=readString(e.issue.raw.title);return`Issue ${e.issue.action}: #${e.issue.issueNumber}${t?` ${t}`:``}`}function formatPullRequestEventMessage(e){let t=readString(e.pullRequest.raw.title);return`Pull request ${e.pullRequest.action}: #${e.pullRequest.pullRequestNumber}${t?` ${t}`:``}`}function isIgnoredInboundComment(e,t,n){if(e.includes(`<!-- eve:github:`)||t?.type===`Bot`)return!0;let r=n?`${n}[bot]`.toLowerCase():``;return r.length>0&&t?.login.toLowerCase()===r}function readString(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{dispatchIssue,dispatchIssueComment,dispatchPullRequest,dispatchPullRequestReviewComment};
|
|
@@ -22,8 +22,18 @@ export interface GitHubPullRequestContextConfig {
|
|
|
22
22
|
/** Input for building one-shot model context for a pull request. */
|
|
23
23
|
export interface GitHubPullRequestContextInput {
|
|
24
24
|
readonly api?: GitHubApiOptions;
|
|
25
|
+
/**
|
|
26
|
+
* When set with {@link headSha}, file patches load via the compare API for
|
|
27
|
+
* this exact base/head pair instead of `/pulls/{number}/files` (current head).
|
|
28
|
+
*/
|
|
29
|
+
readonly baseSha?: string | null;
|
|
25
30
|
readonly config?: GitHubPullRequestContextConfig;
|
|
26
31
|
readonly credentials?: GitHubChannelCredentials;
|
|
32
|
+
/**
|
|
33
|
+
* Webhook-resolved head SHA for this turn. When set, metadata and diffs pin to
|
|
34
|
+
* this commit so injected context matches sandbox checkout.
|
|
35
|
+
*/
|
|
36
|
+
readonly headSha?: string | null;
|
|
27
37
|
readonly installationId?: number;
|
|
28
38
|
readonly owner: string;
|
|
29
39
|
readonly pullRequestNumber: number | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{getGitHubPullRequest,listGitHubPullRequestFiles}from"#public/channels/github/api.js";const MAX_PATCH_BYTES=2e4,GITHUB_DEFAULT_EXCLUDED_DIFF_FILES=[`**/pnpm-lock.yaml`,`**/package-lock.json`,`**/npm-shrinkwrap.json`,`**/yarn.lock`,`**/bun.lockb`,`**/Cargo.lock`,`**/go.sum`,`**/poetry.lock`,`**/Pipfile.lock`,`**/uv.lock`,`**/composer.lock`,`**/Gemfile.lock`,`**/*.min.js`,`**/*.min.css`,`**/*.map`,`**/*.snap`];async function buildGitHubPullRequestContext(
|
|
1
|
+
import{getGitHubPullRequest,listGitHubCompareFiles,listGitHubPullRequestFiles}from"#public/channels/github/api.js";const MAX_PATCH_BYTES=2e4,GITHUB_DEFAULT_EXCLUDED_DIFF_FILES=[`**/pnpm-lock.yaml`,`**/package-lock.json`,`**/npm-shrinkwrap.json`,`**/yarn.lock`,`**/bun.lockb`,`**/Cargo.lock`,`**/go.sum`,`**/poetry.lock`,`**/Pipfile.lock`,`**/uv.lock`,`**/composer.lock`,`**/Gemfile.lock`,`**/*.min.js`,`**/*.min.css`,`**/*.map`,`**/*.snap`];async function buildGitHubPullRequestContext(r){if(r.pullRequestNumber===null)return;let a=withPinnedPullRequestShas(await getGitHubPullRequest({api:r.api,credentials:r.credentials,installationId:r.installationId,owner:r.owner,pullRequestNumber:r.pullRequestNumber,repo:r.repo}),r),o=renderPullRequestMetadata(a),s=readNonEmptySha(r.baseSha)??readNonEmptySha(a.base.sha),c=readNonEmptySha(r.headSha)??readNonEmptySha(a.head.sha),l=readNonEmptySha(r.headSha)!==void 0&&c!==void 0&&s!==void 0?(await listGitHubCompareFiles({api:r.api,baseSha:s,credentials:r.credentials,headSha:c,installationId:r.installationId,owner:r.owner,repo:r.repo})).slice(0,50):await listGitHubPullRequestFiles({api:r.api,credentials:r.credentials,installationId:r.installationId,owner:r.owner,perPage:50,pullRequestNumber:r.pullRequestNumber,repo:r.repo}),u=[...GITHUB_DEFAULT_EXCLUDED_DIFF_FILES,...r.config?.excludedFiles??[]];return o.push(``,...renderPullRequestFiles(l,u)),[[`GitHub pull request context for the current turn. `,`Use this as background for the user's GitHub comment.`,``,o.join(`
|
|
2
2
|
`)].join(`
|
|
3
|
-
`)]}function mergeGitHubContext(e){let t=e.github??[],n=e.hook??[];if(!(t.length===0&&n.length===0))return[...t,...n]}function renderPullRequestMetadata(e){return[`<github_pull_request>`,`number: ${e.number}`,`title: ${e.title}`,`state: ${e.state??`unknown`}`,`draft: ${e.draft?`true`:`false`}`,...e.author?.login?[`author: ${e.author.login}`]:[],...e.htmlUrl?[`url: ${e.htmlUrl}`]:[],...e.base.ref?[`base_ref: ${e.base.ref}`]:[],...e.base.sha?[`base_sha: ${e.base.sha}`]:[],...e.head.ref?[`head_ref: ${e.head.ref}`]:[],...e.head.sha?[`head_sha: ${e.head.sha}`]:[],...e.mergeable===null||e.mergeable===void 0?[]:[`mergeable: ${e.mergeable?`true`:`false`}`],...e.changedFiles===void 0?[]:[`changed_files: ${e.changedFiles}`],...e.additions===void 0?[]:[`additions: ${e.additions}`],...e.deletions===void 0?[]:[`deletions: ${e.deletions}`],...e.body?[``,`body:`,indent(truncateText(e.body,4e3))]:[],`</github_pull_request>`]}function renderPullRequestFiles(e,t){if(e.length===0)return[`<github_pull_request_files>`,`none`,`</github_pull_request_files>`];let
|
|
3
|
+
`)]}function mergeGitHubContext(e){let t=e.github??[],n=e.hook??[];if(!(t.length===0&&n.length===0))return[...t,...n]}function withPinnedPullRequestShas(e,t){let n=readNonEmptySha(t.headSha),r=readNonEmptySha(t.baseSha);return n===void 0&&r===void 0?e:{...e,base:{...e.base,sha:r??e.base.sha},head:{...e.head,sha:n??e.head.sha}}}function readNonEmptySha(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function renderPullRequestMetadata(e){return[`<github_pull_request>`,`number: ${e.number}`,`title: ${e.title}`,`state: ${e.state??`unknown`}`,`draft: ${e.draft?`true`:`false`}`,...e.author?.login?[`author: ${e.author.login}`]:[],...e.htmlUrl?[`url: ${e.htmlUrl}`]:[],...e.base.ref?[`base_ref: ${e.base.ref}`]:[],...e.base.sha?[`base_sha: ${e.base.sha}`]:[],...e.head.ref?[`head_ref: ${e.head.ref}`]:[],...e.head.sha?[`head_sha: ${e.head.sha}`]:[],...e.mergeable===null||e.mergeable===void 0?[]:[`mergeable: ${e.mergeable?`true`:`false`}`],...e.changedFiles===void 0?[]:[`changed_files: ${e.changedFiles}`],...e.additions===void 0?[]:[`additions: ${e.additions}`],...e.deletions===void 0?[]:[`deletions: ${e.deletions}`],...e.body?[``,`body:`,indent(truncateText(e.body,4e3))]:[],`</github_pull_request>`]}function renderPullRequestFiles(e,t){if(e.length===0)return[`<github_pull_request_files>`,`none`,`</github_pull_request_files>`];let n=[`<github_pull_request_files>`],i=MAX_PATCH_BYTES,a=!1;for(let r of e){if(n.push(renderFileSummary(r)),fileMatchesAnyGlob(r.filename,t)){n.push(` patch omitted (excluded)`);continue}if(r.patch===void 0)continue;if(i<=0){a=!0;continue}let e=truncateByBytes(r.patch,i);n.push(`patch:`,indent(e.text)),i-=e.bytes,e.truncated&&(a=!0,i=0)}return a&&n.push(``,`patches_truncated: true`,`max_patch_bytes: ${MAX_PATCH_BYTES}`),n.push(`</github_pull_request_files>`),n}function renderFileSummary(e){let t=[e.status??`modified`,e.additions===void 0?void 0:`+${e.additions}`,e.deletions===void 0?void 0:`-${e.deletions}`].filter(e=>e!==void 0);return`- ${e.filename}${t.length>0?` (${t.join(`, `)})`:``}`}function fileMatchesAnyGlob(e,t){return t.some(t=>globToRegExp(t).test(e))}function globToRegExp(e){let t=``;for(let n=0;n<e.length;n+=1){let r=e.charAt(n);r===`*`?e[n+1]===`*`?(t+=`.*`,n+=1,e[n+1]===`/`&&(n+=1)):t+=`[^/]*`:`\\^$.|?+()[]{}`.includes(r)?t+=`\\${r}`:t+=r}return RegExp(`^${t}$`,`u`)}function truncateByBytes(e,t){let n=new TextEncoder().encode(e);return n.byteLength<=t?{bytes:n.byteLength,text:e,truncated:!1}:{bytes:t,text:`${new TextDecoder().decode(n.slice(0,t))}\n[truncated]`,truncated:!0}}function truncateText(e,t){return e.length<=t?e:`${e.slice(0,t)}\n[truncated]`}function indent(e){return e.split(`
|
|
4
4
|
`).map(e=>` ${e}`).join(`
|
|
5
5
|
`)}export{GITHUB_DEFAULT_EXCLUDED_DIFF_FILES,buildGitHubPullRequestContext,fileMatchesAnyGlob,mergeGitHubContext};
|
|
@@ -21,8 +21,9 @@ export interface NeedsApprovalContext<TInput = Record<string, unknown>> {
|
|
|
21
21
|
}
|
|
22
22
|
export type { ToolModelOutput } from "#shared/tool-definition.js";
|
|
23
23
|
/**
|
|
24
|
-
* Authorization
|
|
25
|
-
*
|
|
24
|
+
* Authorization provider passed to {@link ToolContext.getToken} or
|
|
25
|
+
* {@link ToolContext.requireAuth}. Accepts the same shapes as a connection's
|
|
26
|
+
* `auth`:
|
|
26
27
|
* - a `getToken`-only object (static API keys, pre-provisioned JWTs);
|
|
27
28
|
* `principalType` may be omitted and defaults to `"app"`.
|
|
28
29
|
* - a full interactive OAuth definition (e.g. `connect("okta/myagent")` from
|
|
@@ -62,42 +63,14 @@ export interface ToolAuthOptions {
|
|
|
62
63
|
*
|
|
63
64
|
* Extends {@link SessionContext} with token accessors. Passing a provider
|
|
64
65
|
* resolves that provider inline, which lets one tool use multiple credentials.
|
|
65
|
-
* For backwards compatibility, calling the accessors without a provider uses
|
|
66
|
-
* the tool's deprecated top-level `auth` field and throws when no `auth` exists.
|
|
67
66
|
*/
|
|
68
67
|
export type ToolContext = SessionContext & {
|
|
69
|
-
/**
|
|
70
|
-
* Resolves the bearer token for this tool's declared `auth`,
|
|
71
|
-
* consulting the per-step token cache before invoking the authored
|
|
72
|
-
* `getToken`. For interactive strategies a cache miss throws
|
|
73
|
-
* `ConnectionAuthorizationRequiredError`; the runtime catches it,
|
|
74
|
-
* suspends the turn on a framework-owned callback URL, shows a
|
|
75
|
-
* "Sign in" affordance, and re-runs the tool after the OAuth
|
|
76
|
-
* callback completes.
|
|
77
|
-
*
|
|
78
|
-
* Throws when the tool does not declare an `auth` strategy.
|
|
79
|
-
*
|
|
80
|
-
* @deprecated Prefer `ctx.getToken(provider)` so auth dependencies live at
|
|
81
|
-
* the call site and compose when a tool needs multiple credentials.
|
|
82
|
-
*/
|
|
83
|
-
getToken(): Promise<TokenResult>;
|
|
84
68
|
/**
|
|
85
69
|
* Resolves the bearer token for an inline provider. This accepts the same
|
|
86
70
|
* auth shapes as a connection's `auth` field, including `connect("...")`
|
|
87
71
|
* from `@vercel/connect/eve`.
|
|
88
72
|
*/
|
|
89
73
|
getToken(provider: ToolAuthProvider, options?: ToolAuthOptions): Promise<TokenResult>;
|
|
90
|
-
/**
|
|
91
|
-
* Signals that the caller must complete this tool's authorization flow.
|
|
92
|
-
* Throws `ConnectionAuthorizationRequiredError`, which the runtime converts
|
|
93
|
-
* into a consent prompt (for interactive strategies) and re-runs the tool
|
|
94
|
-
* after sign-in. Use it after a downstream request rejects a token returned
|
|
95
|
-
* by the deprecated no-argument {@link getToken}.
|
|
96
|
-
*
|
|
97
|
-
* @deprecated Prefer `ctx.requireAuth(provider)` so auth dependencies live at
|
|
98
|
-
* the call site and compose when a tool needs multiple credentials.
|
|
99
|
-
*/
|
|
100
|
-
requireAuth(): never;
|
|
101
74
|
/**
|
|
102
75
|
* Signals that the caller must complete authorization for an inline
|
|
103
76
|
* provider before proceeding. Use this after a downstream `401` rejects a
|
|
@@ -114,16 +87,6 @@ export type ToolContext = SessionContext & {
|
|
|
114
87
|
*/
|
|
115
88
|
export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefinition<TInput, TOutput> & {
|
|
116
89
|
execute(input: TInput, ctx: ToolContext): Promise<TOutput> | TOutput;
|
|
117
|
-
/**
|
|
118
|
-
* Optional authorization strategy used by the deprecated no-argument
|
|
119
|
-
* {@link ToolContext.getToken} / {@link ToolContext.requireAuth} accessors.
|
|
120
|
-
*
|
|
121
|
-
* @deprecated Prefer passing a provider at the call site:
|
|
122
|
-
* `ctx.getToken(connect("..."))` or `ctx.requireAuth(connect("..."))`.
|
|
123
|
-
* Inline providers use the same auth shapes and compose when a tool needs
|
|
124
|
-
* multiple credentials.
|
|
125
|
-
*/
|
|
126
|
-
auth?: ToolAuthDefinition;
|
|
127
90
|
/**
|
|
128
91
|
* Optional per-tool approval gate. The return value determines whether
|
|
129
92
|
* user approval is required before executing this tool.
|
|
@@ -160,8 +123,6 @@ export declare function defineTool<TInputSchema extends StandardJSONSchemaV1<unk
|
|
|
160
123
|
execute(input: StandardJSONSchemaV1.InferOutput<TInputSchema>, ctx: ToolContext): Promise<StandardJSONSchemaV1.InferOutput<TOutputSchema>> | StandardJSONSchemaV1.InferOutput<TOutputSchema>;
|
|
161
124
|
needsApproval?: ToolDefinition<StandardJSONSchemaV1.InferOutput<TInputSchema>, unknown>["needsApproval"];
|
|
162
125
|
toModelOutput?: ToolDefinition<unknown, StandardJSONSchemaV1.InferOutput<TOutputSchema>>["toModelOutput"];
|
|
163
|
-
/** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
|
|
164
|
-
auth?: ToolAuthDefinition;
|
|
165
126
|
}): ToolDefinition<StandardJSONSchemaV1.InferOutput<TInputSchema>, StandardJSONSchemaV1.InferOutput<TOutputSchema>>;
|
|
166
127
|
export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown, unknown>, TOutput>(definition: {
|
|
167
128
|
description: ToolDefinition<unknown, unknown>["description"];
|
|
@@ -170,8 +131,6 @@ export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown,
|
|
|
170
131
|
execute(input: StandardJSONSchemaV1.InferOutput<TSchema>, ctx: ToolContext): Promise<TOutput> | TOutput;
|
|
171
132
|
needsApproval?: ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, unknown>["needsApproval"];
|
|
172
133
|
toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
|
|
173
|
-
/** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
|
|
174
|
-
auth?: ToolAuthDefinition;
|
|
175
134
|
}): ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, TOutput>;
|
|
176
135
|
export declare function defineTool<TOutputSchema extends StandardJSONSchemaV1<unknown, unknown>>(definition: {
|
|
177
136
|
description: ToolDefinition<unknown, unknown>["description"];
|
|
@@ -180,8 +139,6 @@ export declare function defineTool<TOutputSchema extends StandardJSONSchemaV1<un
|
|
|
180
139
|
execute(input: Record<string, unknown>, ctx: ToolContext): Promise<StandardJSONSchemaV1.InferOutput<TOutputSchema>> | StandardJSONSchemaV1.InferOutput<TOutputSchema>;
|
|
181
140
|
needsApproval?: ToolDefinition<Record<string, unknown>, unknown>["needsApproval"];
|
|
182
141
|
toModelOutput?: ToolDefinition<unknown, StandardJSONSchemaV1.InferOutput<TOutputSchema>>["toModelOutput"];
|
|
183
|
-
/** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
|
|
184
|
-
auth?: ToolAuthDefinition;
|
|
185
142
|
}): ToolDefinition<Record<string, unknown>, StandardJSONSchemaV1.InferOutput<TOutputSchema>>;
|
|
186
143
|
export declare function defineTool<TOutput>(definition: {
|
|
187
144
|
description: ToolDefinition<unknown, unknown>["description"];
|
|
@@ -190,8 +147,6 @@ export declare function defineTool<TOutput>(definition: {
|
|
|
190
147
|
execute(input: Record<string, unknown>, ctx: ToolContext): Promise<TOutput> | TOutput;
|
|
191
148
|
needsApproval?: ToolDefinition<Record<string, unknown>, unknown>["needsApproval"];
|
|
192
149
|
toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
|
|
193
|
-
/** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
|
|
194
|
-
auth?: ToolAuthDefinition;
|
|
195
150
|
}): ToolDefinition<Record<string, unknown>, TOutput>;
|
|
196
151
|
export declare function defineTool<TInput = unknown, TOutput = unknown>(definition: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
|
|
197
152
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{
|
|
1
|
+
import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){if(e.auth!==void 0)throw Error(`defineTool: The "auth" field is no longer supported. Pass auth providers inline to ctx.getToken(provider) or ctx.requireAuth(provider).`);return Object.assign(e,{[TOOL_BRAND]:!0}),stampDefinitionKey(e,`tool:${e.description}`),e}function defineDynamic(t){let n={kind:DYNAMIC_SENTINEL_KIND,events:t.events};return stampDefinitionKey(n,`dynamic:${Object.keys(t.events).join(`,`)}`),n}const DISABLED_TOOL_SENTINEL_KIND=`eve:disabled-tool`;function disableTool(){return{kind:DISABLED_TOOL_SENTINEL_KIND}}function isDisabledToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_TOOL_SENTINEL_KIND}const ENABLE_WORKFLOW_TOOL_SENTINEL_KIND=`eve:enable-workflow-tool`,ExperimentalWorkflow=Object.freeze({kind:ENABLE_WORKFLOW_TOOL_SENTINEL_KIND});function isEnableWorkflowToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===ENABLE_WORKFLOW_TOOL_SENTINEL_KIND}export{ExperimentalWorkflow,defineDynamic,defineTool,disableTool,isDisabledToolSentinel,isEnableWorkflowToolSentinel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{
|
|
1
|
+
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(i,a,o){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`tool`,moduleMap:a,nodeId:o}),describe(i,`to return an object`)),r={kind:`tool`,logicalPath:i.logicalPath,name:i.name},s=`tool-source:${i.sourceId}`;stampDefinitionKey(n,s),registerDefinitionSource(s,r),registerDefinitionSource(`tool:${n.description}`,r);let c=expectFunction(n.execute,describe(i,`to provide an execute function`));return{description:i.description,execute:c,exportName:i.exportName,inputSchema:i.inputSchema,logicalPath:i.logicalPath,name:i.name,outputSchema:i.outputSchema,sourceId:i.sourceId,sourceKind:`module`,...extractOptionalHooks(n,i)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.needsApproval!==void 0&&(r.needsApproval=expectFunction(t.needsApproval,describe(n,`to provide a needsApproval function`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),t.inputSchema!==void 0&&isFlexibleSchema(t.inputSchema)&&(r.inputStandardSchema=t.inputSchema),t.outputSchema!==void 0&&isFlexibleSchema(t.outputSchema)&&(r.outputStandardSchema=t.outputSchema),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function isFlexibleSchema(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}export{resolveToolDefinition};
|
|
@@ -154,16 +154,6 @@ export type ResolvedToolDefinition = Readonly<Optional<InternalToolDefinitionWit
|
|
|
154
154
|
* handlers and the stream. See {@link ToolModelOutput}.
|
|
155
155
|
*/
|
|
156
156
|
readonly toModelOutput?: (output: unknown) => ToolModelOutput | Promise<ToolModelOutput>;
|
|
157
|
-
/**
|
|
158
|
-
* Optional authorization strategy reattached from the authored
|
|
159
|
-
* module at resolve time. Carries live `getToken` /
|
|
160
|
-
* `startAuthorization` / `completeAuthorization` callbacks, so it
|
|
161
|
-
* cannot survive compilation and must be read off the resolved
|
|
162
|
-
* module like {@link execute}. When present, the execution layer
|
|
163
|
-
* builds token accessors onto the tool context and drives the
|
|
164
|
-
* interactive consent flow scoped to this tool's {@link name}.
|
|
165
|
-
*/
|
|
166
|
-
readonly auth?: AuthorizationDefinition;
|
|
167
157
|
};
|
|
168
158
|
/**
|
|
169
159
|
* Runtime-owned authored hook definition resolved from a compiled module
|
|
@@ -2,12 +2,11 @@ import { detectProjectResolution, type ProjectResolution } from "../project-reso
|
|
|
2
2
|
import type { Prompter } from "../prompter.js";
|
|
3
3
|
import { type SetupState } from "../state.js";
|
|
4
4
|
import type { SetupBox } from "../step.js";
|
|
5
|
-
import { linkProject,
|
|
5
|
+
import { linkProject, unresolvedProject } from "../vercel-project.js";
|
|
6
6
|
/** Injected for tests; defaults to the real Vercel project helpers. */
|
|
7
7
|
export interface LinkProjectDeps {
|
|
8
8
|
linkProject: typeof linkProject;
|
|
9
9
|
detectProjectResolution: typeof detectProjectResolution;
|
|
10
|
-
resolveProjectByNameOrId: typeof resolveProjectByNameOrId;
|
|
11
10
|
unresolvedProject: typeof unresolvedProject;
|
|
12
11
|
}
|
|
13
12
|
export interface LinkProjectOptions {
|
|
@@ -16,18 +15,13 @@ export interface LinkProjectOptions {
|
|
|
16
15
|
deps?: LinkProjectDeps;
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* resolve-provisioning box, so `perform` owns all the work.
|
|
18
|
+
* Executes the resolved Vercel project plan after scaffolding, once the project
|
|
19
|
+
* directory exists. Gather prompts for nothing — every decision was made in the
|
|
20
|
+
* resolve-provisioning box.
|
|
23
21
|
*
|
|
24
|
-
* The plan is authoritative
|
|
25
|
-
* a stale or mismatched `.vercel` link can
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* in `state.project`, which every later box reads.
|
|
29
|
-
*
|
|
30
|
-
* Named `linkVercelProject` because the setup island also exports the
|
|
31
|
-
* `linkProject` executor helper this box drives.
|
|
22
|
+
* The plan is authoritative: the box always re-links to the planned project so
|
|
23
|
+
* a stale or mismatched `.vercel` link can't silently win. Re-linking the same
|
|
24
|
+
* identity is idempotent. The resolution read back from the link metadata lands
|
|
25
|
+
* in `state.project`.
|
|
32
26
|
*/
|
|
33
27
|
export declare function linkVercelProject(options: LinkProjectOptions): SetupBox<SetupState, null, ProjectResolution>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{detectProjectResolution,mergeProjectResolution}from"../project-resolution.js";import{requireProjectPath}from"../state.js";import{linkProject,
|
|
1
|
+
import{detectProjectResolution,mergeProjectResolution}from"../project-resolution.js";import{requireProjectPath}from"../state.js";import{linkProject,unresolvedProject}from"../vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function linkVercelProject(a){let o=a.deps??{linkProject,detectProjectResolution,unresolvedProject};return{id:`link-project`,shouldRun(e){return e.vercelProject.kind!==`none`},async gather(){return null},async perform({state:e,signal:t}){let r=e.vercelProject;if(r.kind===`none`)return o.unresolvedProject();let i=requireProjectPath(e),s=createPromptCommandOutput(a.prompter.log),c=await o.linkProject(a.prompter,i,r,s,{signal:t});if(t?.throwIfAborted(),!c)throw Error("Vercel project provisioning did not complete. Run `vercel link` manually, or re-run and choose not to deploy to Vercel.");let l=await o.detectProjectResolution(i,{signal:t});if(l.kind===`unresolved`)throw Error(`Linked the directory, but could not resolve the Vercel project from its link metadata.`);if(l.projectId!==c.projectId)throw Error(`The linked project does not match the selected project: expected ${c.projectId}, found ${l.projectId}.`);return l},apply(e,n){return{...e,project:mergeProjectResolution(e.project,n)}}}}export{linkVercelProject};
|
|
@@ -4,7 +4,7 @@ import { detectProjectResolution, type ProjectResolution } from "../project-reso
|
|
|
4
4
|
import type { Prompter } from "../prompter.js";
|
|
5
5
|
import type { ProvisioningMode, ResolvedAiGateway, ResolvedVercelProject, SetupState, WiringMode } from "../state.js";
|
|
6
6
|
import type { SetupBox } from "../step.js";
|
|
7
|
-
import { assertNewProjectNameAvailable, isVercelAuthenticated, pickNewProjectName, pickProject, pickTeam, requireAuth, resolveTeam, validateTeam } from "../vercel-project.js";
|
|
7
|
+
import { assertNewProjectNameAvailable, isVercelAuthenticated, pickNewProjectName, pickProject, pickTeam, requireAuth, resolveProjectByNameOrId, resolveTeam, validateTeam } from "../vercel-project.js";
|
|
8
8
|
/** Injected for tests; defaults to the real Vercel project and fs helpers. */
|
|
9
9
|
export interface ResolveProvisioningDeps {
|
|
10
10
|
requireAuth: typeof requireAuth;
|
|
@@ -17,6 +17,7 @@ export interface ResolveProvisioningDeps {
|
|
|
17
17
|
pickProject: typeof pickProject;
|
|
18
18
|
pickNewProjectName: typeof pickNewProjectName;
|
|
19
19
|
assertNewProjectNameAvailable: typeof assertNewProjectNameAvailable;
|
|
20
|
+
resolveProjectByNameOrId: typeof resolveProjectByNameOrId;
|
|
20
21
|
}
|
|
21
22
|
export interface ResolveProvisioningOptions {
|
|
22
23
|
/** Resolves the provisioning-tree questions; the composed stack decides how. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{select,text}from"../ask.js";import{detectProjectResolution,isProjectResolved,mergeProjectResolution}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{assertNewProjectNameAvailable,isVercelAuthenticated,pickNewProjectName,pickProject,pickTeam,requireAuth,resolveTeam,validateTeam}from"../vercel-project.js";import{pathExists}from"../path-exists.js";import{join,resolve}from"node:path";import{byokProviderEnvVar}from"#setup/scaffold/index.js";import{whimsyFor}from"#setup/cli/index.js";function vercelDemands(e){return{slack:e.channelSelection.includes(`slack`),connectSlugs:e.connectionSelection.filter(e=>e.entry.auth?.kind===`connect`).map(e=>e.slug)}}function connectClause(e){let t=e.length===1?`authenticates`:`authenticate`;return`${e.join(`, `)} ${t} through Vercel Connect`}function vercelRequirements(e){let t=[];return e.slack&&t.push(`Slack needs a public URL`),e.connectSlugs.length>0&&t.push(connectClause(e.connectSlugs)),t}function resolveProvisioning(l){let u=l.deps??{requireAuth,isVercelAuthenticated,detectProjectResolution,pathExists,validateTeam,resolveTeam,pickTeam,pickProject,pickNewProjectName,assertNewProjectNameAvailable},parent=()=>resolve(l.targetDirectory??process.cwd());async function detectAdoptableLink(e,t){if(e.projectPath.kind!==`resolved`)return;let n=e.projectPath.path;if(await u.pathExists(join(n,`.vercel`,`project.json`)))return withSpinner(l.prompter,whimsyFor(`project-detect`),async()=>{let e=await u.detectProjectResolution(n,{signal:t});if(!(!isProjectResolved(e)||!await u.isVercelAuthenticated(n,{signal:t})))return e})}async function plansFromFlags(e,t,n,r){if(t.skipVercel)return n.apiKey===void 0?{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:n.apiKey},modelWiring:`gateway`};if(t.team===void 0||t.team.length===0)throw Error(`Headless Vercel provisioning requires --team <slug> or --scope <slug> so the current CLI scope is not applied silently.`);await u.requireAuth(parent(),void 0,{signal:r}),await u.validateTeam(l.prompter,parent(),t.team,{signal:r});let i=await u.resolveTeam(parent(),t.team,{signal:r}),a=n.apiKey===void 0?{kind:`inherit`}:{kind:`byok`,apiGatewayKey:n.apiKey},o
|
|
1
|
+
import{select,text}from"../ask.js";import{detectProjectResolution,isProjectResolved,mergeProjectResolution}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{assertNewProjectNameAvailable,isVercelAuthenticated,pickNewProjectName,pickProject,pickTeam,requireAuth,resolveProjectByNameOrId,resolveTeam,validateTeam}from"../vercel-project.js";import{pathExists}from"../path-exists.js";import{join,resolve}from"node:path";import{byokProviderEnvVar}from"#setup/scaffold/index.js";import{whimsyFor}from"#setup/cli/index.js";function vercelDemands(e){return{slack:e.channelSelection.includes(`slack`),connectSlugs:e.connectionSelection.filter(e=>e.entry.auth?.kind===`connect`).map(e=>e.slug)}}function connectClause(e){let t=e.length===1?`authenticates`:`authenticate`;return`${e.join(`, `)} ${t} through Vercel Connect`}function vercelRequirements(e){let t=[];return e.slack&&t.push(`Slack needs a public URL`),e.connectSlugs.length>0&&t.push(connectClause(e.connectSlugs)),t}function resolveProvisioning(l){let u=l.deps??{requireAuth,isVercelAuthenticated,detectProjectResolution,pathExists,validateTeam,resolveTeam,pickTeam,pickProject,pickNewProjectName,assertNewProjectNameAvailable,resolveProjectByNameOrId},parent=()=>resolve(l.targetDirectory??process.cwd());async function detectAdoptableLink(e,t){if(e.projectPath.kind!==`resolved`)return;let n=e.projectPath.path;if(await u.pathExists(join(n,`.vercel`,`project.json`)))return withSpinner(l.prompter,whimsyFor(`project-detect`),async()=>{let e=await u.detectProjectResolution(n,{signal:t});if(!(!isProjectResolved(e)||!await u.isVercelAuthenticated(n,{signal:t})))return e})}async function plansFromFlags(e,t,n,r){if(t.skipVercel)return n.apiKey===void 0?{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:n.apiKey},modelWiring:`gateway`};if(t.team===void 0||t.team.length===0)throw Error(`Headless Vercel provisioning requires --team <slug> or --scope <slug> so the current CLI scope is not applied silently.`);await u.requireAuth(parent(),void 0,{signal:r}),await u.validateTeam(l.prompter,parent(),t.team,{signal:r});let i=await u.resolveTeam(parent(),t.team,{signal:r}),a=n.apiKey===void 0?{kind:`inherit`}:{kind:`byok`,apiGatewayKey:n.apiKey},o;if(t.project===void 0)o={kind:`new`,project:e,team:i};else{let e=await u.resolveProjectByNameOrId(parent(),i,t.project,{signal:r});if(e===null)throw Error(`Vercel project "${t.project}" was not found in ${i}.`);o={kind:`existing`,project:e,team:i}}return o.kind===`new`&&await u.assertNewProjectNameAvailable(parent(),i,o.project,{signal:r}),{vercelProject:o,aiGateway:a,modelWiring:`gateway`}}async function promptPlans(n,r){let i=l.prompter,a=n.agentName,o=l.adoptExistingLink===!1?void 0:await detectAdoptableLink(n,r);if(o!==void 0)return i.log.info(`This directory is already linked to a Vercel project, so your agent will run there — the AI Gateway authenticates through your Vercel login.`),{vercelProject:{kind:`none`},aiGateway:{kind:`inherit`},modelWiring:`gateway`,project:o};let s=vercelRequirements(vercelDemands(n)),c=!0;if(s.length>0?i.log.info(`${s.join(` and `)}, so your agent will run on Vercel.`):c=await l.asker.ask(select({key:`deploy`,message:`Where should your agent run?`,options:[{id:`vercel`,value:!0,label:`On Vercel`,hint:`AI Gateway, Durable Workflow, Sandbox, and more`},{id:`local`,value:!1,label:`Locally for now`,hint:`run with eve dev, deploy any time later`}],recommended:!0,required:!0})),c){await u.requireAuth(parent(),i,{signal:r});let t=await u.pickTeam(i,parent(),void 0,{signal:r}),n=[{value:`new`,label:`Create a new project`,hint:`Named ${a}`},{value:`link`,label:`Link an existing project`}],o=l.projectSelection!==`existing-only`&&l.prompter.selectEditable?await l.prompter.selectEditable({message:`Vercel project`,options:n,initialValue:`new`,editable:{value:`new`,defaultValue:a,formatHint:e=>`Named ${e}`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}}):void 0;if((l.projectSelection===`existing-only`?`link`:o?.value??await l.asker.ask(select({key:`vercel-project`,message:`Vercel project`,options:[{id:`new`,value:`new`,label:`Create a new project`,hint:`Named ${a}`},{id:`link`,value:`link`,label:`Link an existing project`}],recommended:`new`,required:!0})))===`new`){let e=o?.kind===`edited`?o.text:a;return{vercelProject:{kind:`new`,project:await u.pickNewProjectName(i,parent(),t,e,{signal:r}),team:t},aiGateway:{kind:`inherit`},modelWiring:`gateway`}}return{vercelProject:await u.pickProject(i,parent(),t,{allowCreateWhenEmpty:l.projectSelection!==`existing-only`,signal:r}),aiGateway:{kind:`inherit`},modelWiring:`gateway`}}return await l.asker.ask(select({key:`credential`,message:`How should your agent reach the model?`,options:[{id:`api-key`,value:`api-key`,label:`Use my own AI Gateway API key`,hint:`AI_GATEWAY_API_KEY`},{id:`local`,value:`local`,label:`Use my own provider API key`,hint:byokProviderEnvVar(n.modelId)}],recommended:`api-key`,required:!0}))===`api-key`?{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:await l.asker.ask(text({key:`gateway-api-key`,message:`Enter your AI_GATEWAY_API_KEY`,sensitive:!0,validate:e=>e.trim().length===0?`API key cannot be empty.`:null,required:!0}))},modelWiring:`gateway`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}}return{id:`resolve-provisioning`,async gather({state:e,signal:t}){if(l.mode.headless){let n=await plansFromFlags(e.agentName,l.mode.project,l.mode.aiGateway,t);if(n.vercelProject.kind===`none`){let t=vercelDemands(e);if(t.slack)throw Error(`Slack requires a Vercel project. Remove --skip-vercel to add Slack.`);if(t.connectSlugs.length>0)throw Error(`${connectClause(t.connectSlugs)}, which needs a Vercel project. Remove --skip-vercel to add ${t.connectSlugs.length===1?`it`:`them`}.`)}return n}return promptPlans(e,t)},async perform({input:e}){return e},apply(e,t){return{...e,vercelProject:t.vercelProject,aiGateway:t.aiGateway,modelWiring:t.modelWiring,project:t.project===void 0?e.project:mergeProjectResolution(e.project,t.project)}}}}export{resolveProvisioning};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Prompt } from "@clack/core";
|
|
2
2
|
import { type PromptOption, type PromptValue } from "./prompt-ui.js";
|
|
3
|
-
import { type SelectState } from "./select-state.js";
|
|
3
|
+
import { type SearchActionOption, type SelectState } from "./select-state.js";
|
|
4
4
|
/**
|
|
5
5
|
* A prompt's live status note (e.g. a two-stage quit guard), read on each
|
|
6
6
|
* render. Returns `undefined` when there is nothing to show. Wired in by
|
|
@@ -20,6 +20,7 @@ export declare class SelectComponent extends Prompt<string | string[]> {
|
|
|
20
20
|
readonly options: PromptOption<string>[];
|
|
21
21
|
readonly multiple: boolean;
|
|
22
22
|
readonly search: boolean;
|
|
23
|
+
readonly searchAction: SearchActionOption | undefined;
|
|
23
24
|
readonly required: boolean;
|
|
24
25
|
filter: string;
|
|
25
26
|
optionCursor: number;
|
|
@@ -28,6 +29,7 @@ export declare class SelectComponent extends Prompt<string | string[]> {
|
|
|
28
29
|
options: PromptOption<string>[];
|
|
29
30
|
multiple: boolean;
|
|
30
31
|
search: boolean;
|
|
32
|
+
searchAction?: SearchActionOption;
|
|
31
33
|
required: boolean;
|
|
32
34
|
initial: SelectState;
|
|
33
35
|
render: (this: Omit<SelectComponent, "prompt">) => string | undefined;
|
|
@@ -74,6 +76,10 @@ export declare function runSelectComponent<T extends PromptValue>(input: {
|
|
|
74
76
|
options: readonly PromptOption<T>[];
|
|
75
77
|
multiple: boolean;
|
|
76
78
|
search: boolean;
|
|
79
|
+
searchAction?: {
|
|
80
|
+
label(query: string): string;
|
|
81
|
+
value(query: string): T;
|
|
82
|
+
};
|
|
77
83
|
required: boolean;
|
|
78
84
|
placeholder?: string;
|
|
79
85
|
defaultValue?: 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{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,6 +1,6 @@
|
|
|
1
1
|
import { AI_GATEWAY_API_KEY_ENV_VAR } from "../ai-gateway-api-key.js";
|
|
2
2
|
import { type SelectModelDeps } from "../boxes/select-model.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type VercelProjectOperationOptions } from "../project-resolution.js";
|
|
4
4
|
import type { ModelRouting } from "#shared/agent-definition.js";
|
|
5
5
|
import type { Prompter } from "../prompter.js";
|
|
6
6
|
import { runVercelFlow } from "./vercel.js";
|
|
@@ -79,7 +79,7 @@ export declare const MODEL_MENU_MESSAGE = "";
|
|
|
79
79
|
* and `AI_GATEWAY_API_KEY` outranks `VERCEL_OIDC_TOKEN` because it is the one
|
|
80
80
|
* the provider sub-flow's own-key branch writes.
|
|
81
81
|
*/
|
|
82
|
-
export declare function detectModelProviderStatus(appRoot: string, options?:
|
|
82
|
+
export declare function detectModelProviderStatus(appRoot: string, options?: VercelProjectOperationOptions): Promise<ModelProviderStatus>;
|
|
83
83
|
/**
|
|
84
84
|
* THE MODEL FLOW for the dev TUI's `/model`: a two-row action menu that
|
|
85
85
|
* loops, uniting the model pick and the provider setup behind one entry
|
|
@@ -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};
|