eve 0.29.2 → 0.29.3
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 +23 -0
- package/dist/src/channel/types.d.ts +15 -0
- package/dist/src/cli/commands/integration-setup.d.ts +3 -7
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/registry.d.ts +1 -0
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/trace.d.ts +7 -24
- package/dist/src/cli/commands/trace.js +7 -5
- package/dist/src/cli/dev/tui/blocks.js +1 -1
- package/dist/src/cli/dev/tui/clipboard.d.ts +17 -0
- package/dist/src/cli/dev/tui/clipboard.js +1 -0
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +3 -0
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +6 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/stream-format.d.ts +8 -0
- package/dist/src/cli/dev/tui/stream-format.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +3 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/test/mock-terminal.js +3 -3
- package/dist/src/cli/dev/tui/traces/trace-content.d.ts +28 -0
- package/dist/src/cli/dev/tui/traces/trace-content.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +58 -0
- package/dist/src/cli/dev/tui/traces/trace-conversation.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-store.d.ts +27 -0
- package/dist/src/cli/dev/tui/traces/trace-store.js +1 -0
- package/dist/src/cli/dev/tui/traces/trace-view.d.ts +48 -0
- package/dist/src/cli/dev/tui/traces/trace-view.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-session.d.ts +41 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-session.js +1 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-state.d.ts +110 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-state.js +1 -0
- package/dist/src/cli/ui/alt-screen.d.ts +42 -0
- package/dist/src/cli/ui/alt-screen.js +1 -0
- package/dist/src/cli/ui/terminal-text.d.ts +4 -0
- package/dist/src/cli/ui/terminal-text.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -1
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/LICENSE +21 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/_spectrum-core.d.ts +3 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/_spectrum-imessage.d.ts +2 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.d.ts +496 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +137 -0
- package/dist/src/compiled/@vercel/sandbox/index.js +13 -107
- package/dist/src/compiled/_chunks/node/auth-BS3UoyvT.js +2 -0
- package/dist/src/compiled/_chunks/node/compat-Dm2n85Mx.js +1 -0
- package/dist/src/compiled/_chunks/node/schemas-DtQwuPdM.js +65 -0
- package/dist/src/compiled/_chunks/node/undici-DWL_MYmT.js +95 -0
- package/dist/src/compiled/_chunks/node/version-Cztrk7z6.js +1 -0
- package/dist/src/compiled/shadcn-registry/index.js +461 -893
- package/dist/src/context/keys.d.ts +3 -1
- package/dist/src/context/keys.js +1 -1
- package/dist/src/execution/delegated-parent-notification.js +1 -1
- package/dist/src/execution/delegated-parent-result.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.js +3 -3
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/read-file-tool.js +3 -3
- package/dist/src/execution/sandbox/require-sandbox.d.ts +3 -3
- package/dist/src/execution/sandbox/require-sandbox.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.js +1 -1
- package/dist/src/execution/subagent-adapter-state.d.ts +39 -0
- package/dist/src/execution/subagent-adapter-state.js +1 -0
- package/dist/src/execution/subagent-adapter.d.ts +0 -34
- package/dist/src/execution/subagent-adapter.js +1 -1
- package/dist/src/execution/subagent-tool.d.ts +2 -1
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/instrumentation-lifecycle.d.ts +18 -0
- package/dist/src/harness/instrumentation-native-events.d.ts +3 -1
- package/dist/src/harness/instrumentation-native-events.js +1 -1
- package/dist/src/harness/parent-lineage.d.ts +11 -0
- package/dist/src/harness/parent-lineage.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +7 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/photon/inboundContent.d.ts +4 -0
- package/dist/src/public/channels/photon/inboundContent.js +1 -0
- package/dist/src/public/channels/photon/index.d.ts +1 -0
- package/dist/src/public/channels/photon/index.js +1 -0
- package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +54 -0
- package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -0
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/connect-provisioning.d.ts +32 -0
- package/dist/src/setup/connect-provisioning.js +1 -0
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/registry.js +1 -1
- package/dist/src/setup/integrations/photon/connect.d.ts +40 -0
- package/dist/src/setup/integrations/photon/connect.js +1 -0
- package/dist/src/setup/integrations/photon/management.d.ts +34 -0
- package/dist/src/setup/integrations/photon/management.js +1 -0
- package/dist/src/setup/integrations/photon/setup-flow.d.ts +39 -0
- package/dist/src/setup/integrations/photon/setup-flow.js +20 -0
- package/dist/src/setup/integrations/photon/setup.d.ts +3 -0
- package/dist/src/setup/integrations/photon/setup.js +1 -0
- package/dist/src/setup/integrations/registry.d.ts +6 -0
- package/dist/src/setup/integrations/registry.js +1 -0
- package/dist/src/setup/integrations/runner.d.ts +25 -0
- package/dist/src/setup/integrations/runner.js +1 -0
- package/dist/src/setup/integrations/{channels → shared}/environment.d.ts +3 -3
- package/dist/src/setup/integrations/shared/environment.js +1 -0
- package/dist/src/setup/integrations/shared/scaffold.d.ts +19 -0
- package/dist/src/setup/integrations/shared/scaffold.js +1 -0
- package/dist/src/setup/integrations/{channels → shared}/ui.d.ts +3 -3
- package/dist/src/setup/integrations/shared/ui.js +2 -0
- package/dist/src/setup/integrations/slack/setup.d.ts +16 -0
- package/dist/src/setup/integrations/slack/setup.js +1 -0
- package/dist/src/setup/integrations/types.d.ts +26 -0
- package/dist/src/setup/integrations/web/setup.d.ts +3 -0
- package/dist/src/setup/integrations/web/setup.js +1 -0
- package/dist/src/setup/primitives/run-vercel.d.ts +2 -7
- package/dist/src/setup/primitives/run-vercel.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/update/channels.js +1 -1
- package/dist/src/setup/scaffold/update/connections.js +1 -1
- package/dist/src/setup/slack-connect-lifecycle.d.ts +2 -8
- package/dist/src/setup/slack-connect-lifecycle.js +1 -1
- package/dist/src/setup/state.d.ts +0 -12
- package/dist/src/setup/state.js +1 -1
- package/dist/src/shared/skill-paths.d.ts +10 -0
- package/dist/src/shared/skill-paths.js +2 -2
- package/dist/src/tracing/agent-otel-content.d.ts +32 -0
- package/dist/src/tracing/agent-otel-content.js +4 -0
- package/dist/src/{harness → tracing}/agent-otel-provider.d.ts +10 -1
- package/dist/src/tracing/agent-otel-provider.js +2 -0
- package/dist/src/{harness → tracing}/agent-trace-context-store.d.ts +8 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -0
- package/dist/src/{harness → tracing}/agent-trace-span-processor.d.ts +5 -1
- package/dist/src/tracing/agent-trace-span-processor.js +1 -0
- package/dist/src/tracing/local-instrumentation-runtime.js +1 -0
- package/dist/src/tracing/local-trace-reader.d.ts +57 -0
- package/dist/src/tracing/local-trace-reader.js +1 -0
- package/dist/src/{harness → tracing}/local-trace-retention.js +1 -1
- package/dist/src/{harness → tracing}/local-trace-span-processor.js +1 -1
- package/docs/channels/chat-sdk.mdx +18 -1
- package/docs/channels/meta.json +1 -0
- package/docs/channels/overview.mdx +1 -1
- package/docs/channels/photon.mdx +78 -0
- package/docs/concepts/default-harness.md +2 -0
- package/docs/guides/dev-tui.md +20 -1
- package/docs/guides/instrumentation.md +8 -7
- package/docs/reference/cli.md +9 -1
- package/docs/sandbox.mdx +1 -1
- package/package.json +7 -1
- package/dist/src/compiled/_chunks/node/auth-DMsLOrh7.js +0 -2
- package/dist/src/compiled/_chunks/node/version-BQBAL95V.js +0 -64
- package/dist/src/harness/agent-otel-provider.js +0 -1
- package/dist/src/harness/agent-trace-context-store.js +0 -1
- package/dist/src/harness/agent-trace-span-processor.js +0 -1
- package/dist/src/harness/local-instrumentation-runtime.js +0 -1
- package/dist/src/setup/integrations/channels/environment.js +0 -1
- package/dist/src/setup/integrations/channels/index.d.ts +0 -7
- package/dist/src/setup/integrations/channels/index.js +0 -1
- package/dist/src/setup/integrations/channels/runner.d.ts +0 -7
- package/dist/src/setup/integrations/channels/runner.js +0 -1
- package/dist/src/setup/integrations/channels/setup.d.ts +0 -130
- package/dist/src/setup/integrations/channels/setup.js +0 -2
- package/dist/src/setup/integrations/channels/slack.d.ts +0 -3
- package/dist/src/setup/integrations/channels/slack.js +0 -1
- package/dist/src/setup/integrations/channels/types.d.ts +0 -49
- package/dist/src/setup/integrations/channels/ui.js +0 -2
- package/dist/src/setup/integrations/channels/web.d.ts +0 -3
- package/dist/src/setup/integrations/channels/web.js +0 -1
- /package/dist/src/setup/integrations/{channels/types.js → types.js} +0 -0
- /package/dist/src/{harness → tracing}/local-instrumentation-runtime.d.ts +0 -0
- /package/dist/src/{harness → tracing}/local-trace-retention.d.ts +0 -0
- /package/dist/src/{harness → tracing}/local-trace-span-processor.d.ts +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import{appendEnv}from"../../append-env.js";import{text}from"../../ask.js";import{writeTextFile}from"../../scaffold/files.js";import{deriveSlackConnectorSlug}from"../../scaffold/update/channels.js";import"../../scaffold/index.js";import{WizardCancelledError}from"../../step.js";import{ensureVercelProject}from"../../flows/ensure-vercel-project.js";import{provisionPhotonConnector}from"./connect.js";import{provisionPhotonProject,usePhotonProject,validatePhotonPhoneNumber}from"./management.js";import{openUrl}from"../../primitives/open-url.js";import{join}from"node:path";const defaultDeps={appendEnv,deriveConnectorSlug:deriveSlackConnectorSlug,ensureVercelProject,openUrl,provisionConnector:provisionPhotonConnector,provisionProject:provisionPhotonProject,useProject:usePhotonProject,writeTextFile};function connectTemplate(e){return`import { connectPhotonCredentials } from "@vercel/connect/eve";
|
|
2
|
+
import { photonIMessageChannel } from "eve/channels/photon";
|
|
3
|
+
|
|
4
|
+
export default photonIMessageChannel({
|
|
5
|
+
credentials: connectPhotonCredentials(${JSON.stringify(e)}),
|
|
6
|
+
});
|
|
7
|
+
`}async function choosePhotonProject(e){let n=`eve · ${e.agentName||`agent`}`,r=[{value:`create`,label:`Create a new Photon project`,hint:`Name: ${n}`},{value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],i=e.ui.prompter.selectEditable?await e.ui.prompter.selectEditable({message:`Photon project`,options:r,initialValue:`create`,editable:{value:`create`,defaultValue:n,formatHint:e=>`Name: ${e}`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}}):void 0;if((i?.value??await e.ui.prompter.select({message:`Photon project`,options:r,initialValue:`create`}))===`existing`){let n=await e.ui.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),r=await e.ui.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0}));return{photonProject:{projectId:n.trim(),projectSecret:r.trim()}}}return{photonProject:`create`,photonProjectName:i?.kind===`edited`?i.text.trim():n}}async function chooseSetupPlan(e){try{let t=await e.ui.prompter.select({message:`How would you like to configure Photon?`,options:[{value:`vercel`,label:`Set up Vercel Connect`,hint:e.environment.vercel.kind===`available`?`Link this project and configure Photon automatically`:`Log in to Vercel and link this project`},{value:`portable`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],initialValue:e.environment.vercel.kind===`available`?`vercel`:`portable`});if(t===`vercel`&&e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Photon setup.");let n=await choosePhotonProject(e);return{credentials:t===`vercel`?`vercel-connect`:`environment`,...n}}catch(e){if(e instanceof WizardCancelledError)return`cancelled`;throw e}}async function resolvePhotonProject(e,t,n,r){if(t.photonProject!==`create`)return r.useProject({...t.photonProject,phoneNumber:n});let i=e.ui.prompter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`});try{return await r.provisionProject({projectName:t.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:n,signal:e.signal,onAuthorization(t){e.ui.prompter.log.message(`Authorize Photon: ${t.verificationUrl}`),e.ui.prompter.log.message(`Photon code: ${t.userCode}`),r.openUrl(t.verificationUrl)}})}finally{i?.stop()}}async function scaffoldPhoton(e,n,r){let i=await e.ui.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})),a=e.projectPath,o=await resolvePhotonProject(e,n,i,r);try{let t=join(a,`agent/channels/photon.ts`);if(n.credentials===`vercel-connect`){let n=await r.deriveConnectorSlug(a,e.agentName),i=await r.ensureVercelProject({appRoot:a,prompter:e.ui.prompter,signal:e.signal}),s=await r.provisionConnector({credentials:o,log:e.ui.prompter.log,project:i,projectRoot:a,slug:n,signal:e.signal});await r.writeTextFile(t,connectTemplate(s.uid),{force:e.force})}else await r.appendEnv(join(a,`.env.local`),{IMESSAGE_PROJECT_ID:o.projectId,IMESSAGE_PROJECT_SECRET:o.projectSecret}),await r.writeTextFile(t,`import { photonIMessageChannel } from "eve/channels/photon";
|
|
8
|
+
|
|
9
|
+
async function photonCredentials() {
|
|
10
|
+
const projectId = process.env.IMESSAGE_PROJECT_ID;
|
|
11
|
+
const projectSecret = process.env.IMESSAGE_PROJECT_SECRET;
|
|
12
|
+
if (!projectId || !projectSecret) throw new Error("Photon project credentials are required.");
|
|
13
|
+
return { projectId, projectSecret };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default photonIMessageChannel({
|
|
17
|
+
credentials: photonCredentials,
|
|
18
|
+
webhookSecret: process.env.IMESSAGE_WEBHOOK_SECRET,
|
|
19
|
+
});
|
|
20
|
+
`,{force:e.force}),e.ui.nextSteps([`Deploy the agent, then create a Photon webhook pointing to https://<your-host>/eve/v1/photon.`,`Copy the webhook signing secret into IMESSAGE_WEBHOOK_SECRET, alongside IMESSAGE_PROJECT_ID and IMESSAGE_PROJECT_SECRET, in your host's encrypted environment variables.`]);e.ui.prompter.log.success(`Scaffolded channel: photon`),o.assignedPhoneNumber!==void 0&&e.ui.prompter.note(o.assignedPhoneNumber,`Text your agent`,{tone:`success`});let i=`https://app.photon.codes/dashboard/${o.projectId}`;return e.ui.prompter.note(i,`Photon project`,{tone:`success`}),o.assignedPhoneNumber===void 0?{dashboardUrl:i}:{assignedPhoneNumber:o.assignedPhoneNumber,dashboardUrl:i}}catch(e){throw await o.cleanup().catch(()=>{}),e}}async function setupPhoton(e){try{let t=await chooseSetupPlan(e);return t===`cancelled`?{kind:`cancelled`}:{kind:`done`,...await scaffoldPhoton(e,t,e.deps??defaultDeps)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}export{setupPhoton};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{setupPhoton}from"./setup-flow.js";import{basename}from"node:path";const PHOTON_SETUP={kind:`photon`,label:`Photon`,hint:`Messages through Photon`,async setup(e){let t=await setupPhoton({agentName:basename(e.appRoot),projectPath:e.appRoot,environment:e.environment,ui:e.ui,signal:e.signal,force:e.force});return t.kind===`cancelled`?t:{kind:`done`,facts:[...t.assignedPhoneNumber===void 0?[]:[{label:`Text your agent`,value:t.assignedPhoneNumber,kind:`phone`}],{label:`Photon project`,value:t.dashboardUrl,kind:`url`}]}}};export{PHOTON_SETUP};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SetupIntegration } from "./types.js";
|
|
2
|
+
/** Built-in registry setup integrations in canonical picker order. */
|
|
3
|
+
export declare const SETUP_INTEGRATIONS: readonly SetupIntegration[];
|
|
4
|
+
/** Resolves one built-in setup integration by its registry setup name. */
|
|
5
|
+
export declare function setupIntegration(kind: string): SetupIntegration;
|
|
6
|
+
export { createIntegrationSetupUi } from "./shared/ui.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{PHOTON_SETUP}from"./photon/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createIntegrationSetupUi}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,SLACK_SETUP,PHOTON_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createIntegrationSetupUi,setupIntegration};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RegistrySetupFact } from "#setup/registry-setup-protocol.js";
|
|
2
|
+
import { detectDeployment } from "#setup/project-resolution.js";
|
|
3
|
+
import type { Prompter } from "#setup/prompter.js";
|
|
4
|
+
import { getVercelAuthStatus } from "#setup/vercel-project.js";
|
|
5
|
+
/** Inputs shared by every registry-owned integration setup flow. */
|
|
6
|
+
export interface RunIntegrationSetupOptions {
|
|
7
|
+
appRoot: string;
|
|
8
|
+
prompter: Prompter;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Effects shared by the built-in integration setup runner. */
|
|
13
|
+
export interface IntegrationSetupRunnerDeps {
|
|
14
|
+
detectDeployment: typeof detectDeployment;
|
|
15
|
+
getVercelAuthStatus: typeof getVercelAuthStatus;
|
|
16
|
+
}
|
|
17
|
+
/** Outcome returned by one registry-owned integration setup flow. */
|
|
18
|
+
export type IntegrationSetupOutcome = {
|
|
19
|
+
kind: "cancelled";
|
|
20
|
+
} | {
|
|
21
|
+
kind: "done";
|
|
22
|
+
facts?: readonly RegistrySetupFact[];
|
|
23
|
+
};
|
|
24
|
+
/** Runs one built-in integration setup flow selected by its registry setup name. */
|
|
25
|
+
export declare function runIntegrationSetup(kind: string, options: RunIntegrationSetupOptions, deps?: IntegrationSetupRunnerDeps): Promise<IntegrationSetupOutcome>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createIntegrationSetupUi}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.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);t.prompter.intro(`Set up ${r.label}`),t.prompter.log.message(`Checking Vercel setup...`);let[i,a]=await Promise.all([n.detectDeployment(t.appRoot,{signal:t.signal}),n.getVercelAuthStatus(t.appRoot,{signal:t.signal})]),o=integrationSetupEnvironment(a,projectResolutionFromDeployment(i));return t.prompter.log.info(describeIntegrationSetupEnvironment(o)),await r.setup({environment:o,appRoot:t.appRoot,ui:createIntegrationSetupUi({asker:interactiveAsker(t.prompter),prompter:t.prompter}),yes:t.yes,signal:t.signal})}export{runIntegrationSetup};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ProjectResolution } from "../../project-resolution.js";
|
|
2
2
|
import type { VercelAuthStatus } from "../../vercel-project.js";
|
|
3
3
|
/** Read-only hosting facts available to channel-owned setup hooks. */
|
|
4
|
-
export interface
|
|
4
|
+
export interface IntegrationSetupEnvironment {
|
|
5
5
|
vercel: {
|
|
6
6
|
kind: "available";
|
|
7
7
|
project: ProjectResolution;
|
|
@@ -11,6 +11,6 @@ export interface ChannelSetupEnvironment {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
/** Describes the result of the read-only Vercel capability probe. */
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function describeIntegrationSetupEnvironment(environment: IntegrationSetupEnvironment): string;
|
|
15
15
|
/** Builds channel setup facts from the independent Vercel probes. */
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function integrationSetupEnvironment(authStatus: VercelAuthStatus, project: ProjectResolution): IntegrationSetupEnvironment;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function describeIntegrationSetupEnvironment(e){if(e.vercel.kind===`available`)switch(e.vercel.project.kind){case`deployed`:return`Found an authenticated Vercel account and deployed project (${e.vercel.project.productionUrl}).`;case`linked`:return`Found an authenticated Vercel account and linked project.`;case`unresolved`:return`Found an authenticated Vercel account; this directory is not linked to a project.`}switch(e.vercel.reason){case`logged-out`:return`No authenticated Vercel account found; choose Vercel Connect or portable credentials.`;case`cli-missing`:return`Vercel CLI not found; choose Vercel Connect or portable credentials.`;case`unavailable`:return`Could not verify the Vercel account; choose Vercel Connect or portable credentials.`}}function integrationSetupEnvironment(e,t){return e===`authenticated`?{vercel:{kind:`available`,project:t}}:{vercel:{kind:`unavailable`,reason:e}}}export{describeIntegrationSetupEnvironment,integrationSetupEnvironment};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
|
+
import { detectPackageManager } from "#setup/package-manager.js";
|
|
3
|
+
import { runPackageManagerInstall } from "#setup/primitives/pm/run.js";
|
|
4
|
+
/** Effects used to install dependencies added by an integration scaffold. */
|
|
5
|
+
export interface IntegrationScaffoldDeps {
|
|
6
|
+
detectPackageManager: typeof detectPackageManager;
|
|
7
|
+
runPackageManagerInstall: typeof runPackageManagerInstall;
|
|
8
|
+
}
|
|
9
|
+
/** Installs dependencies added by an integration scaffold without failing setup if installation fails. */
|
|
10
|
+
export declare function installScaffoldDependencies(input: {
|
|
11
|
+
changed: boolean;
|
|
12
|
+
log: ChannelSetupLog;
|
|
13
|
+
projectPath: string;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
skip?: boolean;
|
|
16
|
+
deps?: IntegrationScaffoldDeps;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
/** Reports files overwritten by one integration scaffold. */
|
|
19
|
+
export declare function reportOverwrittenFiles(log: ChannelSetupLog, files: readonly string[] | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{detectPackageManager}from"#setup/package-manager.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{runPackageManagerInstall}from"#setup/primitives/pm/run.js";const defaultDeps={detectPackageManager,runPackageManagerInstall};async function installScaffoldDependencies(e){if(!e.changed||e.skip)return;let r=e.deps??defaultDeps,i=await r.detectPackageManager(e.projectPath);await withPhase(e.log,`Installing channel dependencies (${i.kind} install)...`,()=>r.runPackageManagerInstall(i.kind,e.projectPath,{onOutput:createPromptCommandOutput(e.log),signal:e.signal}))||e.log.warning(`Dependency installation failed. The new channel stays unloadable until \`${i.kind} install\` or a deploy succeeds.`)}function reportOverwrittenFiles(e,t){for(let n of t??[])e.warning(`Overwrote ${n}`)}export{installScaffoldDependencies,reportOverwrittenFiles};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Asker } from "../../ask.js";
|
|
2
2
|
import type { Prompter } from "../../prompter.js";
|
|
3
3
|
/** UI capabilities available to a channel-owned setup hook. */
|
|
4
|
-
export interface
|
|
4
|
+
export interface IntegrationSetupUi {
|
|
5
5
|
readonly asker: Asker;
|
|
6
6
|
readonly prompter: Prompter;
|
|
7
7
|
confirm(input: {
|
|
@@ -12,7 +12,7 @@ export interface ChannelSetupUi {
|
|
|
12
12
|
nextSteps(lines: readonly string[]): void;
|
|
13
13
|
}
|
|
14
14
|
/** Adapts the shared setup asker and prompter to the channel hook UI. */
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function createIntegrationSetupUi(input: {
|
|
16
16
|
asker: Asker;
|
|
17
17
|
prompter: Prompter;
|
|
18
|
-
}):
|
|
18
|
+
}): IntegrationSetupUi;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{SkippedSignal,confirm}from"../../ask.js";function createIntegrationSetupUi(n){return{...n,async confirm(r){try{return await n.asker.ask(confirm(r))}catch(t){if(t instanceof SkippedSignal)return!1;throw t}},nextSteps(e){e.length!==0&&n.prompter.note(e.join(`
|
|
2
|
+
`),`Next steps`,{tone:`success`})}}}export{createIntegrationSetupUi};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { deriveSlackConnectorSlug, ensureChannel } from "#setup/scaffold/index.js";
|
|
2
|
+
import { ensureVercelProject } from "#setup/flows/ensure-vercel-project.js";
|
|
3
|
+
import { provisionSlackbot, reconcileSlackUid } from "#setup/slackbot.js";
|
|
4
|
+
import type { IntegrationSetupContext, IntegrationSetupResult, SetupIntegration } from "../types.js";
|
|
5
|
+
/** Effects used by Slack setup. */
|
|
6
|
+
export interface SlackSetupDeps {
|
|
7
|
+
deriveSlackConnectorSlug: typeof deriveSlackConnectorSlug;
|
|
8
|
+
ensureChannel: typeof ensureChannel;
|
|
9
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
10
|
+
provisionSlackbot: typeof provisionSlackbot;
|
|
11
|
+
reconcileSlackUid: typeof reconcileSlackUid;
|
|
12
|
+
}
|
|
13
|
+
/** Runs the Slack setup flow. Exported for direct integration tests. */
|
|
14
|
+
export declare function setupSlack(context: IntegrationSetupContext, deps?: SlackSetupDeps): Promise<IntegrationSetupResult>;
|
|
15
|
+
/** Slack setup registration. */
|
|
16
|
+
export declare const SLACK_SETUP: SetupIntegration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,ensureVercelProject,provisionSlackbot,reconcileSlackUid};async function chooseCredentials(e){if(e.yes)return`vercel-connect`;try{return await e.ui.prompter.select({message:`How would you like to configure Slack?`,options:[{value:`vercel`,label:`Set up Vercel Connect`,hint:`Sign in and link this project`},{value:`portable`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}]})===`portable`?`environment`:`vercel-connect`}catch(e){if(e instanceof WizardCancelledError)return`cancelled`;throw e}}async function provisionSlack(e,t,n){let r={selectConnector:async(t,n)=>{if(e.yes)return n??t[0];let r=await e.ui.prompter.select({message:`Which Slack app would you like to use?`,options:[...t.map(e=>{let t={value:e.uid,label:`Use ${e.uid}`};return e.uid===n?.uid&&(t.hint=`Matches this agent`),t}),{value:`create`,label:`Create a new Slack app`}],initialValue:n?.uid});return r===`create`?`create`:t.find(e=>e.uid===r)}};e.signal!==void 0&&(r.signal=e.signal),e.ui.prompter.awaitChoice!==void 0&&(r.awaitChoice=e.ui.prompter.awaitChoice);let a=await t.provisionSlackbot(e.ui.prompter.log,e.appRoot,n,void 0,r);if(e.signal?.throwIfAborted(),a.state===`cancelled`)throw new WizardCancelledError;if(a.state!==`attached`){let e=slackbotFailureCopy(a);throw Error(`${e.reason} ${e.followUp}`)}return a}async function setupSlack(n,r=defaultDeps){let i=await chooseCredentials(n);if(i===`cancelled`)return{kind:`cancelled`};if(i===`vercel-connect`&&n.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Slack setup.");let a=await r.deriveSlackConnectorSlug(n.appRoot);if(i===`environment`){let e=await r.ensureChannel({projectRoot:n.appRoot,kind:`slack`,slackConnectorSlug:a,slackCredentials:`environment`,force:n.force,skipDependencyMutation:!0});return reportOverwrittenFiles(n.ui.prompter.log,e.filesOverwritten),n.ui.prompter.log.success(`Scaffolded channel: slack`),n.ui.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),{kind:`done`}}if((await r.ensureVercelProject({appRoot:n.appRoot,prompter:n.ui.prompter,signal:n.signal})).projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let o=await provisionSlack(n,r,a),s=await r.ensureChannel({projectRoot:n.appRoot,kind:`slack`,slackConnectorUid:o.connectorUid,slackConnectorSlug:a,force:n.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(n.ui.prompter.log,s.filesOverwritten),s.action===`skipped`&&!await r.reconcileSlackUid(n.ui.prompter.log,n.appRoot,o,`slack/${a}`))throw Error(`Slack connector UID update is required before deployment.`);return n.ui.prompter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:s.packageJsonUpdated.length>0,log:n.ui.prompter.log,projectPath:n.appRoot,signal:n.signal}),{kind:`done`}}const SLACK_SETUP={kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,setup:setupSlack};export{SLACK_SETUP,setupSlack};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RegistrySetupFact } from "#setup/registry-setup-protocol.js";
|
|
2
|
+
import type { IntegrationSetupEnvironment } from "./shared/environment.js";
|
|
3
|
+
import type { IntegrationSetupUi } from "./shared/ui.js";
|
|
4
|
+
/** Inputs available to one registry-owned integration setup flow. */
|
|
5
|
+
export interface IntegrationSetupContext {
|
|
6
|
+
readonly appRoot: string;
|
|
7
|
+
readonly environment: IntegrationSetupEnvironment;
|
|
8
|
+
readonly ui: IntegrationSetupUi;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
readonly force?: boolean;
|
|
11
|
+
readonly yes?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Outcome from one registry-owned integration setup flow. */
|
|
14
|
+
export type IntegrationSetupResult = {
|
|
15
|
+
readonly kind: "done";
|
|
16
|
+
readonly facts?: readonly RegistrySetupFact[];
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: "cancelled";
|
|
19
|
+
};
|
|
20
|
+
/** One built-in registry-owned integration setup flow. */
|
|
21
|
+
export interface SetupIntegration {
|
|
22
|
+
readonly kind: string;
|
|
23
|
+
readonly label: string;
|
|
24
|
+
readonly hint?: string;
|
|
25
|
+
setup(context: IntegrationSetupContext): Promise<IntegrationSetupResult>;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{ensureChannel}from"#setup/scaffold/index.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectPackageManager}from"#setup/package-manager.js";function reportCompetingNextConfigFiles(e,t){for(let n of t??[])e.warning(`Found competing Next.js config at ${n}; merge any needed settings into next.config.ts and remove it before starting the preview, or Next.js may ignore the generated eve rewrite.`)}const WEB_SETUP={kind:`web`,label:`Web Chat`,hint:`Browser-based chat interface`,async setup(r){r.ui.prompter.log.message(`Scaffolding Web Chat channel files...`);let i=await ensureChannel({projectRoot:r.appRoot,kind:`web`,packageManager:(await detectPackageManager(r.appRoot)).kind,configureVercelServices:r.environment.vercel.kind===`available`,force:r.force,skipDependencyMutation:!0});return reportOverwrittenFiles(r.ui.prompter.log,i.filesOverwritten),i.kind===`web`&&i.action!==`skipped`&&i.nodeEngineOverride!==void 0&&r.ui.prompter.log.warning(formatNodeEngineOverrideWarning(i.nodeEngineOverride)),reportCompetingNextConfigFiles(r.ui.prompter.log,`competingNextConfigFiles`in i?i.competingNextConfigFiles:void 0),i.action===`skipped`?(r.ui.prompter.log.info(`Next.js project detected. Skipping Web Chat scaffolding.`),{kind:`done`}):(r.ui.prompter.log.success(`Scaffolded channel: web`),await installScaffoldDependencies({changed:i.packageJsonUpdated.length>0,log:r.ui.prompter.log,projectPath:r.appRoot,signal:r.signal}),{kind:`done`})}};export{WEB_SETUP};
|
|
@@ -5,6 +5,8 @@ export interface RunVercelOptions {
|
|
|
5
5
|
extraEnv?: Readonly<Record<string, string>>;
|
|
6
6
|
/** Pass `--non-interactive` and close stdin so automation cannot stop on a prompt. */
|
|
7
7
|
nonInteractive?: boolean;
|
|
8
|
+
/** UTF-8 data written to stdin, used to keep connector secrets out of argv. */
|
|
9
|
+
stdin?: string;
|
|
8
10
|
/** Streams command output to a parent-owned renderer instead of writing outside it. */
|
|
9
11
|
onOutput?: ProcessOutputHandler;
|
|
10
12
|
/** Aborts the Vercel CLI subprocess when its parent setup flow is interrupted. */
|
|
@@ -73,12 +75,5 @@ export type VercelCaptureResult = {
|
|
|
73
75
|
ok: false;
|
|
74
76
|
failure: VercelCaptureFailure;
|
|
75
77
|
};
|
|
76
|
-
/**
|
|
77
|
-
* Runs a Vercel CLI lookup and captures stdout.
|
|
78
|
-
*
|
|
79
|
-
* stderr is always captured so a failure's diagnostic survives, even with no
|
|
80
|
-
* live `onOutput` renderer attached; when `onOutput` is supplied, stderr is
|
|
81
|
-
* streamed to it and the failure summary is appended after a non-zero exit.
|
|
82
|
-
*/
|
|
83
78
|
export declare function captureVercel(args: string[], options: RunVercelOptions): Promise<VercelCaptureResult>;
|
|
84
79
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withoutCodingAgentMarkers}from"./coding-agent-env.js";import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{accessSync,constants,existsSync,statSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`}
|
|
1
|
+
import{withoutCodingAgentMarkers}from"./coding-agent-env.js";import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{accessSync,constants,existsSync,statSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`};function buildSpawnEnv(t){return{...withoutCodingAgentMarkers(process.env),...CONNECT_FEATURE_FLAG_ENV,...t}}function commandArgs(e,t){return!t||e.includes(`--non-interactive`)?e:[...e,`--non-interactive`]}function existingDir(e){let t=resolve(e);for(;!existsSync(t);){let e=dirname(t);if(e===t)break;t=e}return t}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function abortMessage(e){return`vercel ${e.join(` `)} was aborted.`}function isAbortError(e,t){return t?.aborted===!0||e.name===`AbortError`||e.code===`ABORT_ERR`}function ancestorDirectories(e){let t=[],n=resolve(e);for(;;){t.push(n);let e=dirname(n);if(e===n)return t;n=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function vercelExecutableNames(e){return e===`win32`?[`vercel.cmd`,`vercel.exe`]:[`vercel`]}function findLocalVercel(e,t){for(let n of ancestorDirectories(e))for(let e of vercelExecutableNames(t)){let t=findExecutable(join(n,`node_modules`,`.bin`,e));if(t!==void 0)return t}}function resolveVercelInvocation(e,t=[],n=process.platform){let r=findLocalVercel(e,n);return n===`win32`?{command:r??`vercel`,commandArgs:t,shell:!0}:r===void 0?{command:`vercel`,commandArgs:t}:{command:r,commandArgs:t}}function stdinMode(e){return e.stdin===void 0?e.nonInteractive?`ignore`:`inherit`:`pipe`}function writeStdin(e,t,n){t===void 0||e.stdin===null||(e.stdin.once(`error`,n),e.stdin.end(t,`utf8`))}function stdioForRun(e){return e.onOutput||e.stdin!==void 0?[stdinMode(e),`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}function runVercelProcess(e,r,i){return r.signal?.aborted===!0?Promise.resolve(i.result({ok:!1,stdout:``,stderr:``,errno:`ABORT_ERR`,message:abortMessage(e)})):new Promise(a=>{let o=existingDir(r.cwd),s=resolveVercelInvocation(o,commandArgs(e,r.nonInteractive)),c=r.onOutput&&createProcessOutputBuffer(r.onOutput),l=spawn(s.command,s.commandArgs,{cwd:o,stdio:i.stdio,env:buildSpawnEnv(r.extraEnv??{}),shell:s.shell,signal:r.signal}),u=armProcessAbort(l,r.signal),d=[],f=[];l.stdout?.on(`data`,e=>{i.capture?d.push(e.toString(`utf8`)):c?.write(`stdout`,e)}),l.stderr?.on(`data`,e=>{i.capture&&f.push(e.toString(`utf8`)),c?.write(`stderr`,e)});let p=!1;function settle(e,t){p||(p=!0,c?.flush(),t&&!e.ok&&(r.onOutput===void 0?i.reportWithoutRenderer&&process.stderr.write(`\n${e.message}\n`):r.onOutput({stream:`stderr`,text:e.message})),a(i.result(e)))}function captured(){return{stdout:d.join(``),stderr:f.join(``)}}function fail(e,t=!0){settle({ok:!1,...captured(),...e},t)}let m=armDeadline(l,r.timeoutMs,()=>{fail({code:null,message:timeoutMessage(e,r.timeoutMs??0)})});writeStdin(l,r.stdin,t=>{fail({errno:t.code,message:`vercel ${e.join(` `)} stdin failed: ${t.message}`})}),l.on(`error`,t=>{isAbortError(t,r.signal)||(u(),m(),fail({errno:t.code,message:t.code===`ENOENT`?`Vercel CLI not found. Install with: npm i -g vercel@latest`:`vercel ${e.join(` `)} failed: ${t.message}`}))}),l.on(`close`,t=>{if(u(),m(),r.signal?.aborted===!0){fail({code:t,errno:`ABORT_ERR`,message:abortMessage(e)},!1);return}if(t===0){settle({ok:!0,...captured()},!1);return}fail(t===null?{code:t,message:abortMessage(e)}:{code:t,message:`vercel ${e.join(` `)} exited with code ${t}.`},t!==null)})})}async function runVercel(e,t){return runVercelProcess(e,t,{stdio:stdioForRun(t),capture:!1,reportWithoutRenderer:!0,result:e=>e.ok})}async function runVercelCaptureStdout(e,t){return runVercelProcess(e,t,{stdio:[stdinMode(t),`pipe`,t.onOutput?`pipe`:`inherit`],capture:!0,reportWithoutRenderer:!0,result:({ok:e,stdout:t,stderr:n})=>n.length===0?{ok:e,stdout:t}:{ok:e,stdout:t,stderr:n}})}function toCaptureFailure(e){let t={stdout:e.stdout,stderr:e.stderr,message:e.message};return e.code!==void 0&&(t.code=e.code),e.errno!==void 0&&(t.errno=e.errno),t}async function captureVercel(e,t){return runVercelProcess(e,t,{stdio:[t.stdin===void 0?`ignore`:`pipe`,`pipe`,`pipe`],capture:!0,reportWithoutRenderer:!1,result:e=>e.ok?{ok:!0,stdout:e.stdout}:{ok:!1,failure:toCaptureFailure(e)}})}export{captureVercel,resolveVercelInvocation,runVercel,runVercelCaptureStdout};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.38`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.
|
|
1
|
+
import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.38`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.3`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
|
|
@@ -1,4 +1,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{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.
|
|
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.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.29.3`,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=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.
|
|
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.3`),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};
|
|
@@ -4,7 +4,7 @@ import { slackChannel } from "eve/channels/slack";
|
|
|
4
4
|
export default slackChannel({
|
|
5
5
|
credentials: connectSlackCredentials(${JSON.stringify(e)}),
|
|
6
6
|
});
|
|
7
|
-
`}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,s=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,s,r,e.onWorkspaceRootMutation,!e.skipDependencyMutation),u=[],f=[],p=[],m=[],_=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?u.push(t):m.push(t)}let v=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:s,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(u.push(...v.filesWritten),m.push(...v.filesSkipped),!e.skipDependencyMutation)for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let r=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(r)){m.push(r);continue}let o=await pathExists(r);await writeTextFile(r,renderWebAppTemplate(n,_),{force:!0}),u.push(r),o&&f.push(r)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let y=[...new Set(u)],b=[...new Set(m)].filter(e=>!y.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:y,filesSkipped:b,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(t){let n=join(t.projectRoot,`agent/channels/slack.ts`),r=await pathExists(n);if(!t.force&&r)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[n],packageJsonUpdated:[]};let s=t.slackCredentials??`vercel-connect`,c=t.slackConnectorSlug??await deriveSlackConnectorSlug(t.projectRoot),l,u=[],d=[n],f=[],p;if(s===`vercel-connect`){if(!t.skipDependencyMutation){let e=resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.
|
|
7
|
+
`}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,s=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,s,r,e.onWorkspaceRootMutation,!e.skipDependencyMutation),u=[],f=[],p=[],m=[],_=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?u.push(t):m.push(t)}let v=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:s,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(u.push(...v.filesWritten),m.push(...v.filesSkipped),!e.skipDependencyMutation)for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let r=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(r)){m.push(r);continue}let o=await pathExists(r);await writeTextFile(r,renderWebAppTemplate(n,_),{force:!0}),u.push(r),o&&f.push(r)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let y=[...new Set(u)],b=[...new Set(m)].filter(e=>!y.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:y,filesSkipped:b,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(t){let n=join(t.projectRoot,`agent/channels/slack.ts`),r=await pathExists(n);if(!t.force&&r)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[n],packageJsonUpdated:[]};let s=t.slackCredentials??`vercel-connect`,c=t.slackConnectorSlug??await deriveSlackConnectorSlug(t.projectRoot),l,u=[],d=[n],f=[],p;if(s===`vercel-connect`){if(!t.skipDependencyMutation){let e=resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`);u=await ensurePackageDependency(join(t.projectRoot,`package.json`),`@vercel/connect`,e)}l=buildSlackConnectTemplate(t.slackConnectorUid??`slack/${c}`)}else{l=`import { slackChannel } from "eve/channels/slack";
|
|
8
8
|
|
|
9
9
|
export default slackChannel();
|
|
10
10
|
`;let n=join(t.projectRoot,`.env.example`);p={path:n,...await pathExists(n)?{content:await readFile(n,`utf8`)}:{}},(await appendEnv(n,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?d.push(n):f.push(n)}try{await writeTextFile(n,l,{force:t.force})}catch(e){throw p!==void 0&&(p.content===void 0?await unlink(p.path):await writeFile(p.path,p.content,`utf8`)),e}let m={kind:`slack`,action:r?`overwritten`:`created`,filesWritten:d,filesSkipped:f,packageJsonUpdated:u,slackConnectorSlug:c};return r&&(m.filesOverwritten=[n]),m}async function listAuthoredChannels(e){let t=join(e,`agent/channels`),i;try{i=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let e of i){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&a.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(e.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
|
|
@@ -1,4 +1,4 @@
|
|
|
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.
|
|
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.3`,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";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { type ConnectTriggerAttachmentResult } from "#setup/connect-provisioning.js";
|
|
1
2
|
import { createPromptCommandOutput, type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
3
|
import { captureVercel, runVercel } from "#setup/primitives/run-vercel.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { type RawSlackConnector, type SlackConnectorDetails, type SlackConnectorRef, type SlackWorkspaceConnection } from "./slack-connect.js";
|
|
5
6
|
export declare const CONNECT_LOOKUP_TIMEOUT_MS = 60000;
|
|
6
|
-
export declare const CONNECT_MUTATION_TIMEOUT_MS: number;
|
|
7
7
|
declare const VercelProjectLinkSchema: z.ZodObject<{
|
|
8
8
|
projectId: z.ZodString;
|
|
9
9
|
orgId: z.ZodString;
|
|
@@ -61,13 +61,7 @@ export declare function findSlackConnector(deps: SlackConnectLifecycleDeps, proj
|
|
|
61
61
|
* while an old trigger destination may still exist. A `detach-failed` connector
|
|
62
62
|
* is left in a known-stale state the caller surfaces with manual recovery steps.
|
|
63
63
|
*/
|
|
64
|
-
export type SlackConnectorAttachmentResult =
|
|
65
|
-
state: "attached";
|
|
66
|
-
} | {
|
|
67
|
-
state: "detach-failed";
|
|
68
|
-
} | {
|
|
69
|
-
state: "attach-failed";
|
|
70
|
-
};
|
|
64
|
+
export type SlackConnectorAttachmentResult = ConnectTriggerAttachmentResult;
|
|
71
65
|
/**
|
|
72
66
|
* Replaces the connector's default trigger destination with the eve route:
|
|
73
67
|
* detach the existing destination first, then attach this project. Either
|
|
@@ -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{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{readFile}from"node:fs/promises";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4,
|
|
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{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{readFile}from"node:fs/promises";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";import{CONNECT_MUTATION_TIMEOUT_MS,replaceConnectTrigger}from"#setup/connect-provisioning.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4,VercelProjectLinkSchema=object({projectId:string().min(1),orgId:string().min(1)});async function listSlackConnectors(e,t,n,i){let a=await e.captureVercel([`connect`,`list`,`-F`,`json`,`--all-projects`],{cwd:t,onOutput:n,timeoutMs:CONNECT_LOOKUP_TIMEOUT_MS,signal:i});if(!a.ok)return{state:`failed`,message:a.failure.message};try{let e=JSON.parse(a.stdout);if(typeof e!=`object`||!e)return{state:`failed`,message:`Vercel returned a malformed connector list.`};let t=e;return Array.isArray(t.connectors??t.clients)?{state:`ok`,body:e,connectors:parseSlackConnectors(e)}:{state:`failed`,message:`Vercel returned a malformed connector list.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the connector list.`}}}async function readProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectLinkSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}async function findSlackConnector(e,t,n,r,i,a){let o=await listSlackConnectors(e,t,i,a);if(o.state===`failed`)return o;let s=new Set(o.connectors.map(e=>e.uid));if(n===void 0)return{state:`not-found`,connectorUids:s};let c=o.connectors.filter(e=>e.id!==void 0&&e.projectIds.includes(n)).sort((e,t)=>t.createdAt-e.createdAt).map(({uid:e,id:t})=>({uid:e,id:t}));if(c.length===0)return{state:`not-found`,connectorUids:s};let l=c.find(e=>e.uid===r);return l===void 0?{state:`found`,connectors:c,connectorUids:s}:{state:`found`,connectors:c,preferred:l,connectorUids:s}}async function attachSlackConnector(e,t,n,r,i){return replaceConnectTrigger({connectorUid:n.uid,projectRoot:t,triggerPath:SLACK_CHANNEL_DEFAULT_ROUTE,onOutput:r,signal:i,deps:e})}async function fetchSlackConnectorDetails(e){let t=e.orgId===void 0?``:`?teamId=${encodeURIComponent(e.orgId)}`,r=[`api`,`/v1/connect/connectors/${encodeURIComponent(e.connectorId)}${t}`];e.orgId!==void 0&&r.push(`--scope`,e.orgId);let i=await e.deps.captureVercel(r,{cwd:e.projectRoot,onOutput:e.onOutput,timeoutMs:e.timeoutMs,signal:e.signal});if(!i.ok)return{state:`failed`,message:i.failure.message};try{let t=parseSlackConnectorDetails(JSON.parse(i.stdout));return t?.ref.id===e.connectorId?{state:`found`,details:t}:{state:`failed`,message:`Vercel returned an invalid Slack connector.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the Slack connector.`}}}async function fetchSlackWorkspace(e){let t=await fetchSlackConnectorDetails(e);return t.state===`failed`?t:t.details.workspace===void 0?{state:`pending`}:{state:`connected`,workspace:t.details.workspace}}async function cleanupConnectorUid(e,t){let{log:n,deps:r,projectRoot:i,onOutput:a}=e;return await r.runVercel([`connect`,`remove`,t,`--disconnect-all`,`--yes`],{cwd:i,onOutput:a,timeoutMs:CONNECT_MUTATION_TIMEOUT_MS})?!0:(n.warning(`Could not remove the abandoned Slack connector. Run \`vercel connect remove ${t} --disconnect-all --yes\` to clean it up.`),!1)}async function cleanupConnectorUids(e,t){let n=[];for(let r of new Set(t))await cleanupConnectorUid(e,r)||n.push(r);return n.length===0?{state:`clean`}:{state:`failed`,connectorUids:n}}async function cleanupCreatedAttempt(e,t){if(t.createdRef)return cleanupConnectorUids(e,[t.createdRef.uid]);e.log.warning(`Vercel returned no connector UID for the abandoned Slack Connect request, so eve cannot prove that request was cancelled. No connector was removed; do not retry until the browser request is no longer usable.`);let n=await listSlackConnectors(e.deps,e.projectRoot,e.onOutput);return n.state===`failed`?{state:`failed`,connectorUids:[]}:{state:`failed`,connectorUids:n.connectors.map(e=>e.uid).filter(e=>(e===t.expectedUid||e.startsWith(`${t.expectedUid}-`))&&!t.baselineConnectorUids.has(e))}}export{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackConnectorDetails,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink};
|
|
@@ -147,8 +147,6 @@ export interface SetupState {
|
|
|
147
147
|
setupMode: SetupMode;
|
|
148
148
|
modelId: string;
|
|
149
149
|
modelWiring: WiringMode;
|
|
150
|
-
/** Channels chosen in the interview phase; scaffolded later by the channels box. */
|
|
151
|
-
channelSelection: ChannelKind[];
|
|
152
150
|
/** Connections planned in the interview phase; scaffolded later by the connections box. */
|
|
153
151
|
connectionSelection: ConnectionPlan[];
|
|
154
152
|
/** Decided once by the resolve-provisioning box; executed later by the link box. */
|
|
@@ -158,20 +156,10 @@ export interface SetupState {
|
|
|
158
156
|
projectPath: ResolvedProjectPath;
|
|
159
157
|
aiGatewayCredentials: ResolvedAiGatewayCredentials;
|
|
160
158
|
chat: ChatPreference | null;
|
|
161
|
-
/** Channels scaffolded so far in this run. */
|
|
162
|
-
channels: ChannelKind[];
|
|
163
|
-
webScaffolded: boolean;
|
|
164
|
-
slackScaffolded: boolean;
|
|
165
159
|
deploymentDependenciesInstalled: boolean;
|
|
166
160
|
/** The linked Vercel project facts, from the link box or the on-disk `.vercel` link. */
|
|
167
161
|
project: ProjectResolution;
|
|
168
162
|
deploymentPending: boolean;
|
|
169
|
-
slackbotCreated: boolean;
|
|
170
|
-
slackbotAttached: boolean;
|
|
171
|
-
slackConnectorUid: string | undefined;
|
|
172
|
-
/** Deep link that opens a DM compose with the bot ("chat with your agent"). */
|
|
173
|
-
slackChatUrl: string | undefined;
|
|
174
|
-
slackWorkspaceName: string | undefined;
|
|
175
163
|
}
|
|
176
164
|
export declare function createDefaultSetupState(): SetupState;
|
|
177
165
|
/**
|
package/dist/src/setup/state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isProjectResolved}from"./project-resolution.js";import{CURRENT_DIRECTORY_PROJECT_NAME}from"#setup/scaffold/index.js";function createDefaultSetupState(){return{
|
|
1
|
+
import{isProjectResolved}from"./project-resolution.js";import{CURRENT_DIRECTORY_PROJECT_NAME}from"#setup/scaffold/index.js";function createDefaultSetupState(){return{deploymentDependenciesInstalled:!1,project:{kind:`unresolved`},deploymentPending:!1,agentName:``,setupMode:`complete`,modelId:``,modelWiring:`gateway`,connectionSelection:[],vercelProject:{kind:`none`},aiGateway:{kind:`inherit`},projectPath:{kind:`unresolved`,inPlace:!1},aiGatewayCredentials:{kind:`unresolved`},chat:null}}function hasVercelProject(t){return t.vercelProject.kind!==`none`||isProjectResolved(t.project)}function requireProjectPath(e){if(e.projectPath.kind===`resolved`)return e.projectPath.path;throw Error(`Project path has not been resolved.`)}function snapshotSetupState(e){return Object.freeze({...e,aiGatewayCredentials:Object.freeze({...e.aiGatewayCredentials}),aiGateway:Object.freeze({...e.aiGateway}),connectionSelection:Object.freeze([...e.connectionSelection]),project:Object.freeze({...e.project}),projectPath:Object.freeze({...e.projectPath}),vercelProject:Object.freeze({...e.vercelProject})})}export{CURRENT_DIRECTORY_PROJECT_NAME,createDefaultSetupState,hasVercelProject,requireProjectPath,snapshotSetupState};
|
|
@@ -12,6 +12,16 @@ export declare function formatFallbackSkillPath(input: {
|
|
|
12
12
|
export declare function resolveSandboxSkillRoot(input: {
|
|
13
13
|
readonly sandbox: SandboxSession;
|
|
14
14
|
}): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves a leading `$HOME` in a model-supplied sandbox path without
|
|
17
|
+
* evaluating any other shell syntax. Skill paths retain their documented
|
|
18
|
+
* `/workspace/skills` fallback when the sandbox does not expose a usable
|
|
19
|
+
* home directory.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSandboxModelPath(input: {
|
|
22
|
+
readonly path: string;
|
|
23
|
+
readonly sandbox: SandboxSession;
|
|
24
|
+
}): Promise<string>;
|
|
15
25
|
export declare function resolveSandboxSkillReadPaths(input: {
|
|
16
26
|
readonly name: string;
|
|
17
27
|
readonly relativePath: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const MODEL_SKILL_ROOT=`$HOME/.agents/skills`,FALLBACK_SKILL_ROOT=`/workspace/skills`,
|
|
2
|
-
`)&&!e.includes(`\r`)}function joinHomeSkillRoot(e){return`${e===`/`?``:e
|
|
1
|
+
const MODEL_SKILL_ROOT=`$HOME/.agents/skills`,FALLBACK_SKILL_ROOT=`/workspace/skills`,MODEL_HOME_ROOT=`$HOME`,sandboxHomeCache=new WeakMap;function formatSkillModelPath(t){return formatSkillPath({name:t.name,relativePath:t.relativePath,root:MODEL_SKILL_ROOT})}function formatFallbackSkillPath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:FALLBACK_SKILL_ROOT})}async function resolveSandboxSkillRoot(e){let n=await resolveSandboxHome(e.sandbox);return n===null?FALLBACK_SKILL_ROOT:joinHomeSkillRoot(n)}async function resolveSandboxModelPath(e){if(!isModelHomePath(e.path))return e.path;let n=await resolveSandboxHome(e.sandbox);if(n!==null){let t=e.path.slice(5);return t.length===0?n:`${n===`/`?``:n}${t}`}return isModelSkillPath(e.path)?`${FALLBACK_SKILL_ROOT}${e.path.slice(20)}`:e.path}async function resolveSandboxSkillReadPaths(e){return[formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})]}async function resolveSandboxSkillWritePath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})}async function resolveSandboxSeedFilePath(e){return isModelSkillPath(e.path)?await resolveSandboxModelPath(e):e.path}function formatSkillPath(e){return`${e.root}/${e.name}/${e.relativePath}`}async function resolveSandboxHome(e){let t=sandboxHomeCache.get(e);if(t!==void 0)return await t;let n=probeSandboxHome(e);return sandboxHomeCache.set(e,n),await n}async function probeSandboxHome(e){try{let t=await e.run({command:`printf '%s\\n' "$HOME"`});if(t.exitCode!==0)return null;let n=t.stdout.trim();return isUsableSandboxHome(n)?normalizeSandboxHome(n):null}catch{return null}}function isModelHomePath(e){return e===MODEL_HOME_ROOT||e.startsWith(`${MODEL_HOME_ROOT}/`)}function isModelSkillPath(e){return e===`$HOME/.agents/skills`||e.startsWith(`$HOME/.agents/skills/`)}function isUsableSandboxHome(e){return e.length>0&&e.startsWith(`/`)&&!e.includes(`\0`)&&!e.includes(`
|
|
2
|
+
`)&&!e.includes(`\r`)}function joinHomeSkillRoot(e){return`${e===`/`?``:e}/.agents/skills`}function normalizeSandboxHome(e){return e===`/`?e:e.replace(/\/+$/,``)}export{FALLBACK_SKILL_ROOT,MODEL_SKILL_ROOT,formatFallbackSkillPath,formatSkillModelPath,resolveSandboxModelPath,resolveSandboxSeedFilePath,resolveSandboxSkillReadPaths,resolveSandboxSkillRoot,resolveSandboxSkillWritePath};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes model and tool payloads into span content attributes for the
|
|
3
|
+
* local trace viewer: prompt messages, the system prompt, responses, and
|
|
4
|
+
* tool arguments/results. Everything is capped so a giant payload cannot
|
|
5
|
+
* bloat a span segment past the reader's per-file limit, and message
|
|
6
|
+
* payloads stay valid JSON through every truncation path.
|
|
7
|
+
*/
|
|
8
|
+
/** Content attributes are capped so a giant payload cannot bloat a span segment. */
|
|
9
|
+
export declare const CONTENT_ATTRIBUTE_LIMIT: number;
|
|
10
|
+
/**
|
|
11
|
+
* Serializes one payload value. `strip` removes {@link CONTENT_NOISE_KEYS};
|
|
12
|
+
* pass `false` for tool data, where those keys may be legitimate domain
|
|
13
|
+
* fields the user authored or the tool returned.
|
|
14
|
+
*/
|
|
15
|
+
export declare function contentAttribute(value: unknown, strip?: boolean): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Serializes the prompt messages, keeping the result parseable: oldest
|
|
18
|
+
* messages drop first behind an omission marker, and a single message over
|
|
19
|
+
* the cap is truncated at the text level rather than the JSON level.
|
|
20
|
+
*/
|
|
21
|
+
export declare function messagesContentAttribute(messages: unknown): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Serializes provider-executed tool results, keeping the attribute valid
|
|
24
|
+
* JSON under the cap: when the full payload is too big, each entry's input
|
|
25
|
+
* and output collapse to capped text at progressively smaller budgets
|
|
26
|
+
* instead of cutting the JSON mid-string.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toolResultsContentAttribute(results: readonly Record<string, unknown>[]): string | undefined;
|
|
29
|
+
/** Normalizes the AI SDK's `instructions` prompt to plain text for `ai.prompt.system`. */
|
|
30
|
+
export declare function systemPromptAttribute(instructions: unknown): string | undefined;
|
|
31
|
+
/** Caps plain text, marking the cut. */
|
|
32
|
+
export declare function textContentAttribute(text: string): string | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const CONTENT_ATTRIBUTE_LIMIT=32*1024,CONTENT_NOISE_KEYS=new Set([`providerOptions`,`providerMetadata`]),TRUNCATED_MESSAGES_KEY=`eve.truncated`;function contentAttribute(e,t=!0){if(e===void 0)return;let n=t?stripContentNoise(e,0):e,r;try{r=JSON.stringify(n)}catch{return}if(r!==void 0)return textContentAttribute(r)}function messagesContentAttribute(e){if(!Array.isArray(e))return contentAttribute(e);let t=stripContentNoise(e,0),r=stringifyContent(t);if(r!==void 0&&r.length<=32768)return r;for(let e=1;e<t.length;e+=1){let r=stringifyContent([{[TRUNCATED_MESSAGES_KEY]:{omittedMessages:e}},...t.slice(e)]);if(r!==void 0&&r.length<=32768)return r}return truncateSingleMessage(t)}function toolResultsContentAttribute(t){if(t.length===0)return;let n=stringifyContent(t);if(n!==void 0&&n.length<=32768)return n;for(let n=CONTENT_ATTRIBUTE_LIMIT;n>=0;n=n>=256?Math.floor(n/2):-1){let e=stringifyContent(t.map(e=>cappedToolResult(e,n)));if(e!==void 0&&e.length<=32768)return e}}function cappedToolResult(e,t){let n={toolName:e.toolName};for(let r of[`input`,`output`,`error`]){if(!(r in e))continue;let i=e[r],a=typeof i==`string`?i:stringifyContent(i)??``;n[r]=a.length<=t?a:`${a.slice(0,t)}… [truncated]`}return n}function systemPromptAttribute(e){if(typeof e==`string`)return textContentAttribute(e);if(!isRecord(e)&&!Array.isArray(e))return;let t=Array.isArray(e)?e:[e],n=[];for(let e of t)if(isRecord(e)){if(typeof e.content==`string`)n.push(e.content);else if(Array.isArray(e.content))for(let t of e.content)isRecord(t)&&t.type===`text`&&typeof t.text==`string`&&n.push(t.text)}let r=n.join(`
|
|
2
|
+
|
|
3
|
+
`).trim();return r.length===0?void 0:textContentAttribute(r)}function textContentAttribute(t){if(t.length!==0)return t.length<=32768?t:`${t.slice(0,CONTENT_ATTRIBUTE_LIMIT)}… [truncated]`}function stripContentNoise(e,n){if(n>32||typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(e=>stripContentNoise(e,n+1));let r={};for(let[i,a]of Object.entries(e))CONTENT_NOISE_KEYS.has(i)||(r[i]=stripContentNoise(a,n+1));return r}function truncateSingleMessage(t){if(t.length===0)return;let r=t[t.length-1];if(!isRecord(r))return;let i={[TRUNCATED_MESSAGES_KEY]:{omittedMessages:t.length-1}},a=typeof r.role==`string`?r.role:`user`,o=``;if(typeof r.content==`string`)o=r.content;else if(Array.isArray(r.content))for(let e of r.content)isRecord(e)&&e.type===`text`&&typeof e.text==`string`&&(o+=(o?`
|
|
4
|
+
`:``)+e.text);for(let t=Math.min(o.length,CONTENT_ATTRIBUTE_LIMIT);t>0;t-=256){let e=stringifyContent([i,{role:a,content:t>=o.length?o:`${o.slice(0,t)}… [truncated]`}]);if(e!==void 0&&e.length<=32768)return e}return stringifyContent([i,{role:a,content:``}])}function stringifyContent(e){try{return JSON.stringify(e)}catch{return}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{CONTENT_ATTRIBUTE_LIMIT,contentAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type SpanContext, type Tracer } from "#compiled/@opentelemetry/api/index.js";
|
|
2
2
|
import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationTurnTerminalEvent } from "#harness/instrumentation-lifecycle.js";
|
|
3
|
+
/** Sized so an ordinary session stays one trace and only an outsized one rolls. */
|
|
4
|
+
export declare const SESSION_WINDOW_TURN_LIMIT = 200;
|
|
3
5
|
export interface AgentSessionTraceState {
|
|
4
6
|
readonly agentName?: string;
|
|
5
7
|
readonly channelKind?: string;
|
|
6
8
|
readonly context: SpanContext;
|
|
7
|
-
readonly pendingStarted: boolean;
|
|
8
9
|
readonly rootSessionId: string;
|
|
10
|
+
readonly turnsInWindow: number;
|
|
11
|
+
readonly window: number;
|
|
9
12
|
}
|
|
10
13
|
export interface AgentTurnTraceState {
|
|
11
14
|
readonly context: SpanContext;
|
|
@@ -36,6 +39,12 @@ export declare class InMemoryAgentTraceStateStore implements AgentTraceStateStor
|
|
|
36
39
|
setTurn(sessionId: string, turnId: string, state: AgentTurnTraceState): void;
|
|
37
40
|
}
|
|
38
41
|
export interface AgentOtelInstrumentationInput {
|
|
42
|
+
/**
|
|
43
|
+
* Capture model prompts/responses and tool call inputs/outputs as span
|
|
44
|
+
* attributes. Content stays on the local machine — this provider only
|
|
45
|
+
* wires the dev-time local spool — but can be turned off per project.
|
|
46
|
+
*/
|
|
47
|
+
readonly captureContent?: boolean;
|
|
39
48
|
readonly frameworkVersion: string;
|
|
40
49
|
readonly stateStore: AgentTraceStateStore;
|
|
41
50
|
readonly tracer: Tracer;
|