config

package
v0.1.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultLogMaxSizeMB  = 50
	DefaultLogMaxAgeDays = 30
	DefaultLogMaxFiles   = 10
)

Default values for log rotation knobs. Exposed as constants so callers can reference them in tests and docs without hardcoding.

View Source
const (
	DefaultServePort                     = 37778
	DefaultAttentionErrorRatePct         = 20
	DefaultAttentionErrorRateWindow      = 20
	DefaultAttentionIdleMinutes          = 5
	DefaultAttentionQuotaPct             = 85
	DefaultAttentionContextPct           = 90
	DefaultAttentionYoloUncheckedMinutes = 30
)

Defaults for `ctm serve` attention thresholds and port. Exposed so callers can reference them without re-hardcoding the numeric literal.

View Source
const DefaultHookTimeoutSec = 5

DefaultHookTimeoutSec mirrors internal/hooks.DefaultTimeout. Kept in sync manually so this package doesn't depend on internal/hooks (which would create a cycle via cmd).

View Source
const SchemaVersion = 1

SchemaVersion is the current on-disk schema version of config.json. Bump this and append a Step to the Plan returned by MigrationPlan() whenever the shape of Config changes in a non-additive way.

Variables

This section is empty.

Functions

func AllowedOriginsPath added in v0.1.2

func AllowedOriginsPath() string

AllowedOriginsPath returns the path to the extra-origins file. One origin per line; blank lines and `#`-prefixed lines are ignored. Read by the serve mutation allowlist so mobile / reverse-proxy hostnames persist across reloads without needing env vars.

func ClaudeEnvExports added in v0.1.20

func ClaudeEnvExports() string

ClaudeEnvExports is the one-call convenience: load the file at ClaudeEnvPath() and return its ShellExports. Errors are swallowed — returning empty string preserves the legacy env.sh behavior of "missing file is fine" while letting the caller stay one-liner clean.

Callers that want loud failure on a malformed file should call LoadClaudeEnv directly.

func ClaudeEnvPath added in v0.1.20

func ClaudeEnvPath() string

ClaudeEnvPath returns the path to the ctm-managed JSON env file. When this file exists, ctm reads it at every claude-launching command and exports its `env` block into the shell BEFORE exec'ing claude. Use this for env vars claude reads too early in startup for the overlay's `env` block to apply (e.g., CLAUDE_CODE_NO_FLICKER).

Replaces the older bash-script env.sh — JSON keeps the format consistent with the rest of ctm's user config (config.json, sessions.json, claude-overlay.json, .bestpractices.json).

func ClaudeOverlayPath

func ClaudeOverlayPath() string

ClaudeOverlayPath returns the path to the optional claude settings overlay. When this file exists, ctm passes --settings <path> to every claude invocation, layering it on top of the user's existing claude settings without modifying ~/.claude/settings.json.

func ConfigPath

func ConfigPath() string

ConfigPath returns the path to the main config file.

func Dir

func Dir() string

Dir returns the ctm config directory (~/.config/ctm/).

func MigrationPlan

func MigrationPlan() migrate.Plan

MigrationPlan returns the migrate.Plan for config.json. Steps is empty at v1 because the initial migration only stamps the version — no content changes are required to turn an unversioned config.json into v1.

Callers run the returned Plan before Load so the typed unmarshal sees a file already at the current SchemaVersion.

func SessionsPath

func SessionsPath() string

SessionsPath returns the path to the sessions file.

func TmuxConfPath

func TmuxConfPath() string

TmuxConfPath returns the path to the tmux config file.

Types

type AttentionThresholds added in v0.1.2

type AttentionThresholds struct {
	ErrorRatePct         int `json:"error_rate_pct"`
	ErrorRateWindow      int `json:"error_rate_window"`
	IdleMinutes          int `json:"idle_minutes"`
	QuotaPct             int `json:"quota_pct"`
	ContextPct           int `json:"context_pct"`
	YoloUncheckedMinutes int `json:"yolo_unchecked_minutes"`
}

AttentionThresholds controls when `ctm serve` flags a session as needing user attention. Zero fields resolve to defaults via Resolved().

func (AttentionThresholds) Resolved added in v0.1.2

Resolved returns a copy of t with any zero-valued field replaced by its built-in default. Mirrors LogPolicy()/HookTimeout(): old configs loaded without the attention block get sane thresholds without a schema bump.

type ClaudeEnvFile added in v0.1.20

type ClaudeEnvFile struct {
	Comment string            `json:"_comment,omitempty"`
	Env     map[string]string `json:"env"`
}

ClaudeEnvFile is the on-disk shape of ~/.config/ctm/claude-env.json.

ctm exports these vars into the shell that spawns claude. This is the canonical home for env vars claude reads too early in startup for the overlay's `env` block to apply (e.g., CLAUDE_CODE_NO_FLICKER). Most env vars belong in claude-overlay.json's `env` block instead.

The Comment field is JSON-convention `_comment` and is preserved on round-trip but otherwise unused.

func LoadClaudeEnv added in v0.1.20

func LoadClaudeEnv(path string) (ClaudeEnvFile, error)

