feat: add config show command for active config inspection#94
Conversation
|
I have thought about wether this might best live as This has the disadvantage that this command is not advertised with Regarding the output format, I think it's important to list the absolute paths to all the files that get included in the config - bonus points if we can have a |
|
I would like to have this more compact to make it clearer what is what, perhaps something along the line of |
|
This merging might also be really good for |
config show command for active config inspection
|
@dwt Good suggestions, applied a number of them:
We can do these in a future PR:
|
|
Looking at the output, I like the compact representation of included config files ❯ ./fence config show
Active config chain:
local file: /Users/dwt/.config/fence/fence.json
└── builtin template: codenit: I was a bit surprised by the user wide config being referred to as 'local file'. Looking at the merged config: that's a great first step. Something for later: I would really like if we could switch to a configuration loader that is able to preserve comments when merging. |
|
Looking at a merged config, I noticed this: "*.key",
"*.pem",
"*.p12",
"*.pfx",
"**/*.key",
"**/*.pem",
"**/*.p12",
"**/*.pfx"that duplication seems like a footgun. We should either document very clearly why this is required or make it so that generates both patterns, i.e. also blocks in the current directory (and then document that). |
|
@dwt The duplication was on Also updated the output to use clearer labels:
|
Summary
Add a
fence config showsubcommand that lets developers inspect the exact config Fence would use, including auto-discovery and inheritance, without running a sandboxed command. This makes repo-localfence.json,@base, and template-based setups easier to audit while keeping the resolved config machine-readable.Resolves #65.
Changes
fence config showas a no-exec inspection path for default config discovery,--settings, and--templatestderrand the fully resolved config as plain JSON onstdoutResolutionTrace/ResolutionStep) so the CLI can render where each inherited layer came fromMarshalConfigJSON()include previously omitted non-empty fields such asdevicesandcommand.acceptSharedBinaryCannotRuntimeDeny, while still keeping generated starter configs compactfence config initinto its own command file without changing the default generated config output@baseresolution, stdout/stderr separation, compact chain formatting, and config renderer completenesscodetemplate to remove duplication and add regression testsDeveloper Experience
Fence now supports these inspection flows:
fence config showfence config show --settings ./custom.jsonfence config show --template codefence config show | jq '.network'When
fence config showis present, Fence does not run a command. Instead, it writes a human-readable resolution chain tostderr, leaves a blank line for readability, and writes the fully resolved config JSON tostdout.Example shape:
stderrstdout(excerpt, the actual output will contain all non-empty resolved fields from the effective config){ "allowPty": true, "network": { "allowLocalBinding": true, "allowLocalOutbound": true, "allowedDomains": [ "api.openai.com", "*.anthropic.com", "github.com", "repo.example.com" // ... ], "deniedDomains": [ "169.254.169.254" // ... ] }, "filesystem": { "allowWrite": [ ".", "/tmp" // ... ] }, // ... }Additional Notes
This change does not alter the default
fence config initdeveloper experience. A normal init still produces compact starter JSON such as{ "extends": "code" }, and empty sections remain omitted. The renderer change only affects cases where fields likedevicesorcommand.acceptSharedBinaryCannotRuntimeDenyare actually set and should appear in resolved/shared JSON output.