eve 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/src/channel/types.d.ts +6 -0
- package/dist/src/chunks/{use-eve-agent-hdPX68_i.js → use-eve-agent-CyDt3Lny.js} +2 -0
- package/dist/src/chunks/{use-eve-agent-CZkX_ZTT.js → use-eve-agent-DaH3cf8K.js} +2 -0
- package/dist/src/cli/commands/agent-prompt/collect-intent.md +1 -1
- package/dist/src/cli/commands/channels.d.ts +0 -17
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/extension-init.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +29 -0
- package/dist/src/cli/commands/integration-connect.js +1 -0
- package/dist/src/cli/commands/integration-setup.d.ts +2 -3
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/register-integration-commands.js +1 -1
- package/dist/src/cli/commands/registry-setup-command.d.ts +13 -3
- package/dist/src/cli/commands/registry-setup-command.js +2 -1
- package/dist/src/cli/commands/registry.d.ts +35 -1
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/trace.js +1 -1
- package/dist/src/cli/dev/tui/agent-header.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth-command.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +8 -7
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +8 -13
- package/dist/src/cli/dev/tui/setup-commands.js +3 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +14 -5
- package/dist/src/cli/dev/tui/setup-panel.d.ts +5 -1
- package/dist/src/cli/dev/tui/setup-panel.js +2 -2
- package/dist/src/cli/dev/tui/status-line.d.ts +1 -1
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +2 -5
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +2 -0
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/tui/vercel-status.d.ts +1 -6
- package/dist/src/cli/dev/tui/vercel-status.js +1 -1
- package/dist/src/cli/option-parsers.d.ts +11 -0
- package/dist/src/cli/option-parsers.js +1 -0
- package/dist/src/cli/run.d.ts +1 -12
- package/dist/src/cli/run.js +3 -3
- package/dist/src/cli/shutdown.d.ts +2 -0
- package/dist/src/cli/shutdown.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +5 -5
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/private.d.ts +21 -5
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/world.d.ts +10 -5
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world-local/index.js +3 -3
- package/dist/src/compiled/@workflow/world-vercel/index.js +13 -13
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-DeZc2RZz.js → attribute-changes-1LmTKuTT.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{private-Cre8uYkA.js → private-BcwCGTV5.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{resume-hook-ip1hbn1b.js → resume-hook-D1_5NCZ6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{run-CWytxfIp.js → run-C240Ctf4.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/sleep-De802yfX.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{wait-until-De9yESQN.js → wait-until-z48sPUjU.js} +2 -2
- package/dist/src/compiled/shadcn-registry/index.d.ts +1 -0
- package/dist/src/evals/assertions/collector.d.ts +2 -10
- package/dist/src/evals/assertions/collector.js +1 -1
- package/dist/src/evals/cli/eval.d.ts +6 -2
- package/dist/src/evals/cli/eval.js +2 -2
- package/dist/src/evals/cli/filter.d.ts +14 -0
- package/dist/src/evals/cli/filter.js +1 -0
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/diagnostics.d.ts +8 -0
- package/dist/src/evals/diagnostics.js +1 -0
- package/dist/src/evals/expect/index.d.ts +1 -1
- package/dist/src/evals/expect/index.js +1 -1
- package/dist/src/evals/index.d.ts +1 -1
- package/dist/src/evals/judge.js +2 -1
- package/dist/src/evals/runner/artifacts.js +1 -1
- package/dist/src/evals/runner/reporters/assertion-diagnostics.d.ts +3 -0
- package/dist/src/evals/runner/reporters/assertion-diagnostics.js +3 -0
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/evals/runner/reporters/console.js +1 -1
- package/dist/src/evals/runner/reporters/junit.js +2 -2
- package/dist/src/evals/types.d.ts +21 -5
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +7 -0
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/turn-sleep.d.ts +12 -0
- package/dist/src/harness/turn-sleep.js +1 -0
- package/dist/src/internal/application/compiled-artifacts.js +7 -7
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +4 -0
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/workflow/development-world-protocol.js +1 -1
- package/dist/src/internal/workflow/world-target.d.ts +7 -0
- package/dist/src/internal/workflow/world-target.js +1 -0
- package/dist/src/protocol/routes.d.ts +4 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/tools/sleep/index.d.ts +18 -0
- package/dist/src/public/tools/sleep/index.js +1 -0
- package/dist/src/runtime/framework-tools/sleep.d.ts +15 -0
- package/dist/src/runtime/framework-tools/sleep.js +1 -0
- package/dist/src/services/dev-client/runtime-artifacts.d.ts +7 -0
- package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
- package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
- package/dist/src/setup/boxes/deploy-project.d.ts +3 -3
- package/dist/src/setup/flows/deploy.js +1 -1
- package/dist/src/setup/flows/ensure-vercel-project.d.ts +17 -0
- package/dist/src/setup/flows/ensure-vercel-project.js +1 -0
- package/dist/src/setup/flows/in-project.d.ts +1 -1
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +20 -0
- package/dist/src/setup/flows/registry.js +1 -0
- package/dist/src/setup/index.d.ts +0 -1
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/{channel-setup-environment.d.ts → integrations/channels/environment.d.ts} +2 -2
- package/dist/src/setup/integrations/channels/environment.js +1 -0
- package/dist/src/setup/{channel-setup-integrations.d.ts → integrations/channels/index.d.ts} +3 -3
- package/dist/src/setup/integrations/channels/index.js +1 -0
- package/dist/src/setup/{channel-setup-runner.d.ts → integrations/channels/runner.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/runner.js +1 -0
- package/dist/src/setup/{boxes/add-channels.d.ts → integrations/channels/setup.d.ts} +32 -22
- package/dist/src/setup/integrations/channels/setup.js +2 -0
- package/dist/src/setup/{channel-setup-slack.d.ts → integrations/channels/slack.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/slack.js +1 -0
- package/dist/src/setup/{channel-setup-integration.d.ts → integrations/channels/types.d.ts} +23 -7
- package/dist/src/setup/{channel-setup-ui.d.ts → integrations/channels/ui.d.ts} +2 -2
- package/dist/src/setup/integrations/channels/ui.js +2 -0
- package/dist/src/setup/{channel-setup-web.d.ts → integrations/channels/web.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/web.js +1 -0
- package/dist/src/setup/primitives/run-vercel.d.ts +1 -0
- package/dist/src/setup/primitives/run-vercel.js +1 -1
- package/dist/src/setup/prompter.d.ts +16 -3
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/registry-setup-client.d.ts +18 -0
- package/dist/src/setup/registry-setup-client.js +2 -0
- package/dist/src/setup/registry-setup-protocol.d.ts +93 -0
- package/dist/src/setup/registry-setup-protocol.js +1 -0
- package/dist/src/setup/scaffold/channels-catalog.d.ts +1 -1
- package/dist/src/setup/scaffold/create/extension.js +2 -2
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/create-in-place.d.ts +1 -0
- package/dist/src/setup/scaffold/create-in-place.js +1 -0
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/connections.js +3 -3
- package/dist/src/setup/scaffold/update/update-connection-connector.js +1 -1
- package/dist/src/setup/vercel-project-framework.d.ts +1 -1
- package/dist/src/setup/vercel-project-framework.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +17 -2
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/overview.mdx +1 -1
- package/docs/channels/slack.mdx +2 -2
- package/docs/concepts/default-harness.md +12 -0
- package/docs/evals/assertions.mdx +8 -1
- package/docs/evals/judge.mdx +11 -1
- package/docs/evals/reporters.mdx +1 -1
- package/docs/evals/running.mdx +3 -0
- package/docs/guides/dev-tui.md +9 -14
- package/docs/guides/instrumentation.md +1 -1
- package/docs/reference/cli.md +25 -38
- package/docs/reference/typescript-api.md +2 -1
- package/docs/tutorial/ship-it.mdx +2 -2
- package/package.json +11 -6
- package/dist/src/compiled/@workflow/core/runtime/world-target.d.ts +0 -11
- package/dist/src/compiled/_chunks/workflow/sleep-BjrUxUcs.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/index.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/parse-name.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/promise.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/time.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/workflow-routes.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/world-target.js +0 -1
- package/dist/src/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js +0 -1
- package/dist/src/setup/boxes/add-channels.js +0 -2
- package/dist/src/setup/boxes/add-connections.d.ts +0 -26
- package/dist/src/setup/boxes/add-connections.js +0 -1
- package/dist/src/setup/boxes/install-channel-registry-items.d.ts +0 -8
- package/dist/src/setup/boxes/install-channel-registry-items.js +0 -1
- package/dist/src/setup/boxes/one-shot-next-steps.d.ts +0 -18
- package/dist/src/setup/boxes/one-shot-next-steps.js +0 -2
- package/dist/src/setup/boxes/preflight.d.ts +0 -37
- package/dist/src/setup/boxes/preflight.js +0 -1
- package/dist/src/setup/boxes/resolve-target.d.ts +0 -58
- package/dist/src/setup/boxes/resolve-target.js +0 -1
- package/dist/src/setup/boxes/scaffold.d.ts +0 -40
- package/dist/src/setup/boxes/scaffold.js +0 -1
- package/dist/src/setup/boxes/select-channels.d.ts +0 -49
- package/dist/src/setup/boxes/select-channels.js +0 -1
- package/dist/src/setup/boxes/select-chat.d.ts +0 -38
- package/dist/src/setup/boxes/select-chat.js +0 -1
- package/dist/src/setup/boxes/select-connections.d.ts +0 -30
- package/dist/src/setup/boxes/select-connections.js +0 -1
- package/dist/src/setup/boxes/select-setup-mode.d.ts +0 -32
- package/dist/src/setup/boxes/select-setup-mode.js +0 -1
- package/dist/src/setup/channel-setup-deployment.d.ts +0 -11
- package/dist/src/setup/channel-setup-deployment.js +0 -1
- package/dist/src/setup/channel-setup-environment.js +0 -1
- package/dist/src/setup/channel-setup-integration.js +0 -1
- package/dist/src/setup/channel-setup-integrations.js +0 -1
- package/dist/src/setup/channel-setup-runner.js +0 -1
- package/dist/src/setup/channel-setup-slack.js +0 -1
- package/dist/src/setup/channel-setup-ui.js +0 -2
- package/dist/src/setup/channel-setup-web.js +0 -1
- package/dist/src/setup/flows/channels.d.ts +0 -57
- package/dist/src/setup/flows/channels.js +0 -1
- package/dist/src/setup/flows/connections.d.ts +0 -37
- package/dist/src/setup/flows/connections.js +0 -3
- package/dist/src/setup/onboarding.d.ts +0 -60
- package/dist/src/setup/onboarding.js +0 -1
- /package/dist/src/{node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/pluralize.js → setup/integrations/channels/types.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ChannelSetupAwaitChoice } from "#setup/cli/index.js";
|
|
1
|
+
import { type ChannelSetupAwaitChoice, type SetupSpinnerIntent } from "#setup/cli/index.js";
|
|
2
2
|
import { type RailSpinner } from "#setup/cli/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Clack constrains option values to readonly primitives. Our scaffold flow
|
|
@@ -63,9 +63,18 @@ export interface SelectNotice {
|
|
|
63
63
|
tone: "success" | "info" | "warning" | "error";
|
|
64
64
|
text: string;
|
|
65
65
|
}
|
|
66
|
+
/** One labeled fact rendered between a select question's description and options. */
|
|
67
|
+
export interface SelectMetadata {
|
|
68
|
+
label: string;
|
|
69
|
+
value: string;
|
|
70
|
+
}
|
|
66
71
|
/** Options common to every {@link Prompter.select} call. */
|
|
67
72
|
export interface SelectCommonOptions<T extends PrompterValue> {
|
|
68
73
|
message: string;
|
|
74
|
+
/** Inert context rendered beneath the question heading and above its options. */
|
|
75
|
+
description?: string;
|
|
76
|
+
/** Labeled facts rendered beneath the description and above the options. */
|
|
77
|
+
metadata?: readonly SelectMetadata[];
|
|
69
78
|
options: SelectOption<T>[];
|
|
70
79
|
/**
|
|
71
80
|
* Add a type-ahead filter line. The filter is a case-insensitive substring
|
|
@@ -86,7 +95,7 @@ export interface SelectCommonOptions<T extends PrompterValue> {
|
|
|
86
95
|
* each hint on its own line below the label with a blank line between options —
|
|
87
96
|
* for small action menus whose hints carry current values. "inline" keeps hints
|
|
88
97
|
* on the label row, suppresses numeric shortcuts, and separates the trailing
|
|
89
|
-
* completion action (e.g. the `/
|
|
98
|
+
* completion action (e.g. the `/add` task list).
|
|
90
99
|
*/
|
|
91
100
|
hintLayout?: "stacked" | "inline";
|
|
92
101
|
/** Outcome lines from earlier laps of a looping menu. */
|
|
@@ -202,6 +211,10 @@ export interface Prompter {
|
|
|
202
211
|
intro(title: string, subtitle?: string): void;
|
|
203
212
|
/** Prints a final green ● end-cap with the message. */
|
|
204
213
|
outro(message: string): void;
|
|
214
|
+
/** Temporarily hands terminal ownership to a command that inherits stdio. */
|
|
215
|
+
withInheritedStdio?<T>(task: () => Promise<T>): Promise<T>;
|
|
216
|
+
/** Gives a setup subprocess exclusive terminal and development-host ownership. */
|
|
217
|
+
withExclusiveTerminal?<T>(task: () => Promise<T>): Promise<T>;
|
|
205
218
|
log: {
|
|
206
219
|
message(text: string): void;
|
|
207
220
|
info(text: string): void;
|
|
@@ -215,7 +228,7 @@ export interface Prompter {
|
|
|
215
228
|
* returning a handle whose `stop()` clears it. Present on the real prompter;
|
|
216
229
|
* optional so lightweight test fakes can omit it.
|
|
217
230
|
*/
|
|
218
|
-
spinner?(message: string): RailSpinner;
|
|
231
|
+
spinner?(message: string, intent?: SetupSpinnerIntent): RailSpinner;
|
|
219
232
|
};
|
|
220
233
|
}
|
|
221
234
|
/**
|
|
@@ -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{
|
|
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{TextPrompt as ht,isCancel as q,settings as h}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{WizardCancelledError}from"./step.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let r,i=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let n=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=i;switch(t.mask?o=a:this.value&&(o=this.userInputWithCursor),this.state){case`error`:return`${n.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=this.value||t.placeholder||``;return t.mask&&(n=this.value?REDACTED_DISPLAY:t.placeholder??``),formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${n}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${n}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(r?.note())}\n`}}});return r=attachQuitGuard(i),i.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});function printNotices(e){for(let n of e??[])n.tone===`success`?t.success(n.text):n.tone===`warning`?t.warning(n.text):n.tone===`error`?t.error(n.text):t.message(n.text)}return{async text(n){t.settle(),printNotices(n.notices);let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle(),printNotices(n.notices),n.description!==void 0&&process.stdout.write(formatRailLine(import_picocolors.default.dim(n.description),import_picocolors.default,process.stdout));for(let{label:e,value:t}of n.metadata??[])process.stdout.write(formatRailLine(`${import_picocolors.default.dim(`${e}:`)} ${t}`,import_picocolors.default,process.stdout));let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,searchAction:n.multiple===!0?void 0:n.searchAction,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Prompter } from "./prompter.js";
|
|
2
|
+
import { type RegistrySetupChildMessage, type RegistrySetupFact } from "./registry-setup-protocol.js";
|
|
3
|
+
interface SetupProcess extends NodeJS.Process {
|
|
4
|
+
send?: (message: RegistrySetupChildMessage) => boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface RegistrySetupClient {
|
|
7
|
+
prompter: Prompter;
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
complete(facts?: readonly RegistrySetupFact[]): void;
|
|
10
|
+
cancel(): void;
|
|
11
|
+
fail(error: unknown): void;
|
|
12
|
+
}
|
|
13
|
+
/** Creates a prompter whose questions and output are rendered by the parent eve process. */
|
|
14
|
+
export declare function createRegistrySetupClient(input?: {
|
|
15
|
+
process?: SetupProcess;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): RegistrySetupClient | undefined;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{WizardCancelledError}from"./step.js";import"./registry-setup-protocol.js";function send(e,t){if(e.send===void 0||!e.connected)throw Error(`The registry setup host disconnected.`);e.send(t)}function registrySetupError(e){if(!(e instanceof Error))return{message:String(e)};let t=e.stack?.split(`
|
|
2
|
+
`).slice(1).map(e=>e.trim()).filter(Boolean);return t===void 0||t.length===0?{message:e.message}:{message:e.message,details:t}}function createRegistrySetupClient(t={}){let n=t.process??process;if(n.send===void 0||process.env.EVE_SETUP_PROTOCOL===void 0)return;let r=new AbortController;t.signal!==void 0&&t.signal.addEventListener(`abort`,()=>r.abort(t.signal?.reason),{once:!0});let i=1,a=new Map;n.on(`message`,t=>{if(t.type===`cancel`){r.abort(new WizardCancelledError);for(let e of a.values())e({type:`cancel`});a.clear();return}a.get(t.id)?.(t)}),send(n,{type:`ready`,version:1});async function prompt(t){r.signal.throwIfAborted();let o=i++,s=await new Promise(e=>{a.set(o,e),send(n,{type:`prompt`,id:o,prompt:t})});if(a.delete(o),s.type===`cancel`||s.cancelled===!0)throw new WizardCancelledError;return s.value}async function validatedText(e,t){let n=t.notices;for(;;){let r=await prompt({kind:e,message:t.message,placeholder:t.placeholder,defaultValue:t.defaultValue,notices:n}),i=t.validate?.(r);if(i===void 0)return r;n=[{tone:`error`,text:i}]}}function select(e){return prompt({kind:`select`,options:e})}let o={text:e=>validatedText(`text`,e),password:e=>validatedText(`password`,e),select,async selectEditable(e){let t=await prompt({kind:`editable-select`,options:{...e,editable:{value:e.editable.value,defaultValue:e.editable.defaultValue}}});if(t.kind===`selected`)return{kind:`selected`,value:t.value};let n=e.editable.validate?.(t.text);if(n!==void 0)throw Error(n);return{kind:`edited`,value:t.value,text:t.text}},acknowledge:e=>prompt({kind:`acknowledge`,options:e}),awaitChoice(t){let r=i++;return{choice:new Promise((i,o)=>{a.set(r,t=>{a.delete(r),t.type===`cancel`||t.cancelled===!0?o(new WizardCancelledError):i(t.value)}),send(n,{type:`prompt`,id:r,prompt:{kind:`choice`,options:t}})}),close:()=>{a.delete(r),send(n,{type:`close-prompt`,id:r})}}},note(e,t,r){send(n,{type:`note`,message:e,title:t,tone:r?.tone})},intro(e,t){send(n,{type:`intro`,text:e,subtitle:t})},outro(e){send(n,{type:`outro`,text:e})},log:{message:e=>send(n,{type:`log`,level:`message`,text:e}),info:e=>send(n,{type:`log`,level:`info`,text:e}),success:e=>send(n,{type:`log`,level:`success`,text:e}),warning:e=>send(n,{type:`log`,level:`warning`,text:e}),error:e=>send(n,{type:`log`,level:`error`,text:e}),commandOutput:e=>send(n,{type:`log`,level:`commandOutput`,text:e}),spinner(e,t){let r=i++;return send(n,{type:`status`,id:r,status:e,intent:t?.kind===`external-action`?t:void 0}),{stop:()=>send(n,{type:`status`,id:r})}}}},s=!1,finish=e=>{s||(s=!0,send(n,{type:`result`,outcome:e}))};return{prompter:o,signal:r.signal,complete:(e=[])=>finish({kind:`completed`,facts:e}),cancel:()=>finish({kind:`cancelled`}),fail:e=>finish({kind:`failed`,error:registrySetupError(e)})}}export{createRegistrySetupClient};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AcknowledgeOptions, MultiSelectOptions, PrompterValue, SelectCommonOptions, SelectNotice, SelectOption, SingleSelectOptions } from "./prompter.js";
|
|
2
|
+
export declare const REGISTRY_SETUP_PROTOCOL_VERSION = 1;
|
|
3
|
+
export type RegistrySetupFact = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
kind?: "text" | "url" | "phone";
|
|
7
|
+
};
|
|
8
|
+
export type RegistrySetupError = {
|
|
9
|
+
message: string;
|
|
10
|
+
details?: readonly string[];
|
|
11
|
+
};
|
|
12
|
+
export type RegistrySetupOutcome = {
|
|
13
|
+
kind: "completed";
|
|
14
|
+
facts: readonly RegistrySetupFact[];
|
|
15
|
+
} | {
|
|
16
|
+
kind: "cancelled";
|
|
17
|
+
} | {
|
|
18
|
+
kind: "failed";
|
|
19
|
+
error: RegistrySetupError;
|
|
20
|
+
};
|
|
21
|
+
export type RegistrySetupPrompt = {
|
|
22
|
+
kind: "text" | "password";
|
|
23
|
+
message: string;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
defaultValue?: string;
|
|
26
|
+
notices?: readonly SelectNotice[];
|
|
27
|
+
} | {
|
|
28
|
+
kind: "select";
|
|
29
|
+
options: SingleSelectOptions<PrompterValue> | MultiSelectOptions<PrompterValue>;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "editable-select";
|
|
32
|
+
options: SelectCommonOptions<PrompterValue> & {
|
|
33
|
+
initialValue?: PrompterValue;
|
|
34
|
+
editable: {
|
|
35
|
+
value: PrompterValue;
|
|
36
|
+
defaultValue: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} | {
|
|
40
|
+
kind: "acknowledge";
|
|
41
|
+
options: AcknowledgeOptions;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "choice";
|
|
44
|
+
options: {
|
|
45
|
+
status: string;
|
|
46
|
+
context: string;
|
|
47
|
+
actions: readonly SelectOption<string>[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type RegistrySetupChildMessage = {
|
|
51
|
+
type: "ready";
|
|
52
|
+
version: typeof REGISTRY_SETUP_PROTOCOL_VERSION;
|
|
53
|
+
} | {
|
|
54
|
+
type: "prompt";
|
|
55
|
+
id: number;
|
|
56
|
+
prompt: RegistrySetupPrompt;
|
|
57
|
+
} | {
|
|
58
|
+
type: "close-prompt";
|
|
59
|
+
id: number;
|
|
60
|
+
} | {
|
|
61
|
+
type: "log";
|
|
62
|
+
level: "message" | "info" | "success" | "warning" | "error" | "commandOutput";
|
|
63
|
+
text: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: "note";
|
|
66
|
+
message: string;
|
|
67
|
+
title?: string;
|
|
68
|
+
tone?: "warning" | "success";
|
|
69
|
+
} | {
|
|
70
|
+
type: "intro" | "outro";
|
|
71
|
+
text: string;
|
|
72
|
+
subtitle?: string;
|
|
73
|
+
} | {
|
|
74
|
+
type: "result";
|
|
75
|
+
outcome: RegistrySetupOutcome;
|
|
76
|
+
} | {
|
|
77
|
+
type: "status";
|
|
78
|
+
id: number;
|
|
79
|
+
status?: string;
|
|
80
|
+
intent?: {
|
|
81
|
+
kind: "external-action";
|
|
82
|
+
emphasis: string;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
export type RegistrySetupParentMessage = {
|
|
86
|
+
type: "prompt-result";
|
|
87
|
+
id: number;
|
|
88
|
+
value?: unknown;
|
|
89
|
+
cancelled?: true;
|
|
90
|
+
} | {
|
|
91
|
+
type: "cancel";
|
|
92
|
+
};
|
|
93
|
+
export declare function isRegistrySetupChildMessage(value: unknown): value is RegistrySetupChildMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const REGISTRY_SETUP_PROTOCOL_VERSION=1;function isRegistrySetupChildMessage(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`ready`||t===`prompt`||t===`close-prompt`||t===`log`||t===`note`||t===`intro`||t===`outro`||t===`result`||t===`status`}export{REGISTRY_SETUP_PROTOCOL_VERSION,isRegistrySetupChildMessage};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build-time catalog of channels used by programmatic setup and
|
|
3
|
-
* `eve
|
|
3
|
+
* `eve add channel/slack`.
|
|
4
4
|
*
|
|
5
5
|
* Channel *identity* (slug, name, and whether it is scaffoldable) is owned by
|
|
6
6
|
* `@vercel/eve-catalog`, the cross-surface source of truth shared with the docs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,t.eveVersion).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 packageJsonTemplate(e){return`${JSON.stringify({name:`__EVE_INIT_APP_NAME__`,version:`0.0.0`,type:`module`,eve:{extension:{source:`./extension`,dist:`./dist/extension`}},files:[`dist`],exports:{".":{types:`./dist/index.d.ts`,default:`./dist/index.mjs`},"./tools":{types:`./dist/tools/index.d.ts`,default:`./dist/tools/index.mjs`}},scripts:{build:`eve extension build`,prepare:`eve extension build`,typecheck:`tsc`},dependencies:{zod:`__EVE_INIT_ZOD_VERSION__`},devDependencies:{"@types/node":`__EVE_INIT_TYPES_NODE_VERSION__`,eve:`__EVE_INIT_PACKAGE_VERSION__`,typescript:`__EVE_INIT_TYPESCRIPT_VERSION__`},peerDependencies:{eve:`*`}},null,2).slice(0,-1)}${e?ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX:``}}\n`}function templateFiles(e){return{"extension/extension.ts":`import { defineExtension } from "eve/extension";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
export default defineExtension({
|
|
@@ -30,4 +30,4 @@ dist
|
|
|
30
30
|
.DS_Store
|
|
31
31
|
*.tsbuildinfo
|
|
32
32
|
`,"AGENTS.md":"# eve Extension Package\n\nThis package is an eve extension — a reusable package of tools, connections,\nskills, hooks, and instruction fragments that a consuming agent mounts under\n`agent/extensions/`.\n\nBefore writing code, read the Extensions guide from the installed eve package\ndocs. In most installs, those docs are at `node_modules/eve/docs/extensions.md`.\nIn workspaces or local package installs, resolve the installed `eve` package\nlocation first and read its `docs/extensions.md`. If package docs are\nunavailable, use https://eve.dev/docs/extensions as a fallback.\n\n## Authoring\n\n- Declare the extension in `extension/extension.ts` with `defineExtension` from\n `eve/extension`. Config is optional; read bound values via the handle's\n `.config` in tools and hooks.\n- Add contributions under `extension/` the same way as in an agent:\n `tools/`, `connections/`, `skills/`, `hooks/`, and optional instruction\n fragments. Names come from file paths; the mount supplies the namespace, so\n name tools for what they do (`search`, not `crm_search`).\n- An extension cannot declare `agent.ts`, `sandbox`, `schedules`, or nested\n `extensions/` — those belong to the consuming agent.\n\n## Build and publish\n\n`eve extension build` (wired to `build`/`prepare`) transforms the complete\nagent-shaped source tree into `dist/extension/`, emits type declarations and a\ncompatibility manifest, and fills the package `exports` map. Ship `dist/` only.\nKeep `eve` as a required wildcard peer so the consumer's eve is the one that runs;\neve validates extension compatibility from the generated manifest. Keep the eve\ndevelopment dependency pinned exactly so builds remain reproducible. Upgrade it\nwhen the extension intentionally adopts a newer eve authoring API.\n","CLAUDE.md":`@AGENTS.md
|
|
33
|
-
`,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let
|
|
33
|
+
`,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let i=blockingCreateInPlaceEntries(await readdir(e));if(i.length>0&&!n){let e=i.slice(0,5).join(`, `),t=i.length>5?`, and ${i.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldExtensionProject(r){let s=resolve(r.targetDirectory??process.cwd(),r.projectName),c=r.projectName===`.`,l=r.overwriteExisting??!1,u=r.packageManager??`pnpm`,d=resolveEvePackageContract(r.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT),f=pinnedNodeEngineMajor(d.nodeEngine),p=resolve(r.workspaceProbeDirectory??s),m=isPackageManagerWorkspaceMember(u,p);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let h={appName:basename(s),eveVersion:d.version,zodPackageVersion:resolveVersionToken(`zodPackageVersion`,r.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,r.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:f,nodeEngine:f};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles(!m))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,h),{force:c&&l}),o&&await r.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:u,projectRoot:s,workspaceProbeRoot:p,onWorkspaceRootMutation:r.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(u,p,{nodeEngineRequirement:d.nodeEngine,onWorkspaceRootMutation:r.onWorkspaceRootMutation}),s}export{scaffoldExtensionProject};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.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{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.29.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -93,4 +93,4 @@ export default defineAgent({
|
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
});
|
|
96
|
-
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e))
|
|
96
|
+
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.38`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function blockingCreateInPlaceEntries(entries: readonly string[]): string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`,`.node-version`,`.nvmrc`,`.protolock`,`.prototools`,`.tool-versions`,`devenv.lock`,`devenv.nix`,`devenv.yaml`,`devbox.json`,`devbox.lock`,`flake.lock`,`flake.nix`]);function isSharedMiseEntry(e){let t=(e.startsWith(`.`)?e.slice(1):e).split(`.`),n=t.at(-1),r=t.slice(1,-1);return t[0]===`mise`&&(n===`toml`||n===`lock`)&&r.every(e=>e!==``&&e!==`local`)}function blockingCreateInPlaceEntries(t){return t.filter(t=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(t)&&!isSharedMiseEntry(t))}export{blockingCreateInPlaceEntries};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{WriteFileExistsError}from"./files.js";import{CURRENT_DIRECTORY_PROJECT_NAME,byokProviderEnvVar,isEveProject,scaffoldBaseProject}from"./create/project.js";import{scaffoldExtensionProject}from"./create/extension.js";import{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset}from"./update/channels.js";import{SCAFFOLDABLE_CHANNELS}from"./channels-catalog.js";import{CONNECTION_CATALOG,CUSTOM_CONNECTION_SLUG,SUPPORTED_PROTOCOLS,catalogSlugs,effectiveProtocols,endpointForProtocol,getCatalogEntry,isValidConnectionSlug}from"./connections/catalog.js";import{ensureConnection,ensureConnectionDependencies,listAuthoredConnections}from"./update/connections.js";import{HumanActionRequiredError}from"../human-action.js";export{CONNECTION_CATALOG,CURRENT_DIRECTORY_PROJECT_NAME,CUSTOM_CONNECTION_SLUG,DEFAULT_SLACK_CONNECTOR_SLUG,HumanActionRequiredError,SCAFFOLDABLE_CHANNELS,SLACK_CHANNEL_DEFAULT_ROUTE,SUPPORTED_PROTOCOLS,WriteFileExistsError,byokProviderEnvVar,catalogSlugs,deriveSlackConnectorSlug,effectiveProtocols,endpointForProtocol,ensureChannel,ensureConnection,ensureConnectionDependencies,getCatalogEntry,hasVercelHostFramework,isEveProject,isNextJsProject,isValidConnectionSlug,listAuthoredChannels,listAuthoredConnections,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset,scaffoldBaseProject,scaffoldExtensionProject};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{endpointForProtocol}from"../connections/catalog.js";import{join}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.2`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
|
|
2
2
|
`)}\n }),\n`;case`none`:return``}}function renderMcpTemplate(e,t,n){return`${n.kind===`connect`?`import { connect } from "@vercel/connect/eve";
|
|
3
3
|
import { defineMcpClientConnection } from "eve/connections";
|
|
4
4
|
`:`import { defineMcpClientConnection } from "eve/connections";
|
|
@@ -15,7 +15,7 @@ export default defineOpenAPIConnection({
|
|
|
15
15
|
spec: "${e.spec}",
|
|
16
16
|
${i} description: "${t}",
|
|
17
17
|
${authBlock(n)}});
|
|
18
|
-
`}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let
|
|
18
|
+
`}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let r=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(r)&&isJsonObject(r.dependencies)?r.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??DEFAULT_CONNECT_PACKAGE_VERSION);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let r=``;await pathExists(e)&&(r=await readFile(e,`utf8`));let i=t.filter(e=>!envKeyPresent(r,e));if(i.length===0)return[];let a=`${r.length>0&&!r.endsWith(`
|
|
19
19
|
`)?`
|
|
20
20
|
`:``}${i.map(e=>`${e}=`).join(`
|
|
21
|
-
`)}\n`;return await writeFile(e,
|
|
21
|
+
`)}\n`;return await writeFile(e,r+a,`utf8`),i}async function ensureConnection(e){let t=e.slug??e.entry.slug,a=resolveAuth(e.entry),o=endpointForProtocol(e.entry,e.protocol);if(o===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let s=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),c=envKeysForAuth(a),l=await pathExists(s);if(!e.force&&l)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:s,filesWritten:[],filesSkipped:[s],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:c};let u=[];if(a.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??DEFAULT_CONNECT_PACKAGE_VERSION);u.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(s,renderTemplate(e.protocol,o,e.entry.description,a),{force:!0});let d=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),c),f={slug:t,protocol:e.protocol,action:l?`overwritten`:`created`,filePath:s,filesWritten:[s],filesSkipped:[],packageJsonUpdated:u,envKeysAdded:d,envKeysRequired:c};return l&&(f.filesOverwritten=[s]),f}async function listAuthoredConnections(n){let r=join(n,USER_AUTHORED_CONNECTION_DIR),i;try{i=await readdir(r,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let n of i){if(n.isFile()){let t=getSupportedModuleBaseName(n.name);t!==null&&a.push(t);continue}if(n.isDirectory())try{(await readdir(join(r,n.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(n.name)}catch{}}return a.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile,writeFile}from"node:fs/promises";const CONNECT_CONNECTOR_REGEX=/(\bconnect\(\s*)(["'`])([^"'`]+)\2/;async function updateConnectionConnectorUid(r,i){let a;try{a=await readFile(r,`utf8`)}catch{return{patched:!1}}
|
|
1
|
+
import{readFile,writeFile}from"node:fs/promises";const CONNECT_CONNECTOR_REGEX=/(\bconnect\(\s*)(["'`])([^"'`]+)\2/,CONNECT_OBJECT_CONNECTOR_REGEX=/(\bconnector\s*:\s*)(["'`])([^"'`]+)\2/;async function updateConnectionConnectorUid(r,i){let a;try{a=await readFile(r,`utf8`)}catch{return{patched:!1}}let o=CONNECT_CONNECTOR_REGEX.test(a)?CONNECT_CONNECTOR_REGEX:CONNECT_OBJECT_CONNECTOR_REGEX.test(a)?CONNECT_OBJECT_CONNECTOR_REGEX:void 0;return o===void 0?{patched:!1}:(await writeFile(r,a.replace(o,(e,t,n)=>`${t}${n}${i}${n}`),`utf8`),{patched:!0})}export{updateConnectionConnectorUid};
|
|
@@ -12,7 +12,7 @@ export interface CreatedProjectFrameworkOptions extends VercelProjectOperationOp
|
|
|
12
12
|
* host framework the project declares on disk (e.g. Next.js).
|
|
13
13
|
*
|
|
14
14
|
* A project created as a standalone eve agent keeps the `eve` preset; adding a
|
|
15
|
-
* host framework via `eve
|
|
15
|
+
* host framework via `eve add channel/web` leaves it stale, so the deploy would
|
|
16
16
|
* build the agent instead of the host app. Since that command already deploys on
|
|
17
17
|
* the user's behalf, this switches the preset directly (no prompt) and notes the
|
|
18
18
|
* change. No host framework, an unlinked directory, or an already-correct preset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{object,string}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{readProjectLink}from"./project-resolution.js";import{isForbiddenApiFailure,normalizeVercelApiResult}from"./vercel-api-failure.js";import{VERCEL_PROJECT_REQUEST_TIMEOUT_MS,parseVercelJson,requireVercelTeamAccess}from"./vercel-project-api.js";import{
|
|
1
|
+
import{object,string}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{readProjectLink}from"./project-resolution.js";import{resolveVercelHostFrameworkPreset}from"./scaffold/update/channels.js";import"./scaffold/index.js";import{isForbiddenApiFailure,normalizeVercelApiResult}from"./vercel-api-failure.js";import{VERCEL_PROJECT_REQUEST_TIMEOUT_MS,parseVercelJson,requireVercelTeamAccess}from"./vercel-project-api.js";import{extname,join}from"node:path";import*as fs from"node:fs/promises";import{captureVercel}from"#setup/primitives/index.js";import"#setup/cli/index.js";const VercelProjectFrameworkSchema=object({framework:string().min(1).nullish()}),EVE_FRAMEWORK_INTEGRATIONS={nextjs:{label:`Next.js`,importSpecifier:`eve/next`},nuxt:{label:`Nuxt`,importSpecifier:`eve/nuxt`},nuxtjs:{label:`Nuxt`,importSpecifier:`eve/nuxt`},sveltekit:{label:`SvelteKit`,importSpecifier:`eve/sveltekit`}},FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS=new Set([`.cjs`,`.cts`,`.js`,`.json`,`.jsx`,`.mjs`,`.mts`,`.svelte`,`.ts`,`.tsx`,`.vue`]),FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES=new Set([`.eve`,`.git`,`.next`,`.nuxt`,`.output`,`.svelte-kit`,`.turbo`,`.vercel`,`build`,`coverage`,`dist`,`node_modules`]);function parseProjectFramework(e,t){let n=VercelProjectFrameworkSchema.safeParse(parseVercelJson(e,t));if(!n.success)throw Error(`Could not read Vercel project framework from ${t}.`);return n.data.framework??void 0}async function fetchProjectFramework(e,t,n,r){let s=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(s.ok)return parseProjectFramework(s.stdout,`project ${n}`);throw isForbiddenApiFailure(s.failure)&&requireVercelTeamAccess(s.failure),Error(`Could not inspect Vercel project "${n}". ${s.failure.message}`)}async function setProjectFramework(e,t,n,r,s,l){let u=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--method`,`PATCH`,`--raw-field`,`framework=${r}`,`--raw`],{cwd:e,onOutput:s,signal:l.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(!u.ok)throw isForbiddenApiFailure(u.failure)&&requireVercelTeamAccess(u.failure),Error(`Could not set Vercel project "${n}" framework to ${r}. ${u.failure.message}`)}async function confirmDetectedFramework(e,t,n){return await e.select({message:`Vercel detected ${n.label}. Is this project using ${n.importSpecifier}?`,options:[{value:!0,label:`Yes, keep ${t}`,hint:`Use this for a host app that integrates eve through ${n.importSpecifier}.`},{value:!1,label:`No, switch to eve`,hint:`Use this for a standalone eve agent.`}]})?`keep`:`switch-to-eve`}function sourceMentionsPackageSpecifier(e,t){return e.includes(`"${t}"`)||e.includes(`'${t}'`)||e.includes(`\`${t}\``)}async function directoryContainsPackageSpecifier(e,t){let n;try{n=await fs.readdir(e,{encoding:`utf8`,withFileTypes:!0})}catch{return!1}for(let r of n){let n=join(e,r.name);if(r.isDirectory()){if(FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES.has(r.name))continue;if(await directoryContainsPackageSpecifier(n,t))return!0;continue}if(!(!r.isFile()||!FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS.has(extname(r.name))))try{if(sourceMentionsPackageSpecifier(await fs.readFile(n,`utf8`),t))return!0}catch{continue}}return!1}async function detectFrameworkIntegrationImport(e,t){return directoryContainsPackageSpecifier(e,t)}async function resolveDetectedFrameworkAction(e,t,n,r){let i=EVE_FRAMEWORK_INTEGRATIONS[n];return i===void 0?`switch-to-eve`:await(r.detectFrameworkIntegrationImport??detectFrameworkIntegrationImport)(t,i.importSpecifier)?`keep`:r.headless?`switch-to-eve`:confirmDetectedFramework(e,n,i)}function frameworkPresetLabel(e){return EVE_FRAMEWORK_INTEGRATIONS[e]?.label??e}function describeError(e){return e instanceof Error?e.message:String(e)}async function syncHostFrameworkPreset(e,t,i,a){let o=await resolveVercelHostFrameworkPreset(t);if(o===void 0)return;let s=await readProjectLink(t);if(s===void 0)return;let c=frameworkPresetLabel(o),l;try{l=await fetchProjectFramework(t,s.orgId,s.projectId,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`Could not check this Vercel project's Framework Preset (${describeError(t)}). If it is not already ${c}, set it under Project Settings → Build and Deployment → Framework Settings before deploying.`);return}if(l===o)return;let u=l===void 0?void 0:frameworkPresetLabel(l),d=u===void 0?`had no Framework Preset set`:`was set to "${u}"`;try{await setProjectFramework(t,s.orgId,s.projectId,o,i,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`${describeError(t)} Set this Vercel project's Framework Preset to ${c} (Project Settings → Build and Deployment → Framework Settings) before deploying, or the deployment will not build your ${c} app.`);return}e.log.info(`This project uses ${c}, but its Vercel Framework Preset ${d}; switched it to ${c} so the deployment builds your app.`)}async function ensureCreatedProjectFramework(e,t,n,r,i,a){let o=await fetchProjectFramework(t,n,r,a);o!==`eve`&&(o===void 0?`switch-to-eve`:await resolveDetectedFrameworkAction(e,t,o,a))===`switch-to-eve`&&await setProjectFramework(t,n,r,`eve`,i,a)}export{ensureCreatedProjectFramework,syncHostFrameworkPreset};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createPromptCommandOutput } from "#setup/cli/index.js";
|
|
2
|
-
import { type VercelCaptureFailure } from "#setup/primitives/index.js";
|
|
3
|
-
import { type ProjectResolution } from "./project-resolution.js";
|
|
2
|
+
import { runVercel, type VercelCaptureFailure } from "#setup/primitives/index.js";
|
|
3
|
+
import { readProjectLink, type ProjectResolution } from "./project-resolution.js";
|
|
4
4
|
import type { Prompter } from "./prompter.js";
|
|
5
5
|
import type { ResolvedVercelProjectSpec, VercelProjectIdentity } from "./state.js";
|
|
6
6
|
import { type VercelProjectOperationOptions } from "./vercel-project-api.js";
|
|
@@ -21,6 +21,21 @@ export interface PickTeamOptions extends VercelProjectOperationOptions {
|
|
|
21
21
|
}
|
|
22
22
|
export interface LinkProjectOperationOptions extends CreatedProjectFrameworkOptions {
|
|
23
23
|
}
|
|
24
|
+
/** Effects used to ensure an interactive Vercel project link. */
|
|
25
|
+
export interface EnsureLinkedVercelProjectDeps {
|
|
26
|
+
readProjectLink: typeof readProjectLink;
|
|
27
|
+
runVercel: typeof runVercel;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the existing Vercel project link or creates one through the Vercel
|
|
31
|
+
* CLI's interactive flow. The CLI owns team and project selection.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ensureLinkedVercelProject(input: {
|
|
34
|
+
projectRoot: string;
|
|
35
|
+
prompter: Prompter;
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
deps?: EnsureLinkedVercelProjectDeps;
|
|
38
|
+
}): Promise<NonNullable<Awaited<ReturnType<typeof readProjectLink>>>>;
|
|
24
39
|
export declare function unresolvedProject(): ProjectResolution;
|
|
25
40
|
/** Resolves the linked project id from a resolution, if any. */
|
|
26
41
|
export declare function projectIdFromResolution(project: ProjectResolution): string | undefined;
|
|
Binary file
|
package/dist/src/svelte/index.js
CHANGED
package/dist/src/vue/index.js
CHANGED
|
@@ -28,7 +28,7 @@ agent/
|
|
|
28
28
|
intake.ts
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Install a built-in channel with `eve add channel/slack` or `eve add channel/web`. You can also author the file by hand.
|
|
32
32
|
|
|
33
33
|
## The eve HTTP channel (default)
|
|
34
34
|
|
package/docs/channels/slack.mdx
CHANGED
|
@@ -21,7 +21,7 @@ The `create` step provisions a destination at the default Connect path. `detach`
|
|
|
21
21
|
|
|
22
22
|
## Add the channel
|
|
23
23
|
|
|
24
|
-
Scaffold the channel and its dependency with `eve
|
|
24
|
+
Scaffold the channel and its dependency with `eve add channel/slack`, or set it up by hand:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
npm install @vercel/connect
|
|
@@ -38,7 +38,7 @@ export default slackChannel({
|
|
|
38
38
|
|
|
39
39
|
`connectSlackCredentials` returns `{ botToken, webhookVerifier }`, keeping token rotation, multi-workspace tenancy, and request verification inside Connect rather than your code.
|
|
40
40
|
|
|
41
|
-
If eve cannot find an authenticated Vercel session, `eve
|
|
41
|
+
If eve cannot find an authenticated Vercel session, `eve add channel/slack` asks whether to set up Vercel Connect or use portable environment credentials. The portable option adds the required names to `.env.example`. Before deploying, appropriate values must be supplied to your runtime environment.
|
|
42
42
|
|
|
43
43
|
### Deploy
|
|
44
44
|
|
|
@@ -103,6 +103,18 @@ export default experimental_workflow({ maxSubagents: 100 });
|
|
|
103
103
|
|
|
104
104
|
With it on, the model can orchestrate the agent's own subagents from model-authored JavaScript, all as one durable step. The tool is root-only — delegated subagent sessions never see it — and one program may dispatch at most the configured `maxSubagents` calls (default 100). See [Dynamic workflows](../guides/dynamic-workflows).
|
|
105
105
|
|
|
106
|
+
## The opt-in `sleep` tool
|
|
107
|
+
|
|
108
|
+
The framework also ships a durable `sleep` tool, but does not add it to agents by default. Enable it with `agent/tools/sleep.ts`:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { sleep } from "eve/tools/sleep";
|
|
112
|
+
|
|
113
|
+
export default sleep();
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The model calls it with `{ seconds }` when it is useful to wait before checking progress or status again. The pause sleeps the durable turn workflow, so it does not hold an application runtime open, and the same turn continues automatically when the duration elapses. If one model response makes concurrent `sleep` calls, eve waits for the longest requested duration.
|
|
117
|
+
|
|
106
118
|
## What to read next
|
|
107
119
|
|
|
108
120
|
- [Tools](../tools): define your own tools, gate them on approval, and shape their output with `toModelOutput`
|
|
@@ -73,6 +73,12 @@ t.check(
|
|
|
73
73
|
| `similarity(expected)` | normalized Levenshtein similarity, 1 = identical | soft |
|
|
74
74
|
| `satisfies(fn, label)` | custom boolean predicate | gate |
|
|
75
75
|
|
|
76
|
+
For example, a failed labeled equality check prints:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
✗ equals [status] (0% < 100%): expected {"status":"active"}; received {"status":"disabled"}
|
|
80
|
+
```
|
|
81
|
+
|
|
76
82
|
Pick the cheapest builder that captures what "correct" means. When exact match is too strict but a judge model is overkill, `similarity` is the middle ground. For nuanced grading, reach for the [judge](./judge).
|
|
77
83
|
|
|
78
84
|
## The matcher mini-language
|
|
@@ -154,12 +160,13 @@ Every assertion returns a chainable handle. Severity rides on the assertion, so
|
|
|
154
160
|
- `.gate(threshold?)` is hard. A miss marks the eval `failed` and `eve eval` exits non-zero.
|
|
155
161
|
- `.soft(threshold?)` is tracked data. A below-threshold miss marks the eval `scored`, fatal only under `--strict`. With no threshold, it is tracked-only and never fails.
|
|
156
162
|
- `.atLeast(threshold)` is soft with a bar (equivalent to `.soft(threshold)`).
|
|
163
|
+
- `.label(name)` adds a stable name when an eval records several assertions from the same family.
|
|
157
164
|
|
|
158
165
|
The defaults are chosen so you rarely set severity. Run-level methods and `includes`/`equals`/`matches` are gates; `similarity` and every `t.judge.*` assertion are soft. Annotate only when you deviate:
|
|
159
166
|
|
|
160
167
|
```ts
|
|
161
168
|
t.calledTool("get_weather").soft(); // record the tool call as a metric, don't gate
|
|
162
|
-
t.check(t.reply, similarity("Sunny")).atLeast(0.8);
|
|
169
|
+
t.check(t.reply, similarity("Sunny")).label("forecast wording").atLeast(0.8);
|
|
163
170
|
t.check(t.reply, includes("error")).soft(); // track without failing the build
|
|
164
171
|
```
|
|
165
172
|
|
package/docs/evals/judge.mdx
CHANGED
|
@@ -28,6 +28,16 @@ The judges live under `t.judge.autoevals`. The namespace names the [Braintrust a
|
|
|
28
28
|
| `t.judge.autoevals.closedQA(criteria)` | Whether the reply satisfies a free-form yes/no criterion (no expected answer to match) |
|
|
29
29
|
| `t.judge.autoevals.sql(expected)` | Semantic equivalence of two SQL statements |
|
|
30
30
|
|
|
31
|
+
A failed `closedQA` assertion prints the input and judge explanation:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
✗ judge.autoevals.closedQA [citation] (0% < 80%): prompt: "Name the source."
|
|
35
|
+
criteria: "cites a source"
|
|
36
|
+
response: "It is widely believed."
|
|
37
|
+
rationale: "The response does not cite a source."
|
|
38
|
+
choice: "N"
|
|
39
|
+
```
|
|
40
|
+
|
|
31
41
|
The reference or criteria is the positional argument. An options object follows:
|
|
32
42
|
|
|
33
43
|
- `on` is the value to grade, defaulting to `t.reply`. Pass an intermediate draft or parsed value to grade it instead.
|
|
@@ -48,7 +58,7 @@ Judge assertions are soft, so the threshold rides on the assertion handle. There
|
|
|
48
58
|
|
|
49
59
|
```ts
|
|
50
60
|
t.judge.autoevals.closedQA("cites a source"); // tracked, never fails
|
|
51
|
-
t.judge.autoevals.closedQA("cites a source").atLeast(0.6);
|
|
61
|
+
t.judge.autoevals.closedQA("cites a source").label("citation").atLeast(0.6);
|
|
52
62
|
t.judge.autoevals.factuality(reference).gate(0.8); // hard gate at 0.8
|
|
53
63
|
```
|
|
54
64
|
|
package/docs/evals/reporters.mdx
CHANGED
|
@@ -38,7 +38,7 @@ export default defineEval({
|
|
|
38
38
|
});
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
The reporter config takes an optional `projectName` and `experimentName`, plus a base experiment (by name or id) to diff against. Gate assertions log as binary scores under a `gate:` prefix so experiments diff gate regressions the same way they diff soft-score regressions.
|
|
41
|
+
The reporter config takes an optional `projectName` and `experimentName`, plus a base experiment (by name or id) to diff against. Gate assertions log as binary scores under a `gate:` prefix so experiments diff gate regressions the same way they diff soft-score regressions. Repeated names use `#2`, `#3`, and later suffixes; use `.label(name)` to give them meaningful names. Failed assertion details are stored in the Braintrust metadata under `eveFailedAssertions`.
|
|
42
42
|
|
|
43
43
|
A reporter instance observes the evals that reference it. Share one instance across several evals (the config, a `shared.ts` export, or every entry of a dataset array) and their results land in a single experiment. Listing the same config reporter on an eval too does not double-report it.
|
|
44
44
|
|
package/docs/evals/running.mdx
CHANGED
|
@@ -10,6 +10,7 @@ eve eval # run all discovered evals locally
|
|
|
10
10
|
eve eval weather smoke # run selected evals (an id, or a directory prefix)
|
|
11
11
|
eve eval --url https://<app> # target a remote app instead of a local host
|
|
12
12
|
eve eval --tag fast # only evals carrying a tag
|
|
13
|
+
eve eval --exclude-tag slow # skip evals carrying a tag
|
|
13
14
|
eve eval --strict # soft below-threshold assertions also fail the exit code
|
|
14
15
|
eve eval --timeout 60000 # per-eval timeout in milliseconds
|
|
15
16
|
eve eval --max-concurrency 4 # cap concurrent eval executions (default 8)
|
|
@@ -22,6 +23,8 @@ eve eval --skip-report # skip config and eval-defined reporters (e.g. Br
|
|
|
22
23
|
|
|
23
24
|
Positional ids match exactly or by directory prefix: `eve eval weather` runs `evals/weather.eval.ts`, every eval under `evals/weather/`, and every entry of an array-exported `weather.eval.ts`.
|
|
24
25
|
|
|
26
|
+
Tag filters compose: `--tag` keeps evals carrying at least one listed tag, then `--exclude-tag` drops any eval carrying an excluded tag. A `--tag` filter that matches nothing is a configuration error (exit `2`), but a run where `--exclude-tag` removes every match succeeds with nothing executed — exclusion expresses "this suite does not apply here."
|
|
27
|
+
|
|
25
28
|
## Exit codes
|
|
26
29
|
|
|
27
30
|
| Code | Means |
|