Skip to content

Configuration

Every setting in the files you can edit by hand. They live in ~/.config/candle/harness/, or in the folder CANDLE_HARNESS_HOME names: config.toml, layouts.toml, wallets.toml, triggers.toml and bots.toml side by side, and your themes in themes/.

A setting that says it’s where a fresh install starts is only a starting point: once you pick something in the Candle Harness, your pick is kept across restarts.

Your agents, their limits, and how the Candle Harness runs. An agent’s settings are in its own table, [agents.<name>], named for the agent. Setup writes this file, and a problem in it is refused with its line, saying why; a setting the Candle Harness doesn’t know is only warned of.

Takes: "paper" or "live" · Default: "paper"

The mode a fresh install starts in. Once you switch, the mode you last picked is kept across restarts.

mode = "live"

Takes: an agent’s name · Default: the first agent listed

The agent a line without as <agent> runs as when the Candle Harness starts. agent <name> changes it while the Candle Harness runs.

activeAgent = "agent-b"
[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-b.limits]
perTradeUsd = 10
perDayUsd = 50

Takes: a dollar amount above 0 · Default: none: every agent sets one

The most one of this agent’s trades may be worth. The core checks it before a card is made, and refuses a trade over it.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100

Takes: a dollar amount above 0 · Default: none: every agent sets one

The most this agent may trade in a day, all its trades together. Set below perTradeUsd, it binds first, and the Candle Harness warns of it.

[agents.agent-a.limits]
perDayUsd = 100
perTradeUsd = 25

Takes: "embedded", or a wallet’s name or address · Default: the embedded wallet, when the agent’s key may pay from it; else its only TEE wallet

The wallet this agent pays from when a trade names none. from <wallet> on a trade overrides it, and every card names the wallet that pays.

[agents.agent-a]
wallet = "embedded"
[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100

Takes: "quant", "trader" or "bare" · Default: "quant"

The preset this agent starts on: Quant, an analyst with Hacc’s data and Candle’s skills; Trader, a plain trading agent; or Bare, the essentials only. The preset you last picked with ctrl-g is kept.

[agents.agent-a]
preset = "trader"
[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100

Takes: "off", "everything", or a list of commands · Default: "off"

Shell access for this agent. A list runs only a plain command whose words start with an entry’s, with nothing joined, piped or substituted. With the shell on, the agent’s reads aren’t held to its research folder, and cards and limits don’t cover what the shell runs. Engines differ here: Codex runs everything or nothing.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.tools]
shell = ["ls", "cat"]

Takes: "off", or a list of programs · Default: "off"

The code runner for this agent: the programs it may run in its research folder with research_run, each by its name or full path. Each run is held to the folder by the system, with no network, for at most 60 seconds, and its output comes back to the agent. Offered only where the system can hold it (macOS, or Linux 6.12 or later); the model picker and the palette turn it on for the active agent.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.tools]
run = ["python3", "bun", "node"]

Takes: a list of tool names, * matching any characters · Default: every tool

Only these tools are offered to the agent; every other is hidden from it. An empty list offers none.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.tools]
allow = ["candle_*", "research_*"]

Takes: a list of tool names, * matching any characters · Default: []

These tools are hidden from the agent entirely, even where allow names them.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.tools]
deny = ["candle_launch_token"]

Takes: a whole number from 0 to 1000 · Default: 4

How many turns triggers may wake this agent for in an hour. A wake past it is skipped and said; wakes that come while the agent is busy join one turn, which counts once. 0 means triggers never wake it.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.wake]
perHour = 2

Takes: a whole number from 0 to 1000 · Default: 24

How many turns triggers may wake this agent for in 24 hours. A wake past it is skipped and said.

[agents.agent-a.limits]
perTradeUsd = 25
perDayUsd = 100
[agents.agent-a.wake]
perDay = 10

Takes: "card" or "instant" · Default: "card"

Whether a live trade you type is a card you approve, or runs at once. “instant” covers every one-press card you type, not only trades: a stake, closing empty accounts, an image upload or a token page edit (both public) run at once too. On a wallet set to trade inside limits, a typed trade inside its figures runs at once either way.

[cards]
typedTrades = "instant"

Takes: "auto" or "market" · Default: "auto"

How a card is valued when it’s proposed: auto uses Candle’s quote for the exact trade as soon as Candle offers one, and a fresh market read until then; market keeps to market reads.

