smoo config schema: first-class schema patch verbs (show/add/rm) - #490
Merged
Conversation
smoo config schema show/add/rm — patch the @smooai/config schema remote-first from the CLI instead of pull → hand-edit → push. add is an upsert (no separate edit-key); cross-tier adds are refused showing the existing declaration; rm warns that values are not deleted; --dry-run prints the would-be diff without POSTing. Reuses the existing /config/schemas list + push endpoints and the pull-style refuse-to-guess schema picker. A pulled JSON-Schema-shaped .smooai-config/schema.json in the cwd is updated alongside the remote so the two stay in sync. Ran the cargo gates manually (fmt --check, clippy no new errors, 108 config tests incl. 15 new schema tests); pre-commit skipped for the shared-target poisoning issue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KF6EFZ3mMGGF4m1543yWQP
🦋 Changeset detectedLatest commit: 6598c36 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
brentrager
enabled auto-merge (squash)
August 20, 2026 17:00
brentrager
added a commit
that referenced
this pull request
Aug 20, 2026
…remote (#493) The write direction (schema add/rm, config push) shipped in #490; this is the read direction. `smoo config schema pull` reconciles the LOCAL schema representation with the org's remote schema, correctly for both consumer kinds: a plain pulled schema.json is overwritten (config pull --force semantics), while a TypeScript consumer (config.ts present) is never rewritten wholesale — remote-only keys become ready-to-paste snippets in the file's own conventions (value-schema names and defineLimit clamp fields derived from how the build serializes them), and --write appends them into the right tier block mechanically, refusing all-or-nothing when a block can't be located unambiguously. Local-only keys are reported, never deleted; tier/type drift on shared keys is reported as tables. Claude-Session: https://claude.ai/code/session_01KF6EFZ3mMGGF4m1543yWQP Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Patching the @smooai/config schema from the CLI used to mean
pull→ hand-edit.smooai-config/schema.json→push. This adds a first-classschemasubgroup to the config command (smoo config schema …, also reachable asth smoo config schema/ hiddenth config schema):schema show [--schema-name] [--json]— render the remote schema: every declared key per tier with its type and any description/default/clamp metadata.schema add <key> --tier secret|public|feature_flag|limit [--type] [--description] [--default] [--min/--max]— upsert a key declaration (there is no separateedit-key; re-adding in the same tier patches the given fields onto the existing declaration).--typedefaults per tier (feature_flag→boolean, limit→number, else string);--min/--maxare the limit clamp bounds and are refused on any other tier.schema rm <key> [--tier]— remove a declaration.--tieracts as a guard: naming the wrong tier errors with the actual one.Design
Remote-first, one shot. Fetches the remote schema via the same
GET /organizations/{org}/config/schemaslist endpointpush/pullalready use, applies the patch in memory (pure functions, tested against fixture JSON matching a live pull of the real smooai schema), and POSTs a new version via the samePOST /config/schemas/{id}/pushendpoint. No local.smooai-config/schema.jsonrequired — but if a pulled (JSON-Schema-shaped) one exists in the cwd it is updated too, and aconfig.ts-generated manifest is left alone with a pointer atsmoo config build.Safety:
addis refused loudly, showing the existing declaration and theschema rmfix.rmalways prints "values set for this key are not deleted — useth config delete" (checking live values would cost a per-environment fan-out; the unconditional reminder is cheaper and always true).API_URL≡apiUrl) means an upsert patches the existing spelling instead of inserting a duplicate.resolve_pull_schemarule aspull);--schema-namedisambiguates.--dry-runprints the would-be change and stops before the POST.Verification
cargo fmt --checkclean; clippy adds no new errors; 108 config tests pass including 15 new ones (clap parse tests for all three verbs, add/upsert/rm/tier-conflict round-trips on fixture JSON, dry-run render,pick_schema_entrysemantics).Live smoke against the real org (dry-run only — nothing was POSTed):
Docs updated in
docs/Engineering/Using-th-CLI.md; changeset added (@smooai/smoothminor).🤖 Generated with Claude Code
https://claude.ai/code/session_01KF6EFZ3mMGGF4m1543yWQP