Summary
Rename the pervasive baseDir / baseDirs concept to outputRoot / outputRoots so it reads symmetrically against the new inputRoot concept being introduced in #1514.
Motivation / Purpose
PR #1514 decouples the source .rulesync/ directory from the output directory by adding a new parameter. During review we agreed to land that new parameter as inputRoot for clarity. The natural counterpart is to rename the existing baseDir (which in practice is the output root — where generated tool configs are written to) to outputRoot.
Keeping the names asymmetric (inputRoot ↔ baseDir) would be confusing and erode the clarity benefit of the original rename. However, baseDir is pervasive across the public API and shipping the full rename inside #1514 would bloat that PR and make it harder to review behavior changes in isolation. Splitting it out into a dedicated refactor is the right call.
Deprecation policy (coexistence period)
The old names must stay functional during a coexistence period so existing users are not broken. Concretely:
- CLI flag:
--base-dirs / -b continues to work as an alias of --output-roots. When the old flag is used, the CLI emits a deprecation warning log (e.g. logger.warn("--base-dirs is deprecated; use --output-roots instead. It will be removed in a future release.")).
- Config file field:
baseDirs in rulesync.jsonc continues to be accepted as an alias of outputRoots. When the old field is present, the config loader emits a deprecation warning log on startup.
- Public programmatic API:
Config.getBaseDirs() continues to exist alongside getOutputRoots() and returns the same value, but emits a deprecation warning the first time it is called per process (to avoid spam). The underlying storage is outputRoots.
- Zod schema: accept both
baseDirs and outputRoots; if both are present, prefer outputRoots and warn; if only baseDirs is present, map it internally to outputRoots and warn.
Removal timeline: keep the deprecated surface for at least one full minor release cycle, then remove in the next major version bump. Update CHANGELOG.md and the docs to call out the deprecation at the time of the rename and the removal at the time of the major bump.
Internal-only parameters (processor constructors, file-class fromFile / fromDir signatures) are not part of the documented public API and can be renamed directly without aliasing. If a downstream user is importing these internals they will see a TypeScript error on upgrade, which is acceptable.
Details
Scope: rename baseDir → outputRoot (and baseDirs → outputRoots) everywhere, preserving behavior. There is no functional change in this issue.
Affected surfaces (non-exhaustive; grep currently shows ~4385 baseDir occurrences across ~310 files):
- CLI flag:
-b, --base-dirs <paths> → -b, --output-roots <paths> in src/cli/index.ts (keep old name as deprecated alias)
- Config schema:
ConfigParamsSchema.baseDirs → outputRoots in src/config/config.ts, plus handling for the field in rulesync.jsonc (keep old field as deprecated alias)
- Config class:
Config.getBaseDirs() → getOutputRoots() and the private baseDirs field (keep old accessor as deprecated alias)
- Config resolver:
getBaseDirsInLightOfGlobal and related helpers in src/config/config-resolver.ts
- Processors:
FeatureProcessor / DirFeatureProcessor constructor param and protected field in src/types/feature-processor.ts and src/types/dir-feature-processor.ts, plus every subclass under src/features/**/*-processor.ts (internal — direct rename)
- File classes: every
RulesyncFile / tool-file fromFile / fromDir signature that accepts baseDir (internal — direct rename)
- Utilities:
validateBaseDir → validateOutputRoot in src/utils/file.ts (internal — direct rename)
- Tests: all test files that reference these names, plus new tests exercising the deprecation-warning paths
- Docs:
docs/**/*.md, skills/rulesync/*.md (synced by scripts/sync-skill-docs.ts), and README.md
Acceptance criteria
- All production code uses
outputRoot / outputRoots exclusively for the new surface.
--base-dirs and the baseDirs field in rulesync.jsonc still work, and produce a visible deprecation warning log each time they are used.
Config.getBaseDirs() still works and produces a deprecation warning the first time it is called per process.
- A regression test confirms each deprecated alias still maps to the new behavior and emits the expected warning.
- Existing tests are updated to use the new names.
- Docs under
docs/ and skills/rulesync/ reflect the new naming, and explicitly mention the deprecation of the old names.
CHANGELOG.md notes both the new name and the deprecation.
pnpm cicheck passes.
Out of scope
Additional Context
Summary
Rename the pervasive
baseDir/baseDirsconcept tooutputRoot/outputRootsso it reads symmetrically against the newinputRootconcept being introduced in #1514.Motivation / Purpose
PR #1514 decouples the source
.rulesync/directory from the output directory by adding a new parameter. During review we agreed to land that new parameter asinputRootfor clarity. The natural counterpart is to rename the existingbaseDir(which in practice is the output root — where generated tool configs are written to) tooutputRoot.Keeping the names asymmetric (
inputRoot↔baseDir) would be confusing and erode the clarity benefit of the original rename. However,baseDiris pervasive across the public API and shipping the full rename inside #1514 would bloat that PR and make it harder to review behavior changes in isolation. Splitting it out into a dedicated refactor is the right call.Deprecation policy (coexistence period)
The old names must stay functional during a coexistence period so existing users are not broken. Concretely:
--base-dirs/-bcontinues to work as an alias of--output-roots. When the old flag is used, the CLI emits a deprecation warning log (e.g.logger.warn("--base-dirs is deprecated; use --output-roots instead. It will be removed in a future release.")).baseDirsinrulesync.jsonccontinues to be accepted as an alias ofoutputRoots. When the old field is present, the config loader emits a deprecation warning log on startup.Config.getBaseDirs()continues to exist alongsidegetOutputRoots()and returns the same value, but emits a deprecation warning the first time it is called per process (to avoid spam). The underlying storage isoutputRoots.baseDirsandoutputRoots; if both are present, preferoutputRootsand warn; if onlybaseDirsis present, map it internally tooutputRootsand warn.Removal timeline: keep the deprecated surface for at least one full minor release cycle, then remove in the next major version bump. Update
CHANGELOG.mdand the docs to call out the deprecation at the time of the rename and the removal at the time of the major bump.Internal-only parameters (processor constructors, file-class
fromFile/fromDirsignatures) are not part of the documented public API and can be renamed directly without aliasing. If a downstream user is importing these internals they will see a TypeScript error on upgrade, which is acceptable.Details
Scope: rename
baseDir→outputRoot(andbaseDirs→outputRoots) everywhere, preserving behavior. There is no functional change in this issue.Affected surfaces (non-exhaustive; grep currently shows ~4385
baseDiroccurrences across ~310 files):-b, --base-dirs <paths>→-b, --output-roots <paths>insrc/cli/index.ts(keep old name as deprecated alias)ConfigParamsSchema.baseDirs→outputRootsinsrc/config/config.ts, plus handling for the field inrulesync.jsonc(keep old field as deprecated alias)Config.getBaseDirs()→getOutputRoots()and the privatebaseDirsfield (keep old accessor as deprecated alias)getBaseDirsInLightOfGlobaland related helpers insrc/config/config-resolver.tsFeatureProcessor/DirFeatureProcessorconstructor param and protected field insrc/types/feature-processor.tsandsrc/types/dir-feature-processor.ts, plus every subclass undersrc/features/**/*-processor.ts(internal — direct rename)RulesyncFile/ tool-filefromFile/fromDirsignature that acceptsbaseDir(internal — direct rename)validateBaseDir→validateOutputRootinsrc/utils/file.ts(internal — direct rename)docs/**/*.md,skills/rulesync/*.md(synced byscripts/sync-skill-docs.ts), andREADME.mdAcceptance criteria
outputRoot/outputRootsexclusively for the new surface.--base-dirsand thebaseDirsfield inrulesync.jsoncstill work, and produce a visible deprecation warning log each time they are used.Config.getBaseDirs()still works and produces a deprecation warning the first time it is called per process.docs/andskills/rulesync/reflect the new naming, and explicitly mention the deprecation of the old names.CHANGELOG.mdnotes both the new name and the deprecation.pnpm cicheckpasses.Out of scope
rulesyncDir→inputRootrename, which is handled in feat: add --rulesync-dir flag to decouple source rules from output directory #1514.Additional Context