Skip to content

Agent value exploration#4

Open
DealPatrol wants to merge 8 commits into
mainfrom
cursor/agent-value-exploration-46f9
Open

Agent value exploration#4
DealPatrol wants to merge 8 commits into
mainfrom
cursor/agent-value-exploration-46f9

Conversation

@DealPatrol
Copy link
Copy Markdown
Owner

Add a secure environment setup agent to automate discovery and configuration of project environment variables.

The agent helps users identify required environment variables, provides links to common service providers for setup, and interactively prompts for values to write to .env.local, ensuring secrets are never automatically scraped or stolen. This addresses the user's request for an agent to manage environment variables in a secure and guided manner.


Open in Web Open in Cursor 

cursoragent and others added 2 commits February 25, 2026 17:52
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
@cursor
Copy link
Copy Markdown

cursor Bot commented Feb 25, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
repo-app-architect Ready Ready Preview, Comment Apr 22, 2026 7:14pm
v0-repo-app-architect Ready Ready Preview, Comment, Open in v0 Apr 22, 2026 7:14pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a Node-based “env setup agent” to help users discover required environment variables across the codebase/docs and generate a .env.local (or template) via guided prompts, plus documentation and package scripts to run it.

Changes:

  • Introduces scripts/env-agent.mjs to scan for env var usage, print a report, and optionally write an env file.
  • Adds pnpm env:scan / pnpm env:setup scripts for easier usage.
  • Documents the agent in README.md and QUICK_START.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
scripts/env-agent.mjs New CLI tool to scan env var usage and generate .env files.
package.json Adds env:scan and env:setup scripts.
README.md Documents how to run the env setup agent and what it does/doesn’t do.
QUICK_START.md Mentions the optional helper command for env setup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/env-agent.mjs
Comment on lines +500 to +509
const outputPath = path.resolve(rootDir, args.outputPath)
let values = args.templateOnly ? new Map() : await readExistingEnv(outputPath)

if (!args.nonInteractive && report.length > 0 && !args.templateOnly) {
values = await promptForValues(report, values, args.overwrite)
}

const fileContent = renderEnvFile(report, values, !args.templateOnly)
await fs.mkdir(path.dirname(outputPath), { recursive: true })
await fs.writeFile(outputPath, fileContent, 'utf8')
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

--output is resolved and written without any guardrails, so running the script with a crafted path can overwrite arbitrary files outside the repo. Since this is a setup tool that users may run verbatim from docs, consider refusing to write outside process.cwd() by default (or requiring an explicit --allow-outside-root confirmation) to reduce accidental damage.

Copilot uses AI. Check for mistakes.
Comment thread scripts/env-agent.mjs
Comment on lines +403 to +433
async function promptForValues(report, existingValues, shouldOverwrite) {
const rl = readline.createInterface({ input, output })
const values = new Map(existingValues)

try {
for (const item of report) {
const alreadySet = values.has(item.key) && values.get(item.key) !== ''
if (alreadySet && !shouldOverwrite) {
continue
}

output.write(`\n${item.key}\n`)
output.write(` Type: ${item.type}\n`)

if (item.provider) {
output.write(` Provider: ${item.provider.name}\n`)
output.write(` Docs: ${item.provider.url}\n`)
output.write(` Note: ${item.provider.note}\n`)
} else {
output.write(' Provider: Unknown (check project docs)\n')
}

if (alreadySet) {
output.write(' Current value exists. Press enter to keep it.\n')
} else {
output.write(' Enter value (leave blank to skip for now).\n')
}

const prompt = alreadySet ? 'New value: ' : 'Value: '
const response = await rl.question(prompt)

Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

promptForValues uses readline.question(), which echoes user input to the terminal. For keys classified as secret, this will visibly display secrets in scrollback/terminal recordings. Consider using a no-echo/password prompt for item.type === 'secret' (or an explicit allowlist), while keeping normal echo for non-secret keys.

Copilot uses AI. Check for mistakes.
Comment thread scripts/env-agent.mjs
Comment on lines +488 to +490
const content = await fs.readFile(filePath, 'utf8')
const relativePath = toPosixPath(path.relative(rootDir, filePath))
extractFromSource(content, relativePath, discoveredMap)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The scan loop reads each file as UTF-8 without handling read/parse failures; a single unreadable file (permissions) or non-UTF8 content will abort the entire agent. Consider wrapping the per-file readFile/extractFromSource in a try/catch and continuing (optionally with a brief warning) so the agent is resilient on real-world repos.

Suggested change
const content = await fs.readFile(filePath, 'utf8')
const relativePath = toPosixPath(path.relative(rootDir, filePath))
extractFromSource(content, relativePath, discoveredMap)
try {
const content = await fs.readFile(filePath, 'utf8')
const relativePath = toPosixPath(path.relative(rootDir, filePath))
extractFromSource(content, relativePath, discoveredMap)
} catch (error) {
const relativePath = toPosixPath(path.relative(rootDir, filePath))
console.warn(`Skipping ${relativePath}: ${error.message}`)
}

Copilot uses AI. Check for mistakes.
Comment thread scripts/env-agent.mjs
Comment on lines +273 to +276
function classifyKey(key) {
const isPublic = key.startsWith('NEXT_PUBLIC_') || key.startsWith('PUBLIC_')
const isSecret = !isPublic && SECRET_HINTS.some((hint) => key.includes(hint))

Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

SECRET_HINTS includes the substring KEY, which causes many non-secret variables (e.g. STACK_PUBLISHED_CLIENT_KEY from the README) to be classified as secret. This makes the report/env-file comments misleading. Consider narrowing the heuristic (e.g., remove KEY and rely on more specific hints like SECRET/TOKEN/PASSWORD or add an explicit public allowlist for known published/client keys).

Suggested change
function classifyKey(key) {
const isPublic = key.startsWith('NEXT_PUBLIC_') || key.startsWith('PUBLIC_')
const isSecret = !isPublic && SECRET_HINTS.some((hint) => key.includes(hint))
const PUBLIC_ENV_ALLOWLIST = new Set([
// Known published/client keys that are documented as public
'STACK_PUBLISHED_CLIENT_KEY',
])
function classifyKey(key) {
if (PUBLIC_ENV_ALLOWLIST.has(key)) {
return 'public'
}
const isPublic =
key.startsWith('NEXT_PUBLIC_') || key.startsWith('PUBLIC_')
// Use a narrowed set of secret hints that excludes overly generic "key" hints
const effectiveSecretHints = Array.isArray(SECRET_HINTS)
? SECRET_HINTS.filter((hint) => !/key/i.test(String(hint)))
: []
const isSecret =
!isPublic &&
effectiveSecretHints.length > 0 &&
effectiveSecretHints.some((hint) => key.includes(hint))

Copilot uses AI. Check for mistakes.
@DealPatrol DealPatrol marked this pull request as ready for review February 26, 2026 00:38
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
Co-authored-by: DealPatrol <DealPatrol@users.noreply.github.com>
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.

3 participants