Expand description
forge.toml schema + loader.
Org model. Projects are grouped under [[orgs]] (Stargate,
Gateway, Personal, etc.). Each org carries the accounts = [...]
pin shared by all its projects, replacing the per-project pin
that lived here before. Projects within an org keep a flat list
via [[orgs.projects]]. A launch with no project named opens every
project whose seat the store records as open, resuming the session
forge stored for each unless --new is passed; the alphabetically
first project is the fallback target when no project is named and no
picker chooses one.
Selection policy. The gateway’s declared-model walk: over the
org’s accounts primaries and fallback_accounts, the first
account that declares the project’s model, preferring ready over
saturated and keeping bailed last (saturated then leads to a
cooling filter). Utilization is never compared between accounts; it
collapses to one boolean per account. Every spawn in an org takes
the same walk, so there is no per-session spread.
Re-exports§
use std::collections::BTreeMap;🔒use std::collections::HashMap;🔒use std::fs;🔒use std::path::Path;🔒use std::path::PathBuf;🔒use std::time::Duration;🔒use forge_primitives::GotifyConfig;🔒use forge_primitives::account::Provider;🔒use forge_primitives::browser::ProfileKey;🔒use forge_primitives::permission::PermissionMode;🔒use forge_primitives::slack::SlackConfig;🔒use forge_primitives::ClientConfig;🔒use forge_primitives::ServerConfig;🔒use serde::Deserialize;🔒use serde::Deserialize;🔒use crate::error::WorkspaceError;🔒
Structs§
- Account
Entry 🔒 - Unknown fields are rejected so a near-miss key (
providers) fails loudly instead of loading and leaving the account probing the wrong endpoint until preflight hangs on it. - Browser
Settings - The
[browser]table: how the server’s browser hosts encode, and when an idle profile closes. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Config
Reload - What one
forge.tomlreload changed, in the terms the boot’s log line reads: the tables whose new values are live from their next use, and the keys whose values are stored but need a restart. - Documents
Settings 🔒 - One
[documents]table. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Forge
Toml 🔒 - The whole
forge.toml. Unknown keys are rejected so a mistyped section name fails the load instead of being ignored. - Gateway
Settings 🔒 - One
[gateway]table. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Handoff
Policy - The trigger a session reads, with the project’s table over the top-level one and the defaults under both.
- Handoff
Settings - The
[handoff]table, top-level or per project. Every key is optional so a project’s table can set the one it disagrees on and inherit the rest. - Huggingface
Settings [huggingface]: the token a gated Hub repository needs. The speaking model’s own repository is open, so an absent token changes nothing.- Loaded
Account 🔒 - One account as the config load produces it. The gateway’s account state is built from these, and the spawn path stamps the per-account env onto the child from here.
- Loaded
Config 🔒 - Loaded
Project 🔒 - Model
Settings - The
[models."<name>"]table: the parameters a model name carries to every spawn, keyed by the canonical name forge.toml already pins projects to. Model-shaped values live here rather than in code, so changing a model is a config edit. Unknown fields are rejected so a mistyped key cannot silently leave a parameter unset. - OrgEntry 🔒
- One
[[orgs]]entry. Unknown keys are rejected: a misspelledfallback_accountsparses clean as “no fallbacks” otherwise, which is a silent behaviour change from a typo. - Plugin
Settings - The
[plugins]section. Unknown fields are rejected so a mistyped key cannot silently leave auto-update doing nothing. - Project
Entry 🔒 - Sessions
Config - The validated
[sessions]table: whether a dead durable seat comes back, how many restarts it gets, the wait before each, and how long a restarted seat must stay up before its count resets. - Sessions
Section 🔒 - One
[sessions]table. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Slack
Binding 🔒 [orgs.slack]or[orgs.projects.slack]: the one[[slack]]label a scope’s sessions act in.- Terminal
Settings - The
[terminal]table: the shell a seat’s terminal runs, how much scrollback the model keeps, and when an idle terminal closes. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Usage
Settings 🔒 - One
[usage]table. Unknown fields are rejected so a mistyped key fails the load instead of being ignored. - Vault
Config 🔒 - The validated
[vault]section. - Vault
Section 🔒 - Optional
[vault]section: the Vaultwarden account the vault family talks to. Bothurlandemailare required when the section is present; there is no built-in default, becauseforge.tomlis the one source of truth for the account.
Constants§
- DEFAULT_
DOCUMENT_ MAX_ MIB - The ceiling a handed document has to fit under when the
[documents] max_size_mibkey is absent, in MiB. - DEFAULT_
GATEWAY_ PORT - The port the gateway’s listener binds when
[gateway] portis absent. Fixed, not OS-assigned: every session’s base URL names it, so a drift would point children at an address nothing serves. - DEFAULT_
HANDOFF_ AFTER_ COMPACTIONS - The compaction count the backstop hands off at when the key is absent. One is the first compaction: the fill trigger should have fired before it, and a session that reaches two is the alarm the record exists for.
- DEFAULT_
HANDOFF_ AT_ PERCENT - The share of the window a session hands off at when the key is absent.
- DEFAULT_
HEAL - Whether a dead durable seat comes back when
[sessions] healis absent. - DEFAULT_
HEAL_ ATTEMPTS - The restart count when
[sessions] heal_attemptsis absent: three restarts, which caps what a deterministic fault can burn. - DEFAULT_
HEAL_ BACKOFF_ SECONDS - The waits before each restart when
[sessions] heal_backoffis absent, in seconds: 5 s, 30 s, then 2 min. - DEFAULT_
HEAL_ STABLE_ SECONDS - How long a restarted seat must stay up before its death count resets
when
[sessions] heal_stableis absent, in seconds. - DEFAULT_
MAX_ 🔒WORKERS_ PER_ PROJECT - Cap on a project’s concurrently live dynamic workers when its
max_workersoverride is absent. - DEFAULT_
USAGE_ POLL_ SECONDS - The interval the background usage poller refreshes on when the
[usage] poll_secondskey is absent, in seconds. 60 s stays clear of the OAuth usage endpoint’s 429 throttle under multi-instance polling while bounding how stale the account-usage cache can be. - DOCUMENT_
MAX_ MIB_ LIMIT - The highest
[documents] max_size_mibforge accepts, in MiB. A document crosses the socket base64-encoded, a third larger, and the desktop client’s frame cap is 256 MiB (client/src-tauri’sMAX_FRAME_BYTES): 190 MiB raw lands at ~253.3 MiB, inside the cap with room for the answer’s other fields.
Functions§
- applied_
env_ 🔒keys - Sorted key NAMES a project contributes - never values; these tables hold tokens.
- default_
terminal_ 🔒shell - The shell a terminal runs when
[terminal] shellnames none: the person’s own$SHELL, or the platform’s login shell. - ensure_
forge_ 🔒data_ dir forge_data_dirwith acreate_dir_all, returning the path.- expand_
home 🔒 - fingerprint_
of 🔒 - A stable 64-bit fingerprint of the file’s raw text, in hex. The settings page carries the fingerprint it loaded and a save is refused when the file has moved since.
- forge_
data_ 🔒dir - The subdirectory holding every file forge itself owns (config,
state, cron, lock), kept apart from claude’s own top-level
config-dir files. Pure path join; call
ensure_forge_data_dirwhen the directory has to exist before writing into it. - format_
session_ 🔒duration - The file’s spelling of a resolved
[sessions]duration, for the settings page: the largest unit that divides it exactly. - is_
bare_ 🔒key_ char - A TOML bare-key character (
a-z A-Z 0-9 _ - .). - load_
from_ 🔒dir - Load + validate
forge.toml. Returns the parsed orgs + projects with~expanded. - load_
from_ 🔒text - Load + validate raw
forge.tomltext, with the path its errors name. The settings save validates a candidate through here before it replaces the file, so the file a save writes is one a boot would accept. - parse_
position 🔒 - Where a parse failure sits in the document, from the byte span the error
carries:
at line N, column M in <key>, or empty when it names no span - no position rather than a confident line 1. - parse_
session_ 🔒duration - A
[sessions]duration as the file writes it: digits and one unit,ms,s,morh. A bare number is refused rather than guessed. - read_
config 🔒 - Read
forge/forge.toml. Returns the path read plus its raw contents. - read_
env_ 🔒file - Parse
KEY=valuelines, skipping blanks and#comments. Every way this can go wrong warns and yields the keys it did read - a project’s env file is not worth refusing to boot over, and a partial read is visible in the per-spawn applied record’s key list. - resolve_
client 🔒 - The
[client]section: an unset name is not an error and not a fallback, it means the built-in. A set one has to be a name forge ships, because a key that is quietly ignored reads as the key not working. - resolve_
project_ 🔒env - resolve_
server 🔒 - The
[server]section, refusing the two ports that cannot work: 0, which is OS-assigned and so unguessable, and the gateway’s own port, where the listener that binds second loses at boot. - scrub_
quoted 🔒 - The error’s own words with any double-quoted run scrubbed: serde renders
a mismatched value as
invalid type: string "…", and a value in this file can be a token (#2267). A key is backtick-quoted and stays legible. - seat_
env 🔒 - A seat’s children’s environment: the server’s own first, then the account and project tables over it.
- session_
env 🔒 - Complete
[env]<[accounts.env]< the project’s env, narrowest winning per key, over the already-mergedaccount_env. Applied here rather than at load because one account serves many projects, so merging earlier would leak a project’s keys into every other project on that account. - slack_
binding_ 🔒label - The label a scope’s
slackbinding resolves to, or a load error naming the label asked for and the ones that exist: a binding to a workspace forge does not have would leave every Slack tool dead at runtime. - trim_
setup_ 🔒token - A project’s env: the
env_fileentries with the inlineenvtable layered over them, since the inline form is the more explicit statement of the two. Trim the setup token a project’s env declares: the spawned child reads that map verbatim, so a padded value would fail to authenticate. The account layers never reach here with one - the load drops the gateway keys before they merge. - validate_
handoff_ 🔒settings - Refuse a trigger that can never fire or fires on every turn.
scopenames the table the value came from, so the error says which one to edit.