[pricing]
source = "market"

Takes: a tool’s name · Default: "candle_quote"

The name of Candle’s quote tool, which auto pricing looks for.

[pricing]
quoteTool = "candle_quote"

Takes: "sol", "usdc" or "cndl" · Default: "sol"

What a buy sized in dollars (buy $25 MOON) spends on Solana, for a token Candle didn’t launch.

[trade]
spendAsset = "usdc"

Takes: "claude-code", "codex", "grok", "opencode" or "pi" · Default: "claude-code"

The engine a new agent starts on. The engine you pick for each agent with ctrl-g is kept.

[engine]
default = "codex"

Takes: a model’s name, as its engine lists it · Default: the engine’s own default

The model a new agent starts on. The model you pick for each agent with ctrl-g is kept.

[engine]
model = "gpt-5.5"

Takes: a path, or a name on your PATH · Default: "claude"

Where Claude Code is installed. The Candle Harness runs your own install, signed in as you.

[engine.claude]
path = "/usr/local/bin/claude"

Takes: a path, or a name on your PATH · Default: "codex"

Where Codex is installed. The Candle Harness runs your own install, signed in as you.

[engine.codex]
path = "/usr/local/bin/codex"

Takes: a path, or a name on your PATH · Default: "grok"

Where Grok is installed. The Candle Harness runs your own install, signed in as you.

[engine.grok]
path = "/usr/local/bin/grok"

Takes: a path, or a name on your PATH · Default: "opencode"

Where OpenCode is installed. The Candle Harness runs your own install, signed in as you.

[engine.opencode]
path = "/usr/local/bin/opencode"

Takes: a path, or a name on your PATH · Default: "pi"

Where Pi is installed. The Candle Harness runs your own install, signed in as you.

[engine.pi]
path = "/usr/local/bin/pi"

Takes: a whole number above 0 · Default: 30

The most steps one of the agent’s turns may take before it stops.

[engine]
stepCap = 20

Takes: a path, or a name on your PATH · Default: "candle"

Where Candle’s CLI is installed. The Candle Harness runs your own candle for the commands that need it.

[candle]
cliPath = "/usr/local/bin/candle"

Takes: a CLI profile’s name · Default: unset: the CLI picks its profile as it always does

The Candle CLI profile the Candle Harness acts as. Setup records the one you signed in with, so switching the CLI’s active profile elsewhere never moves the Candle Harness to another account.

[candle]
profile = "candle-harness"

Takes: an https address (plain http only for 127.0.0.1 or localhost) · Default: unset: the CLI profile’s own

The Solana RPC the Candle Harness gives Candle’s CLI, for the commands that use one, such as a TEE wallet’s trades.

[candle]
rpcUrl = "https://rpc.example.com"

Takes: "cli" or "package" · Default: "cli"

How Candle’s MCP server runs for each agent’s key: cli runs candle mcp from candle.cliPath; package runs the candle-mcp package at candle.mcp.path.

[candle.mcp]
route = "cli"

Takes: a path, or a name on your PATH · Default: "candle-mcp"

Where the candle-mcp package is, when candle.mcp.route is package.

[candle.mcp]
path = "candle-mcp"

Takes: "active", "all", "group:<name>", or a list of up to 20 wallets · Default: "active"

Which wallets the panes show on a fresh install: the ones a Candle Harness agent can pay from, every one, one of your groups, or the wallets you list by name, address or embedded. A wallet the Candle Harness stopped always shows until it’s swept. The choice you last made in the Wallets pane is kept.

[wallets]
show = "all"

Takes: true or false · Default: true

Hacc, Candle’s market data engine. Off hides every Hacc tool from the agent and closes the signal stream.

[hacc]
enabled = false

Takes: "24h", "midnight", "session", or a time of day such as "18:00" · Default: "24h"

The P&L window a fresh install starts on: the last 24 hours, since midnight, since the Candle Harness was last closed, or since a time of day. The window you last picked is kept.

[pnl]
window = "midnight"

Takes: a list of folders, each from / or ~/ · Default: []

Skill folders of your own, such as Claude Code’s ~/.claude/skills, for the core to read and serve to the agent, which can’t read them itself. Where a fresh install starts: the choice you last made in settings ▾ → skills is kept.

[skills]
from = ["~/.claude/skills"]

Takes: a folder, from / or ~/ · Default: "~/candle-bots"

