-
Notifications
You must be signed in to change notification settings - Fork 514
Add fix command registration and update agent UI label handling #1387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
08b03be
Add fix command registration and update agent UI label handling
aadesh18 cf73d6c
Merge branch 'dev' into add-fix-command
aadesh18 4898368
Enhance stdin reading in fix command to limit input size
aadesh18 5acbcbd
Implement abortable prompt handling in fix command for improved user …
aadesh18 792bd91
better warning
aadesh18 300c0a9
bot comment
aadesh18 a8171f3
bot comments
aadesh18 451dace
bot comment
aadesh18 97dcfe4
Merge branch 'dev' into add-fix-command
aadesh18 5566663
Merge branch 'dev' into add-fix-command
aadesh18 0c262a8
Add stack doctor (#1390)
aadesh18 3984c46
Merge branch 'dev' into add-fix-command
aadesh18 f79413a
bot comment
aadesh18 45e8ccf
Merge branch 'dev' into add-fix-command
aadesh18 c7de434
Enhance package.json validation in stack doctor command
aadesh18 cc26cac
Merge branch 'dev' into add-fix-command
aadesh18 c3afc02
Merge branch 'dev' into add-fix-command
aadesh18 c159e41
Merge branch 'dev' into add-fix-command
aadesh18 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| import { confirm, input } from "@inquirer/prompts"; | ||
| import { Command } from "commander"; | ||
| import { runClaudeAgent } from "../lib/claude-agent.js"; | ||
| import { CliError } from "../lib/errors.js"; | ||
| import { isNonInteractiveEnv } from "../lib/interactive.js"; | ||
|
|
||
| type FixOptions = { | ||
| error?: string, | ||
| outputDir?: string, | ||
| yes?: boolean, | ||
| }; | ||
|
|
||
| const MAX_ERROR_LENGTH = 8000; | ||
| const MAX_STDIN_BYTES = MAX_ERROR_LENGTH * 4; | ||
|
|
||
| async function abortablePrompt<T>(promise: Promise<T>): Promise<T> { | ||
| try { | ||
| return await promise; | ||
| } catch (error: unknown) { | ||
| if (error != null && typeof error === "object" && "name" in error && (error as { name: unknown }).name === "ExitPromptError") { | ||
| console.log("\nAborted."); | ||
| process.exit(0); | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
|
|
||
| async function readStdin(): Promise<string> { | ||
| if (process.stdin.isTTY) return ""; | ||
| const chunks: Buffer[] = []; | ||
| let totalBytes = 0; | ||
| for await (const chunk of process.stdin) { | ||
| const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk; | ||
| const remaining = MAX_STDIN_BYTES - totalBytes; | ||
| if (buf.length >= remaining) { | ||
| chunks.push(buf.subarray(0, remaining)); | ||
| totalBytes += remaining; | ||
| break; | ||
| } | ||
| chunks.push(buf); | ||
| totalBytes += buf.length; | ||
| } | ||
| return Buffer.concat(chunks).toString("utf-8").trim(); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| export function registerFixCommand(program: Command) { | ||
| program | ||
| .command("fix") | ||
| .description("Use an AI agent to fix a Stack Auth error in your project") | ||
| .option("--error <text>", "The error message to fix (also accepts stdin)") | ||
| .option("--output-dir <dir>", "Directory of the project to fix (defaults to cwd)") | ||
| .option("-y, --yes", "Skip the confirmation prompt") | ||
| .action(async (opts: FixOptions) => { | ||
| await runFix(opts); | ||
| }); | ||
| } | ||
|
|
||
| async function runFix(opts: FixOptions) { | ||
| const outputDir = opts.outputDir ?? process.cwd(); | ||
|
vercel[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
|
aadesh18 marked this conversation as resolved.
|
||
| let errorText = (opts.error ?? "").trim(); | ||
| if (!errorText) { | ||
| const piped = await readStdin(); | ||
| if (piped) errorText = piped; | ||
| } | ||
| if (!errorText) { | ||
| if (isNonInteractiveEnv()) { | ||
| throw new CliError("No error provided. Pass --error \"...\" or pipe the error to stdin."); | ||
| } | ||
| errorText = (await abortablePrompt(input({ | ||
| message: "Paste the Stack Auth error you want fixed:", | ||
| validate: (v) => v.trim().length > 0 || "Error text is required", | ||
| }))).trim(); | ||
| } | ||
|
|
||
| if (errorText.length > MAX_ERROR_LENGTH) { | ||
| const originalLength = errorText.length; | ||
| errorText = errorText.slice(0, MAX_ERROR_LENGTH); | ||
| console.warn(`\nWarning: error text was ${originalLength} characters; truncated to ${MAX_ERROR_LENGTH}. The agent will not see anything past the cutoff.\n`); | ||
| } | ||
|
aadesh18 marked this conversation as resolved.
aadesh18 marked this conversation as resolved.
|
||
|
|
||
| console.log("\nError to fix:\n"); | ||
| console.log(" " + errorText.split("\n").join("\n ")); | ||
| console.log(); | ||
|
|
||
| console.log(`Working directory: ${outputDir}`); | ||
|
|
||
| if (!opts.yes && !isNonInteractiveEnv()) { | ||
| const ok = await abortablePrompt(confirm({ | ||
| message: "Run the AI agent to fix this error?", | ||
| default: true, | ||
| })); | ||
| if (!ok) { | ||
| console.log("Aborted."); | ||
| return; | ||
| } | ||
| } | ||
|
aadesh18 marked this conversation as resolved.
|
||
|
|
||
| const prompt = buildFixPrompt(errorText); | ||
| const success = await runClaudeAgent({ | ||
| prompt, | ||
| cwd: outputDir, | ||
| label: "Fixing Stack Auth error...", | ||
| }); | ||
|
|
||
| if (!success) { | ||
| throw new CliError("The AI agent was unable to complete the fix. See the output above for details."); | ||
| } | ||
| } | ||
|
|
||
| function buildFixPrompt(errorText: string): string { | ||
| return [ | ||
| "You are fixing a Stack Auth (https://stack-auth.com, package `@stackframe/*`) integration error in the user's project.", | ||
| "", | ||
| "YOUR JOB: actually apply the fix to the files on disk using the Edit/Write tools. Do not just diagnose and stop. Do not just describe what to do. Make the edits.", | ||
| "", | ||
| "Workflow (do all of these — do not skip steps):", | ||
| "1. Read the files needed to understand the error: package.json, stack.config.ts if present, .env / .env.local, the file(s) referenced in the stack trace, app/layout.* or pages/_app.*, and any handler route (e.g. app/handler/[...stack]/page.tsx).", | ||
| "2. Diagnose the Stack Auth root cause (e.g. missing StackProvider wrapping, missing env vars, wrong handler route path, incorrect stack.config.ts, wrong import from @stackframe/*, missing API keys, missing `stackServerApp` instance, etc.).", | ||
| "3. Apply the minimal fix using Edit/Write. Actually modify the files. If env vars are missing, instruct the user clearly (do not invent secret values).", | ||
| "4. After editing, verify your change by re-reading the affected file(s).", | ||
| "", | ||
| "GUARDRAILS:", | ||
| "- If, after reading the relevant files, the error is clearly NOT caused by Stack Auth, stop and explain why instead of editing.", | ||
| "- No unrelated refactors, formatting changes, dependency upgrades, or cleanup.", | ||
| "- No destructive shell commands (`rm -rf`, `git reset --hard`, force pushes, deleting branches, anything outside the project directory).", | ||
| "- Never print secret values (STACK_SECRET_SERVER_KEY, etc.) — refer to env vars by name only.", | ||
| "", | ||
| "The user pasted the following error:", | ||
| "", | ||
| "<<<ERROR_START>>>", | ||
| JSON.stringify(errorText), | ||
| "<<<ERROR_END>>>", | ||
| "", | ||
| "FINAL OUTPUT FORMAT — your last assistant message MUST be exactly this markdown structure, with nothing before or after it:", | ||
| "", | ||
| "## Error", | ||
| "<one or two sentence plain-language summary of what went wrong>", | ||
| "", | ||
| "## Files changed", | ||
| "- `path/to/file1` — <one-line description of the change>", | ||
| "- `path/to/file2` — <one-line description of the change>", | ||
| "(If you didn't change any files, write `_None_` here and explain why in the Solution section.)", | ||
| "", | ||
| "## Solution", | ||
| "<2–5 sentences: what the root cause was, what you changed and why, and any follow-up the user must do themselves (e.g. set an env var, restart the dev server).>", | ||
| ].join("\n"); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.