Clean up resolved settings interfaces

This commit is contained in:
Bryan Helmkamp 2026-03-27 15:32:06 -04:00
parent d5287a1af5
commit 33f4da33c1
No known key found for this signature in database
94 changed files with 691 additions and 1188 deletions

View file

@ -25,7 +25,7 @@ export default [
route("runs/:id", "routes/run-detail.tsx", [
index("routes/run-overview.tsx"),
route("stages/:stageId", "routes/run-stages.tsx"),
route("configuration", "routes/run-configuration.tsx"),
route("settings", "routes/run-settings.tsx"),
route("graph", "routes/run-graph.tsx"),
route("files", "routes/run-files.tsx"),
route("verification", "routes/run-verification.tsx"),

View file

@ -305,11 +305,11 @@ export default function RunGraph({ loaderData }: Route.ComponentProps) {
<ul className="mt-2 space-y-0.5">
<li>
<Link
to={`/runs/${id}/configuration`}
to={`/runs/${id}/settings`}
className="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm text-fg-3 transition-colors hover:bg-overlay hover:text-fg"
>
<DocumentTextIcon className="size-4 shrink-0 text-fg-muted" />
Run Configuration
Run Settings
</Link>
</li>
<li>

View file

@ -320,11 +320,11 @@ export default function RunOverview({ loaderData }: Route.ComponentProps) {
<ul className="mt-2 space-y-0.5">
<li>
<Link
to={`/runs/${id}/configuration`}
to={`/runs/${id}/settings`}
className="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm text-fg-3 transition-colors hover:bg-overlay hover:text-fg"
>
<DocumentTextIcon className="size-4 shrink-0 text-fg-muted" />
Run Configuration
Run Settings
</Link>
</li>
<li>

View file

@ -4,8 +4,8 @@ import { DocumentTextIcon, MapIcon } from "@heroicons/react/24/outline";
import { CollapsibleFile } from "../components/collapsible-file";
import { apiJson } from "../api-client";
import { formatDurationSecs } from "../lib/format";
import type { PaginatedRunStageList, RunConfiguration } from "@qltysh/fabro-api-client";
import type { Route } from "./+types/run-configuration";
import type { PaginatedRunStageList, RunSettings } from "@qltysh/fabro-api-client";
import type { Route } from "./+types/run-settings";
export const handle = { wide: true };
@ -27,9 +27,9 @@ const statusConfig: Record<StageStatus, { icon: typeof CheckCircleIcon; color: s
};
export async function loader({ request, params }: Route.LoaderArgs) {
const [{ data: apiStages }, config] = await Promise.all([
const [{ data: apiStages }, settings] = await Promise.all([
apiJson<PaginatedRunStageList>(`/runs/${params.id}/stages`, { request }),
apiJson<RunConfiguration>(`/runs/${params.id}/configuration`, { request }),
apiJson<RunSettings>(`/runs/${params.id}/settings`, { request }),
]);
const stages: Stage[] = apiStages.map((s) => ({
id: s.id,
@ -37,12 +37,12 @@ export async function loader({ request, params }: Route.LoaderArgs) {
status: s.status as StageStatus,
duration: s.duration_secs != null ? formatDurationSecs(s.duration_secs) : "--",
}));
return { stages, config };
return { stages, settings };
}
export default function RunConfiguration({ loaderData }: Route.ComponentProps) {
export default function RunSettingsPage({ loaderData }: Route.ComponentProps) {
const { id } = useParams();
const { stages, config } = loaderData;
const { stages, settings } = loaderData;
return (
<div className="flex gap-6">
@ -74,11 +74,11 @@ export default function RunConfiguration({ loaderData }: Route.ComponentProps) {
<ul className="mt-2 space-y-0.5">
<li>
<Link
to={`/runs/${id}/configuration`}
to={`/runs/${id}/settings`}
className="flex items-center gap-2 rounded-md bg-overlay px-2 py-1.5 text-sm text-fg transition-colors"
>
<DocumentTextIcon className="size-4 shrink-0 text-fg-muted" />
Run Configuration
Run Settings
</Link>
</li>
<li>
@ -96,7 +96,7 @@ export default function RunConfiguration({ loaderData }: Route.ComponentProps) {
<div className="min-w-0 flex-1">
<CollapsibleFile
file={{ name: "run.json", contents: JSON.stringify(config, null, 2), lang: "json" }}
file={{ name: "run.json", contents: JSON.stringify(settings, null, 2), lang: "json" }}
/>
</div>
</div>

View file

@ -144,11 +144,11 @@ export default function RunStages({ loaderData }: Route.ComponentProps) {
<ul className="mt-2 space-y-0.5">
<li>
<Link
to={`/runs/${id}/configuration`}
to={`/runs/${id}/settings`}
className="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm text-fg-3 transition-colors hover:bg-overlay hover:text-fg"
>
<DocumentTextIcon className="size-4 shrink-0 text-fg-muted" />
Run Configuration
Run Settings
</Link>
</li>
<li>

View file

@ -1,6 +1,6 @@
import { apiJson } from "../api-client";
import { CollapsibleFile } from "../components/collapsible-file";
import type { ServerConfiguration } from "@qltysh/fabro-api-client";
import type { ServerSettings } from "@qltysh/fabro-api-client";
import type { Route } from "./+types/settings";
export function meta({}: Route.MetaArgs) {
@ -10,17 +10,17 @@ export function meta({}: Route.MetaArgs) {
export const handle = { hideHeader: true };
export async function loader({ request }: Route.LoaderArgs) {
const config = await apiJson<ServerConfiguration>("/settings", { request });
return { config };
const settings = await apiJson<ServerSettings>("/settings", { request });
return { settings };
}
export default function Settings({ loaderData }: Route.ComponentProps) {
const { config } = loaderData;
const { settings } = loaderData;
return (
<div className="mx-auto max-w-4xl">
<CollapsibleFile
file={{ name: "server.json", contents: JSON.stringify(config, null, 2), lang: "json" }}
file={{ name: "server.json", contents: JSON.stringify(settings, null, 2), lang: "json" }}
/>
</div>
);

View file

@ -21,13 +21,13 @@ export default function WorkflowDefinition() {
}, []);
if (workflow == null) {
return <p className="text-sm text-fg-muted">No configuration found.</p>;
return <p className="text-sm text-fg-muted">No settings found.</p>;
}
return (
<div className="flex flex-col gap-6">
<CollapsibleFile
file={{ name: "run.json", contents: JSON.stringify(workflow.config, null, 2), lang: "json" }}
file={{ name: "run.json", contents: JSON.stringify(workflow.settings, null, 2), lang: "json" }}
defaultOpen={false}
/>
{dotReady && (

View file

@ -1,7 +1,7 @@
import { ChevronRightIcon } from "@heroicons/react/20/solid";
import { Link, Outlet, useLocation, useParams } from "react-router";
import { apiJson } from "../api-client";
import type { WorkflowDetail as ApiWorkflowDetail, RunConfiguration } from "@qltysh/fabro-api-client";
import type { WorkflowDetail as ApiWorkflowDetail, RunSettings } from "@qltysh/fabro-api-client";
import type { Route } from "./+types/workflow-detail";
export interface WorkflowEntry {
@ -9,7 +9,7 @@ export interface WorkflowEntry {
slug: string;
description: string;
filename: string;
config: RunConfiguration;
settings: RunSettings;
graph: string;
}
@ -21,7 +21,7 @@ export const workflowData: Record<string, WorkflowEntry> = {
slug: "fix_build",
filename: "fix_build.fabro",
description: "Automatically diagnoses and fixes CI build failures by analyzing error logs, identifying root causes, and applying targeted code changes.",
config: {
settings: {
version: 1,
goal: "Diagnose and fix CI build failures",
graph: "fix_build.fabro",
@ -62,7 +62,7 @@ export const workflowData: Record<string, WorkflowEntry> = {
slug: "implement",
filename: "implement.fabro",
description: "Generates production-ready code from a technical blueprint, including tests, documentation, and a pull request ready for review.",
config: {
settings: {
version: 1,
goal: "Implement feature from technical blueprint",
graph: "implement.fabro",
@ -118,7 +118,7 @@ export const workflowData: Record<string, WorkflowEntry> = {
slug: "sync_drift",
filename: "sync_drift.fabro",
description: "Detects configuration and code drift between environments, then generates reconciliation patches to bring everything back in sync.",
config: {
settings: {
version: 1,
goal: "Detect and reconcile configuration drift across environments",
graph: "sync_drift.fabro",
@ -163,7 +163,7 @@ export const workflowData: Record<string, WorkflowEntry> = {
slug: "expand",
filename: "expand.fabro",
description: "Evolves the product by analyzing usage patterns and specifications to propose and implement incremental improvements.",
config: {
settings: {
version: 1,
goal: "Propose and implement incremental product improvements",
graph: "expand.fabro",
@ -216,7 +216,7 @@ export async function loader({ request, params }: Route.LoaderArgs) {
slug: apiWorkflow.slug,
description: apiWorkflow.description,
filename: apiWorkflow.filename,
config: apiWorkflow.config,
settings: apiWorkflow.settings,
graph: apiWorkflow.graph,
};
return { workflow };

View file

@ -563,21 +563,21 @@ paths:
schema:
$ref: "#/components/schemas/ErrorResponse"
/runs/{id}/configuration:
/runs/{id}/settings:
get:
operationId: retrieveRunConfiguration
operationId: retrieveRunSettings
tags: [Run Internals]
summary: Retrieve Run Configuration
description: Returns the structured configuration used to launch this run.
summary: Retrieve Run Settings
description: Returns the structured settings used to launch this run.
parameters:
- $ref: "#/components/parameters/RunId"
responses:
"200":
description: Run configuration
description: Run settings
content:
application/json:
schema:
$ref: "#/components/schemas/RunConfiguration"
$ref: "#/components/schemas/RunSettings"
"404":
description: Run not found
content:
@ -673,7 +673,7 @@ paths:
operationId: retrieveWorkflow
tags: [Workflows]
summary: Retrieve Workflow
description: Returns the full detail of a workflow including its Graphviz graph, TOML config, and description.
description: Returns the full detail of a workflow including its Graphviz graph, resolved settings, and description.
parameters:
- $ref: "#/components/parameters/WorkflowName"
responses:
@ -1257,17 +1257,17 @@ paths:
/settings:
get:
operationId: retrieveServerConfiguration
operationId: retrieveServerSettings
tags: [Settings]
summary: Retrieve Server Configuration
description: Returns the structured server configuration.
summary: Retrieve Server Settings
description: Returns the structured server settings.
responses:
"200":
description: Server configuration
description: Server settings
content:
application/json:
schema:
$ref: "#/components/schemas/ServerConfiguration"
$ref: "#/components/schemas/ServerSettings"
components:
securitySchemes:
@ -2925,14 +2925,14 @@ components:
$ref: "#/components/schemas/WorkflowSchedule"
WorkflowDetail:
description: Full detail of a workflow definition including graph and configuration.
description: Full detail of a workflow definition including graph and resolved settings.
type: object
required:
- name
- slug
- filename
- description
- config
- settings
- graph
properties:
name:
@ -2951,8 +2951,8 @@ components:
type: string
description: Prose description of what the workflow does.
example: Automatically diagnoses and fixes CI build failures.
config:
$ref: "#/components/schemas/RunConfiguration"
settings:
$ref: "#/components/schemas/RunSettings"
graph:
type: string
description: Graphviz DOT language source defining the workflow graph.
@ -3981,10 +3981,10 @@ components:
description: Number of rows returned.
example: 6
# ── Configuration Schemas ────────────────────────────────────────────
# ── Settings Schemas ─────────────────────────────────────────────────
RunConfiguration:
description: Structured run configuration mirroring FabroConfig.
RunSettings:
description: Structured run settings mirroring FabroSettings.
type: object
required:
- version
@ -3992,7 +3992,7 @@ components:
properties:
version:
type: integer
description: Configuration schema version.
description: Settings schema version.
example: 1
goal:
type: string
@ -4006,11 +4006,11 @@ components:
type: string
description: Working directory for the run.
llm:
$ref: "#/components/schemas/LlmConfiguration"
$ref: "#/components/schemas/LlmSettings"
setup:
$ref: "#/components/schemas/SetupConfiguration"
$ref: "#/components/schemas/SetupSettings"
sandbox:
$ref: "#/components/schemas/SandboxConfiguration"
$ref: "#/components/schemas/SandboxSettings"
vars:
type: object
additionalProperties:
@ -4021,7 +4021,7 @@ components:
items:
$ref: "#/components/schemas/HookDefinition"
LlmConfiguration:
LlmSettings:
description: LLM provider and model settings.
type: object
properties:
@ -4041,7 +4041,7 @@ components:
type: string
description: Provider fallback chains.
SetupConfiguration:
SetupSettings:
description: Setup commands run before the workflow.
type: object
required:
@ -4056,7 +4056,7 @@ components:
type: integer
description: Timeout per command in milliseconds.
SandboxConfiguration:
SandboxSettings:
description: Sandbox execution environment settings.
type: object
properties:
@ -4071,20 +4071,20 @@ components:
type: boolean
description: Whether to use a devcontainer for the sandbox.
daytona:
$ref: "#/components/schemas/DaytonaConfiguration"
$ref: "#/components/schemas/DaytonaSettings"
exe:
$ref: "#/components/schemas/ExeConfiguration"
$ref: "#/components/schemas/ExeSettings"
ssh:
$ref: "#/components/schemas/SshConfiguration"
$ref: "#/components/schemas/SshSettings"
local:
$ref: "#/components/schemas/LocalSandboxConfiguration"
$ref: "#/components/schemas/LocalSandboxSettings"
env:
type: object
additionalProperties:
type: string
description: Environment variables injected into the sandbox.
LocalSandboxConfiguration:
LocalSandboxSettings:
description: Local sandbox settings.
type: object
properties:
@ -4094,7 +4094,7 @@ components:
enum: [always, clean, dirty, never]
default: clean
ExeConfiguration:
ExeSettings:
description: exe.dev sandbox configuration.
type: object
properties:
@ -4102,7 +4102,7 @@ components:
type: string
description: VM image to use for the exe.dev sandbox.
SshConfiguration:
SshSettings:
description: SSH sandbox configuration for user-provided hosts.
type: object
required:
@ -4119,7 +4119,7 @@ components:
type: string
description: Optional path to a custom SSH config file.
DaytonaConfiguration:
DaytonaSettings:
description: Daytona-specific sandbox settings.
type: object
properties:
@ -4132,7 +4132,7 @@ components:
type: string
description: Labels applied to the sandbox.
snapshot:
$ref: "#/components/schemas/DaytonaSnapshotConfiguration"
$ref: "#/components/schemas/DaytonaSnapshotSettings"
network:
description: "Network access mode: \"block\", \"allow_all\", or {\"allow_list\": [...]}."
oneOf:
@ -4154,7 +4154,7 @@ components:
default: false
description: Skip git repo detection and cloning during initialization.
DaytonaSnapshotConfiguration:
DaytonaSnapshotSettings:
description: Snapshot configuration for Daytona sandboxes.
type: object
required:
@ -4255,8 +4255,8 @@ components:
type: boolean
description: Whether hook runs in sandbox.
ServerConfiguration:
description: Structured server configuration mirroring FabroConfig.
ServerSettings:
description: Structured server settings mirroring FabroSettings.
type: object
properties:
storage_dir:
@ -4266,48 +4266,48 @@ components:
type: integer
description: Maximum concurrent runs.
web:
$ref: "#/components/schemas/WebConfiguration"
$ref: "#/components/schemas/WebSettings"
api:
$ref: "#/components/schemas/ApiConfiguration"
$ref: "#/components/schemas/ApiSettings"
git:
$ref: "#/components/schemas/GitConfiguration"
$ref: "#/components/schemas/GitSettings"
features:
$ref: "#/components/schemas/Features"
log:
$ref: "#/components/schemas/LogConfiguration"
$ref: "#/components/schemas/LogSettings"
work_dir:
type: string
description: Default working directory.
llm:
$ref: "#/components/schemas/LlmConfiguration"
$ref: "#/components/schemas/LlmSettings"
setup:
$ref: "#/components/schemas/SetupConfiguration"
$ref: "#/components/schemas/SetupSettings"
sandbox:
$ref: "#/components/schemas/SandboxConfiguration"
$ref: "#/components/schemas/SandboxSettings"
vars:
type: object
additionalProperties:
type: string
description: Default variable map.
checkpoint:
$ref: "#/components/schemas/CheckpointConfiguration"
$ref: "#/components/schemas/CheckpointSettings"
pull_request:
$ref: "#/components/schemas/PullRequestConfiguration"
$ref: "#/components/schemas/PullRequestSettings"
hooks:
type: array
items:
$ref: "#/components/schemas/HookDefinition"
assets:
$ref: "#/components/schemas/AssetsConfiguration"
$ref: "#/components/schemas/AssetsSettings"
mcp_servers:
type: object
additionalProperties:
$ref: "#/components/schemas/McpServerEntry"
description: Default MCP server configurations.
github:
$ref: "#/components/schemas/GitHubConfiguration"
$ref: "#/components/schemas/GitHubSettings"
GitHubConfiguration:
GitHubSettings:
description: GitHub App token injection configuration.
type: object
properties:
@ -4349,7 +4349,7 @@ components:
type: integer
description: Tool call timeout in seconds.
AssetsConfiguration:
AssetsSettings:
description: Asset collection configuration.
type: object
properties:
@ -4359,7 +4359,7 @@ components:
type: string
description: Glob patterns for files to collect as run assets.
LogConfiguration:
LogSettings:
description: Logging configuration.
type: object
properties:
@ -4367,7 +4367,7 @@ components:
type: string
description: Log level (e.g. trace, debug, info).
CheckpointConfiguration:
CheckpointSettings:
description: Checkpoint configuration for file exclusion.
type: object
properties:
@ -4377,7 +4377,7 @@ components:
type: string
description: Glob patterns to exclude from checkpoints.
PullRequestConfiguration:
PullRequestSettings:
description: Pull request creation configuration.
type: object
properties:
@ -4395,7 +4395,7 @@ components:
enum: [squash, merge, rebase]
description: Merge strategy for auto-merge.
WebConfiguration:
WebSettings:
description: Web UI configuration.
type: object
properties:
@ -4403,9 +4403,9 @@ components:
type: string
description: Web UI URL.
auth:
$ref: "#/components/schemas/AuthConfiguration"
$ref: "#/components/schemas/AuthSettings"
AuthConfiguration:
AuthSettings:
description: Authentication configuration.
type: object
properties:
@ -4421,7 +4421,7 @@ components:
type: string
description: Allowed usernames.
ApiConfiguration:
ApiSettings:
description: API server configuration.
type: object
properties:
@ -4437,9 +4437,9 @@ components:
- mtls
description: Authentication strategies.
tls:
$ref: "#/components/schemas/TlsConfiguration"
$ref: "#/components/schemas/TlsSettings"
TlsConfiguration:
TlsSettings:
description: TLS certificate configuration.
type: object
required:
@ -4457,7 +4457,7 @@ components:
type: string
description: CA certificate file path.
GitConfiguration:
GitSettings:
description: Git provider configuration.
type: object
properties:
@ -4476,11 +4476,11 @@ components:
type: string
description: GitHub App slug.
author:
$ref: "#/components/schemas/GitAuthorConfiguration"
$ref: "#/components/schemas/GitAuthorSettings"
webhooks:
$ref: "#/components/schemas/WebhookConfiguration"
$ref: "#/components/schemas/WebhookSettings"
GitAuthorConfiguration:
GitAuthorSettings:
description: Git commit author configuration.
type: object
properties:
@ -4491,7 +4491,7 @@ components:
type: string
description: Author email for commits.
WebhookConfiguration:
WebhookSettings:
description: Webhook delivery configuration.
type: object
required:
@ -4566,4 +4566,4 @@ components:
login:
type: string
description: User's login identifier (e.g. GitHub username).
example: octocat
example: octocat

View file

@ -104,12 +104,12 @@ pub async fn get_run_verification(
paginated_response(runs::verifications(), &pagination)
}
pub async fn get_run_configuration(
pub async fn get_run_settings(
_auth: AuthenticatedService,
State(_state): State<Arc<AppState>>,
Path(_id): Path<String>,
) -> Response {
(StatusCode::OK, Json(runs::configuration())).into_response()
(StatusCode::OK, Json(runs::settings())).into_response()
}
pub async fn steer_run_stub(
@ -588,11 +588,11 @@ pub async fn list_models(
// ── Settings ───────────────────────────────────────────────────────────
pub async fn get_server_configuration(
pub async fn get_server_settings(
_auth: AuthenticatedService,
State(_state): State<Arc<AppState>>,
) -> Response {
(StatusCode::OK, Json(settings::server_config())).into_response()
(StatusCode::OK, Json(settings::server_settings())).into_response()
}
// ── Usage ──────────────────────────────────────────────────────────────
@ -1276,7 +1276,7 @@ mod runs {
]
}
pub fn configuration() -> serde_json::Value {
pub fn settings() -> serde_json::Value {
serde_json::to_value(fabro_config::FabroSettings {
version: Some(1),
goal: Some("Add rate limiting to auth endpoints".into()),
@ -1431,7 +1431,7 @@ mod workflows {
]
}
fn run_config_to_api(cfg: fabro_config::FabroSettings) -> RunConfiguration {
fn run_settings_to_api(cfg: fabro_config::FabroSettings) -> RunSettings {
fn strip_nulls(val: serde_json::Value) -> serde_json::Value {
match val {
serde_json::Value::Object(map) => serde_json::Value::Object(
@ -1455,7 +1455,7 @@ mod workflows {
WorkflowDetail {
name: "Fix Build".into(), slug: "fix_build".into(), filename: "fix_build.fabro".into(),
description: "Automatically diagnoses and fixes CI build failures by analyzing error logs, identifying root causes, and applying targeted code changes.".into(),
config: run_config_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_config::FabroSettings {
version: Some(1),
goal: Some("Diagnose and fix CI build failures".into()),
graph: Some("fix_build.fabro".into()),
@ -1526,7 +1526,7 @@ mod workflows {
WorkflowDetail {
name: "Implement Feature".into(), slug: "implement".into(), filename: "implement.fabro".into(),
description: "Generates production-ready code from a technical blueprint, including tests, documentation, and a pull request ready for review.".into(),
config: run_config_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_config::FabroSettings {
version: Some(1),
goal: Some("Implement feature from technical blueprint".into()),
graph: Some("implement.fabro".into()),
@ -1615,7 +1615,7 @@ mod workflows {
WorkflowDetail {
name: "Sync Drift".into(), slug: "sync_drift".into(), filename: "sync_drift.fabro".into(),
description: "Detects configuration and code drift between environments, then generates reconciliation patches to bring everything back in sync.".into(),
config: run_config_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_config::FabroSettings {
version: Some(1),
goal: Some("Detect and reconcile configuration drift across environments".into()),
graph: Some("sync_drift.fabro".into()),
@ -1692,7 +1692,7 @@ mod workflows {
WorkflowDetail {
name: "Expand Product".into(), slug: "expand".into(), filename: "expand.fabro".into(),
description: "Evolves the product by analyzing usage patterns and specifications to propose and implement incremental improvements.".into(),
config: run_config_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_config::FabroSettings {
version: Some(1),
goal: Some("Propose and implement incremental product improvements".into()),
graph: Some("expand.fabro".into()),
@ -3244,7 +3244,7 @@ mod settings {
use fabro_config::server::*;
use fabro_config::FabroSettings;
pub fn server_config() -> serde_json::Value {
pub fn server_settings() -> serde_json::Value {
serde_json::to_value(FabroSettings {
storage_dir: Some("/home/fabro/.fabro".into()),
max_concurrent_runs: Some(10),

View file

@ -83,12 +83,11 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
// Initialize data directory and SQLite database
let config_path = args.config;
let server_config: FabroSettings =
fabro_config::server::load_server_config(config_path.as_deref())?.try_into()?;
let data_dir = fabro_config::server::resolve_storage_dir(&server_config);
let server_settings = fabro_config::server::load_server_settings(config_path.as_deref())?;
let data_dir = fabro_config::server::resolve_storage_dir(&server_settings);
// Shared config for live reloading
let shared_config = Arc::new(RwLock::new(server_config));
let shared_config = Arc::new(RwLock::new(server_settings));
// CLI overrides take precedence over config file values, even after reload
let cli_model = args.model;
@ -215,12 +214,8 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
interval.tick().await; // skip first immediate tick
loop {
interval.tick().await;
match fabro_config::server::load_server_config(config_path_for_poll.as_deref()) {
match fabro_config::server::load_server_settings(config_path_for_poll.as_deref()) {
Ok(new_config) => {
let Ok(new_config) = FabroSettings::try_from(new_config) else {
warn!("Failed to finalize reloaded server config");
continue;
};
let changed = {
let cfg = config_for_poll.read().expect("config lock poisoned");
*cfg != new_config

View file

@ -185,10 +185,7 @@ fn demo_routes() -> Router<Arc<AppState>> {
"/runs/{id}/verification",
get(crate::demo::get_run_verification),
)
.route(
"/runs/{id}/configuration",
get(crate::demo::get_run_configuration),
)
.route("/runs/{id}/settings", get(crate::demo::get_run_settings))
.route("/runs/{id}/steer", post(crate::demo::steer_run_stub))
.route(
"/runs/{id}/preview",
@ -250,7 +247,7 @@ fn demo_routes() -> Router<Arc<AppState>> {
.route("/models", get(crate::demo::list_models))
.route("/models/{id}/test", post(test_model))
.route("/completions", post(create_completion))
.route("/settings", get(crate::demo::get_server_configuration))
.route("/settings", get(crate::demo::get_server_settings))
.route("/usage", get(crate::demo::get_aggregate_usage))
}
@ -273,7 +270,7 @@ fn real_routes() -> Router<Arc<AppState>> {
.route("/runs/{id}/files", get(not_implemented))
.route("/runs/{id}/usage", get(not_implemented))
.route("/runs/{id}/verification", get(not_implemented))
.route("/runs/{id}/configuration", get(not_implemented))
.route("/runs/{id}/settings", get(not_implemented))
.route("/runs/{id}/steer", post(not_implemented))
.route("/runs/{id}/preview", post(not_implemented))
.route("/workflows", get(not_implemented))
@ -520,7 +517,7 @@ async fn start_run(
let run_id = ulid::Ulid::new().to_string();
info!(run_id = %run_id, "Run queued");
let run_dir = std::env::temp_dir().join(format!("fabro-{}", uuid::Uuid::new_v4()));
let config = fabro_config::FabroSettings {
let settings = fabro_config::FabroSettings {
dry_run: Some(state.dry_run),
hooks: state.hooks.clone(),
sandbox: Some(fabro_config::sandbox::SandboxSettings {
@ -529,11 +526,11 @@ async fn start_run(
}),
..Default::default()
};
let run_labels = config.labels.clone();
let run_labels = settings.labels.clone();
let persisted = match operations::create(
&req.dot_source,
RunCreateOptions {
config,
settings,
run_dir: Some(run_dir.clone()),
run_id: Some(run_id.clone()),
workflow_slug: None,
@ -701,10 +698,9 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
};
let run_record = persisted.run_record().clone();
let run_options = RunOptions {
config: run_record.config,
settings: run_record.settings,
run_dir: run_dir.clone(),
cancel_token: Some(cancel_token),
dry_run: state.dry_run,
run_id: run_id.clone(),
labels: run_record.labels,
git_author: state.git_author.clone(),

View file

@ -396,18 +396,18 @@ fn fully_populated_server_config() -> FabroSettings {
}
#[test]
fn server_config_keys_match_openapi_spec() {
let config = fully_populated_server_config();
let json = serde_json::to_value(&config).expect("serialize ServerConfig");
fn server_settings_keys_match_openapi_spec() {
let settings = fully_populated_server_config();
let json = serde_json::to_value(&settings).expect("serialize ServerSettings");
let spec = load_spec_json();
let schema = &spec["components"]["schemas"]["ServerConfiguration"];
let schema = &spec["components"]["schemas"]["ServerSettings"];
let mut errors = Vec::new();
compare_schema("ServerConfiguration", &json, schema, &spec, &mut errors);
compare_schema("ServerSettings", &json, schema, &spec, &mut errors);
if !errors.is_empty() {
panic!(
"ServerConfig ↔ OpenAPI schema drift:\n {}",
"ServerSettings ↔ OpenAPI schema drift:\n {}",
errors.join("\n ")
);
}

View file

@ -8,7 +8,7 @@ use fabro_config::FabroSettings;
#[cfg(feature = "server")]
use tracing::debug;
pub fn load_cli_config(path: Option<&Path>) -> anyhow::Result<FabroSettings> {
pub fn load_cli_settings(path: Option<&Path>) -> anyhow::Result<FabroSettings> {
fabro_config::cli::load_cli_config(path)?.try_into()
}

View file

@ -6,7 +6,7 @@ use crate::args::AssetCpArgs;
use crate::shared::split_run_path;
pub fn cp_command(args: &AssetCpArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let (run_id, asset_path) = parse_source(&args.source);
let run = fabro_workflows::run_lookup::resolve_run(&base, run_id)?;

View file

@ -4,7 +4,7 @@ use crate::args::AssetListArgs;
use crate::shared::format_size;
pub fn list_command(args: &AssetListArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run = fabro_workflows::run_lookup::resolve_run(&base, &args.run_id)?;
let entries = fabro_workflows::assets::scan_assets(&run.path, args.node.as_deref())?;

View file

@ -928,7 +928,7 @@ pub async fn run_doctor(verbose: bool, live: bool) -> i32 {
spinner.enable_steady_tick(std::time::Duration::from_millis(80));
// Gather state
let cli_config = crate::cli_config::load_cli_config(None).unwrap_or_default();
let cli_config = crate::cli_config::load_cli_settings(None).unwrap_or_default();
let config_path = dirs::home_dir().map(|h| h.join(".fabro").join("cli.toml"));
let config_exists = config_path.as_ref().is_some_and(|p| p.exists());
@ -943,9 +943,7 @@ pub async fn run_doctor(verbose: bool, live: bool) -> i32 {
let daytona_configured = std::env::var("DAYTONA_API_KEY").is_ok();
#[cfg(feature = "server")]
let server_config = fabro_config::server::load_server_config(None)
.and_then(fabro_config::FabroSettings::try_from)
.unwrap_or_default();
let server_config = fabro_config::server::load_server_settings(None).unwrap_or_default();
#[cfg(feature = "server")]
let api_status = {

View file

@ -4,7 +4,7 @@ use crate::args::GlobalArgs;
use crate::cli_config;
pub async fn execute(mut args: fabro_agent::cli::AgentArgs, globals: &GlobalArgs) -> Result<()> {
let cli_config = cli_config::load_cli_config(None)?;
let cli_config = cli_config::load_cli_settings(None)?;
#[cfg(feature = "sleep_inhibitor")]
let _sleep_guard = crate::sleep_inhibitor::guard(cli_config.prevent_idle_sleep_enabled());
let exec_defaults = cli_config.exec.as_ref();

View file

@ -6,7 +6,7 @@ use anyhow::Result;
use crate::args::{GlobalArgs, LlmCommand, LlmNamespace};
pub async fn dispatch(ns: LlmNamespace, globals: &GlobalArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
match ns.command {
LlmCommand::Prompt(args) => prompt::execute(args, &cli_config, globals).await,

View file

@ -11,7 +11,7 @@ pub async fn execute(
let server = {
#[cfg(feature = "server")]
{
let cli_config = cli_config::load_cli_config(None)?;
let cli_config = cli_config::load_cli_settings(None)?;
let resolved = cli_config::resolve_mode(
globals.mode.clone(),
globals.server_url.as_deref(),

View file

@ -9,7 +9,7 @@ pub async fn close_command(
args: PrCloseArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
close_from(&base, args, github_app).await
}

View file

@ -10,7 +10,7 @@ pub async fn create_command(
args: PrCreateArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
create_from(&base, args, github_app).await
}

View file

@ -9,7 +9,7 @@ pub async fn list_command(
args: PrListArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
list_from(&base, args, github_app).await
}

View file

@ -9,7 +9,7 @@ pub async fn merge_command(
args: PrMergeArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
merge_from(&base, args, github_app).await
}

View file

@ -11,7 +11,7 @@ use anyhow::{Context, Result};
use crate::args::{PrCommand, PrNamespace};
pub async fn dispatch(ns: PrNamespace) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let github_app = crate::shared::github::build_github_app_credentials(cli_config.app_id());
match ns.command {

View file

@ -9,7 +9,7 @@ pub async fn view_command(
args: PrViewArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
view_from(&base, args, github_app).await
}

View file

@ -29,11 +29,8 @@ pub async fn execute(mut args: PreflightArgs) -> anyhow::Result<()> {
let git_status =
fabro_workflows::git::sync_status(&original_cwd, "origin", detected_base_branch.as_deref());
let sandbox_provider = resolve_sandbox_provider(
args.sandbox.map(Into::into),
Some(&source_input.config),
&source_input.run_defaults,
)?;
let sandbox_provider =
resolve_sandbox_provider(args.sandbox.map(Into::into), &source_input.settings)?;
let validated = fabro_workflows::operations::validate(
&source_input.raw_source,
@ -45,7 +42,7 @@ pub async fn execute(mut args: PreflightArgs) -> anyhow::Result<()> {
.unwrap_or(Path::new("."))
.to_path_buf(),
),
config: Some(source_input.config.clone()),
settings: Some(source_input.settings.clone()),
goal_override: source_input.goal_override.clone(),
..Default::default()
},
@ -57,10 +54,9 @@ pub async fn execute(mut args: PreflightArgs) -> anyhow::Result<()> {
run_preflight(
validated.graph(),
&Some(source_input.config),
&source_input.settings,
args.model.as_deref(),
args.provider.as_deref(),
&source_input.run_defaults,
git_status,
sandbox_provider,
styles,

View file

@ -150,7 +150,7 @@ async fn check_github_app_installation() {
};
// Load CLI config to get app_id and slug
let cli_config = match crate::cli_config::load_cli_config(None) {
let cli_config = match crate::cli_config::load_cli_settings(None) {
Ok(c) => c,
Err(_) => return,
};

View file

@ -42,7 +42,7 @@ pub async fn attach_run(
let is_tty = std::io::stderr().is_terminal();
let verbose = fabro_workflows::records::RunRecord::load(run_dir)
.map(|record| record.config.verbose_enabled())
.map(|record| record.settings.verbose_enabled())
.unwrap_or(false);
let mut progress_ui = run_progress::ProgressUI::new(is_tty, verbose);

View file

@ -21,7 +21,7 @@ enum CopyDirection {
pub async fn cp_command(args: CpArgs) -> Result<()> {
let direction = parse_direction(&args.src, &args.dst)?;
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
match direction {

View file

@ -33,7 +33,7 @@ pub async fn create_run(
let run_dir = match args
.storage_dir
.clone()
.or_else(|| source_input.config.storage_dir.clone())
.or_else(|| source_input.settings.storage_dir.clone())
{
Some(sd) => make_run_dir(&sd.join("runs"), &run_id, args.dry_run),
None => default_run_dir(&run_id, args.dry_run),
@ -43,24 +43,20 @@ pub async fn create_run(
.ok()
.and_then(|(_, branch)| branch);
if !args.dry_run {
let _ = resolve_sandbox_provider(
args.sandbox.map(Into::into),
Some(&source_input.config),
&source_input.run_defaults,
)?;
let _ = resolve_sandbox_provider(args.sandbox.map(Into::into), &source_input.settings)?;
}
let config = source_input.config.clone();
let settings = source_input.settings.clone();
let persisted = match fabro_workflows::operations::create(
&source_input.raw_source,
fabro_workflows::operations::RunCreateOptions {
config,
settings,
run_dir: Some(run_dir.clone()),
run_id: Some(run_id.clone()),
workflow_slug: source_input.workflow_slug.clone(),
labels: {
let mut labels = source_input.config.labels.clone();
let mut labels = source_input.settings.labels.clone();
labels.extend(parse_labels(&args.label));
labels
},

View file

@ -16,7 +16,7 @@ pub async fn execute(storage_dir: PathBuf, run_id: String, resume: bool) -> Resu
let run_dir = fabro_workflows::run_lookup::find_run_by_prefix(&runs_base, &run_id)?;
let styles: &'static fabro_util::terminal::Styles =
Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr()));
let cli_config = cli_config::load_cli_config(None)?;
let cli_config = cli_config::load_cli_settings(None)?;
let github_app = shared::github::build_github_app_credentials(cli_config.app_id());
let git_author = fabro_workflows::git::GitAuthor::from_options(
cli_config.git_author().and_then(|a| a.name.clone()),
@ -54,22 +54,14 @@ pub async fn execute(storage_dir: PathBuf, run_id: String, resume: bool) -> Resu
super::execute::resume_from_record(
persisted,
run_dir.clone(),
cli_config,
styles,
github_app,
git_author,
)
.await
} else {
super::execute::run_from_record(
persisted,
run_dir.clone(),
cli_config,
styles,
github_app,
git_author,
)
.await
super::execute::run_from_record(persisted, run_dir.clone(), styles, github_app, git_author)
.await
};
match result {

View file

@ -8,7 +8,7 @@ use crate::args::DiffArgs;
pub async fn run(args: DiffArgs) -> Result<()> {
info!(run_id = %args.run, "Showing diff");
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_dir = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?.path;

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@ use tracing::{debug, info};
use crate::args::LogsArgs;
pub fn run(args: LogsArgs, styles: &Styles) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?;

View file

@ -24,13 +24,13 @@ pub async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<()> {
RunCommands::Create(args) => {
let styles: &'static fabro_util::terminal::Styles =
Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr()));
let cli_config = fabro_config::cli::load_cli_config(None)?;
let (run_id, _run_dir) = create::create_run(&args, cli_config, styles, true).await?;
let cli_defaults = fabro_config::cli::load_cli_config(None)?;
let (run_id, _run_dir) = create::create_run(&args, cli_defaults, styles, true).await?;
println!("{run_id}");
Ok(())
}
RunCommands::Start { run } => {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?;
let child = start::start_run(&run_info.path, false)?;
@ -40,7 +40,7 @@ pub async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<()> {
RunCommands::Attach { run } => {
let styles: &'static fabro_util::terminal::Styles =
Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr()));
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?;
let exit_code = attach::attach_run(&run_info.path, false, styles, None).await?;
@ -67,7 +67,7 @@ pub async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<()> {
Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr()));
#[cfg(feature = "sleep_inhibitor")]
let _sleep_guard = {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
crate::sleep_inhibitor::guard(cli_config.prevent_idle_sleep_enabled())
};
resume::resume_command(args, styles).await

View file

@ -5,7 +5,7 @@ use crate::args::PreviewArgs;
use crate::shared::validate_daytona_provider;
pub async fn run(args: PreviewArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_dir = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?.path;
let sandbox_json = run_dir.join("sandbox.json");

View file

@ -11,7 +11,7 @@ use crate::args::ResumeArgs;
/// artifacts from the previous execution, then spawns an engine subprocess
/// (identical to `fabro run`'s create→start→attach flow).
pub async fn resume_command(args: ResumeArgs, styles: &'static Styles) -> anyhow::Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_dir = fabro_workflows::run_lookup::find_run_by_prefix(&base, &args.run)?;

View file

@ -5,7 +5,7 @@ use crate::args::SshArgs;
use crate::shared::validate_daytona_provider;
pub async fn run(args: SshArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_dir = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?.path;
let sandbox_json = run_dir.join("sandbox.json");

View file

@ -130,7 +130,7 @@ mod tests {
RunRecord {
run_id: "run-test123".to_string(),
created_at: Utc::now(),
config: FabroSettings::default(),
settings: FabroSettings::default(),
graph: Graph {
name: "test".to_string(),
..Default::default()

View file

@ -9,7 +9,7 @@ use crate::args::WaitArgs;
use crate::shared::format_duration_ms;
pub fn run(args: WaitArgs, styles: &Styles) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run_info = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?;

View file

@ -18,7 +18,7 @@ pub struct InspectOutput {
}
pub fn run(args: &InspectArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let run = fabro_workflows::run_lookup::resolve_run(&base, &args.run)?;
let output = inspect_run_dir(&run.run_id, &run.path, run.status)?;

View file

@ -12,7 +12,7 @@ use crate::shared::{color_if, format_duration_ms, tilde_path};
use super::short_run_id;
pub fn list_command(args: &RunsListArgs, styles: &Styles) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
let runs = fabro_workflows::run_lookup::scan_runs(&base)?;
let label_filters = parse_label_filters(&args.filter.label);

View file

@ -8,7 +8,7 @@ use crate::args::RunsRemoveArgs;
use super::short_run_id;
pub async fn remove_command(args: &RunsRemoveArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
remove_from(args, &base).await
}

View file

@ -9,7 +9,7 @@ use crate::args::DfArgs;
use crate::shared::format_size;
pub fn df_command(args: &DfArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let data_dir = cli_config.storage_dir();
let runs_base = fabro_workflows::run_lookup::runs_base(&data_dir);
let logs_base = fabro_workflows::run_lookup::logs_base(&data_dir);

View file

@ -8,7 +8,7 @@ use crate::args::RunsPruneArgs;
use crate::shared::format_size;
pub fn prune_command(args: &RunsPruneArgs) -> Result<()> {
let cli_config = crate::cli_config::load_cli_config(None)?;
let cli_config = crate::cli_config::load_cli_settings(None)?;
let base = fabro_workflows::run_lookup::runs_base(&cli_config.storage_dir());
prune_from(args, &base)
}

View file

@ -99,19 +99,15 @@ async fn main_inner() -> (String, Result<()>) {
#[cfg(feature = "server")]
{
if let Commands::Serve(args) = command.as_ref() {
match fabro_config::server::load_server_config(args.config.as_deref()) {
Ok(server_config) => match fabro_config::FabroSettings::try_from(server_config)
{
Ok(server_settings) => (
server_settings.log.as_ref().and_then(|l| l.level.clone()),
false,
),
Err(err) => return (command_name, Err(err)),
},
match fabro_config::server::load_server_settings(args.config.as_deref()) {
Ok(server_settings) => (
server_settings.log.as_ref().and_then(|l| l.level.clone()),
false,
),
Err(err) => return (command_name, Err(err)),
}
} else {
match crate::cli_config::load_cli_config(None) {
match crate::cli_config::load_cli_settings(None) {
Ok(cli_config) => (
cli_config.log.as_ref().and_then(|l| l.level.clone()),
cli_config.upgrade_check_enabled(),
@ -122,7 +118,7 @@ async fn main_inner() -> (String, Result<()>) {
}
#[cfg(not(feature = "server"))]
{
match crate::cli_config::load_cli_config(None) {
match crate::cli_config::load_cli_settings(None) {
Ok(cli_config) => (
cli_config.log.as_ref().and_then(|l| l.level.clone()),
cli_config.upgrade_check_enabled(),
@ -184,7 +180,7 @@ async fn main_inner() -> (String, Result<()>) {
fabro_api::serve::serve_command(args, styles).await?;
}
Commands::Doctor { verbose, dry_run } => {
let cli_config = cli_config::load_cli_config(None)?;
let cli_config = cli_config::load_cli_settings(None)?;
let verbose = verbose || cli_config.verbose_enabled();
let exit_code = commands::doctor::run_doctor(verbose, !dry_run).await;
std::process::exit(exit_code);

View file

@ -1637,21 +1637,21 @@ fn create_explicit_workflow_path_uses_project_config_relative_to_workflow() {
let run_record: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(run_dir.join("run.json")).unwrap()).unwrap();
assert_eq!(run_record["config"]["auto_approve"].as_bool(), Some(true));
assert_eq!(run_record["settings"]["auto_approve"].as_bool(), Some(true));
assert_eq!(
run_record["config"]["storage_dir"].as_str(),
run_record["settings"]["storage_dir"].as_str(),
Some(storage_dir.to_str().unwrap())
);
assert_eq!(
run_record["config"]["sandbox"]["preserve"].as_bool(),
run_record["settings"]["sandbox"]["preserve"].as_bool(),
Some(true)
);
assert_eq!(
run_record["config"]["llm"]["model"].as_str(),
run_record["settings"]["llm"]["model"].as_str(),
Some("gpt-5.2")
);
assert_eq!(
run_record["config"]["setup"]["commands"],
run_record["settings"]["setup"]["commands"],
serde_json::json!(["workflow-setup", "project-setup", "cli-setup"])
);
}

View file

@ -296,6 +296,10 @@ pub fn load_server_config(path: Option<&Path>) -> anyhow::Result<FabroConfig> {
crate::load_config_file(path, "server.toml")
}
pub fn load_server_settings(path: Option<&Path>) -> anyhow::Result<FabroSettings> {
load_server_config(path)?.try_into()
}
/// Resolve the storage directory: config value > default `~/.fabro`.
pub fn resolve_storage_dir(config: &FabroSettings) -> PathBuf {
config.storage_dir()

View file

@ -199,6 +199,42 @@ impl FabroSettings {
self.git.as_ref().map(|g| &g.author)
}
pub fn sandbox_settings(&self) -> Option<&SandboxSettings> {
self.sandbox.as_ref()
}
pub fn setup_settings(&self) -> Option<&SetupSettings> {
self.setup.as_ref()
}
pub fn setup_commands(&self) -> &[String] {
self.setup
.as_ref()
.map(|setup| setup.commands.as_slice())
.unwrap_or(&[])
}
pub fn setup_timeout_ms(&self) -> Option<u64> {
self.setup.as_ref().and_then(|setup| setup.timeout_ms)
}
pub fn preserve_sandbox_enabled(&self) -> bool {
self.sandbox
.as_ref()
.and_then(|sandbox| sandbox.preserve)
.unwrap_or(false)
}
pub fn github_permissions(&self) -> Option<&HashMap<String, String>> {
self.github
.as_ref()
.and_then(|github| (!github.permissions.is_empty()).then_some(&github.permissions))
}
pub fn mcp_server_entries(&self) -> &HashMap<String, McpServerEntry> {
&self.mcp_servers
}
pub fn verbose_enabled(&self) -> bool {
self.verbose.unwrap_or(false)
}

View file

@ -144,10 +144,9 @@ impl Handler for SubWorkflowHandler {
let git_state = services.git_state();
let child_run_options = RunOptions {
config: fabro_config::FabroSettings::default(),
settings: fabro_config::FabroSettings::default(),
run_dir: child_logs,
cancel_token: Some(cancel_token),
dry_run: services.dry_run,
run_id: format!("{parent_run_id}_child_{}", node.id),
labels: HashMap::new(),
git_author: git_state

View file

@ -186,7 +186,7 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
}
// Push run branch (skip in dry-run mode)
if !self.run_options.dry_run {
if !self.run_options.dry_run_enabled() {
if let Some(branch) = self
.run_options
.git

View file

@ -16,12 +16,12 @@ use crate::transforms::{expand_vars, Transform};
pub struct ValidateOptions {
pub base_dir: Option<PathBuf>,
pub custom_transforms: Vec<Box<dyn Transform>>,
pub config: Option<FabroSettings>,
pub settings: Option<FabroSettings>,
pub goal_override: Option<String>,
}
pub struct RunCreateOptions {
pub config: FabroSettings,
pub settings: FabroSettings,
pub run_dir: Option<PathBuf>,
pub run_id: Option<String>,
pub workflow_slug: Option<String>,
@ -42,7 +42,7 @@ pub fn validate(dot_source: &str, options: ValidateOptions) -> Result<Validated,
dot_source,
options.base_dir,
options.custom_transforms,
options.config.as_ref(),
options.settings.as_ref(),
options.goal_override.as_deref(),
)
}
@ -61,13 +61,13 @@ pub fn validate_from_file(path: &Path) -> Result<Validated, FabroError> {
)
}
/// Parse, transform, validate, normalize config, and persist a run.
/// Parse, transform, validate, resolve settings, and persist a run.
pub fn create(dot_source: &str, options: RunCreateOptions) -> Result<Persisted, FabroError> {
let validated = preprocess_and_validate(
dot_source,
options.base_dir.clone(),
Vec::new(),
Some(&options.config),
Some(&options.settings),
options.goal_override.as_deref(),
)?;
@ -96,10 +96,10 @@ fn preprocess_and_validate(
dot_source: &str,
base_dir: Option<PathBuf>,
custom_transforms: Vec<Box<dyn Transform>>,
config: Option<&FabroSettings>,
settings: Option<&FabroSettings>,
goal_override: Option<&str>,
) -> Result<Validated, FabroError> {
let source = match config.and_then(|cfg| cfg.vars.as_ref()) {
let source = match settings.and_then(|resolved| resolved.vars.as_ref()) {
Some(vars) => {
let mut vars = vars.clone();
// `$goal` is resolved later from the graph goal after any goal override.
@ -137,7 +137,7 @@ fn persist_validated(
options: RunCreateOptions,
) -> Result<Persisted, FabroError> {
let RunCreateOptions {
mut config,
settings,
run_dir,
run_id,
workflow_slug,
@ -149,17 +149,17 @@ fn persist_validated(
base_dir: _,
} = options;
finalize_settings(&mut config, validated.graph());
let settings = resolve_run_settings(settings, validated.graph());
let run_id = run_id.unwrap_or_else(|| ulid::Ulid::new().to_string());
let run_dir = run_dir.unwrap_or_else(|| default_run_dir(&run_id, config.dry_run_enabled()));
let run_dir = run_dir.unwrap_or_else(|| default_run_dir(&run_id, settings.dry_run_enabled()));
let working_directory = working_directory
.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
let run_record = RunRecord {
run_id,
created_at: Utc::now(),
config,
settings,
graph: validated.graph().clone(),
workflow_slug,
working_directory,
@ -177,8 +177,8 @@ fn persist_validated(
)
}
pub(crate) fn finalize_settings(config: &mut FabroSettings, graph: &Graph) {
let llm_config = config.llm.as_ref();
pub(crate) fn resolve_run_settings(mut settings: FabroSettings, graph: &Graph) -> FabroSettings {
let llm_config = settings.llm.as_ref();
let configured_model = llm_config.and_then(|l| l.model.as_deref());
let configured_provider = llm_config.and_then(|l| l.provider.as_deref());
let graph_provider = graph.attrs.get("default_provider").and_then(|v| v.as_str());
@ -208,16 +208,18 @@ pub(crate) fn finalize_settings(config: &mut FabroSettings, graph: &Graph) {
None => (model, provider),
};
let llm = config.llm.get_or_insert_default();
let llm = settings.llm.get_or_insert_default();
llm.model = Some(resolved_model);
llm.provider = resolved_provider;
let goal = graph.goal().to_string();
config.goal = if goal.is_empty() { None } else { Some(goal) };
config.pull_request = config
settings.goal = if goal.is_empty() { None } else { Some(goal) };
settings.pull_request = settings
.pull_request
.take()
.filter(|pull_request| pull_request.enabled);
settings
}
pub fn default_run_dir(run_id: &str, dry_run: bool) -> PathBuf {
@ -308,7 +310,7 @@ mod tests {
let validated = validate(
dot,
ValidateOptions {
config: Some(FabroSettings {
settings: Some(FabroSettings {
vars: Some(HashMap::from([("who".to_string(), "agent".to_string())])),
..Default::default()
}),
@ -407,7 +409,7 @@ mod tests {
let err = create(
dot,
RunCreateOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: None,
run_id: None,
workflow_slug: None,
@ -435,7 +437,7 @@ mod tests {
let persisted = create(
MINIMAL_DOT,
RunCreateOptions {
config: FabroSettings {
settings: FabroSettings {
llm: Some(fabro_config::run::LlmSettings {
model: Some("sonnet".to_string()),
provider: None,
@ -466,7 +468,7 @@ mod tests {
assert_eq!(
persisted
.run_record()
.config
.settings
.llm
.as_ref()
.and_then(|llm| llm.model.as_deref()),
@ -475,17 +477,17 @@ mod tests {
assert_eq!(
persisted
.run_record()
.config
.settings
.llm
.as_ref()
.and_then(|llm| llm.provider.as_deref()),
Some("anthropic")
);
assert_eq!(
persisted.run_record().config.goal.as_deref(),
persisted.run_record().settings.goal.as_deref(),
Some("override goal")
);
assert!(persisted.run_record().config.pull_request.is_none());
assert!(persisted.run_record().settings.pull_request.is_none());
assert_eq!(
persisted.run_record().workflow_slug.as_deref(),
Some("slug")

View file

@ -32,7 +32,7 @@ pub struct StartPullRequestConfig {
/// Options for `start()` and `resume()`.
///
/// Fields that are derivable from `RunRecord` (run_id, labels, base_branch,
/// host_repo_path, config, workflow_slug) are read from disk by `run_engine()`.
/// host_repo_path, settings, workflow_slug) are read from disk by `run_engine()`.
/// Callers only provide truly external values.
pub struct StartOptions {
// Truly external (not derivable from RunRecord)
@ -51,9 +51,6 @@ pub struct StartOptions {
pub github_app: Option<fabro_github::GitHubAppCredentials>,
pub worktree_mode: Option<WorktreeMode>,
pub registry_override: Option<Arc<crate::handler::HandlerRegistry>>,
// Still external for now — could be derived from RunRecord.config in follow-up
pub dry_run: bool,
pub retro: StartRetroOptions,
pub finalize: StartFinalizeOptions,
pub pull_request: StartPullRequestConfig,
@ -116,13 +113,12 @@ async fn run_engine(
) -> Result<Started, FabroError> {
let preserve_sandbox = options.finalize.preserve_sandbox;
// Build RunOptions from the persisted RunRecord + external caller options
// Build RunOptions from the persisted RunRecord + external caller options.
let record = persisted.run_record();
let run_options = RunOptions {
config: record.config.clone(),
settings: record.settings.clone(),
run_dir: persisted.run_dir().to_path_buf(),
cancel_token: options.cancel_token,
dry_run: options.dry_run,
run_id: record.run_id.clone(),
labels: record.labels.clone(),
git_author: options.git_author,
@ -161,7 +157,7 @@ async fn run_engine(
let init_options = InitOptions {
run_id: record.run_id.clone(),
dry_run: options.dry_run,
dry_run: run_options.dry_run_enabled(),
emitter: options.emitter,
sandbox: options.sandbox,
llm: options.llm,
@ -274,7 +270,7 @@ mod tests {
crate::operations::create(
dot,
crate::operations::RunCreateOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: Some(run_dir.to_path_buf()),
run_id: Some("run-test".to_string()),
workflow_slug: Some("test".to_string()),
@ -333,7 +329,6 @@ mod tests {
github_app: None,
worktree_mode: None,
registry_override: Some(registry),
dry_run: false,
retro: StartRetroOptions { enabled: false },
finalize: StartFinalizeOptions { preserve_sandbox },
pull_request: StartPullRequestConfig {

View file

@ -199,7 +199,7 @@ pub async fn execute(init: Initialized) -> Executed {
let graph_max = graph.max_node_visits();
let max_node_visits = if graph_max > 0 {
Some(graph_max as usize)
} else if run_options.dry_run {
} else if run_options.dry_run_enabled() {
Some(10)
} else {
None

View file

@ -69,9 +69,8 @@ fn test_run_options(run_dir: &Path, run_id: &str) -> RunOptions {
RunOptions {
run_dir: run_dir.to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: run_id.into(),
config: FabroSettings::default(),
settings: FabroSettings::default(),
git: None,
host_repo_path: None,
labels: HashMap::new(),
@ -115,7 +114,7 @@ fn persisted_workflow(graph: Graph, source: String, run_dir: &Path, run_id: &str
RunRecord {
run_id: run_id.to_string(),
created_at: Utc::now(),
config: FabroSettings::default(),
settings: FabroSettings::default(),
graph,
workflow_slug: Some("test".to_string()),
working_directory: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),

View file

@ -311,10 +311,9 @@ mod tests {
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
dry_run: true,
run_id: "run-test".to_string(),
labels: HashMap::new(),
git_author: crate::git::GitAuthor::default(),

View file

@ -737,7 +737,7 @@ pub async fn initialize(
};
if effective_dry_run {
options.dry_run = true;
options.run_options.dry_run = true;
options.run_options.settings.dry_run = Some(true);
}
let has_run_branch = options
@ -900,10 +900,9 @@ mod tests {
fn test_settings(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: "run-test".to_string(),
labels: HashMap::new(),
git_author: crate::git::GitAuthor::default(),
@ -925,7 +924,7 @@ mod tests {
RunRecord {
run_id: "run-test".to_string(),
created_at: Utc::now(),
config: FabroSettings::default(),
settings: FabroSettings::default(),
graph,
workflow_slug: Some("test".to_string()),
working_directory: std::env::current_dir().unwrap(),

View file

@ -110,7 +110,7 @@ mod tests {
RunRecord {
run_id: "run-123".to_string(),
created_at: Utc::now(),
config: FabroSettings {
settings: FabroSettings {
dry_run: Some(true),
verbose: Some(true),
..Default::default()

View file

@ -488,7 +488,7 @@ pub async fn pull_request(concluded: Concluded, options: &PullRequestOptions) ->
let mut pr_url = None;
if let Some(pr_cfg) = &options.pr_config {
if run_options.dry_run {
if run_options.dry_run_enabled() {
tracing::debug!("Skipping PR creation: run is in dry-run mode");
} else if let Err(ref e) = outcome {
tracing::debug!(error = %e, "Skipping PR creation: engine returned an error");

View file

@ -127,7 +127,7 @@ pub async fn retro(executed: Executed, options: &RetroOptions) -> Retroed {
provider: _,
} = executed;
let dry_run = run_options.dry_run;
let dry_run = run_options.dry_run_enabled();
let retro = if options.enabled {
run_retro(options, dry_run).await
@ -183,10 +183,9 @@ mod tests {
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
dry_run: true,
run_id: "run-test".to_string(),
labels: HashMap::new(),
git_author: crate::git::GitAuthor::default(),

View file

@ -12,7 +12,7 @@ const FILE_NAME: &str = "run.json";
pub struct RunRecord {
pub run_id: String,
pub created_at: DateTime<Utc>,
pub config: FabroSettings,
pub settings: FabroSettings,
pub graph: Graph,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workflow_slug: Option<String>,
@ -73,7 +73,7 @@ mod tests {
RunRecord {
run_id: "run-abc123".to_string(),
created_at: Utc::now(),
config: FabroSettings::default(),
settings: FabroSettings::default(),
graph,
workflow_slug: Some("smoke".to_string()),
working_directory: PathBuf::from("/home/user/project"),

View file

@ -19,10 +19,9 @@ pub struct GitCheckpointOptions {
/// Options for a workflow run.
#[derive(Clone)]
pub struct RunOptions {
pub config: FabroSettings,
pub settings: FabroSettings,
pub run_dir: PathBuf,
pub cancel_token: Option<Arc<AtomicBool>>,
pub dry_run: bool,
/// Unique identifier for this workflow run.
pub run_id: String,
/// User-defined key-value labels for this run.
@ -44,17 +43,21 @@ pub struct RunOptions {
}
impl RunOptions {
pub fn dry_run_enabled(&self) -> bool {
self.settings.dry_run_enabled()
}
pub fn checkpoint_exclude_globs(&self) -> &[String] {
&self.config.checkpoint.exclude_globs
&self.settings.checkpoint.exclude_globs
}
/// PR config (already normalized — disabled entries stripped at construction).
pub fn pull_request(&self) -> Option<&PullRequestSettings> {
self.config.pull_request.as_ref()
self.settings.pull_request.as_ref()
}
pub fn asset_globs(&self) -> &[String] {
self.config
self.settings
.assets
.as_ref()
.map(|a| a.include.as_slice())

View file

@ -38,7 +38,7 @@ fn initialized(
registry: Arc::new(registry),
hook_runner: options.hook_runner,
env: options.env,
dry_run: run_options.dry_run,
dry_run: run_options.dry_run_enabled(),
llm_client: None,
model: String::new(),
provider: fabro_llm::Provider::Anthropic,

View file

@ -389,10 +389,9 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
let run_options = RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: "test-run".into(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),
@ -581,10 +580,9 @@ async fn daytona_git_checkpoint_remote_emits_events() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env.clone());
let run_options = RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: "git-cp-test".into(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),
@ -768,10 +766,9 @@ async fn daytona_parallel_git_branching_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), Arc::clone(&env));
let run_options = RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: run_tmp.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: run_id.clone(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),
@ -1145,10 +1142,9 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
let meta_branch = MetadataStore::branch_name(&run_id);
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
let run_options = RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: run_id.clone(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),
@ -1286,7 +1282,7 @@ async fn daytona_asset_collection() {
graph.edges.push(Edge::new("create_assets", "exit"));
let run_options = RunOptions {
config: FabroSettings {
settings: FabroSettings {
assets: Some(fabro_config::run::AssetsSettings {
include: vec!["test-results/**".to_string()],
}),
@ -1294,7 +1290,6 @@ async fn daytona_asset_collection() {
},
run_dir: dir.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: "asset-test-daytona".into(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),
@ -1543,10 +1538,9 @@ async fn daytona_git_push_run_branch_to_origin() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
let run_options = RunOptions {
config: FabroSettings::default(),
settings: FabroSettings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
dry_run: false,
run_id: run_id.clone(),
labels: std::collections::HashMap::new(),
git_author: fabro_workflows::git::GitAuthor::default(),

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ import type { PaginatedStageTurnList } from '../models';
// @ts-ignore
import type { RunCheckpoint } from '../models';
// @ts-ignore
import type { RunConfiguration } from '../models';
import type { RunSettings } from '../models';
/**
* RunInternalsApi - axios parameter creator
*/
@ -184,16 +184,16 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
};
},
/**
* Returns the structured configuration used to launch this run.
* @summary Retrieve Run Configuration
* Returns the structured settings used to launch this run.
* @summary Retrieve Run Settings
* @param {string} id Unique run identifier (ULID).
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveRunConfiguration: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
retrieveRunSettings: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('retrieveRunConfiguration', 'id', id)
const localVarPath = `/runs/{id}/configuration`
assertParamExists('retrieveRunSettings', 'id', id)
const localVarPath = `/runs/{id}/settings`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -319,16 +319,16 @@ export const RunInternalsApiFp = function(configuration?: Configuration) {
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
* Returns the structured configuration used to launch this run.
* @summary Retrieve Run Configuration
* Returns the structured settings used to launch this run.
* @summary Retrieve Run Settings
* @param {string} id Unique run identifier (ULID).
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async retrieveRunConfiguration(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunConfiguration>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.retrieveRunConfiguration(id, options);
async retrieveRunSettings(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunSettings>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.retrieveRunSettings(id, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.retrieveRunConfiguration']?.[localVarOperationServerIndex]?.url;
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.retrieveRunSettings']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
@ -389,14 +389,14 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b
return localVarFp.retrieveRunCheckpoint(id, options).then((request) => request(axios, basePath));
},
/**
* Returns the structured configuration used to launch this run.
* @summary Retrieve Run Configuration
* Returns the structured settings used to launch this run.
* @summary Retrieve Run Settings
* @param {string} id Unique run identifier (ULID).
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveRunConfiguration(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunConfiguration> {
return localVarFp.retrieveRunConfiguration(id, options).then((request) => request(axios, basePath));
retrieveRunSettings(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunSettings> {
return localVarFp.retrieveRunSettings(id, options).then((request) => request(axios, basePath));
},
/**
* Returns the key-value context map accumulated during the run. Empty if the run has not started.
@ -454,14 +454,14 @@ export class RunInternalsApi extends BaseAPI {
}
/**
* Returns the structured configuration used to launch this run.
* @summary Retrieve Run Configuration
* Returns the structured settings used to launch this run.
* @summary Retrieve Run Settings
* @param {string} id Unique run identifier (ULID).
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
public retrieveRunConfiguration(id: string, options?: RawAxiosRequestConfig) {
return RunInternalsApiFp(this.configuration).retrieveRunConfiguration(id, options).then((request) => request(this.axios, this.basePath));
public retrieveRunSettings(id: string, options?: RawAxiosRequestConfig) {
return RunInternalsApiFp(this.configuration).retrieveRunSettings(id, options).then((request) => request(this.axios, this.basePath));
}
/**
@ -475,4 +475,3 @@ export class RunInternalsApi extends BaseAPI {
return RunInternalsApiFp(this.configuration).retrieveRunContext(id, options).then((request) => request(this.axios, this.basePath));
}
}

View file

@ -22,19 +22,19 @@ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObj
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';
// @ts-ignore
import type { ServerConfiguration } from '../models';
import type { ServerSettings } from '../models';
/**
* SettingsApi - axios parameter creator
*/
export const SettingsApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
* Returns the structured server configuration.
* @summary Retrieve Server Configuration
* Returns the structured server settings.
* @summary Retrieve Server Settings
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveServerConfiguration: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
retrieveServerSettings: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/settings`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -75,15 +75,15 @@ export const SettingsApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = SettingsApiAxiosParamCreator(configuration)
return {
/**
* Returns the structured server configuration.
* @summary Retrieve Server Configuration
* Returns the structured server settings.
* @summary Retrieve Server Settings
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async retrieveServerConfiguration(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ServerConfiguration>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.retrieveServerConfiguration(options);
async retrieveServerSettings(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ServerSettings>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.retrieveServerSettings(options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['SettingsApi.retrieveServerConfiguration']?.[localVarOperationServerIndex]?.url;
const localVarOperationServerBasePath = operationServerMap['SettingsApi.retrieveServerSettings']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
}
@ -96,13 +96,13 @@ export const SettingsApiFactory = function (configuration?: Configuration, baseP
const localVarFp = SettingsApiFp(configuration)
return {
/**
* Returns the structured server configuration.
* @summary Retrieve Server Configuration
* Returns the structured server settings.
* @summary Retrieve Server Settings
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveServerConfiguration(options?: RawAxiosRequestConfig): AxiosPromise<ServerConfiguration> {
return localVarFp.retrieveServerConfiguration(options).then((request) => request(axios, basePath));
retrieveServerSettings(options?: RawAxiosRequestConfig): AxiosPromise<ServerSettings> {
return localVarFp.retrieveServerSettings(options).then((request) => request(axios, basePath));
},
};
};
@ -112,13 +112,12 @@ export const SettingsApiFactory = function (configuration?: Configuration, baseP
*/
export class SettingsApi extends BaseAPI {
/**
* Returns the structured server configuration.
* @summary Retrieve Server Configuration
* Returns the structured server settings.
* @summary Retrieve Server Settings
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
public retrieveServerConfiguration(options?: RawAxiosRequestConfig) {
return SettingsApiFp(this.configuration).retrieveServerConfiguration(options).then((request) => request(this.axios, this.basePath));
public retrieveServerSettings(options?: RawAxiosRequestConfig) {
return SettingsApiFp(this.configuration).retrieveServerSettings(options).then((request) => request(this.axios, this.basePath));
}
}

View file

@ -133,7 +133,7 @@ export const WorkflowsApiAxiosParamCreator = function (configuration?: Configura
};
},
/**
* Returns the full detail of a workflow including its DOT graph, TOML config, and description.
* Returns the full detail of a workflow including its DOT graph, resolved settings, and description.
* @summary Retrieve Workflow
* @param {string} name URL-safe slug identifying a workflow definition.
* @param {*} [options] Override http request option.
@ -212,7 +212,7 @@ export const WorkflowsApiFp = function(configuration?: Configuration) {
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
* Returns the full detail of a workflow including its DOT graph, TOML config, and description.
* Returns the full detail of a workflow including its DOT graph, resolved settings, and description.
* @summary Retrieve Workflow
* @param {string} name URL-safe slug identifying a workflow definition.
* @param {*} [options] Override http request option.
@ -257,7 +257,7 @@ export const WorkflowsApiFactory = function (configuration?: Configuration, base
return localVarFp.listWorkflows(pageLimit, pageOffset, options).then((request) => request(axios, basePath));
},
/**
* Returns the full detail of a workflow including its DOT graph, TOML config, and description.
* Returns the full detail of a workflow including its DOT graph, resolved settings, and description.
* @summary Retrieve Workflow
* @param {string} name URL-safe slug identifying a workflow definition.
* @param {*} [options] Override http request option.
@ -299,7 +299,7 @@ export class WorkflowsApi extends BaseAPI {
}
/**
* Returns the full detail of a workflow including its DOT graph, TOML config, and description.
* Returns the full detail of a workflow including its DOT graph, resolved settings, and description.
* @summary Retrieve Workflow
* @param {string} name URL-safe slug identifying a workflow definition.
* @param {*} [options] Override http request option.
@ -309,4 +309,3 @@ export class WorkflowsApi extends BaseAPI {
return WorkflowsApiFp(this.configuration).retrieveWorkflow(name, options).then((request) => request(this.axios, this.basePath));
}
}

View file

@ -15,12 +15,12 @@
// May contain unused imports in some cases
// @ts-ignore
import type { TlsConfiguration } from './tls-configuration';
import type { TlsSettings } from './tls-configuration';
/**
* API server configuration.
*/
export interface ApiConfiguration {
export interface ApiSettings {
/**
* API base URL.
*/
@ -28,15 +28,15 @@ export interface ApiConfiguration {
/**
* Authentication strategies.
*/
'authentication_strategies'?: Array<ApiConfigurationAuthenticationStrategiesEnum>;
'tls'?: TlsConfiguration;
'authentication_strategies'?: Array<ApiSettingsAuthenticationStrategiesEnum>;
'tls'?: TlsSettings;
}
export const ApiConfigurationAuthenticationStrategiesEnum = {
export const ApiSettingsAuthenticationStrategiesEnum = {
JWT: 'jwt',
MTLS: 'mtls'
} as const;
export type ApiConfigurationAuthenticationStrategiesEnum = typeof ApiConfigurationAuthenticationStrategiesEnum[keyof typeof ApiConfigurationAuthenticationStrategiesEnum];
export type ApiSettingsAuthenticationStrategiesEnum = typeof ApiSettingsAuthenticationStrategiesEnum[keyof typeof ApiSettingsAuthenticationStrategiesEnum];

View file

@ -17,7 +17,7 @@
/**
* Asset collection configuration.
*/
export interface AssetsConfiguration {
export interface AssetsSettings {
/**
* Glob patterns for files to collect as run assets.
*/

View file

@ -17,22 +17,22 @@
/**
* Authentication configuration.
*/
export interface AuthConfiguration {
export interface AuthSettings {
/**
* Auth provider.
*/
'provider'?: AuthConfigurationProviderEnum;
'provider'?: AuthSettingsProviderEnum;
/**
* Allowed usernames.
*/
'allowed_usernames'?: Array<string>;
}
export const AuthConfigurationProviderEnum = {
export const AuthSettingsProviderEnum = {
GITHUB: 'github',
INSECURE_DISABLED: 'insecure_disabled'
} as const;
export type AuthConfigurationProviderEnum = typeof AuthConfigurationProviderEnum[keyof typeof AuthConfigurationProviderEnum];
export type AuthSettingsProviderEnum = typeof AuthSettingsProviderEnum[keyof typeof AuthSettingsProviderEnum];

View file

@ -17,7 +17,7 @@
/**
* Checkpoint configuration for file exclusion.
*/
export interface CheckpointConfiguration {
export interface CheckpointSettings {
/**
* Glob patterns to exclude from checkpoints.
*/

View file

@ -14,7 +14,7 @@
export interface DaytonaConfigurationNetworkOneOf {
export interface DaytonaSettingsNetworkOneOf {
/**
* CIDR allowlist for network access.
*/

View file

@ -15,12 +15,12 @@
// May contain unused imports in some cases
// @ts-ignore
import type { DaytonaConfigurationNetworkOneOf } from './daytona-configuration-network-one-of';
import type { DaytonaSettingsNetworkOneOf } from './daytona-configuration-network-one-of';
/**
* @type DaytonaConfigurationNetwork
* @type DaytonaSettingsNetwork
* Network access mode: \"block\", \"allow_all\", or {\"allow_list\": [...]}.
*/
export type DaytonaConfigurationNetwork = DaytonaConfigurationNetworkOneOf | string;
export type DaytonaSettingsNetwork = DaytonaSettingsNetworkOneOf | string;

View file

@ -15,15 +15,15 @@
// May contain unused imports in some cases
// @ts-ignore
import type { DaytonaConfigurationNetwork } from './daytona-configuration-network';
import type { DaytonaSettingsNetwork } from './daytona-configuration-network';
// May contain unused imports in some cases
// @ts-ignore
import type { DaytonaSnapshotConfiguration } from './daytona-snapshot-configuration';
import type { DaytonaSnapshotSettings } from './daytona-snapshot-configuration';
/**
* Daytona-specific sandbox settings.
*/
export interface DaytonaConfiguration {
export interface DaytonaSettings {
/**
* Auto-stop interval in seconds.
*/
@ -32,7 +32,7 @@ export interface DaytonaConfiguration {
* Labels applied to the sandbox.
*/
'labels'?: { [key: string]: string; };
'snapshot'?: DaytonaSnapshotConfiguration;
'network'?: DaytonaConfigurationNetwork;
'snapshot'?: DaytonaSnapshotSettings;
'network'?: DaytonaSettingsNetwork;
}

View file

@ -17,7 +17,7 @@
/**
* Snapshot configuration for Daytona sandboxes.
*/
export interface DaytonaSnapshotConfiguration {
export interface DaytonaSnapshotSettings {
/**
* Snapshot name.
*/

View file

@ -17,7 +17,7 @@
/**
* exe.dev sandbox configuration.
*/
export interface ExeConfiguration {
export interface ExeSettings {
/**
* VM image to use for the exe.dev sandbox.
*/

View file

@ -17,7 +17,7 @@
/**
* Git commit author configuration.
*/
export interface GitAuthorConfiguration {
export interface GitAuthorSettings {
/**
* Author name for commits.
*/

View file

@ -15,19 +15,19 @@
// May contain unused imports in some cases
// @ts-ignore
import type { GitAuthorConfiguration } from './git-author-configuration';
import type { GitAuthorSettings } from './git-author-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { WebhookConfiguration } from './webhook-configuration';
import type { WebhookSettings } from './webhook-configuration';
/**
* Git provider configuration.
*/
export interface GitConfiguration {
export interface GitSettings {
/**
* Git provider.
*/
'provider'?: GitConfigurationProviderEnum;
'provider'?: GitSettingsProviderEnum;
/**
* GitHub App ID.
*/
@ -40,14 +40,14 @@ export interface GitConfiguration {
* GitHub App slug.
*/
'slug'?: string;
'author'?: GitAuthorConfiguration;
'webhooks'?: WebhookConfiguration;
'author'?: GitAuthorSettings;
'webhooks'?: WebhookSettings;
}
export const GitConfigurationProviderEnum = {
export const GitSettingsProviderEnum = {
GITHUB: 'github'
} as const;
export type GitConfigurationProviderEnum = typeof GitConfigurationProviderEnum[keyof typeof GitConfigurationProviderEnum];
export type GitSettingsProviderEnum = typeof GitSettingsProviderEnum[keyof typeof GitSettingsProviderEnum];

View file

@ -17,7 +17,7 @@
/**
* GitHub App token injection configuration.
*/
export interface GitHubConfiguration {
export interface GitHubSettings {
/**
* GitHub API permissions to request (e.g. contents = write).
*/

View file

@ -17,7 +17,7 @@
/**
* LLM provider and model settings.
*/
export interface LlmConfiguration {
export interface LlmSettings {
/**
* Model identifier.
*/

View file

@ -17,20 +17,20 @@
/**
* Local sandbox settings.
*/
export interface LocalSandboxConfiguration {
export interface LocalSandboxSettings {
/**
* Git worktree mode for local sandbox.
*/
'worktree_mode'?: LocalSandboxConfigurationWorktreeModeEnum;
'worktree_mode'?: LocalSandboxSettingsWorktreeModeEnum;
}
export const LocalSandboxConfigurationWorktreeModeEnum = {
export const LocalSandboxSettingsWorktreeModeEnum = {
ALWAYS: 'always',
CLEAN: 'clean',
DIRTY: 'dirty',
NEVER: 'never'
} as const;
export type LocalSandboxConfigurationWorktreeModeEnum = typeof LocalSandboxConfigurationWorktreeModeEnum[keyof typeof LocalSandboxConfigurationWorktreeModeEnum];
export type LocalSandboxSettingsWorktreeModeEnum = typeof LocalSandboxSettingsWorktreeModeEnum[keyof typeof LocalSandboxSettingsWorktreeModeEnum];

View file

@ -17,7 +17,7 @@
/**
* Logging configuration.
*/
export interface LogConfiguration {
export interface LogSettings {
/**
* Log level (e.g. trace, debug, info).
*/

View file

@ -17,7 +17,7 @@
/**
* Pull request creation configuration.
*/
export interface PullRequestConfiguration {
export interface PullRequestSettings {
/**
* Whether to create a pull request after a successful run.
*/

View file

@ -18,20 +18,20 @@
import type { HookDefinition } from './hook-definition';
// May contain unused imports in some cases
// @ts-ignore
import type { LlmConfiguration } from './llm-configuration';
import type { LlmSettings } from './llm-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { SandboxConfiguration } from './sandbox-configuration';
import type { SandboxSettings } from './sandbox-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { SetupConfiguration } from './setup-configuration';
import type { SetupSettings } from './setup-configuration';
/**
* Structured run configuration mirroring WorkflowRunConfig.
* Structured run settings mirroring FabroSettings.
*/
export interface RunConfiguration {
export interface RunSettings {
/**
* Configuration schema version.
* Settings schema version.
*/
'version': number;
/**
@ -46,13 +46,12 @@ export interface RunConfiguration {
* Working directory for the run.
*/
'work_dir'?: string;
'llm'?: LlmConfiguration;
'setup'?: SetupConfiguration;
'sandbox'?: SandboxConfiguration;
'llm'?: LlmSettings;
'setup'?: SetupSettings;
'sandbox'?: SandboxSettings;
/**
* Variable map for template expansion.
*/
'vars'?: { [key: string]: string; };
'hooks'?: Array<HookDefinition>;
}

View file

@ -15,21 +15,21 @@
// May contain unused imports in some cases
// @ts-ignore
import type { DaytonaConfiguration } from './daytona-configuration';
import type { DaytonaSettings } from './daytona-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { ExeConfiguration } from './exe-configuration';
import type { ExeSettings } from './exe-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { LocalSandboxConfiguration } from './local-sandbox-configuration';
import type { LocalSandboxSettings } from './local-sandbox-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { SshConfiguration } from './ssh-configuration';
import type { SshSettings } from './ssh-configuration';
/**
* Sandbox execution environment settings.
*/
export interface SandboxConfiguration {
export interface SandboxSettings {
/**
* Sandbox provider name.
*/
@ -42,10 +42,10 @@ export interface SandboxConfiguration {
* Whether to use a devcontainer for the sandbox.
*/
'devcontainer'?: boolean;
'daytona'?: DaytonaConfiguration;
'exe'?: ExeConfiguration;
'ssh'?: SshConfiguration;
'local'?: LocalSandboxConfiguration;
'daytona'?: DaytonaSettings;
'exe'?: ExeSettings;
'ssh'?: SshSettings;
'local'?: LocalSandboxSettings;
/**
* Environment variables injected into the sandbox.
*/

View file

@ -15,51 +15,51 @@
// May contain unused imports in some cases
// @ts-ignore
import type { ApiConfiguration } from './api-configuration';
import type { ApiSettings } from './api-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { AssetsConfiguration } from './assets-configuration';
import type { AssetsSettings } from './assets-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { CheckpointConfiguration } from './checkpoint-configuration';
import type { CheckpointSettings } from './checkpoint-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { Features } from './features';
// May contain unused imports in some cases
// @ts-ignore
import type { GitConfiguration } from './git-configuration';
import type { GitSettings } from './git-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { GitHubConfiguration } from './git-hub-configuration';
import type { GitHubSettings } from './git-hub-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { HookDefinition } from './hook-definition';
// May contain unused imports in some cases
// @ts-ignore
import type { LlmConfiguration } from './llm-configuration';
import type { LlmSettings } from './llm-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { LogConfiguration } from './log-configuration';
import type { LogSettings } from './log-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { McpServerEntry } from './mcp-server-entry';
// May contain unused imports in some cases
// @ts-ignore
import type { PullRequestConfiguration } from './pull-request-configuration';
import type { PullRequestSettings } from './pull-request-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { SandboxConfiguration } from './sandbox-configuration';
import type { SandboxSettings } from './sandbox-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { SetupConfiguration } from './setup-configuration';
import type { SetupSettings } from './setup-configuration';
// May contain unused imports in some cases
// @ts-ignore
import type { WebConfiguration } from './web-configuration';
import type { WebSettings } from './web-configuration';
/**
* Structured server configuration mirroring ServerConfig.
* Structured server settings mirroring FabroSettings.
*/
export interface ServerConfiguration {
export interface ServerSettings {
/**
* Data directory path.
*/
@ -68,30 +68,29 @@ export interface ServerConfiguration {
* Maximum concurrent runs.
*/
'max_concurrent_runs'?: number;
'web'?: WebConfiguration;
'api'?: ApiConfiguration;
'git'?: GitConfiguration;
'web'?: WebSettings;
'api'?: ApiSettings;
'git'?: GitSettings;
'features'?: Features;
'log'?: LogConfiguration;
'log'?: LogSettings;
/**
* Default working directory.
*/
'work_dir'?: string;
'llm'?: LlmConfiguration;
'setup'?: SetupConfiguration;
'sandbox'?: SandboxConfiguration;
'llm'?: LlmSettings;
'setup'?: SetupSettings;
'sandbox'?: SandboxSettings;
/**
* Default variable map.
*/
'vars'?: { [key: string]: string; };
'checkpoint'?: CheckpointConfiguration;
'pull_request'?: PullRequestConfiguration;
'checkpoint'?: CheckpointSettings;
'pull_request'?: PullRequestSettings;
'hooks'?: Array<HookDefinition>;
'assets'?: AssetsConfiguration;
'assets'?: AssetsSettings;
/**
* Default MCP server configurations.
*/
'mcp_servers'?: { [key: string]: McpServerEntry; };
'github'?: GitHubConfiguration;
'github'?: GitHubSettings;
}

View file

@ -17,7 +17,7 @@
/**
* Setup commands run before the workflow.
*/
export interface SetupConfiguration {
export interface SetupSettings {
/**
* Shell commands to execute.
*/

View file

@ -17,7 +17,7 @@
/**
* SSH sandbox configuration for user-provided hosts.
*/
export interface SshConfiguration {
export interface SshSettings {
/**
* SSH destination (e.g. user@host or an SSH alias).
*/

View file

@ -17,7 +17,7 @@
/**
* TLS certificate configuration.
*/
export interface TlsConfiguration {
export interface TlsSettings {
/**
* Certificate file path.
*/

View file

@ -15,16 +15,16 @@
// May contain unused imports in some cases
// @ts-ignore
import type { AuthConfiguration } from './auth-configuration';
import type { AuthSettings } from './auth-configuration';
/**
* Web UI configuration.
*/
export interface WebConfiguration {
export interface WebSettings {
/**
* Web UI URL.
*/
'url'?: string;
'auth'?: AuthConfiguration;
'auth'?: AuthSettings;
}

View file

@ -17,17 +17,17 @@
/**
* Webhook delivery configuration.
*/
export interface WebhookConfiguration {
export interface WebhookSettings {
/**
* Webhook delivery strategy.
*/
'strategy': WebhookConfigurationStrategyEnum;
'strategy': WebhookSettingsStrategyEnum;
}
export const WebhookConfigurationStrategyEnum = {
export const WebhookSettingsStrategyEnum = {
TAILSCALE_FUNNEL: 'tailscale_funnel'
} as const;
export type WebhookConfigurationStrategyEnum = typeof WebhookConfigurationStrategyEnum[keyof typeof WebhookConfigurationStrategyEnum];
export type WebhookSettingsStrategyEnum = typeof WebhookSettingsStrategyEnum[keyof typeof WebhookSettingsStrategyEnum];

View file

@ -15,10 +15,10 @@
// May contain unused imports in some cases
// @ts-ignore
import type { RunConfiguration } from './run-configuration';
import type { RunSettings } from './run-configuration';
/**
* Full detail of a workflow definition including graph and configuration.
* Full detail of a workflow definition including graph and resolved settings.
*/
export interface WorkflowDetail {
/**
@ -37,10 +37,9 @@ export interface WorkflowDetail {
* Prose description of what the workflow does.
*/
'description': string;
'config': RunConfiguration;
'settings': RunSettings;
/**
* DOT language source defining the workflow graph.
*/
'graph': string;
}