The Build tab’s bots folder, where your coding harness writes bots: each bot in a folder of its own, beside the rules every bot runs under, the client, and Candle’s bot-building skills. Where a fresh install starts: the folder you last picked in the Build pane is kept.

[build]
folder = "~/code/candle-bots"

Takes: "claude-code", "codex", "grok", "opencode", "pi", or a command such as "aider --no-git" · Default: unset: the Build pane asks

The coding harness the Build tab opens, unmodified and signed in as you: one of the five, by the binary its engine setting names, or a command of your own. Where a fresh install starts: the harness you last picked in the Build pane is kept.

[build]
harness = "claude-code"

Takes: true or false · Default: false

macOS only: keep the Mac from sleeping while a trigger or bot is on, so a level, a schedule or a bot’s exit isn’t missed while it sleeps. A closed lid still sleeps a Mac on battery. Where a fresh install starts: the choice you last made in the palette is kept.

[core]
keepAwake = true

Takes: "auto", "native", "osc", "bell" or "off" · Default: "auto"

How a notification reaches you. Only while the Candle Harness’s window isn’t in front: auto is your computer’s own notification here and the terminal’s notification over SSH, and the bell where neither works. native is always the computer’s, osc the terminal’s, bell the bell alone, and off nothing. With no Candle Harness window open, the core sends the computer’s own, on a Mac or a Linux desktop; over SSH or on a VPS with no window open, nothing reaches you. Read when the core starts.

[notify]
mode = "bell"

Takes: a list from "cards", "triggers", "bots", "wakes", "kill", "keys" and "core" · Default: ["cards", "triggers", "bots", "wakes", "kill", "keys", "core"]

What notifies you: a card waiting that you didn’t make (cards), a trigger firing (triggers), a rules bot’s every buy and sell, a bot’s trade that waits for you, was refused or failed, and a bot’s sell held (bots, a bot’s trades that come together as one notice), a wake skipped at its agent’s cap (wakes), the kill switch going on (kill), Candle holding a key (keys), and the core stopping when nobody asked it to (core). Leave one out to stop it. Read when the core starts.

[notify]
on = ["cards", "triggers"]

Takes: the words it stands for · Default: none

A word that stands for the start of a typed line: b5 = "buy $5 of" makes b5 MOON buy $5 of MOON. An alias can’t take a command’s own name, such as buy, can’t loop, and can’t make more than 5 parts.

[aliases]
b5 = "buy $5 of"

Takes: a theme’s name · Default: "Candle dark"

The theme a fresh install starts on: Candle dark, Candle light, Terminal, or one of yours by its file’s name. The theme you last picked in the palette is kept, until you change this by hand.

[theme]
name = "Candle light"

Your tabs and your own layouts. The layout menu writes it when you save a layout or tick a tab on or off, and a hand edit is read when the file changes. A problem is named with its line and left out, and a file with a problem is never written over, so a hand edit is never lost.

Takes: 1 to 20 characters · Default: the nine tabs: Trade, Cockpit, Trending, Signals, P&L, Research, Journal, Perps and Bots

A tab’s name, as the tab bar shows it. Each name is used once.

tabs = [{ name = "Desk", layout = "Cockpit" }]

Takes: a layout’s name: a preset’s, or one of yours · Default: each tab’s own preset

The layout the tab shows. A name that isn’t a layout shows Agent-first, and the Candle Harness says which line.

tabs = [{ name = "Desk", layout = "Agent-first" }]

Takes: true or false · Default: true

Whether the tab is on the tab bar. A tab ticked off in settings ▾ stays in the file with shown = false, keeping its place and layout. One tab is always shown.

tabs = [{ name = "Trade", layout = "Agent-first" }, { name = "Perps", layout = "Perps", shown = false }]

Takes: a row or column of panes · Default: none: every layout of yours has one

The layout’s panes: ["row", …] or ["column", …], then its children. A child is a pane and its weight ("token 50"), a pane with fixed rows inside a column ("agent 8 rows"), or another row or column with its weight after it (["column", 60, …]). The panes: agent, token, token:2, token:3, positions, wallets, activity, feed, signals, new, graduated, final-stretch, pnl, pnl-chart, pnl-positions, trades, journal, check, traders, token-signals, mentions, perps, lists, away, triggers, bots, bot, build, build-folder, build-test; token:2 and token:3 are more token panes, each pinned on a token of its own while token follows the link.

