diff --git a/README.md b/README.md index 0b6bc0e..720df7d 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,10 @@ cfg status `cfg doctor` is read-only. Run it before the first import for a new database or `.cfg.toml`; it reports secret-deny matches, large fields, and live-rule/key issues in one pass, with paste-ready `secret_fields` and `ignore_fields` -suggestions. +suggestions. `cfg doctor --status` prints a "where am I" header: the resolved config +file, env, target database, identity mode and whether it is verified, store reachability, +and how many records are tracked or drifted — plus a warning if a `needs_approval` +environment is still in `open` identity mode (writes would succeed unaudited). Check drift: @@ -212,10 +215,24 @@ cfg status cfg diff agent_configs:agent_planner =HEAD =live ``` -Commit a full JSON document: +Edit a few fields in place (the fast path — no temp file). `cfg set` fetches the live +document and commits the change through the same drift-guarded path as `cfg commit`, so +it refuses on out-of-band drift rather than clobbering it: + +```bash +cfg set modelgarden_models:openai/gpt-4o-mini enabled=true retry.max=3 -m "enable + retry" +``` + +Values are JSON-coerced (`enabled=true` → bool, `n=5` → int, `tags=["a","b"]` → list); +prefix with `str:` to force a string (`version=str:1.0`). Use `cfg edit ` to hand-edit +the whole document in `$EDITOR`. + +Commit a full JSON document (add `--dry-run` to preview the field-level delta and exit +without writing): ```bash cfg commit agent_configs:agent_planner --from planner.json -m "tune planner routing" +cfg commit agent_configs:agent_planner --from planner.json --dry-run ``` Commit multiple records as one batch intent: @@ -305,12 +322,16 @@ Common commands: ```bash cfg init cfg doctor [record] +cfg doctor --status cfg import --all -m "initial import" cfg status [record] cfg diff [from] [to] cfg impact [from] [to] cfg commit --from -m "message" +cfg commit --from --dry-run cfg commit --bulk-from -m "message" +cfg set field=value nested.field=value -m "message" +cfg edit -m "message" cfg branch list cfg branch create --from main cfg branch delete @@ -337,7 +358,17 @@ cfg whoami cfg ui ``` -Every command supports `--json` for scripts and agents. +Every command supports `--json` for scripts and agents. By default output is human-readable +when stdout is a terminal and JSON when piped or redirected; set `CFG_OUTPUT=json|human|auto` +to control this, and `--json` always forces JSON. + +Every refusal and terminal outcome also carries a `next` block — a plain-language reason plus +the exact next command(s) to run. On the CLI it prints to stderr; over `--json`/MCP it is a +structured `next` field so agents can act on `next.commands` directly. + +Environment defaults: `CFG_ENV` (default env), `CFG_CONFIG` (config file path), and +`CFG_AUTHOR` (author) let you set a session once instead of repeating flags. cfgit also +discovers `.cfg.toml` by walking up from the current directory. Refs: @@ -413,10 +444,17 @@ The MCP server exposes the same operations with a uniform envelope: "status": "ok", "code": 0, "message": "", - "data": {} + "data": {}, + "state": null, + "next": null } ``` +`state` echoes the outcome's terminal state (for example `changed_outside_cfgit`), and `next` +carries a self-teaching remedy — `{why, remedy, commands, docs}` — when the outcome needs one +(a refusal, drift, a blocked batch, an identity/permission failure). Agents should branch on +`state` and follow `next.commands`; both are `null` on a clean success. + Tools include: - `cfg_status` @@ -425,6 +463,7 @@ Tools include: - `cfg_impact` - `cfg_commit` - `cfg_bulk_commit` +- `cfg_set` - `cfg_branch_list` - `cfg_branch_create` - `cfg_branch_delete` diff --git a/docs/USAGE.md b/docs/USAGE.md index 50e32f5..08cb497 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -125,6 +125,48 @@ secret-shaped fields and values from `[secrets]`. Fields in `secret_fields` are stripped before history. Use `--allow-secret` only for intentional fixtures or false positives; cfgit records that override in history metadata. +## Preview a commit + +Add `--dry-run` to a single-record commit to see the exact field-level delta versus the live +record and exit without writing. It returns `would_commit` with the changes, or the same +`changed_outside_cfgit` / `noop` a real commit would, and still runs the secret policy so a +blocked secret surfaces before you write: + +```bash +cfg commit agent_configs:agent_planner --from planner.json --dry-run +``` + +## Fast field edits (set / edit) + +For a few scalar fields you do not need a full document or a temp file. `cfg set` fetches the +live document, applies your changes, and commits through the same path as `cfg commit` — so it +still refuses on out-of-band drift instead of clobbering it (it is not a raw write): + +```bash +cfg set modelgarden_models:openai/gpt-4o-mini enabled=true retry.max=3 -m "enable + retry" +``` + +Paths are dotted, with list indices as `tags[0]`. Values are JSON-coerced — `enabled=true` +becomes a boolean, `n=5` an integer, `tags=["a","b"]` a list — and a `str:` prefix forces a +string (`version=str:1.0`). Add `--dry-run` to preview. To hand-edit the whole document in your +`$EDITOR` instead, use `cfg edit -m "message"`. + +## Situational awareness + +`cfg doctor --status` prints a one-look header of where you are pointed: resolved config file, +env, target database, identity mode and whether it is verified, store reachability, and the +number of tracked and drifted records. If a `needs_approval` environment is still in `open` +identity mode — so writes would succeed unaudited — it prints a warning with the fix. That same +warning also prints on any mutating command against such an environment; suppress it in scripts +with `CFG_WARN_OPEN_MODE=0`. + +## Guidance on every outcome + +Every refusal and terminal outcome carries a `next` block: a plain-language reason plus the +exact next command(s) to run (for drift, that is `cfg diff` then `cfg adopt`). On the CLI it +prints to stderr; over `--json` and MCP it is a structured `next` field, so agents can follow +`next.commands` without guessing. + ## Branches and PRs Branching is opt-in: @@ -274,14 +316,32 @@ shows recent activity across all configured records: current live drift plus the latest cfgit history entries. Selecting one of those entries opens that record's normal history and diff view. -## JSON mode +## Output mode + +By default output is human-readable when stdout is a terminal and JSON when piped or +redirected, so interactive use reads well while pipelines stay parseable. Control it with +`CFG_OUTPUT`: + +```bash +cfg status # human on a TTY, JSON when piped +cfg --json status # always JSON +CFG_OUTPUT=json cfg status # always JSON +CFG_OUTPUT=human cfg status # always human +``` + +`--json` and `CFG_OUTPUT=json` always force JSON. Agents and scripts should branch on `status` +and `state`, not on human-readable text. + +## Session defaults -Every command supports JSON output: +To avoid repeating flags, set environment defaults once: ```bash -cfg --json status -cfg --json diff agent_configs:agent_planner +export CFG_ENV=prod # default for --env +export CFG_CONFIG=./cfgit/aistudio.cfg.toml # default for --config-file +export CFG_AUTHOR=you@example.com # default author (open identity mode) ``` -Agents and scripts should branch on `status` or the command output state, not on -human-readable text. +cfgit also discovers `.cfg.toml` by walking up from the current directory, so you can run it +from a subdirectory without `--config-file`. Global flags (`--config-file`, `--env`, `--author`, +`--branch`, `--json`) go before the subcommand: `cfg --env prod status`.