Skip to content

feat: allow custom docs folder path via docsDir config#32

Open
hiiamtrong wants to merge 4 commits intocodeaholicguy:mainfrom
hiiamtrong:feat/custom-docs-dir
Open

feat: allow custom docs folder path via docsDir config#32
hiiamtrong wants to merge 4 commits intocodeaholicguy:mainfrom
hiiamtrong:feat/custom-docs-dir

Conversation

@hiiamtrong
Copy link

Add a docsDir option to .ai-devkit.json that allows users to customize where AI documentation is stored instead of the hardcoded docs/ai path. The init command now prompts for the docs directory, and templates also support the new field.

Closes #31

sotatek added 3 commits March 6, 2026 00:02
Add a docsDir option to .ai-devkit.json that allows users to
customize where AI documentation is stored instead of the hardcoded
docs/ai path. The init command now prompts for the docs directory,
and templates also support the new field.

Closes codeaholicguy#31
Allows setting custom docs directory non-interactively via
`ai-devkit init --docs-dir .ai-docs`. Priority: CLI flag >
template config > interactive prompt > default (docs/ai).
When copying command templates, replace all `docs/ai` references with
the configured docsDir value. This affects copyCommands, copyGeminiSpecificFiles,
and copyCommandsToGlobal. Also fix init command to use docsDir-aware
template manager for environment setup.
@codeaholicguy
Copy link
Owner

codeaholicguy commented Mar 6, 2026

Thanks for the suggestion; it is a good idea, and I have some comments as well.

Naming docsDir is too narrow

docsDir tightly couples the config to "documentation". If ai-devkit later generates other artifacts (scaffolds, configs, reports), you'd need yet another config field. The name also mixes concerns, it's really about where ai-devkit puts its managed artifacts, not specifically "docs".

Alternatively, if the intent truly is only for docs and you foresee other config paths later, a namespaced approach like paths.docs would be more scalable:

{
    "paths": {
      "docs": ".ai-docs"
    }
}

This scales cleanly to paths.commands, paths.skills, etc. without polluting the top-level config.

TemplateManager constructor signature

constructor(targetDir: string = process.cwd(), docsDir: string = DEFAULT_DOCS_DIR)

This leads to awkward call sites like new TemplateManager(undefined, docsDir) scattered throughout the codebase (init.ts, phase.ts, install.service.ts). Positional optional params don't scale, if you add a third option, all callers break.

Use an options object:

constructor(options?: { targetDir?: string; docsDir?: string })

This is more readable, extensible, and avoids the undefined placeholder anti-pattern.

replaceDocsDir using string.split().join() is fragile

private replaceDocsDir(content: string): string {
    return content.split(DEFAULT_DOCS_DIR).join(this.docsDir);
}

This is a naive global string replacement. It would incorrectly replace occurrences in URLs, code examples, or comments that happen to contain docs/ai. For example, a template containing "See https://example.com/docs/ai/guide" would get corrupted.

Better, use template variables like {{docsDir}} in the template files, this is explicit, safe, and makes templates self-documenting.

LintOptions.docsDir mixes config with user options

Adding docsDir to LintOptions conflates runtime configuration with user-facing CLI options. LintOptions should represent what the user passes (feature, json), not internal config state.

Better, create a LintConfig / LintContext that wraps resolved config, separate from user options

Interactive prompt for docsDir adds friction

The init command now always prompts for docs directory in interactive mode. For 95%+ of users who want the default, this is unnecessary friction in the setup flow.

Don't prompt for it during init. Let users configure it via the config file or --docs-dir flag. The default should "just work" silently.

DOCS_DIR constant in lint/constants.ts is now redundant

export const DOCS_DIR = DEFAULT_DOCS_DIR;

This re-exports DEFAULT_DOCS_DIR under a different name, which is confusing. Just use DEFAULT_DOCS_DIR directly where needed.

- Rename config field from flat `docsDir` to namespaced `paths.docs`
- Change TemplateManager constructor to options object pattern
- Use {{docsDir}} template variables instead of naive string replacement
- Separate docsDir from LintOptions into standalone parameter
- Remove interactive prompt for docsDir during init
- Remove redundant DOCS_DIR constant re-export
@hiiamtrong
Copy link
Author

Addressed all 6 items in 953e00c:

  1. paths.docs naming — Config now uses paths: { docs: "..." } instead of flat docsDir. Template files support both paths.docs (new) and docsDir (backward compat).

  2. Options object constructorTemplateManager now takes { targetDir?, docsDir? }. No more new TemplateManager(undefined, docsDir).

  3. Template variables — Templates use {{docsDir}} placeholders instead of split(DEFAULT_DOCS_DIR).join(). Explicit, safe, and self-documenting.

  4. Separated lint config from user optionsdocsDir removed from LintOptions. runLintChecks accepts it as a separate parameter.

  5. Removed interactive prompt — No longer prompts for docs directory during init. Configurable via --docs-dir flag or config/template file.

  6. Removed redundant DOCS_DIR — Lint service imports DEFAULT_DOCS_DIR directly from types.

All 346 tests pass. Ready for another look @codeaholicguy.

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.

Allow custom docs folder path in .ai-devkit.json

2 participants