feat: CLI should respect tsconfig.json for path resolution and general configuration#1013
Conversation
🦋 Changeset detectedLatest commit: a2da92d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (24)
📝 WalkthroughWalkthroughThis PR adds comprehensive TypeScript configuration ( Changestsconfig-Aware CLI Feature
Code Cleanup & Refactoring
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 Hi @yamcodes, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
arkenv
@arkenv/bun-plugin
@arkenv/cli
@arkenv/fumadocs-ui
@arkenv/vite-plugin
commit: |
📦 Bundle Size Report
✅ All size limits passed! |
|
🤖 I'm sorry @yamcodes, but I was unable to process your request. Please see the logs for more details. |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (1)
packages/fumadocs-ui/src/components/ai-actions.tsx (1)
55-55: ⚖️ Poor tradeoffConsider adding user-facing error feedback.
The empty catch block silently swallows clipboard errors. While the button won't show a checkmark on failure (providing basic visual feedback), users may not understand why the copy operation failed. Clipboard API failures can occur due to browser permissions, HTTPS requirements, or network issues when fetching the markdown content.
💡 Potential improvement
Consider adding simple error feedback, such as:
+const [error, setError] = useState<string | null>(null); + const [checked, onClick] = useCopyButton(async () => { + setError(null); const cached = cache.get(markdownUrl); if (cached) return navigator.clipboard.writeText(cached); setLoading(true); try { await navigator.clipboard.write([ // ... ]); - } catch (_err) { + } catch (err) { + setError("Failed to copy. Please check permissions and try again."); } finally { setLoading(false); } });Then display the error message near the button when present.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/fumadocs-ui/src/components/ai-actions.tsx` at line 55, The catch block in packages/fumadocs-ui/src/components/ai-actions.tsx that swallows clipboard errors should surface a user-facing error message: capture the caught error (use _err or err), log it (console.error or a logger), set a local React state (e.g. copyError via useState) with err.message or a friendly string, and display that state near the copy button (small inline text or tooltip) so users see why the clipboard action failed; ensure you clear the error on a successful copy or after a timeout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.changeset/respect-tsconfig-cli.md:
- Around line 10-13: Change the inconsistent present tense in the release notes
by updating the fourth bullet "Framework & Package Manager Detection: Leverages
parsed `tsconfig.json` context..." to past tense (e.g., "Leveraged parsed
`tsconfig.json` context...") and scan the other bullets to ensure they all use
past tense (e.g., "Added", "Updated", "Enhanced", "Leveraged") so the four
bullets are stylistically consistent.
In `@packages/cli/src/cli/ui/prompts/steps.ts`:
- Around line 72-77: The prompt handler currently returns the raw text() answer
verbatim, allowing whitespace-only input; update the block that awaits text(...)
(the answer variable) so you trim the string and, if the trimmed result is
empty, fall back to defaultEnvPath before returning — still return null when
isCancel(answer) is true; reference the text(...) call, the answer variable,
isCancel(answer) check, and defaultEnvPath when making the change.
In `@packages/cli/src/features/scaffold/scaffold.ts`:
- Around line 200-205: The code returns a relative env path that can escape the
workspace when currentTsConfig.compilerOptions.rootDir is outside cwd; update
the logic around the rootDir handling (the block using currentTsConfig, rootDir,
rel and path.relative) to detect when rootDir is outside cwd (e.g., rel is
empty? or rel === "." is fine, but if rel startsWith("..") or
path.isAbsolute(rootDir) resolving outside cwd) and in that case fall back to
"./env.ts" instead of returning a "../..." path; otherwise continue returning
`./${rel}/env.ts` as before. Ensure you reference the existing symbols
currentTsConfig, compilerOptions.rootDir, path.relative, cwd and the rootDir/rel
variables when making the change.
In `@packages/cli/src/features/scaffold/tsconfig-parser.ts`:
- Around line 64-81: Detected potential infinite recursion when following
parsed.extends chains; add cycle protection by tracking visited config file
paths (use a Set of resolved absolute paths) and checking before recursing.
Concretely, update loadTsConfig to accept an optional visited:Set<string> (or
create one at entry), resolve each ext to an absolute path (extPath) as you
already do, then if visited.has(extPath) skip or throw a clear error instead of
calling await loadTsConfig(extPath); otherwise add extPath to visited before
recursing and pass visited down to the recursive loadTsConfig call. Ensure the
initial call seeds the visited set with the top-level configPath.
- Around line 144-153: The current alias matching uses startsWith(cleanPattern)
and returns the first target, which allows unintended prefix matches and picks a
non-specific alias; update the resolve logic in tsconfig-parser.ts to (1)
distinguish patterns that end with '*' from exact patterns: only allow prefix
matches when the original pattern had a trailing '*' and require full equality
when it did not, and (2) prefer the most specific alias by selecting the longest
cleanPattern match instead of returning the first match—e.g., compute
cleanPattern and a boolean hadStar from pattern, collect matching entries, sort
or pick the one with the largest cleanPattern.length, then map that match's
targets to cleanTarget/targetRel and resolve with path.resolve(baseUrl,
targetRel).
- Around line 73-77: The code uses require.resolve(...) to compute extPath (the
variable assigned on line with require.resolve) which fails in ESM; replace that
call with an ESM-compatible resolver: use import.meta.resolve(ext, { paths:
[path.dirname(configPath)] }) (await the promise) and convert the returned URL
to a filesystem path if necessary (e.g., with fileURLToPath) before assigning to
extPath; keep the existing fallback that sets extPath =
path.resolve(path.dirname(configPath), "node_modules", ext) inside the catch
path. Alternatively, if you must support older Node versions, create a require
via createRequire(import.meta.url) from "module" and call requireResolve =
createRequire(...).resolve(ext, { paths: [...] }) in place of require.resolve.
Ensure you update the surrounding function (where extPath is used) to be async
if using import.meta.resolve and handle errors consistently.
In `@packages/cli/src/shared/ports/prompt.port.ts`:
- Around line 11-12: Change the tsConfig parameter type from any to the concrete
ParsedTsConfig | null across the init → adapter → wizard pipeline: update the
port's tsConfig declaration (the interface exposing tsConfig), change the
adapter function signature that passes tsConfig to getEnvExampleKeys(), and
update the wizard prompt parameter types to accept ParsedTsConfig | null; add
import type { ParsedTsConfig } from "`@/features/scaffold/tsconfig-parser`" in
each affected file and ensure calls to getEnvExampleKeys(tsConfig) match the new
type.
In `@skills/skill-creator/assets/eval-review.html`:
- Around line 111-113: The HTML still calls the old global names (addRow,
exportEvalSet, updateQuery, updateTrigger, deleteRow) while your JS renamed them
(_updateQuery, _updateTrigger, etc.), causing ReferenceError; restore
compatibility by adding thin global wrapper functions that map the old names to
the new ones (for example implement global functions addRow(...) that call the
new addRow implementation or exportEvalSet(...) that calls the renamed function,
and implement updateQuery(idx,val){ return _updateQuery(idx,val); },
updateTrigger(idx,val){ return _updateTrigger(idx,val); }, deleteRow(idx){
return _deleteRow(idx); }) so the inline HTML handlers keep working without
changing markup.
In `@skills/skill-creator/eval-viewer/viewer.html`:
- Around line 1132-1134: The concatenation that builds the html string (variable
html) inserts unescaped metadata fields (metadata.timestamp, metadata.evals_run
items, metadata.runs_per_configuration and other similar interpolations)
directly into innerHTML, exposing an XSS risk; fix by escaping these values
before concatenation (add/use a helper like escapeHtml(value) and apply it to
metadata.timestamp, each entry in metadata.evals_run,
metadata.runs_per_configuration, etc.), or construct the DOM with
createElement/textContent instead of assigning raw innerHTML, and update the
code paths that build the html string (the blocks referencing html and metadata)
to use the sanitizer helper or text nodes.
- Line 907: Inline onclick handlers are failing because function declarations
like _toggleGrades were renamed or moved out of the global scope; restore the
original public handler names (e.g., _toggleGrades) or update the inline onclick
attributes to call the new names, and ensure these handlers are globally
accessible (attach them to window, e.g., window._toggleGrades = _toggleGrades)
if the functions live inside a closure; apply the same fix to the other renamed
handlers referenced around the other affected spots (lines near 986, 1026, 1063,
1106-1110).
---
Nitpick comments:
In `@packages/fumadocs-ui/src/components/ai-actions.tsx`:
- Line 55: The catch block in packages/fumadocs-ui/src/components/ai-actions.tsx
that swallows clipboard errors should surface a user-facing error message:
capture the caught error (use _err or err), log it (console.error or a logger),
set a local React state (e.g. copyError via useState) with err.message or a
friendly string, and display that state near the copy button (small inline text
or tooltip) so users see why the clipboard action failed; ensure you clear the
error on a successful copy or after a timeout.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 89f158ef-6005-4b36-b465-5975c9d1060b
📒 Files selected for processing (18)
.changeset/respect-tsconfig-cli.mdapps/www/hooks/use-copy-command.test.tspackages/arkenv/src/standard-mode.test.tspackages/cli/src/adapters/prompt.adapter.tspackages/cli/src/cli/commands/init.tspackages/cli/src/cli/ui/prompts/steps.tspackages/cli/src/cli/ui/prompts/wizard.tspackages/cli/src/features/scaffold/env-parser.test.tspackages/cli/src/features/scaffold/env-parser.tspackages/cli/src/features/scaffold/index.tspackages/cli/src/features/scaffold/scaffold.test.tspackages/cli/src/features/scaffold/scaffold.tspackages/cli/src/features/scaffold/tsconfig-parser.tspackages/cli/src/shared/ports/prompt.port.tspackages/fumadocs-ui/src/components/ai-actions.tsxpackages/fumadocs-ui/src/components/header.tsxskills/skill-creator/assets/eval-review.htmlskills/skill-creator/eval-viewer/viewer.html
| if (currentTsConfig?.compilerOptions?.rootDir) { | ||
| const rootDir = currentTsConfig.compilerOptions.rootDir; | ||
| const rel = path.relative(cwd, rootDir); | ||
| if (!rel || rel === ".") return "./env.ts"; | ||
| return `./${rel}/env.ts`; | ||
| } |
There was a problem hiding this comment.
Prevent defaults that escape the current workspace.
When rootDir is outside cwd, this returns paths like ./../.../env.ts, which can steer scaffolding writes outside the project.
Suggested fix
if (currentTsConfig?.compilerOptions?.rootDir) {
const rootDir = currentTsConfig.compilerOptions.rootDir;
const rel = path.relative(cwd, rootDir);
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
+ return "./env.ts";
+ }
if (!rel || rel === ".") return "./env.ts";
return `./${rel}/env.ts`;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (currentTsConfig?.compilerOptions?.rootDir) { | |
| const rootDir = currentTsConfig.compilerOptions.rootDir; | |
| const rel = path.relative(cwd, rootDir); | |
| if (!rel || rel === ".") return "./env.ts"; | |
| return `./${rel}/env.ts`; | |
| } | |
| if (currentTsConfig?.compilerOptions?.rootDir) { | |
| const rootDir = currentTsConfig.compilerOptions.rootDir; | |
| const rel = path.relative(cwd, rootDir); | |
| if (rel.startsWith("..") || path.isAbsolute(rel)) { | |
| return "./env.ts"; | |
| } | |
| if (!rel || rel === ".") return "./env.ts"; | |
| return `./${rel}/env.ts`; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/src/features/scaffold/scaffold.ts` around lines 200 - 205, The
code returns a relative env path that can escape the workspace when
currentTsConfig.compilerOptions.rootDir is outside cwd; update the logic around
the rootDir handling (the block using currentTsConfig, rootDir, rel and
path.relative) to detect when rootDir is outside cwd (e.g., rel is empty? or rel
=== "." is fine, but if rel startsWith("..") or path.isAbsolute(rootDir)
resolving outside cwd) and in that case fall back to "./env.ts" instead of
returning a "../..." path; otherwise continue returning `./${rel}/env.ts` as
before. Ensure you reference the existing symbols currentTsConfig,
compilerOptions.rootDir, path.relative, cwd and the rootDir/rel variables when
making the change.
| if (parsed.extends) { | ||
| const extendsArr = Array.isArray(parsed.extends) | ||
| ? parsed.extends | ||
| : [parsed.extends]; | ||
| for (const ext of extendsArr) { | ||
| let extPath: string; | ||
| if (ext.startsWith(".") || path.isAbsolute(ext)) { | ||
| extPath = path.resolve(path.dirname(configPath), ext); | ||
| } else { | ||
| try { | ||
| extPath = require.resolve(ext, { paths: [path.dirname(configPath)] }); | ||
| } catch { | ||
| extPath = path.resolve(path.dirname(configPath), "node_modules", ext); | ||
| } | ||
| } | ||
|
|
||
| const baseConfig = await loadTsConfig(extPath); | ||
| const baseOptions = { ...baseConfig.compilerOptions }; |
There was a problem hiding this comment.
Add cycle protection for recursive extends loading.
A cyclic extends chain can recurse forever and eventually crash the CLI. Guard visited config paths before recursing.
Suggested fix
-export async function loadTsConfig(
- configPath: string,
-): Promise<ParsedTsConfig> {
+export async function loadTsConfig(
+ configPath: string,
+ visited = new Set<string>(),
+): Promise<ParsedTsConfig> {
+ const normalizedConfigPath = path.resolve(configPath);
+ if (visited.has(normalizedConfigPath)) {
+ return { path: normalizedConfigPath, compilerOptions: {} };
+ }
+ visited.add(normalizedConfigPath);
+
let content = "";
try {
- content = await fsp.readFile(configPath, "utf-8");
+ content = await fsp.readFile(normalizedConfigPath, "utf-8");
} catch {
- return { path: configPath, compilerOptions: {} };
+ return { path: normalizedConfigPath, compilerOptions: {} };
}
@@
- const baseConfig = await loadTsConfig(extPath);
+ const baseConfig = await loadTsConfig(extPath, visited);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/src/features/scaffold/tsconfig-parser.ts` around lines 64 - 81,
Detected potential infinite recursion when following parsed.extends chains; add
cycle protection by tracking visited config file paths (use a Set of resolved
absolute paths) and checking before recursing. Concretely, update loadTsConfig
to accept an optional visited:Set<string> (or create one at entry), resolve each
ext to an absolute path (extPath) as you already do, then if
visited.has(extPath) skip or throw a clear error instead of calling await
loadTsConfig(extPath); otherwise add extPath to visited before recursing and
pass visited down to the recursive loadTsConfig call. Ensure the initial call
seeds the visited set with the top-level configPath.
| for (const [pattern, targets] of Object.entries(paths)) { | ||
| const cleanPattern = pattern.replace(/\*$/, ""); | ||
| if (importSpecifier.startsWith(cleanPattern)) { | ||
| const subpath = importSpecifier.slice(cleanPattern.length); | ||
| for (const target of targets) { | ||
| const cleanTarget = target.replace(/\*$/, ""); | ||
| const targetRel = `${cleanTarget}${subpath}`; | ||
| return path.resolve(baseUrl, targetRel); | ||
| } | ||
| } |
There was a problem hiding this comment.
Alias matching is too permissive and can resolve wrong imports.
startsWith(cleanPattern) can match unintended specifiers (for example, a pattern ending with / can still prefix-match unrelated inputs). Also, returning the first match can pick a less specific alias.
Suggested fix
- for (const [pattern, targets] of Object.entries(paths)) {
- const cleanPattern = pattern.replace(/\*$/, "");
- if (importSpecifier.startsWith(cleanPattern)) {
+ const entries = Object.entries(paths).sort(
+ ([a], [b]) => b.replace(/\*$/, "").length - a.replace(/\*$/, "").length,
+ );
+ for (const [pattern, targets] of entries) {
+ const hasWildcard = pattern.endsWith("*");
+ const cleanPattern = pattern.replace(/\*$/, "");
+ const matched = hasWildcard
+ ? importSpecifier.startsWith(cleanPattern)
+ : importSpecifier === cleanPattern;
+ if (matched) {
const subpath = importSpecifier.slice(cleanPattern.length);
for (const target of targets) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for (const [pattern, targets] of Object.entries(paths)) { | |
| const cleanPattern = pattern.replace(/\*$/, ""); | |
| if (importSpecifier.startsWith(cleanPattern)) { | |
| const subpath = importSpecifier.slice(cleanPattern.length); | |
| for (const target of targets) { | |
| const cleanTarget = target.replace(/\*$/, ""); | |
| const targetRel = `${cleanTarget}${subpath}`; | |
| return path.resolve(baseUrl, targetRel); | |
| } | |
| } | |
| const entries = Object.entries(paths).sort( | |
| ([a], [b]) => b.replace(/\*$/, "").length - a.replace(/\*$/, "").length, | |
| ); | |
| for (const [pattern, targets] of entries) { | |
| const hasWildcard = pattern.endsWith("*"); | |
| const cleanPattern = pattern.replace(/\*$/, ""); | |
| const matched = hasWildcard | |
| ? importSpecifier.startsWith(cleanPattern) | |
| : importSpecifier === cleanPattern; | |
| if (matched) { | |
| const subpath = importSpecifier.slice(cleanPattern.length); | |
| for (const target of targets) { | |
| const cleanTarget = target.replace(/\*$/, ""); | |
| const targetRel = `${cleanTarget}${subpath}`; | |
| return path.resolve(baseUrl, targetRel); | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/src/features/scaffold/tsconfig-parser.ts` around lines 144 -
153, The current alias matching uses startsWith(cleanPattern) and returns the
first target, which allows unintended prefix matches and picks a non-specific
alias; update the resolve logic in tsconfig-parser.ts to (1) distinguish
patterns that end with '*' from exact patterns: only allow prefix matches when
the original pattern had a trailing '*' and require full equality when it did
not, and (2) prefer the most specific alias by selecting the longest
cleanPattern match instead of returning the first match—e.g., compute
cleanPattern and a boolean hadStar from pattern, collect matching entries, sort
or pick the one with the largest cleanPattern.length, then map that match's
targets to cleanTarget/targetRel and resolve with path.resolve(baseUrl,
targetRel).
|
The latest updates on your projects. Learn more about Vercel for GitHub. Warning Deployment cooldown active@yamcodes has triggered deployments too frequently. Please wait 12 minutes and 51 seconds before the next automated deployment. ⌛ How to resolve this issue?After the wait time has elapsed, a deployment can be triggered by pushing new commits to this PR or by re-running the workflow. We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?We enforce rate limits to ensure stability and fair usage of resources for all contributors. |
…nents, and expose internal handlers for eval tools
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @arkenv/cli@0.0.9 ### Patch Changes - #### Refined setup experience in `arkenv init` _[`#1016`](#1016) [`d536ed7`](d536ed7) [@yamcodes](https://github.com/yamcodes)_ - **Clearer Framework Options**: Updated terminology to better distinguish between server-side runtime validation and client-side bundling integrations. - **Architecture Detection**: Improved detection logic recommends the most efficient configuration based on your project's features. - **Better In-File Guidance**: Generated templates now include comments clarifying validation behavior for your specific environment. - #### Add keyboard navigation hints _[`ac3adcc`](ac3adcc) [@yamcodes](https://github.com/yamcodes)_ - #### Improve Ctrl+C handling and implement graceful shutdown _[`#1019`](#1019) [`102ce4a`](102ce4a) [@yamcodes](https://github.com/yamcodes)_ - Implemented graceful shutdown for `SIGINT` (Ctrl+C) to flush logs and JSON data, with a 2-second safety timeout and support for immediate exit on a second Ctrl+C. - Corrected exit code (130) for `SIGINT` terminations. - Fixed a bug where the `init` wizard would continue after a prompt was cancelled. - #### Respect `tsconfig.json` for path resolution and scaffolding _[`#1013`](#1013) [`0a18edd`](0a18edd) [@yamcodes](https://github.com/yamcodes)_ The Arkenv CLI now dynamically resolves configuration paths and scans project files by respecting `tsconfig.json` settings (`rootDir`, `paths`, `baseUrl`). Key improvements include: - **Robust `tsconfig` Parser**: Added support for parsing `tsconfig.json` files with comments (`jsonc-parser`), handling `extends`, `rootDir`, `baseUrl`, and `paths` alias resolution. - **Dynamic Scaffolding Defaults**: Updated `init` scaffolding logic to suggest project-appropriate default paths based on `compilerOptions.rootDir` rather than hardcoding `./src/env.ts`. - **Advanced Environment Scanning**: Enhanced `getEnvExampleKeys` to scan project source files for `process.env` and `import.meta.env` usages, correctly resolving aliased imports (e.g. `@/env`). - **Framework & Package Manager Detection**: Leveraged parsed `tsconfig.json` context to accurately identify project frameworks and package managers. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fixes #908
The Arkenv CLI now dynamically resolves configuration paths and scans project files by respecting
tsconfig.jsonsettings (rootDir,paths,baseUrl).Key improvements include:
tsconfigParser: Added support for parsingtsconfig.jsonfiles with comments (jsonc-parser), handlingextends,rootDir,baseUrl, andpathsalias resolution.initscaffolding logic to suggest project-appropriate default paths based oncompilerOptions.rootDirrather than hardcoding./src/env.ts.getEnvExampleKeysto scan project source files forprocess.envandimport.meta.envusages, correctly resolving aliased imports (e.g.@/env).tsconfig.jsoncontext to accurately identify project frameworks and package managers.Summary by CodeRabbit
New Features
tsconfig.jsonfor path resolution and scaffolding, includingrootDir,baseUrl, and path aliasesprocess.envandimport.meta.envusages with alias import resolutiontsconfig.jsonconfigurationTests
Chores