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.
Files changed (72) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/cli/commands/deploy.js +1 -1
  3. package/dist/src/cli/commands/init.js +1 -1
  4. package/dist/src/cli/commands/link.d.ts +2 -2
  5. package/dist/src/cli/commands/link.js +1 -1
  6. package/dist/src/cli/dev/tui/setup-flow.d.ts +5 -0
  7. package/dist/src/cli/dev/tui/setup-panel.d.ts +4 -1
  8. package/dist/src/cli/dev/tui/setup-panel.js +1 -1
  9. package/dist/src/cli/dev/tui/setup-selection-input.d.ts +2 -1
  10. package/dist/src/cli/dev/tui/setup-selection-input.js +2 -2
  11. package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
  12. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  13. package/dist/src/execution/node-step.js +1 -1
  14. package/dist/src/execution/tool-auth.d.ts +16 -39
  15. package/dist/src/execution/tool-auth.js +1 -1
  16. package/dist/src/internal/application/package.js +1 -1
  17. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  18. package/dist/src/public/channels/github/api.d.ts +5 -0
  19. package/dist/src/public/channels/github/api.js +1 -1
  20. package/dist/src/public/channels/github/dispatch.js +1 -1
  21. package/dist/src/public/channels/github/pr-context.d.ts +10 -0
  22. package/dist/src/public/channels/github/pr-context.js +2 -2
  23. package/dist/src/public/definitions/tool.d.ts +3 -48
  24. package/dist/src/public/definitions/tool.js +1 -1
  25. package/dist/src/runtime/resolve-tool.js +1 -1
  26. package/dist/src/runtime/types.d.ts +0 -10
  27. package/dist/src/setup/boxes/link-project.d.ts +8 -14
  28. package/dist/src/setup/boxes/link-project.js +1 -1
  29. package/dist/src/setup/boxes/resolve-provisioning.d.ts +2 -1
  30. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  31. package/dist/src/setup/cli/select-component.d.ts +7 -1
  32. package/dist/src/setup/cli/select-component.js +1 -1
  33. package/dist/src/setup/cli/select-option-codec.d.ts +1 -0
  34. package/dist/src/setup/cli/select-option-codec.js +1 -1
  35. package/dist/src/setup/cli/select-state.d.ts +14 -1
  36. package/dist/src/setup/cli/select-state.js +1 -1
  37. package/dist/src/setup/flows/model.d.ts +2 -2
  38. package/dist/src/setup/index.d.ts +1 -1
  39. package/dist/src/setup/package-manager.d.ts +2 -1
  40. package/dist/src/setup/package-manager.js +1 -1
  41. package/dist/src/setup/primitives/pm/index.d.ts +1 -1
  42. package/dist/src/setup/primitives/pm/pnpm.d.ts +11 -1
  43. package/dist/src/setup/primitives/pm/pnpm.js +5 -2
  44. package/dist/src/setup/primitives/pm/types.d.ts +10 -1
  45. package/dist/src/setup/project-resolution.d.ts +9 -6
  46. package/dist/src/setup/project-resolution.js +1 -1
  47. package/dist/src/setup/prompter.d.ts +13 -0
  48. package/dist/src/setup/prompter.js +1 -1
  49. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  50. package/dist/src/setup/scaffold/create/project.d.ts +8 -0
  51. package/dist/src/setup/scaffold/create/project.js +8 -7
  52. package/dist/src/setup/scaffold/update/channels.d.ts +8 -0
  53. package/dist/src/setup/scaffold/update/channels.js +2 -2
  54. package/dist/src/setup/scaffold/update/package-json.d.ts +3 -0
  55. package/dist/src/setup/scaffold/update/package-json.js +1 -1
  56. package/dist/src/setup/scaffold/workspace-glob.d.ts +5 -0
  57. package/dist/src/setup/scaffold/workspace-glob.js +1 -0
  58. package/dist/src/setup/scaffold/workspace-root.d.ts +29 -0
  59. package/dist/src/setup/scaffold/workspace-root.js +1 -0
  60. package/dist/src/setup/state.d.ts +7 -2
  61. package/dist/src/setup/vercel-api-failure.d.ts +9 -0
  62. package/dist/src/setup/vercel-api-failure.js +1 -0
  63. package/dist/src/setup/vercel-deployment.js +1 -1
  64. package/dist/src/setup/vercel-project-api.d.ts +25 -0
  65. package/dist/src/setup/vercel-project-api.js +1 -0
  66. package/dist/src/setup/vercel-project.d.ts +9 -51
  67. package/dist/src/setup/vercel-project.js +1 -1
  68. package/docs/guides/auth-and-route-protection.md +2 -4
  69. package/docs/guides/dev-tui.md +1 -1
  70. package/docs/reference/cli.md +1 -1
  71. package/docs/reference/typescript-api.md +0 -2
  72. 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(n){if(n.pullRequestNumber===null)return;let i=renderPullRequestMetadata(await getGitHubPullRequest({api:n.api,credentials:n.credentials,installationId:n.installationId,owner:n.owner,pullRequestNumber:n.pullRequestNumber,repo:n.repo})),a=await listGitHubPullRequestFiles({api:n.api,credentials:n.credentials,installationId:n.installationId,owner:n.owner,perPage:50,pullRequestNumber:n.pullRequestNumber,repo:n.repo}),o=[...GITHUB_DEFAULT_EXCLUDED_DIFF_FILES,...n.config?.excludedFiles??[]];return i.push(``,...renderPullRequestFiles(a,o)),[[`GitHub pull request context for the current turn. `,`Use this as background for the user's GitHub comment.`,``,i.join(`
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 r=[`<github_pull_request_files>`],i=MAX_PATCH_BYTES,a=!1;for(let n of e){if(r.push(renderFileSummary(n)),fileMatchesAnyGlob(n.filename,t)){r.push(` patch omitted (excluded)`);continue}if(n.patch===void 0)continue;if(i<=0){a=!0;continue}let e=truncateByBytes(n.patch,i);r.push(`patch:`,indent(e.text)),i-=e.bytes,e.truncated&&(a=!0,i=0)}return a&&r.push(``,`patches_truncated: true`,`max_patch_bytes: ${MAX_PATCH_BYTES}`),r.push(`</github_pull_request_files>`),r}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(`
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 strategy declared on a {@link ToolDefinition} via the
25
- * `auth` field. Accepts the same shapes as a connection's `auth`:
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{normalizeAuthorizationSpec}from"#runtime/connections/validate-authorization.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){return e.auth!==void 0&&(e.auth=normalizeAuthorizationSpec(e.auth,`defineTool:`)),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
+ 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{normalizeAuthorizationSpec}from"#runtime/connections/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(r,a,o){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:r,kindLabel:`tool`,moduleMap:a,nodeId:o}),describe(r,`to return an object`)),i={kind:`tool`,logicalPath:r.logicalPath,name:r.name},s=`tool-source:${r.sourceId}`;stampDefinitionKey(n,s),registerDefinitionSource(s,i),registerDefinitionSource(`tool:${n.description}`,i);let c=expectFunction(n.execute,describe(r,`to provide an execute function`));return{description:r.description,execute:c,exportName:r.exportName,inputSchema:r.inputSchema,logicalPath:r.logicalPath,name:r.name,outputSchema:r.outputSchema,sourceId:r.sourceId,sourceKind:`module`,...extractOptionalHooks(n,r)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}function extractOptionalHooks(t,n){let i={};return t.needsApproval!==void 0&&(i.needsApproval=expectFunction(t.needsApproval,describe(n,`to provide a needsApproval function`))),t.toModelOutput!==void 0&&(i.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),t.inputSchema!==void 0&&isFlexibleSchema(t.inputSchema)&&(i.inputStandardSchema=t.inputSchema),t.outputSchema!==void 0&&isFlexibleSchema(t.outputSchema)&&(i.outputStandardSchema=t.outputSchema),t.auth!==void 0&&(i.auth=normalizeAuthorizationSpec(t.auth,`${describe(n,`to provide a valid auth object`)}:`)),i}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};
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, resolveProjectByNameOrId, unresolvedProject } from "../vercel-project.js";
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
- * THE PROJECT BOX. Executes the resolved Vercel project plan after scaffolding,
20
- * once the project directory exists (so `vercel link` can write `.vercel/`).
21
- * The gather prompts for nothing: every decision was made up front by the
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. The box always re-links to the planned project so
25
- * a stale or mismatched `.vercel` link can never silently win over the choice
26
- * made up front. `vercel link --project X --yes` is an idempotent rewrite, so
27
- * re-runs stay safe. The resolution read back from `.vercel/project.json` lands
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,resolveProjectByNameOrId,unresolvedProject}from"../vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function linkVercelProject(o){let s=o.deps??{linkProject,detectProjectResolution,resolveProjectByNameOrId,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 s.unresolvedProject();let i=requireProjectPath(e),a=createPromptCommandOutput(o.prompter.log),c=await s.linkProject(o.prompter,i,r,a,{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 s.detectProjectResolution(i,{signal:t});if(l.kind===`unresolved`)throw Error(`Linked the directory, but could not resolve the Vercel project from .vercel/project.json.`);let u=await s.resolveProjectByNameOrId(i,r.team,r.project,{signal:t});if(u===null||l.projectId!==u.id)throw Error(`Linked project identity did not match the planned Vercel project "${r.project}".`);return l},apply(e,n){return{...e,project:mergeProjectResolution(e.project,n)}}}}export{linkVercelProject};
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=t.project===void 0?{kind:`new`,project:e,team:i}:{kind:`existing`,project:t.project,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`}}let s=await u.pickProject(i,parent(),t,{allowCreateWhenEmpty:l.projectSelection!==`existing-only`,signal:r});return{vercelProject:{kind:s.exists?`existing`:`new`,project:s.project,team:t},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
+ 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.`);return Array.isArray(c)?c.map(e=>t.decode(e)):t.decode(c)}export{SelectComponent,runSelectComponent};
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{options:e.map((e,r)=>{if(n.has(e.value))throw Error(`Select option values must be unique; duplicate at index ${r}.`);let i=`option-${r}`;return n.set(e.value,i),t.set(i,e.value),{...e,value:i}}),encode(e){let t=n.get(e);if(t===void 0)throw Error(`Select initial value does not match an option.`);return t},decode(e){let n=t.get(e);if(n===void 0)throw Error(`Select returned an unknown option key: ${e}`);return n}}}export{createSelectOptionCodec};
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 n=t.trim().toLowerCase();return n===``?[...e]:e.filter(e=>e.label.toLowerCase().includes(n)||e.value.toLowerCase().includes(n)||(e.hint?.toLowerCase().includes(n)??!1)||(e.focusHint?.toLowerCase().includes(n)??!1))}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),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),i)}}case`up`:case`down`:{let e=filterOptions(r.options,t.filter),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)[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),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,selectValueAtCursor,submitRowIndex};
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 ProjectDetectionOptions } from "../project-resolution.js";
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?: ProjectDetectionOptions): Promise<ModelProviderStatus>;
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 lockfile, then pnpm.
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 hasAncestorPnpmWorkspace(e){let n=dirname(resolve(e));for(;;){if(existsSync(join(n,`pnpm-workspace.yaml`)))return!0;let e=dirname(n);if(e===n)return!1;n=e}}function pnpmWorkspaceClaimsProject(e,t){let r;try{r=JSON.parse(e)}catch{return}if(!Array.isArray(r)||r.length===0)return;let canonicalPath=e=>{let t=resolve(e);try{return realpathSync.native(t)}catch{return t}},i=canonicalPath(t),a=!1;for(let e of r){if(typeof e!=`object`||!e)continue;let t=e.path;if(typeof t==`string`&&(a=!0,canonicalPath(t)===i))return!0}return a?!1:void 0}const pnpmPackageManager={kind:`pnpm`,scaffoldFiles:{[PNPM_WORKSPACE_PATH]:PNPM_WORKSPACE_CONTENT},async applyProjectConfiguration(e){let t=join(e,PNPM_WORKSPACE_PATH);return await ensurePnpmWorkspacePolicy(t)===`written`?{filesSkipped:[],filesWritten:[t]}:{filesSkipped:[t],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 n=process.env.npm_execpath;if(n!==void 0&&n.toLowerCase().includes(`pnpm`)){let t=extname(n).toLowerCase();return t===`.cjs`||t===`.js`?{args:[n,...e],command:process.execPath}:{args:e,command:n,shell:process.platform===`win32`}}if(process.env.npm_config_user_agent?.toLowerCase().startsWith(`pnpm/`))return{args:e,command:`pnpm`,shell:process.platform===`win32`};let r=process.env.PNPM_HOME;if(r!==void 0){let n=join(r,process.platform===`win32`?`pnpm.CMD`:`pnpm`);if(existsSync(n))return{args:e,command:n,shell:process.platform===`win32`}}return{args:e,command:`pnpm`}}};export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,PNPM_WORKSPACE_PATH,hasAncestorPnpmWorkspace,pnpmPackageManager,pnpmWorkspaceClaimsProject};
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};