Skip to content

feat: auto-discover project configs#93

Merged
jy-tan merged 2 commits intomainfrom
per-project-config
Mar 29, 2026
Merged

feat: auto-discover project configs#93
jy-tan merged 2 commits intomainfrom
per-project-config

Conversation

@jy-tan
Copy link
Copy Markdown
Contributor

@jy-tan jy-tan commented Mar 29, 2026

Summary

Add first-class per-project config support by auto-discovering the nearest fence.json when --settings is not provided, and add a reserved @base extends target so repo configs can layer on top of each developer's normal Fence config. This also moves extends resolution into internal/config and hardens cycle detection with canonical IDs for templates, files, and @base.

Resolves #42.

Changes

  • Add internal/config/resolve.go so config inheritance lives with config loading instead of inside internal/templates
  • Add @base as a reserved extends target that resolves through Fence's default user config path and falls back to built-in defaults when no home config exists, add tests
  • Auto-discover the nearest ancestor fence.json before falling back to the default home config path when --settings is omitted
  • Switch CLI and public package helpers to path-aware resolution so cycle detection can catch references back to the original config file
  • Harden extends cycle detection by tracking canonical target IDs for templates, files, and @base, including symlink-aware file identity
  • Update CLI help text, README, and config docs to describe the new per-project workflow

Developer Experience

Per-user config:

// ~/.config/fence/fence.json
{
  "extends": "code"
}

Recall that the code template allows api.openai.com.

Per-project config:

// ./fence.json
{
  "extends": "@base",
  "network": {
    "deniedDomains": ["api.openai.com"]
  }
}

CLI usage with no explicit --settings:

$ fence -- curl -fsS https://api.openai.com
curl: (22) The requested URL returned error: 403

This works because Fence now discovers ./fence.json, resolves @base against the user's normal config, and applies the project override automatically.

Future PRs

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/config/config.go">

<violation number="1" location="internal/config/config.go:279">
P2: Nearest-config discovery should ignore directories named `fence.json`; otherwise CLI config resolution can fail on `os.ReadFile` with "is a directory".</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@dwt
Copy link
Copy Markdown
Collaborator

dwt commented Mar 29, 2026

I would have expected the local config to be named .fence.json - to not clutter up the default dev folder as much in every ls.

Did you have a specific reason to make it visible by default?

Later on I would love to support configuration in something like pyproject.toml for eve less clutter, but that's far in the future

@jy-tan
Copy link
Copy Markdown
Contributor Author

jy-tan commented Mar 29, 2026

I'm leaning towards it being fence.json, for the following reasons:

  • Discoverability: since fence now auto-discovers project config, a hidden file makes the behavior more mysterious. Someone runs fence -> something blocked -> ls doesn't explain why. Future auditing functionality could mitigate this, but as a policy tool, being more visible helps.
  • It matches "shared repo config" conventions like package.json, tsconfig.json, pyproject.toml, etc.

Project directory cleanliness is also valid but might be secondary here.

What do you think?

@jy-tan jy-tan merged commit 202f191 into main Mar 29, 2026
6 checks passed
@jy-tan jy-tan deleted the per-project-config branch March 29, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per project configuration that extends from the home config

2 participants