eve 0.66.0 → 0.66.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/src/channel/forwarded-principal.d.ts +26 -6
- package/dist/src/channel/forwarded-principal.js +1 -1
- package/dist/src/chunks/{use-eve-agent-BUeSjwIk.js → use-eve-agent-Di1u2zKu.js} +24 -4
- package/dist/src/chunks/{use-eve-agent-ydPlURM4.js → use-eve-agent-PbSMyJ6e.js} +24 -4
- package/dist/src/cli/commands/deploy.d.ts +3 -1
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/extension-build.js +1 -1
- package/dist/src/cli/commands/integration-connect.js +1 -1
- package/dist/src/cli/commands/register-project-commands.js +1 -1
- package/dist/src/cli/commands/registry-project.d.ts +2 -1
- package/dist/src/cli/commands/registry-project.js +2 -2
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/trace-detail.d.ts +5 -25
- package/dist/src/cli/commands/trace-detail.js +1 -1
- package/dist/src/cli/commands/trace.js +2 -2
- package/dist/src/cli/commands/vercel-non-interactive.d.ts +7 -0
- package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
- package/dist/src/cli/dev/run-interactive-ui.js +1 -1
- package/dist/src/cli/dev/tui/argument-typeahead.d.ts +1 -1
- package/dist/src/cli/dev/tui/argument-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/registry-result-message.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +2 -2
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +3 -1
- package/dist/src/cli/dev/tui/setup-commands.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -0
- package/dist/src/cli/dev/tui/setup-panel.js +4 -4
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +2 -10
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +2 -2
- package/dist/src/cli/dev/tui/terminal-renderer.js +10 -10
- package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/open-stream.d.ts +3 -2
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.d.ts +16 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/discover/filesystem.d.ts +2 -0
- package/dist/src/discover/filesystem.js +1 -1
- package/dist/src/discover/grammar.d.ts +4 -2
- package/dist/src/discover/grammar.js +1 -1
- package/dist/src/discover/sandbox.js +1 -1
- package/dist/src/evals/session.d.ts +3 -2
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +8 -2
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/types.d.ts +12 -4
- package/dist/src/execution/cancel-indexed-session-tasks-step.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/route-child-delivery.js +2 -2
- package/dist/src/execution/session/admission.js +1 -1
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/input-queue.d.ts +12 -10
- package/dist/src/execution/session/input-queue.js +1 -1
- package/dist/src/execution/session/next-input.js +1 -1
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step-result.d.ts +3 -1
- package/dist/src/execution/session/turn-step-result.js +1 -1
- package/dist/src/execution/session/turn-step-types.d.ts +7 -2
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/parent/control-shared.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch.js +1 -1
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.d.ts +1 -0
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/ask-question-workflow.js +1 -1
- package/dist/src/execution/tools/sleep-workflow.js +1 -1
- package/dist/src/execution/tools/subagent/accept-event-step.js +1 -1
- package/dist/src/execution/tools/subagent/invoke-preparation.js +1 -1
- package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
- package/dist/src/execution/tools/subagent/task-cancel.d.ts +1 -1
- package/dist/src/execution/tools/subagent/task-cancel.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/turn-tag-state.d.ts +2 -2
- package/dist/src/harness/workflow-tool-runs.d.ts +33 -5
- package/dist/src/harness/workflow-tool-runs.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/instrumentation-layout.js +1 -1
- package/dist/src/internal/model-auth/vercel-cli.d.ts +2 -0
- package/dist/src/internal/model-auth/vercel-cli.js +1 -1
- package/dist/src/internal/nitro/host/build-extension.js +1 -1
- package/dist/src/internal/nitro/host/extension-build-lock.d.ts +9 -0
- package/dist/src/internal/nitro/host/extension-build-lock.js +1 -0
- package/dist/src/internal/nitro/host/extension-capability-requirements.d.ts +1 -0
- package/dist/src/internal/nitro/host/extension-capability-requirements.js +1 -1
- package/dist/src/internal/nitro/host/extension-declarations.js +1 -1
- package/dist/src/internal/nitro/host/extension-distribution.js +1 -1
- package/dist/src/internal/nitro/host/extension-state-usage.d.ts +2 -2
- package/dist/src/internal/nitro/host/extension-state-usage.js +1 -1
- package/dist/src/internal/nitro/host/prepare-application-host.d.ts +5 -4
- package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
- package/dist/src/internal/nitro/host/types.d.ts +2 -2
- package/dist/src/internal/nitro/host/workspace-extensions.d.ts +31 -0
- package/dist/src/internal/nitro/host/workspace-extensions.js +1 -0
- package/dist/src/public/next/index.d.ts +10 -7
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +3 -0
- package/dist/src/public/next/server.js +2 -2
- package/dist/src/self-modification/extension/local-only.d.ts +5 -0
- package/dist/src/self-modification/extension/local-only.js +1 -0
- package/dist/src/self-modification/extension/subagents/agent/instructions.js +6 -6
- package/dist/src/self-modification/extension/subagents/agent/skills/trace_analysis.d.ts +10 -0
- package/dist/src/self-modification/extension/subagents/agent/skills/trace_analysis.js +19 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace.d.ts +128 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace.js +1 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace_spans.d.ts +80 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace_spans.js +1 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.js +1 -1
- package/dist/src/self-modification/extension/subagents/agent/tools/search_traces.d.ts +53 -0
- package/dist/src/self-modification/extension/subagents/agent/tools/search_traces.js +1 -0
- package/dist/src/self-modification/extension/trace-inspection.d.ts +15 -0
- package/dist/src/self-modification/extension/trace-inspection.js +1 -0
- package/dist/src/self-modification/sandbox.js +1 -1
- package/dist/src/setup/ask.d.ts +2 -0
- package/dist/src/setup/ask.js +1 -1
- package/dist/src/setup/boxes/link-project.d.ts +2 -0
- package/dist/src/setup/boxes/link-project.js +1 -1
- package/dist/src/setup/cli/option-row.d.ts +3 -1
- package/dist/src/setup/cli/option-row.js +1 -1
- package/dist/src/setup/flows/deploy.d.ts +1 -0
- package/dist/src/setup/flows/deploy.js +1 -1
- package/dist/src/setup/flows/install-vercel-cli.js +1 -1
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model-login-connection.js +1 -1
- package/dist/src/setup/flows/model-login.d.ts +4 -0
- package/dist/src/setup/flows/model-login.js +1 -1
- package/dist/src/setup/flows/vercel-model-login.js +1 -1
- package/dist/src/setup/integrations/runner.js +1 -1
- package/dist/src/setup/integrations/web/setup.d.ts +15 -10
- package/dist/src/setup/integrations/web/setup.js +30 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/create/web-template.d.ts +7 -3
- package/dist/src/setup/scaffold/create/web-template.js +39 -20
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/slackbot.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +2 -0
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/setup/vercel-trace-sampling.d.ts +3 -0
- package/dist/src/setup/vercel-trace-sampling.js +1 -0
- package/dist/src/subagents/parent-notification.d.ts +1 -1
- package/dist/src/subagents/remote-dispatch.d.ts +1 -0
- package/dist/src/subagents/remote-dispatch.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tasks/delivery-context.js +2 -2
- package/dist/src/tasks/notification.d.ts +6 -0
- package/dist/src/tasks/notification.js +1 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -1
- package/dist/src/tracing/local-trace-analysis.d.ts +51 -0
- package/dist/src/tracing/local-trace-analysis.js +1 -0
- package/dist/src/tracing/local-trace-discovery-index.d.ts +15 -0
- package/dist/src/tracing/local-trace-discovery-index.js +1 -0
- package/dist/src/tracing/local-trace-operations.d.ts +13 -0
- package/dist/src/tracing/local-trace-operations.js +1 -0
- package/dist/src/tracing/local-trace-query.d.ts +17 -0
- package/dist/src/tracing/local-trace-query.js +1 -0
- package/dist/src/tracing/local-trace-span-processor.js +1 -1
- package/dist/src/tracing/local-trace-summary.d.ts +31 -0
- package/dist/src/tracing/local-trace-summary.js +1 -0
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/project-structure.mdx +2 -4
- package/docs/concepts/sessions-runs-and-streaming.md +2 -2
- package/docs/evals/cases.mdx +1 -0
- package/docs/extensions.md +3 -1
- package/docs/guides/auth-and-route-protection.md +33 -1
- package/docs/guides/client/streaming.mdx +26 -0
- package/docs/guides/deployment/vercel.mdx +5 -5
- package/docs/guides/frontend/nextjs.mdx +20 -7
- package/docs/guides/frontend/overview.mdx +1 -1
- package/docs/guides/instrumentation/agent-runs.mdx +4 -4
- package/docs/guides/remote-agents.md +3 -1
- package/docs/install-integrations.mdx +1 -1
- package/docs/reference/agent-files.md +16 -0
- package/docs/reference/cli.md +1 -1
- package/docs/subagents/index.mdx +8 -2
- package/package.json +1 -1
- package/dist/src/internal/nitro/host/dev-workspace-extensions.d.ts +0 -18
- package/dist/src/internal/nitro/host/dev-workspace-extensions.js +0 -1
- package/dist/src/tasks/session-task-cohorts.d.ts +0 -7
- package/dist/src/tasks/session-task-cohorts.js +0 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type LocalTraceSummary } from "#tracing/local-trace-summary.js";
|
|
2
|
+
import type { ResolvedSelfModificationConfig } from "../../../../config.js";
|
|
3
|
+
export declare function resolveSearchTracesTool(config: ResolvedSelfModificationConfig): (import("eve/tools").ToolDefinition<Record<string, unknown>, {
|
|
4
|
+
conversationId: string;
|
|
5
|
+
coverage: {
|
|
6
|
+
complete: boolean;
|
|
7
|
+
considered: number;
|
|
8
|
+
matched: number;
|
|
9
|
+
stored: number;
|
|
10
|
+
warning?: string;
|
|
11
|
+
};
|
|
12
|
+
matches: readonly LocalTraceSummary[];
|
|
13
|
+
truncated: boolean;
|
|
14
|
+
}> & {
|
|
15
|
+
execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
|
|
16
|
+
conversationId: string;
|
|
17
|
+
coverage: {
|
|
18
|
+
complete: boolean;
|
|
19
|
+
considered: number;
|
|
20
|
+
matched: number;
|
|
21
|
+
stored: number;
|
|
22
|
+
warning?: string;
|
|
23
|
+
};
|
|
24
|
+
matches: readonly LocalTraceSummary[];
|
|
25
|
+
truncated: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
}) | null;
|
|
28
|
+
declare const _default: import("eve/tools").DynamicSentinel<(import("eve/tools").ToolDefinition<Record<string, unknown>, {
|
|
29
|
+
conversationId: string;
|
|
30
|
+
coverage: {
|
|
31
|
+
complete: boolean;
|
|
32
|
+
considered: number;
|
|
33
|
+
matched: number;
|
|
34
|
+
stored: number;
|
|
35
|
+
warning?: string;
|
|
36
|
+
};
|
|
37
|
+
matches: readonly LocalTraceSummary[];
|
|
38
|
+
truncated: boolean;
|
|
39
|
+
}> & {
|
|
40
|
+
execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
|
|
41
|
+
conversationId: string;
|
|
42
|
+
coverage: {
|
|
43
|
+
complete: boolean;
|
|
44
|
+
considered: number;
|
|
45
|
+
matched: number;
|
|
46
|
+
stored: number;
|
|
47
|
+
warning?: string;
|
|
48
|
+
};
|
|
49
|
+
matches: readonly LocalTraceSummary[];
|
|
50
|
+
truncated: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
}) | null>;
|
|
53
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineLocalOnlyDynamic,resolveLocalOnly}from"../../../local-only.js";import{TRACE_ID,readTraceSources}from"../../../trace-inspection.js";import{summarizeLocalTrace}from"#tracing/local-trace-summary.js";import{resolveConversationId}from"#tracing/conversation-context.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{defineTool}from"eve/tools";import{queryLocalTraceSummaries}from"#tracing/local-trace-query.js";import{localTraceConversationMarker,localTraceIndexedMarker}from"#tracing/local-trace-discovery-index.js";const DEFAULT_SORT_BY=`latest`,searchTracesTool=defineTool({description:`Search summaries for traces in the invoking conversation.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{limit:{type:`integer`,minimum:1,maximum:50,default:50},sortBy:{enum:[`duration`,`failures`,`inputTokens`,`latest`],type:`string`,default:DEFAULT_SORT_BY,description:`Rank examined traces by elapsed time, error-span count, summed step input tokens, or start time. Defaults to latest.`}}},outputSchema:{type:`object`,additionalProperties:!0},async execute(e,t){let n=parseInput(e),r=trace.getSpan(context.active())?.spanContext().traceId,i=resolveConversationId(t.session.parent?.rootSessionId??t.session.id),a=await t.getSandbox(),[o,s,c]=await Promise.all([a.run({command:`ls -1dt /traces/*`}),a.run({command:`ls -1 /traces/*/${localTraceIndexedMarker()}`}),a.run({command:`ls -1 /traces/*/${localTraceConversationMarker(i)}`})]);if(o.exitCode!==0&&!isEmptyTraceListing(o))throw Error(`Could not list local traces: ${o.stderr}`);let l=[...traceIds(o.stdout)],u=l.filter(e=>e!==r),d=traceIds(s.stdout),f=new Set(traceIds(c.stdout)),p=u.filter(e=>!d.has(e)),m=p.slice(0,100),h=new Map,g=0,read=async e=>{try{return await readTraceSources(e,t)}catch(e){if(t.abortSignal.aborted)throw e;g+=1;return}};for(let e of m){if(t.abortSignal.aborted)throw Error(`Trace search was cancelled.`);let n=await read(e);n!==void 0&&contains(n,`gen_ai.conversation.id`,i)&&(f.add(e),h.set(e,summarizeLocalTrace(e,n.map(({span:e})=>e))))}let _=u.filter(e=>f.has(e)),v=_.slice(0,200),y=[];for(let e of v){if(t.abortSignal.aborted)throw Error(`Trace search was cancelled.`);let n=h.get(e);if(n!==void 0){y.push(n);continue}let r=await read(e);r!==void 0&&y.push(summarizeLocalTrace(e,r.map(({span:e})=>e)))}let b=queryLocalTraceSummaries(y,n),x=p.length-m.length+_.length-v.length,S={complete:x===0&&g===0,considered:v.length,matched:_.length,stored:l.length},C=[];return x!==0&&C.push(`Some older traces could not be included.`),g!==0&&C.push(`Some traces could not be read.`),C.length>0&&(S.warning=C.join(` `)),{conversationId:i,coverage:S,matches:b.matches,truncated:b.truncated}}});function parseInput(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Trace search input must be an object.`);let t=e,n=t.limit===void 0?50:t.limit;if(typeof n!=`number`||!Number.isInteger(n)||n<1||n>50)throw Error(`limit must be an integer between 1 and 50.`);if(t.sortBy!==void 0&&t.sortBy!==`latest`&&t.sortBy!==`duration`&&t.sortBy!==`failures`&&t.sortBy!==`inputTokens`)throw Error(`sortBy must be latest, duration, failures, or inputTokens.`);return{limit:n,sortBy:t.sortBy??DEFAULT_SORT_BY}}function traceIds(e){let t=new Set;for(let n of e.split(/\r?\n/u)){let e=n.split(`/`).filter(Boolean).find(e=>TRACE_ID.test(e));e!==void 0&&t.add(e)}return t}function isEmptyTraceListing(e){return e.stdout.trim()===``&&e.stderr.includes(`/traces/*`)&&/no such file or directory/iu.test(e.stderr)}function contains(e,t,n){return e.some(({span:e})=>e.attributes[t]===n)}function resolveSearchTracesTool(e){return resolveLocalOnly(e,searchTracesTool)}var search_traces_default=defineLocalOnlyDynamic(searchTracesTool);export{search_traces_default as default,resolveSearchTracesTool};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolContext } from "eve/tools";
|
|
2
|
+
import { type LocalTraceSpan } from "#tracing/local-trace-reader.js";
|
|
3
|
+
export interface LocalTraceSpanSource {
|
|
4
|
+
readonly segmentFile: string;
|
|
5
|
+
readonly span: LocalTraceSpan;
|
|
6
|
+
}
|
|
7
|
+
export declare const TRACE_ID: RegExp;
|
|
8
|
+
export declare const SPAN_ID: RegExp;
|
|
9
|
+
export declare function readTraceSources(traceId: string, ctx: Pick<ToolContext, "abortSignal" | "getSandbox">): Promise<LocalTraceSpanSource[]>;
|
|
10
|
+
export declare function boundedText(value: string, maximum: number): string;
|
|
11
|
+
export declare function detailFields(source: LocalTraceSpanSource): {
|
|
12
|
+
readonly arguments: unknown;
|
|
13
|
+
readonly error: string | undefined;
|
|
14
|
+
readonly result: unknown;
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseLocalTraceSegment}from"#tracing/local-trace-reader.js";const TRACE_ID=/^[0-9a-f]{32}$/u,SPAN_ID=/^[0-9a-f]{16}$/u,SEGMENT_FILE=/^[0-9a-f]{16}\.otlp\.json$/u;async function readTraceSources(e,t){let n=await t.getSandbox(),r=`/traces/${e}/segments`,i=await n.run({command:`ls -1 ${r}`});if(i.exitCode!==0)throw Error(`Could not list local trace segments: ${i.stderr}`);let a=i.stdout.split(/\r?\n/u).filter(e=>SEGMENT_FILE.test(e)).sort((e,t)=>e.localeCompare(t));if(a.length>500)throw Error(`Trace has ${a.length} segments (maximum 500).`);let o=[];for(let i of a){if(t.abortSignal.aborted)throw Error(`Trace inspection was cancelled.`);let a=await n.readTextFile({path:`${r}/${i}`});if(!(a===null||a.length>8388608))for(let t of parseLocalTraceSegment(a,e))o.push({segmentFile:i,span:t})}return o}function boundedText(e,t){return e.length<=t?e:`${e.slice(0,t-1)}…`}function detailFields(e){return{arguments:e.span.attributes[`gen_ai.tool.call.arguments`],error:e.span.statusMessage,result:e.span.attributes[`gen_ai.tool.call.result`]}}export{SPAN_ID,TRACE_ID,boundedText,detailFields,readTraceSources};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveSelfModificationConfig}from"./config.js";import{createGitHubCredentialProvider}from"./credentials.js";import{
|
|
1
|
+
import{resolveSelfModificationConfig}from"./config.js";import{createGitHubCredentialProvider}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{SELF_MODIFICATION_BASELINE_NETWORK_POLICY}from"./network-policy.js";import{REPOSITORY_PATH,prepareSelfModificationWorkspace}from"./git-workspace.js";import{createSelfModificationFilesystem}from"./filesystem.js";import{bindSandboxEnvironment}from"#shared/sandbox-environment.js";import{shellQuote}from"#shared/shell-quote.js";import{defineSandbox}from"#public/definitions/sandbox.js";import{SANDBOX_PROVIDER_PROBES}from"#sandbox/providers/default.js";import{JustBashSandbox}from"#sandbox/providers/just-bash.js";import{MicrosandboxSandbox}from"#sandbox/providers/microsandbox.js";import{VercelSandbox}from"#sandbox/providers/vercel.js";function defineSelfModificationSandbox(e={}){let t=resolveSelfModificationConfig(e.config),n=resolveSelfModificationMode(t);if(n!==`deployed`){let e=n===`local`?JustBashSandbox.environment({filesystem:createSelfModificationFilesystem}):JustBashSandbox.environment();return bindSandboxEnvironment(defineSandbox(()=>e.open()),e)}let r=selectDeployedSelfModificationEnvironment(SANDBOX_PROVIDER_PROBES);return bindSandboxEnvironment(defineSandbox(async({session:e})=>{let n=await r.open({networkPolicy:SELF_MODIFICATION_BASELINE_NETWORK_POLICY});if(t.deployed===void 0)return n;if(e.parent===void 0)throw Error(`Production self-modification requires a child session.`);if(n.setNetworkPolicy===void 0)throw Error(`Production self-modification requires mutable sandbox network policy.`);let i={...n,setNetworkPolicy:n.setNetworkPolicy},a=t.deployed,o=await createGitHubCredentialProvider(a.credentials).resolve({capability:`checkout`,repository:a.repository});await prepareSelfModificationWorkspace({directory:a.directory,repository:a.repository,sandbox:i,targetBranch:a.targetBranch,token:o});let s=a.directory===`.`?REPOSITORY_PATH:`${REPOSITORY_PATH}/${a.directory}`;if((await n.run({command:`rm -rf /source && ln -s ${shellQuote(`${s}/agent`)} /source`})).exitCode!==0)throw Error(`Self-modification could not mount the agent source.`);return n}),r)}function selectDeployedSelfModificationEnvironment(e){if(e.isDeployedOnVercel())return VercelSandbox.environment();if(e.isMicrosandboxSupported())return MicrosandboxSandbox.environment();throw Error(`Deployed self-modification requires runtime credential transforms. No supported provider is available. Use Vercel Sandbox or microsandbox on a supported self-hosted system.`)}var sandbox_default=defineSelfModificationSandbox();export{sandbox_default as default,defineSelfModificationSandbox,selectDeployedSelfModificationEnvironment};
|
package/dist/src/setup/ask.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ export type Question<T> = {
|
|
|
65
65
|
search?: boolean;
|
|
66
66
|
/** Placeholder for the filter line while it is empty. */
|
|
67
67
|
placeholder?: string;
|
|
68
|
+
/** Render option hints inline or on a separate line in interactive TUI panels. */
|
|
69
|
+
hintLayout?: "stacked" | "inline";
|
|
68
70
|
} | {
|
|
69
71
|
kind: "confirm";
|
|
70
72
|
} | {
|
package/dist/src/setup/ask.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{optionById,optionByValue,requiredOptionId}from"./question-options.js";import{renderEditableQuestion}from"./ask-editable.js";import{InteractionRequired,InvalidAnswerError,SkippedSignal}from"./ask-signals.js";import{SetupPrerequisiteRequired}from"./integrations/shared/prerequisite.js";const select=e=>({...e,kind:`select`}),confirm=e=>({...e,kind:`confirm`});function text(e){return{...e,kind:`text`}}function announce(e,t,n,r){return e?.onResolved?.({key:t,value:n,source:r}),n}function coerceAnswer(e,t){if(e.kind===`select`){let n=String(t),r=optionById(e,n);if(!r){let t=e.options.map(e=>e.id).join(`, `);throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${n}. Expected one of: ${t}.`)}return r.value}if(e.kind===`confirm`){let n=typeof t==`boolean`?t:t===`true`||t!==`false`&&null;if(n===null)throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": expected a boolean.`);return n}let n=String(t),r=e.validate?.(n);if(r)throw new InvalidAnswerError(e,r);return n}function coerceManyAnswer(e,t){if(!Array.isArray(t))throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": expected an array of option ids.`);let n=[];for(let r of t){let t=String(r),i=optionById(e,t);if(!i){let n=e.options.map(e=>e.id).join(`, `);throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${t}. Expected one of: ${n}.`)}if(i.disabled){let n=i.disabledReason===void 0?``:` (${i.disabledReason})`;throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${t} is unavailable${n}.`)}n.includes(i.value)||n.push(i.value)}for(let t of e.options)t.locked===!0&&!n.includes(t.value)&&n.push(t.value);return n}async function renderQuestion(e,t){if(t.kind===`select`){let n=t.detected??t.recommended;return coerceAnswer(t,await e.select({message:t.message,options:t.options.map(e=>({value:e.id,label:e.label,hint:e.hint,featured:e.featured})),initialValue:n===void 0?void 0:requiredOptionId(t,n,t.detected===void 0?`recommendation`:`detected value`),search:t.search,placeholder:t.placeholder}))}if(t.kind===`confirm`){let n=t.detected??t.recommended;return coerceAnswer(t,await e.select({message:t.message,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}],initialValue:n===void 0?void 0:n?`yes`:`no`})===`yes`)}let n=t.validate,r=n===void 0?void 0:e=>n(e)??void 0,i=t.detected??t.recommended;return coerceAnswer(t,t.sensitive?await e.password({message:t.message,validate:r}):await e.text({message:t.message,placeholder:t.placeholder,defaultValue:i===void 0?void 0:String(i),validate:r}))}async function renderManyQuestion(e,t){let n=t.detected??t.recommended;return(await e.select({multiple:!0,message:t.message,options:t.options.map(e=>({value:e.id,label:e.label,hint:e.hint,featured:e.featured,disabled:e.disabled,disabledReason:e.disabledReason,locked:e.locked,lockedReason:e.lockedReason})),initialValues:n===void 0?void 0:n.map(e=>requiredOptionId(t,e,t.detected===void 0?`recommendation`:`detected value`)),required:t.requireSelection,search:t.search,placeholder:t.placeholder})).map(e=>{let n=optionById(t,e);if(!n)throw new InvalidAnswerError(t,`Invalid answer for "${t.key}": ${e} is not an option id.`);return n.value})}function interactiveAsker(e,t){return{async ask(n){let r=await renderQuestion(e,n);return n.internal?r:announce(t,n.key,r,`asked`)},async askEditable(n){let r=await renderEditableQuestion(e,n);return announce(t,n.key,r.value,`asked`),r.text!==void 0&&announce(t,n.editable.key,r.text,`asked`),r},async askMany(n){let r=await renderManyQuestion(e,n);return n.internal?r:announce(t,n.key,r,`asked`)}}}function headlessAsker(e){function refuse(t){throw t.required?new InteractionRequired(t):(announce(e,t.key,void 0,`skipped`),new SkippedSignal(t.key))}return{async ask(e){return refuse(e)},async askEditable(e){return refuse(e)},async askMany(e){return refuse(e)}}}function withAnswers(e,t){return n=>({async ask(r){if(r.key in e){let n=coerceAnswer(r,e[r.key]);return announce(t,r.key,n,`answer`)}if(r.kind===`text`&&r.sensitive===!0){let e=process.env[r.environment];if(e!==void 0)return coerceAnswer(r,e);try{return await n.ask(r)}catch(e){throw e instanceof InteractionRequired?new SetupPrerequisiteRequired({kind:`environment`,code:r.key,message:`Set ${r.environment}, then retry setup.`,variable:r.environment,sensitive:!0}):e}}return n.ask(r)},async askEditable(r){if(!(r.key in e))return n.askEditable(r);let i=coerceAnswer(select({key:r.key,message:r.message,options:r.options}),e[r.key]);if(announce(t,r.key,i,`answer`),i!==r.editable.value)return{value:i};if(!(r.editable.key in e))return{value:i,text:(await n.ask(text({key:r.editable.key,message:optionByValue(r,i)?.label??r.message,recommended:r.editable.recommended,required:r.required,validate:r.editable.validate}))).trim()};let a=String(e[r.editable.key]),o=r.editable.validate?.(a);if(o)throw new InvalidAnswerError(text({key:r.editable.key,message:r.editable.label,required:r.required}),o);let s=a.trim();return announce(t,r.editable.key,s,`answer`),{value:i,text:s}},async askMany(r){if(r.key in e){let n=coerceManyAnswer(r,e[r.key]);return announce(t,r.key,n,`answer`)}return n.askMany(r)}})}function withRequired(e){return t=>({async ask(n){return!n.required&&e.includes(n.key)?t.ask({...n,required:!0}):t.ask(n)},async askEditable(n){return t.askEditable(!n.required&&e.includes(n.key)?{...n,required:!0}:n)},async askMany(n){return!n.required&&e.includes(n.key)?t.askMany({...n,required:!0}):t.askMany(n)}})}function withPolicy(e,t){return n=>({async ask(r){if(e===`assume`){if(r.detected!==void 0)return r.kind===`select`&&requiredOptionId(r,r.detected,`detected value`),announce(t,r.key,r.detected,`detected`);if(r.recommended!==void 0)return r.kind===`select`&&requiredOptionId(r,r.recommended,`recommendation`),announce(t,r.key,r.recommended,`assumed`);if(!r.required)throw announce(t,r.key,void 0,`skipped`),new SkippedSignal(r.key);return n.ask(r)}return r.detected!==void 0&&await n.ask(confirm({key:r.key,message:`Use the detected value for "${r.key}"?`,internal:!0}))?announce(t,r.key,r.detected,`detected`):n.ask(r)},async askEditable(r){if(e!==`assume`||r.recommended===void 0)return n.askEditable(r);requiredOptionId(r,r.editable.value,`configured editable value`),requiredOptionId(r,r.recommended,`recommendation`);let i=r.recommended===r.editable.value?{value:r.recommended,text:r.editable.recommended}:{value:r.recommended};return announce(t,r.key,i.value,`assumed`),i.text!==void 0&&announce(t,r.editable.key,i.text,`assumed`),i},async askMany(r){if(e===`assume`){if(r.detected!==void 0){for(let e of r.detected)requiredOptionId(r,e,`detected value`);return announce(t,r.key,[...r.detected],`detected`)}if(r.recommended!==void 0){for(let e of r.recommended)requiredOptionId(r,e,`recommendation`);return announce(t,r.key,[...r.recommended],`assumed`)}if(!r.required)throw announce(t,r.key,void 0,`skipped`),new SkippedSignal(r.key);return n.askMany(r)}return r.detected!==void 0&&await n.ask(confirm({key:r.key,message:`Use the detected value for "${r.key}"?`,internal:!0}))?announce(t,r.key,[...r.detected],`detected`):n.askMany(r)}})}export{InteractionRequired,InvalidAnswerError,SkippedSignal,confirm,headlessAsker,interactiveAsker,select,text,withAnswers,withPolicy,withRequired};
|
|
1
|
+
import{optionById,optionByValue,requiredOptionId}from"./question-options.js";import{renderEditableQuestion}from"./ask-editable.js";import{InteractionRequired,InvalidAnswerError,SkippedSignal}from"./ask-signals.js";import{SetupPrerequisiteRequired}from"./integrations/shared/prerequisite.js";const select=e=>({...e,kind:`select`}),confirm=e=>({...e,kind:`confirm`});function text(e){return{...e,kind:`text`}}function announce(e,t,n,r){return e?.onResolved?.({key:t,value:n,source:r}),n}function coerceAnswer(e,t){if(e.kind===`select`){let n=String(t),r=optionById(e,n);if(!r){let t=e.options.map(e=>e.id).join(`, `);throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${n}. Expected one of: ${t}.`)}return r.value}if(e.kind===`confirm`){let n=typeof t==`boolean`?t:t===`true`||t!==`false`&&null;if(n===null)throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": expected a boolean.`);return n}let n=String(t),r=e.validate?.(n);if(r)throw new InvalidAnswerError(e,r);return n}function coerceManyAnswer(e,t){if(!Array.isArray(t))throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": expected an array of option ids.`);let n=[];for(let r of t){let t=String(r),i=optionById(e,t);if(!i){let n=e.options.map(e=>e.id).join(`, `);throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${t}. Expected one of: ${n}.`)}if(i.disabled){let n=i.disabledReason===void 0?``:` (${i.disabledReason})`;throw new InvalidAnswerError(e,`Invalid answer for "${e.key}": ${t} is unavailable${n}.`)}n.includes(i.value)||n.push(i.value)}for(let t of e.options)t.locked===!0&&!n.includes(t.value)&&n.push(t.value);return n}async function renderQuestion(e,t){if(t.kind===`select`){let n=t.detected??t.recommended;return coerceAnswer(t,await e.select({message:t.message,options:t.options.map(e=>({value:e.id,label:e.label,hint:e.hint,featured:e.featured})),initialValue:n===void 0?void 0:requiredOptionId(t,n,t.detected===void 0?`recommendation`:`detected value`),search:t.search,placeholder:t.placeholder,hintLayout:t.hintLayout}))}if(t.kind===`confirm`){let n=t.detected??t.recommended;return coerceAnswer(t,await e.select({message:t.message,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}],initialValue:n===void 0?void 0:n?`yes`:`no`})===`yes`)}let n=t.validate,r=n===void 0?void 0:e=>n(e)??void 0,i=t.detected??t.recommended;return coerceAnswer(t,t.sensitive?await e.password({message:t.message,validate:r}):await e.text({message:t.message,placeholder:t.placeholder,defaultValue:i===void 0?void 0:String(i),validate:r}))}async function renderManyQuestion(e,t){let n=t.detected??t.recommended;return(await e.select({multiple:!0,message:t.message,options:t.options.map(e=>({value:e.id,label:e.label,hint:e.hint,featured:e.featured,disabled:e.disabled,disabledReason:e.disabledReason,locked:e.locked,lockedReason:e.lockedReason})),initialValues:n===void 0?void 0:n.map(e=>requiredOptionId(t,e,t.detected===void 0?`recommendation`:`detected value`)),required:t.requireSelection,search:t.search,placeholder:t.placeholder})).map(e=>{let n=optionById(t,e);if(!n)throw new InvalidAnswerError(t,`Invalid answer for "${t.key}": ${e} is not an option id.`);return n.value})}function interactiveAsker(e,t){return{async ask(n){let r=await renderQuestion(e,n);return n.internal?r:announce(t,n.key,r,`asked`)},async askEditable(n){let r=await renderEditableQuestion(e,n);return announce(t,n.key,r.value,`asked`),r.text!==void 0&&announce(t,n.editable.key,r.text,`asked`),r},async askMany(n){let r=await renderManyQuestion(e,n);return n.internal?r:announce(t,n.key,r,`asked`)}}}function headlessAsker(e){function refuse(t){throw t.required?new InteractionRequired(t):(announce(e,t.key,void 0,`skipped`),new SkippedSignal(t.key))}return{async ask(e){return refuse(e)},async askEditable(e){return refuse(e)},async askMany(e){return refuse(e)}}}function withAnswers(e,t){return n=>({async ask(r){if(r.key in e){let n=coerceAnswer(r,e[r.key]);return announce(t,r.key,n,`answer`)}if(r.kind===`text`&&r.sensitive===!0){let e=process.env[r.environment];if(e!==void 0)return coerceAnswer(r,e);try{return await n.ask(r)}catch(e){throw e instanceof InteractionRequired?new SetupPrerequisiteRequired({kind:`environment`,code:r.key,message:`Set ${r.environment}, then retry setup.`,variable:r.environment,sensitive:!0}):e}}return n.ask(r)},async askEditable(r){if(!(r.key in e))return n.askEditable(r);let i=coerceAnswer(select({key:r.key,message:r.message,options:r.options}),e[r.key]);if(announce(t,r.key,i,`answer`),i!==r.editable.value)return{value:i};if(!(r.editable.key in e))return{value:i,text:(await n.ask(text({key:r.editable.key,message:optionByValue(r,i)?.label??r.message,recommended:r.editable.recommended,required:r.required,validate:r.editable.validate}))).trim()};let a=String(e[r.editable.key]),o=r.editable.validate?.(a);if(o)throw new InvalidAnswerError(text({key:r.editable.key,message:r.editable.label,required:r.required}),o);let s=a.trim();return announce(t,r.editable.key,s,`answer`),{value:i,text:s}},async askMany(r){if(r.key in e){let n=coerceManyAnswer(r,e[r.key]);return announce(t,r.key,n,`answer`)}return n.askMany(r)}})}function withRequired(e){return t=>({async ask(n){return!n.required&&e.includes(n.key)?t.ask({...n,required:!0}):t.ask(n)},async askEditable(n){return t.askEditable(!n.required&&e.includes(n.key)?{...n,required:!0}:n)},async askMany(n){return!n.required&&e.includes(n.key)?t.askMany({...n,required:!0}):t.askMany(n)}})}function withPolicy(e,t){return n=>({async ask(r){if(e===`assume`){if(r.detected!==void 0)return r.kind===`select`&&requiredOptionId(r,r.detected,`detected value`),announce(t,r.key,r.detected,`detected`);if(r.recommended!==void 0)return r.kind===`select`&&requiredOptionId(r,r.recommended,`recommendation`),announce(t,r.key,r.recommended,`assumed`);if(!r.required)throw announce(t,r.key,void 0,`skipped`),new SkippedSignal(r.key);return n.ask(r)}return r.detected!==void 0&&await n.ask(confirm({key:r.key,message:`Use the detected value for "${r.key}"?`,internal:!0}))?announce(t,r.key,r.detected,`detected`):n.ask(r)},async askEditable(r){if(e!==`assume`||r.recommended===void 0)return n.askEditable(r);requiredOptionId(r,r.editable.value,`configured editable value`),requiredOptionId(r,r.recommended,`recommendation`);let i=r.recommended===r.editable.value?{value:r.recommended,text:r.editable.recommended}:{value:r.recommended};return announce(t,r.key,i.value,`assumed`),i.text!==void 0&&announce(t,r.editable.key,i.text,`assumed`),i},async askMany(r){if(e===`assume`){if(r.detected!==void 0){for(let e of r.detected)requiredOptionId(r,e,`detected value`);return announce(t,r.key,[...r.detected],`detected`)}if(r.recommended!==void 0){for(let e of r.recommended)requiredOptionId(r,e,`recommendation`);return announce(t,r.key,[...r.recommended],`assumed`)}if(!r.required)throw announce(t,r.key,void 0,`skipped`),new SkippedSignal(r.key);return n.askMany(r)}return r.detected!==void 0&&await n.ask(confirm({key:r.key,message:`Use the detected value for "${r.key}"?`,internal:!0}))?announce(t,r.key,[...r.detected],`detected`):n.askMany(r)}})}export{InteractionRequired,InvalidAnswerError,SkippedSignal,confirm,headlessAsker,interactiveAsker,select,text,withAnswers,withPolicy,withRequired};
|
|
@@ -14,6 +14,8 @@ export interface LinkProjectOptions {
|
|
|
14
14
|
prompter: Prompter;
|
|
15
15
|
/** Headless runs must not ask follow-up questions after the plan is fixed. */
|
|
16
16
|
headless?: boolean;
|
|
17
|
+
/** Configure 100% trace sampling for a newly created project. */
|
|
18
|
+
traceSampling?: boolean;
|
|
17
19
|
deps?: LinkProjectDeps;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
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(e){let t=e.deps??{linkProject,detectProjectResolution,unresolvedProject};return{id:`link-project`,shouldRun(e){return e.vercelProject.kind!==`none`},async gather(){return null},async perform({state:n,signal:r}){let i=n.vercelProject;if(i.kind===`none`)return t.unresolvedProject();let a=requireProjectPath(n),o=createPromptCommandOutput(e.prompter.log),s=await t.linkProject(e.prompter,a,i,o,
|
|
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(e){let t=e.deps??{linkProject,detectProjectResolution,unresolvedProject};return{id:`link-project`,shouldRun(e){return e.vercelProject.kind!==`none`},async gather(){return null},async perform({state:n,signal:r}){let i=n.vercelProject;if(i.kind===`none`)return t.unresolvedProject();let a=requireProjectPath(n),o=createPromptCommandOutput(e.prompter.log),s={signal:r};e.headless&&(s.headless=!0),e.traceSampling!==void 0&&(s.traceSampling=e.traceSampling);let c=await t.linkProject(e.prompter,a,i,o,s);if(r?.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 t.detectProjectResolution(a,{signal:r});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,t){return{...e,project:mergeProjectResolution(e.project,t)}}}}export{linkVercelProject};
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
/** The color primitives the row painter needs; satisfied by both the TUI theme and the CLI palette. */
|
|
14
14
|
export interface RowColors {
|
|
15
15
|
blue(text: string): string;
|
|
16
|
-
bold
|
|
16
|
+
bold(text: string): string;
|
|
17
17
|
dim(text: string): string;
|
|
18
18
|
green(text: string): string;
|
|
19
19
|
inverse(text: string): string;
|
|
@@ -61,6 +61,8 @@ interface OptionRowInput {
|
|
|
61
61
|
state: OptionRowState;
|
|
62
62
|
/** Whether an un-hovered, selectable row draws the placeholder glyph. */
|
|
63
63
|
placeholder: boolean;
|
|
64
|
+
/** TUI lists use type weight rather than a caret to show focus. */
|
|
65
|
+
presentation?: "cursor" | "minimal";
|
|
64
66
|
/** Spaces inserted before the hint's dot so hints tab-align to a shared column. */
|
|
65
67
|
hintPadding?: number;
|
|
66
68
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const UNICODE_ROW_GLYPHS={pointer:`›`,selectedPointer:`›`,success:`✓`,placeholder:` `,dot:`·`,warning:`⚠`};function resolveOptionRowState(e,t){if(Number(e.disabled===!0)+Number(e.completed===!0)+Number(e.locked===!0)>1)throw Error(`An option row cannot combine disabled, completed, or locked states.`);if(e.disabled===!0){let t={kind:`disabled`};return e.disabledReason!==void 0&&(t.reason=e.disabledReason),e.disabledReasonTone!==void 0&&(t.reasonTone=e.disabledReasonTone),t}if(e.completed===!0)return{kind:`completed`};if(e.locked===!0){let t={kind:`locked`};return e.lockedReason!==void 0&&(t.reason=e.lockedReason),t}return{kind:`available`,checked:t}}function parenthetical(e){return e===void 0?``:` (${e})`}function unfocusedGlyph(e){return e.placeholder?e.colors.dim(e.glyphs.placeholder):` `}function disabledLabel(e,t,n,r){if(t.reasonTone===`warning`){let i=t.reason===void 0?``:` ${r.warning} ${t.reason}`;return`${n.dim(e)}${n.yellow(i)}`}let i=parenthetical(t.reason);return n.dim(`${e}${i}`)}function optionRowPresentation(e){let{colors:t,glyphs:n,state:r}=e;switch(r.kind){case`available`:return e.isCursor?{glyph:r.checked?n.success:n.selectedPointer,label:e.label}:{glyph:r.checked?t.green(n.success):unfocusedGlyph(e),label:e.accent===`warning`?t.yellow(e.label):e.label};case`completed`:return{glyph:e.isCursor?t.dim(n.pointer):t.green(n.success),label:t.dim(e.label)};case`disabled`:return{glyph:e.isCursor?t.dim(n.pointer):unfocusedGlyph(e),label:disabledLabel(e.label,r,t,n)};case`locked`:return{glyph:t.dim(t.green(n.success)),label:t.dim(`${e.label}${parenthetical(r.reason)}`)}}return r}function renderCursorRow(e,t,n,r){return t?(r===`warning`?n.yellow:n.bold
|
|
1
|
+
const UNICODE_ROW_GLYPHS={pointer:`›`,selectedPointer:`›`,success:`✓`,placeholder:` `,dot:`·`,warning:`⚠`};function resolveOptionRowState(e,t){if(Number(e.disabled===!0)+Number(e.completed===!0)+Number(e.locked===!0)>1)throw Error(`An option row cannot combine disabled, completed, or locked states.`);if(e.disabled===!0){let t={kind:`disabled`};return e.disabledReason!==void 0&&(t.reason=e.disabledReason),e.disabledReasonTone!==void 0&&(t.reasonTone=e.disabledReasonTone),t}if(e.completed===!0)return{kind:`completed`};if(e.locked===!0){let t={kind:`locked`};return e.lockedReason!==void 0&&(t.reason=e.lockedReason),t}return{kind:`available`,checked:t}}function parenthetical(e){return e===void 0?``:` (${e})`}function unfocusedGlyph(e){return e.placeholder?e.colors.dim(e.glyphs.placeholder):` `}function disabledLabel(e,t,n,r){if(t.reasonTone===`warning`){let i=t.reason===void 0?``:` ${r.warning} ${t.reason}`;return`${n.dim(e)}${n.yellow(i)}`}let i=parenthetical(t.reason);return n.dim(`${e}${i}`)}function optionRowPresentation(e){let{colors:t,glyphs:n,state:r}=e;switch(r.kind){case`available`:return e.isCursor?{glyph:r.checked?n.success:n.selectedPointer,label:e.label}:{glyph:r.checked?t.green(n.success):unfocusedGlyph(e),label:e.accent===`warning`?t.yellow(e.label):e.label};case`completed`:return{glyph:e.isCursor?t.dim(n.pointer):t.green(n.success),label:t.dim(e.label)};case`disabled`:return{glyph:e.isCursor?t.dim(n.pointer):unfocusedGlyph(e),label:disabledLabel(e.label,r,t,n)};case`locked`:return{glyph:t.dim(t.green(n.success)),label:t.dim(`${e.label}${parenthetical(r.reason)}`)}}return r}function renderCursorRow(e,t,n,r){return t?(r===`warning`?n.yellow:n.bold)(` ${e}`):` ${e}`}function renderOptionRowContinuation(e){return` ${e}`}function renderOptionRow(e){let{colors:t,glyphs:n}=e,{glyph:r,label:i}=optionRowPresentation(e),a=e.isCursor&&e.state.kind===`available`,o=e.hint;e.isCursor&&e.focusHint!==void 0&&(o=e.focusHint);let s=``;if(o!==void 0){let r=Math.max(0,(e.hintPadding??0)+1);s=t.dim(`${` `.repeat(r)}${n.dot} ${o}`)}if(e.presentation===`minimal`){let n=e.state.kind===`available`?a?t.bold(i):t.dim(i):i;return` ${e.state.kind===`available`&&!e.state.checked||e.state.kind===`disabled`&&!e.isCursor?` `:r} ${n}${s}`}return`${renderCursorRow(`${r} ${i}`,a,t,e.accent)}${s}`}export{UNICODE_ROW_GLYPHS,renderCursorRow,renderOptionRow,renderOptionRowContinuation,resolveOptionRowState};
|
|
@@ -36,6 +36,7 @@ export declare function runDeployFlow(input: {
|
|
|
36
36
|
appRoot: string;
|
|
37
37
|
prompter: Prompter;
|
|
38
38
|
signal?: AbortSignal;
|
|
39
|
+
traceSampling?: boolean;
|
|
39
40
|
/** False when no TTY: an unlinked directory refuses instead of prompting. */
|
|
40
41
|
interactive: boolean;
|
|
41
42
|
deps?: Partial<DeployFlowDeps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runInstallVercelCliFlow}from"./install-vercel-cli.js";import{runLoginFlow}from"./login.js";import{inspectApplication}from"#services/inspect-application.js";import{isChatGptModelRouting}from"#shared/chatgpt-model.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(e){let{appRoot:t,prompter:n,interactive:r,signal:i}=e,a={detectDeployment,inspectApplication,runLoginFlow,runInstallVercelCliFlow,...e.deps};try{let e=(await a.inspectApplication(t)).compiledState?.manifest.config.model?.routing;if(isChatGptModelRouting(e))return{kind:`local-model`}}catch{}let o=await withSpinner(n,`Checking the current Vercel link...`,async()=>{let e=await a.detectDeployment(t,{signal:i});return i?.throwIfAborted(),projectResolutionFromDeployment(e)}),s=isProjectResolved(o);if(!s&&!r)return{kind:`needs-link`};if(r){let e=await a.runLoginFlow({appRoot:t,prompter:n,signal:i});if(e.kind===`cli-missing`){let r=await a.runInstallVercelCliFlow({appRoot:t,prompter:n,signal:i});if(r.kind===`cancelled`)return{kind:`cancelled`};if(r.kind===`failed`)throw Error("Could not install the Vercel CLI. Install it with `npm i -g vercel@latest`, then retry deployment.");e=await a.runLoginFlow({appRoot:t,prompter:n,signal:i})}if(e.kind===`cancelled`)return{kind:`cancelled`};if(e.kind!==`already`&&e.kind!==`logged-in`)throw Error(e.kind===`unavailable`?`Could not reach Vercel. Check your connection and retry deployment.`:`Vercel login did not complete. Retry deployment to sign in.`)}let c=inProjectSetupState(t,o,{deploymentPending:!0}),l=s?[deployProject({prompter:n,headless:!r,deps:a.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(n)),prompter:n,targetDirectory:t,mode:{headless:!1},deps:a.resolveProvisioning}),linkVercelProject({prompter:n,deps:a.linkProject}),deployProject({prompter:n,headless:!r,deps:a.deployProject})],u=prompterSink(n);if(!r)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(l,c,u,{snapshot:snapshotSetupState,signal:i})).project)};let d=await runInteractive(l,c,u,{snapshot:snapshotSetupState,signal:i});return d.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(d.state.project)}}export{runDeployFlow};
|
|
1
|
+
import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runInstallVercelCliFlow}from"./install-vercel-cli.js";import{runLoginFlow}from"./login.js";import{inspectApplication}from"#services/inspect-application.js";import{isChatGptModelRouting}from"#shared/chatgpt-model.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(e){let{appRoot:t,prompter:n,interactive:r,signal:i}=e,a={detectDeployment,inspectApplication,runLoginFlow,runInstallVercelCliFlow,...e.deps};try{let e=(await a.inspectApplication(t)).compiledState?.manifest.config.model?.routing;if(isChatGptModelRouting(e))return{kind:`local-model`}}catch{}let o=await withSpinner(n,`Checking the current Vercel link...`,async()=>{let e=await a.detectDeployment(t,{signal:i});return i?.throwIfAborted(),projectResolutionFromDeployment(e)}),s=isProjectResolved(o);if(!s&&!r)return{kind:`needs-link`};if(r){let e=await a.runLoginFlow({appRoot:t,prompter:n,signal:i});if(e.kind===`cli-missing`){let r=await a.runInstallVercelCliFlow({appRoot:t,prompter:n,signal:i});if(r.kind===`cancelled`)return{kind:`cancelled`};if(r.kind===`failed`)throw Error("Could not install the Vercel CLI. Install it with `npm i -g vercel@latest`, then retry deployment.");e=await a.runLoginFlow({appRoot:t,prompter:n,signal:i})}if(e.kind===`cancelled`)return{kind:`cancelled`};if(e.kind!==`already`&&e.kind!==`logged-in`)throw Error(e.kind===`unavailable`?`Could not reach Vercel. Check your connection and retry deployment.`:`Vercel login did not complete. Retry deployment to sign in.`)}let c=inProjectSetupState(t,o,{deploymentPending:!0}),l=s?[deployProject({prompter:n,headless:!r,deps:a.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(n)),prompter:n,targetDirectory:t,mode:{headless:!1},deps:a.resolveProvisioning}),linkVercelProject({prompter:n,traceSampling:e.traceSampling,deps:a.linkProject}),deployProject({prompter:n,headless:!r,deps:a.deployProject})],u=prompterSink(n);if(!r)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(l,c,u,{snapshot:snapshotSetupState,signal:i})).project)};let d=await runInteractive(l,c,u,{snapshot:snapshotSetupState,signal:i});return d.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(d.state.project)}}export{runDeployFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withSpinner}from"../with-spinner.js";import{resultSucceeded,runVercel,spawnPackageManager}from"#setup/primitives/index.js";import{
|
|
1
|
+
import{withSpinner}from"../with-spinner.js";import{resultSucceeded,runVercel,spawnPackageManager}from"#setup/primitives/index.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{detectPackageManager}from"#setup/package-manager.js";import{createPromptCommandOutput}from"#setup/cli/index.js";const defaultDeps={getVercelAuthStatus,detectPackageManager,runVercel,spawnPackageManager};function globalInstallArguments(e){switch(e){case`npm`:return[`install`,`-g`,`vercel@latest`];case`yarn`:return[`global`,`add`,`vercel@latest`];case`pnpm`:case`bun`:return[`add`,`-g`,`vercel@latest`]}}function summarizeUpgradeFailure(e){let t=e.map(e=>e.trim().replace(/\s+/gu,` `)).filter(e=>e!==``&&e!==`}`&&!e.startsWith(`at `)&&!/^vercel upgrade exited with code \d+\.$/u.test(e)),n=t.find(e=>/^(?:error\b|err_|.*\b(?:cannot|failed|could not)\b)/iu.test(e))??t.at(-1);if(n!==void 0)return n.length<=240?n:`${n.slice(0,239)}…`}async function runInstallVercelCliFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={...defaultDeps,...e.deps},a=createPromptCommandOutput(n.log),probe=async()=>await i.getVercelAuthStatus(t,{signal:r})!==`cli-missing`;if(!e.upgrade&&await withSpinner(n,`Checking for the Vercel CLI…`,probe))return r?.throwIfAborted(),{kind:`already`};r?.throwIfAborted();let o,s;if(e.upgrade){let e=[];o=await withSpinner(n,`Upgrading the Vercel CLI…`,async()=>{let n=await i.runVercel([`upgrade`],{cwd:t,onOutput:t=>{a(t),t.stream===`stderr`&&e.push(t.text)},signal:r,nonInteractive:!0});return n||(s=summarizeUpgradeFailure(e)),n})}else{let e=await i.detectPackageManager(t);o=await withSpinner(n,`Installing the Vercel CLI with ${e.kind}…`,async()=>resultSucceeded(await i.spawnPackageManager(e.kind,t,globalInstallArguments(e.kind),{onOutput:a,signal:r,nonInteractive:!0})))}if(r?.aborted===!0)return{kind:`cancelled`};if(!o)return s===void 0?{kind:`failed`}:{kind:`failed`,reason:s};let c=await withSpinner(n,`Verifying the Vercel CLI…`,probe);return r?.throwIfAborted(),c?{kind:`installed`}:e.upgrade?{kind:`failed`,reason:`The Vercel CLI could not be found after the upgrade completed.`}:{kind:`failed`}}export{runInstallVercelCliFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withSpinner}from"../with-spinner.js";import{
|
|
1
|
+
import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{runVercel}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function vercelLoginUrl(e){return e.match(/https:\/\/vercel\.com\/oauth\/device\?[^\s]+/u)?.[0]}const defaultDeps={getVercelAuthStatus,runVercelLogin:({cwd:e,onOutput:t,signal:n})=>runVercel([`login`],{cwd:e,nonInteractive:!0,onOutput:t,timeoutMs:3e5,signal:n})};async function runVercelLoginWithControls(e,t,n,r,i){if(r.awaitChoice===void 0)return withSpinner(r,`Opening Vercel login in your browser…`,()=>e.runVercelLogin({cwd:t,onOutput:n,signal:i}));let a=new AbortController,o=i?AbortSignal.any([i,a.signal]):a.signal,s=r.awaitChoice({status:`Logging in to Vercel…`,context:`Complete the login in your browser`,actions:[{value:`cancel`,label:`Cancel`}]}),c=e.runVercelLogin({cwd:t,onOutput:n,signal:o});try{let e=await Promise.race([c.then(e=>({via:`work`,ok:e})),s.choice.then(()=>({via:`choice`}))]);return e.via===`work`?e.ok:(a.abort(),await c.catch(()=>{}),`cancelled`)}finally{s.close()}}async function runLoginFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={...defaultDeps,...e.deps},a=createPromptCommandOutput(n.log),o,onOutput=e=>{a(e);let t=vercelLoginUrl(e.text);t!==void 0&&t!==o&&(o=t,n.log.info(`Open ${t}`))},probeAuth=()=>i.getVercelAuthStatus(t,{signal:r}),s=await withSpinner(n,`Checking your Vercel login…`,probeAuth);switch(r?.throwIfAborted(),s){case`authenticated`:if(e.force!==!0)return{kind:`already`};break;case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};case`logged-out`:break;default:return s}if(e.allowLogin===!1)return{kind:`failed`};let c=await runVercelLoginWithControls(i,t,onOutput,n,r);if(c===`cancelled`)return{kind:`cancelled`};if(!c)return{kind:`failed`};let l=await withSpinner(n,`Confirming your Vercel login…`,probeAuth);switch(r?.throwIfAborted(),l){case`authenticated`:return{kind:`logged-in`};case`logged-out`:return{kind:`failed`};case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};default:return l}}export{runLoginFlow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ensureChatGptAuth}from"./chatgpt-auth.js";import{withLoginProgress}from"./model-login-progress.js";import{loginVercelModel}from"./vercel-model-login.js";import{resolveModelApiKey}from"#internal/model-auth/transport.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{
|
|
1
|
+
import{ensureChatGptAuth}from"./chatgpt-auth.js";import{withLoginProgress}from"./model-login-progress.js";import{loginVercelModel}from"./vercel-model-login.js";import{resolveModelApiKey}from"#internal/model-auth/transport.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{readVercelCliConnection,refreshVercelCliConnection}from"#internal/model-auth/vercel-cli.js";import{availableDirectModels}from"#internal/model-auth/available-models.js";import{modelKeySecretName,readVercelSession,writeModelSecret}from"#internal/model-auth/store.js";import{VERCEL_MODEL_CLIENT_ID,resolveVercelSession,validateVercelAccess}from"#internal/model-auth/vercel.js";import{validateGatewayApiKey}from"#setup/validate-gateway-key.js";const CONNECTION_OPTIONS=[{value:`vercel`,label:`Vercel Account`},{value:`ai-gateway-key`,label:`Vercel AI Gateway API Key`},{value:`chatgpt`,label:`ChatGPT Subscription`},{value:`openai`,label:`OpenAI API Key`},{value:`anthropic`,label:`Anthropic API Key`}];async function reuseModelConnection(e,t,n){switch(e){case`chatgpt`:return(await getDefaultCodexTokenBroker().refreshState()).kind===`ready`?{selected:e}:void 0;case`vercel`:{if(!await readVercelSession(VERCEL_MODEL_CLIENT_ID))return;let r=await resolveVercelSession();return t??={teamId:r.teamId,teamName:r.teamName},await validateVercelAccess(r.accessToken,t.teamId,n),{selected:e,team:t}}case`vercel-cli`:{let r=await readVercelCliConnection();if(!r)return;t??={teamId:r.teamId,teamName:r.teamId};try{await validateVercelAccess(r.token,t.teamId,n)}catch{if(n?.throwIfAborted(),await refreshVercelCliConnection(),r=await readVercelCliConnection(),!r)return;await validateVercelAccess(r.token,t.teamId,n)}return{selected:e,team:t}}case`ai-gateway-project`:return await getVercelOidcToken().catch(()=>void 0)?{selected:e}:void 0;case`ai-gateway-key`:{let t=await resolveModelApiKey(e);return(await validateGatewayApiKey(t,n)).kind===`valid`?{selected:e}:void 0}case`openai`:case`anthropic`:return{selected:e,availableModels:await availableDirectModels(e,await resolveModelApiKey(e),n)}}}async function authenticateModelConnection(e){let{selected:t,prompter:n,signal:r}=e;if(t===`vercel`)return{selected:t,team:await loginVercelModel(n,r,e.team?.teamId)};if(t===`chatgpt`)return await ensureChatGptAuth({signal:r,log:e=>n.log.info(e)}),{selected:t};if(t===`vercel-cli`||t===`ai-gateway-project`)throw Error(`Choose a connection with /login.`);let i=CONNECTION_OPTIONS.find(e=>e.value===t).label,a=(await n.password({message:i,validate:e=>e.trim()?void 0:`Enter an API key.`})).trim(),o=await withLoginProgress(n,`Checking ${i}…`,async()=>{if(t!==`ai-gateway-key`)return availableDirectModels(t,a,r);if((await validateGatewayApiKey(a,r)).kind!==`valid`)throw Error(`Could not validate the Gateway key. Check the key and your connection, then retry.`)});return r?.throwIfAborted(),await writeModelSecret(modelKeySecretName(t),a),{selected:t,availableModels:o}}export{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection};
|
|
@@ -7,6 +7,10 @@ type LoginInput = {
|
|
|
7
7
|
agentRoot?: string;
|
|
8
8
|
prompter: Prompter;
|
|
9
9
|
automatic?: boolean;
|
|
10
|
+
/** Connection selected by the TUI's `/login <connection>` completion. */
|
|
11
|
+
selected?: ModelConnectionSelection;
|
|
12
|
+
/** TUI callers can omit the redundant picker heading beneath `/login`. */
|
|
13
|
+
connectionMessage?: string;
|
|
10
14
|
signal?: AbortSignal;
|
|
11
15
|
/** Applies writes under one watcher lease and waits for runtime activation. */
|
|
12
16
|
withConnectionUpdate?(task: () => Promise<void>): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fetchGatewayCatalog}from"../boxes/select-model.js";import{measureLoginStage,withLoginProgress}from"./model-login-progress.js";import{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection}from"./model-login-connection.js";import{changeValidatedAgentModel,readAuthoredModelSelection}from"./model-source-change.js";import{MODEL_CONNECTION_ENV}from"#internal/model-auth/transport.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{inspectApplication}from"#services/inspect-application.js";import{WizardCancelledError}from"#setup/step.js";import{MODEL_HELPERS,parseModelHelper}from"#shared/model-helper.js";import{providerSettingsMatch,readProviderKeySourceSync,readProviderSelection,readProviderTeamSync,resolveAvailableProviders,writeProviderSelection}from"#setup/provider-settings.js";import{resolveModelEndpointStatus}from"#internal/resolve-model-endpoint-status.js";import{classifyModelRouting}from"#internal/classify-model-routing.js";import{availableHelperModels}from"#internal/model-auth/available-models.js";import{isModelConnection,readDefaultConnection,writeDefaultConnection}from"#internal/model-auth/store.js";function environmentConnection(e){if(e.AI_GATEWAY_API_KEY?.trim())return`ai-gateway-key`;if(e.VERCEL_OIDC_TOKEN?.trim())return`ai-gateway-project`;if(e.OPENAI_API_KEY?.trim())return`openai`;if(e.ANTHROPIC_API_KEY?.trim())return`anthropic`}async function readLoginModel(e){let t=await readAuthoredModelSelection(e);if(t!==void 0)return{selection:t,external:parseModelHelper(t)!==void 0};let n=(await inspectApplication(e)).compiledState?.manifest.config.model;return{selection:n?.routing.kind===`gateway`&&n.source===void 0?n.id:void 0,external:n?.routing.kind===`external`}}function modelSelection(e,t){let n=e===`chatgpt`||e===`openai`||e===`anthropic`?e:void 0,r=t.selection===void 0?void 0:parseModelHelper(t.selection),i=n?r?.helper===n:t.selection!==void 0&&!t.external,a=n?MODEL_HELPERS[n].defaultModel:DEFAULT_AGENT_MODEL_ID,o=r?.id??t.selection;return{helper:n,compatible:i,defaultId:a,needsModels:!i||o===a}}async function applyConnection(e,t,n,r){let{appRoot:i,prompter:a,signal:o}=e,{selected:s,team:c}=t,{helper:l,compatible:u,defaultId:d,needsModels:f}=modelSelection(s,n),p;if(f){let e=t.availableModels??r??(l?await withLoginProgress(a,`Loading available models…`,()=>availableHelperModels(l,o)):[]),i=d;if(!e.includes(i)){if(e.length===0)throw Error(`No models are available for this connection. Choose another connection with /login.`);i=await a.select({message:`Choose an available model`,search:!0,options:e.map(e=>({value:e,label:e}))})}let s=l?MODEL_HELPERS[l].prefix+i:i;(!u||s!==n.selection)&&(p=s)}let m=s===`openai`||s===`anthropic`||s===`ai-gateway-key`?e.automatic?readProviderKeySourceSync(i)??(environmentConnection(process.env)===s?`environment`:`secret`):`secret`:void 0,h={selected:s,...c,keySource:m},g=!await providerSettingsMatch(i,h),save=async()=>{if(o?.throwIfAborted(),p!==void 0){let t=await changeValidatedAgentModel({appRoot:e.agentRoot??i,slug:p});if(t.kind===`rejected`)throw Error(t.message)}g&&await writeProviderSelection(i,s,c,m),process.env[MODEL_CONNECTION_ENV]=s,m?process.env.EVE_MODEL_KEY_SOURCE=m:delete process.env.EVE_MODEL_KEY_SOURCE,c?(process.env.EVE_MODEL_TEAM=c.teamId,process.env.EVE_MODEL_TEAM_NAME=c.teamName):(delete process.env.EVE_MODEL_TEAM,delete process.env.EVE_MODEL_TEAM_NAME)};p===void 0?await save():await withLoginProgress(a,`Loading selected model…`,()=>measureLoginStage(`activation`,()=>e.withConnectionUpdate?e.withConnectionUpdate(save):save())),e.automatic||await writeDefaultConnection(s);let _=p??n.selection,v=l&&_?parseModelHelper(_)?.id:_,y;if(v){let e=l?{kind:`external`,provider:MODEL_HELPERS[l].provider}:classifyModelRouting(v);y={id:v,routing:e,endpoint:resolveModelEndpointStatus(e,{apiKey:s===`ai-gateway-key`,oidc:s===`ai-gateway-project`,account:s===`vercel`||s===`vercel-cli`,team:c?.teamName},{state:`ready`})}}return{kind:`ready`,reload:p!==void 0&&e.withConnectionUpdate===void 0,...y&&{model:y}}}async function runModelLogin(e){let{appRoot:t,prompter:n,signal:r}=e,i,getModel=()=>i??=measureLoginStage(`source_inspection`,()=>readLoginModel(e.agentRoot??t)),connect=async(i,a)=>{let o=new AbortController,s=r?AbortSignal.any([r,o.signal]):o.signal,c=getModel().then(async e=>{let t=modelSelection(i,e);return{model:e,models:!t.helper&&t.needsModels?(await measureLoginStage(`gateway_catalog`,()=>fetchGatewayCatalog(s))).filter(e=>e.type===`language`).map(e=>e.id):void 0}}).then(e=>({value:e}),e=>({error:e}));try{let r=readProviderTeamSync(t),o=await measureLoginStage(`authentication`,async()=>a?await withLoginProgress(n,`Checking model access…`,()=>reuseModelConnection(i,r,s)):await authenticateModelConnection({selected:i,team:r,prompter:n,signal:s}));if(!o)return;let l=await withLoginProgress(n,`Loading available models…`,()=>c);if(`error`in l)throw l.error;return await applyConnection({...e,automatic:a,signal:s},o,l.value.model,l.value.models)}finally{o.abort()}};try{if(e.automatic){let{model:e,selected:a}=await withLoginProgress(n,`Reading saved connection…`,async()=>{let[e,n,r,i]=await Promise.all([getModel(),readProviderSelection(t),resolveAvailableProviders(t),readDefaultConnection()]),a=e.selection===void 0?void 0:parseModelHelper(e.selection)?.helper;return{model:e,selected:n??a??environmentConnection(process.env)??(r.includes(`ai-gateway-project`)?`ai-gateway-project`:void 0)??i??`vercel-cli`}});if(e.external&&e.selection===void 0)return{kind:`ready`,reload:!1};try{let e=await connect(a,!0);if(e)return e}catch(e){i=void 0,r?.throwIfAborted(),n.log.warning(e instanceof Error?e.message:`Could not connect automatically. Retry /login.`)}}for(;;){let
|
|
1
|
+
import{fetchGatewayCatalog}from"../boxes/select-model.js";import{measureLoginStage,withLoginProgress}from"./model-login-progress.js";import{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection}from"./model-login-connection.js";import{changeValidatedAgentModel,readAuthoredModelSelection}from"./model-source-change.js";import{MODEL_CONNECTION_ENV}from"#internal/model-auth/transport.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{inspectApplication}from"#services/inspect-application.js";import{WizardCancelledError}from"#setup/step.js";import{MODEL_HELPERS,parseModelHelper}from"#shared/model-helper.js";import{providerSettingsMatch,readProviderKeySourceSync,readProviderSelection,readProviderTeamSync,resolveAvailableProviders,writeProviderSelection}from"#setup/provider-settings.js";import{resolveModelEndpointStatus}from"#internal/resolve-model-endpoint-status.js";import{classifyModelRouting}from"#internal/classify-model-routing.js";import{availableHelperModels}from"#internal/model-auth/available-models.js";import{isModelConnection,readDefaultConnection,writeDefaultConnection}from"#internal/model-auth/store.js";function environmentConnection(e){if(e.AI_GATEWAY_API_KEY?.trim())return`ai-gateway-key`;if(e.VERCEL_OIDC_TOKEN?.trim())return`ai-gateway-project`;if(e.OPENAI_API_KEY?.trim())return`openai`;if(e.ANTHROPIC_API_KEY?.trim())return`anthropic`}async function readLoginModel(e){let t=await readAuthoredModelSelection(e);if(t!==void 0)return{selection:t,external:parseModelHelper(t)!==void 0};let n=(await inspectApplication(e)).compiledState?.manifest.config.model;return{selection:n?.routing.kind===`gateway`&&n.source===void 0?n.id:void 0,external:n?.routing.kind===`external`}}function modelSelection(e,t){let n=e===`chatgpt`||e===`openai`||e===`anthropic`?e:void 0,r=t.selection===void 0?void 0:parseModelHelper(t.selection),i=n?r?.helper===n:t.selection!==void 0&&!t.external,a=n?MODEL_HELPERS[n].defaultModel:DEFAULT_AGENT_MODEL_ID,o=r?.id??t.selection;return{helper:n,compatible:i,defaultId:a,needsModels:!i||o===a}}async function applyConnection(e,t,n,r){let{appRoot:i,prompter:a,signal:o}=e,{selected:s,team:c}=t,{helper:l,compatible:u,defaultId:d,needsModels:f}=modelSelection(s,n),p;if(f){let e=t.availableModels??r??(l?await withLoginProgress(a,`Loading available models…`,()=>availableHelperModels(l,o)):[]),i=d;if(!e.includes(i)){if(e.length===0)throw Error(`No models are available for this connection. Choose another connection with /login.`);i=await a.select({message:`Choose an available model`,search:!0,options:e.map(e=>({value:e,label:e}))})}let s=l?MODEL_HELPERS[l].prefix+i:i;(!u||s!==n.selection)&&(p=s)}let m=s===`openai`||s===`anthropic`||s===`ai-gateway-key`?e.automatic?readProviderKeySourceSync(i)??(environmentConnection(process.env)===s?`environment`:`secret`):`secret`:void 0,h={selected:s,...c,keySource:m},g=!await providerSettingsMatch(i,h),save=async()=>{if(o?.throwIfAborted(),p!==void 0){let t=await changeValidatedAgentModel({appRoot:e.agentRoot??i,slug:p});if(t.kind===`rejected`)throw Error(t.message)}g&&await writeProviderSelection(i,s,c,m),process.env[MODEL_CONNECTION_ENV]=s,m?process.env.EVE_MODEL_KEY_SOURCE=m:delete process.env.EVE_MODEL_KEY_SOURCE,c?(process.env.EVE_MODEL_TEAM=c.teamId,process.env.EVE_MODEL_TEAM_NAME=c.teamName):(delete process.env.EVE_MODEL_TEAM,delete process.env.EVE_MODEL_TEAM_NAME)};p===void 0?await save():await withLoginProgress(a,`Loading selected model…`,()=>measureLoginStage(`activation`,()=>e.withConnectionUpdate?e.withConnectionUpdate(save):save())),e.automatic||await writeDefaultConnection(s);let _=p??n.selection,v=l&&_?parseModelHelper(_)?.id:_,y;if(v){let e=l?{kind:`external`,provider:MODEL_HELPERS[l].provider}:classifyModelRouting(v);y={id:v,routing:e,endpoint:resolveModelEndpointStatus(e,{apiKey:s===`ai-gateway-key`,oidc:s===`ai-gateway-project`,account:s===`vercel`||s===`vercel-cli`,team:c?.teamName},{state:`ready`})}}return{kind:`ready`,reload:p!==void 0&&e.withConnectionUpdate===void 0,...y&&{model:y}}}async function runModelLogin(e){let{appRoot:t,prompter:n,signal:r}=e,i,getModel=()=>i??=measureLoginStage(`source_inspection`,()=>readLoginModel(e.agentRoot??t)),connect=async(i,a)=>{let o=new AbortController,s=r?AbortSignal.any([r,o.signal]):o.signal,c=getModel().then(async e=>{let t=modelSelection(i,e);return{model:e,models:!t.helper&&t.needsModels?(await measureLoginStage(`gateway_catalog`,()=>fetchGatewayCatalog(s))).filter(e=>e.type===`language`).map(e=>e.id):void 0}}).then(e=>({value:e}),e=>({error:e}));try{let r=readProviderTeamSync(t),o=await measureLoginStage(`authentication`,async()=>a?await withLoginProgress(n,`Checking model access…`,()=>reuseModelConnection(i,r,s)):await authenticateModelConnection({selected:i,team:r,prompter:n,signal:s}));if(!o)return;let l=await withLoginProgress(n,`Loading available models…`,()=>c);if(`error`in l)throw l.error;return await applyConnection({...e,automatic:a,signal:s},o,l.value.model,l.value.models)}finally{o.abort()}};try{if(e.automatic){let{model:e,selected:a}=await withLoginProgress(n,`Reading saved connection…`,async()=>{let[e,n,r,i]=await Promise.all([getModel(),readProviderSelection(t),resolveAvailableProviders(t),readDefaultConnection()]),a=e.selection===void 0?void 0:parseModelHelper(e.selection)?.helper;return{model:e,selected:n??a??environmentConnection(process.env)??(r.includes(`ai-gateway-project`)?`ai-gateway-project`:void 0)??i??`vercel-cli`}});if(e.external&&e.selection===void 0)return{kind:`ready`,reload:!1};try{let e=await connect(a,!0);if(e)return e}catch(e){i=void 0,r?.throwIfAborted(),n.log.warning(e instanceof Error?e.message:`Could not connect automatically. Retry /login.`)}}let a=e.selected;for(;;){let t=a??await n.select({message:e.connectionMessage??`Choose a connection`,search:!0,options:[...CONNECTION_OPTIONS]});if(a=void 0,!isModelConnection(t))throw Error(`Choose a model connection.`);try{let e=await connect(t,!1);if(e)return e}catch(e){if(i=void 0,e instanceof WizardCancelledError)return{kind:`cancelled`};r?.throwIfAborted(),n.log.warning(e instanceof Error?e.message:`Connection failed. Retry /login.`)}}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}export{environmentConnection,runModelLogin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withLoginProgress}from"./model-login-progress.js";import{isObject}from"#shared/guards.js";import{rememberModelTeamSlug}from"#internal/model-auth/vercel-team.js";import{setTimeout}from"node:timers/promises";import{
|
|
1
|
+
import{withLoginProgress}from"./model-login-progress.js";import{isObject}from"#shared/guards.js";import{rememberModelTeamSlug}from"#internal/model-auth/vercel-team.js";import{setTimeout}from"node:timers/promises";import{readVercelCliTeam}from"#internal/model-auth/vercel-cli.js";import{openUrl}from"#setup/primitives/open-url.js";import{writeVercelSession}from"#internal/model-auth/store.js";import{VERCEL_MODEL_CLIENT_ID,VERCEL_OAUTH_ISSUER,authJson,sessionFromToken,validateVercelAccess,vercelApiJson,vercelOAuthEndpoints}from"#internal/model-auth/vercel.js";async function loginVercelModel(e,t,n){let{endpoints:r,device:i}=await withLoginProgress(e,`Opening Vercel sign-in…`,async()=>{let e=await vercelOAuthEndpoints(t);return{endpoints:e,device:await authJson(e.device,{method:`POST`,body:new URLSearchParams({client_id:VERCEL_MODEL_CLIENT_ID,scope:`openid offline_access`}),signal:t})}});if(typeof i.device_code!=`string`||typeof i.verification_uri!=`string`||typeof i.user_code!=`string`)throw Error(`Could not start Vercel sign-in. Retry /login.`);let a=typeof i.verification_uri_complete==`string`?i.verification_uri_complete:i.verification_uri;if(URL.parse(a)?.origin!==VERCEL_OAUTH_ISSUER)throw Error(`Vercel returned an unexpected sign-in URL. Retry /login.`);e.log.info(`Open ${a} · code ${i.user_code}`),openUrl(a);let o=typeof i.interval==`number`?Math.max(1,Math.min(30,i.interval)):5,s=typeof i.expires_in==`number`?Math.min(600,i.expires_in):300,c=Date.now()+s*1e3,l=e.log.spinner?.(`Finish signing in to Vercel in your browser`,{kind:`external-action`,emphasis:`your browser`}),u;try{for(;Date.now()<c;){await setTimeout(o*1e3,void 0,{signal:t});let e=await authJson(r.token,{method:`POST`,body:new URLSearchParams({client_id:VERCEL_MODEL_CLIENT_ID,grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:i.device_code}),signal:t});if(e.error!==`authorization_pending`){if(e.error===`slow_down`){o=Math.min(30,o+5);continue}if(e.error)throw Error(`Vercel sign-in was declined or expired. Retry /login.`);u=sessionFromToken(e);break}}}finally{l?.stop()}if(!u)throw Error(`Vercel sign-in timed out. Retry /login.`);let[d,f]=await withLoginProgress(e,`Loading Vercel teams…`,()=>Promise.all([loadTeams(u.accessToken,t),readVercelCliTeam()])),p=d.find(e=>e.id===n)??d.find(e=>e.id===f),m=d.length===1?d[0]:void 0;for(;;){if(!m){let t=await e.select({message:`Choose a Vercel team`,search:!0,initialValue:p?.id,options:d.map(e=>({value:e.id,label:e.name}))});m=d.find(e=>e.id===t)}if(!m)throw Error(`That Vercel team is no longer available. Retry /login.`);let n=m;try{await withLoginProgress(e,`Checking AI Gateway access for ${m.slug??m.name}…`,()=>validateVercelAccess(u.accessToken,n.id,t));break}catch(n){if(t?.throwIfAborted(),d.length===1)throw n;e.log.warning(`AI Gateway is unavailable for that team. Choose another team or press Esc to return.`),m=void 0}}return u.teamId=m.id,u.teamName=m.name,t?.throwIfAborted(),await writeVercelSession(u,VERCEL_MODEL_CLIENT_ID),m.slug&&rememberModelTeamSlug(m.id,m.slug),{teamId:m.id,teamName:m.name}}async function loadTeams(e,t){let n=[],r;for(let i=0;i<20;i++){let i=await vercelApiJson(`https://api.vercel.com/v2/teams?limit=100${r===void 0?``:`&until=${r}`}`,{headers:{authorization:`Bearer ${e}`},signal:t});if(!Array.isArray(i.teams))throw Error(`Could not list Vercel teams. Retry /login.`);for(let e of i.teams)isObject(e)&&typeof e.id==`string`&&typeof e.name==`string`&&n.push({id:e.id,name:e.name,slug:typeof e.slug==`string`?e.slug:void 0});if(r=isObject(i.pagination)&&typeof i.pagination.next==`number`?i.pagination.next:void 0,r===void 0)break}if(n.length===0)throw Error(`No Vercel team is available. Join a team or choose another connection in /login.`);return n}export{loginVercelModel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{
|
|
1
|
+
import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{interactiveAsker}from"#setup/ask.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e),i=t.projectRoot??t.appRoot;t.prompter.intro(`Set up ${r.label}`,r.hint),t.prompter.log.message(`Checking Vercel setup...`);let[a,o]=await Promise.all([n.detectDeployment(i,{signal:t.signal}),n.getVercelAuthStatus(i,{signal:t.signal})]),s=projectResolutionFromDeployment(a),c=integrationSetupEnvironment(o,s);return t.prompter.log.info(r.describeEnvironment?.(c)??describeIntegrationSetupEnvironment(c)),r.run(createSetupContexts({appRoot:t.appRoot,projectRoot:i,asker:t.asker??interactiveAsker(t.prompter),environment:c,prompter:t.prompter,resolveVercelProject:t.resolveVercelProject??(e=>resolveIntegrationVercelProject({appRoot:i,integration:e,signal:t.signal})),signal:t.signal,force:t.force,beginExternalAction:t.beginExternalAction}))}export{runIntegrationSetup};
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { resolveEveProjectContext } from "#internal/project-context.js";
|
|
2
|
+
import { detectPackageManager, type PackageManagerKind } from "#setup/package-manager.js";
|
|
3
|
+
import { pathExists, writeTextFile } from "#setup/scaffold/files.js";
|
|
4
|
+
import { syncHostFrameworkPreset } from "#setup/vercel-project-framework.js";
|
|
3
5
|
import { type SetupApplyContext, type SetupPrepareContext } from "../types.js";
|
|
4
6
|
export interface WebSetupDeps {
|
|
5
7
|
detectPackageManager: typeof detectPackageManager;
|
|
6
|
-
|
|
8
|
+
pathExists: typeof pathExists;
|
|
9
|
+
readTextFile(path: string): Promise<string>;
|
|
10
|
+
resolveEveProjectContext: typeof resolveEveProjectContext;
|
|
11
|
+
syncHostFrameworkPreset: typeof syncHostFrameworkPreset;
|
|
12
|
+
writeTextFile: typeof writeTextFile;
|
|
7
13
|
}
|
|
8
14
|
export interface WebSetupPlan {
|
|
9
|
-
|
|
10
|
-
packageManager:
|
|
15
|
+
hosting: "next" | "vercel";
|
|
16
|
+
packageManager: PackageManagerKind;
|
|
11
17
|
}
|
|
12
18
|
export declare function prepareWebSetup(context: SetupPrepareContext, deps?: WebSetupDeps): Promise<WebSetupPlan>;
|
|
13
19
|
export declare function applyWebSetup(plan: WebSetupPlan, context: SetupApplyContext, deps?: WebSetupDeps): Promise<{
|
|
14
|
-
facts:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
deploymentRequired: true;
|
|
20
|
+
facts: {
|
|
21
|
+
label: string;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
19
24
|
}>;
|
|
20
25
|
export declare const WEB_SETUP: import("../types.js").SetupIntegration;
|
|
@@ -1 +1,30 @@
|
|
|
1
|
-
import{defineSetupIntegration}from"../types.js";import{
|
|
1
|
+
import{defineSetupIntegration}from"../types.js";import{readFile}from"node:fs/promises";import{join}from"node:path";import{resolveEveProjectContext}from"#internal/project-context.js";import{detectPackageManager}from"#setup/package-manager.js";import{pathExists,writeTextFile}from"#setup/scaffold/files.js";import{select}from"#setup/ask.js";import{WEB_CHANNEL_TEMPLATES}from"#setup/scaffold/create/web-template.js";import{createPromptCommandOutput}from"#setup/cli/index.js";import{syncHostFrameworkPreset}from"#setup/vercel-project-framework.js";const NEXT_HOSTED_CONFIG=`import type { NextConfig } from "next";
|
|
2
|
+
import { withEve } from "eve/next";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const nextConfig: NextConfig = {};
|
|
6
|
+
const eveRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
7
|
+
|
|
8
|
+
export default withEve(nextConfig, { eveRoot });
|
|
9
|
+
`,PEER_SERVICE_NEXT_CONFIG=`import type { NextConfig } from "next";
|
|
10
|
+
|
|
11
|
+
const nextConfig: NextConfig = {};
|
|
12
|
+
|
|
13
|
+
export default nextConfig;
|
|
14
|
+
`,PEER_SERVICE_VERCEL_CONFIG=`import { withEve } from "eve/vercel";
|
|
15
|
+
|
|
16
|
+
export default await withEve({
|
|
17
|
+
services: {
|
|
18
|
+
web: { framework: "nextjs", root: "apps/web" },
|
|
19
|
+
},
|
|
20
|
+
routes: [
|
|
21
|
+
{ src: "^(.*)$", destination: { type: "service", service: "web" } },
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
`,defaultDeps={detectPackageManager,pathExists,readTextFile:e=>readFile(e,`utf8`),resolveEveProjectContext,syncHostFrameworkPreset,writeTextFile};async function prepareWebSetup(e,t=defaultDeps){let n=await t.resolveEveProjectContext(e.appRoot);if(n.kind===`workspace`)throw Error(`Web Chat setup requires a selected workspace agent.`);let r=await e.asker.ask(select({key:`web-hosting`,message:`How should Web Chat and your agents be deployed?`,options:[{id:`vercel`,label:`Vercel services`,hint:`(Recommended) Web Chat and agents deploy as separate services.`,value:`vercel`},{id:`next`,label:`Next.js`,hint:`One Next.js app serves Web Chat and routes agent requests.`,value:`next`}],recommended:`vercel`,required:!0}));return r===`vercel`&&await e.resolveVercelProject(`Web Chat`),{hosting:r,packageManager:(await t.detectPackageManager(n.environmentRoot)).kind}}function runScriptCommand(e,t){switch(e){case`npm`:return`npm run ${t}`;case`pnpm`:return`pnpm ${t}`;case`yarn`:return`yarn ${t}`;case`bun`:return`bun run ${t}`}}async function configurePeerServiceScripts(e,t){let n=join(e,`package.json`),r=JSON.parse(await t.readTextFile(n)),i={...r.scripts};i.dev??=`eve dev`,i[`dev:eve`]??=`eve dev`,i[`dev:services`]??=`vercel dev`,await t.writeTextFile(n,`${JSON.stringify({...r,scripts:i},null,2)}\n`,{force:!0})}async function assertInstallerOwned(e,t){try{let n=await readFile(e,`utf8`);if(t.includes(n))return}catch(e){if(e.code===`ENOENT`)return;throw e}throw Error(`Could not configure Web Chat because ${e} contains authored configuration. Preserve it and compose the eve integration manually.`)}async function applyWebSetup(e,t,n=defaultDeps){let r=await n.resolveEveProjectContext(t.appRoot);if(r.kind===`workspace`)throw Error(`Web Chat setup requires a selected workspace agent.`);let i=r.kind===`workspace-member`?r.member.appRoot:r.appRoot,a=join(i,`agent`,`channels`,`eve.ts`);(t.force||!await n.pathExists(a))&&await n.writeTextFile(a,WEB_CHANNEL_TEMPLATES.default,{force:t.force});let o=r.kind===`workspace-member`?r.member.name:void 0,s=join(r.environmentRoot,`apps`,`web`);await n.writeTextFile(join(s,`app`,`eve-agent.ts`),`/** Named workspace agent selected by the Web Chat installer. */\nexport const WEB_CHAT_AGENT: string | undefined = ${o===void 0?`undefined`:JSON.stringify(o)};\n`,{force:!0});let c=join(s,`next.config.ts`);await assertInstallerOwned(c,[`import type { NextConfig } from "next";
|
|
25
|
+
import { withEve } from "eve/next";
|
|
26
|
+
|
|
27
|
+
const nextConfig: NextConfig = {};
|
|
28
|
+
|
|
29
|
+
export default withEve(nextConfig);
|
|
30
|
+
`,NEXT_HOSTED_CONFIG,PEER_SERVICE_NEXT_CONFIG]);let l;if(e.hosting===`vercel`){let e=join(r.environmentRoot,`vercel.ts`),i=join(r.environmentRoot,`vercel.json`);if(await assertInstallerOwned(e,[PEER_SERVICE_VERCEL_CONFIG]),await n.pathExists(i))throw Error(`Could not configure Vercel services because ${i} already exists. Preserve it and compose eve/vercel manually.`);await n.writeTextFile(c,PEER_SERVICE_NEXT_CONFIG,{force:!0}),await n.writeTextFile(e,PEER_SERVICE_VERCEL_CONFIG,{force:!0}),await configurePeerServiceScripts(r.environmentRoot,n),await n.syncHostFrameworkPreset(t.presenter,r.environmentRoot,createPromptCommandOutput(t.presenter.log),{signal:t.signal}),l=`dev:services`}else await n.writeTextFile(c,NEXT_HOSTED_CONFIG,{force:!0}),l=`dev:web`;return t.presenter.log.success(`Configured channel: web`),{facts:[{label:``,value:`Start locally with \`${runScriptCommand(e.packageManager,l)}\`.`}]}}const WEB_SETUP=defineSetupIntegration({kind:`web`,label:`Web Chat`,hint:`Browser-based chat interface`,prepare:prepareWebSetup,apply:applyWebSetup});export{WEB_SETUP,applyWebSetup,prepareWebSetup};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.105`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.66.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_CHANNEL_TEMPLATES.default,"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -76,7 +76,7 @@ eve deploy
|
|
|
76
76
|
\`\`\`
|
|
77
77
|
|
|
78
78
|
\`eve deploy\` links a Vercel project if needed and deploys the agent to production. See the [eve deployment documentation](https://eve.dev/docs/guides/deployment/vercel) for authentication, environment variables, and deployment options.
|
|
79
|
-
`,"agent/channels/eve.ts":
|
|
79
|
+
`,"agent/channels/eve.ts":WEB_CHANNEL_TEMPLATES.default,"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE,"tsconfig.json":`{
|
|
80
80
|
"compilerOptions": {
|
|
81
81
|
"target": "ES2022",
|
|
82
82
|
"module": "esnext",
|