Skip to content

feat: confstash — standardized project config loading (discovery, extends/presets, layered merge with provenance) - #97

Merged
pyramation merged 2 commits into
mainfrom
feat/confstash
Jul 28, 2026
Merged

feat: confstash — standardized project config loading (discovery, extends/presets, layered merge with provenance)#97
pyramation merged 2 commits into
mainfrom
feat/confstash

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

New confstash package: a cosmiconfig-equivalent, in-house config loader for CLI tools — the project-level complement to appstash. First consumer will be safegres (configurable rules/presets/scoring, constructive-io/constructive-planning#1282); designed so @pgpmjs/env's hand-rolled pgpm.config.js/pgpm.json walkUp+deepmerge loading can later migrate onto it behavior-preservingly (see constructive-io/constructive-planning#1283).

const loader = createConfigLoader<MyConfig>({
  tool: 'mytool',                     // derives search places: mytool.config.{ts,js,mjs,cjs},
  presets: { 'mytool:strict': {...} },//   .mytoolrc{,.json,.yaml,.yml,.js}, mytool.json, package.json key
  defaults, envLayer, userStash: true // layers: defaults -> extends/presets -> user stash -> file -> env -> overrides
});
loader.loadSync({ cwd, overrides });  // -> { config, filepath, layers, isEmpty }
loader.explainSync();                 // per-key provenance for print-config UX

Key decisions:

  • Sync-first (loadSync) so CLIs like pgpm (whose loader is synchronous) can adopt it; load() additionally supports ESM .mjs configs via an indirect dynamic import that survives CJS transpilation/jest.
  • arrayMerge: 'replace' default — matches @pgpmjs/env's replaceArrays semantics.
  • extends resolution: named presets → relative paths → npm packages, recursive with cycle detection; defineConfig<T>() for typed authoring.
  • Provenance tracking: every layer records source/origin; explainLayers attributes each resolved leaf value (like eslint --print-config + git config --show-origin).
  • Optional userStash layer reads ~/.<tool>/config/config.json via appstash (workspace dep); the pgpm-compat shape is covered by a dedicated test.

Tests: 29 passing (packages/confstash, uses NODE_OPTIONS=--experimental-vm-modules for the ESM-config test).

Link to Devin session: https://app.devin.ai/sessions/671aac6e50b04e8caacd3f54c1c63bc6
Requested by: @pyramation

@pyramation pyramation self-assigned this Jul 28, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@socket-security

socket-security Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcross-env@​10.1.010010010081100

View full report

@pyramation
pyramation merged commit 90fe732 into main Jul 28, 2026
51 checks passed
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.

1 participant