eve 0.25.3 → 0.26.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 +23 -0
- package/dist/src/chunks/{use-eve-agent-Cy73lgA6.js → use-eve-agent-BkztZA0v.js} +76 -55
- package/dist/src/chunks/{use-eve-agent-CQIeqmKc.js → use-eve-agent-CruinZmd.js} +76 -55
- package/dist/src/cli/commands/logs-events.d.ts +36 -0
- package/dist/src/cli/commands/logs-events.js +2 -0
- package/dist/src/cli/commands/logs.d.ts +64 -0
- package/dist/src/cli/commands/logs.js +4 -0
- package/dist/src/cli/dev/diagnostic-dump.d.ts +60 -0
- package/dist/src/cli/dev/diagnostic-dump.js +1 -0
- package/dist/src/cli/dev/diagnostic-sink.d.ts +37 -0
- package/dist/src/cli/dev/diagnostic-sink.js +1 -0
- package/dist/src/cli/dev/diagnostics.d.ts +42 -0
- package/dist/src/cli/dev/diagnostics.js +1 -0
- package/dist/src/cli/dev/tui/blocks.d.ts +4 -0
- package/dist/src/cli/dev/tui/blocks.js +7 -7
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/diagnostic-presentation.d.ts +14 -0
- package/dist/src/cli/dev/tui/diagnostic-presentation.js +2 -0
- package/dist/src/cli/dev/tui/errors.d.ts +21 -16
- package/dist/src/cli/dev/tui/errors.js +1 -1
- package/dist/src/cli/dev/tui/line-editor.js +1 -1
- package/dist/src/cli/dev/tui/markdown.js +1 -1
- package/dist/src/cli/dev/tui/model-editor.d.ts +103 -0
- package/dist/src/cli/dev/tui/model-editor.js +1 -0
- package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth-command.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +5 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +3 -0
- package/dist/src/cli/dev/tui/setup-panel.d.ts +33 -0
- package/dist/src/cli/dev/tui/setup-panel.js +4 -4
- package/dist/src/cli/dev/tui/status-line.d.ts +8 -6
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +3 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +11 -10
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
- package/dist/src/cli/dev/tui/theme.d.ts +14 -0
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tool-format.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/run.js +2 -2
- package/dist/src/cli/ui/live-row.js +1 -1
- package/dist/src/client/agent-info-schema.d.ts +9 -0
- package/dist/src/client/agent-info-schema.js +1 -1
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +1 -2
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/open-stream.d.ts +14 -10
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-utils.d.ts +2 -1
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +3 -5
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +0 -6
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +4 -0
- package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-create.js +1 -1
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/model-call-error.d.ts +11 -30
- package/dist/src/harness/model-call-error.js +1 -1
- package/dist/src/harness/semantic-errors/index.d.ts +9 -0
- package/dist/src/harness/semantic-errors/index.js +1 -0
- package/dist/src/harness/semantic-errors/rule.d.ts +76 -0
- package/dist/src/harness/semantic-errors/rule.js +1 -0
- package/dist/src/harness/semantic-errors/rules/gateway.d.ts +11 -0
- package/dist/src/harness/semantic-errors/rules/gateway.js +1 -0
- package/dist/src/harness/semantic-errors/rules/model-provider.d.ts +11 -0
- package/dist/src/harness/semantic-errors/rules/model-provider.js +1 -0
- package/dist/src/harness/semantic-errors/rules/sandbox.d.ts +16 -0
- package/dist/src/harness/semantic-errors/rules/sandbox.js +1 -0
- package/dist/src/harness/semantic-errors/rules/system.d.ts +2 -0
- package/dist/src/harness/semantic-errors/rules/system.js +1 -0
- package/dist/src/harness/semantic-errors/rules/workflow.d.ts +9 -0
- package/dist/src/harness/semantic-errors/rules/workflow.js +1 -0
- package/dist/src/harness/semantic-errors/signals.d.ts +28 -0
- package/dist/src/harness/semantic-errors/signals.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/workflow-sandbox.d.ts +6 -0
- package/dist/src/harness/workflow-sandbox.js +2 -2
- package/dist/src/internal/application/output-publication-lock.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/logging.d.ts +33 -1
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +3 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/workflow/development-world-client.js +1 -1
- package/dist/src/internal/workflow/development-world-server.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/models/openai/chatgpt/model.js +3 -1
- package/dist/src/react/use-eve-agent.d.ts +0 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/setup/boxes/add-channels.js +1 -1
- package/dist/src/setup/boxes/deploy-project.js +1 -1
- package/dist/src/setup/boxes/model-capabilities.d.ts +24 -0
- package/dist/src/setup/boxes/model-capabilities.js +1 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/boxes/select-model.d.ts +30 -8
- package/dist/src/setup/boxes/select-model.js +1 -1
- package/dist/src/setup/cli/option-row.js +1 -1
- package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
- package/dist/src/setup/cli/prompt-ui.js +2 -2
- package/dist/src/setup/cli/rail-log.d.ts +4 -6
- package/dist/src/setup/cli/rail-log.js +3 -2
- package/dist/src/setup/connection-connector.js +2 -2
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model-source-change.d.ts +38 -0
- package/dist/src/setup/flows/model-source-change.js +1 -0
- package/dist/src/setup/flows/model.d.ts +65 -62
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.d.ts +20 -0
- package/dist/src/setup/flows/provider.js +3 -3
- package/dist/src/setup/prompter.d.ts +2 -0
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/slack-connect-lifecycle.js +1 -1
- package/dist/src/setup/slackbot.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +6 -0
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +1 -8
- package/dist/src/shared/errors.d.ts +5 -0
- package/dist/src/shared/errors.js +1 -1
- package/dist/src/shared/gateway-service-tier.d.ts +19 -0
- package/dist/src/shared/gateway-service-tier.js +1 -0
- package/dist/src/shared/model-summary.d.ts +12 -0
- package/dist/src/shared/model-summary.js +1 -0
- package/dist/src/shared/workflow-sandbox.d.ts +2 -0
- package/dist/src/shared/workflow-sandbox.js +1 -1
- package/dist/src/source-change/agent-config-ast.d.ts +54 -0
- package/dist/src/source-change/agent-config-ast.js +2 -0
- package/dist/src/source-change/agent-config-string-path.d.ts +18 -0
- package/dist/src/source-change/agent-config-string-path.js +2 -0
- package/dist/src/source-change/apply-agent-model-settings.d.ts +26 -0
- package/dist/src/source-change/apply-agent-model-settings.js +1 -0
- package/dist/src/source-change/apply-model-name.js +1 -2
- package/dist/src/source-change/static-source-change.d.ts +14 -0
- package/dist/src/source-change/static-source-change.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +0 -6
- 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.d.ts +0 -2
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/execution-model-and-durability.md +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/getting-started.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +1 -1
- package/docs/guides/client/overview.mdx +1 -1
- package/docs/guides/client/streaming.mdx +1 -10
- package/docs/guides/deployment/meta.json +4 -0
- package/docs/guides/deployment/overview.md +61 -0
- package/docs/guides/deployment/self-hosting.md +88 -0
- package/docs/guides/deployment/vercel.mdx +90 -0
- package/docs/guides/dev-tui.md +8 -4
- package/docs/guides/dynamic-capabilities.md +2 -0
- package/docs/guides/frontend/nextjs.mdx +1 -1
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +2 -5
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -4
- package/docs/guides/frontend/use-eve-agent-vue.mdx +1 -4
- package/docs/guides/instrumentation.md +1 -1
- package/docs/reference/cli.md +24 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/docs/guides/deployment.md +0 -210
- /package/dist/src/cli/{dev/tui → ui}/live-region.d.ts +0 -0
- /package/dist/src/cli/{dev/tui → ui}/live-region.js +0 -0
- /package/dist/src/cli/{dev/tui → ui}/terminal-text.d.ts +0 -0
- /package/dist/src/cli/{dev/tui → ui}/terminal-text.js +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment facts captured once per `eve dev` process, written into the
|
|
3
|
+
* diagnostic dump so a shared log always travels with the toolchain state
|
|
4
|
+
* that produced it.
|
|
5
|
+
*/
|
|
6
|
+
export interface DevEnvironmentInfo {
|
|
7
|
+
readonly eveVersion: string;
|
|
8
|
+
readonly nodeVersion: string;
|
|
9
|
+
readonly platform: string;
|
|
10
|
+
readonly vercelCliVersion?: string;
|
|
11
|
+
readonly vercelCliPath?: string;
|
|
12
|
+
/** Local durable session store measurements; absent when the directory does not exist yet. */
|
|
13
|
+
readonly sessionsDirectory?: {
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly files: number;
|
|
16
|
+
readonly bytes: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Aggregate counters for the TUI process's session activity. Reported by
|
|
21
|
+
* the renderer at each turn boundary so the dump stays current even if
|
|
22
|
+
* the process dies mid-session.
|
|
23
|
+
*/
|
|
24
|
+
export interface DevSessionStats {
|
|
25
|
+
readonly prompts: number;
|
|
26
|
+
readonly inputTokens: number;
|
|
27
|
+
readonly outputTokens: number;
|
|
28
|
+
/** Tool invocations observed, keyed by tool name. */
|
|
29
|
+
readonly toolCalls: Readonly<Record<string, number>>;
|
|
30
|
+
/** Distinct subagent dispatches that produced observable output. */
|
|
31
|
+
readonly subagents: number;
|
|
32
|
+
}
|
|
33
|
+
export interface DevDiagnosticDump {
|
|
34
|
+
readonly path: string;
|
|
35
|
+
/** Project-relative reference, forward slashes on every platform. */
|
|
36
|
+
readonly displayPath: string;
|
|
37
|
+
updateSessionStats(stats: DevSessionStats): void;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export interface CreateDevDiagnosticDumpOptions {
|
|
41
|
+
/** Injectable environment collector; defaults to {@link collectDevEnvironmentInfo}. */
|
|
42
|
+
readonly environment?: () => Promise<DevEnvironmentInfo>;
|
|
43
|
+
readonly now?: () => Date;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Creates the environment dump paired with one dev diagnostic log: the same
|
|
47
|
+
* instance name with a `.dump` extension. The environment section is
|
|
48
|
+
* collected in the background and written as soon as it resolves; session
|
|
49
|
+
* stats rewrite the file on every update. Like the log sink, write failures
|
|
50
|
+
* disable the dump silently — never through stderr, which the TUI captures.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createDevDiagnosticDump(appRoot: string, logPath: string, options?: CreateDevDiagnosticDumpOptions): DevDiagnosticDump;
|
|
53
|
+
/** Collects the real environment facts for {@link createDevDiagnosticDump}. */
|
|
54
|
+
export declare function collectDevEnvironmentInfo(appRoot: string): Promise<DevEnvironmentInfo>;
|
|
55
|
+
/**
|
|
56
|
+
* Counts files and total bytes under the app's local durable session store
|
|
57
|
+
* (`.eve/.workflow-data`). Returns `undefined` when the directory does not
|
|
58
|
+
* exist yet.
|
|
59
|
+
*/
|
|
60
|
+
export declare function measureSessionsDirectory(appRoot: string): Promise<DevEnvironmentInfo["sessionsDirectory"]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{constants}from"node:fs";import{delimiter,join,relative,sep}from"node:path";import{access,readdir,stat,writeFile}from"node:fs/promises";import{LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH}from"#internal/workflow/local-world-data-directory.js";import{captureVercel,resolveVercelInvocation}from"#setup/primitives/run-vercel.js";function createDevDiagnosticDump(e,t,n={}){let r=t.replace(/\.log$/,`.dump`),o=n.now??(()=>new Date),s=o().getTime(),c,l,u=Promise.resolve(),d=!1,f=!1,write=()=>{if(f||d)return;let e=formatDump({at:o(),durationMs:o().getTime()-s,environment:c,stats:l});u=u.then(()=>writeFile(r,e,{encoding:`utf8`,mode:384})).catch(()=>{d=!0})};return write(),(n.environment??(()=>collectDevEnvironmentInfo(e)))().then(e=>{c=e,write()}).catch(()=>{}),{path:r,displayPath:relative(e,r).split(sep).join(`/`),updateSessionStats(e){l=e,write()},async close(){f||(write(),f=!0,await u)}}}function formatDump(e){let t={updatedAt:e.at.toISOString(),durationMs:e.durationMs,environment:e.environment??null,session:e.stats??null};return`${JSON.stringify(t,null,2)}\n`}async function collectDevEnvironmentInfo(t){let[n,r]=await Promise.all([detectVercelCli(t),measureSessionsDirectory(t)]),i={eveVersion:resolveInstalledPackageInfo().version,nodeVersion:process.version,platform:`${process.platform} ${process.arch}`,...n};return r!==void 0&&(i.sessionsDirectory=r),i}async function detectVercelCli(e){let t=resolveVercelInvocation(e),[n,r]=await Promise.all([captureVercel([`--version`],{cwd:e,nonInteractive:!0,timeoutMs:5e3}),t.command===`vercel`?findOnPath(`vercel`):Promise.resolve(t.command)]),i=n.ok?n.stdout:`${n.failure.stdout}\n${n.failure.stderr}`,a=/(\d+\.\d+\.\d+\S*)/.exec(i)?.[1],o={};return a!==void 0&&(o.vercelCliVersion=a),r!==void 0&&(o.vercelCliPath=r),o}async function findOnPath(e){let i=(process.env.PATH??``).split(delimiter).filter(e=>e.length>0);for(let n of i){let i=join(n,e);try{return await access(i,constants.X_OK),i}catch{}}}async function measureSessionsDirectory(e){let t=join(e,LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH),n;try{n=await readdir(t,{recursive:!0,withFileTypes:!0})}catch{return}let i=0,a=0;for(let e of n)if(e.isFile()){i+=1;try{a+=(await stat(join(e.parentPath,e.name))).size}catch{}}return{path:LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH,files:i,bytes:a}}export{collectDevEnvironmentInfo,createDevDiagnosticDump,measureSessionsDirectory};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LogLevel } from "#internal/logging.js";
|
|
2
|
+
import type { JsonObject } from "#shared/json.js";
|
|
3
|
+
export type DevDiagnosticSource = "stderr" | "stdout" | "sandbox" | "workflow" | "tool" | "log";
|
|
4
|
+
/** Captured output or a failure summary attributed to one capture point. */
|
|
5
|
+
export interface DevDiagnosticOutputEntry {
|
|
6
|
+
readonly source: Exclude<DevDiagnosticSource, "log">;
|
|
7
|
+
readonly summary?: string;
|
|
8
|
+
readonly detail: string;
|
|
9
|
+
/** Structured remediation carried by cataloged failures. */
|
|
10
|
+
readonly hint?: string;
|
|
11
|
+
}
|
|
12
|
+
/** One structured record from eve's own logger. */
|
|
13
|
+
export interface DevDiagnosticLogRecordEntry {
|
|
14
|
+
readonly source: "log";
|
|
15
|
+
readonly level: LogLevel;
|
|
16
|
+
readonly namespace: string;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly fields?: JsonObject;
|
|
19
|
+
}
|
|
20
|
+
export type DevDiagnosticEntry = DevDiagnosticOutputEntry | DevDiagnosticLogRecordEntry;
|
|
21
|
+
export interface DevDiagnosticSink {
|
|
22
|
+
readonly path: string;
|
|
23
|
+
/**
|
|
24
|
+
* Project-relative reference with forward slashes on every platform:
|
|
25
|
+
* it is a display and correlation token (transcript pointers,
|
|
26
|
+
* `eve logs <ref>` input), not a filesystem path.
|
|
27
|
+
*/
|
|
28
|
+
readonly displayPath: string;
|
|
29
|
+
append(entry: DevDiagnosticEntry): void;
|
|
30
|
+
close(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export interface CreateDevDiagnosticSinkOptions {
|
|
33
|
+
readonly now?: () => Date;
|
|
34
|
+
readonly pid?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Creates the local, process-owned diagnostics file used by `eve dev`. */
|
|
37
|
+
export declare function createDevDiagnosticSink(appRoot: string, options?: CreateDevDiagnosticSinkOptions): Promise<DevDiagnosticSink>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{join,relative,sep}from"node:path";import{chmod,mkdir,open}from"node:fs/promises";async function createDevDiagnosticSink(t,n={}){let o=join(t,`.eve`,`logs`);await mkdir(o,{recursive:!0,mode:448}),await chmod(o,448);let s=n.now?.()??new Date,c=n.pid??process.pid,l=join(o,`dev-${s.toISOString().replaceAll(`:`,`-`)}-${c}.log`);return createOpenSink(t,l,await open(l,`wx`,384),()=>n.now?.()??new Date)}function createOpenSink(e,r,i,a){let o=Promise.resolve(),s=!1,c=!1;return{path:r,displayPath:relative(e,r).split(sep).join(`/`),append(e){if(c||s)return;let t=formatDiagnosticEntry(e,a());o=o.then(()=>i.appendFile(t,`utf8`)).catch(()=>{s=!0})},async close(){c||(c=!0,await o,await i.close())}}}function formatDiagnosticEntry(e,t){return`${JSON.stringify({at:t.toISOString(),...e})}\n`}export{createDevDiagnosticSink};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type LogRecord } from "#internal/logging.js";
|
|
2
|
+
import { type CreateDevDiagnosticDumpOptions } from "./diagnostic-dump.js";
|
|
3
|
+
import { type DevDiagnosticEntry } from "./diagnostic-sink.js";
|
|
4
|
+
/**
|
|
5
|
+
* The one diagnostics recorder an `eve dev` process owns: the per-process
|
|
6
|
+
* JSONL log (sink), its environment dump, session-stats accumulation, and
|
|
7
|
+
* ownership of eve's structured log records. The TUI holds a single
|
|
8
|
+
* reference and calls in at its capture points; everything stateful about
|
|
9
|
+
* diagnostics lives here, not in the renderer.
|
|
10
|
+
*/
|
|
11
|
+
export interface DevDiagnostics {
|
|
12
|
+
/** Project-relative path of the diagnostic log, for transcript pointers. */
|
|
13
|
+
readonly displayPath: string;
|
|
14
|
+
/** Appends one captured record to the per-process diagnostic log. */
|
|
15
|
+
append(entry: DevDiagnosticEntry): void;
|
|
16
|
+
recordPrompt(): void;
|
|
17
|
+
recordStepUsage(usage: {
|
|
18
|
+
inputTokens?: number;
|
|
19
|
+
outputTokens?: number;
|
|
20
|
+
} | undefined): void;
|
|
21
|
+
recordToolCall(toolName: string): void;
|
|
22
|
+
recordSubagentDispatch(callId: string): void;
|
|
23
|
+
/** Rewrites the environment dump with the stats accumulated so far. */
|
|
24
|
+
reportStats(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Takes ownership of eve's structured log records: each record is
|
|
27
|
+
* persisted to the log with its structure intact and then handed to
|
|
28
|
+
* `onRecord` for display. While subscribed, records never reach the
|
|
29
|
+
* console, so a host that also scrapes stderr sees each record exactly
|
|
30
|
+
* once.
|
|
31
|
+
*/
|
|
32
|
+
subscribeLogRecords(onRecord: (record: LogRecord) => void): void;
|
|
33
|
+
unsubscribeLogRecords(): void;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates the diagnostics recorder for one `eve dev` process: the
|
|
38
|
+
* exclusive per-process log plus its same-instance environment dump.
|
|
39
|
+
* Rejects when the log cannot be created (callers run without
|
|
40
|
+
* diagnostics rather than crash the TUI).
|
|
41
|
+
*/
|
|
42
|
+
export declare function createDevDiagnostics(appRoot: string, options?: CreateDevDiagnosticDumpOptions): Promise<DevDiagnostics>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createDevDiagnosticDump}from"./diagnostic-dump.js";import{createDevDiagnosticSink}from"./diagnostic-sink.js";import{setLogRecordSubscriber}from"#internal/logging.js";async function createDevDiagnostics(n,r={}){let i=await createDevDiagnosticSink(n);return new DevDiagnosticsRecorder(i,createDevDiagnosticDump(n,i.path,r))}var DevDiagnosticsRecorder=class{displayPath;#e;#t;#n=0;#r=0;#i=0;#a=new Map;#o=new Set;constructor(e,t){this.displayPath=e.displayPath,this.#e=e,this.#t=t}append(e){this.#e.append(e)}recordPrompt(){this.#n+=1}recordStepUsage(e){this.#r+=e?.inputTokens??0,this.#i+=e?.outputTokens??0}recordToolCall(e){this.#a.set(e,(this.#a.get(e)??0)+1)}recordSubagentDispatch(e){this.#o.add(e)}reportStats(){let e={prompts:this.#n,inputTokens:this.#r,outputTokens:this.#i,toolCalls:Object.fromEntries(this.#a),subagents:this.#o.size};this.#t.updateSessionStats(e)}subscribeLogRecords(e){setLogRecordSubscriber(t=>{let n={source:`log`,level:t.level,namespace:t.namespace,message:t.message};this.#e.append(t.fields===void 0?n:{...n,fields:t.fields}),e(t)})}unsubscribeLogRecords(){setLogRecordSubscriber(void 0)}async close(){await this.#t.close(),await this.#e.close()}};export{createDevDiagnostics};
|
|
@@ -39,6 +39,8 @@ export interface Block {
|
|
|
39
39
|
* rendered dim beneath the headline, capped to a handful of lines.
|
|
40
40
|
*/
|
|
41
41
|
detail?: string;
|
|
42
|
+
/** Structured remediation shown between an error's body and its detail. */
|
|
43
|
+
hint?: string;
|
|
42
44
|
/** Tool, connection, or synthetic command lifecycle status. */
|
|
43
45
|
status?: ToolStatus;
|
|
44
46
|
/** When true, treat `body` as pre-styled and only wrap + indent it. */
|
|
@@ -47,6 +49,8 @@ export interface Block {
|
|
|
47
49
|
collapsed?: boolean;
|
|
48
50
|
/** When true, expand tool input/output instead of summarizing. */
|
|
49
51
|
expanded?: boolean;
|
|
52
|
+
/** Captured-log visibility used for concise-vs-raw diagnostic replay. */
|
|
53
|
+
logVisibility?: "stderr-only" | "all-only";
|
|
50
54
|
/** Raw tool input / output for the expanded view. */
|
|
51
55
|
toolInput?: unknown;
|
|
52
56
|
toolOutput?: unknown;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{isPromptControlCommand}from"./prompt-commands.js";import{
|
|
1
|
+
import{isPromptControlCommand}from"./prompt-commands.js";import{formatValuePretty,truncate}from"./tool-format.js";import{renderMarkdown}from"./markdown.js";import{sliceVisible,visibleLength,wrapVisibleLine}from"#cli/ui/terminal-text.js";function renderBlockLines(e,t,n,r){let i=nestingPrefix(e.depth??0,n);return renderBody(e,Math.max(8,t-visibleLength(i)),n,r).map(e=>`${i}${e}`)}function nestingPrefix(e,t){return e<=0?``:`${t.colors.orange(t.glyph.rule)} `.repeat(e)}function renderBody(e,t,n,r){switch(e.kind){case`user`:return renderUser(e,t,n);case`assistant`:case`subagent-step`:return renderProse(e,t,n);case`reasoning`:return renderReasoning(e,t,n);case`tool`:case`subagent-tool`:return renderTool(e,t,n,r);case`error`:return renderError(e,t,n);case`notice`:return renderNotice(e,t,n);case`warning`:return renderWarning(e,t,n);case`result`:return renderResult(e,t,n);case`flow`:return renderFlow(e,t,n);case`command`:return renderCommand(e,n);case`question`:case`connection-auth`:return renderPreformatted(e,t,n);case`sandbox`:return renderSandbox(e,t,n,r);case`log`:return renderLog(e,t,n,r);case`subagent`:return renderSubagentHeader(e,t,n);case`agent-header`:return(e.body??``).split(`
|
|
2
2
|
`)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,t,n){let i=[],a=e.kind===`subagent-step`,s=a?``:`${n.colors.bold(n.colors.white(n.glyph.brand))} `,c=a?``:` `;e.reasoning&&e.reasoning.trim().length>0&&i.push(...renderReasoningLines(e.reasoning,t,n));let l=(e.body??``).trim();return l.length===0&&i.length===0?[`${s}${n.colors.dim(`thinking${n.glyph.ellipsis}`)}`]:(l.length>0&&renderMarkdown(l).split(`
|
|
3
|
-
`).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!a&&i.length===0?i.push(`${s}${e}`):i.push(`${c}${e}`)}),i.length>0?i:[`${s}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderTool(e,t,
|
|
4
|
-
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let
|
|
5
|
-
`))for(let e of wrapVisibleLine(n,t-2))
|
|
6
|
-
`),f=[];for(let e of d){let
|
|
7
|
-
`),h=[];for(let e of m){let
|
|
8
|
-
`).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(e,
|
|
3
|
+
`).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!a&&i.length===0?i.push(`${s}${e}`):i.push(`${c}${e}`)}),i.length>0?i:[`${s}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderTool(e,t,r,i){let{icon:a,accent:o}=toolGlyph(e.status??`running`,r,i),s=e.title??`tool`,c=t-2,l=truncatePlain(s,c),u=`${a} ${r.colors.bold(l)}`,d=c-l.length-2,f=e.subtitle??``;f.length>0&&d>=6&&(u+=` ${r.colors.gray(truncate(f,d))}`);let p=[u];return e.expanded?p.push(...renderToolExpanded(e,t,r)):e.status===`done`&&e.result&&e.result.length>0?p.push(resultLine(r.glyph.arrow,e.result,t,r,o)):e.status===`error`&&e.result?p.push(resultLine(r.glyph.arrow,e.result,t,r,r.colors.red)):e.status===`denied`&&p.push(resultLine(r.glyph.arrow,`denied`,t,r,r.colors.yellow)),p}function renderToolExpanded(e,n,r){let i=[],push=(e,a,o)=>{if(a!==void 0){i.push(` ${r.colors.dim(e)}`);for(let e of wrap(formatValuePretty(a),n-4))i.push(` ${o(e)}`)}};return push(`input`,e.toolInput,r.colors.gray),e.status===`error`&&e.result?push(`error`,e.result,r.colors.red):push(`output`,e.toolOutput,r.colors.gray),i}function resultLine(e,t,r,i,a){let o=r-4;return` ${i.colors.dim(e)} ${a(truncate(t,o))}`}function toolGlyph(e,t,n){switch(e){case`done`:return{icon:t.colors.green(t.glyph.success),accent:t.colors.gray};case`error`:return{icon:t.colors.red(t.glyph.error),accent:t.colors.red};case`denied`:return{icon:t.colors.yellow(t.glyph.warning),accent:t.colors.yellow};case`approval`:return{icon:t.colors.yellow(t.glyph.question),accent:t.colors.yellow};default:return{icon:t.colors.yellow(n.spinner),accent:t.colors.gray}}}function renderError(e,t,n){let r=n.colors.red(n.colors.bold(n.glyph.error)),i=e.title??`Error`,a=[`${r} ${n.colors.red(n.colors.bold(i))}`];for(let r of wrap(e.body??``,t-2))a.push(` ${colorizeError(r,n)}`);if(e.hint!==void 0&&e.hint.trim().length>0)for(let[r,i]of wrap(e.hint,t-4).entries()){let e=r===0?`${n.glyph.arrow} `:` `;a.push(` ${n.colors.cyan(`${e}${i}`)}`)}return a.push(...renderErrorDetail(e.detail,t,n)),a}function renderErrorDetail(e,t,n){if(e===void 0||e.trim().length===0)return[];let r=e.split(`
|
|
4
|
+
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let r=e.kind===`connection-auth`?n.colors.yellow(n.glyph.connection):n.colors.yellow(n.colors.bold(n.glyph.question)),i=wrap(e.title??``,t-2),a=i.length===0?[`${r} `]:i.map((e,t)=>t===0?`${r} ${n.colors.bold(e)}`:` ${n.colors.bold(e)}`);for(let n of(e.body??``).split(`
|
|
5
|
+
`))for(let e of wrapVisibleLine(n,t-2))a.push(` ${e}`);return a}function renderSandbox(e,t,n,r){let i=n.colors.cyan(n.glyph.rule),s=n.colors.dim(`sandbox ${n.glyph.dot} `),c=visibleLength(s),l=` `.repeat(c),u=r.previous?.kind===`sandbox`,d=(e.body??``).split(`
|
|
6
|
+
`),f=[];for(let e of d){let r=wrapVisibleLine(e,Math.max(1,t-2-c));for(let e of r){let t=f.length===0&&!u?s:l;f.push(`${i} ${t}${n.colors.gray(e)}`)}}return f.length>0?f:[`${i}`]}function renderLog(e,t,n,r){let i=e.title===`stderr`,s=i?n.colors.red:n.colors.gray,c=n.colors.dim(n.glyph.rule),l=i?`stderr`:`stdout`,u=n.colors.dim(`${l} ${n.glyph.dot} `),d=visibleLength(u),f=` `.repeat(d),p=r.previous?.kind===`log`&&r.previous.title===e.title,m=(e.body??``).split(`
|
|
7
|
+
`),h=[];for(let e of m){let r=wrapVisibleLine(e,Math.max(1,t-2-d));for(let e of r){let t=h.length===0&&!p?u:f;h.push(`${c} ${t}${n.colors.dim(s(e))}`)}}return h.length>0?h:[`${c}`]}function renderSubagentHeader(e,t,n){let r=truncatePlain(e.title??`subagent`,Math.max(8,t-14));return[`${n.colors.orange(n.glyph.subagent)} ${n.colors.bold(r)} ${n.colors.dim(`subagent`)}`]}function wrap(e,t){return e.trim().length===0?[]:e.split(`
|
|
8
|
+
`).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(e,t){return visibleLength(e)<=t?e:sliceVisible(e,t)}export{renderAttentionRows,renderBlockLines};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sliceVisible,visibleLength}from"
|
|
1
|
+
import{sliceVisible,visibleLength}from"#cli/ui/terminal-text.js";import{renderCursorRow}from"#setup/cli/option-row.js";function typeaheadFor(e,t,n){let r=matchingCommands(e,t),i=n===void 0?void 0:n.matches[n.selectedIndex],a=i===void 0?-1:r.indexOf(i);return{query:t,matches:r,selectedIndex:a>=0?a:0,dismissed:n!==void 0&&n.dismissed&&n.query===t}}function matchingCommands(e,t){if(!t.startsWith(`/`)||/\s/.test(t))return[];let n=t.slice(1);return e.filter(e=>[e.name,...e.aliases].some(e=>e.startsWith(n)))}function isTypeaheadOpen(e){return e.matches.length>0&&!e.dismissed}function moveTypeaheadSelection(e,t){let n=e.matches.length;if(n===0)return e;let r=(e.selectedIndex+t+n)%n;return{...e,selectedIndex:r}}function dismissTypeahead(e){return e.dismissed?e:{...e,dismissed:!0}}function selectedTypeaheadCommand(e){return e.matches[e.selectedIndex]}function typeaheadCompletion(e){return`/${e.name}${e.takesArgument?` `:``}`}function inlineCommandHint(e){if(e.dismissed||e.matches.length!==1)return;let t=e.matches[0],n=e.query.startsWith(`/`)?e.query.slice(1):e.query;if([t.name,...t.aliases].includes(n))return t.argumentHint??``}function renderCommandSuggestions(r,i,a){let o=i.colors,s=r.matches.length,c=Math.min(s,10),l=Math.max(0,Math.min(r.selectedIndex-Math.floor(c/2),s-c)),u=Math.min(l+c,s),d=r.matches.slice(l,u),invocation=e=>{let t=e.aliases.map(e=>` (/${e})`).join(``);return`/${e.name}${t}`},f=Math.max(...d.map(e=>invocation(e).length))+2;return d.map((e,t)=>{let a=l+t===r.selectedIndex,s=`/${e.name}`,c=renderCursorRow(a?`${i.glyph.selectedPointer} ${s}`:` ${s}`,a,o),u=invocation(e).slice(`/${e.name}`.length),d=` `.repeat(f-invocation(e).length);return a&&(u.startsWith(` `)?u=u.slice(1):d=d.slice(1)),`${c}${o.dim(u)}${d}${o.dim(e.description)}`}).map(n=>visibleLength(n)>a?sliceVisible(n,a):n)}export{dismissTypeahead,inlineCommandHint,isTypeaheadOpen,moveTypeaheadSelection,renderCommandSuggestions,selectedTypeaheadCommand,typeaheadCompletion,typeaheadFor};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type DiagnosticPresentation = {
|
|
2
|
+
readonly kind: "inline";
|
|
3
|
+
readonly text: string;
|
|
4
|
+
} | {
|
|
5
|
+
readonly kind: "stored";
|
|
6
|
+
readonly summary: string;
|
|
7
|
+
readonly omittedLines: number;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
};
|
|
10
|
+
/** Chooses whether process diagnostics stay inline or collapse to the local sink. */
|
|
11
|
+
export declare function presentDiagnostic(text: string, path: string): DiagnosticPresentation;
|
|
12
|
+
export declare function formatStoredDiagnostic(presentation: Extract<DiagnosticPresentation, {
|
|
13
|
+
kind: "stored";
|
|
14
|
+
}>): string;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function presentDiagnostic(e,t){let n=e.split(`
|
|
2
|
+
`);if(n.length<=4&&e.length<=600)return{kind:`inline`,text:e};let r=n.find(e=>e.trim().length>0)?.trim()??`Diagnostic output`;return{kind:`stored`,summary:r.length<=240?r:`${r.slice(0,239)}…`,omittedLines:Math.max(0,n.length-1),path:t}}function formatStoredDiagnostic(e){let t=e.omittedLines,n=t===0?`diagnostic details`:`${t} diagnostic line${t===1?``:`s`}`;return`${e.summary}\n… ${n} · details: ${e.path}`}export{formatStoredDiagnostic,presentDiagnostic};
|
|
@@ -40,6 +40,23 @@ export declare function failureKey(event: FailureStreamEvent): string;
|
|
|
40
40
|
* which case the message stands alone instead of reading `Code: Code: …`.
|
|
41
41
|
*/
|
|
42
42
|
export declare function formatFailureMessage(event: FailureStreamEvent): string;
|
|
43
|
+
/**
|
|
44
|
+
* The structured fields the harness attaches to failure-event details:
|
|
45
|
+
* the semantic-error catalog's identity and remediation, plus the raw
|
|
46
|
+
* inspection dump for unrecognized failures. One projection so every
|
|
47
|
+
* consumer narrows the untyped `details` payload the same way.
|
|
48
|
+
*/
|
|
49
|
+
export interface FailureDetails {
|
|
50
|
+
readonly semanticErrorId?: string;
|
|
51
|
+
readonly hint?: string;
|
|
52
|
+
readonly detail?: string;
|
|
53
|
+
}
|
|
54
|
+
export declare function failureDetails(event: FailureStreamEvent): FailureDetails;
|
|
55
|
+
/**
|
|
56
|
+
* Extracts the structured remediation hint attached to a failure event's
|
|
57
|
+
* details by the semantic-error catalog, if any.
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatFailureHint(event: FailureStreamEvent): string | undefined;
|
|
43
60
|
/**
|
|
44
61
|
* Extracts the diagnostic dump attached to a failure event, if any.
|
|
45
62
|
*
|
|
@@ -51,20 +68,8 @@ export declare function formatFailureMessage(event: FailureStreamEvent): string;
|
|
|
51
68
|
*/
|
|
52
69
|
export declare function formatFailureDetail(event: FailureStreamEvent): string | undefined;
|
|
53
70
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* the diagnostic detail along with it. The variant is picked off the summary
|
|
58
|
-
* message the harness wrote, so a stale key, an expired OIDC token, and
|
|
59
|
-
* missing credentials each get the fix that actually applies.
|
|
60
|
-
*/
|
|
61
|
-
export declare function formatGatewayAuthFailureNotice(event: FailureStreamEvent): string;
|
|
62
|
-
/**
|
|
63
|
-
* Recognizes a model-call failure caused by AI Gateway authentication. The
|
|
64
|
-
* primary signal is the machine-readable `gatewayName` the harness merges
|
|
65
|
-
* into every model-call failure's details (`extractModelCallErrorDetails`);
|
|
66
|
-
* the summary name is the fallback for payloads whose gateway error was not
|
|
67
|
-
* preserved on the cause chain. Both identifiers are imported from the
|
|
68
|
-
* harness module that writes them, so the two sides cannot drift.
|
|
71
|
+
* The surface-local hint for a failure, when the TUI can offer a better
|
|
72
|
+
* fix than the catalog's (currently: gateway credential failures resolve
|
|
73
|
+
* in-session via `/model`). Returns `undefined` to keep the harness hint.
|
|
69
74
|
*/
|
|
70
|
-
export declare function
|
|
75
|
+
export declare function localFailureHint(event: FailureStreamEvent): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var InterruptedError=class extends Error{constructor(){super(`Interrupted`),this.name=`InterruptedError`}};function interruptedError(){return new InterruptedError}function isInterruptedError(e){return e instanceof InterruptedError}function isAbortLikeError(e){return e instanceof Error?e.name===`AbortError`||/\babort(?:ed)?\b/iu.test(e.message):!1}function failureKey(e){return`${e.data.code}:${e.data.message}`}function formatFailureMessage(e){let{code:t,message:n}=e.data;return!t||n===t||n.startsWith(`${t}:`)||n.startsWith(`${t} `)?n:`${t}: ${n}`}function failureDetails(e){let t=e.data.details;if(typeof t!=`object`||!t)return{};let n=t,r={};return typeof n.semanticErrorId==`string`&&(r.semanticErrorId=n.semanticErrorId),typeof n.hint==`string`&&n.hint.trim().length>0&&(r.hint=n.hint.trim()),typeof n.detail==`string`&&(r.detail=n.detail),r}function formatFailureHint(e){return failureDetails(e).hint}function formatFailureDetail(e){let t=failureDetails(e).detail;if(t===void 0)return;let n=t.trim();if(!(n.length===0||n===e.data.message.trim()))return n}const LOCAL_HINT_OVERRIDES={"gateway-auth-invalid-api-key":`Run /model to refresh credentials, or update AI_GATEWAY_API_KEY in .env.local (a stale shell export can shadow it).`,"gateway-auth-invalid-oidc-token":`Run /model to refresh the OIDC token, or set AI_GATEWAY_API_KEY in .env.local.`,"gateway-auth-missing-credentials":`Run /model to connect this to a project and refresh AI Gateway credentials, or set AI_GATEWAY_API_KEY manually in .env.local.`};function localFailureHint(t){let n=failureDetails(t).semanticErrorId;return n===void 0?void 0:LOCAL_HINT_OVERRIDES[n]}export{InterruptedError,failureDetails,failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,interruptedError,isAbortLikeError,isInterruptedError,localFailureHint};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{inputTextWidth,offsetAtVisibleColumn}from"
|
|
1
|
+
import{inputTextWidth,offsetAtVisibleColumn}from"#cli/ui/terminal-text.js";import{graphemeBoundaryAtOrAfter,graphemes,nextGraphemeBoundary,previousGraphemeBoundary}from"#shared/text-boundaries.js";const EMPTY_LINE={text:``,cursor:0};function lineOf(e){return{text:e,cursor:e.length}}function maskLine(e){return{text:`•`.repeat(graphemes(e.text).length),cursor:graphemes(e.text.slice(0,e.cursor)).length}}function insert(e,t){if(t.length===0)return e;let r=e.text.slice(0,e.cursor)+t+e.text.slice(e.cursor);return{text:r,cursor:graphemeBoundaryAtOrAfter(r,e.cursor+t.length)}}function backspace(e){if(e.cursor===0)return e;let t=previousGraphemeBoundary(e.text,e.cursor),r=e.text.slice(0,t)+e.text.slice(e.cursor);return{text:r,cursor:graphemeBoundaryAtOrAfter(r,t)}}function deleteForward(e){if(e.cursor>=e.text.length)return e;let t=nextGraphemeBoundary(e.text,e.cursor),r=e.text.slice(0,e.cursor)+e.text.slice(t);return{text:r,cursor:graphemeBoundaryAtOrAfter(r,e.cursor)}}function moveLeft(e){return e.cursor===0?e:{text:e.text,cursor:previousGraphemeBoundary(e.text,e.cursor)}}function moveRight(e){return e.cursor>=e.text.length?e:{text:e.text,cursor:nextGraphemeBoundary(e.text,e.cursor)}}function moveHome(e){let t=logicalLineStart(e.text,e.cursor);return e.cursor===t?e:{text:e.text,cursor:t}}function moveEnd(e){let t=logicalLineEnd(e.text,e.cursor);return e.cursor===t?e:{text:e.text,cursor:t}}function killToEnd(e){let t=logicalLineEnd(e.text,e.cursor);return e.cursor>=t?e:{text:e.text.slice(0,e.cursor)+e.text.slice(t),cursor:e.cursor}}function killToStart(e){let t=logicalLineStart(e.text,e.cursor);return e.cursor<=t?e:{text:e.text.slice(0,t)+e.text.slice(e.cursor),cursor:t}}function deleteWord(e){if(e.cursor===0)return e;let t=logicalLineStart(e.text,e.cursor),r=e.cursor;for(;r>t;){let t=previousGraphemeBoundary(e.text,r);if(!isWhitespace(e.text.slice(t,r)))break;r=t}for(;r>t;){let t=previousGraphemeBoundary(e.text,r);if(isWhitespace(e.text.slice(t,r)))break;r=t}let i=e.text.slice(0,r)+e.text.slice(e.cursor);return{text:i,cursor:graphemeBoundaryAtOrAfter(i,r)}}function logicalLineStart(e,t){return t===0?0:e.lastIndexOf(`
|
|
2
2
|
`,t-1)+1}function logicalLineEnd(e,t){let n=e.indexOf(`
|
|
3
3
|
`,t);return n===-1?e.length:n}function applyLineEditorKey(e,t,n){let r=n?.multiline??!1;switch(t.type){case`text`:return insert(e,r?t.value:t.value.replaceAll(`
|
|
4
4
|
`,` `));case`newline`:return r?insert(e,`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{visibleLength}from"
|
|
1
|
+
import{visibleLength}from"#cli/ui/terminal-text.js";const ansi={bold:`\x1B[1m`,boldOff:`\x1B[22m`,italic:`\x1B[3m`,italicOff:`\x1B[23m`};function renderMarkdown(e){let t=e.split(`
|
|
2
2
|
`),n=[];for(let e=0;e<t.length;e+=1){let r=parseTable(t,e);if(r!=null){n.push(...renderTable(r)),e=r.endIndex-1;continue}n.push(renderMarkdownLine(t[e]??``))}return n.join(`
|
|
3
3
|
`)}function renderMarkdownLine(e){if(e.startsWith(`### `))return renderInlineMarkdown(`▶ ${e.slice(4)}`);if(e.startsWith(`## `))return renderInlineMarkdown(`■ ${e.slice(3)}`);if(e.startsWith(`# `))return renderInlineMarkdown(`█ ${e.slice(2)}`);let t=e.match(/^(\s*)[-+*]\s+(.*)$/);if(t){let[,e,n=``]=t;return renderInlineMarkdown(`${e}•${n.length>0?` ${n}`:``}`)}return/^\d+\. /.test(e)?renderInlineMarkdown(e.replace(/^(\d+)\. /,`$1. `)):e.startsWith(`> `)?renderInlineMarkdown(`│ ${e.slice(2)}`):renderInlineMarkdown(e)}function renderInlineMarkdown(e){let n=[];return e.replaceAll(/https?:\/\/\S+/g,e=>{let t=`\uE000${n.length}\uE001`;return n.push(e),t}).replaceAll(/`([^`]+)`/g,`$1`).replaceAll(/\*\*([^*\n]+)\*\*/g,`${ansi.bold}$1${ansi.boldOff}`).replaceAll(/__([^_\n]+)__/g,`${ansi.bold}$1${ansi.boldOff}`).replaceAll(/\*([^*\n]+)\*/g,`${ansi.italic}$1${ansi.italicOff}`).replaceAll(/_([^_\n]+)_/g,`${ansi.italic}$1${ansi.italicOff}`).replaceAll(/\uE000(\d+)\uE001/g,(e,t)=>n[Number(t)]??``)}function parseTable(e,t){let n=parseTableCells(e[t]??``);if(n==null||n.length<2)return;let r=parseTableCells(e[t+1]??``);if(r==null||r.length!==n.length)return;let i=parseTableAlignments(r);if(i==null)return;let a=[],o=t+2;for(;o<e.length;){let t=parseTableCells(e[o]??``);if(t==null)break;a.push(normalizeTableRow(t,n.length)),o+=1}return{alignments:i,endIndex:o,header:n,rows:a}}function parseTableCells(e){if(!e.includes(`|`))return;let t=e.trim();t.startsWith(`|`)&&(t=t.slice(1)),t.endsWith(`|`)&&!t.endsWith(`\\|`)&&(t=t.slice(0,-1));let n=[],r=``;for(let e=0;e<t.length;e+=1){let i=t[e],a=t[e+1];if(i===`\\`&&a===`|`){r+=`|`,e+=1;continue}if(i===`|`){n.push(r.trim()),r=``;continue}r+=i}return n.push(r.trim()),n}function parseTableAlignments(e){let t=[];for(let n of e){let e=n.match(/^(:)?-{3,}(:)?$/);if(e==null)return;let[,r,i]=e;t.push(r!=null&&i!=null?`center`:i==null?`left`:`right`)}return t}function normalizeTableRow(e,t){return Array.from({length:t},(t,n)=>e[n]??``)}function renderTable(n){let r=n.header.map(e=>`${ansi.bold}${renderInlineMarkdown(e)}${ansi.boldOff}`),i=n.rows.map(e=>e.map(renderInlineMarkdown)),a=[r,...i],o=n.alignments.map((t,n)=>Math.max(3,...a.map(t=>visibleLength(t[n]??``))));return[formatTableRow(r,o,n.alignments),o.map(e=>`─`.repeat(e)).join(` `),...i.map(e=>formatTableRow(e,o,n.alignments))]}function formatTableRow(e,t,n){return e.map((e,r)=>alignTableCell(e,t[r]??0,n[r]??`left`)).join(` `)}function alignTableCell(t,n,r){let i=Math.max(0,n-visibleLength(t));if(r===`right`)return`${` `.repeat(i)}${t}`;if(r===`center`){let e=Math.floor(i/2),n=i-e;return`${` `.repeat(e)}${t}${` `.repeat(n)}`}return`${t}${` `.repeat(i)}`}export{renderMarkdown};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type ReasoningLevel } from "#setup/boxes/model-capabilities.js";
|
|
2
|
+
import type { GatewayModelCapabilities } from "#setup/boxes/model-capabilities.js";
|
|
3
|
+
import { type SelectState } from "#setup/cli/select-state.js";
|
|
4
|
+
import type { ModelSettingsRequest, ModelSettingsResult } from "#setup/flows/model.js";
|
|
5
|
+
import type { SelectOption } from "#setup/prompter.js";
|
|
6
|
+
/** The Change-model menu's rows, in visual order. */
|
|
7
|
+
export type ModelEditorRowId = "model" | "reasoning" | "tier" | "done";
|
|
8
|
+
/**
|
|
9
|
+
* The screen stack, depth two: the value menu, or the model list it opens.
|
|
10
|
+
* Reasoning and tier adjust inline on their menu rows — only the catalog pick
|
|
11
|
+
* warrants its own screen. The list carries scratch select state seeded when
|
|
12
|
+
* opened; Esc drops it, so "returns unchanged" is structural.
|
|
13
|
+
*/
|
|
14
|
+
export type ModelEditorScreen = {
|
|
15
|
+
kind: "menu";
|
|
16
|
+
cursor: ModelEditorRowId;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "model";
|
|
19
|
+
select: SelectState;
|
|
20
|
+
};
|
|
21
|
+
/** The in-progress values; nothing lands in source until the menu's Done. */
|
|
22
|
+
export interface ModelEditorDraft {
|
|
23
|
+
modelId: string | null;
|
|
24
|
+
reasoning: "default" | ReasoningLevel;
|
|
25
|
+
tier: "standard" | "priority";
|
|
26
|
+
}
|
|
27
|
+
/** One Change-model interaction, advanced by {@link transitionModelEditor}. */
|
|
28
|
+
export interface ModelEditorState {
|
|
29
|
+
screen: ModelEditorScreen;
|
|
30
|
+
draft: ModelEditorDraft;
|
|
31
|
+
/** Catalog capabilities for `draft.modelId`; recomputed on every pick. */
|
|
32
|
+
capabilities: GatewayModelCapabilities | undefined;
|
|
33
|
+
}
|
|
34
|
+
/** Semantic input after terminal-key decoding. */
|
|
35
|
+
export type ModelEditorEvent = {
|
|
36
|
+
type: "move";
|
|
37
|
+
direction: "up" | "down";
|
|
38
|
+
} | {
|
|
39
|
+
type: "adjust";
|
|
40
|
+
direction: "left" | "right";
|
|
41
|
+
} | {
|
|
42
|
+
type: "char";
|
|
43
|
+
char: string;
|
|
44
|
+
} | {
|
|
45
|
+
type: "backspace";
|
|
46
|
+
} | {
|
|
47
|
+
type: "cancel";
|
|
48
|
+
} | {
|
|
49
|
+
type: "submit";
|
|
50
|
+
};
|
|
51
|
+
export type ModelEditorTransition = {
|
|
52
|
+
kind: "ignore";
|
|
53
|
+
state: ModelEditorState;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "render";
|
|
56
|
+
state: ModelEditorState;
|
|
57
|
+
} | {
|
|
58
|
+
kind: "cancel";
|
|
59
|
+
} | {
|
|
60
|
+
kind: "settle";
|
|
61
|
+
result: ModelSettingsResult;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* How a value row presents: an adjustable control, a dim explanatory line the
|
|
65
|
+
* cursor skips, or nothing at all — a control that cannot apply to the
|
|
66
|
+
* drafted model (no priority tier) is noise, while an authored-but-unowned
|
|
67
|
+
* state (custom tier, external provider) still explains itself.
|
|
68
|
+
*/
|
|
69
|
+
export type ModelEditorSectionView = {
|
|
70
|
+
kind: "interactive";
|
|
71
|
+
} | {
|
|
72
|
+
kind: "static";
|
|
73
|
+
text: string;
|
|
74
|
+
} | {
|
|
75
|
+
kind: "hidden";
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The reasoning row stays interactive while a level is drafted even when the
|
|
79
|
+
* catalog disowns reasoning, so the authored value at least stays visible.
|
|
80
|
+
*/
|
|
81
|
+
export declare function reasoningSectionView(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
|
|
82
|
+
/** The tier row's presentation; static or hidden for every state it cannot own. */
|
|
83
|
+
export declare function tierSectionView(request: ModelSettingsRequest, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
|
|
84
|
+
/**
|
|
85
|
+
* The track's notch positions: the levels the catalog supports (every level
|
|
86
|
+
* when capabilities are unknown). The provider default is not a notch — an
|
|
87
|
+
* unset draft renders an empty track and the first right-adjust enters the
|
|
88
|
+
* scale at the lowest level. A drafted level the catalog does not list is
|
|
89
|
+
* inserted in canonical level order, so the track never hides the value it
|
|
90
|
+
* is about to replace.
|
|
91
|
+
*/
|
|
92
|
+
export declare function reasoningPositions(capabilities: GatewayModelCapabilities | undefined, drafted: "default" | ReasoningLevel): readonly ReasoningLevel[];
|
|
93
|
+
/**
|
|
94
|
+
* The value menu's rows, derived fresh from the draft on every transition and
|
|
95
|
+
* paint: interactive sections are pickable rows, static sections are disabled
|
|
96
|
+
* rows carrying their explanation, and a hidden tier is omitted entirely.
|
|
97
|
+
* Value hints are the painter's job — it styles them with theme glyphs.
|
|
98
|
+
*/
|
|
99
|
+
export declare function modelEditorMenuRows(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): SelectOption<ModelEditorRowId>[];
|
|
100
|
+
/** Creates the screen's state; the cursor opens on the first pickable row. */
|
|
101
|
+
export declare function initialModelEditorState(request: ModelSettingsRequest): ModelEditorState;
|
|
102
|
+
/** Applies one keypress worth of semantics; terminal resources stay in the renderer. */
|
|
103
|
+
export declare function transitionModelEditor(state: ModelEditorState, event: ModelEditorEvent, request: ModelSettingsRequest): ModelEditorTransition;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ALL_REASONING_LEVELS}from"#setup/boxes/model-capabilities.js";import{filterOptions,initialSelectState,reduceSelect,selectValueAtCursor}from"#setup/cli/select-state.js";const NOT_EDITABLE_TEXT=`No editable agent.ts config object is available`;function reasoningSectionView(e,t,n){return e.settingsEditable?n?.reasoning===!1&&t.reasoning==="default"?{kind:`static`,text:`Not supported by the selected model`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function tierSectionView(e,t){return e.settingsEditable?e.externalRouting?{kind:`static`,text:`Disabled for a direct external provider`}:e.serviceTier.kind===`custom`?{kind:`static`,text:`Custom (${e.serviceTier.value}) — authored in agent.ts`}:t!==void 0&&!t.fastMode?{kind:`hidden`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function reasoningPositions(t,n){let r=[...t===void 0?ALL_REASONING_LEVELS:t.reasoningLevels];if(n!=="default"&&!r.includes(n)){let t=ALL_REASONING_LEVELS.indexOf(n),i=r.findIndex(n=>ALL_REASONING_LEVELS.indexOf(n)>t);i===-1?r.push(n):r.splice(i,0,n)}return r}function snapReasoningToCapabilities(t,n){if(t==="default"||n===void 0)return t;let r=n.reasoningLevels;if(!n.reasoning||r.length===0)return`default`;if(r.includes(t))return t;let i=ALL_REASONING_LEVELS.indexOf(t),a=r[0];for(let t of r)Math.abs(ALL_REASONING_LEVELS.indexOf(t)-i)<Math.abs(ALL_REASONING_LEVELS.indexOf(a)-i)&&(a=t);return a}function modelEditorMenuRows(e,t,n){let r=[];e.model.kind===`pick`?r.push({value:`model`,label:`Model`}):r.push({value:`model`,label:`Model`,disabled:!0,description:e.model.reason});let i=reasoningSectionView(e,t,n);i.kind===`static`?r.push({value:`reasoning`,label:`Reasoning effort`,disabled:!0,description:i.text}):r.push({value:`reasoning`,label:`Reasoning effort`});let a=tierSectionView(e,n);return a.kind===`interactive`?r.push({value:`tier`,label:`Service tier`}):a.kind===`static`&&r.push({value:`tier`,label:`Service tier`,disabled:!0,description:a.text}),r.push({value:`done`,label:`Done`}),r}function initialModelEditorState(e){let t={modelId:e.model.current,reasoning:e.reasoning??`default`,tier:e.serviceTier.kind===`priority`?`priority`:`standard`},n=e.capabilitiesFor(t.modelId);return{screen:{kind:`menu`,cursor:modelEditorMenuRows(e,t,n).find(e=>e.disabled!==!0)?.value??`done`},draft:t,capabilities:n}}function expandedModelSelect(e,t){let r={options:e.model.kind===`pick`?e.model.options:[]};return t!==null&&(r.defaultValue=t),initialSelectState(r)}function ignore(e){return{kind:`ignore`,state:e}}function toMenu(e,t){return{kind:`render`,state:{...e,screen:{kind:`menu`,cursor:t}}}}function settleResult(e,t){let n={};if(e.model.kind===`pick`&&t.modelId!==null&&t.modelId!==e.model.current&&(n.model=t.modelId),!e.settingsEditable)return n;t.reasoning!==(e.reasoning??`default`)&&(n.reasoning=t.reasoning);let r=!e.externalRouting&&e.serviceTier.kind!==`custom`,i=e.serviceTier.kind===`priority`?`priority`:`standard`;return r&&t.tier!==i&&(n.serviceTier=t.tier),n}function adjustMenuValue(e,t,n,r){let i=r===`left`?-1:1;if(n===`reasoning`){if(reasoningSectionView(t,e.draft,e.capabilities).kind!==`interactive`)return ignore(e);let n=reasoningPositions(e.capabilities,e.draft.reasoning);if(n.length===0)return ignore(e);let r=e.draft.reasoning==="default"?-1:n.indexOf(e.draft.reasoning),a=r===-1?n[i===1?0:n.length-1]:n[(r+i+n.length)%n.length];return a===e.draft.reasoning?ignore(e):{kind:`render`,state:{...e,draft:{...e.draft,reasoning:a}}}}if(n===`tier`){if(tierSectionView(t,e.capabilities).kind!==`interactive`)return ignore(e);let n=e.draft.tier===`priority`?`standard`:`priority`;return{kind:`render`,state:{...e,draft:{...e.draft,tier:n}}}}return ignore(e)}function transitionMenu(e,t,n,i){let a=modelEditorMenuRows(n,e.draft,e.capabilities);switch(t.type){case`cancel`:return{kind:`cancel`};case`move`:{let n=a[reduceSelect({filter:``,cursor:Math.max(0,a.findIndex(e=>e.value===i)),selected:new Set},{type:t.direction},{options:a}).cursor]?.value;return n===void 0||n===i?ignore(e):toMenu(e,n)}case`adjust`:return adjustMenuValue(e,n,i,t.direction);case`submit`:{let t=a.find(e=>e.value===i);return t===void 0||t.disabled===!0?ignore(e):i===`model`?{kind:`render`,state:{...e,screen:{kind:`model`,select:expandedModelSelect(n,e.draft.modelId)}}}:i===`done`?{kind:`settle`,result:settleResult(n,e.draft)}:transitionMenu(e,{type:`move`,direction:`down`},n,i)}case`char`:case`backspace`:return ignore(e)}}function transitionModelScreen(e,n,a,o){let s=a.model.kind===`pick`?a.model.options:[],renderSelect=t=>t===o?ignore(e):{kind:`render`,state:{...e,screen:{kind:`model`,select:t}}};switch(n.type){case`cancel`:return o.filter.length>0?renderSelect(reduceSelect(o,{type:`clear`},{options:s})):toMenu(e,`model`);case`move`:return renderSelect(reduceSelect(o,{type:n.direction},{options:s}));case`char`:return renderSelect(reduceSelect(o,{type:`char`,char:n.char},{options:s}));case`backspace`:return renderSelect(reduceSelect(o,{type:`backspace`},{options:s}));case`submit`:{let n=selectValueAtCursor(filterOptions(s,o.filter),o.cursor);if(n===void 0)return ignore(e);let r=a.capabilitiesFor(n);return{kind:`render`,state:{screen:{kind:`menu`,cursor:`model`},draft:{...e.draft,modelId:n,reasoning:snapReasoningToCapabilities(e.draft.reasoning,r),tier:r!==void 0&&!r.fastMode?`standard`:e.draft.tier},capabilities:r}}}case`adjust`:return ignore(e)}}function transitionModelEditor(e,t,n){switch(e.screen.kind){case`menu`:return transitionMenu(e,t,n,e.screen.cursor);case`model`:return transitionModelScreen(e,t,n,e.screen.select)}}export{initialModelEditorState,modelEditorMenuRows,reasoningPositions,reasoningSectionView,tierSectionView,transitionModelEditor};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApplyModelOutcome } from "#setup/flows/model.js";
|
|
1
|
+
import type { ApplyModelOutcome } from "#setup/flows/model-source-change.js";
|
|
2
2
|
import type { PromptCommandHandler } from "./runner.js";
|
|
3
3
|
import type { RemoteAuthFlow } from "./remote-auth.js";
|
|
4
4
|
import type { TuiSetupFlows } from "./setup-commands.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{
|
|
1
|
+
import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{modelChangeRefusalForUneditableModel:t}=await import(`#setup/flows/model.js`),{changeAgentModel:i,formatApplyModelOutcome:a}=await import(`#setup/flows/model-source-change.js`),o=await(n.modelChangeRefusal??t)(e);return o===null?{message:a(await(n.applyModel??i)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o,disabledConnectionReasons:i.disabledConnectionReasons};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{i.keepSetupFlowOpen!==!0&&o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{createTuiPrompter}from"./tui-prompter.js";import{describeRemoteAuthCompletedMutations}from"./remote-auth-result.js";import{runRemoteAuthFlow}from"./remote-auth.js";import{remoteHost}from"./target.js";import{WizardCancelledError}from"#setup/step.js";function shouldConfigureTrustedSources(e){switch(e.state){case`auth-required`:case`auth-failed`:return e.challenge.kind===`vercel-deployment-protection`;case`unavailable`:return e.failure.code===`TRUSTED_SOURCES_ENVIRONMENT_MISMATCH`;case`checking`:case`authenticating`:case`ready`:return!1}}function unavailableAfterAuthentication(e,t){let[n=t,...r]=t.split(/\n\s*\n/u);return[`Authentication was refreshed, but ${e} is unavailable: ${/[.!?]$/u.test(n.trim())?n.trim():`${n.trim()}.`}`,...r.map(e=>e.trim()).filter(e=>e.length>0)].join(`
|
|
2
2
|
|
|
3
|
-
`)}function mutedRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runRemoteAuthCommand(i){i.renderer.begin(`Authenticate via Vercel OIDC`,`pulse`);let a=!0,o=!1,s=new AbortController,c=i.renderer.waitForInterrupt(),l=i.connection.current().target;try{let u=i.flow??runRemoteAuthFlow,d=shouldConfigureTrustedSources(i.connection.current().connection),f=createTuiPrompter(mutedRenderer(i.renderer,()=>o)),p=i.connection.authenticate(async e=>{let t=await u({workspaceRoot:l.workspaceRoot,serverUrl:l.serverUrl,configureTrustedSources:d,prompter:f,signal:e});return a=t.kind===`failed`,t},s.signal),m=await Promise.race([p.then(e=>({kind:`completed`,outcome:e})),c.promise.then(()=>({kind:`interrupted`}))]);m.kind===`interrupted`&&(o=!0,a=!0,s.abort(new WizardCancelledError));let h=m.kind===`completed`?m.outcome:await p;switch(h.kind){case`authenticated`:return`Authenticated ${remoteHost(l)} via Vercel OIDC.`;case`cancelled`:if(o){let e=describeRemoteAuthCompletedMutations(h.completedMutations);return e.length===0?`/vc:login interrupted.`:`/vc:login interrupted. Completed before interruption: ${e.join(`, `)}.`}return h.completedMutations.some(e=>e.kind===`vercel-login`)?`/vc:login
|
|
3
|
+
`)}function mutedRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runRemoteAuthCommand(i){i.renderer.begin(`Authenticate via Vercel OIDC`,`pulse`);let a=!0,o=!1,s=new AbortController,c=i.renderer.waitForInterrupt(),l=i.connection.current().target;try{let u=i.flow??runRemoteAuthFlow,d=shouldConfigureTrustedSources(i.connection.current().connection),f=createTuiPrompter(mutedRenderer(i.renderer,()=>o)),p=i.connection.authenticate(async e=>{let t=await u({workspaceRoot:l.workspaceRoot,serverUrl:l.serverUrl,configureTrustedSources:d,prompter:f,signal:e});return a=t.kind===`failed`,t},s.signal),m=await Promise.race([p.then(e=>({kind:`completed`,outcome:e})),c.promise.then(()=>({kind:`interrupted`}))]);m.kind===`interrupted`&&(o=!0,a=!0,s.abort(new WizardCancelledError));let h=m.kind===`completed`?m.outcome:await p;switch(h.kind){case`authenticated`:return`Authenticated ${remoteHost(l)} via Vercel OIDC.`;case`cancelled`:if(o){let e=describeRemoteAuthCompletedMutations(h.completedMutations);return e.length===0?`/vc:login interrupted.`:`/vc:login interrupted. Completed before interruption: ${e.join(`, `)}.`}return h.completedMutations.some(e=>e.kind===`vercel-login`)?`/vc:login dismissed after logging in to Vercel.`:`/vc:login dismissed.`;case`failed`:return h.message;case`unavailable`:return unavailableAfterAuthentication(remoteHost(l),h.failure.message)}}finally{c.dispose(),i.renderer.setStatus(void 0),i.renderer.end({preserveDiagnostics:a})}}export{runRemoteAuthCommand};
|
|
@@ -12,6 +12,7 @@ import { type VercelStatusEffect, type VercelStatusSnapshot } from "./vercel-sta
|
|
|
12
12
|
import { type McpConnectionProbe } from "./mcp-connection-status.js";
|
|
13
13
|
import type { detectProjectIdentity } from "#setup/project-resolution.js";
|
|
14
14
|
import { getVercelAuthStatus } from "#setup/vercel-project.js";
|
|
15
|
+
import type { DevDiagnostics } from "../diagnostics.js";
|
|
15
16
|
export { parsePromptCommand, type PromptCommand } from "./prompt-commands.js";
|
|
16
17
|
export type AgentTUIStreamResult = {
|
|
17
18
|
events: AsyncIterable<AgentTUIStreamEvent> | ReadableStream<AgentTUIStreamEvent>;
|
|
@@ -62,12 +63,14 @@ export type AgentTUIStreamEvent = {
|
|
|
62
63
|
} | {
|
|
63
64
|
type: "error";
|
|
64
65
|
errorText: string;
|
|
66
|
+
hint?: string;
|
|
65
67
|
detail?: string;
|
|
66
68
|
} | {
|
|
67
69
|
type: "finish";
|
|
68
70
|
usage?: AgentTUIStreamUsage;
|
|
69
71
|
};
|
|
70
72
|
export type AgentTUITurnState = {
|
|
73
|
+
aborted?: boolean;
|
|
71
74
|
boundaryEvent?: "session.completed" | "session.failed" | "session.waiting";
|
|
72
75
|
pendingApprovals: AgentTUIToolApprovalRequest[];
|
|
73
76
|
pendingQuestions: InputRequest[];
|
|
@@ -311,6 +314,8 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
|
|
|
311
314
|
getVercelAuthStatus?: typeof getVercelAuthStatus;
|
|
312
315
|
/** Reports phases from this runner's initial local-dev connection. */
|
|
313
316
|
onBootProgress?: DevBootProgressReporter;
|
|
317
|
+
/** Parent-owned diagnostics recorder; omitted for remote and test renderers. */
|
|
318
|
+
diagnostics?: DevDiagnostics;
|
|
314
319
|
};
|
|
315
320
|
export declare class EveTUIRunner {
|
|
316
321
|
#private;
|