[layouts."My desk"]
root = ["row", ["column", 60, "token 50", "activity 50"], "agent 40"]

Takes: a whole number of columns, from 60 · Default: the width its panes need

The terminal width below which the layout collapses to the agent and one switched pane. It can’t be below the width the panes need.

[layouts."My desk"]
collapse = 140
root = ["row", ["column", 60, "token 50", "activity 50"], "agent 40"]

Takes: a preset’s name · Default: none

The preset the layout was saved from. The Candle Harness writes it, with from_panes, so it can offer you a pane that preset has gained since.

[layouts."My desk"]
from = "Agent-first"
from_panes = ["agent", "token", "activity"]
root = ["row", ["column", 60, "token 50", "activity 50"], "agent 40"]

Takes: a list of panes · Default: none

The panes the preset in from had when the layout was saved.

[layouts."My desk"]
from = "Agent-first"
from_panes = ["agent", "token", "activity"]
root = ["row", ["column", 60, "token 50", "activity 50"], "agent 40"]

The Candle Harness’s own names for wallets, and your wallet groups. The Candle Harness writes it whole when you name a wallet or change a group, so a comment of yours below its header won’t survive that. A problem is named with its line and left out, and a file with a problem is never written over.

Takes: up to 64 characters · Default: none

The Candle Harness’s own name for a wallet that neither Candle nor the vault labels, such as the embedded wallet. A name is unique, has no space at either end, and can’t be embedded, an agent’s name, or shaped like an address. The Candle Harness writes this when you name a wallet.

[names]
"Fk3eQ9mW2vT8rYp5LxN7cZ1bH4jS6dGuAa8KqRwEs2Vn" = "main"

Takes: the start of a wallet’s name · Default: none

Every wallet whose name starts with this, in any case, is in the group, as Candle’s bot-* selects.

[groups.bots]
prefix = "bot-"

Takes: a list of wallets, by name or address · Default: none

These wallets are in the group, kept by address so a rename never drops one. A group organises wallets; it never pays.

[groups.desk]
wallets = ["main", "embedded"]

Your triggers: when something happens, what to do. The Candle Harness writes it whole when you approve a trigger’s card, or switch or remove one. Set on = false to switch one off by hand; any other change holds that trigger until its card is approved again, so nothing adds or widens a trigger but your press. A problem is named with its line and left out, and a file with a problem is never written over.

Takes: an agent’s name · Default: the agent that proposed it

The agent the trigger belongs to: its trades use this agent’s key, limits and default wallet.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false

Takes: a trigger’s line · Default: none

The trigger as it was written and approved, with token names and aliases as typed: when MOON < $0.40 sell 50% of MOON.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false

Takes: a trigger’s line · Default: none

The same line with aliases expanded and token names as mints: what it does when it fires, whatever an alias or a name means later.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false

Takes: true or false · Default: true

Whether it’s switched on. Set it to false to switch it off; it’s switched back on in the Triggers overlay, as it was approved.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false

Takes: true or false · Default: false

For a level: whether it re-arms each time it’s crossed back, rather than firing once and switching off.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false

Takes: a duration, such as "30m", "2h" or "1d" · Default: "30m"

The least time between two firings: of the same token, for a tape trigger or one on your personal signals.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = true
cooldown = "2h"

Takes: "paper" or "live" · Default: the mode it was approved in

Whether the trigger’s trades are paper or live, whatever mode the Candle Harness is in when it fires. It’s set when its card is approved; taking one live is a new card.

[triggers."MOON < $0.40"]
agent = "agent-a"
line = "when MOON < $0.40 sell 50% of MOON"
expansion = "when MoonFake11111111111111111111111111111111111 < $0.40 sell 50% of MoonFake11111111111111111111111111111111111"
on = true
again = false
mode = "live"

Your rules bots: a Hacc strategy definition each, run by the Candle Harness, with the agent, wallet and mode it runs as. The Candle Harness writes it whole when you approve a bot’s card, or narrow, pause, stop, resume or remove one. Set state = "paused" or "stopped" to pause or stop one by hand; any other change holds its entries until its card is approved again, while its exits still sell as it was approved. A problem is named with its line and left out, and a file with a problem is never written over.

Takes: an agent’s name · Default: the agent that proposed it

