Documentation
¶
Index ¶
- Constants
- func AllowedOriginsPath() string
- func ClaudeEnvExports() string
- func ClaudeEnvPath() string
- func ClaudeOverlayPath() string
- func ConfigPath() string
- func Dir() string
- func MigrationPlan() migrate.Plan
- func SessionsPath() string
- func TmuxConfPath() string
- type AttentionThresholds
- type ClaudeEnvFile
- type Config
- type ServeConfig
Constants ¶
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.
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.
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).
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 MigrationPlan ¶
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 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
func (t AttentionThresholds) Resolved() AttentionThresholds
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 Load ¶
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 ¶
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.
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.