Skip to content
2 changes: 2 additions & 0 deletions COOKBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ jobs:
- Create an issue with `@junie-agent` in the title or body → Junie analyzes and proposes a solution
- Submit a PR review mentioning `@junie-agent` → Junie addresses your feedback
- Comment `@junie-agent resolve conflicts` on a PR with merge conflicts → Junie resolves the conflicts
- Comment `@junie-agent minor-fix rename variable x to y` in a PR → Junie makes the requested adjustment

**Features enabled:**
- ✅ Minor Fixes - quickly implement small PR adjustments with `minor-fix`
- ✅ Single comment mode - updates one comment instead of creating multiple
- ✅ Works on issues, PRs, comments, and reviews
- ✅ Only triggers on explicit `@junie-agent` mentions
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ A powerful GitHub Action that integrates [Junie](https://www.jetbrains.com/junie
- **PR Management**: Reviews code changes and implements requested modifications
- **Inline Code Reviews**: Create code review comments with GitHub suggestions directly on PR diffs
- **Conflict Resolution**: Resolve merge conflicts via `@junie-agent` comment or automatic detection
- **Minor PR Fixes**: Quickly implement small changes in PRs using `@junie-agent minor-fix [instruction]`
- **CI Failure Analysis**: Investigates failed checks and suggests fixes using MCP integration
- **Flexible Triggers**: Activate via mentions, assignees, labels, or custom prompts
- **Smart Branch Management**: Context-aware branch creation and management
Expand Down Expand Up @@ -100,6 +101,7 @@ jobs:
3. Start using Junie:
- Comment `@junie-agent help me fix this bug` on an issue
- Mention `@junie-agent review this change` in a PR
- Comment `@junie-agent minor-fix rename variable x to y` in a PR to make quick adjustments

## Jira Integration

Expand Down Expand Up @@ -140,7 +142,7 @@ Each recipe includes complete workflows, prompts, and configuration examples you

| Input | Description | Default |
|-------|-------------|---------|
| `prompt` | Custom instructions for Junie. Special values: `code-review` for structured PR reviews, `fix-ci` for CI failure analysis. See [Cookbook](COOKBOOK.md) for examples. | - |
| `prompt` | Custom instructions for Junie. Special values: `code-review` for structured PR reviews, `fix-ci` for CI failure analysis, `minor-fix` for quick PR adjustments. See [Cookbook](COOKBOOK.md) for examples. | - |
| `junie_version` | Junie CLI version to install | `624.1.0` |
| `model` | Model to use for the primary agent. Available: `gpt-5-2025-08-07`, `gpt-5.2-codex`, `gpt-5.2-2025-12-11`, `claude-sonnet-4-5-20250929`, `claude-opus-4-5-20251101`, `gemini-3-pro-preview`, `gemini-3-flash-preview`, `grok-4-1-fast-reasoning` | - |
| `junie_work_dir` | Working directory for Junie files | `/tmp/junie-work` |
Expand Down Expand Up @@ -207,6 +209,7 @@ For detailed setup instructions, see the [Jira Integration Guide](docs/JIRA_INTE
| `pr_url` | URL of the pull request created by Junie (if any) |
| `junie_title` | Title of the task completion from Junie |
| `junie_summary` | Summary of the changes made by Junie |
| `custom_junie_args` | Custom Junie arguments extracted from prompt/comment (e.g., `--model=value`) |
| `github_token` | The GitHub token used by the action |

**Example usage:**
Expand Down
45 changes: 45 additions & 0 deletions src/constants/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export const FIX_CI_ACTION = "fix-ci";

export const FIX_CI_TRIGGER_PHRASE_REGEXP = new RegExp(FIX_CI_ACTION, 'i');

export const MINOR_FIX_ACTION = "minor-fix";

export const MINOR_FIX_TRIGGER_PHRASE_REGEXP = new RegExp(MINOR_FIX_ACTION, 'i');

export const JIRA_EVENT_ACTION = "jira_event";

export const WORKING_BRANCH_PREFIX = "junie/";
Expand Down Expand Up @@ -155,6 +159,47 @@ Your task is to analyze CI failures and suggest fixes WITHOUT implementing them.
`;
}

export function createMinorFixPrompt(diffPoint: string, userRequest?: string): string {
const diffCommand = `gh pr diff ${diffPoint}`
const userRequestSection = userRequest
? `\n### User Request\nThe user has specifically requested: "${userRequest}"\nFocus on addressing this request while following all the guidelines below.\n`
: '';
const gatherInfoUserRequestNote = userRequest
? `\n - Focus specifically on understanding what "${userRequest}" means in the context of this PR. Identify the relevant files, functions, or code sections that relate to this request.`
: '';

return `
Your task is to make a minor fix to this Pull Request based on the user's request.
${userRequestSection}
### Steps to follow
1. Gather Information
- Read the Pull Request diff by using \`${diffCommand} | grep "^diff --git"\`. Do not write the diff to file.
- Understand the context of the changes and what the PR is trying to accomplish.${gatherInfoUserRequestNote}

2. Implement the Fix
- Make the requested changes to the codebase.
- Keep changes minimal and focused on the specific request.
- Follow the existing code style and conventions in the repository.
- Do NOT make unrelated changes or "improvements" beyond what was requested.

3. Validation
- Ensure your changes compile/build successfully.
- Run relevant tests if applicable.
- Verify the fix addresses the user's request.

### Guidelines
- **Scope**: Only make changes directly related to the user's request. Do not refactor or "improve" unrelated code.
- **Style**: Match the existing code style, naming conventions, and patterns in the repository.
- **Safety**: Be conservative with changes. When in doubt, make the smaller change.
- **Testing**: If you modify logic, ensure existing tests still pass. Add tests only if explicitly requested.

### Output
Submit a brief summary of the changes you made and why they address the user's request.

IMPORTANT: Do NOT commit or push changes. The system will handle all git operations (staging, committing, and pushing) automatically.
`;
}

/**
* Creates a hidden marker for identifying Junie comments from a specific workflow.
* This HTML comment is invisible to users but allows finding Junie comments
Expand Down
10 changes: 9 additions & 1 deletion src/github/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ import {
DEFAULT_TRIGGER_PHRASE,
FIX_CI_ACTION,
JIRA_EVENT_ACTION, JUNIE_AGENT,
MINOR_FIX_ACTION,
RESOLVE_CONFLICTS_ACTION
} from "../constants/github";
import {isReviewOrCommentHasCodeReviewTrigger, isReviewOrCommentHasFixCITrigger} from "./validation/trigger";
import {isReviewOrCommentHasCodeReviewTrigger, isReviewOrCommentHasFixCITrigger, isReviewOrCommentHasMinorFixTrigger} from "./validation/trigger";

// Jira integration types
export type JiraComment = {
Expand Down Expand Up @@ -499,6 +500,13 @@ export function isFixCodeReviewEvent(context: JunieExecutionContext) {
return isCodeReviewInPrompt || isCodeReviewInComment;
}

export function isMinorFixEvent(context: JunieExecutionContext) {
const isMinorFixInPrompt = context.inputs.prompt?.includes(MINOR_FIX_ACTION);
const isMinorFixInComment = isReviewOrCommentHasMinorFixTrigger(context);
console.log(`Minor fix detection: inPrompt=${isMinorFixInPrompt}, inComment=${isMinorFixInComment}`);
return isMinorFixInPrompt || isMinorFixInComment;
}


/**
* Checks if the context is triggered by user interaction (comments, PR/issue events)
Expand Down
1 change: 1 addition & 0 deletions src/github/junie/junie-tasks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
isIssueCommentEvent,
isIssuesEvent,
isMinorFixEvent,
isPullRequestEvent,
isPullRequestReviewCommentEvent,
isPullRequestReviewEvent,
Expand Down
40 changes: 39 additions & 1 deletion src/github/junie/new-prompt-formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
isIssueCommentEvent,
isIssuesEvent,
isJiraWorkflowDispatchEvent,
isMinorFixEvent,
isPullRequestEvent,
isPullRequestReviewCommentEvent,
isPullRequestReviewEvent,
Expand All @@ -25,7 +26,7 @@ import {
} from "../context";
import {downloadJiraAttachmentsAndRewriteText} from "./attachment-downloader";
import {sanitizeContent} from "../../utils/sanitizer";
import {createCodeReviewPrompt, createFixCIFailuresPrompt, GIT_OPERATIONS_NOTE} from "../../constants/github";
import {createCodeReviewPrompt, createFixCIFailuresPrompt, createMinorFixPrompt, GIT_OPERATIONS_NOTE, MINOR_FIX_ACTION} from "../../constants/github";
import {extractJunieArgs} from "../../utils/junie-args-parser";
import {BranchInfo} from "../operations/branch";

Expand Down Expand Up @@ -112,6 +113,7 @@ ${GIT_OPERATIONS_NOTE}

const isCodeReview = isFixCodeReviewEvent(context)
const isFixCI = isFixCIEvent(context)
const isMinorFix = isMinorFixEvent(context)

if (issue && isCodeReview) {
const branchName = branchInfo.prBaseBranch || branchInfo.baseBranch;
Expand All @@ -123,8 +125,44 @@ ${GIT_OPERATIONS_NOTE}
const diffPoint = context.isPR && context.entityNumber ? String(context.entityNumber) : branchName;
console.log(`Using FIX-CI prompt for diffPoint: ${diffPoint}`);
return createFixCIFailuresPrompt(diffPoint);
} else if (isMinorFix) {
const branchName = branchInfo.prBaseBranch || branchInfo.baseBranch;
const diffPoint = context.isPR && context.entityNumber ? String(context.entityNumber) : branchName;
// Extract user request from comment (text after "minor-fix")
const userRequest = this.extractMinorFixRequest(context);
console.log(`Using MINOR-FIX prompt for diffPoint: ${diffPoint}, userRequest: ${userRequest || '(none)'}`);
return createMinorFixPrompt(diffPoint, userRequest);
}
}

/**
* Extracts the user's request text from a comment that triggered the minor-fix action.
* The request is the text that follows "minor-fix" in the comment.
* For example: "minor-fix rename variable foo to bar" -> "rename variable foo to bar"
*/
private extractMinorFixRequest(context: JunieExecutionContext): string | undefined {
let commentBody: string | undefined;

if (isIssueCommentEvent(context) || isPullRequestReviewCommentEvent(context)) {
commentBody = context.payload.comment.body;
} else if (isPullRequestReviewEvent(context)) {
commentBody = context.payload.review.body || undefined;
}

if (!commentBody) {
return undefined;
}

// Match "minor-fix" (case insensitive) and capture everything after it
const match = commentBody.match(new RegExp(`${MINOR_FIX_ACTION}\\s*(.*)`, 'is'));
if (match && match[1]) {
const request = match[1].trim();
return request.length > 0 ? request : undefined;
}

return undefined;
}

private async generateJiraPrompt(context: JunieExecutionContext): Promise<string> {
const jira = context.payload as JiraIssuePayload;

Expand Down
6 changes: 5 additions & 1 deletion src/github/validation/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
isPullRequestReviewCommentEvent,
isPullRequestReviewEvent,
} from "../context";
import {CODE_REVIEW_TRIGGER_PHRASE_REGEXP, FIX_CI_TRIGGER_PHRASE_REGEXP, RESOLVE_CONFLICTS_TRIGGER_PHRASE_REGEXP} from "../../constants/github";
import {CODE_REVIEW_TRIGGER_PHRASE_REGEXP, FIX_CI_TRIGGER_PHRASE_REGEXP, MINOR_FIX_TRIGGER_PHRASE_REGEXP, RESOLVE_CONFLICTS_TRIGGER_PHRASE_REGEXP} from "../../constants/github";

/**
* Detects if the Junie trigger phrase is present in the workflow context
Expand Down Expand Up @@ -99,6 +99,10 @@ export function isReviewOrCommentHasFixCITrigger(context: JunieExecutionContext)
return isReviewOrCommentHasTrigger(context, FIX_CI_TRIGGER_PHRASE_REGEXP)
}

export function isReviewOrCommentHasMinorFixTrigger(context: JunieExecutionContext) {
return isReviewOrCommentHasTrigger(context, MINOR_FIX_TRIGGER_PHRASE_REGEXP)
}

export function isReviewOrCommentHasTrigger(context: JunieExecutionContext, regExp: RegExp) {
if (
isPullRequestReviewEvent(context) &&
Expand Down
Loading