The agent the bot belongs to: its trades use this agent’s key and limits.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: "embedded", or a wallet’s address · Default: none

The wallet the bot pays from and sells from. A wallet of its own keeps its book exact and its risk to what that wallet holds.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: "paper" or "live" · Default: none

Whether the bot trades on paper or live, whatever mode the Candle Harness is in. Taking a bot live is a new card.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: "on", "paused" or "stopped" · Default: "on"

Paused takes no new entries while its exits still sell; stopped trades nothing, and leaves its positions to you. Setting either here is always taken; a bot goes back on from the Bots tab, as it was approved.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: a whole number of basis points, from 10 to 10000 · Default: the route’s default

The bot’s own slippage bound, approved on its card: shown in amber where it’s looser than the default, or under it, where its sells may not fill. A card takes none under 10.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
maxSlippageBps = 300
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: Hacc’s strategy definition, as tables · Default: none

What the bot enters on, how it exits and how much it stakes, in the field names of Hacc’s strategy lab, so the same definition backtests on Hacc.

[bots.confluence-small]
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
[bots.confluence-small.definition]
chain = "solana"
[bots.confluence-small.definition.entry]
source = "pattern"
pattern = "confluence"
[bots.confluence-small.definition.entry.filters]
max_mcap_usd = 500000
[bots.confluence-small.definition.exit]
take_profit_pct = 100
stop_loss_pct = 40
[bots.confluence-small.definition.sizing]
usd_per_trade = 2
max_concurrent = 4

Takes: "code" · Default: a rules bot

A program of yours, the Candle Harness runs and holds to its figures, where a rules bot has a definition. Its agent, wallet, mode, state and maxSlippageBps are as a rules bot’s.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

Takes: an absolute path · Default: none

A code bot’s folder: its command runs there. Your code is yours to change; the core holds it to its figures whatever it does.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

Takes: a list of words · Default: none

What runs a code bot, word by word, in its folder and with no shell. Changing it is a new card.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

Takes: a dollar figure · Default: none

The most one of a code bot’s buys or swaps may spend. Raising it is a new card; lowering it is at once.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

Takes: a dollar figure, at least perTradeUsd · Default: none

The most a code bot’s buys and swaps may spend in a day. Raising it is a new card; lowering it is at once.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

Takes: a whole number, from 1 to 100 · Default: none

The most positions a code bot may hold open at once. Raising it is a new card; lowering it is at once.

[bots.momentum]
kind = "code"
agent = "agent-a"
wallet = "embedded"
mode = "paper"
state = "on"
folder = "/home/you/candle-bots/momentum"
command = ["bun", "run", "bot.ts"]
perTradeUsd = 2
perDayUsd = 10
maxOpen = 3

A theme of yours is a file in themes/ beside config.toml, named for the theme: themes/Night desk.toml is the theme Night desk. It names only the colours it changes, and the rest come from its base. Each theme is checked when it loads: one that would make text unreadable, or two meanings alike, isn’t used, and says why. A colour or key that isn’t right is named with its line and left out.

Takes: "Candle dark" or "Candle light" · Default: "Candle dark"

The theme yours starts from. Every colour you don’t set is its.

base = "Candle light"

Each takes "#rrggbb", and one you don’t set is the base theme’s. The agent’s reply has colours of its own, under [reply].

KeyWhat it colours
pageBehind everything, around the panes.
barThe status bar, the tab bar and the input line.
paneInside a pane.
borderA pane’s border.
selectedBehind the highlighted row, card or tab.
focusThe focused pane’s border, and an overlay’s. Borders only, never text.
brightThe text you act on.
textContent.
dimLabels, times and sources.
headingPane headings.
attentionLook at this: a waiting card, a near limit, a flag.
goodFilled, and up.
badRefused, down, and the kill switch.
controlAnything you can click, drawn as a chip.
control_bgBehind a chip.
control_hoverBehind a chip under the mouse.
bad_bgBehind the kill switch’s chip, the one red chip.
paper_bgBehind PAPER in the status bar.
heading under [reply]A heading in the agent’s reply.
bright under [reply]Bold text and addresses in a reply.
dim under [reply]A table’s labels and rules, and a list’s bullets, in a reply.
code under [reply]Code in a reply.
quote under [reply]A quote in a reply, and its bar.
base = "Candle dark"
pane = "#101418"
attention = "#ffb000"
[reply]
code = "#9ecbff"