LoadClaudeEnv reads claude-env.json from path. Returns the zero ClaudeEnvFile and a nil error when the file does not exist — a missing file is treated as "no extra env vars to export," same graceful degradation the previous env.sh sourcing had.

Returns a non-nil error on:

  • a present but malformed JSON file (loud failure: corrupt config should not silently drop env vars)
  • any env key that is not a portable shell variable name

On error the returned ClaudeEnvFile is the zero value.

func (ClaudeEnvFile) ShellExports added in v0.1.20

func (f ClaudeEnvFile) ShellExports() string

ShellExports returns a single-line `export KEY1='val1' KEY2='val2'` clause suitable for prepending to the claude launch command. Returns "" when there are no entries so callers can branch on emptiness without producing a stray "export " in the shell.

Keys are emitted alphabetically so the launch command is deterministic across runs (handy for diffing process trees and tests).

Values are wrapped in single quotes with embedded single quotes escaped as '\” — the standard POSIX-safe quoting that handles arbitrary characters including spaces, $, `, !, and the literal `{uuid}` placeholder consumed downstream by `ctm statusline`.

type Config

type Config struct {
	// SchemaVersion is stamped onto config.json by the migrate runner on
	// startup. Exposed so Load/write round-trip preserves it; callers
	// should not set it explicitly — Default() and write() handle it.
	SchemaVersion int `json:"schema_version"`

	RequiredEnv             []string `json:"required_env"`
	RequiredInPath          []string `json:"required_in_path"`
	ScrollbackLines         int      `json:"scrollback_lines"`
	HealthCheckTimeoutSec   int      `json:"health_check_timeout_seconds"`
	GitCheckpointBeforeYolo bool     `json:"git_checkpoint_before_yolo"`
	DefaultMode             string   `json:"default_mode"`

	// Log rotation knobs for ~/.config/ctm/logs/<session>.jsonl.
	// A zero value means "use the built-in default" (50 MiB / 30 d / 10
	// files). To effectively disable a cap, set it to a very large number
	// rather than 0. LogPolicy() resolves zeros to defaults.
	LogMaxSizeMB  int `json:"log_max_size_mb"`
	LogMaxAgeDays int `json:"log_max_age_days"`
	LogMaxFiles   int `json:"log_max_files"`

	// Hooks maps lifecycle event names (on_attach, on_new, on_yolo,
	// on_safe, on_kill) to shell commands run when the event fires.
	// Nil / empty means no hooks. Commands run with CTM_EVENT +
	// CTM_SESSION_{NAME,UUID,MODE,WORKDIR} in the env and are bounded
	// by HookTimeoutSec seconds. See internal/hooks for the full
	// contract.
	Hooks map[string]string `json:"hooks"`

	// HookTimeoutSec is the per-hook wall-clock ceiling. Zero → default
	// (5 s). Set a very large number to effectively disable the cap.
	HookTimeoutSec int `json:"hook_timeout_seconds"`

	// Serve holds configuration for `ctm serve` (the local UI daemon).
	// Missing from old configs is fine: strict decoding tolerates absent
	// keys, and zero-valued fields fall back to built-in defaults via
	// their accessor helpers.
	Serve ServeConfig `json:"serve"`
}

Config holds user preferences for ctm.

func Default

func Default() Config

Default returns a Config populated with sensible defaults.

func Load

func Load(path string) (Config, error)

Load reads Config from path. If the file does not exist it creates it with defaults and returns those defaults.

The decoder is strict: unknown top-level keys are rejected. On the first load that encounters an unknown key (typo, dropped experimental field, etc.), ctm copies the original bytes to a sibling ".bak.unknowns.<unix-nano>", strips the unknown keys, rewrites the file, and emits a WARN-level slog line naming each dropped key. See internal/jsonstrict for the full contract. This self-heals once, then strictness catches future typos immediately.

func (Config) HookTimeout

func (c Config) HookTimeout() time.Duration

HookTimeout returns the per-hook wall-clock ceiling. A zero HookTimeoutSec resolves to DefaultHookTimeoutSec so old configs (and users who never set it) still get a sensible default.

func (Config) LogPolicy

func (c Config) LogPolicy() logrotate.Policy

LogPolicy builds the logrotate.Policy from this Config, substituting the built-in defaults for any knob left at 0. Config files written before the log-rotation knobs existed load those fields as 0, so this is how old installs get sensible retention without a schema bump.

type ServeConfig added in v0.1.2

type ServeConfig struct {
	Port              int                 `json:"port"`
	BearerToken       string              `json:"bearer_token"`
	WebhookURL        string              `json:"webhook_url"`
	WebhookAuth       string              `json:"webhook_auth"`
	StatuslineDumpDir string              `json:"statusline_dump_dir"`
	Attention         AttentionThresholds `json:"attention"`
}

ServeConfig holds knobs for the `ctm serve` daemon. All fields are optional; zero values resolve to defaults via ServeConfig accessors.

func (ServeConfig) ResolvedPort added in v0.1.2

func (s ServeConfig) ResolvedPort() int

Port returns the listen port for `ctm serve`, substituting DefaultServePort when the configured value is non-positive so old configs that predate the serve block still bind the canonical port.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL