@wrenai/genbi 0.0.1
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/LICENSE +201 -0
- package/README.md +141 -0
- package/bin/genbi.mjs +31 -0
- package/dist/assets/echarts-LTFC-ysd.js +40 -0
- package/dist/assets/index-Bo--QMUN.js +441 -0
- package/dist/assets/index-Xs4q7pNo.css +1 -0
- package/dist/index.html +14 -0
- package/dist/wrenai_logo.png +0 -0
- package/dist/wrenai_logo_white.png +0 -0
- package/dist-server/harness/auth/detect.d.ts +18 -0
- package/dist-server/harness/auth/detect.js +37 -0
- package/dist-server/harness/auth/index.d.ts +4 -0
- package/dist-server/harness/auth/index.js +2 -0
- package/dist-server/harness/auth/probe.d.ts +18 -0
- package/dist-server/harness/auth/probe.js +52 -0
- package/dist-server/harness/auth/types.d.ts +42 -0
- package/dist-server/harness/auth/types.js +9 -0
- package/dist-server/harness/bundle/loader.d.ts +32 -0
- package/dist-server/harness/bundle/loader.js +43 -0
- package/dist-server/harness/bundle/schema.d.ts +199 -0
- package/dist-server/harness/bundle/schema.js +127 -0
- package/dist-server/harness/bundle/version.d.ts +10 -0
- package/dist-server/harness/bundle/version.js +43 -0
- package/dist-server/harness/capability/gate.d.ts +6 -0
- package/dist-server/harness/capability/gate.js +29 -0
- package/dist-server/harness/capability/registry.d.ts +6 -0
- package/dist-server/harness/capability/registry.js +17 -0
- package/dist-server/harness/cli-args.d.ts +123 -0
- package/dist-server/harness/cli-args.js +247 -0
- package/dist-server/harness/cli.d.ts +2 -0
- package/dist-server/harness/cli.js +151 -0
- package/dist-server/harness/compile/cache.d.ts +23 -0
- package/dist-server/harness/compile/cache.js +109 -0
- package/dist-server/harness/compile/compose-profile.d.ts +34 -0
- package/dist-server/harness/compile/compose-profile.js +95 -0
- package/dist-server/harness/compile/errors.d.ts +22 -0
- package/dist-server/harness/compile/errors.js +41 -0
- package/dist-server/harness/compile/fingerprint.d.ts +22 -0
- package/dist-server/harness/compile/fingerprint.js +84 -0
- package/dist-server/harness/compile/index.d.ts +8 -0
- package/dist-server/harness/compile/index.js +7 -0
- package/dist-server/harness/compile/pipeline.d.ts +66 -0
- package/dist-server/harness/compile/pipeline.js +176 -0
- package/dist-server/harness/compile/resolve-binary.d.ts +55 -0
- package/dist-server/harness/compile/resolve-binary.js +133 -0
- package/dist-server/harness/compile/types.d.ts +107 -0
- package/dist-server/harness/compile/types.js +1 -0
- package/dist-server/harness/compile/warble-identity.d.ts +12 -0
- package/dist-server/harness/compile/warble-identity.js +33 -0
- package/dist-server/harness/compliance/gate.d.ts +35 -0
- package/dist-server/harness/compliance/gate.js +48 -0
- package/dist-server/harness/compliance/index.d.ts +2 -0
- package/dist-server/harness/compliance/index.js +1 -0
- package/dist-server/harness/compliance/types.d.ts +16 -0
- package/dist-server/harness/compliance/types.js +1 -0
- package/dist-server/harness/events/emitter.d.ts +34 -0
- package/dist-server/harness/events/emitter.js +25 -0
- package/dist-server/harness/events/index.d.ts +4 -0
- package/dist-server/harness/events/index.js +2 -0
- package/dist-server/harness/events/sse.d.ts +20 -0
- package/dist-server/harness/events/sse.js +48 -0
- package/dist-server/harness/events/types.d.ts +131 -0
- package/dist-server/harness/events/types.js +1 -0
- package/dist-server/harness/exec/errors.d.ts +16 -0
- package/dist-server/harness/exec/errors.js +29 -0
- package/dist-server/harness/exec/index.d.ts +5 -0
- package/dist-server/harness/exec/index.js +2 -0
- package/dist-server/harness/exec/local.d.ts +32 -0
- package/dist-server/harness/exec/local.js +134 -0
- package/dist-server/harness/exec/policy.d.ts +12 -0
- package/dist-server/harness/exec/policy.js +1 -0
- package/dist-server/harness/exec/types.d.ts +63 -0
- package/dist-server/harness/exec/types.js +1 -0
- package/dist-server/harness/guardrails/index.d.ts +2 -0
- package/dist-server/harness/guardrails/index.js +1 -0
- package/dist-server/harness/guardrails/policy.d.ts +45 -0
- package/dist-server/harness/guardrails/policy.js +57 -0
- package/dist-server/harness/index.d.ts +37 -0
- package/dist-server/harness/index.js +19 -0
- package/dist-server/harness/loop/errors.d.ts +53 -0
- package/dist-server/harness/loop/errors.js +72 -0
- package/dist-server/harness/loop/executor.d.ts +123 -0
- package/dist-server/harness/loop/executor.js +380 -0
- package/dist-server/harness/loop/guard.d.ts +16 -0
- package/dist-server/harness/loop/guard.js +1 -0
- package/dist-server/harness/loop/index.d.ts +5 -0
- package/dist-server/harness/loop/index.js +3 -0
- package/dist-server/harness/native-producer/index.d.ts +109 -0
- package/dist-server/harness/native-producer/index.js +302 -0
- package/dist-server/harness/npm-package-resolve.d.ts +28 -0
- package/dist-server/harness/npm-package-resolve.js +47 -0
- package/dist-server/harness/providers/adapters/anthropic.d.ts +7 -0
- package/dist-server/harness/providers/adapters/anthropic.js +6 -0
- package/dist-server/harness/providers/adapters/mock.d.ts +4 -0
- package/dist-server/harness/providers/adapters/mock.js +5 -0
- package/dist-server/harness/providers/adapters/openai-compatible.d.ts +10 -0
- package/dist-server/harness/providers/adapters/openai-compatible.js +10 -0
- package/dist-server/harness/providers/binding.d.ts +23 -0
- package/dist-server/harness/providers/binding.js +13 -0
- package/dist-server/harness/providers/errors.d.ts +6 -0
- package/dist-server/harness/providers/errors.js +12 -0
- package/dist-server/harness/providers/index.d.ts +18 -0
- package/dist-server/harness/providers/index.js +22 -0
- package/dist-server/harness/providers/registry.d.ts +16 -0
- package/dist-server/harness/providers/registry.js +24 -0
- package/dist-server/harness/render/envelope.d.ts +145 -0
- package/dist-server/harness/render/envelope.js +428 -0
- package/dist-server/harness/render/errors.d.ts +33 -0
- package/dist-server/harness/render/errors.js +46 -0
- package/dist-server/harness/render/index.d.ts +5 -0
- package/dist-server/harness/render/index.js +3 -0
- package/dist-server/harness/render/validate.d.ts +13 -0
- package/dist-server/harness/render/validate.js +88 -0
- package/dist-server/harness/route/adapter-spec.d.ts +40 -0
- package/dist-server/harness/route/adapter-spec.js +61 -0
- package/dist-server/harness/route/agent-sdk-cli.d.ts +30 -0
- package/dist-server/harness/route/agent-sdk-cli.js +86 -0
- package/dist-server/harness/route/agent-sdk-manifest.d.ts +31 -0
- package/dist-server/harness/route/agent-sdk-manifest.js +56 -0
- package/dist-server/harness/route/artifact-content.d.ts +53 -0
- package/dist-server/harness/route/artifact-content.js +83 -0
- package/dist-server/harness/route/chat-event-mapper.d.ts +95 -0
- package/dist-server/harness/route/chat-event-mapper.js +164 -0
- package/dist-server/harness/route/codex-ask-events.d.ts +25 -0
- package/dist-server/harness/route/codex-ask-events.js +395 -0
- package/dist-server/harness/route/codex-ask.d.ts +15 -0
- package/dist-server/harness/route/codex-ask.js +242 -0
- package/dist-server/harness/route/codex-local-cli.d.ts +20 -0
- package/dist-server/harness/route/codex-local-cli.js +78 -0
- package/dist-server/harness/route/codex-local-manifest.d.ts +22 -0
- package/dist-server/harness/route/codex-local-manifest.js +180 -0
- package/dist-server/harness/route/describe.d.ts +54 -0
- package/dist-server/harness/route/describe.js +84 -0
- package/dist-server/harness/route/dispatched.d.ts +138 -0
- package/dist-server/harness/route/dispatched.js +339 -0
- package/dist-server/harness/route/in-process.d.ts +43 -0
- package/dist-server/harness/route/in-process.js +106 -0
- package/dist-server/harness/route/index.d.ts +19 -0
- package/dist-server/harness/route/index.js +12 -0
- package/dist-server/harness/route/profile-source.d.ts +37 -0
- package/dist-server/harness/route/profile-source.js +76 -0
- package/dist-server/harness/route/route.d.ts +33 -0
- package/dist-server/harness/route/route.js +114 -0
- package/dist-server/harness/route/tier-binding.d.ts +36 -0
- package/dist-server/harness/route/tier-binding.js +63 -0
- package/dist-server/harness/route/types.d.ts +286 -0
- package/dist-server/harness/route/types.js +1 -0
- package/dist-server/harness/session/errors.d.ts +4 -0
- package/dist-server/harness/session/errors.js +7 -0
- package/dist-server/harness/session/gate.d.ts +11 -0
- package/dist-server/harness/session/gate.js +13 -0
- package/dist-server/harness/session/index.d.ts +5 -0
- package/dist-server/harness/session/index.js +3 -0
- package/dist-server/harness/session/run.d.ts +60 -0
- package/dist-server/harness/session/run.js +333 -0
- package/dist-server/harness/session/types.d.ts +29 -0
- package/dist-server/harness/session/types.js +1 -0
- package/dist-server/harness/setup/codex-events.d.ts +12 -0
- package/dist-server/harness/setup/codex-events.js +108 -0
- package/dist-server/harness/setup/runner.d.ts +497 -0
- package/dist-server/harness/setup/runner.js +1314 -0
- package/dist-server/harness/tools/errors.d.ts +107 -0
- package/dist-server/harness/tools/errors.js +141 -0
- package/dist-server/harness/tools/index.d.ts +13 -0
- package/dist-server/harness/tools/index.js +8 -0
- package/dist-server/harness/tools/mcp.d.ts +26 -0
- package/dist-server/harness/tools/mcp.js +15 -0
- package/dist-server/harness/tools/native.d.ts +179 -0
- package/dist-server/harness/tools/native.js +322 -0
- package/dist-server/harness/tools/parse.d.ts +14 -0
- package/dist-server/harness/tools/parse.js +18 -0
- package/dist-server/harness/tools/resolve-wren-binary.d.ts +12 -0
- package/dist-server/harness/tools/resolve-wren-binary.js +21 -0
- package/dist-server/harness/tools/resolve.d.ts +51 -0
- package/dist-server/harness/tools/resolve.js +79 -0
- package/dist-server/harness/tools/setup-native.d.ts +84 -0
- package/dist-server/harness/tools/setup-native.js +353 -0
- package/dist-server/harness/tools/wiring.d.ts +10 -0
- package/dist-server/harness/tools/wiring.js +16 -0
- package/dist-server/providers/setup.provider.yaml +31 -0
- package/dist-server/providers/wren.provider.yaml +33 -0
- package/dist-server/server/adopt.d.ts +87 -0
- package/dist-server/server/adopt.js +263 -0
- package/dist-server/server/app.d.ts +6 -0
- package/dist-server/server/app.js +2521 -0
- package/dist-server/server/auth-choice.d.ts +16 -0
- package/dist-server/server/auth-choice.js +36 -0
- package/dist-server/server/bin.d.ts +2 -0
- package/dist-server/server/bin.js +601 -0
- package/dist-server/server/bootstrap-project-binding.d.ts +31 -0
- package/dist-server/server/bootstrap-project-binding.js +71 -0
- package/dist-server/server/clarify.d.ts +10 -0
- package/dist-server/server/clarify.js +17 -0
- package/dist-server/server/codex-setup-mcp.d.ts +2 -0
- package/dist-server/server/codex-setup-mcp.js +147 -0
- package/dist-server/server/compose.d.ts +89 -0
- package/dist-server/server/compose.js +271 -0
- package/dist-server/server/conn-config.d.ts +30 -0
- package/dist-server/server/conn-config.js +253 -0
- package/dist-server/server/context-files.d.ts +12 -0
- package/dist-server/server/context-files.js +117 -0
- package/dist-server/server/context-map.d.ts +30 -0
- package/dist-server/server/context-map.js +95 -0
- package/dist-server/server/context-source.d.ts +68 -0
- package/dist-server/server/context-source.js +85 -0
- package/dist-server/server/db.d.ts +862 -0
- package/dist-server/server/db.js +1839 -0
- package/dist-server/server/enrichment-runner.d.ts +184 -0
- package/dist-server/server/enrichment-runner.js +213 -0
- package/dist-server/server/enrichment-verify.d.ts +73 -0
- package/dist-server/server/enrichment-verify.js +290 -0
- package/dist-server/server/enrichment.d.ts +232 -0
- package/dist-server/server/enrichment.js +199 -0
- package/dist-server/server/env-detect.d.ts +8 -0
- package/dist-server/server/env-detect.js +17 -0
- package/dist-server/server/env-field-hints.d.ts +46 -0
- package/dist-server/server/env-field-hints.js +48 -0
- package/dist-server/server/fold.d.ts +133 -0
- package/dist-server/server/fold.js +407 -0
- package/dist-server/server/harness-profile-sources.d.ts +3 -0
- package/dist-server/server/harness-profile-sources.js +24 -0
- package/dist-server/server/harness.d.ts +19 -0
- package/dist-server/server/harness.js +439 -0
- package/dist-server/server/impact.d.ts +18 -0
- package/dist-server/server/impact.js +85 -0
- package/dist-server/server/interactive-terminal.d.ts +175 -0
- package/dist-server/server/interactive-terminal.js +336 -0
- package/dist-server/server/native-artifacts.d.ts +1004 -0
- package/dist-server/server/native-artifacts.js +564 -0
- package/dist-server/server/native-dispatch-registry.d.ts +42 -0
- package/dist-server/server/native-dispatch-registry.js +45 -0
- package/dist-server/server/native-producer-fence.d.ts +14 -0
- package/dist-server/server/native-producer-fence.js +48 -0
- package/dist-server/server/native-session-resume.d.ts +6 -0
- package/dist-server/server/native-session-resume.js +103 -0
- package/dist-server/server/native-session-workspace.d.ts +40 -0
- package/dist-server/server/native-session-workspace.js +175 -0
- package/dist-server/server/native-sessions.d.ts +374 -0
- package/dist-server/server/native-sessions.js +1517 -0
- package/dist-server/server/native-wren-runtime.d.ts +20 -0
- package/dist-server/server/native-wren-runtime.js +259 -0
- package/dist-server/server/node-pty-host.d.ts +31 -0
- package/dist-server/server/node-pty-host.js +100 -0
- package/dist-server/server/route-intent.d.ts +40 -0
- package/dist-server/server/route-intent.js +23 -0
- package/dist-server/server/runtime-binding.d.ts +52 -0
- package/dist-server/server/runtime-binding.js +258 -0
- package/dist-server/server/source-catalog.d.ts +84 -0
- package/dist-server/server/source-catalog.js +221 -0
- package/dist-server/server/source-driver.d.ts +35 -0
- package/dist-server/server/source-driver.js +124 -0
- package/dist-server/server/spa.d.ts +2 -0
- package/dist-server/server/spa.js +51 -0
- package/dist-server/server/subscription-model-catalog.d.ts +27 -0
- package/dist-server/server/subscription-model-catalog.js +203 -0
- package/dist-server/server/turn.d.ts +249 -0
- package/dist-server/server/turn.js +1074 -0
- package/dist-server/server/wire-types.d.ts +799 -0
- package/dist-server/server/wire-types.js +1 -0
- package/dist-server/server/wren-home.d.ts +19 -0
- package/dist-server/server/wren-home.js +33 -0
- package/dist-server/server/wren-profiles.d.ts +43 -0
- package/dist-server/server/wren-profiles.js +123 -0
- package/package.json +93 -0
- package/profiles/genbi-default/context/binding.yml +9 -0
- package/profiles/genbi-default/ir.golden.json +506 -0
- package/profiles/genbi-default/profile.yml +16 -0
- package/profiles/genbi-enrich-context/components/apply_enrichment/component.yml +42 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/component.yml +30 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/steps/draft.md +34 -0
- package/profiles/genbi-enrich-context/components/inspect_context/component.yml +32 -0
- package/profiles/genbi-enrich-context/components/inspect_context/steps/inspect.md +13 -0
- package/profiles/genbi-enrich-context/context/binding.yml +4 -0
- package/profiles/genbi-enrich-context/ir.golden.json +302 -0
- package/profiles/genbi-enrich-context/profile.yml +15 -0
- package/profiles/genbi-monitor/context/binding.yml +7 -0
- package/profiles/genbi-monitor/ir.golden.json +188 -0
- package/profiles/genbi-monitor/profile.yml +27 -0
- package/profiles/genbi-setup/components/build_context/component.yml +44 -0
- package/profiles/genbi-setup/components/build_context/steps/build.md +14 -0
- package/profiles/genbi-setup/components/connect_source/component.yml +51 -0
- package/profiles/genbi-setup/components/connect_source/steps/connect.md +23 -0
- package/profiles/genbi-setup/context/binding.yml +8 -0
- package/profiles/genbi-setup/ir.golden.json +140 -0
- package/profiles/genbi-setup/profile.yml +18 -0
- package/profiles/genbi-setup/raw/schema.json +5 -0
|
@@ -0,0 +1,799 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BFF's UI-facing wire contract.
|
|
3
|
+
*
|
|
4
|
+
* These types are the UI's frozen consumer contract, reproduced verbatim
|
|
5
|
+
* (exact field names/casing) from the `WrenAI-genbi` frontend's expected
|
|
6
|
+
* shapes. They are deliberately NOT imported from that repo — this harness
|
|
7
|
+
* repo must not read or depend on it — so this file is the single source of
|
|
8
|
+
* truth for what the BFF serializes onto the wire. Keep it byte-for-byte in
|
|
9
|
+
* sync with the frontend if the UI contract ever changes; do not "improve" the
|
|
10
|
+
* shapes here independently of that source.
|
|
11
|
+
*
|
|
12
|
+
* The one exception is `RenderEnvelope`: that type is owned by this harness
|
|
13
|
+
* (`harness/render/index.ts`) and is imported directly rather than redefined.
|
|
14
|
+
*/
|
|
15
|
+
import type { RenderEnvelope } from "../harness/render/index.js";
|
|
16
|
+
import type { ArtifactContentDto, ArtifactContentUnavailableReason } from "../harness/route/index.js";
|
|
17
|
+
export type { RenderEnvelope };
|
|
18
|
+
export type { ArtifactContentDto, ArtifactContentUnavailableReason };
|
|
19
|
+
export type SessionEventKind = "user" | "clarify" | "answer" | "refusal" | "artifact" | "published" | "saved" | "setup_status";
|
|
20
|
+
/**
|
|
21
|
+
* A BFF-owned, bounded inspection record for a Setup work-log row. Unlike
|
|
22
|
+
* `input` and `detail`, this is safe to persist and return from Setup
|
|
23
|
+
* recovery: it contains only an allowlisted command/action summary, output
|
|
24
|
+
* or an actionable error, and an optional elapsed duration.
|
|
25
|
+
*/
|
|
26
|
+
export interface ToolStepInspection {
|
|
27
|
+
readonly action?: string;
|
|
28
|
+
readonly output?: string;
|
|
29
|
+
readonly error?: string;
|
|
30
|
+
readonly durationMs?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface ToolStep {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
readonly label: string;
|
|
35
|
+
readonly state: "running" | "done" | "error";
|
|
36
|
+
/**
|
|
37
|
+
* `"tool"` — a tool call. `"subagent"` — a nested sub-agent/Task turn
|
|
38
|
+
* (subscription dispatchers only; the in-process path has no such mechanism). `"step"` — one of
|
|
39
|
+
* In-process's own bundle-declared LLM steps (`step.start`/`step.finish`), i.e.
|
|
40
|
+
* the agent's own reasoning/output for that step, distinct from any tool
|
|
41
|
+
* calls it happened to make along the way. `"decision"` — a
|
|
42
|
+
* deterministic control-flow decision the BFF made for the turn (intent
|
|
43
|
+
* routing, clarify, verify-gate verdict), display-only; it is not produced
|
|
44
|
+
* by the agent runtime and carries no tool/step of its own.
|
|
45
|
+
*/
|
|
46
|
+
readonly kind: "tool" | "subagent" | "step" | "decision";
|
|
47
|
+
readonly parent?: string;
|
|
48
|
+
readonly depth?: number;
|
|
49
|
+
/** The tool call's input (e.g. the `query` tool's `{sql}`), so the UI can expand a step to show what it ran. */
|
|
50
|
+
readonly input?: unknown;
|
|
51
|
+
/** A compact, bounded summary — success result summary, or the error message on a failed step. Never full result rows. */
|
|
52
|
+
readonly detail?: string;
|
|
53
|
+
/** Server-owned safe projection used by Setup work logs; never raw tool input or detail. */
|
|
54
|
+
readonly inspection?: ToolStepInspection;
|
|
55
|
+
}
|
|
56
|
+
export interface UserEvent {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly kind: "user";
|
|
59
|
+
readonly text: string;
|
|
60
|
+
}
|
|
61
|
+
/** BFF-produced (see `server/clarify.ts`'s D1 heuristic) — never comes from the agent runtime. */
|
|
62
|
+
export interface ClarifyEvent {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly kind: "clarify";
|
|
65
|
+
readonly prompt: string;
|
|
66
|
+
readonly chips: readonly string[];
|
|
67
|
+
}
|
|
68
|
+
export interface TextAnswerPayload {
|
|
69
|
+
readonly form: "text";
|
|
70
|
+
readonly text: string;
|
|
71
|
+
readonly verified: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Whether this turn attempted a data task (ran a query or assembled a
|
|
74
|
+
* dashboard), including one that failed or was refused — as opposed to a
|
|
75
|
+
* pure conversational/capability reply that made no data claim at all.
|
|
76
|
+
* The UI shows the Verified/Unverified badge only when this is `true`;
|
|
77
|
+
* a conversational answer (`false`) hides the badge entirely rather than
|
|
78
|
+
* showing a misleading "Unverified".
|
|
79
|
+
*/
|
|
80
|
+
readonly dataAnswer: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface RichAnswerPayload {
|
|
83
|
+
readonly form: "rich";
|
|
84
|
+
readonly envelope: RenderEnvelope;
|
|
85
|
+
}
|
|
86
|
+
export interface AnswerEvent {
|
|
87
|
+
readonly id: string;
|
|
88
|
+
readonly kind: "answer";
|
|
89
|
+
readonly answer: TextAnswerPayload | RichAnswerPayload;
|
|
90
|
+
}
|
|
91
|
+
/** `fix` is BFF-synthesized — the agent runtime's `RefusalResult` carries no remediation text. */
|
|
92
|
+
export interface RefusalEvent {
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly kind: "refusal";
|
|
95
|
+
readonly reason: string;
|
|
96
|
+
readonly fix: string;
|
|
97
|
+
}
|
|
98
|
+
export type ArtifactKind = "dashboard" | "report" | "chart";
|
|
99
|
+
export interface ArtifactEvent {
|
|
100
|
+
/** Generic stream event id (`evt-*`) — used by the UI for React keys/dedup. Not the artifact row id. */
|
|
101
|
+
readonly id: string;
|
|
102
|
+
readonly kind: "artifact";
|
|
103
|
+
readonly name: string;
|
|
104
|
+
readonly artifactKind: ArtifactKind;
|
|
105
|
+
readonly location: string;
|
|
106
|
+
/** The persisted artifact row id (`artifact-*`, from `store.createArtifact`) — pass this to the publish route. */
|
|
107
|
+
readonly artifactId: string;
|
|
108
|
+
}
|
|
109
|
+
export type PublishScope = "workspace" | "link" | "public";
|
|
110
|
+
export interface PublishedEvent {
|
|
111
|
+
readonly id: string;
|
|
112
|
+
readonly kind: "published";
|
|
113
|
+
readonly artifactName: string;
|
|
114
|
+
readonly link: string;
|
|
115
|
+
readonly scope: PublishScope;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A distinct, persisted event marking that an artifact was saved
|
|
119
|
+
* to the Artifacts page. Deliberately NOT a field on `ArtifactEvent` itself:
|
|
120
|
+
* session events are replayed verbatim from storage (see
|
|
121
|
+
* `getAskSessionData`), so "is this saved" must be recomputed by the UI
|
|
122
|
+
* scanning for this event rather than baked into the artifact event's own
|
|
123
|
+
* stored payload — that's what makes the saved state correct after a
|
|
124
|
+
* reload/replay with zero extra bookkeeping.
|
|
125
|
+
*
|
|
126
|
+
* Keyed on `artifactId` (the persisted artifact row id), NOT `artifactName`:
|
|
127
|
+
* two artifacts in the same session can share a name (e.g. re-running the
|
|
128
|
+
* same prompt twice), and matching on name alone would mark the *other*,
|
|
129
|
+
* never-saved artifact as saved too — with no way left to save it from the
|
|
130
|
+
* UI. `artifactName` is kept for display only. (`PublishedEvent` has this
|
|
131
|
+
* same name-keyed flaw; it's intentionally left as-is since the publish UI
|
|
132
|
+
* is hidden behind `PUBLISH_UI_ENABLED` and tracked separately.)
|
|
133
|
+
*/
|
|
134
|
+
export interface SavedEvent {
|
|
135
|
+
readonly id: string;
|
|
136
|
+
readonly kind: "saved";
|
|
137
|
+
readonly artifactId: string;
|
|
138
|
+
readonly artifactName: string;
|
|
139
|
+
readonly savedAt: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The mirror of `SavedEvent`: marks that a previously-saved
|
|
143
|
+
* artifact was un-saved ("unpinned") from the Artifacts page. Appended
|
|
144
|
+
* instead of deleting the earlier `SavedEvent`: the session's event log is a
|
|
145
|
+
* persisted, replayed history (see `getAskSessionData`), and deleting a
|
|
146
|
+
* stored event would corrupt that replay. "Is this artifact currently saved"
|
|
147
|
+
* is instead recomputed by scanning for whichever `SavedEvent`/`UnsavedEvent`
|
|
148
|
+
* for this `artifactId` is most recent (latest-wins) — see the frontend's
|
|
149
|
+
* `isArtifactSaved`. Keyed on `artifactId`, not `artifactName`, for the same
|
|
150
|
+
* reason as `SavedEvent`.
|
|
151
|
+
*/
|
|
152
|
+
export interface UnsavedEvent {
|
|
153
|
+
readonly id: string;
|
|
154
|
+
readonly kind: "unsaved";
|
|
155
|
+
readonly artifactId: string;
|
|
156
|
+
readonly artifactName: string;
|
|
157
|
+
readonly unsavedAt: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* One resumable choice a setup turn is blocked on (`SetupStatusEvent.decision`
|
|
161
|
+
* or `SetupAdoptResponse.decision`, status `"needs_decision"`) — e.g. an
|
|
162
|
+
* `error_max_turns` checkpoint (continue vs stop), a same-name project
|
|
163
|
+
* conflict (rename/clean/cancel), an unbuilt-context confirmation
|
|
164
|
+
* (`build_context`: build/cancel), or an unpinned-project profile choice
|
|
165
|
+
* (`select_profile`: one option per candidate profile). `kind` distinguishes
|
|
166
|
+
* which checkpoint this is. Every kind except `select_profile` resolves via
|
|
167
|
+
* `POST /api/setup/decision`, which carries the `id` of the chosen `options`
|
|
168
|
+
* entry back; `select_profile` is stateless and instead resolves by
|
|
169
|
+
* re-POSTing `/api/setup/adopt` with the chosen option's `id` as `profile`
|
|
170
|
+
* (see `SetupAdoptResponse`'s doc comment). Kept minimal/generic (a bare
|
|
171
|
+
* string `kind`, not a closed union) so adding a future checkpoint kind never
|
|
172
|
+
* requires touching this wire type again.
|
|
173
|
+
*/
|
|
174
|
+
export interface SetupDecision {
|
|
175
|
+
readonly kind: string;
|
|
176
|
+
readonly options: readonly {
|
|
177
|
+
readonly id: string;
|
|
178
|
+
readonly label: string;
|
|
179
|
+
}[];
|
|
180
|
+
readonly detail?: string;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* `POST /api/setup/adopt`'s request body — the one required input is an
|
|
184
|
+
* absolute path to an existing wren project directory (has its own
|
|
185
|
+
* `wren_project.yml`; may or may not have a pinned `profile:` yet, and may or
|
|
186
|
+
* may not have a built `target/mdl.json` yet). Unlike the create flow's
|
|
187
|
+
* `projectName`, this is a full path, not a single safe path segment under a
|
|
188
|
+
* configured workspace root — adopt points at a project that can live
|
|
189
|
+
* anywhere on disk.
|
|
190
|
+
*
|
|
191
|
+
* `profile` is optional and only ever sent on a *second* call: when the
|
|
192
|
+
* first call comes back `needs_decision` with `decision.kind ===
|
|
193
|
+
* "select_profile"`, the caller re-POSTs the same `projectPath` plus the
|
|
194
|
+
* chosen candidate's `name` as `profile`. That re-POST runs
|
|
195
|
+
* `wren context set-profile <profile>` to write a durable pin before
|
|
196
|
+
* re-verifying — see `server/adopt.ts`'s module doc comment for the full
|
|
197
|
+
* three-state flow this drives.
|
|
198
|
+
*/
|
|
199
|
+
export interface SetupAdoptRequest {
|
|
200
|
+
readonly projectPath: string;
|
|
201
|
+
readonly profile?: string;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* `POST /api/setup/adopt`'s synchronous response — verification (path
|
|
205
|
+
* validity, profile pin/resolution, live connection smoke test) runs inline,
|
|
206
|
+
* no SSE turn involved, so the outcome comes back as a plain JSON body
|
|
207
|
+
* rather than a streamed `SetupStatusEvent`. The three outcomes mirror
|
|
208
|
+
* `SetupStatusEvent.status` on purpose (same three-way shape the frontend
|
|
209
|
+
* already knows how to render), just delivered synchronously:
|
|
210
|
+
*
|
|
211
|
+
* - `"ok"`: the project verified AND already has a built context — bound
|
|
212
|
+
* immediately, wizard lands on "bind".
|
|
213
|
+
* - `"needs_decision"`: the project verified but needs one more round-trip
|
|
214
|
+
* before it can bind. Two distinct checkpoints share this status, told
|
|
215
|
+
* apart by `decision.kind`:
|
|
216
|
+
* - `"build_context"` (options `"build"` | `"cancel"`) — connection
|
|
217
|
+
* verified, no built context yet. Resolve via the existing
|
|
218
|
+
* `POST /api/setup/decision` endpoint; choosing "build" dispatches the
|
|
219
|
+
* same `build_context` agentic turn the create flow's context step
|
|
220
|
+
* uses (open its `{turnId}` on
|
|
221
|
+
* `GET /api/sessions/:id/stream?turn=<turnId>` exactly like a
|
|
222
|
+
* context-step turn), and binds the project once that turn's
|
|
223
|
+
* `SETUP_STATUS: ok` verifies `target/mdl.json`. Choosing "cancel"
|
|
224
|
+
* just drops the pending decision — nothing was bound, so there's
|
|
225
|
+
* nothing to undo. Returned with HTTP 200.
|
|
226
|
+
* - `"select_profile"` (one option per candidate profile, `id`/`label`
|
|
227
|
+
* both the profile name) — the project has no `profile:` pin, but one
|
|
228
|
+
* or more profiles in `~/.wren/profiles.yml` share its `data_source`.
|
|
229
|
+
* Each candidate is `{name, datasource}` only — never any other
|
|
230
|
+
* profile field (host/port/credentials never cross the wire). Resolve
|
|
231
|
+
* by re-POSTing `/api/setup/adopt` with `profile` set to the chosen
|
|
232
|
+
* candidate's name (NOT via `/api/setup/decision` — that endpoint's
|
|
233
|
+
* session/pending-decision bookkeeping doesn't apply here, this
|
|
234
|
+
* checkpoint is stateless). Returned with **HTTP 409**, not 200 — see
|
|
235
|
+
* below.
|
|
236
|
+
* - `"error"`: verification failed (bad path, no `wren_project.yml`,
|
|
237
|
+
* unsupported connector, no compatible profile found for an unpinned
|
|
238
|
+
* project, or a failed live smoke query) — nothing was bound. `message`
|
|
239
|
+
* names which check failed.
|
|
240
|
+
*
|
|
241
|
+
* HTTP status: `"ok"` and `"needs_decision"` with `decision.kind ===
|
|
242
|
+
* "build_context"` both return 200 (a well-formed request that produced a
|
|
243
|
+
* definite, structured result needing no retry of the *same* request).
|
|
244
|
+
* `"needs_decision"` with `decision.kind === "select_profile"` returns
|
|
245
|
+
* **409 Conflict** instead, since the caller must re-issue a *different*
|
|
246
|
+
* request (this same route, with `profile` now set) to proceed — the 409
|
|
247
|
+
* signals "resubmit with more information," which plain 200 does not.
|
|
248
|
+
* `"error"` also returns 200 (a well-formed request whose verification
|
|
249
|
+
* failed is still a successful call to this endpoint); 400 is reserved for a
|
|
250
|
+
* malformed request (missing/non-string `projectPath`).
|
|
251
|
+
*/
|
|
252
|
+
export interface SetupAdoptResponse {
|
|
253
|
+
readonly sessionId?: string;
|
|
254
|
+
readonly status: "ok" | "needs_decision" | "error";
|
|
255
|
+
readonly message: string;
|
|
256
|
+
readonly decision?: SetupDecision;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Terminal event for a setup-wizard turn (agentic `connect`/`connect_resume`
|
|
260
|
+
* dispatch — see `harness/setup/runner.ts`'s `parseSetupTerminal`). Distinct from
|
|
261
|
+
* `AnswerEvent`: a setup turn's finalText is a scaffolding narration, not an
|
|
262
|
+
* answer to show verbatim, and its outcome is one of four states the UI must
|
|
263
|
+
* branch on (advance the wizard / prompt for `.env` completion / show an
|
|
264
|
+
* error / resolve a checkpoint decision), not a yes/no verified answer.
|
|
265
|
+
* `decision` is present iff `status === "needs_decision"`.
|
|
266
|
+
*/
|
|
267
|
+
export interface SetupStatusEvent {
|
|
268
|
+
readonly id: string;
|
|
269
|
+
readonly kind: "setup_status";
|
|
270
|
+
readonly status: "ok" | "needs_input" | "error" | "needs_decision";
|
|
271
|
+
readonly message: string;
|
|
272
|
+
readonly decision?: SetupDecision;
|
|
273
|
+
}
|
|
274
|
+
export type SessionEvent = UserEvent | ClarifyEvent | AnswerEvent | RefusalEvent | ArtifactEvent | PublishedEvent | SavedEvent | UnsavedEvent | SetupStatusEvent;
|
|
275
|
+
export interface AskSessionData {
|
|
276
|
+
readonly id: string;
|
|
277
|
+
readonly title: string;
|
|
278
|
+
readonly updatedAt: string;
|
|
279
|
+
readonly events: readonly SessionEvent[];
|
|
280
|
+
readonly workLog: readonly ToolStep[];
|
|
281
|
+
}
|
|
282
|
+
export interface SessionSummary {
|
|
283
|
+
readonly id: string;
|
|
284
|
+
readonly title: string;
|
|
285
|
+
readonly updatedAt: string;
|
|
286
|
+
}
|
|
287
|
+
export type SemanticColumnKey = "pk" | "fk";
|
|
288
|
+
export interface SemanticColumn {
|
|
289
|
+
readonly name: string;
|
|
290
|
+
readonly type: string;
|
|
291
|
+
readonly key?: SemanticColumnKey;
|
|
292
|
+
}
|
|
293
|
+
export interface SemanticModel {
|
|
294
|
+
readonly key: string;
|
|
295
|
+
readonly name: string;
|
|
296
|
+
readonly columns: readonly SemanticColumn[];
|
|
297
|
+
/** Optional: the BFF's live-project remap has no ER layout source and omits this — the UI must lay itself out when absent. Still populated by the seeded fixture path. */
|
|
298
|
+
readonly position?: {
|
|
299
|
+
readonly x: number;
|
|
300
|
+
readonly y: number;
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
export type RelationshipType = "one-to-one" | "one-to-many" | "many-to-one" | "many-to-many";
|
|
304
|
+
export interface SemanticRelationship {
|
|
305
|
+
readonly key: string;
|
|
306
|
+
readonly name: string;
|
|
307
|
+
readonly fromModel: string;
|
|
308
|
+
readonly toModel: string;
|
|
309
|
+
readonly type: RelationshipType;
|
|
310
|
+
}
|
|
311
|
+
export type MeasureAdditivity = "additive" | "non-additive";
|
|
312
|
+
export interface SemanticMeasure {
|
|
313
|
+
readonly key: string;
|
|
314
|
+
readonly name: string;
|
|
315
|
+
readonly baseModel: string;
|
|
316
|
+
readonly expression: string;
|
|
317
|
+
readonly additivity: MeasureAdditivity;
|
|
318
|
+
}
|
|
319
|
+
export interface KnowledgeStatus {
|
|
320
|
+
readonly instructionsPresent: boolean;
|
|
321
|
+
readonly verifiedPairCount: number;
|
|
322
|
+
}
|
|
323
|
+
export interface ContextOverview {
|
|
324
|
+
readonly models: readonly SemanticModel[];
|
|
325
|
+
readonly relationships: readonly SemanticRelationship[];
|
|
326
|
+
readonly measures: readonly SemanticMeasure[];
|
|
327
|
+
readonly knowledge: KnowledgeStatus;
|
|
328
|
+
readonly projectName: string;
|
|
329
|
+
/** The full bound project directory path (`resolveUserProject`), not just its basename — "" when unbound, same guard as `projectName`. */
|
|
330
|
+
readonly projectPath: string;
|
|
331
|
+
}
|
|
332
|
+
export type ContextFileKind = "model" | "relationship" | "cube" | "knowledge" | "view";
|
|
333
|
+
export interface ContextFileNode {
|
|
334
|
+
readonly key: string;
|
|
335
|
+
readonly title: string;
|
|
336
|
+
readonly children?: readonly ContextFileNode[];
|
|
337
|
+
readonly kind?: ContextFileKind;
|
|
338
|
+
readonly path?: string;
|
|
339
|
+
readonly content?: string;
|
|
340
|
+
readonly entityKey?: string;
|
|
341
|
+
}
|
|
342
|
+
export type ImpactSeverity = "none" | "compatibility" | "structural" | "semantic";
|
|
343
|
+
export type ImpactNodeKind = "model" | "measure" | "relationship" | "view";
|
|
344
|
+
export interface ImpactNode {
|
|
345
|
+
readonly key: string;
|
|
346
|
+
readonly name: string;
|
|
347
|
+
readonly kind: ImpactNodeKind;
|
|
348
|
+
}
|
|
349
|
+
export interface BlastRadius {
|
|
350
|
+
readonly seed: ImpactNode;
|
|
351
|
+
readonly downstream: readonly ImpactNode[];
|
|
352
|
+
readonly severity: ImpactSeverity;
|
|
353
|
+
}
|
|
354
|
+
export interface BrokenPair {
|
|
355
|
+
readonly question: string;
|
|
356
|
+
readonly refs: readonly string[];
|
|
357
|
+
readonly hitDownstreamKeys: readonly string[];
|
|
358
|
+
}
|
|
359
|
+
export interface ImpactResponse {
|
|
360
|
+
readonly blastRadius: BlastRadius;
|
|
361
|
+
readonly brokenPairs: readonly BrokenPair[];
|
|
362
|
+
}
|
|
363
|
+
export interface EvalRun {
|
|
364
|
+
readonly id: string;
|
|
365
|
+
readonly when: string;
|
|
366
|
+
readonly score: number;
|
|
367
|
+
readonly gateThreshold: number;
|
|
368
|
+
readonly gatePass: boolean;
|
|
369
|
+
readonly regressions: number;
|
|
370
|
+
readonly cost: string;
|
|
371
|
+
readonly p50: string;
|
|
372
|
+
}
|
|
373
|
+
export interface ComponentScore {
|
|
374
|
+
readonly component: string;
|
|
375
|
+
readonly score: number;
|
|
376
|
+
readonly delta: number;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* `"adopt"` stands in for `"connect"` in the step SEQUENCE (not alongside it)
|
|
380
|
+
* once the wizard's mode is `"adopt"` — see `SetupMode`/`GET+POST
|
|
381
|
+
* /api/setup/mode`: the adopt flow points at an existing project directory
|
|
382
|
+
* (`POST /api/setup/adopt`) instead of scaffolding+crediting a new one, so it
|
|
383
|
+
* has no need for a separate "connect" step. `POST /api/setup/mode` rewrites
|
|
384
|
+
* `setup.steps` to swap the one entry for the other; the array is always
|
|
385
|
+
* exactly one of {`"connect"`, `"adopt"`}, never both.
|
|
386
|
+
*/
|
|
387
|
+
export type StepKey = "runtime" | "connect" | "adopt" | "context" | "bind" | "ask";
|
|
388
|
+
export type StepState = "done" | "current" | "todo";
|
|
389
|
+
export interface SetupStep {
|
|
390
|
+
readonly key: StepKey;
|
|
391
|
+
readonly title: string;
|
|
392
|
+
readonly state: StepState;
|
|
393
|
+
}
|
|
394
|
+
/** A safe, read-only snapshot of the most recent retryable setup failure. */
|
|
395
|
+
export interface SetupFailureRecovery {
|
|
396
|
+
readonly attempt: "connect" | "connect_resume" | "context";
|
|
397
|
+
readonly projectName: string;
|
|
398
|
+
readonly sourceType: string;
|
|
399
|
+
readonly error: string;
|
|
400
|
+
readonly workLog: readonly ToolStep[];
|
|
401
|
+
}
|
|
402
|
+
/** Safe reload snapshot for a completed setup turn paused on user input. */
|
|
403
|
+
export interface SetupNeedsInputRecovery {
|
|
404
|
+
readonly attempt: "connect" | "connect_resume" | "context";
|
|
405
|
+
readonly projectName: string;
|
|
406
|
+
readonly sourceType: string;
|
|
407
|
+
readonly message: string;
|
|
408
|
+
readonly workLog: readonly ToolStep[];
|
|
409
|
+
}
|
|
410
|
+
/** `GET /api/setup/recovery` intentionally exposes no SDK session anchor. */
|
|
411
|
+
export interface SetupRecoveryResponse {
|
|
412
|
+
readonly failure?: SetupFailureRecovery;
|
|
413
|
+
/** Latest public paused terminal; its `sessionId` is the BFF setup session, never an SDK id. */
|
|
414
|
+
readonly needsInput?: SetupNeedsInputRecovery;
|
|
415
|
+
/** Reload-safe public context decision; never includes a provider anchor. */
|
|
416
|
+
readonly sessionId?: string;
|
|
417
|
+
readonly decision?: SetupDecision;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* The setup wizard's two entry paths, chosen once at wizard start (`POST
|
|
421
|
+
* /api/setup/mode`): `"create"` scaffolds a brand-new project (the
|
|
422
|
+
* pre-existing connect -> context -> bind flow, unchanged); `"adopt"` points
|
|
423
|
+
* the wizard at an existing wren project directory (`POST /api/setup/adopt`)
|
|
424
|
+
* and — when that project already has a built `target/mdl.json` — skips
|
|
425
|
+
* straight to bind, no context step needed. `GET /api/setup/mode` returns
|
|
426
|
+
* `{ mode: undefined }` before the user has picked either, which the frontend
|
|
427
|
+
* reads as "show the create-vs-adopt choice screen."
|
|
428
|
+
*/
|
|
429
|
+
export type SetupMode = "create" | "adopt";
|
|
430
|
+
/**
|
|
431
|
+
* One field key discovered in the scaffolded project's `.env` template (see
|
|
432
|
+
* `GET /api/setup/connect/env-fields`, `server/app.ts`) — never a value, only
|
|
433
|
+
* the key name plus a secret/non-secret display hint so the frontend can
|
|
434
|
+
* render a masked `Input.Password` for credential-shaped keys.
|
|
435
|
+
*/
|
|
436
|
+
export interface SetupEnvField {
|
|
437
|
+
readonly key: string;
|
|
438
|
+
readonly secret: boolean;
|
|
439
|
+
}
|
|
440
|
+
export type AuthMode = "subscription" | "byo" | "local";
|
|
441
|
+
export type Deployment = "personal" | "hosted";
|
|
442
|
+
export type SubscriptionProvider = "claude" | "codex";
|
|
443
|
+
/** One non-sensitive model suggestion reported by the signed-in subscription provider. */
|
|
444
|
+
export interface SubscriptionModelCatalogEntry {
|
|
445
|
+
readonly model: string;
|
|
446
|
+
readonly displayName: string;
|
|
447
|
+
readonly description?: string;
|
|
448
|
+
readonly isDefault?: boolean;
|
|
449
|
+
readonly reasoningEfforts?: readonly {
|
|
450
|
+
readonly value: string;
|
|
451
|
+
readonly displayName: string;
|
|
452
|
+
readonly description?: string;
|
|
453
|
+
}[];
|
|
454
|
+
}
|
|
455
|
+
/** Sanitized result of provider-owned model discovery. */
|
|
456
|
+
export type SubscriptionModelCatalog = {
|
|
457
|
+
readonly version: 1;
|
|
458
|
+
readonly status: "ready";
|
|
459
|
+
readonly provider: SubscriptionProvider;
|
|
460
|
+
readonly models: readonly SubscriptionModelCatalogEntry[];
|
|
461
|
+
} | {
|
|
462
|
+
readonly version: 1;
|
|
463
|
+
readonly status: "unavailable";
|
|
464
|
+
readonly provider: SubscriptionProvider;
|
|
465
|
+
readonly code: "not_authenticated" | "runtime_unavailable" | "timeout" | "protocol_error";
|
|
466
|
+
readonly retryable: boolean;
|
|
467
|
+
};
|
|
468
|
+
/** A concrete adapter selectable for an individual compiled-bundle tier. */
|
|
469
|
+
export type RuntimeTierAdapter = "anthropic" | "openai-compatible" | "local";
|
|
470
|
+
/** Kept as the legacy/default-runtime spelling used by the BYO auth control. */
|
|
471
|
+
export type ApiKeyAdapter = "anthropic" | "openai-compatible";
|
|
472
|
+
/** NOTE: unrelated to the harness's own `AdapterSpec`/`tierBinding` — this is UI-facing config only. */
|
|
473
|
+
export interface TierModelBinding {
|
|
474
|
+
readonly tier: string;
|
|
475
|
+
/** Explicit override; when omitted, `RuntimeSettings.apiKeyModel` is the default. */
|
|
476
|
+
readonly model?: string;
|
|
477
|
+
/** Explicit override; when omitted, the runtime's selected/default adapter applies. */
|
|
478
|
+
readonly adapter?: RuntimeTierAdapter;
|
|
479
|
+
/** Required for openai-compatible/local overrides; never contains credentials. */
|
|
480
|
+
readonly baseURL?: string;
|
|
481
|
+
}
|
|
482
|
+
export interface RuntimeSettings {
|
|
483
|
+
readonly authMode: AuthMode;
|
|
484
|
+
/** Which personal subscription CLI is used when `authMode` is `"subscription"`. */
|
|
485
|
+
readonly subscriptionProvider?: SubscriptionProvider;
|
|
486
|
+
readonly tierModels: readonly TierModelBinding[];
|
|
487
|
+
readonly hybrid: boolean;
|
|
488
|
+
readonly deployment: Deployment;
|
|
489
|
+
/** Which api-key adapter `"byo"` dispatches through. Non-secret — never the key itself. */
|
|
490
|
+
readonly apiKeyAdapter?: ApiKeyAdapter;
|
|
491
|
+
/** Model name override for the api-key adapter. Non-secret. */
|
|
492
|
+
readonly apiKeyModel?: string;
|
|
493
|
+
/** Base URL override, `openai-compatible` only. Non-secret. */
|
|
494
|
+
readonly apiKeyBaseURL?: string;
|
|
495
|
+
/**
|
|
496
|
+
* Model for the subscription dispatcher itself. This is deliberately NOT a
|
|
497
|
+
* profile tier: compiled bundles own their step tiers, while subscription
|
|
498
|
+
* dispatchers need a separate driver model.
|
|
499
|
+
*/
|
|
500
|
+
readonly subscriptionDriverModel?: string;
|
|
501
|
+
}
|
|
502
|
+
/** Login availability only. No credential contents or metadata cross this boundary. */
|
|
503
|
+
export interface SubscriptionLoginStatus {
|
|
504
|
+
readonly claude: boolean;
|
|
505
|
+
readonly codex: boolean;
|
|
506
|
+
}
|
|
507
|
+
/** `PUT /api/config/runtime`'s response — the persisted settings plus any compliance warnings (e.g. the subscription ToS notice) surfaced for this save. `GET /api/config/runtime` stays a plain `RuntimeSettings` — warnings are a save-time concern only. */
|
|
508
|
+
export interface NativeRuntimeBindingDto {
|
|
509
|
+
readonly configured: boolean;
|
|
510
|
+
readonly generation: number;
|
|
511
|
+
readonly provider?: SubscriptionProvider;
|
|
512
|
+
readonly target?: "claude-code:interactive" | "codex:interactive";
|
|
513
|
+
readonly targetLabel?: "Claude CLI" | "Codex CLI";
|
|
514
|
+
}
|
|
515
|
+
export type RuntimeSettingsPutResponse = RuntimeSettings & {
|
|
516
|
+
readonly warnings: readonly string[];
|
|
517
|
+
readonly nativeSessionBinding: NativeRuntimeBindingDto;
|
|
518
|
+
};
|
|
519
|
+
/** Read-only health of the saved Runtime, for correcting legacy settings before dispatch. */
|
|
520
|
+
export type RuntimeSettingsReadiness = {
|
|
521
|
+
readonly valid: true;
|
|
522
|
+
} | {
|
|
523
|
+
readonly valid: false;
|
|
524
|
+
readonly correction: string;
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Whether each api-key adapter's required credential env var is present on the BFF process —
|
|
528
|
+
* booleans only, never the key value/prefix/suffix/length. Powers the setup wizard's api-key
|
|
529
|
+
* step so it can say "detected"/"missing" without ever handling the secret itself. See `GET
|
|
530
|
+
* /api/config/env-detect` (`server/app.ts`) and `detectAdapterEnv` (`server/env-detect.ts`).
|
|
531
|
+
*/
|
|
532
|
+
export interface AdapterEnvStatus {
|
|
533
|
+
readonly anthropic: boolean;
|
|
534
|
+
readonly openaiCompatible: boolean;
|
|
535
|
+
}
|
|
536
|
+
export interface PublishedInfo {
|
|
537
|
+
readonly link: string;
|
|
538
|
+
readonly scope: PublishScope;
|
|
539
|
+
}
|
|
540
|
+
export interface ArtifactDto {
|
|
541
|
+
readonly id: string;
|
|
542
|
+
readonly sessionId: string;
|
|
543
|
+
readonly name: string;
|
|
544
|
+
readonly artifactKind: ArtifactKind;
|
|
545
|
+
readonly location: string;
|
|
546
|
+
readonly verified: boolean;
|
|
547
|
+
readonly createdAt: string;
|
|
548
|
+
readonly published?: PublishedInfo;
|
|
549
|
+
/** Present only once the artifact has been saved to the Artifacts page. */
|
|
550
|
+
readonly savedAt?: string;
|
|
551
|
+
/** Native provenance is safe routing metadata; credentials and binding identity never cross this DTO. */
|
|
552
|
+
readonly nativeSessionId?: string;
|
|
553
|
+
}
|
|
554
|
+
export interface HarnessProfile {
|
|
555
|
+
readonly id: string;
|
|
556
|
+
readonly name: string;
|
|
557
|
+
readonly boundContext: string;
|
|
558
|
+
readonly verifyGate: boolean;
|
|
559
|
+
readonly bundleId: string;
|
|
560
|
+
readonly bundleVersion: string;
|
|
561
|
+
/**
|
|
562
|
+
* The bundle's declared IR compatibility range (`bundle.compat`) — e.g.
|
|
563
|
+
* `"0.3"` when `min_ir_version === max_ir_version`, or `"0.3–0.4"` when the
|
|
564
|
+
* bundle spans a range. See `buildProfile` in `server/harness.ts`.
|
|
565
|
+
*/
|
|
566
|
+
readonly irVersion: string;
|
|
567
|
+
/** `bundle.target` — the compiled dispatch target, e.g. `"vercel:headless"`. */
|
|
568
|
+
readonly dispatchTarget: string;
|
|
569
|
+
/**
|
|
570
|
+
* A short (first 7 hex chars), deterministic sha256 content hash of the
|
|
571
|
+
* compiled bundle (canonical, sorted-key JSON stringify — see
|
|
572
|
+
* `computeBundleHash` in `server/harness.ts`). NOT a "last compiled"
|
|
573
|
+
* timestamp; the store tracks no such thing.
|
|
574
|
+
*/
|
|
575
|
+
readonly bundleHash: string;
|
|
576
|
+
/**
|
|
577
|
+
* Derived from real state (the Setup wizard's "bind" step), not a
|
|
578
|
+
* hardcoded literal — see `deriveProfileStatus` in `server/harness.ts`.
|
|
579
|
+
* `"Bound"` once the user has completed Setup's Compile & Bind step;
|
|
580
|
+
* an honest alternative (e.g. `"Not bound yet"`) otherwise.
|
|
581
|
+
*/
|
|
582
|
+
readonly status: string;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Which auth strategy is actually configured — mirrors
|
|
586
|
+
* `AuthChoice["mode"]` (`harness/auth/index.ts`) verbatim. Deliberately NOT the
|
|
587
|
+
* internal `inProcess`/`dispatched` framework-dispatch bucketing (that terminology
|
|
588
|
+
* must never reach the wire); see `runtimeBackendAndLabel` in
|
|
589
|
+
* `server/harness.ts`.
|
|
590
|
+
*/
|
|
591
|
+
export type HarnessRuntimeBackend = "subscription" | "api-key" | "local" | "gateway";
|
|
592
|
+
/**
|
|
593
|
+
* Which provider-specific back-end owns this configuration. Claude and
|
|
594
|
+
* Codex subscriptions use their respective local dispatchers; api-key,
|
|
595
|
+
* local, and gateway modes run in-process. Codex Ask can still be disabled
|
|
596
|
+
* independently, which is surfaced on component status.
|
|
597
|
+
*/
|
|
598
|
+
export type HarnessRuntimeDispatcher = "claude-agent-sdk" | "codex-local" | "in-process";
|
|
599
|
+
export interface HarnessRuntime {
|
|
600
|
+
readonly backend: HarnessRuntimeBackend;
|
|
601
|
+
readonly label: string;
|
|
602
|
+
/** See `HarnessRuntimeDispatcher`'s doc comment. */
|
|
603
|
+
readonly dispatcher: HarnessRuntimeDispatcher;
|
|
604
|
+
/**
|
|
605
|
+
* The SAME source `GET /api/config/runtime` reports
|
|
606
|
+
* (`store.getRuntimeSettings().tierModels`), filtered to the tiers this
|
|
607
|
+
* bundle actually declares — so the two endpoints always agree on what
|
|
608
|
+
* model backs each tier. Previously this derived the tier -> model
|
|
609
|
+
* binding `route()` would really apply (see `server/harness.ts` git
|
|
610
|
+
* history), but under a `subscription` auth choice that real binding is
|
|
611
|
+
* genuinely unobservable from this harness (the `warble-agent-sdk`
|
|
612
|
+
* dispatcher owns model routing internally), which surfaced the same
|
|
613
|
+
* auth label for every tier instead of a real model name. Reusing the
|
|
614
|
+
* store's settings directly fixes that and keeps this DTO consistent with
|
|
615
|
+
* `RuntimeSettings.tierModels`. Each component's own `model`/`tiers`
|
|
616
|
+
* (`HarnessComponent`) are unaffected — those still report the real
|
|
617
|
+
* per-component binding, see `buildComponent`.
|
|
618
|
+
*/
|
|
619
|
+
readonly tierModels: readonly TierModelBinding[];
|
|
620
|
+
}
|
|
621
|
+
export type ConnectionHealth = "healthy" | "degraded" | "down";
|
|
622
|
+
/**
|
|
623
|
+
* The Harness page's "Data source · connection" panel — see `buildConnection`
|
|
624
|
+
* in `server/harness.ts`. `type`/`location` are resolved by
|
|
625
|
+
* `server/conn-config.ts`'s `resolveConnectionSource`, in order:
|
|
626
|
+
* the onboarding-only `conn.yml` first, if it happens to exist and carries a
|
|
627
|
+
* `datasource`; otherwise the project's persistent `wren_project.yml` —
|
|
628
|
+
* `data_source:` (always present) is `type`, and its pinned `profile:`, if
|
|
629
|
+
* any, is resolved against `~/.wren/profiles.yml` to supply the fields
|
|
630
|
+
* `describeConnection` turns into `location` (a duckdb path, or an
|
|
631
|
+
* allowlisted host/database-shaped string for DB-type sources — never a
|
|
632
|
+
* credential). A project with no profile pin honestly reports `type` with
|
|
633
|
+
* `location` `"—"` rather than fabricating one from the profiles store's
|
|
634
|
+
* global `active` profile. `via`/`lastSync` stay honest `"—"` placeholders —
|
|
635
|
+
* there is no real "which mechanism"/"last synced at" signal available from
|
|
636
|
+
* this harness. `tablesSynced` is real (`store.getContextModels().length`).
|
|
637
|
+
*/
|
|
638
|
+
export interface HarnessConnection {
|
|
639
|
+
readonly type: string;
|
|
640
|
+
readonly location: string;
|
|
641
|
+
readonly via: string;
|
|
642
|
+
readonly tablesSynced: number;
|
|
643
|
+
readonly lastSync: string;
|
|
644
|
+
readonly health: ConnectionHealth;
|
|
645
|
+
}
|
|
646
|
+
export type CapabilityOutcome = "native" | "realize-via";
|
|
647
|
+
export interface HarnessCapability {
|
|
648
|
+
readonly capability: string;
|
|
649
|
+
readonly outcome: CapabilityOutcome;
|
|
650
|
+
readonly providedBy: string;
|
|
651
|
+
readonly criticality?: string;
|
|
652
|
+
}
|
|
653
|
+
export interface HarnessGuardrail {
|
|
654
|
+
readonly name: string;
|
|
655
|
+
readonly enforcement: string;
|
|
656
|
+
readonly locked: boolean;
|
|
657
|
+
/** Present only when the guardrail carries a numeric limit, e.g. `row_limit` = 1000, `statement_timeout` = 30. */
|
|
658
|
+
readonly threshold?: number;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* One step of a component's declared step→artifact dataflow (`agent.steps[]`
|
|
662
|
+
* in the compiled bundle) — read-only introspection of the wiring the
|
|
663
|
+
* executor itself keys on (`consumes` is a hard precondition), not something
|
|
664
|
+
* this DTO executes.
|
|
665
|
+
*/
|
|
666
|
+
export interface HarnessStep {
|
|
667
|
+
readonly name: string;
|
|
668
|
+
readonly tier: string;
|
|
669
|
+
readonly consumes: readonly string[];
|
|
670
|
+
readonly produces: string;
|
|
671
|
+
/** `step.realization.kind` — `"independent"` or `"repair_fold"`. */
|
|
672
|
+
readonly realization: string;
|
|
673
|
+
/** `step.when?.guard`, e.g. `"on_failure"` — present only when the step is conditionally gated. */
|
|
674
|
+
readonly guard?: string;
|
|
675
|
+
/** `step.realization.fold_into` — present only for `"repair_fold"` steps. */
|
|
676
|
+
readonly foldInto?: string;
|
|
677
|
+
/** `step.realization.max_attempts` — present only for `"repair_fold"` steps. */
|
|
678
|
+
readonly maxAttempts?: number;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* A bundle-declared agent ("component" in the DTO/bundle vocabulary), shown
|
|
682
|
+
* on the frontend as a **Component** — not a "sub-agent": that framing is
|
|
683
|
+
* reserved for the profile level. This harness's runtime routes exactly ONE
|
|
684
|
+
* component per turn from the user's intent, so every other component listed
|
|
685
|
+
* here is a read-only declared part of the compiled bundle, not a
|
|
686
|
+
* concurrently-running sub-agent. `model`/`tiers` are the REAL tier binding
|
|
687
|
+
* resolved as if this component were the one running (see `buildComponent`
|
|
688
|
+
* in `server/harness.ts`), not the Setup page's seeded settings.
|
|
689
|
+
*/
|
|
690
|
+
export interface HarnessComponent {
|
|
691
|
+
readonly id: string;
|
|
692
|
+
readonly name: string;
|
|
693
|
+
readonly componentType: string;
|
|
694
|
+
/** `agent.realization_kind`, e.g. `"skill"`. */
|
|
695
|
+
readonly realizationKind: string;
|
|
696
|
+
/** `agent.trigger`, e.g. `"one_shot"`. */
|
|
697
|
+
readonly trigger: string;
|
|
698
|
+
/** `agent.outcome`, e.g. `"none"`. */
|
|
699
|
+
readonly outcome: string;
|
|
700
|
+
readonly callableAs: string;
|
|
701
|
+
readonly model: string;
|
|
702
|
+
readonly tiers: readonly TierModelBinding[];
|
|
703
|
+
readonly capabilities: readonly HarnessCapability[];
|
|
704
|
+
readonly guardrails: readonly HarnessGuardrail[];
|
|
705
|
+
/** `agent.tools[]` — e.g. `{ name: "query", source: "mcp:sample/query" }`. */
|
|
706
|
+
readonly tools: readonly {
|
|
707
|
+
readonly name: string;
|
|
708
|
+
readonly source: string;
|
|
709
|
+
}[];
|
|
710
|
+
/**
|
|
711
|
+
* The declared render-block `type` consts from `agent.output_schema`
|
|
712
|
+
* (`blocks.items.anyOf[].properties.type.const`, or the single-item form
|
|
713
|
+
* when there's no `anyOf`) — `[]` when the component declares no typed
|
|
714
|
+
* output blocks. See `extractOutputBlocks` in `server/harness.ts`.
|
|
715
|
+
*/
|
|
716
|
+
readonly outputBlocks: readonly string[];
|
|
717
|
+
/** The component's declared step→artifact dataflow (`agent.steps[]`). */
|
|
718
|
+
readonly steps: readonly HarnessStep[];
|
|
719
|
+
readonly status: string;
|
|
720
|
+
/** Stable display-only explanation; never exposes a target capability or execution plan. */
|
|
721
|
+
readonly unavailableReason?: string;
|
|
722
|
+
/**
|
|
723
|
+
* Present only when this component is unavailable on the compiled dispatch
|
|
724
|
+
* target (`agent.availability`) but the currently-selected purpose's native
|
|
725
|
+
* session IS available — i.e. it actually runs, just not via the
|
|
726
|
+
* programmatic path. `status` is `"ready"` in this case; the programmatic
|
|
727
|
+
* limitation moves here instead of being promoted into `unavailableReason`.
|
|
728
|
+
* Keyed off which `buildComponent` branch produced the status, never off
|
|
729
|
+
* matching Warble's reason string.
|
|
730
|
+
*/
|
|
731
|
+
readonly nativeAvailability?: {
|
|
732
|
+
/** The native session's target label, e.g. `"Claude CLI"` — why this actually runs. */
|
|
733
|
+
readonly viaLabel: "Claude CLI" | "Codex CLI";
|
|
734
|
+
/** The compiled dispatch target that cannot run it, e.g. `"claude-agent-sdk:local"`. */
|
|
735
|
+
readonly compiledDispatchTarget: string;
|
|
736
|
+
/** `agent.availability.reason` — the original bundle-level explanation, preserved for the expanded row. */
|
|
737
|
+
readonly compiledUnavailableReason: string;
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
export interface HarnessDto {
|
|
741
|
+
/** The single server-owned native purpose whose bundle is described below. */
|
|
742
|
+
readonly purpose: HarnessPurpose;
|
|
743
|
+
readonly profile: HarnessProfile;
|
|
744
|
+
readonly runtime: HarnessRuntime;
|
|
745
|
+
readonly connection: HarnessConnection;
|
|
746
|
+
/** See `HarnessComponent`'s doc comment — bundle agents are shown as Components, not sub-agents. */
|
|
747
|
+
readonly components: readonly HarnessComponent[];
|
|
748
|
+
/** Closed native dispatch registry projected from the same runtime binding as launch. */
|
|
749
|
+
readonly nativeSessions: {
|
|
750
|
+
readonly binding: NativeRuntimeBindingDto;
|
|
751
|
+
readonly dispatches: readonly {
|
|
752
|
+
readonly purpose: "analysis" | "setup" | "context_enrichment";
|
|
753
|
+
readonly profile: string;
|
|
754
|
+
readonly scopeKind: "bootstrap" | "bound_project";
|
|
755
|
+
readonly target?: "claude-code:interactive" | "codex:interactive";
|
|
756
|
+
readonly targetLabel?: "Claude CLI" | "Codex CLI";
|
|
757
|
+
readonly available: boolean;
|
|
758
|
+
readonly reason?: string;
|
|
759
|
+
}[];
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* A read-only projection of the selected purpose. `executionKind` is the
|
|
764
|
+
* discriminator that keeps form-led Setup runner readiness separate from
|
|
765
|
+
* native terminal readiness; no browser-provided launch/profile/target input
|
|
766
|
+
* is represented here.
|
|
767
|
+
*/
|
|
768
|
+
interface HarnessPurposeBase {
|
|
769
|
+
readonly purpose: "setup" | "analysis" | "context_enrichment";
|
|
770
|
+
readonly profile: "genbi-setup" | "genbi-default" | "genbi-enrich-context";
|
|
771
|
+
readonly scopeKind: "bootstrap" | "bound_project";
|
|
772
|
+
readonly available: boolean;
|
|
773
|
+
readonly reason?: string;
|
|
774
|
+
}
|
|
775
|
+
export type HarnessPurpose = HarnessPurposeBase & ({
|
|
776
|
+
readonly executionKind: "setup_runner";
|
|
777
|
+
readonly target: "claude-agent-sdk:setup" | "codex-local:setup" | "in-process:setup";
|
|
778
|
+
readonly targetLabel: "Claude Setup runner" | "Codex Setup runner" | "In-process Setup runner";
|
|
779
|
+
} | {
|
|
780
|
+
readonly executionKind: "native_session";
|
|
781
|
+
readonly target?: "claude-code:interactive" | "codex:interactive";
|
|
782
|
+
readonly targetLabel?: "Claude CLI" | "Codex CLI";
|
|
783
|
+
});
|
|
784
|
+
export type SseEventName = "worklog" | "event" | "error" | "done";
|
|
785
|
+
export type SseFrame = {
|
|
786
|
+
readonly event: "worklog";
|
|
787
|
+
readonly data: readonly ToolStep[];
|
|
788
|
+
} | {
|
|
789
|
+
readonly event: "event";
|
|
790
|
+
readonly data: SessionEvent;
|
|
791
|
+
} | {
|
|
792
|
+
readonly event: "error";
|
|
793
|
+
readonly data: {
|
|
794
|
+
readonly message: string;
|
|
795
|
+
};
|
|
796
|
+
} | {
|
|
797
|
+
readonly event: "done";
|
|
798
|
+
readonly data: Record<string, never>;
|
|
799
|
+
};
|